Skip to content

Commit b9b728c

Browse files
committed
Selectively allow generation of line directives
1 parent 6d1abbc commit b9b728c

File tree

7 files changed

+147
-108
lines changed

7 files changed

+147
-108
lines changed

RELEASENOTES.docu

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,4 +1737,9 @@ extern typedef struct { } my_type_t;</pre> </add-note></build-id>
17371737
compilation of devices with huge arrays of ports. The
17381738
option <tt>--help-no-compat</tt> lists all features that can be
17391739
disabled.</add-note></build-id>
1740+
<build-id value="next"><add-note> Addressed multiple issues with line
1741+
directive generation which were detrimental to the use of debugging and
1742+
coverage tools. Generated C lines should now only ever be redirected to
1743+
DML when the DML line in question can be reasonably considered to describe
1744+
the operation of the C line. </add-note></build-id>
17401745
</rn>

py/dml/c_backend.py

Lines changed: 71 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,11 @@ def generate_hfile(device, headers, filename):
261261
emit_guard_start(filename)
262262
out('#define DML_PREFIX(x) '+crep.cname(device)+'_##x\n\n')
263263

264-
for c in headers:
265-
c.toc()
266-
out('\n')
264+
with allow_linemarks():
265+
for c in headers:
266+
c.toc()
267+
out('\n')
267268

268-
reset_line_directive()
269269
out('\n')
270270

271271
out('#include <simics/util/help-macros.h>\n')
@@ -435,7 +435,6 @@ def generate_attr_setter(fname, node, port, dimsizes, cprefix, loopvars,
435435

436436
code = mkCompound(None, declarations(fscope) + setcode)
437437
code.toc_inline()
438-
reset_line_directive()
439438
if dimsizes:
440439
# abort on first bad value
441440
out('if (_status != Sim_Set_Ok) goto exit;\n')
@@ -491,7 +490,6 @@ def generate_attr_getter(fname, node, port, dimsizes, cprefix, loopvars):
491490
[], [valuevar], node.site)
492491
code = mkCompound(node.site, declarations(fscope) + [getcode])
493492
code.toc_inline()
494-
reset_line_directive()
495493

496494
for depth, loopvar in reversed(list(enumerate(loopvars))):
497495
out('SIM_attr_list_set_item(&_val%d, %s, _val%d);\n'
@@ -760,8 +758,6 @@ def wrap_method(meth, wrapper_name, indices=()):
760758
indices,
761759
inargs, outargs).toc()
762760
output_dml_state_change('_dev')
763-
764-
reset_line_directive()
765761
if retvar:
766762
out('return '+retvar+';\n')
767763
out('}\n', preindent = -1)
@@ -1110,8 +1106,6 @@ def generate_simple_events(device):
11101106
out('}\n\n', preindent = -1)
11111107
splitting_point()
11121108

1113-
reset_line_directive()
1114-
11151109
def generate_after_on_hooks_artifacts(device):
11161110
for info in dml.globals.after_on_hook_infos:
11171111
site = SimpleSite(f'after on hook {string_literal(info.string_key)}')
@@ -1186,8 +1180,6 @@ def error_out(exc, msg):
11861180
out('}\n\n', preindent = -1)
11871181
splitting_point()
11881182

1189-
reset_line_directive()
1190-
11911183
if dml.globals.after_on_hook_infos:
11921184
init = '{\n%s\n}' % (',\n'.join(
11931185
' {%s, %s, %s, %s, %s, %d}'
@@ -1213,7 +1205,6 @@ def error_out(exc, msg):
12131205
+ f'_after_on_hook_infos[{info.uniq}].callback_key, '
12141206
+ f'&_after_on_hook_infos[{info.uniq}]);\n')
12151207
out('}\n', preindent = -1)
1216-
reset_line_directive()
12171208
splitting_point()
12181209

12191210
def generate_immediate_after_callbacks(device):
@@ -1235,8 +1226,6 @@ def generate_immediate_after_callbacks(device):
12351226
out('}\n\n', preindent = -1)
12361227
splitting_point()
12371228

1238-
reset_line_directive()
1239-
12401229
def generate_simple_events_control_methods(device):
12411230
start_function_definition(
12421231
'void _cancel_simple_events(conf_object_t *_obj, _identity_t domain)')
@@ -1592,9 +1581,9 @@ def generate_initialize(device):
15921581

15931582
mkCompound(device.site, stmts).toc()
15941583
else:
1595-
codegen_inline_byname(device, (), '_init', [], [], device.site).toc()
1584+
codegen_inline_byname(device, (), '_init', [], [],
1585+
device.site).toc()
15961586

1597-
reset_line_directive()
15981587
if dml.globals.api_version <= compat.api_6:
15991588
out('SIM_add_notifier(_obj, Sim_Notify_Object_Delete, _obj, '
16001589
+ crep.cname(device) + '_pre_del_notify, NULL);\n')
@@ -1632,7 +1621,6 @@ def generate_finalize(device):
16321621
if not code.is_empty:
16331622
code.toc()
16341623
out('}\n\n', preindent = -1)
1635-
reset_line_directive()
16361624

16371625
def generate_deinit(device):
16381626
start_function_definition(
@@ -1715,7 +1703,6 @@ def generate_deinit(device):
17151703
out('}\n', preindent = -1)
17161704

17171705
out('}\n\n', preindent = -1)
1718-
reset_line_directive()
17191706
splitting_point()
17201707

17211708
def generate_reset(device, hardness):
@@ -1734,7 +1721,6 @@ def generate_reset(device, hardness):
17341721
code = mkCompound(method.site, declarations(scope) + [code])
17351722
code.toc()
17361723
out('}\n\n', preindent = -1)
1737-
reset_line_directive()
17381724

17391725
# {(B, C): A} means that a static array 'const uint32 _indices_B_C[A][B][C][3]'
17401726
# will be generated, where element [x][y][z] is {x,y,z}
@@ -1853,7 +1839,6 @@ def generate_init_static_vars(device):
18531839
for line in init.splitlines(keepends=True):
18541840
out(line)
18551841
out('}\n\n', preindent = -1)
1856-
reset_line_directive()
18571842

18581843
def generate_init_data_objs(device):
18591844
start_function_definition(
@@ -1881,23 +1866,23 @@ def generate_init_data_objs(device):
18811866
# mainly meant to capture EIDXVAR; for other errors, the error will
18821867
# normally re-appear when evaluating per instance
18831868
except DMLError:
1884-
for indices in node.all_indices():
1885-
index_exprs = tuple(mkIntegerLiteral(node.site, i)
1886-
for i in indices)
1887-
nref = mkNodeRef(node.site, node, index_exprs)
1888-
try:
1889-
init = eval_initializer(
1890-
node.site, node._type, node.astinit,
1891-
Location(node.parent, index_exprs), global_scope,
1892-
True)
1893-
except DMLError as e:
1894-
report(e)
1895-
else:
1896-
if deep_const(node._type):
1897-
coverity_marker('store_writes_const_field',
1898-
'FALSE',
1899-
node.site)
1900-
init.assign_to(nref, node._type)
1869+
with allow_linemarks():
1870+
for indices in node.all_indices():
1871+
index_exprs = tuple(mkIntegerLiteral(node.site, i)
1872+
for i in indices)
1873+
nref = mkNodeRef(node.site, node, index_exprs)
1874+
try:
1875+
init = eval_initializer(
1876+
node.site, node._type, node.astinit,
1877+
Location(node.parent, index_exprs),
1878+
global_scope, True)
1879+
except DMLError as e:
1880+
report(e)
1881+
else:
1882+
markers = ([('store_writes_const_field', 'FALSE')]
1883+
if deep_const(node._type) else [])
1884+
coverity_markers(markers, node.site)
1885+
init.assign_to(nref, node._type)
19011886
else:
19021887
index_exprs = ()
19031888
for (i, sz) in enumerate(node.dimsizes):
@@ -1907,13 +1892,14 @@ def generate_init_data_objs(device):
19071892
postindent=1)
19081893
index_exprs += (mkLit(node.site, var, TInt(64, True)),)
19091894
nref = mkNodeRef(node.site, node, index_exprs)
1910-
if deep_const(node._type):
1911-
coverity_marker('store_writes_const_field', 'FALSE', node.site)
1912-
init.assign_to(nref, node._type)
1895+
with allow_linemarks():
1896+
markers = ([('store_writes_const_field', 'FALSE')]
1897+
if deep_const(node._type) else [])
1898+
coverity_markers(markers, node.site)
1899+
init.assign_to(nref, node._type)
19131900
for _ in range(node.dimensions):
19141901
out('}\n', postindent=-1)
19151902
out('}\n\n', preindent = -1)
1916-
reset_line_directive()
19171903
splitting_point()
19181904

19191905
ident_chars = set(chr(i)
@@ -3157,7 +3143,7 @@ def generate_startup_trait_calls(data, idxvars):
31573143
method.site, mkLit(method.site, '_tref', TTrait(trait)), method)
31583144
with IgnoreFailure(site):
31593145
codegen_call_traitmethod(method.site, method_ref, [],
3160-
outargs) .toc()
3146+
outargs).toc()
31613147
out('}\n', preindent=-1)
31623148

31633149
def generate_startup_regular_call(method, idxvars):
@@ -3262,7 +3248,6 @@ def splitting_point():
32623248
assert_global_c_scope()
32633249
if c_split_threshold and c_file.tell() > c_split_threshold:
32643250
c_file.advance()
3265-
reset_line_directive()
32663251

32673252
c_file = None
32683253
def generate_cfile(device, footers,
@@ -3352,14 +3337,15 @@ def generate_cfile_body(device, footers, full_module, filename_prefix):
33523337

33533338
for t in list(dml.globals.traits.values()):
33543339
for m in list(t.method_impls.values()):
3355-
if gather_size_statistics:
3356-
ctx = StrOutput()
3357-
with ctx:
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:
33583348
generate_trait_method(m)
3359-
size_statistics[m.site.loc()] = [len(ctx.buf)]
3360-
out(ctx.buf)
3361-
else:
3362-
generate_trait_method(m)
33633349
# Note: methods may be added to method_queue while doing this,
33643350
# so don't try to be too smart
33653351
generated_funcs = set()
@@ -3374,39 +3360,39 @@ def generate_cfile_body(device, footers, full_module, filename_prefix):
33743360
for (n, v) in func.inp
33753361
if isinstance(v, Expression)]
33763362

3377-
if gather_size_statistics:
3378-
ctx = StrOutput()
3379-
else:
3380-
ctx = nullcontext()
3381-
with ErrorContext(func.method), ctx:
3382-
if specializations:
3383-
out('/* %s\n' % func.get_name())
3384-
for (n, v) in specializations:
3385-
out(' %s = %s\n' % (n, v))
3386-
out('*/\n')
3363+
with allow_linemarks():
3364+
if gather_size_statistics:
3365+
ctx = StrOutput()
33873366
else:
3388-
out('/* %s */\n' % func.get_name())
3389-
3390-
start_function_definition(func.prototype)
3391-
som_linemark(func.method.astcode.site)
3392-
out('{\n', postindent = 1)
3393-
try:
3394-
code.toc_inline()
3395-
except DMLError as e:
3396-
report(e)
3397-
# Any errors should have been caught during
3398-
# codegen_method, when all Expression and Statement
3399-
# objects are instantiated.
3400-
raise ICE(e.site, 'error during late compile stage')
3401-
eom_linemark(func.method.rbrace_site)
3402-
out('}\n\n', preindent = -1)
3403-
reset_line_directive()
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())
3376+
3377+
start_function_definition(func.prototype)
3378+
som_linemark(func.method.astcode.site)
3379+
out('{\n', postindent = 1)
3380+
try:
3381+
code.toc_inline()
3382+
except DMLError as e:
3383+
report(e)
3384+
# Any errors should have been caught during
3385+
# codegen_method, when all Expression and Statement
3386+
# objects are instantiated.
3387+
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)
34043394
splitting_point()
34053395

3406-
if gather_size_statistics:
3407-
size_statistics.setdefault(func.method.site.loc(), []).append(
3408-
len(ctx.buf))
3409-
out(ctx.buf)
34103396

34113397
if gather_size_statistics:
34123398
Path(filename_prefix + "-size-stats.json").write_text(json.dumps(
@@ -3451,11 +3437,10 @@ def generate_cfile_body(device, footers, full_module, filename_prefix):
34513437
generate_index_enumerations()
34523438
generate_tuple_table()
34533439

3454-
for c in footers:
3455-
c.toc()
3456-
out('\n')
3457-
3458-
reset_line_directive()
3440+
with allow_linemarks():
3441+
for c in footers:
3442+
c.toc()
3443+
out('\n')
34593444

34603445
if full_module:
34613446
# caught as error earlier on

py/dml/codegen.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,8 +3481,8 @@ def codegen_inline_byname(node, indices, meth_name, inargs, outargs,
34813481
else:
34823482
meth_node = node
34833483

3484-
return codegen_inline(meth_node.site, meth_node, indices,
3485-
inargs, outargs, inhibit_copyin)
3484+
return codegen_inline(site, meth_node, indices, inargs, outargs,
3485+
inhibit_copyin)
34863486

34873487
intercepted_in_int_reg = {
34883488
'get_name': int_register.codegen_get_name,
@@ -3601,24 +3601,25 @@ def codegen_inline(site, meth_node, indices, inargs, outargs,
36013601
code = [codegen_statement(meth_node.astcode,
36023602
Location(meth_node, indices),
36033603
param_scope)]
3604-
if exit_handler.used:
3605-
code.append(mkLabel(site, exit_handler.label))
3606-
code.extend(copyout)
3607-
body = mkCompound(site, declarations(param_scope) + code)
3608-
return mkInlinedMethod(site, meth_node, body)
3604+
post = ([mkLabel(site, exit_handler.label)]
3605+
if exit_handler.used else [])
3606+
post.extend(copyout)
3607+
return mkInlinedMethod(site, meth_node, declarations(param_scope),
3608+
code, post)
36093609
else:
36103610
assert meth_node.astcode.kind == 'compound'
36113611
[subs] = meth_node.astcode.args
36123612
location = Location(meth_node, indices)
36133613
exit_handler = GotoExit_dml14(outargs)
36143614
with exit_handler:
36153615
code = codegen_statements(subs, location, param_scope)
3616-
if exit_handler.used:
3617-
code.append(mkLabel(site, exit_handler.label))
3618-
body = mkCompound(site, declarations(param_scope) + code)
3616+
decls = declarations(param_scope)
3617+
post = ([mkLabel(site, exit_handler.label)]
3618+
if exit_handler.used else [])
3619+
body = mkCompound(site, decls + code)
36193620
if meth_node.outp and body.control_flow().fallthrough:
36203621
report(ENORET(meth_node.astcode.site))
3621-
return mkInlinedMethod(site, meth_node, body)
3622+
return mkInlinedMethod(site, meth_node, decls, code, post)
36223623

36233624
def c_rettype(outp, throws):
36243625
if throws:
@@ -3885,8 +3886,8 @@ def prelude():
38853886
with fail_handler, exit_handler:
38863887
code.append(codegen_statement(ast, location, fnscope))
38873888
if exit_handler.used:
3888-
code.append(mkLabel(site, exit_handler.label))
3889-
code.append(codegen_return(site, outp, throws, [
3889+
code.append(mkLabel(rbrace_site, exit_handler.label))
3890+
code.append(codegen_return(rbrace_site, outp, throws, [
38903891
lookup_var(site, fnscope, varname) for (varname, _) in outp]))
38913892
to_return = mkCompound(site, code)
38923893
else:
@@ -3895,15 +3896,18 @@ def prelude():
38953896
assert ast.kind == 'compound'
38963897
[subs] = ast.args
38973898
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.
38983901
body = prelude()
38993902
body.extend(codegen_statements(subs, location, fnscope))
39003903
code = mkCompound(site, body)
39013904
if code.control_flow().fallthrough:
39023905
if outp:
39033906
report(ENORET(site))
39043907
else:
3905-
code = mkCompound(site, body + [codegen_exit(site,
3906-
[])])
3908+
code = mkCompound(site,
3909+
body + [codegen_exit(rbrace_site,
3910+
[])])
39073911
to_return = code
39083912
return to_return
39093913

0 commit comments

Comments
 (0)