Skip to content

Commit 47dc243

Browse files
authored
[NB] introduce inlining of array constructors (#13035)
* [NB] introduce inlining of array constructors * [NB] fix inlining of record constructors - use correct equation and not auxiliary variable index - update how nesting is handled - dumping updates for equations * [NB] small fix
1 parent 1456d33 commit 47dc243

File tree

3 files changed

+129
-19
lines changed

3 files changed

+129
-19
lines changed

OMCompiler/Compiler/NBackEnd/Classes/NBEquation.mo

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,20 @@ public
157157
end if;
158158
end fromFrames;
159159

160+
function addFrames
161+
input output Iterator iter;
162+
input list<Frame> frames;
163+
protected
164+
list<ComponentRef> names1, names2;
165+
list<Expression> ranges1, ranges2;
166+
algorithm
167+
if not listEmpty(frames) then
168+
(names1, ranges1) := getFrames(iter);
169+
(names2, ranges2) := List.unzip(frames);
170+
iter := fromFrames(List.zip(listAppend(names1, names2), listAppend(ranges1, ranges2)));
171+
end if;
172+
end addFrames;
173+
160174
function getFrames
161175
input Iterator iter;
162176
output list<ComponentRef> names;
@@ -855,8 +869,12 @@ public
855869
protected
856870
Pointer<Variable> residualVar;
857871
algorithm
858-
residualVar := getResidualVar(eqn);
859-
name := BVariable.getVarName(residualVar);
872+
if isDummy(Pointer.access(eqn)) then
873+
name := ComponentRef.EMPTY();
874+
else
875+
residualVar := getResidualVar(eqn);
876+
name := BVariable.getVarName(residualVar);
877+
end if;
860878
end getEqnName;
861879

862880
function getResidualVar
@@ -3646,7 +3664,9 @@ public
36463664
new_eq := func(eq);
36473665
if not referenceEq(eq, new_eq) then
36483666
// Do not update the expandable array entry, but the pointer itself
3649-
if debug and UnorderedSet.contains(ComponentRef.toString(Equation.getEqnName(eq_ptr)), debug_eqns) and not Equation.equalName(Pointer.create(eq), Pointer.create(new_eq)) then
3667+
if debug and (UnorderedSet.contains(ComponentRef.toString(Equation.getEqnName(eq_ptr)), debug_eqns)
3668+
or UnorderedSet.contains(ComponentRef.toString(Equation.getEqnName(Pointer.create(new_eq))), debug_eqns))
3669+
and not Equation.equalName(Pointer.create(eq), Pointer.create(new_eq)) then
36503670
print("[debugFollowEquations] The equation:\n" + Equation.toString(eq) + "\nGets replaced by:\n" + Equation.toString(new_eq) + "\n");
36513671
end if;
36523672
Pointer.update(eq_ptr, new_eq);

OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBFunctionAlias.mo

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -190,21 +190,21 @@ protected
190190
function createName
191191
input Type ty;
192192
input Iterator iter;
193-
input Pointer<Integer> index;
193+
input Pointer<Integer> aux_index;
194194
input Boolean init;
195195
output ComponentRef name;
196196
protected
197197
Type new_ty = ty;
198198
algorithm
199199
if not Iterator.isEmpty(iter) then
200200
new_ty := Type.liftArrayRightList(ty, list(Dimension.fromInteger(i) for i in Iterator.sizes(iter)));
201-
(_, name) := BVariable.makeAuxVar(NBVariable.FUNCTION_STR, Pointer.access(index), new_ty, init);
201+
(_, name) := BVariable.makeAuxVar(NBVariable.FUNCTION_STR, Pointer.access(aux_index), new_ty, init);
202202
// add iterators to subscripts of auxilliary variable
203203
name := ComponentRef.mergeSubscripts(Iterator.normalizedSubscripts(iter), name, true, true);
204204
else
205-
(_, name) := BVariable.makeAuxVar(NBVariable.FUNCTION_STR, Pointer.access(index), new_ty, init);
205+
(_, name) := BVariable.makeAuxVar(NBVariable.FUNCTION_STR, Pointer.access(aux_index), new_ty, init);
206206
end if;
207-
Pointer.update(index, Pointer.access(index) + 1);
207+
Pointer.update(aux_index, Pointer.access(aux_index) + 1);
208208
end createName;
209209
end Call_Aux;
210210

@@ -220,8 +220,9 @@ protected
220220
extends Module.functionAliasInterface;
221221
protected
222222
UnorderedMap<Call_Id, Call_Aux> map = UnorderedMap.new<Call_Aux>(Call_Id.hash, Call_Id.isEqual);
223+
VariablePointers variables = VarData.getVariables(varData);
223224
UnorderedMap<BClock, ComponentRef> clock_map;
224-
Pointer<Integer> index = Pointer.create(1);
225+
Pointer<Integer> aux_index = Pointer.create(1);
225226
list<Pointer<Variable>> new_vars_disc = {}, new_vars_cont = {}, new_vars_init = {}, new_vars_recd = {}, new_vars_clck;
226227
list<Pointer<Equation>> new_eqns_disc = {}, new_eqns_cont = {}, new_eqns_init = {}, new_eqns_clck;
227228
list<tuple<Call_Id, Call_Aux>> debug_lst_sim, debug_lst_ini;
@@ -238,7 +239,8 @@ protected
238239

239240
case EqData.EQ_DATA_SIM() algorithm
240241
// first collect all new functions from simulation equations
241-
eqData.simulation := EquationPointers.map(eqData.simulation, function introduceFunctionAliasEquation(map = map, index = index, init = false));
242+
eqData.simulation := EquationPointers.map(eqData.simulation,
243+
function introduceFunctionAliasEquation(map = map, variables = variables, aux_index = aux_index, eqn_index = eqData.uniqueIndex, init = false));
242244

243245
// create new simulation variables and corresponding equations for the function alias
244246
for tpl in listReverse(UnorderedMap.toList(map)) loop
@@ -268,7 +270,8 @@ protected
268270
end if;
269271

270272
// afterwards collect all functions from initial equations
271-
eqData.initials := EquationPointers.map(eqData.initials, function introduceFunctionAliasEquation(map = map, index = index, init = true));
273+
eqData.initials := EquationPointers.map(eqData.initials,
274+
function introduceFunctionAliasEquation(map = map, variables = variables, aux_index = aux_index, eqn_index = eqData.uniqueIndex, init = true));
272275

273276
// create new initialization variables and corresponding equations for the function alias
274277
for tpl in listReverse(UnorderedMap.toList(map)) loop
@@ -328,26 +331,34 @@ protected
328331

329332
function introduceFunctionAliasEquation
330333
"creates auxilliary variables for all not inlineable function calls in the equation"
331-
input output Equation eq;
334+
input output Equation eqn;
332335
input UnorderedMap<Call_Id, Call_Aux> map;
333-
input Pointer<Integer> index;
336+
input VariablePointers variables;
337+
input Pointer<Integer> aux_index;
338+
input Pointer<Integer> eqn_index;
334339
input Boolean init;
335340
protected
336341
Iterator iter;
337342
Boolean stop;
338343
algorithm
339-
(iter, stop) := match eq
344+
// inline trivial array constructors first
345+
eqn := Inline.inlineArrayConstructorSingle(eqn, Iterator.EMPTY(), variables, eqn_index);
346+
347+
// get iterator and determine if it needs to be checked further
348+
(iter, stop) := match eqn
340349
local
341350
Equation body;
342-
case Equation.FOR_EQUATION(body = {body}) then (eq.iter, Equation.isWhenEquation(Pointer.create(body))
351+
case Equation.FOR_EQUATION(body = {body}) then (eqn.iter, Equation.isWhenEquation(Pointer.create(body))
343352
or Equation.isIfEquation(Pointer.create(body)));
344353
case Equation.WHEN_EQUATION() then (Iterator.EMPTY(), true);
345354
case Equation.IF_EQUATION() then (Iterator.EMPTY(), true);
346355
case Equation.ALGORITHM() then (Iterator.EMPTY(), true);
347356
else (Iterator.EMPTY(), false);
348357
end match;
358+
359+
// do the function alias replacement
349360
if not stop then
350-
eq := Equation.map(eq, function introduceFunctionAlias(map = map, index = index, iter = iter, init = init));
361+
eqn := Equation.map(eqn, function introduceFunctionAlias(map = map, aux_index = aux_index, iter = iter, init = init));
351362
end if;
352363
end introduceFunctionAliasEquation;
353364

@@ -357,7 +368,7 @@ protected
357368
ToDo: also exclude special functions der(), pre(), ..."
358369
input output Expression exp;
359370
input UnorderedMap<Call_Id, Call_Aux> map;
360-
input Pointer<Integer> index;
371+
input Pointer<Integer> aux_index;
361372
input Iterator iter;
362373
input Boolean init;
363374
algorithm
@@ -395,11 +406,11 @@ protected
395406
ty := Expression.typeOf(exp);
396407
new_exp := match ty
397408
case Type.TUPLE() algorithm
398-
names := list(Call_Aux.createName(sub_ty, new_iter, index, init) for sub_ty in ty.types);
409+
names := list(Call_Aux.createName(sub_ty, new_iter, aux_index, init) for sub_ty in ty.types);
399410
tpl_lst := list(if ComponentRef.size(cref, true) == 0 then Expression.fromCref(ComponentRef.WILD()) else Expression.fromCref(cref) for cref in names);
400411
then Expression.TUPLE(ty, tpl_lst);
401412
else algorithm
402-
name := Call_Aux.createName(ty, new_iter, index, init);
413+
name := Call_Aux.createName(ty, new_iter, aux_index, init);
403414
then Expression.fromCref(name);
404415
end match;
405416
end if;

OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBInline.mo

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ protected
5050
import Expression = NFExpression;
5151
import NFFunction.Function;
5252
import NFFlatten.FunctionTree;
53+
import InstNode = NFInstNode.InstNode;
5354
import Statement = NFStatement;
5455
import Subscript = NFSubscript;
5556
import Type = NFType;
@@ -169,6 +170,47 @@ public
169170
slices := list(Slice.SLICE(eqn, {}) for eqn in Pointer.access(record_eqns));
170171
end inlineRecordSliceEquation;
171172

173+
function inlineArrayConstructorSingle
174+
input output Equation eqn;
175+
input Iterator iter;
176+
input VariablePointers variables;
177+
input Pointer<Integer> index;
178+
input Pointer<list<Pointer<Equation>>> new_eqns = Pointer.create({});
179+
output Boolean changed;
180+
algorithm
181+
try
182+
(eqn, changed) := match eqn
183+
local
184+
Equation new_eqn, body;
185+
Expression lhs, rhs;
186+
Call call;
187+
188+
// CREF = {... for i in []} array constructor equation
189+
case Equation.ARRAY_EQUATION(lhs = lhs as Expression.CREF(), rhs = rhs as Expression.CALL(call = call as Call.TYPED_ARRAY_CONSTRUCTOR())) algorithm
190+
then (inlineArrayConstructor(eqn, lhs.cref, call.exp, call.iters, eqn.attr, iter, variables, new_eqns, index), true);
191+
192+
// {... for i in []} = CREF array constructor equation
193+
case Equation.ARRAY_EQUATION(lhs = lhs as Expression.CALL(call = call as Call.TYPED_ARRAY_CONSTRUCTOR()), rhs = rhs as Expression.CREF()) algorithm
194+
then (inlineArrayConstructor(eqn, rhs.cref, call.exp, call.iters, eqn.attr, iter, variables, new_eqns, index), true);
195+
196+
// apply on for-equation. assumed to be split up
197+
case Equation.FOR_EQUATION(body = {body}) algorithm
198+
(new_eqn, changed) := inlineArrayConstructorSingle(body, eqn.iter, variables, index, new_eqns);
199+
new_eqn := if changed then new_eqn else eqn;
200+
then (new_eqn, changed);
201+
202+
// nothing happens
203+
else (eqn, false);
204+
end match;
205+
// unpack the equation
206+
eqn := if Equation.isDummy(eqn) then Pointer.access(List.first(Pointer.access(new_eqns))) else eqn;
207+
else
208+
if Flags.isSet(Flags.FAILTRACE) then
209+
Error.addCompilerWarning("Failed to inline following equation:\n" + Equation.toString(eqn));
210+
end if;
211+
end try;
212+
end inlineArrayConstructorSingle;
213+
172214
protected
173215
function inline extends Module.inlineInterface;
174216
protected
@@ -238,7 +280,6 @@ protected
238280
end if;
239281
end inlineRecordsTuplesArrays;
240282

241-
protected
242283
function inlineRecordTupleArrayEquation
243284
input output Equation eqn;
244285
input Iterator iter;
@@ -252,6 +293,7 @@ protected
252293
local
253294
Equation new_eqn, body;
254295
Expression lhs, rhs;
296+
Call call;
255297
list<Expression> elements;
256298
Integer size;
257299

@@ -282,6 +324,14 @@ protected
282324
elements := list(NFExpression.applySubscripts({Subscript.INDEX(Expression.INTEGER(i))}, rhs) for i in 1:arrayLength(lhs.elements));
283325
then inlineArrayEquation(eqn, lhs.elements, listArray(elements), eqn.attr, iter, variables, new_eqns, index);
284326

327+
// CREF = {... for i in []} array constructor equation
328+
case Equation.ARRAY_EQUATION(lhs = lhs as Expression.CREF(), rhs = rhs as Expression.CALL(call = call as Call.TYPED_ARRAY_CONSTRUCTOR())) algorithm
329+
then inlineArrayConstructor(eqn, lhs.cref, call.exp, call.iters, eqn.attr, iter, variables, new_eqns, index);
330+
331+
// {... for i in []} = CREF array constructor equation
332+
case Equation.ARRAY_EQUATION(lhs = lhs as Expression.CALL(call = call as Call.TYPED_ARRAY_CONSTRUCTOR()), rhs = rhs as Expression.CREF()) algorithm
333+
then inlineArrayConstructor(eqn, rhs.cref, call.exp, call.iters, eqn.attr, iter, variables, new_eqns, index);
334+
285335
// apply on for-equation. assumed to be split up
286336
case Equation.FOR_EQUATION(body = {body}) algorithm
287337
new_eqn := inlineRecordTupleArrayEquation(body, eqn.iter, variables, new_eqns, index, inlineSimple);
@@ -393,6 +443,35 @@ protected
393443
eqn := Equation.DUMMY_EQUATION();
394444
end inlineArrayEquation;
395445

446+
function inlineArrayConstructor
447+
input output Equation eqn;
448+
input ComponentRef cref;
449+
input Expression rhs;
450+
input list<tuple<InstNode, Expression>> iters;
451+
input EquationAttributes attr;
452+
input Iterator iter;
453+
input VariablePointers variables;
454+
input Pointer<list<Pointer<Equation>>> new_eqns;
455+
input Pointer<Integer> index;
456+
protected
457+
list<tuple<ComponentRef, Expression>> frames
458+
= list((ComponentRef.makeIterator(Util.tuple21(tpl), Type.INTEGER()), Util.tuple22(tpl)) for tpl in iters);
459+
list<Subscript> subs;
460+
Expression cref_exp;
461+
list<Pointer<Equation>> eqns;
462+
algorithm
463+
if Flags.isSet(Flags.DUMPBACKENDINLINE) then
464+
print("[" + getInstanceName() + "] Inlining: " + Equation.toString(eqn) + "\n");
465+
end if;
466+
eqns := Pointer.access(new_eqns);
467+
// add the iterators to the cref
468+
subs := list(Subscript.INDEX(Expression.CREF(Type.INTEGER(), Util.tuple21(tpl))) for tpl in frames);
469+
cref_exp := Expression.fromCref(ComponentRef.mergeSubscripts(subs, cref, true));
470+
eqns := createInlinedEquation(eqns, cref_exp, rhs, attr, Iterator.addFrames(iter, frames), variables, index);
471+
Pointer.update(new_eqns, eqns);
472+
eqn := Equation.DUMMY_EQUATION();
473+
end inlineArrayConstructor;
474+
396475
function createInlinedEquation
397476
"used for inlining record, tuple and array equations.
398477
tries to create new equation from lhs and rhs and applying

0 commit comments

Comments
 (0)