Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
[NF] Optimize evaluation of for loops.
Browse files Browse the repository at this point in the history
- Replace for loop iterators with mutable expressions before starting to
  evaluate a function, so we don't have to do it each time a for loop is
  entered.

Belonging to [master]:
  - #2753
  • Loading branch information
perost authored and OpenModelica-Hudson committed Oct 31, 2018
1 parent 7e237d3 commit 9a92511
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 8 deletions.
43 changes: 35 additions & 8 deletions Compiler/NFFrontEnd/NFEvalFunction.mo
Expand Up @@ -131,6 +131,7 @@ algorithm
// bindings of the function parameters. But they probably need to be
// sorted by dependencies first.
fn_body := applyReplacements(repl, fn_body);
fn_body := optimizeBody(fn_body);
ctrl := evaluateStatements(fn_body);

if ctrl <> FlowControl.ASSERTION then
Expand Down Expand Up @@ -389,6 +390,39 @@ algorithm
end if;
end applyReplacementCref;

function optimizeBody
input output list<Statement> body;
algorithm
body := list(Statement.map(s, optimizeStatement) for s in body);
end optimizeBody;

function optimizeStatement
input output Statement stmt;
algorithm
() := match stmt
local
Expression iter_exp;

// Replace iterators in for loops with mutable expressions, so we don't need
// to do it each time we enter a for loop during evaluation.
case Statement.FOR()
algorithm
// Make a mutable expression with a placeholder value.
iter_exp := Expression.makeMutable(Expression.EMPTY(Type.UNKNOWN()));
// 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);
// Replace the iterator node with the mutable expression too.
stmt.iterator := InstNode.EXP_NODE(iter_exp);
then
();

else ();
end match;
end optimizeStatement;

function createResult
input ReplTree.Tree repl;
input list<InstNode> outputs;
Expand Down Expand Up @@ -679,14 +713,7 @@ algorithm
range_iter := RangeIterator.fromExp(range_exp);

if RangeIterator.hasNext(range_iter) then
// Replace the iterator with a mutable expression.
// TODO: If each iterator contained a mutable binding that we could update
// this wouldn't be necessary, but the handling of for loops needs to
// be fixed so we don't try to evaluate iterators when we shouldn't.
iter_exp := Mutable.create(Expression.INTEGER(0));
value := Expression.MUTABLE(iter_exp);
body := Statement.mapExpList(forBody,
function Expression.replaceIterator(iterator = iterator, iteratorValue = value));
InstNode.EXP_NODE(exp = Expression.MUTABLE(exp = iter_exp)) := iterator;

// Loop through each value in the iteration range.
while RangeIterator.hasNext(range_iter) loop
Expand Down
5 changes: 5 additions & 0 deletions Compiler/NFFrontEnd/NFInstNode.mo
Expand Up @@ -44,6 +44,7 @@ import Visibility = NFPrefixes.Visibility;
import NFModifier.Modifier;
import SCodeDump;
import DAE;
import Expression = NFExpression;

protected
import List;
Expand Down Expand Up @@ -245,6 +246,10 @@ uniontype InstNode
list<InstNode> locals;
end IMPLICIT_SCOPE;

record EXP_NODE
Expression exp;
end EXP_NODE;

record EMPTY_NODE end EMPTY_NODE;

function new
Expand Down
45 changes: 45 additions & 0 deletions Compiler/NFFrontEnd/NFStatement.mo
Expand Up @@ -196,11 +196,56 @@ public
end for;
then
();

else ();
end match;

func(stmt);
end apply;

function map
input output Statement stmt;
input MapFn func;

partial function MapFn
input output Statement stmt;
end MapFn;
algorithm
() := match stmt
case FOR()
algorithm
stmt.body := list(map(s, func) for s in stmt.body);
then
();

case IF()
algorithm
stmt.branches := list(
(Util.tuple21(b),
list(map(s, func) for s in Util.tuple22(b))) for b in stmt.branches);
then
();

case WHEN()
algorithm
stmt.branches := list(
(Util.tuple21(b),
list(map(s, func) for s in Util.tuple22(b))) for b in stmt.branches);
then
();

case WHILE()
algorithm
stmt.body := list(map(s, func) for s in stmt.body);
then
();

else ();
end match;

stmt := func(stmt);
end map;

function mapExpList
input output list<Statement> stmtl;
input MapFunc func;
Expand Down

0 comments on commit 9a92511

Please sign in to comment.