Skip to content

Commit

Permalink
Fix array constructor simplification (#11391)
Browse files Browse the repository at this point in the history
- The simplification of array constructors where the iterator was only
  used to subscript array expressions also triggered for expressions
  that didn't use the iterator at all, simplify the check to only check
  for e.g. `{1, 2, 3}[i]`.

Fixes #11385
  • Loading branch information
perost committed Oct 18, 2023
1 parent 37e61b7 commit dc60bd1
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 33 deletions.
15 changes: 0 additions & 15 deletions OMCompiler/Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -5788,21 +5788,6 @@ public
end match;
end mapSplitExpressions3;

function hasNonArrayIteratorSubscript
"Returns true if the given iterator is only used to subscript array
expression in the given expression, otherwise false."
input Expression exp;
input InstNode iterator;
output Boolean res;
algorithm
res := match exp
case CREF() then containsIterator(exp, iterator);
case SUBSCRIPTED_EXP() then not isArray(exp.exp) and
Subscript.listContainsExp(exp.subscripts, function containsIterator(iterator = iterator));
else containsShallow(exp, function hasNonArrayIteratorSubscript(iterator = iterator));
end match;
end hasNonArrayIteratorSubscript;

function mapCrefScalars
"Takes a cref expression and applies a function to each scalar cref,
creating a new expression with the same dimensions as the given cref.
Expand Down
17 changes: 15 additions & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo
Expand Up @@ -514,9 +514,9 @@ algorithm
exp := Expression.replaceIterator(exp, iter, e);
exp := Expression.makeArray(ty, listArray({exp}));
outExp := simplify(exp);
elseif Expression.isLiteral(e) and not Expression.hasNonArrayIteratorSubscript(exp, iter) then
elseif Expression.isLiteral(e) and isIteratorSubscriptedArray(exp, iter) then
// If the iterator is only used to subscript array expressions like
// {{1, 2, 3}[i] in i 1:3}, then we might as well expand it.
// {{1, 2, 3}[i] for i in 1:3}, then we might as well expand it.
(outExp, expanded) := ExpandExp.expandArrayConstructor(exp, ty, iters);

if expanded then
Expand All @@ -537,6 +537,19 @@ algorithm
end matchcontinue;
end simplifyArrayConstructor;

function isIteratorSubscriptedArray
input Expression exp;
input InstNode iterator;
output Boolean res;
algorithm
res := match exp
case Expression.SUBSCRIPTED_EXP()
then Expression.isArray(exp.exp) and
List.all(exp.subscripts, function Subscript.equalsIterator(iterator = iterator));
else false;
end match;
end isIteratorSubscriptedArray;

function simplifyReduction
input Call call;
output Expression outExp;
Expand Down
Expand Up @@ -10,18 +10,21 @@ end R;

model ArrayConstructorRecord1
parameter R r[3](x = {1, 2, 3});
Real x[:] = {i.x for i in r};
parameter Real x[:] = {i.x for i in r};
end ArrayConstructorRecord1;

// Result:
// function R "Automatically generated record constructor for R"
// input Real x;
// output R res;
// end R;
//
// class ArrayConstructorRecord1
// parameter Real r[1].x = 1.0;
// parameter Real r[2].x = 2.0;
// parameter Real r[3].x = 3.0;
// Real x[1];
// Real x[2];
// Real x[3];
// equation
// x = {1.0, 2.0, 3.0};
// parameter Real x[1] = 1.0;
// parameter Real x[2] = 2.0;
// parameter Real x[3] = 3.0;
// end ArrayConstructorRecord1;
// endResult
Expand Up @@ -10,18 +10,21 @@ end R;

model ArrayConstructorRecord2
parameter R r[3];
Real x[:] = {i.x for i in r};
parameter Real x[:] = {i.x for i in r};
end ArrayConstructorRecord2;

// Result:
// function R "Automatically generated record constructor for R"
// input Real x = 1.0;
// output R res;
// end R;
//
// class ArrayConstructorRecord2
// parameter Real r[1].x = 1.0;
// parameter Real r[2].x = 1.0;
// parameter Real r[3].x = 1.0;
// Real x[1];
// Real x[2];
// Real x[3];
// equation
// x = {1.0, 1.0, 1.0};
// parameter Real x[1] = 1.0;
// parameter Real x[2] = 1.0;
// parameter Real x[3] = 1.0;
// end ArrayConstructorRecord2;
// endResult
18 changes: 18 additions & 0 deletions testsuite/flattening/modelica/scodeinst/BuiltinAttribute23.mo
@@ -0,0 +1,18 @@
// name: BuiltinAttribute23
// keywords:
// status: correct
// cflags: -d=newInst --newBackend
//

model BuiltinAttribute23
parameter Real x0;
type T = Real[3] (each start = x0);
T t;
end BuiltinAttribute23;

// Result:
// class BuiltinAttribute23
// parameter Real x0;
// Real[3] t(start = array(x0 for $t1 in 1:3));
// end BuiltinAttribute23;
// endResult
9 changes: 6 additions & 3 deletions testsuite/flattening/modelica/scodeinst/FuncVectorization3.mo
Expand Up @@ -18,13 +18,16 @@ end FuncVectorization3;


// Result:
// function FuncVectorization3.f
// input Real x;
// output Real y = x;
// end FuncVectorization3.f;
//
// class FuncVectorization3
// Real x[1];
// Real x[2];
// Real x[3];
// equation
// x[1] = 1.0;
// x[2] = 2.0;
// x[3] = 3.0;
// x = array(FuncVectorization3.f({1.0, 2.0, 3.0}[$i1]) for $i1 in 1:3);
// end FuncVectorization3;
// endResult
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -83,6 +83,7 @@ BuiltinAttribute19.mo \
BuiltinAttribute20.mo \
BuiltinAttribute21.mo \
BuiltinAttribute22.mo \
BuiltinAttribute23.mo \
BuiltinLookup1.mo \
BuiltinTime.mo \
BuiltinTimeSubscripted.mo \
Expand Down
2 changes: 1 addition & 1 deletion testsuite/flattening/modelica/scodeinst/OCGTests.mos
Expand Up @@ -190,7 +190,7 @@ checkModel(PowerSystems.Examples.AC3ph.Inverters.Rectifier); getErrorString();
// ""
// "Check of Modelica.Mechanics.MultiBody.Examples.Loops.PlanarLoops_analytic completed successfully.
// Class Modelica.Mechanics.MultiBody.Examples.Loops.PlanarLoops_analytic has 4009 equation(s) and 4009 variable(s).
// 3052 of these are trivial equation(s)."
// 3034 of these are trivial equation(s)."
// ""
// "Check of Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects.ActuatedDrive completed successfully.
// Class Modelica.Mechanics.MultiBody.Examples.Rotational3DEffects.ActuatedDrive has 1525 equation(s) and 1525 variable(s).
Expand Down

0 comments on commit dc60bd1

Please sign in to comment.