Skip to content

Commit

Permalink
Simplify for-statements more (#8117)
Browse files Browse the repository at this point in the history
- Unroll for-statements where the iteration range consists of only one
  value (like `for i in 1:1 loop`).
- Add Equation/Statement.replaceIteratorList to simplify the code.
  • Loading branch information
perost committed Nov 12, 2021
1 parent 3dba97e commit 2baf5e9
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 34 deletions.
14 changes: 2 additions & 12 deletions OMCompiler/Compiler/NFFrontEnd/NFArrayConnections.mo
Expand Up @@ -253,7 +253,7 @@ protected
case Equation.FOR(range = SOME(range))
algorithm
range := Ceval.evalExp(range, Ceval.EvalTarget.RANGE(Equation.info(eq)));
body := applyIterator(eq.iterator, range, eq.body);
body := Equation.replaceIteratorList(eq.body, eq.iterator, range);
nmvTable := addConnectionsToGraph(body, graph, vCount, eCount, nmvTable);
then
();
Expand All @@ -268,15 +268,6 @@ protected
end for;
end addConnectionsToGraph;

function applyIterator
input InstNode iterator;
input Expression range;
input output list<Equation> body;
algorithm
body := Equation.mapExpList(body,
function Expression.replaceIterator(iterator = iterator, iteratorValue = range));
end applyIterator;

function createConnection
input Expression lhs;
input Expression rhs;
Expand Down Expand Up @@ -929,8 +920,7 @@ protected
// Scalar range means the interval had the same lower and upper bound,
// in which case the iterator can be replaced with the scalar expression
// instead of creating an unnecessary for loop here.
body := Equation.mapExpList(body,
function Expression.replaceIterator(iterator = iterators[i], iteratorValue = ranges[i]));
body := Equation.replaceIteratorList(body, iterators[i], ranges[i]);
else
body := {Equation.FOR(iterators[i], SOME(ranges[i]), body, DAE.emptyElementSource)};
end if;
Expand Down
9 changes: 9 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFEquation.mo
Expand Up @@ -899,6 +899,15 @@ public
res := false;
end containsExpList;

function replaceIteratorList
input output list<Equation> eql;
input InstNode iterator;
input Expression value;
algorithm
eql := mapExpList(eql,
function Expression.replaceIterator(iterator = iterator, iteratorValue = value));
end replaceIteratorList;

function isConnect
input Equation eq;
output Boolean isConnect;
Expand Down
5 changes: 1 addition & 4 deletions OMCompiler/Compiler/NFFrontEnd/NFEvalFunction.mo
Expand Up @@ -483,10 +483,7 @@ algorithm
// Make a mutable expression with a placeholder value.
iter_exp := Expression.makeMutable(Expression.EMPTY(InstNode.getType(stmt.iterator)));
// Replace the iterator with the expression in the body of the for loop.
stmt.body := list(
Statement.mapExp(s, function Expression.replaceIterator(
iterator = stmt.iterator, iteratorValue = iter_exp))
for s in stmt.body);
stmt.body := Statement.replaceIteratorList(stmt.body, stmt.iterator, iter_exp);
// Replace the iterator node with the mutable expression too.
stmt.iterator := InstNode.EXP_NODE(iter_exp);
then
Expand Down
3 changes: 1 addition & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -1400,8 +1400,7 @@ algorithm

while RangeIterator.hasNext(range_iter) loop
(range_iter, val) := RangeIterator.next(range_iter);
unrolled_body := Equation.mapExpList(body,
function Expression.replaceIterator(iterator = iter, iteratorValue = val));
unrolled_body := Equation.replaceIteratorList(body, iter, val);
unrolled_body := flattenEquations(unrolled_body, prefix, settings);
equations := listAppend(unrolled_body, equations);
end while;
Expand Down
35 changes: 19 additions & 16 deletions OMCompiler/Compiler/NFFrontEnd/NFSimplifyModel.mo
Expand Up @@ -164,19 +164,24 @@ algorithm
body := simplifyEquations(eq.body);

if not Equation.containsExpList(body, function Expression.containsIterator(iterator = eq.iterator)) then
// Remove the surrounding loop if the equations inside aren't using the iterator.
equations := List.append_reverse(body, equations);
else
// TODO: This causes issues with the -nfScalarize tests for some reason.
// TODO: This causes issues with the -nfScalarize tests for some
// reason, which is the only case this applies to since we
// normally unroll for loops and never get here.
//dim := Type.nthDimension(Expression.typeOf(e), 1);

//if Dimension.isOne(dim) then
// // Unroll the loop if the iteration range consists of only one value.
// e := Expression.applySubscript(Subscript.INDEX(Expression.INTEGER(1)), e);

// body := Equation.mapExpList(body,
// function Expression.replaceIterator(iterator = eq.iterator, iteratorValue = e));
// e := SimplifyExp.simplify(e);
// body := Equation.replaceIteratorList(body, eq.iterator, e);
// body := simplifyEquations(body);
// equations := List.append_reverse(body, equations);
//elseif not Dimension.isZero(dim) then
//if not Dimension.isZero(dim) then
// Otherwise just simplify if the iteration range is not empty.
eq.range := SimplifyExp.simplifyOpt(eq.range);
eq.body := body;
equations := eq :: equations;
Expand Down Expand Up @@ -297,25 +302,23 @@ algorithm
statements := match stmt
local
Expression e, lhs, rhs;
Type ty;
Dimension dim;
list<Statement> body;

case Statement.ASSIGNMENT() then simplifyAssignment(stmt, statements);

case Statement.FOR(range = SOME(e))
algorithm
ty := Expression.typeOf(e);
dim := Type.nthDimension(ty, 1);

//if Dimension.isOne(dim) then
// e := Expression.applySubscript(Subscript.INDEX(Expression.INTEGER(1)), e);
// body := Statement.mapExpList(stmt.body,
// function Expression.replaceIterator(iterator = stmt.iterator, iteratorValue = e));
// body := simplifyStatements(body);
// statements := listAppend(listReverse(body), statements);
//elseif not Dimension.isZero(dim) then
if not Dimension.isZero(dim) then
dim := Type.nthDimension(Expression.typeOf(e), 1);

if Dimension.isOne(dim) then
// Unroll the loop if the iteration range consists of only one value.
e := Expression.applySubscript(Subscript.INDEX(Expression.INTEGER(1)), e);
body := Statement.replaceIteratorList(stmt.body, stmt.iterator, e);
body := simplifyStatements(body);
statements := listAppend(listReverse(body), statements);
elseif not Dimension.isZero(dim) then
// Otherwise just simplify if the iteration range is not empty.
stmt.range := SOME(SimplifyExp.simplify(e));
stmt.body := simplifyStatements(stmt.body);
statements := stmt :: statements;
Expand Down
9 changes: 9 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFStatement.mo
Expand Up @@ -517,6 +517,15 @@ public
end match;
end foldExp;

function replaceIteratorList
input output list<Statement> stmtl;
input InstNode iterator;
input Expression value;
algorithm
stmtl := mapExpList(stmtl,
function Expression.replaceIterator(iterator = iterator, iteratorValue = value));
end replaceIteratorList;

function toString
input Statement stmt;
input String indent = "";
Expand Down
26 changes: 26 additions & 0 deletions testsuite/flattening/modelica/scodeinst/ForStatement3.mo
@@ -0,0 +1,26 @@
// name: ForStatement3
// keywords:
// status: correct
// cflags: -d=newInst
//
//

model ForStatement3
Real x[5];
algorithm
for i in 2:2 loop
x[i] := time;
end for;
end ForStatement3;

// Result:
// class ForStatement3
// Real x[1];
// Real x[2];
// Real x[3];
// Real x[4];
// Real x[5];
// algorithm
// x[2] := time;
// end ForStatement3;
// endResult
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -468,6 +468,7 @@ ForEquationNonParam.mo \
ForEquationShadow1.mo \
ForStatement1.mo \
ForStatement2.mo \
ForStatement3.mo \
ForStatementArray.mo \
ForStatementNonVector.mo \
ForStatementPrefix.mo \
Expand Down

0 comments on commit 2baf5e9

Please sign in to comment.