Skip to content

Commit

Permalink
Improve handling of package constants
Browse files Browse the repository at this point in the history
- Try to fetch the binding of a package constant from its parent if it
  doesn't have a binding and is a record field.
- Add case for cref in Expression.nthRecordElement that returns a new
  cref instead of a record element expression.
- Disable collection of package constants in functions, since it doesn't
  work properly anyway.
- Move collection of package constants before collection of functions,
  so that function in package constants are also collected.
  • Loading branch information
perost committed Jan 14, 2021
1 parent 7cd9aa3 commit 63e15e6
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 20 deletions.
7 changes: 7 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -4478,6 +4478,13 @@ public

case RECORD() then listGet(recordExp.elements, index);

case CREF()
algorithm
Type.COMPLEX(cls = node) := Type.arrayElementType(typeOf(recordExp));
node := Class.nthComponent(index, InstNode.getClass(node));
then
fromCref(ComponentRef.prefixCref(node, InstNode.getType(node), {}, recordExp.cref));

case ARRAY(elements = {}, ty = Type.ARRAY(elementType = Type.COMPLEX(cls = node)))
then makeEmptyArray(InstNode.getType(Class.nthComponent(index, InstNode.getClass(node))));

Expand Down
8 changes: 4 additions & 4 deletions OMCompiler/Compiler/NFFrontEnd/NFInst.mo
Expand Up @@ -174,13 +174,13 @@ algorithm
// Apply simplifications to the model.
flatModel := SimplifyModel.simplify(flatModel);

// Collect a tree of all functions that are still used in the flat model.
functions := Flatten.collectFunctions(flatModel);

// Collect package constants that couldn't be substituted with their values
// (e.g. because they where used with non-constant subscripts), and add them
// to the model.
flatModel := Package.collectConstants(flatModel, functions);
flatModel := Package.collectConstants(flatModel);

// Collect a tree of all functions that are still used in the flat model.
functions := Flatten.collectFunctions(flatModel);

// Dump the flat model to a stream if dumpFlat = true.
flatString := if dumpFlat then
Expand Down
59 changes: 53 additions & 6 deletions OMCompiler/Compiler/NFFrontEnd/NFPackage.mo
Expand Up @@ -51,6 +51,7 @@ protected
import NFInstNode.InstNode;
import Sections = NFSections;
import Statement = NFStatement;
import Type = NFType;
import Typing = NFTyping;
import Variable = NFVariable;

Expand Down Expand Up @@ -78,7 +79,6 @@ public
public
function collectConstants
input output FlatModel flatModel;
input FunctionTree functions;
protected
list<Variable> vars;
Constants constants;
Expand All @@ -89,7 +89,7 @@ public
constants := Equation.foldExpList(flatModel.initialEquations, collectExpConstants, constants);
constants := Algorithm.foldExpList(flatModel.algorithms, collectExpConstants, constants);
constants := Algorithm.foldExpList(flatModel.initialAlgorithms, collectExpConstants, constants);
constants := FunctionTree.fold(functions, collectFuncConstants, constants);
//constants := FunctionTree.fold(functions, collectFuncConstants, constants);

vars := listReverse(Variable.fromCref(c) for c in Constants.listKeys(constants));
vars := listAppend(Variable.expand(v) for v in vars);
Expand Down Expand Up @@ -142,18 +142,17 @@ public
input output Constants constants;
protected
ComponentRef cref;
Binding binding;
algorithm
() := match exp
case Expression.CREF(cref = cref as ComponentRef.CREF())
algorithm
if ComponentRef.isPackageConstant(cref) then
Typing.typeComponentBinding(cref.node, NFInstContext.CLASS);
binding := getPackageConstantBinding(cref);
// Add the constant to the set.
constants := Constants.add(constants, ComponentRef.stripSubscriptsAll(cref));
// Collect constants from the constant's binding.
constants := collectBindingConstants(
Component.getBinding(InstNode.component(ComponentRef.node(cref))),
constants);
constants := collectBindingConstants(binding, constants);
end if;
then
();
Expand All @@ -162,6 +161,54 @@ public
end match;
end collectExpConstants_traverser;

function getPackageConstantBinding
input ComponentRef cref;
output Binding binding;
protected
InstNode cr_node = ComponentRef.node(cref);
algorithm
Typing.typeComponentBinding(cr_node, NFInstContext.CLASS);
binding := Component.getImplicitBinding(InstNode.component(cr_node));

if Binding.isUnbound(binding) then
binding := getPackageConstantBinding2(cr_node, ComponentRef.rest(cref));
InstNode.componentApply(cr_node, Component.setBinding, binding);
end if;
end getPackageConstantBinding;

function getPackageConstantBinding2
input InstNode fieldNode;
input ComponentRef cref;
output Binding binding;
protected
InstNode cr_node;
Boolean is_record;
algorithm
if not ComponentRef.isCref(cref) then
binding := NFBinding.EMPTY_BINDING;
return;
end if;

is_record := Type.isRecord(Type.arrayElementType(ComponentRef.nodeType(cref)));
cr_node := ComponentRef.node(cref);

if not (InstNode.isComponent(cr_node) and is_record) then
binding := NFBinding.EMPTY_BINDING;
return;
end if;

Typing.typeComponentBinding(cr_node, NFInstContext.CLASS);
binding := Component.getBinding(InstNode.component(cr_node));

if Binding.isUnbound(binding) then
binding := getPackageConstantBinding2(cr_node, ComponentRef.rest(cref));
end if;

if Binding.isBound(binding) then
binding := Binding.recordFieldBinding(fieldNode, binding);
end if;
end getPackageConstantBinding2;

function collectFuncConstants
input Absyn.Path name;
input Function func;
Expand Down
3 changes: 2 additions & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFVariable.mo
Expand Up @@ -77,7 +77,7 @@ public
node := ComponentRef.node(cref);
comp := InstNode.component(node);
ty := ComponentRef.getSubscriptedType(cref);
binding := Component.getBinding(comp);
binding := Component.getImplicitBinding(comp);
vis := InstNode.visibility(node);
attr := Component.getAttributes(comp);
cmt := Component.comment(comp);
Expand All @@ -104,6 +104,7 @@ public
Expression.arrayScalarElements(ExpandExp.expandCref(Expression.fromCref(var.name))));

v := var;
v.ty := Type.arrayElementType(v.ty);
vars := {};
binding := var.binding;

Expand Down
6 changes: 1 addition & 5 deletions OMCompiler/Compiler/Script/NFApi.mo
Expand Up @@ -697,13 +697,9 @@ algorithm
flat_model := EvalConstants.evaluate(flat_model);
flat_model := UnitCheck.checkUnits(flat_model);
flat_model := SimplifyModel.simplify(flat_model);
flat_model := Package.collectConstants(flat_model);
funcs := Flatten.collectFunctions(flat_model);

// Collect package constants that couldn't be substituted with their values
// (e.g. because they where used with non-constant subscripts), and add them
// to the model.
flat_model := Package.collectConstants(flat_model, funcs);

// Scalarize array components in the flat model.
if Flags.isSet(Flags.NF_SCALARIZE) then
flat_model := Scalarize.scalarize(flat_model);
Expand Down
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -728,6 +728,7 @@ OperatorOverloadError1.mo \
OperatorOverloadSum1.mo \
PackageConstant1.mo \
PackageConstant3.mo \
PackageConstant4.mo \
ParameterBug.mos \
PartialApplication1.mo \
PartialApplicationInvalidArg1.mo \
Expand Down
14 changes: 10 additions & 4 deletions testsuite/flattening/modelica/scodeinst/PackageConstant3.mo
Expand Up @@ -18,15 +18,21 @@ package P
end ext_func;
end P;

model M
model PackageConstant3
Real x = P.r[1].x;
end M;
end PackageConstant3;

// Result:
// class M
// function P.ext_func
// output Real x;
//
// external "C" x = ext_func();
// end P.ext_func;
//
// class PackageConstant3
// parameter Real P.r[1].x = P.ext_func();
// parameter Real P.r[2].x = P.ext_func();
// parameter Real P.r[3].x = P.ext_func();
// Real x = P.r[1].x;
// end M;
// end PackageConstant3;
// endResult
38 changes: 38 additions & 0 deletions testsuite/flattening/modelica/scodeinst/PackageConstant4.mo
@@ -0,0 +1,38 @@
// name: PackageConstant4
// keywords:
// status: correct
// cflags: -d=newInst
//

package P
record R
Real x;
end R;

parameter R r1(x = ext_func());
parameter R r2[1] = {r1};

function ext_func
output Real x;

external "C";
end ext_func;
end P;

model PackageConstant4
Real x = P.r2[1].x;
end PackageConstant4;

// Result:
// function P.ext_func
// output Real x;
//
// external "C" x = ext_func();
// end P.ext_func;
//
// class PackageConstant4
// parameter Real P.r1.x = P.ext_func();
// parameter Real P.r2[1].x = P.r1.x;
// Real x = P.r2[1].x;
// end PackageConstant4;
// endResult

0 comments on commit 63e15e6

Please sign in to comment.