Skip to content

Commit 480dbcf

Browse files
committed
Port of RAII's Expression.write/Initializer.assign_to revamp
1 parent 6a22da5 commit 480dbcf

File tree

7 files changed

+224
-150
lines changed

7 files changed

+224
-150
lines changed

py/dml/c_backend.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,7 @@ def generate_init_data_objs(device):
18371837
start_function_definition(
18381838
'void _init_data_objs(%s *_dev)' % (crep.structtype(device),))
18391839
out('{\n', postindent = 1)
1840-
with crep.DeviceInstanceContext():
1840+
with crep.DeviceInstanceContext(), allow_linemarks():
18411841
for node in device.initdata:
18421842
# Usually, the initializer is constant, but we permit that it
18431843
# depends on index. When the initializer is constant, we use a loop
@@ -1859,37 +1859,39 @@ def generate_init_data_objs(device):
18591859
# mainly meant to capture EIDXVAR; for other errors, the error will
18601860
# normally re-appear when evaluating per instance
18611861
except DMLError:
1862-
with allow_linemarks():
1863-
for indices in node.all_indices():
1864-
index_exprs = tuple(mkIntegerLiteral(node.site, i)
1865-
for i in indices)
1866-
nref = mkNodeRef(node.site, node, index_exprs)
1867-
try:
1868-
init = eval_initializer(
1869-
node.site, node._type, node.astinit,
1870-
Location(node.parent, index_exprs),
1871-
global_scope, True)
1872-
except DMLError as e:
1873-
report(e)
1874-
else:
1875-
markers = ([('store_writes_const_field', 'FALSE')]
1876-
if deep_const(node._type) else [])
1877-
coverity_markers(markers, init.site)
1878-
init.assign_to(nref, node._type)
1862+
for indices in node.all_indices():
1863+
index_exprs = tuple(mkIntegerLiteral(node.site, i)
1864+
for i in indices)
1865+
nref = mkNodeRef(node.site, node, index_exprs)
1866+
try:
1867+
init = eval_initializer(
1868+
node.site, node._type, node.astinit,
1869+
Location(node.parent, index_exprs),
1870+
global_scope, True)
1871+
except DMLError as e:
1872+
report(e)
1873+
else:
1874+
markers = ([('store_writes_const_field', 'FALSE')]
1875+
if deep_const(node._type) else [])
1876+
coverity_markers(markers, init.site)
1877+
out(init.assign_to(nref.read(), node._type) + ';\n')
18791878
else:
18801879
index_exprs = ()
1880+
if node.dimensions:
1881+
reset_line_directive()
18811882
for (i, sz) in enumerate(node.dimsizes):
18821883
var = 'i%d' % (i,)
18831884
out(('for (int %s = 0; %s < %s; ++%s) {\n'
18841885
% (var, var, sz, var)),
18851886
postindent=1)
18861887
index_exprs += (mkLit(node.site, var, TInt(64, True)),)
18871888
nref = mkNodeRef(node.site, node, index_exprs)
1888-
with allow_linemarks():
1889-
markers = ([('store_writes_const_field', 'FALSE')]
1890-
if deep_const(node._type) else [])
1891-
coverity_markers(markers, init.site)
1892-
init.assign_to(nref, node._type)
1889+
markers = ([('store_writes_const_field', 'FALSE')]
1890+
if deep_const(node._type) else [])
1891+
coverity_markers(markers, init.site)
1892+
out(init.assign_to(nref.read(), node._type) + ';\n')
1893+
if node.dimensions:
1894+
reset_line_directive()
18931895
for _ in range(node.dimensions):
18941896
out('}\n', postindent=-1)
18951897
out('}\n\n', preindent = -1)

py/dml/codegen.py

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -704,9 +704,9 @@ def error_out_at_index(_i, exc, msg):
704704
site, val_expr, targets, error_out_at_index,
705705
f'deserialization of arguments to {self.method.name}')
706706
if self.args_type:
707-
ctree.mkAssignStatement(site, out_expr,
708-
ctree.ExpressionInitializer(
709-
tmp_out_ref)).toc()
707+
ctree.AssignStatement(site, out_expr,
708+
ctree.ExpressionInitializer(
709+
tmp_out_ref)).toc()
710710

711711
@property
712712
def args_type(self):
@@ -822,8 +822,8 @@ def error_out_at_index(_i, exc, msg):
822822
'deserialization of arguments to a send_now')
823823

824824

825-
ctree.mkAssignStatement(site, out_expr,
826-
ctree.ExpressionInitializer(tmp_out_ref)).toc()
825+
ctree.AssignStatement(site, out_expr,
826+
ctree.ExpressionInitializer(tmp_out_ref)).toc()
827827

828828
@property
829829
def args_type(self):
@@ -2132,8 +2132,8 @@ def make_static_var(site, location, static_sym_type, name, init=None,
21322132
with init_code:
21332133
if deep_const(static_sym_type):
21342134
coverity_marker('store_writes_const_field', 'FALSE')
2135-
init.assign_to(mkStaticVariable(site, static_sym),
2136-
static_sym_type)
2135+
out(init.assign_to(mkStaticVariable(site, static_sym).read(),
2136+
static_sym_type) + ';\n')
21372137
c_init = init_code.buf
21382138
else:
21392139
c_init = None
@@ -2355,7 +2355,6 @@ def stmt_assign(stmt, location, scope):
23552355
else:
23562356
method_tgts = tgts
23572357

2358-
# TODO support multiple assign sources. It should be generalized.
23592358
method_invocation = try_codegen_invocation(site, src_asts, method_tgts,
23602359
location, scope)
23612360
if method_invocation:
@@ -2371,19 +2370,26 @@ def stmt_assign(stmt, location, scope):
23712370
+ f'initializer: Expected {src_asts}, got 1'))
23722371
return []
23732372

2374-
stmts = []
23752373
lscope = Symtab(scope)
2374+
init_typ = tgts[-1].ctype()
23762375
init = eval_initializer(
2377-
site, tgts[-1].ctype(), src_asts[0], location, scope, False)
2378-
2379-
for (i, tgt) in enumerate(reversed(tgts[1:])):
2380-
name = 'tmp%d' % (i,)
2381-
sym = lscope.add_variable(
2382-
name, type=tgt.ctype(), site=tgt.site, init=init, stmt=True)
2383-
init = ExpressionInitializer(mkLocalVariable(tgt.site, sym))
2384-
stmts.extend([sym_declaration(sym),
2385-
mkAssignStatement(tgt.site, tgt, init)])
2386-
return stmts + [mkAssignStatement(tgts[0].site, tgts[0], init)]
2376+
tgts[-1].site, init_typ, src_asts[0], location, scope, False)
2377+
2378+
if len(tgts) == 1:
2379+
return [mkAssignStatement(tgts[0].site, tgts[0], init)]
2380+
2381+
sym = lscope.add_variable(
2382+
'tmp', type=init_typ, site=init.site, init=init,
2383+
stmt=True)
2384+
init_expr = mkLocalVariable(init.site, sym)
2385+
stmts = [sym_declaration(sym)]
2386+
for tgt in reversed(tgts[1:]):
2387+
stmts.append(mkCopyData(tgt.site, init_expr, tgt))
2388+
init_expr = (tgt if isinstance(tgt, NonValue)
2389+
else source_for_assignment(tgt.site, tgt.ctype(),
2390+
init_expr))
2391+
stmts.append(mkCopyData(tgts[0].site, init_expr, tgts[0]))
2392+
return [mkCompound(site, stmts)]
23872393
else:
23882394
# Guaranteed by grammar
23892395
assert tgt_ast.kind == 'assign_target_tuple' and len(tgts) > 1
@@ -2410,43 +2416,51 @@ def stmt_assign(stmt, location, scope):
24102416
stmt=True)
24112417
syms.append(sym)
24122418

2413-
stmts.extend(map(sym_declaration, syms))
2419+
stmts.extend(sym_declaration(sym) for sym in syms)
24142420
stmts.extend(
2415-
mkAssignStatement(
2416-
tgt.site, tgt, ExpressionInitializer(mkLocalVariable(tgt.site,
2417-
sym)))
2421+
AssignStatement(
2422+
tgt.site, tgt,
2423+
ExpressionInitializer(mkLocalVariable(tgt.site, sym)))
24182424
for (tgt, sym) in zip(tgts, syms))
2419-
return stmts
2425+
return [mkCompound(site, stmts)]
24202426

24212427
@statement_dispatcher
24222428
def stmt_assignop(stmt, location, scope):
2423-
(kind, site, tgt_ast, op, src_ast) = stmt
2429+
(_, site, tgt_ast, op, src_ast) = stmt
24242430

24252431
tgt = codegen_expression(tgt_ast, location, scope)
2426-
if deep_const(tgt.ctype()):
2432+
if isinstance(tgt, ctree.InlinedParam):
2433+
raise EASSINL(tgt.site, tgt.name)
2434+
if not tgt.writable:
2435+
raise EASSIGN(site, tgt)
2436+
2437+
ttype = tgt.ctype()
2438+
if deep_const(ttype):
24272439
raise ECONST(tgt.site)
2428-
if isinstance(tgt, ctree.BitSlice):
2429-
# destructive hack
2430-
return stmt_assign(
2431-
ast.assign(site, ast.assign_target_chain(site, [tgt_ast]),
2432-
[ast.initializer_scalar(
2433-
site,
2434-
ast.binop(site, tgt_ast, op[:-1], src_ast))]),
2435-
location, scope)
2440+
24362441
src = codegen_expression(src_ast, location, scope)
2437-
ttype = tgt.ctype()
2438-
lscope = Symtab(scope)
2439-
sym = lscope.add_variable(
2440-
'tmp', type = TPtr(ttype), site = tgt.site,
2441-
init = ExpressionInitializer(mkAddressOf(tgt.site, tgt)), stmt=True)
2442-
# Side-Effect Free representation of the tgt lvalue
2443-
tgt_sef = mkDereference(site, mkLocalVariable(tgt.site, sym))
2444-
return [
2445-
sym_declaration(sym), mkExpressionStatement(
2446-
site,
2447-
mkAssignOp(site, tgt_sef, arith_binops[op[:-1]](
2448-
site, tgt_sef, src)))]
24492442

2443+
if tgt.addressable:
2444+
lscope = Symtab(scope)
2445+
tmp_tgt_sym = lscope.add_variable(
2446+
'_tmp_tgt', type = TPtr(ttype), site = tgt.site,
2447+
init = ExpressionInitializer(mkAddressOf(tgt.site, tgt)),
2448+
stmt=True)
2449+
# Side-Effect Free representation of the tgt lvalue
2450+
tgt = mkDereference(site, mkLocalVariable(tgt.site, tmp_tgt_sym))
2451+
else:
2452+
# TODO Not ideal. This path is needed to deal with writable
2453+
# expressions that do not correspond to C lvalues; such as bit slices.
2454+
# The incurred repeated evaluation is painful.
2455+
tmp_tgt_sym = None
2456+
2457+
assign_src = source_for_assignment(site, ttype,
2458+
arith_binops[op[:-1]](site, tgt, src))
2459+
2460+
return [mkCompound(site,
2461+
([sym_declaration(tmp_tgt_sym)] if tmp_tgt_sym else [])
2462+
+ [mkExpressionStatement(site,
2463+
ctree.AssignOp(site, tgt, assign_src))])]
24502464
@statement_dispatcher
24512465
def stmt_expression(stmt, location, scope):
24522466
[expr] = stmt.args
@@ -3886,7 +3900,7 @@ def prelude():
38863900
param = mkDereference(site,
38873901
mkLit(site, name, TPtr(typ)))
38883902
fnscope.add(ExpressionSymbol(name, param, site))
3889-
code.append(mkAssignStatement(site, param, init))
3903+
code.append(AssignStatement(site, param, init))
38903904
else:
38913905
code = []
38923906

0 commit comments

Comments
 (0)