Skip to content

Commit

Permalink
Improve sorting of local function variables (#8218)
Browse files Browse the repository at this point in the history
- Take the modifiers on local record instances into account too when
  computing the dependencies between local function variables.

Fixes thorade/HelmholtzMedia#48
  • Loading branch information
perost committed Nov 24, 2021
1 parent f6468ae commit e920dc2
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
37 changes: 28 additions & 9 deletions OMCompiler/Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -2475,26 +2475,45 @@ protected
input UnorderedSet<InstNode> locals;
output list<InstNode> dependencies;
protected
Component comp;
Binding binding;
UnorderedSet<InstNode> deps;
algorithm
// Use a set to store the dependencies to avoid duplicates.
deps := UnorderedSet.new(InstNode.hash, InstNode.refEqual, 1);
deps := getLocalDependencies2(node, locals, deps);

comp := InstNode.component(node);
binding := Component.getBinding(comp);

if Binding.hasExp(binding) then
deps := getLocalDependenciesExp(Binding.getExp(binding), locals, deps);
end if;
// If we have a record instance with fields that have bindings that refer to
// other fields we'll get a dependency on the record instance itself here.
// But that's actually fine, so remove it to avoid a false cycle being detected.
UnorderedSet.remove(node, deps);

deps := Type.foldDims(Component.getType(comp),
deps := Type.foldDims(InstNode.getType(node),
function getLocalDependenciesDim(locals = locals), deps);

dependencies := UnorderedSet.toList(deps);
end getLocalDependencies;

function getLocalDependencies2
input InstNode node;
input UnorderedSet<InstNode> locals;
input output UnorderedSet<InstNode> dependencies;
protected
Component comp;
Binding binding;
algorithm
comp := InstNode.component(node);
binding := Component.getBinding(comp);

if Binding.hasExp(binding) then
dependencies := getLocalDependenciesExp(Binding.getExp(binding), locals, dependencies);
elseif Type.isRecord(Component.getType(comp)) then
// If the component is a record instance without a binding, check the
// bindings on the record fields instead.
dependencies := ClassTree.foldComponents(
Class.classTree(InstNode.getClass(node)),
function getLocalDependencies2(locals = locals), dependencies);
end if;
end getLocalDependencies2;

function getLocalDependenciesExp
input Expression exp;
input UnorderedSet<InstNode> locals;
Expand Down
43 changes: 43 additions & 0 deletions testsuite/flattening/modelica/scodeinst/FunctionCompOrder4.mo
@@ -0,0 +1,43 @@
// name: FunctionCompOrder4
// keywords:
// status: correct
// cflags: -d=newInst
//

record R
Real x;
end R;

function f
input Real x;
output Real y;
protected
R r(x = lx);
Real lx = x;
algorithm
y := r.x;
end f;

model FunctionCompOrder4
Real x = f(time);
end FunctionCompOrder4;

// Result:
// function R "Automatically generated record constructor for R"
// input Real x;
// output R res;
// end R;
//
// function f
// input Real x;
// output Real y;
// protected Real lx = x;
// protected R r;
// algorithm
// y := r.x;
// end f;
//
// class FunctionCompOrder4
// Real x = f(time);
// end FunctionCompOrder4;
// endResult
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -584,6 +584,7 @@ FunctionalArgInvalidType1.mo \
FunctionCompOrder1.mo \
FunctionCompOrder2.mo \
FunctionCompOrder3.mo \
FunctionCompOrder4.mo \
FunctionDerivative1.mo \
FunctionDerivativeInvalidInput1.mo \
FunctionDerivativeInvalidOrder1.mo \
Expand Down

0 comments on commit e920dc2

Please sign in to comment.