From 961c6386a1c058d35f951865ba271293d3e10485 Mon Sep 17 00:00:00 2001 From: kabdelhak Date: Fri, 14 Jun 2024 11:00:48 +0200 Subject: [PATCH] [NB] update record function handling - [NF] correctly identify all non default constructor functions - inline record constructors after inlining functions in replacements - add tuples to the check for inlining record elemetns --- .../NBackEnd/Modules/2_Pre/NBInline.mo | 36 +++++++++++-------- .../Compiler/NBackEnd/Util/NBReplacements.mo | 31 ++++++++++++++-- OMCompiler/Compiler/NFFrontEnd/NFFunction.mo | 17 +++++---- 3 files changed, 62 insertions(+), 22 deletions(-) diff --git a/OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBInline.mo b/OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBInline.mo index 0d0209b60eb..707180cd87c 100644 --- a/OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBInline.mo +++ b/OMCompiler/Compiler/NBackEnd/Modules/2_Pre/NBInline.mo @@ -185,23 +185,24 @@ protected protected UnorderedMap replacements "rules for replacements are stored inside here"; UnorderedSet set "new iterators from function bodies"; + VariablePointers variables = VarData.getVariables(varData); algorithm // collect functions replacements := UnorderedMap.new(AbsynUtil.pathHash, AbsynUtil.pathEqual); replacements := FunctionTree.fold(funcTree, function collectInlineFunctions(inline_types = inline_types), replacements); // apply replacements - eqData := Replacements.replaceFunctions(eqData, replacements); + eqData := Replacements.replaceFunctions(eqData, variables, replacements); // replace record constucters after functions because record operator // functions will produce record constructors once inlined - eqData := inlineRecordsTuples(eqData, VarData.getVariables(varData)); + eqData := inlineRecordsTuples(eqData, variables); // collect new iterators from replaced function bodies set := UnorderedSet.new(BVariable.hash, BVariable.equalName); - eqData := EqData.map(eqData, function BackendDAE.lowerEquationIterators(variables = VarData.getVariables(varData), set = set)); + eqData := EqData.map(eqData, function BackendDAE.lowerEquationIterators(variables = variables, set = set)); varData := VarData.addTypedList(varData, UnorderedSet.toList(set), NBVariable.VarData.VarType.ITERATOR); - eqData := EqData.mapExp(eqData, function BackendDAE.lowerComponentReferenceExp(variables = VarData.getVariables(varData))); + eqData := EqData.mapExp(eqData, function BackendDAE.lowerComponentReferenceExp(variables = variables)); end inline; function collectInlineFunctions @@ -313,16 +314,8 @@ protected algorithm tmp_eqns := Pointer.access(record_eqns); for i in 1:recordSize loop - new_lhs := Expression.nthRecordElement(i, lhs); - new_rhs := Expression.nthRecordElement(i, rhs); - - // lower indexed record constructor elements - new_lhs := Expression.map(new_lhs, inlineRecordConstructorElements); - new_rhs := Expression.map(new_rhs, inlineRecordConstructorElements); - - // lower the new component references of record attributes - new_lhs := Expression.map(new_lhs, function BackendDAE.lowerComponentReferenceExp(variables = variables)); - new_rhs := Expression.map(new_rhs, function BackendDAE.lowerComponentReferenceExp(variables = variables)); + new_lhs := inlineRecordExp(lhs, i, variables); + new_rhs := inlineRecordExp(rhs, i, variables); // create new equation tmp_eqn := Equation.makeAssignment(new_lhs, new_rhs, index, NBEquation.SIMULATION_STR, iter, attr); @@ -343,6 +336,21 @@ protected new_eqn := Equation.DUMMY_EQUATION(); end inlineRecordEquationWork; +public + function inlineRecordExp + "inlines record constructors in a single expression" + input output Expression exp; + input Integer index; + input VariablePointers variables; + algorithm + exp := Expression.nthRecordElement(index, exp); + // lower indexed record constructor elements + exp := Expression.map(exp, inlineRecordConstructorElements); + // lower the new component references of record attributes + exp := Expression.map(exp, function BackendDAE.lowerComponentReferenceExp(variables = variables)); + end inlineRecordExp; + +protected function inlineRecordConstructorElements "removes indexed constructor element calls Constructor(a,b,c)[2] --> b" diff --git a/OMCompiler/Compiler/NBackEnd/Util/NBReplacements.mo b/OMCompiler/Compiler/NBackEnd/Util/NBReplacements.mo index 7f68fe65b5a..b156dd5ceed 100644 --- a/OMCompiler/Compiler/NBackEnd/Util/NBReplacements.mo +++ b/OMCompiler/Compiler/NBackEnd/Util/NBReplacements.mo @@ -64,6 +64,7 @@ protected // Backend imports import BVariable = NBVariable; import NBEquation.{EqData, Equation, EquationPointers}; + import Inline = NBInline; import Solve = NBSolve; import StrongComponent = NBStrongComponent; import NBVariable.{VarData, VariablePointers}; @@ -265,17 +266,19 @@ public "replaces all function calls in the replacements map with their body expressions, if possible." input output EqData eqData; + input VariablePointers variables; input UnorderedMap replacements; algorithm // do nothing if replacements are empty if UnorderedMap.isEmpty(replacements) then return; end if; - eqData := EqData.mapExp(eqData, function applyFuncExp(replacements = replacements)); + eqData := EqData.mapExp(eqData, function applyFuncExp(replacements = replacements, variables = variables)); end replaceFunctions; function applyFuncExp "Needs to be mapped with Expression.map()" input output Expression exp "Replacement happens inside this expression"; input UnorderedMap replacements "rules for replacements are stored inside here"; + input VariablePointers variables; algorithm exp := match exp local @@ -320,6 +323,9 @@ public body_exp := Expression.map(body_exp, function applySimpleExp(replacements = local_replacements)); body_exp := SimplifyExp.combineBinaries(body_exp); body_exp := SimplifyExp.simplifyDump(body_exp, true, getInstanceName(), "\n"); + // inline possible record constructors + //body_exp := Expression.map(body_exp, function applyFuncTupleExp(variables = variables)); + if Flags.isSet(Flags.DUMPBACKENDINLINE) then print("[" + getInstanceName() + "] Inlining: " + Expression.toString(exp) + "\n"); @@ -331,6 +337,26 @@ public end match; end applyFuncExp; + function applyFuncTupleExp + input output Expression exp; + input VariablePointers variables; + protected + Type ty; + Option sz; + list inlined_record = {}; + algorithm + ty := Expression.typeOf(exp); + sz := Type.complexSize(ty); + + // if the call returns a record constructor, it has to be inlined + if Util.isSome(sz) then + for i in Util.getOption(sz):-1:1 loop + inlined_record := Inline.inlineRecordExp(exp, i, variables) :: inlined_record; + end for; + exp := Expression.TUPLE(ty, inlined_record); + end if; + end applyFuncTupleExp; + function addInputArgTpl "adds an input to argument replacement and also adds all record children replacements." @@ -359,7 +385,8 @@ public then list(Expression.fromCref(BVariable.getVarName(child)) for child in arg_children); // if it is a basic record, take its elements - case Expression.RECORD() then arg.elements; + case Expression.RECORD() then arg.elements; + case Expression.TUPLE() then arg.elements; // if the argument is a record constructor, map it to its attributes case Expression.CALL(call = call as Call.TYPED_CALL(fn = fn)) algorithm diff --git a/OMCompiler/Compiler/NFFrontEnd/NFFunction.mo b/OMCompiler/Compiler/NFFrontEnd/NFFunction.mo index 526df1217d4..01786e64f67 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFFunction.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFFunction.mo @@ -1990,12 +1990,17 @@ uniontype Function function isNonDefaultRecordConstructor input Function fn; - output Boolean isConstructor; - algorithm - isConstructor := match fn.path - case Absyn.Path.QUALIFIED(path = Absyn.Path.QUALIFIED(name = "'constructor'")) then true; - else false; - end match; + output Boolean b = isNonDefaultRecordConstructorPath(fn.path); + function isNonDefaultRecordConstructorPath + input Absyn.Path path; + output Boolean b; + algorithm + b := match path + case Absyn.Path.QUALIFIED(name = "'constructor'") then true; + case Absyn.Path.QUALIFIED() then isNonDefaultRecordConstructorPath(path.path); + else false; + end match; + end isNonDefaultRecordConstructorPath; end isNonDefaultRecordConstructor; function toDAE