From dac3cfbf7d01bd35f84e5e3a8238f2a445f32e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Tue, 3 Nov 2020 13:17:31 +0100 Subject: [PATCH] Add new debug flag combineSubscripts - Add new debug flag combineSubscripts that when used together with newInst moves all subscripts to the end of component references. --- .../Compiler/NFFrontEnd/NFComponentRef.mo | 22 ++++++++++ OMCompiler/Compiler/NFFrontEnd/NFFlatModel.mo | 15 +++++++ OMCompiler/Compiler/NFFrontEnd/NFInst.mo | 18 ++++++++ OMCompiler/Compiler/NFFrontEnd/NFVariable.mo | 13 ++++++ OMCompiler/Compiler/Util/Flags.mo | 2 + OMCompiler/Compiler/Util/FlagsUtil.mo | 3 +- OMCompiler/Compiler/Util/List.mo | 15 +++++++ .../modelica/scodeinst/CombineSubscripts1.mo | 27 ++++++++++++ .../modelica/scodeinst/CombineSubscripts2.mo | 41 +++++++++++++++++++ .../flattening/modelica/scodeinst/Makefile | 2 + 10 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 testsuite/flattening/modelica/scodeinst/CombineSubscripts1.mo create mode 100644 testsuite/flattening/modelica/scodeinst/CombineSubscripts2.mo diff --git a/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo b/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo index 5bc70d68e5f..73d4dadd9e3 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo @@ -635,6 +635,28 @@ public end match; end replaceWholeSubscripts; + function combineSubscripts + "Moves all subscripts to the end of the cref. + Ex: a[1, 2].b[4] => a.b[1, 2, 4]" + input output ComponentRef cref; + protected + list subs; + algorithm + // Fill in : subscripts where needed so the cref is fully subscripted. + cref := fillSubscripts(cref); + // Fetch all the subscripts. + subs := List.flatten(subscriptsAll(cref)); + + if listEmpty(subs) then + return; + end if; + + // Remove unnecessary : subscripts from the head of the list. + subs := List.trim(subs, Subscript.isWhole); + // Replace the cref's subscripts. + cref := setSubscripts(subs, stripSubscriptsAll(cref)); + end combineSubscripts; + function compare input ComponentRef cref1; input ComponentRef cref2; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFFlatModel.mo b/OMCompiler/Compiler/NFFrontEnd/NFFlatModel.mo index ffdeca8fcbd..b1483d54cfc 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFFlatModel.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFFlatModel.mo @@ -94,6 +94,21 @@ public ElementSource source; end FLAT_MODEL; + function mapExp + input output FlatModel flatModel; + input MapFn fn; + + partial function MapFn + input output Expression exp; + end MapFn; + algorithm + flatModel.variables := list(Variable.mapExp(v, fn) for v in flatModel.variables); + flatModel.equations := Equation.mapExpList(flatModel.equations, fn); + flatModel.initialEquations := Equation.mapExpList(flatModel.initialEquations, fn); + flatModel.algorithms := Algorithm.mapExpList(flatModel.algorithms, fn); + flatModel.initialAlgorithms := Algorithm.mapExpList(flatModel.initialAlgorithms, fn); + end mapExp; + function toString input FlatModel flatModel; input Boolean printBindingTypes = false; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFInst.mo b/OMCompiler/Compiler/NFFrontEnd/NFInst.mo index 5c6685d415c..235a7bfbaa5 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFInst.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFInst.mo @@ -193,6 +193,10 @@ algorithm VerifyModel.verify(flatModel); + if Flags.isSet(Flags.COMBINE_SUBSCRIPTS) then + flatModel := FlatModel.mapExp(flatModel, combineSubscripts); + end if; + if Flags.isSet(Flags.NF_DUMP_FLAT) then print("FlatModel:\n" + FlatModel.toString(flatModel) + "\n"); end if; @@ -3586,5 +3590,19 @@ algorithm end if; end checkPartialClass; +function combineSubscripts + input output Expression exp; +algorithm + () := match exp + case Expression.CREF() + algorithm + exp.cref := ComponentRef.combineSubscripts(exp.cref); + then + (); + + else (); + end match; +end combineSubscripts; + annotation(__OpenModelica_Interface="frontend"); end NFInst; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo b/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo index 52994e4b9b0..36d97c5fa58 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo @@ -142,6 +142,19 @@ public binding := NFBinding.EMPTY_BINDING; end lookupTypeAttribute; + function mapExp + input output Variable var; + input MapFn fn; + + partial function MapFn + input output Expression exp; + end MapFn; + algorithm + var.binding := Binding.mapExp(var.binding, fn); + var.typeAttributes := list( + (Util.tuple21(a), Binding.mapExp(Util.tuple22(a), fn)) for a in var.typeAttributes); + end mapExp; + function toString input Variable var; input String indent = ""; diff --git a/OMCompiler/Compiler/Util/Flags.mo b/OMCompiler/Compiler/Util/Flags.mo index dcc047b76d0..76f4749a4e7 100644 --- a/OMCompiler/Compiler/Util/Flags.mo +++ b/OMCompiler/Compiler/Util/Flags.mo @@ -562,6 +562,8 @@ constant DebugFlag DUMP_DATARECONCILIATION = DEBUG_FLAG(193, "dataReconciliation Gettext.gettext("Dumps all the dataReconciliation extraction algorithm procedure")); constant DebugFlag ARRAY_CONNECT = DEBUG_FLAG(194, "arrayConnect", false, Gettext.gettext("Use experimental array connection handler.")); +constant DebugFlag COMBINE_SUBSCRIPTS = DEBUG_FLAG(195, "combineSubscripts", false, + Gettext.gettext("Move all subscripts to the end of component references.")); public // CONFIGURATION FLAGS diff --git a/OMCompiler/Compiler/Util/FlagsUtil.mo b/OMCompiler/Compiler/Util/FlagsUtil.mo index 30bba897850..e68db95442d 100644 --- a/OMCompiler/Compiler/Util/FlagsUtil.mo +++ b/OMCompiler/Compiler/Util/FlagsUtil.mo @@ -250,7 +250,8 @@ constant list allDebugFlags = { Flags.NF_DUMP_FLAT, Flags.DUMP_FORCE_FMI_ATTRIBUTES, Flags.DUMP_DATARECONCILIATION, - Flags.ARRAY_CONNECT + Flags.ARRAY_CONNECT, + Flags.COMBINE_SUBSCRIPTS }; protected diff --git a/OMCompiler/Compiler/Util/List.mo b/OMCompiler/Compiler/Util/List.mo index 75f4aee3df0..558e7c545af 100644 --- a/OMCompiler/Compiler/Util/List.mo +++ b/OMCompiler/Compiler/Util/List.mo @@ -7690,6 +7690,21 @@ algorithm end for; end maxElement; +function trim + "Removes elements from the head of the list while the given function returns + true for the first element, or until the list is empty." + input output list l; + input PredFn fn; + + partial function PredFn + input T e; + output Boolean res; + end PredFn; +algorithm + while not listEmpty(l) and fn(listHead(l)) loop + l := listRest(l); + end while; +end trim; annotation(__OpenModelica_Interface="util"); end List; diff --git a/testsuite/flattening/modelica/scodeinst/CombineSubscripts1.mo b/testsuite/flattening/modelica/scodeinst/CombineSubscripts1.mo new file mode 100644 index 00000000000..28036071ae7 --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/CombineSubscripts1.mo @@ -0,0 +1,27 @@ +// name: CombineSubscripts1 +// keywords: +// status: correct +// cflags: -d=newInst,-nfScalarize,combineSubscripts +// + +model B + Real[10] c; +end B; + +model CombineSubscripts1 + B[100] b; +equation + for i in 1:100 loop + b[i].c[10] = 2; + end for; +end CombineSubscripts1; + +// Result: +// class CombineSubscripts1 +// Real[100, 10] b.c; +// equation +// for i in 1:100 loop +// b.c[i,10] = 2.0; +// end for; +// end CombineSubscripts1; +// endResult diff --git a/testsuite/flattening/modelica/scodeinst/CombineSubscripts2.mo b/testsuite/flattening/modelica/scodeinst/CombineSubscripts2.mo new file mode 100644 index 00000000000..c0c503198b7 --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/CombineSubscripts2.mo @@ -0,0 +1,41 @@ +// name: CombineSubscripts2 +// keywords: +// status: correct +// cflags: -d=newInst,-nfScalarize,combineSubscripts +// + +record A + Real[4] a; +end A; + +model CombineSubscripts2 + A[3] b; +equation + for i in 1:4 loop + b[3].a[i] = 1; + end for; + + for i in 1:4 loop + b.a[i] = {1, 2, 3}; + end for; + + for i in 1:3 loop + b[i].a = {1, 2, 3, 4}; + end for; +end CombineSubscripts2; + +// Result: +// class CombineSubscripts2 +// Real[3, 4] b.a; +// equation +// for i in 1:4 loop +// b.a[3,i] = 1.0; +// end for; +// for i in 1:4 loop +// b.a[i] = {1.0, 2.0, 3.0}; +// end for; +// for i in 1:3 loop +// b.a[i,:] = {1.0, 2.0, 3.0, 4.0}; +// end for; +// end CombineSubscripts2; +// endResult diff --git a/testsuite/flattening/modelica/scodeinst/Makefile b/testsuite/flattening/modelica/scodeinst/Makefile index 892a77cc64f..dc86ce3d1b0 100644 --- a/testsuite/flattening/modelica/scodeinst/Makefile +++ b/testsuite/flattening/modelica/scodeinst/Makefile @@ -203,6 +203,8 @@ ClassMod4.mo \ ClassMod5.mo \ ClassMod6.mo \ ClockConstructor1.mo \ +CombineSubscripts1.mo \ +CombineSubscripts2.mo \ Comment1.mo \ CompAsFunc.mo \ ComponentAsTypeError.mo \