Skip to content

Commit 66c2d4b

Browse files
committed
Address bugs due to lack of linemark generation
Port `Statement.toc()` family rework from RAII PR Don't DML linemark code injected by memoized methods Suppress redundant line directive generation
1 parent d26148c commit 66c2d4b

File tree

9 files changed

+429
-349
lines changed

9 files changed

+429
-349
lines changed

py/dml/c_backend.py

Lines changed: 44 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -746,10 +746,9 @@ def wrap_method(meth, wrapper_name, indices=()):
746746
indices = tuple(mkIntegerLiteral(meth.site, i) for i in indices)
747747
with crep.DeviceInstanceContext():
748748
if retvar:
749-
decl = mkDeclaration(meth.site, retvar, rettype,
750-
init = get_initializer(meth.site, rettype,
751-
None, None, None))
752-
decl.toc()
749+
mkDeclaration(meth.site, retvar, rettype,
750+
init = get_initializer(meth.site, rettype,
751+
None, None, None)).toc()
753752

754753
with LogFailure(meth.site, meth, indices):
755754
inargs = [mkLit(meth.site, v, t) for v, t in meth.inp]
@@ -1341,7 +1340,6 @@ def generate_reg_callback(meth, name):
13411340
+ ', '.join(params) + ')\n')
13421341
out('{\n', postindent = 1)
13431342
out('%s *_dev = _obj;\n' % dev_t)
1344-
scope = Symtab(global_scope)
13451343
fail = ReturnFailure(meth.site)
13461344
with fail, crep.DeviceInstanceContext():
13471345
inargs = [mkLit(meth.site, n, t) for n, t in meth.inp]
@@ -1352,8 +1350,7 @@ def generate_reg_callback(meth, name):
13521350
for i in range(meth.dimensions)),
13531351
inargs, outargs)]
13541352

1355-
code = mkCompound(meth.site, declarations(scope) + code + [fail.nofail()])
1356-
code.toc()
1353+
mkCompound(meth.site, code + [fail.nofail()]).toc_inline()
13571354
out('}\n', preindent = -1)
13581355
out('\n')
13591356

@@ -1618,8 +1615,7 @@ def generate_finalize(device):
16181615
else:
16191616
code = codegen_inline_byname(device, (), '_post_init', [], [],
16201617
device.site)
1621-
if not code.is_empty:
1622-
code.toc()
1618+
code.toc_inline()
16231619
out('}\n\n', preindent = -1)
16241620

16251621
def generate_deinit(device):
@@ -1665,8 +1661,7 @@ def generate_deinit(device):
16651661
device.get_component('destroy', 'method').site, device, ()):
16661662
code = codegen_inline_byname(device, (), 'destroy', [], [],
16671663
device.site)
1668-
if not code.is_empty:
1669-
code.toc()
1664+
code.toc()
16701665

16711666
# Cancel all pending afters on hooks
16721667
by_dims = {}
@@ -1712,14 +1707,12 @@ def generate_reset(device, hardness):
17121707
out('{\n', postindent = 1)
17131708
out(crep.structtype(device) + ' *_dev UNUSED = ('
17141709
+ crep.structtype(device) + ' *)_obj;\n\n')
1715-
scope = Symtab(global_scope)
17161710
method_name = hardness + '_reset'
17171711
method = device.get_component(method_name, 'method')
17181712
with LogFailure(method.site, device, ()), crep.DeviceInstanceContext():
17191713
code = codegen_call_byname(method.site, device, (),
17201714
method_name, [], [])
1721-
code = mkCompound(method.site, declarations(scope) + [code])
1722-
code.toc()
1715+
code.toc_inline()
17231716
out('}\n\n', preindent = -1)
17241717

17251718
# {(B, C): A} means that a static array 'const uint32 _indices_B_C[A][B][C][3]'
@@ -2039,14 +2032,6 @@ def generate_extern_trampoline_dml12(exported_name, func):
20392032
", ".join(n for (n, t) in func.cparams)))
20402033
out("}\n", preindent=-1)
20412034

2042-
def som_linemark(site):
2043-
if dml.globals.linemarks:
2044-
out('#line %d "%s"\n' % (site.lineno, quote_filename(site.filename())))
2045-
2046-
def eom_linemark(site):
2047-
if dml.globals.linemarks:
2048-
out('#line %d "%s"\n' % (site.lineno, quote_filename(site.filename())))
2049-
20502035
def generate_each_in_table(trait, instances):
20512036
items = []
20522037
for (node, subnodes) in instances:
@@ -2167,9 +2152,12 @@ def generate_trait_method(m):
21672152
code = m.codegen_body()
21682153
out('/* %s */\n' % (str(m),))
21692154
start_function_definition(m.declaration())
2170-
out('{\n', postindent=1)
2171-
code.toc_inline()
2172-
out('}\n', preindent=-1)
2155+
with allow_linemarks():
2156+
site_linemark(m.site)
2157+
out('{\n', postindent=1)
2158+
code.toc_inline()
2159+
site_linemark(m.rbrace_site)
2160+
out('}\n', preindent=-1)
21732161

21742162
def generate_adjustor_thunk(traitname, name, inp, outp, throws, independent,
21752163
vtable_path, def_path, hardcoded_impl=None):
@@ -3337,15 +3325,15 @@ def generate_cfile_body(device, footers, full_module, filename_prefix):
33373325

33383326
for t in list(dml.globals.traits.values()):
33393327
for m in list(t.method_impls.values()):
3340-
with allow_linemarks():
3341-
if gather_size_statistics:
3342-
ctx = StrOutput()
3343-
with ctx:
3344-
generate_trait_method(m)
3345-
size_statistics[m.site.loc()] = [len(ctx.buf)]
3346-
out(ctx.buf)
3347-
else:
3328+
if gather_size_statistics:
3329+
ctx = StrOutput(filename=output.current().filename,
3330+
lineno=output.current().lineno)
3331+
with ctx:
33483332
generate_trait_method(m)
3333+
size_statistics[m.site.loc()] = [len(ctx.buf)]
3334+
out(ctx.buf)
3335+
else:
3336+
generate_trait_method(m)
33493337
# Note: methods may be added to method_queue while doing this,
33503338
# so don't try to be too smart
33513339
generated_funcs = set()
@@ -3360,23 +3348,24 @@ def generate_cfile_body(device, footers, full_module, filename_prefix):
33603348
for (n, v) in func.inp
33613349
if isinstance(v, Expression)]
33623350

3363-
with allow_linemarks():
3364-
if gather_size_statistics:
3365-
ctx = StrOutput()
3351+
if gather_size_statistics:
3352+
ctx = StrOutput(lineno=output.current().lineno,
3353+
filename=output.current().filename)
3354+
else:
3355+
ctx = nullcontext()
3356+
with ErrorContext(func.method), ctx:
3357+
if specializations:
3358+
out('/* %s\n' % func.get_name())
3359+
for (n, v) in specializations:
3360+
out(' %s = %s\n' % (n, v))
3361+
out('*/\n')
33663362
else:
3367-
ctx = nullcontext()
3368-
with ErrorContext(func.method), ctx:
3369-
if specializations:
3370-
out('/* %s\n' % func.get_name())
3371-
for (n, v) in specializations:
3372-
out(' %s = %s\n' % (n, v))
3373-
out('*/\n')
3374-
else:
3375-
out('/* %s */\n' % func.get_name())
3363+
out('/* %s */\n' % func.get_name())
33763364

3377-
start_function_definition(func.prototype)
3378-
som_linemark(func.method.astcode.site)
3379-
out('{\n', postindent = 1)
3365+
start_function_definition(func.prototype)
3366+
with allow_linemarks():
3367+
site_linemark(func.method.astcode.site)
3368+
out('{\n', postindent=1)
33803369
try:
33813370
code.toc_inline()
33823371
except DMLError as e:
@@ -3385,12 +3374,13 @@ def generate_cfile_body(device, footers, full_module, filename_prefix):
33853374
# codegen_method, when all Expression and Statement
33863375
# objects are instantiated.
33873376
raise ICE(e.site, 'error during late compile stage')
3388-
eom_linemark(func.method.rbrace_site)
3389-
out('}\n\n', preindent = -1)
3390-
if gather_size_statistics:
3391-
size_statistics.setdefault(func.method.site.loc(), []).append(
3392-
len(ctx.buf))
3393-
out(ctx.buf)
3377+
site_linemark(func.method.rbrace_site)
3378+
out('}\n', preindent=-1)
3379+
out('\n')
3380+
if gather_size_statistics:
3381+
size_statistics.setdefault(func.method.site.loc(), []).append(
3382+
len(ctx.buf))
3383+
out(ctx.buf)
33943384
splitting_point()
33953385

33963386

py/dml/codegen.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from .expr_util import *
2020
from .symtab import *
2121
from .messages import *
22-
from .output import out
22+
from .output import *
2323
from .types import *
2424
from .set import Set
2525
from .slotsmeta import auto_init
@@ -316,11 +316,13 @@ def __init__(self, func):
316316
assert func.method.independent
317317
self.func = func
318318
self.method = func.method
319+
# SimpleSite wrapper to avoid linemarks being generated.
320+
self.site = SimpleSite(self.method.site.loc())
319321

320322
def make_ref(self, ref, typ):
321323
indexing = ''.join([f'[_idx{i}]'
322324
for i in range(self.method.dimensions)])
323-
return mkLit(self.method.site, f'_memo{indexing}.{ref}', typ)
325+
return mkLit(self.site, f'_memo{indexing}.{ref}', typ)
324326

325327
def prelude(self):
326328
struct_body = ''.join(
@@ -331,10 +333,10 @@ def prelude(self):
331333
+ [(f'p_{name}', typ) for (name, typ) in self.func.outp]))
332334
array_defs = ''.join([f'[{i}]' for i in self.method.dimsizes])
333335
struct_var_def = mkInline(
334-
self.method.site,
336+
self.site,
335337
f'static struct {{{struct_body}}} _memo{array_defs};')
336338
return [struct_var_def] + memoization_common_prelude(
337-
self.method.logname_anonymized(), self.method.site, self.func.outp,
339+
self.method.logname_anonymized(), self.site, self.func.outp,
338340
self.func.throws, self.make_ref)
339341
def exit_handler(self):
340342
return MemoizedReturnExit(self.method.site, self.func.outp,
@@ -347,16 +349,18 @@ class SharedIndependentMemoized(Memoization):
347349
def __init__(self, method):
348350
assert method.independent
349351
self.method = method
352+
# SimpleSite wrapper to avoid linemarks being generated.
353+
self.site = SimpleSite(self.method.site.loc())
350354
def make_ref(self, ref, typ):
351355
traitname = cident(self.method.trait.name)
352-
return mkLit(self.method.site,
356+
return mkLit(self.site,
353357
f'((struct _{traitname} *) _{traitname}.trait)'
354358
+ f'->_memo_outs_{self.method.name}'
355359
+ f'[_{traitname}.id.encoded_index].{ref}', typ)
356360
def prelude(self):
357361
return memoization_common_prelude(
358-
self.method.name, self.method.site, self.method.outp,
359-
self.method.throws, self.make_ref)
362+
self.method.name, self.site, self.method.outp, self.method.throws,
363+
self.make_ref)
360364
def exit_handler(self):
361365
return MemoizedReturnExit(self.method.site, self.method.outp,
362366
self.method.throws, self.make_ref)
@@ -1925,7 +1929,7 @@ def codegen_statement(tree, *args):
19251929

19261930
@statement_dispatcher
19271931
def stmt_compound(stmt, location, scope):
1928-
[stmt_asts] = stmt.args
1932+
[stmt_asts, rbrace_site] = stmt.args
19291933
if (logging.show_porting and stmt.site.dml_version() == (1, 2)
19301934
and not stmt.site.filename().endswith('dml-builtins.dml')):
19311935
method = location.method()
@@ -1942,7 +1946,8 @@ def stmt_compound(stmt, location, scope):
19421946
ret.site))
19431947
lscope = Symtab(scope)
19441948
statements = codegen_statements(stmt_asts, location, lscope)
1945-
return [mkCompound(stmt.site, declarations(lscope) + statements)]
1949+
return [mkCompound(stmt.site, declarations(lscope) + statements,
1950+
rbrace_site)]
19461951

19471952
def check_shadowing(scope, name, site):
19481953
if (dml.globals.dml_version == (1, 2)
@@ -2197,7 +2202,7 @@ def stmt_null(stmt, location, scope):
21972202

21982203
@statement_dispatcher
21992204
def stmt_if(stmt, location, scope):
2200-
[cond_ast, truebranch, falsebranch] = stmt.args
2205+
[cond_ast, truebranch, falsebranch, else_site] = stmt.args
22012206
cond = as_bool(codegen_expression(cond_ast, location, scope))
22022207
if cond.constant and stmt.site.dml_version() == (1, 2):
22032208
if (logging.show_porting
@@ -2212,8 +2217,7 @@ def stmt_if(stmt, location, scope):
22122217
if errors:
22132218
report(PHASH(stmt.site))
22142219
if falsebranch:
2215-
report(PHASHELSE(dmlparse.end_site(truebranch.site),
2216-
'else'))
2220+
report(PHASHELSE(else_site, 'else'))
22172221
if (not falsebranch and cond_ast.kind == 'binop'
22182222
and cond_ast.args[1] == '&&'):
22192223
lh = as_bool(codegen_expression(cond_ast.args[0], location, scope))
@@ -2234,7 +2238,7 @@ def stmt_if(stmt, location, scope):
22342238
fbranch = codegen_statement(falsebranch, location, scope)
22352239
else:
22362240
fbranch = None
2237-
return [ctree.If(stmt.site, cond, tbranch, fbranch)]
2241+
return [ctree.If(stmt.site, cond, tbranch, fbranch, else_site)]
22382242

22392243
@statement_dispatcher
22402244
def stmt_hashif(stmt, location, scope):
@@ -3219,7 +3223,7 @@ def stmt_switch(stmt, location, scope):
32193223
with CLoopContext():
32203224
if stmt.site.dml_version() != (1, 2):
32213225
assert body_ast.kind == 'compound'
3222-
[stmt_asts] = body_ast.args
3226+
[stmt_asts, rbrace_site] = body_ast.args
32233227
stmts = codegen_statements(stmt_asts, location, scope)
32243228
if (not stmts
32253229
or not isinstance(stmts[0], (ctree.Case, ctree.Default))):
@@ -3257,7 +3261,7 @@ def stmt_switch(stmt, location, scope):
32573261
body_stmts.append(mkSubsequentCases(
32583262
subsequent_cases[0].site, subsequent_cases, default_found))
32593263

3260-
body = ctree.Compound(body_ast.site, body_stmts)
3264+
body = ctree.Compound(body_ast.site, body_stmts, rbrace_site)
32613265
else:
32623266
body = codegen_statement(body_ast, location, scope)
32633267

@@ -3608,15 +3612,15 @@ def codegen_inline(site, meth_node, indices, inargs, outargs,
36083612
code, post)
36093613
else:
36103614
assert meth_node.astcode.kind == 'compound'
3611-
[subs] = meth_node.astcode.args
3615+
[subs, rbrace_site] = meth_node.astcode.args
36123616
location = Location(meth_node, indices)
36133617
exit_handler = GotoExit_dml14(outargs)
36143618
with exit_handler:
36153619
code = codegen_statements(subs, location, param_scope)
36163620
decls = declarations(param_scope)
36173621
post = ([mkLabel(site, exit_handler.label)]
36183622
if exit_handler.used else [])
3619-
body = mkCompound(site, decls + code)
3623+
body = mkCompound(site, decls + code, rbrace_site)
36203624
if meth_node.outp and body.control_flow().fallthrough:
36213625
report(ENORET(meth_node.astcode.site))
36223626
return mkInlinedMethod(site, meth_node, decls, code, post)
@@ -3772,7 +3776,7 @@ def codegen_method_func(func):
37723776
method.parent, indices,
37733777
[mkLit(method.site, n, t) for (n, t) in func.inp],
37743778
[mkLit(method.site, "*%s" % n, t) for (n, t) in func.outp],
3775-
method.site)
3779+
SimpleSite(method.site.loc()))
37763780
inline_scope = MethodParamScope(global_scope)
37773781
for (name, e) in func.inp:
37783782
if dml.globals.dml_version == (1, 2) and (
@@ -3894,10 +3898,8 @@ def prelude():
38943898
# manually deconstruct compound AST node, to make sure
38953899
# top-level locals share scope with parameters
38963900
assert ast.kind == 'compound'
3897-
[subs] = ast.args
3901+
[subs, _] = ast.args
38983902
with fail_handler, exit_handler:
3899-
# TODO The linemarks for the prelude will point to the method
3900-
# declaration, which is not optimal, but should be fine.
39013903
body = prelude()
39023904
body.extend(codegen_statements(subs, location, fnscope))
39033905
code = mkCompound(site, body)
@@ -3907,7 +3909,8 @@ def prelude():
39073909
else:
39083910
code = mkCompound(site,
39093911
body + [codegen_exit(rbrace_site,
3910-
[])])
3912+
[])],
3913+
rbrace_site)
39113914
to_return = code
39123915
return to_return
39133916

0 commit comments

Comments
 (0)