Skip to content

Commit

Permalink
Improve #9399 using additions from #9408 (#9427)
Browse files Browse the repository at this point in the history
* Use the externally used records marker.

* Set marker to always be true for the OF.

* Use a map/dictionary instead of keeping separate lists.

  - Use a map (string, record Declaration) to keep a track of records in
    the SimCode. This allows for a simpler and quicker check. In addition
    we can update entries easily.

* Add MetaModelica records to the map as well.

* Debug help

* Fix traversal order to avoid possible(?) infinite recursion.

* Disable the old creation of record declarations.

  - See what fails in the testsuite.
  - It was actually affecting some tests because nested records were cycling
    back and messing with the order. Not exactly sure how but is not
    relevant anymore.

* Simplify processing of record declrations.

  - Remove returned lists from functions:
     elaborateNestedRecordDeclarations
     elaborateRecordDeclarationsFromTypes
     elaborateRecordDeclarationsForRecord
     elaborateNestedRecordDeclarations

  - Remove input lists from functions:
    - elaborateRecordDeclarationsFromTypes

* Make sure we do not overwrite true values to false.

  - If an entry already exists in the map and we always update, then there
    is a chance we might overwrite a 'true' value with a 'false' value
    for external conversion marker.

    Check if the entry exists and if it is marked false while then new
    incoming entry is marked true, then update it. Otherwise do nothing.

* Remove input lists from functions

  - Remove input lists from functions:
    - elaborateNestedRecordDeclarations
    - elaborateRecordDeclarationsForRecord

* Remove input and output lists from more functions.

  - Removed from
    - elaborateRecordDeclarationsForMetarecords

* Remove input and output lists from elaborateRecordDeclarations.

* Remove input and output lists from more functions.

  - Remove input and output lists from functions:
    - elaborateFunctions2
    - elaborateFunction

* Convert recursive functions to loops.

  - Recursive functions converted to loops:
    - elaborateNestedRecordDeclarations
    - elaborateRecordDeclarationsForMetarecords
    - elaborateRecordDeclarationsFromTypes

* Rename some functions to be more descriptive.

  - elaborateRecordDeclarationsForMetarecords -> collectRecDeclsFromMetaRecordCallExps
  - elaborateNestedRecordDeclarations -> collectRecDeclsFromTypesVars
  - elaborateRecordDeclarationsFromTypes -> collectRecDeclsFromTypes
  - elaborateRecordDeclarationsForRecord -> collectRecDeclsFromType

* Change how records are collected from metarecordcalls

  - Instead of:
    - traversing all expressions, collecting all meta record calls to a list,
      and then traversing this list to collect record declarations

    - collect record declarations while traversing all expressions (without
      collecting metarecordcalls into a whole new list.)

* Rename functions to be more descriptive.

  - elaborateRecordDeclarations -> collectRecDeclsFromElems

* Convert recursive functions to loops.

  - Convert recursive functions to loops:
    - collectRecDeclsFromElems (used to be `elaborateRecordDeclarations`)

* Some minor cleanup and renaming.

  - declMap -> recDeclsMap
  - needsExternalConversion -> usedExternally
  • Loading branch information
mahge committed Sep 25, 2022
1 parent c5cd7b7 commit eb5e7e0
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 276 deletions.
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/FrontEnd/DAE.mo
Expand Up @@ -964,7 +964,7 @@ public uniontype Type "models the different front-end and back-end types"
ClassInf.State complexClassType "The type of a class";
list<Var> varLst "The variables of a complex type";
EqualityConstraint equalityConstraint;
Boolean needsExternalConversion "If the record is passed to an external function at any point, we need to generate conversion functions for it (for instance to convert 'modelica_integer' to 'int')";
Boolean usedExternally "If the record is passed to an external function at any point, we need to generate conversion functions for it (for instance to convert 'modelica_integer' to 'int')";
end T_COMPLEX;

record T_SUBTYPE_BASIC
Expand Down
4 changes: 2 additions & 2 deletions OMCompiler/Compiler/FrontEnd/Inst.mo
Expand Up @@ -1012,7 +1012,7 @@ algorithm
end for;
tvars := listReverse(tvars);

then DAE.T_COMPLEX(inType.complexClassType, tvars, inType.equalityConstraint, inType.needsExternalConversion);
then DAE.T_COMPLEX(inType.complexClassType, tvars, inType.equalityConstraint, inType.usedExternally);
end match;

end markDerivedRecordOutsideBindings;
Expand Down Expand Up @@ -1084,7 +1084,7 @@ algorithm
end for;
tvars := listReverse(tvars);

then DAE.T_COMPLEX(inType.complexClassType, tvars, inType.equalityConstraint, inType.needsExternalConversion);
then DAE.T_COMPLEX(inType.complexClassType, tvars, inType.equalityConstraint, inType.usedExternally);
end match;

end markTypesVarsOutsideBindings;
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/FrontEnd/InstSection.mo
Expand Up @@ -3108,7 +3108,7 @@ algorithm
equation
vars = List.sort(vars, connectorCompGt);
then
DAE.T_COMPLEX(ci_state, vars, ec, inType.needsExternalConversion);
DAE.T_COMPLEX(ci_state, vars, ec, inType.usedExternally);
else inType;
Expand Down
4 changes: 2 additions & 2 deletions OMCompiler/Compiler/FrontEnd/InstUtil.mo
Expand Up @@ -5545,7 +5545,7 @@ algorithm
case (_,st,l,NONE(),equalityConstraint,_)
equation
failure(ClassInf.META_UNIONTYPE(_) = st);
then DAE.T_COMPLEX(st,l,equalityConstraint, false);
then DAE.T_COMPLEX(st,l,equalityConstraint, true);

// extending
case (_,st,l,SOME(bc),equalityConstraint,_)
Expand Down Expand Up @@ -5646,7 +5646,7 @@ algorithm

// not extending basic type!
case (_,st,l,NONE(),_)
then DAE.T_COMPLEX(st,l,NONE(), false); // adrpo: TODO! check equalityConstraint!
then DAE.T_COMPLEX(st,l,NONE(), true); // adrpo: TODO! check equalityConstraint!

case (_,st,l,SOME(bc),_)
then DAE.T_SUBTYPE_BASIC(st,l,bc,NONE());
Expand Down
6 changes: 3 additions & 3 deletions OMCompiler/Compiler/FrontEnd/Types.mo
Expand Up @@ -441,7 +441,7 @@ algorithm
equation
vars = List.map(vars, convertFromExpToTypesVar);
then
DAE.T_COMPLEX(CIS, vars, ec, inType.needsExternalConversion);
DAE.T_COMPLEX(CIS, vars, ec, inType.usedExternally);

case DAE.T_SUBTYPE_BASIC(CIS, vars, ty, ec)
equation
Expand Down Expand Up @@ -3871,7 +3871,7 @@ algorithm
true = Config.acceptMetaModelicaGrammar();
varLst = list(simplifyVar(v) for v in varLst);
then
DAE.T_COMPLEX(CIS, varLst, ec, inType.needsExternalConversion);
DAE.T_COMPLEX(CIS, varLst, ec, inType.usedExternally);
// do this for records too, otherwise:
// frame.R = Modelica.Mechanics.MultiBody.Frames.Orientation({const_matrix);
Expand All @@ -3880,7 +3880,7 @@ algorithm
equation
varLst = list(simplifyVar(v) for v in varLst);
then
DAE.T_COMPLEX(CIS, varLst, ec, inType.needsExternalConversion);
DAE.T_COMPLEX(CIS, varLst, ec, inType.usedExternally);
// otherwise just return the same!
case DAE.T_COMPLEX() then inType;
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/SimCode/SimCodeFunction.mo
Expand Up @@ -120,7 +120,7 @@ uniontype RecordDeclaration
Option<String> aliasName "alias of struct (record) name ? encoded. Code generators can generate an aliasing typedef using this, and avoid problems when casting a record from one type to another (*(othertype*)(&var)), which only works if you have a lhs value.";
Absyn.Path defPath "definition path";
list<Variable> variables "only name and type";
Boolean needsExternalConversion "If the record is passed to an external function at any point, we need to generate conversion functions for it (for instance to convert 'modelica_integer' to 'int')";
Boolean usedExternally "If the record is passed to an external function at any point, we need to generate conversion functions for it (for instance to convert 'modelica_integer' to 'int')";
end RECORD_DECL_FULL;

record RECORD_DECL_ADD_CONSTRCTOR
Expand Down
424 changes: 169 additions & 255 deletions OMCompiler/Compiler/SimCode/SimCodeFunctionUtil.mo

Large diffs are not rendered by default.

35 changes: 24 additions & 11 deletions OMCompiler/Compiler/Template/CodegenCFunctions.tpl
Expand Up @@ -427,7 +427,7 @@ template recordDeclaration(RecordDeclaration recDecl)
<%recordModelicaCallConstrctor(r.name, r.variables)%>

<%recordCopyDef(r.name, r.variables)%>
<%recordCopyExternalDefs(r.name, r.variables)%>
<%if r.usedExternally then recordCopyExternalDefs(r.name, r.variables)%>
>>
case r as RECORD_DECL_ADD_CONSTRCTOR(__) then
<<
Expand Down Expand Up @@ -498,7 +498,7 @@ end recordDeclarationExtraCtor;

template recordDeclarationFullHeader(RecordDeclaration recDecl)
"Generates structs for a record declaration. This will generate
a default record construtor function (no argumens) and a record copy function.
a default record constructor function (no arguments) and a record copy function.
These generated functions are fully recursive. That means records in records
will be handled properly.
It will also generate (#define) array versions of these functions."
Expand Down Expand Up @@ -536,28 +536,41 @@ template recordDeclarationFullHeader(RecordDeclaration recDecl)
case SOME(str) then
<<
typedef <%str%> <%rec_name%>;
typedef <%str%>_external <%rec_name%>_external;
<% if r.usedExternally then
<<
typedef <%str%>_external <%rec_name%>_external;
>>
%>
>>
else
<<
typedef struct {
<%r.variables |> var as VARIABLE(__) => '<%varType(var)%> _<%crefStr(var.name)%>;' ;separator="\n"%>
} <%rec_name%>;
typedef struct {
<%r.variables |> var as VARIABLE(__) => '<%extType(var.ty, true, false, false)%> _<%crefStr(var.name)%>;' ;separator="\n"%>
} <%rec_name%>_external;
>> %>
<% if r.usedExternally then
<<
typedef struct {
<%r.variables |> var as VARIABLE(__) => '<%extType(var.ty, true, false, false)%> _<%crefStr(var.name)%>;' ;separator="\n"%>
} <%rec_name%>_external;
>>
%>
>>
%>
extern struct record_description <%underscorePath(r.defPath)%>__desc;

void <%ctor_func_name%>(threadData_t *threadData, void* v_ths <%ctor_additional_inputs%>);
#define <%ctor_macro_name%>(td, ths <%ctor_macro_additional_inputs%>) <%ctor_func_name%>(td, &ths <%ctor_macro_additional_inputs%>)
void <%cpy_func_name%>(void* v_src, void* v_dst);
#define <%cpy_macro_name%>(src,dst) <%cpy_func_name%>(&src, &dst)
void <%cpy_to_external_func_name%>(void* v_src, void* v_dst);
#define <%cpy_to_external_macro_name%>(src,dst) <%cpy_to_external_func_name%>(&src, &dst)
void <%cpy_from_external_func_name%>(void* v_src, void* v_dst);
#define <%cpy_from_external_macro_name%>(src,dst) <%cpy_from_external_func_name%>(&src, &dst)

<%if r.usedExternally then
<<
void <%cpy_to_external_func_name%>(void* v_src, void* v_dst);
#define <%cpy_to_external_macro_name%>(src,dst) <%cpy_to_external_func_name%>(&src, &dst)
void <%cpy_from_external_func_name%>(void* v_src, void* v_dst);
#define <%cpy_from_external_macro_name%>(src,dst) <%cpy_from_external_func_name%>(&src, &dst)
>>
%>
// This function should eventually replace the default 'modelica' record constructor funcition
// that omc used to generate, i.e., replace functionBodyRecordConstructor template.
// <%rec_name%> <%modelica_ctor_name%>(threadData_t *threadData <%modelica_ctor_inputs%>);
Expand Down
1 change: 1 addition & 0 deletions OMCompiler/Compiler/Template/SimCodeTV.mo
Expand Up @@ -1045,6 +1045,7 @@ package SimCodeFunction
Option<String> aliasName;
Absyn.Path defPath;
list<Variable> variables;
Boolean usedExternally;
end RECORD_DECL_FULL;
record RECORD_DECL_ADD_CONSTRCTOR
String ctor_name;
Expand Down

0 comments on commit eb5e7e0

Please sign in to comment.