Skip to content

Commit df4077e

Browse files
committed
Port of RAII's Expression.write/Initializer.assign_to revamp
1 parent 16b5aa9 commit df4077e

File tree

7 files changed

+223
-150
lines changed

7 files changed

+223
-150
lines changed

py/dml/c_backend.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,7 +1875,7 @@ def generate_init_data_objs(device):
18751875
start_function_definition(
18761876
'void _init_data_objs(%s *_dev)' % (crep.structtype(device),))
18771877
out('{\n', postindent = 1)
1878-
with crep.DeviceInstanceContext():
1878+
with crep.DeviceInstanceContext(), allow_linemarks():
18791879
for node in device.initdata:
18801880
# Usually, the initializer is constant, but we permit that it
18811881
# depends on index. When the initializer is constant, we use a loop
@@ -1897,37 +1897,39 @@ def generate_init_data_objs(device):
18971897
# mainly meant to capture EIDXVAR; for other errors, the error will
18981898
# normally re-appear when evaluating per instance
18991899
except DMLError:
1900-
with allow_linemarks():
1901-
for indices in node.all_indices():
1902-
index_exprs = tuple(mkIntegerLiteral(node.site, i)
1903-
for i in indices)
1904-
nref = mkNodeRef(node.site, node, index_exprs)
1905-
try:
1906-
init = eval_initializer(
1907-
node.site, node._type, node.astinit,
1908-
Location(node.parent, index_exprs),
1909-
global_scope, True)
1910-
except DMLError as e:
1911-
report(e)
1912-
else:
1913-
markers = ([('store_writes_const_field', 'FALSE')]
1914-
if deep_const(node._type) else [])
1915-
coverity_markers(markers, init.site)
1916-
init.assign_to(nref, node._type)
1900+
for indices in node.all_indices():
1901+
index_exprs = tuple(mkIntegerLiteral(node.site, i)
1902+
for i in indices)
1903+
nref = mkNodeRef(node.site, node, index_exprs)
1904+
try:
1905+
init = eval_initializer(
1906+
node.site, node._type, node.astinit,
1907+
Location(node.parent, index_exprs),
1908+
global_scope, True)
1909+
except DMLError as e:
1910+
report(e)
1911+
else:
1912+
markers = ([('store_writes_const_field', 'FALSE')]
1913+
if deep_const(node._type) else [])
1914+
coverity_markers(markers, init.site)
1915+
out(init.assign_to(nref.read(), node._type) + ';\n')
19171916
else:
19181917
index_exprs = ()
1918+
if node.dimensions:
1919+
reset_line_directive()
19191920
for (i, sz) in enumerate(node.dimsizes):
19201921
var = 'i%d' % (i,)
19211922
out(('for (int %s = 0; %s < %s; ++%s) {\n'
19221923
% (var, var, sz, var)),
19231924
postindent=1)
19241925
index_exprs += (mkLit(node.site, var, TInt(64, True)),)
19251926
nref = mkNodeRef(node.site, node, index_exprs)
1926-
with allow_linemarks():
1927-
markers = ([('store_writes_const_field', 'FALSE')]
1928-
if deep_const(node._type) else [])
1929-
coverity_markers(markers, init.site)
1930-
init.assign_to(nref, node._type)
1927+
markers = ([('store_writes_const_field', 'FALSE')]
1928+
if deep_const(node._type) else [])
1929+
coverity_markers(markers, init.site)
1930+
out(init.assign_to(nref.read(), node._type) + ';\n')
1931+
if node.dimensions:
1932+
reset_line_directive()
19311933
for _ in range(node.dimensions):
19321934
out('}\n', postindent=-1)
19331935
out('}\n\n', preindent = -1)

py/dml/codegen.py

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -719,9 +719,9 @@ def error_out_at_index(_i, exc, msg):
719719
site, val_expr, targets, error_out_at_index,
720720
f'deserialization of arguments to {self.method.name}')
721721
if self.args_type:
722-
ctree.mkAssignStatement(site, out_expr,
723-
ctree.ExpressionInitializer(
724-
tmp_out_ref)).toc()
722+
ctree.AssignStatement(site, out_expr,
723+
ctree.ExpressionInitializer(
724+
tmp_out_ref)).toc()
725725

726726
@property
727727
def args_type(self):
@@ -837,8 +837,8 @@ def error_out_at_index(_i, exc, msg):
837837
'deserialization of arguments to a send_now')
838838

839839

840-
ctree.mkAssignStatement(site, out_expr,
841-
ctree.ExpressionInitializer(tmp_out_ref)).toc()
840+
ctree.AssignStatement(site, out_expr,
841+
ctree.ExpressionInitializer(tmp_out_ref)).toc()
842842

843843
@property
844844
def args_type(self):
@@ -2122,8 +2122,8 @@ def make_static_var(site, location, static_sym_type, name, init=None,
21222122
with init_code:
21232123
if deep_const(static_sym_type):
21242124
coverity_marker('store_writes_const_field', 'FALSE')
2125-
init.assign_to(mkStaticVariable(site, static_sym),
2126-
static_sym_type)
2125+
out(init.assign_to(mkStaticVariable(site, static_sym).read(),
2126+
static_sym_type) + ';\n')
21272127
c_init = init_code.buf
21282128
else:
21292129
c_init = None
@@ -2345,7 +2345,6 @@ def stmt_assign(stmt, location, scope):
23452345
else:
23462346
method_tgts = tgts
23472347

2348-
# TODO support multiple assign sources. It should be generalized.
23492348
method_invocation = try_codegen_invocation(site, src_asts, method_tgts,
23502349
location, scope)
23512350
if method_invocation:
@@ -2361,19 +2360,26 @@ def stmt_assign(stmt, location, scope):
23612360
+ f'initializer: Expected {src_asts}, got 1'))
23622361
return []
23632362

2364-
stmts = []
23652363
lscope = Symtab(scope)
2364+
init_typ = tgts[-1].ctype()
23662365
init = eval_initializer(
2367-
site, tgts[-1].ctype(), src_asts[0], location, scope, False)
2368-
2369-
for (i, tgt) in enumerate(reversed(tgts[1:])):
2370-
name = 'tmp%d' % (i,)
2371-
sym = lscope.add_variable(
2372-
name, type=tgt.ctype(), site=tgt.site, init=init, stmt=True)
2373-
init = ExpressionInitializer(mkLocalVariable(tgt.site, sym))
2374-
stmts.extend([sym_declaration(sym),
2375-
mkAssignStatement(tgt.site, tgt, init)])
2376-
return stmts + [mkAssignStatement(tgts[0].site, tgts[0], init)]
2366+
tgts[-1].site, init_typ, src_asts[0], location, scope, False)
2367+
2368+
if len(tgts) == 1:
2369+
return [mkAssignStatement(tgts[0].site, tgts[0], init)]
2370+
2371+
sym = lscope.add_variable(
2372+
'tmp', type=init_typ, site=init.site, init=init,
2373+
stmt=True)
2374+
init_expr = mkLocalVariable(init.site, sym)
2375+
stmts = [sym_declaration(sym)]
2376+
for tgt in reversed(tgts[1:]):
2377+
stmts.append(mkCopyData(tgt.site, init_expr, tgt))
2378+
init_expr = (tgt if isinstance(tgt, NonValue)
2379+
else source_for_assignment(tgt.site, tgt.ctype(),
2380+
init_expr))
2381+
stmts.append(mkCopyData(tgts[0].site, init_expr, tgts[0]))
2382+
return [mkCompound(site, stmts)]
23772383
else:
23782384
# Guaranteed by grammar
23792385
assert tgt_ast.kind == 'assign_target_tuple' and len(tgts) > 1
@@ -2400,43 +2406,51 @@ def stmt_assign(stmt, location, scope):
24002406
stmt=True)
24012407
syms.append(sym)
24022408

2403-
stmts.extend(map(sym_declaration, syms))
2409+
stmts.extend(sym_declaration(sym) for sym in syms)
24042410
stmts.extend(
2405-
mkAssignStatement(
2406-
tgt.site, tgt, ExpressionInitializer(mkLocalVariable(tgt.site,
2407-
sym)))
2411+
AssignStatement(
2412+
tgt.site, tgt,
2413+
ExpressionInitializer(mkLocalVariable(tgt.site, sym)))
24082414
for (tgt, sym) in zip(tgts, syms))
2409-
return stmts
2415+
return [mkCompound(site, stmts)]
24102416

24112417
@statement_dispatcher
24122418
def stmt_assignop(stmt, location, scope):
2413-
(kind, site, tgt_ast, op, src_ast) = stmt
2419+
(_, site, tgt_ast, op, src_ast) = stmt
24142420

24152421
tgt = codegen_expression(tgt_ast, location, scope)
2416-
if deep_const(tgt.ctype()):
2422+
if isinstance(tgt, ctree.InlinedParam):
2423+
raise EASSINL(tgt.site, tgt.name)
2424+
if not tgt.writable:
2425+
raise EASSIGN(site, tgt)
2426+
2427+
ttype = tgt.ctype()
2428+
if deep_const(ttype):
24172429
raise ECONST(tgt.site)
2418-
if isinstance(tgt, ctree.BitSlice):
2419-
# destructive hack
2420-
return stmt_assign(
2421-
ast.assign(site, ast.assign_target_chain(site, [tgt_ast]),
2422-
[ast.initializer_scalar(
2423-
site,
2424-
ast.binop(site, tgt_ast, op[:-1], src_ast))]),
2425-
location, scope)
2430+
24262431
src = codegen_expression(src_ast, location, scope)
2427-
ttype = tgt.ctype()
2428-
lscope = Symtab(scope)
2429-
sym = lscope.add_variable(
2430-
'tmp', type = TPtr(ttype), site = tgt.site,
2431-
init = ExpressionInitializer(mkAddressOf(tgt.site, tgt)), stmt=True)
2432-
# Side-Effect Free representation of the tgt lvalue
2433-
tgt_sef = mkDereference(site, mkLocalVariable(tgt.site, sym))
2434-
return [
2435-
sym_declaration(sym), mkExpressionStatement(
2436-
site,
2437-
mkAssignOp(site, tgt_sef, arith_binops[op[:-1]](
2438-
site, tgt_sef, src)))]
24392432

2433+
if tgt.addressable and not isinstance(tgt, Variable):
2434+
lscope = Symtab(scope)
2435+
tmp_tgt_sym = lscope.add_variable(
2436+
'_tmp_tgt', type = TPtr(ttype), site = tgt.site,
2437+
init = ExpressionInitializer(mkAddressOf(tgt.site, tgt)),
2438+
stmt=True)
2439+
# Side-Effect Free representation of the tgt lvalue
2440+
tgt = mkDereference(site, mkLocalVariable(tgt.site, tmp_tgt_sym))
2441+
else:
2442+
# TODO Not ideal. This path is needed to deal with writable
2443+
# expressions that do not correspond to C lvalues; such as bit slices.
2444+
# The incurred repeated evaluation is painful.
2445+
tmp_tgt_sym = None
2446+
2447+
assign_src = source_for_assignment(site, ttype,
2448+
arith_binops[op[:-1]](site, tgt, src))
2449+
2450+
return [mkCompound(site,
2451+
([sym_declaration(tmp_tgt_sym)] if tmp_tgt_sym else [])
2452+
+ [mkExpressionStatement(site,
2453+
ctree.AssignOp(site, tgt, assign_src))])]
24402454
@statement_dispatcher
24412455
def stmt_expression(stmt, location, scope):
24422456
[expr] = stmt.args
@@ -3903,7 +3917,7 @@ def prelude():
39033917
param = mkDereference(site,
39043918
mkLit(site, name, TPtr(typ)))
39053919
fnscope.add(ExpressionSymbol(name, param, site))
3906-
code.append(mkAssignStatement(site, param, init))
3920+
code.append(AssignStatement(site, param, init))
39073921
else:
39083922
code = []
39093923

0 commit comments

Comments
 (0)