Skip to content

Commit

Permalink
Split updateParameters into simple and complex
Browse files Browse the repository at this point in the history
Compile simple literal bindings separate from other bindings. The simple
bindings can be sorted according to index to get better cache locality
and disable optimization since they are only executed once anyway.

Also split the binding equations into multiple files when there are too
many of them.
  • Loading branch information
sjoelund authored and OpenModelica-Hudson committed Oct 10, 2017
1 parent 6138df4 commit aad32e0
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 7 deletions.
13 changes: 13 additions & 0 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -13143,5 +13143,18 @@ algorithm
end match;
end tupleHead;

public function isSimpleLiteralValue "A value that requires nothing special during code generation. String literals are special and not included."
input DAE.Exp exp;
output Boolean b;
algorithm
b := match exp
case DAE.ICONST() then true;
case DAE.RCONST() then true;
case DAE.BCONST() then true;
case DAE.ENUM_LITERAL() then true;
else false;
end match;
end isSimpleLiteralValue;

annotation(__OpenModelica_Interface="frontend");
end Expression;
56 changes: 56 additions & 0 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -13384,5 +13384,61 @@ algorithm
clockedPartitions := simcode.clockedPartitions;
end getClockedPartitions;

public function isScalarLiteralAssignment
input SimCode.SimEqSystem eq;
output Boolean b;
algorithm
b := match eq
case SimCode.SES_SIMPLE_ASSIGN() then Expression.isSimpleLiteralValue(eq.exp);
else false;
end match;
end isScalarLiteralAssignment;

public function selectScalarLiteralAssignments
input output list<SimCode.SimEqSystem> eqs;
algorithm
eqs := list(e for e guard isScalarLiteralAssignment(e) in eqs);
end selectScalarLiteralAssignments;

public function filterScalarLiteralAssignments
input output list<SimCode.SimEqSystem> eqs;
algorithm
eqs := list(e for e guard not isScalarLiteralAssignment(e) in eqs);
end filterScalarLiteralAssignments;

public function sortSimpleAssignmentBasedOnLhs
input output list<SimCode.SimEqSystem> eqs;
algorithm
eqs := List.sort(eqs, function lhsGreaterThan(simCode=getSimCode()));
end sortSimpleAssignmentBasedOnLhs;

protected function lhsGreaterThan
input SimCode.SimEqSystem eq1,eq2;
input SimCode.SimCode simCode;
output Boolean b;
algorithm
b := match (eq1,eq2)
case (SimCode.SES_SIMPLE_ASSIGN(),SimCode.SES_SIMPLE_ASSIGN())
then simvarGraterThan(cref2simvar(eq1.cref, simCode), cref2simvar(eq2.cref, simCode));
else false;
end match;
end lhsGreaterThan;

protected function simvarGraterThan
input SimCodeVar.SimVar v1,v2;
output Boolean b;
protected
Integer t1,t2,k1,k2;
// Sort according to type, varkind, index
algorithm
k1 := valueConstructor(v1.varKind);
k2 := valueConstructor(v2.varKind);
t1 := valueConstructor(v1.type_);
t2 := valueConstructor(v2.type_);
b := if t1==t2 then
(if k1==k2 then v1.index > v2.index else k1>k2)
else t1>t2;
end simvarGraterThan;

annotation(__OpenModelica_Interface="backend");
end SimCodeUtil;
7 changes: 4 additions & 3 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -659,7 +659,7 @@ template simulationFile_bnd(SimCode simCode)
<%functionUpdateBoundVariableAttributes(simCode, startValueEquations, nominalValueEquations, minValueEquations, maxValueEquations, modelNamePrefix(simCode))%>
<%functionUpdateBoundParameters(parameterEquations, simCode.fileNamePrefix, simCode.fullPathPrefix, modelNamePrefix(simCode))%>
<%functionUpdateBoundParameters(selectScalarLiteralAssignments(parameterEquations), filterScalarLiteralAssignments(parameterEquations), simCode.fileNamePrefix, simCode.fullPathPrefix, modelNamePrefix(simCode))%>
#if defined(__cplusplus)
}
Expand Down Expand Up @@ -2935,17 +2935,18 @@ template functionUpdateBoundVariableAttributes(SimCode simCode, list<SimEqSystem
>>
end functionUpdateBoundVariableAttributes;
template functionUpdateBoundParameters(list<SimEqSystem> parameterEquations, String fileNamePrefix, String fullPathPrefix, String modelNamePrefix)
template functionUpdateBoundParameters(list<SimEqSystem> simpleParameterEquations, list<SimEqSystem> parameterEquations, String fileNamePrefix, String fullPathPrefix, String modelNamePrefix)
"Generates function in simulation file."
::=
let &eqFuncs = buffer ""
let fncalls = functionEquationsMultiFiles(parameterEquations, listLength(parameterEquations), intMul(6 /* Binding equations are small */, Flags.getConfigInt(Flags.EQUATIONS_PER_FILE)), fileNamePrefix, fullPathPrefix, modelNamePrefix, "updateBoundParameters", "08bnd", &eqFuncs)
let fncalls = functionEquationsMultiFiles(parameterEquations, listLength(parameterEquations), Flags.getConfigInt(Flags.EQUATIONS_PER_FILE), fileNamePrefix, fullPathPrefix, modelNamePrefix, "updateBoundParameters", "08bnd", &eqFuncs)
<<
<%eqFuncs%>
OMC_DISABLE_OPT
int <%symbolName(modelNamePrefix,"updateBoundParameters")%>(DATA *data, threadData_t *threadData)
{
TRACE_PUSH
<%sortSimpleAssignmentBasedOnLhs(simpleParameterEquations) |> eq as SES_SIMPLE_ASSIGN(__) => '<%cref(cref)%> = <%daeExpSimpleLiteral(exp)%>;' ; separator="\n" %>
<%fncalls%>
TRACE_POP
return 0;
Expand Down
19 changes: 15 additions & 4 deletions Compiler/Template/CodegenCFunctions.tpl
Expand Up @@ -4304,11 +4304,11 @@ end getTempDeclMatchOutputName;
used in Compiler/Template/CodegenQSS.tpl"
::=
match codegenExpSanityCheck(exp, context)
case e as ICONST(__) then '((modelica_integer) <%integer%>)' /* Yes, we need to cast int to long on 64-bit arch... */
case e as RCONST(__) then real
case e as ICONST(__)
case e as RCONST(__)
case e as BCONST(__)
case e as ENUM_LITERAL(__) then daeExpSimpleLiteral(exp)
case e as SCONST(__) then daeExpSconst(string, &preExp, &varDecls)
case e as BCONST(__) then boolStrC(bool)
case e as ENUM_LITERAL(__) then index
case e as CREF(__) then daeExpCrefRhs(e, context, &preExp, &varDecls, &auxFunction)
case e as BINARY(__) then daeExpBinary(e, context, &preExp, &varDecls, &auxFunction)
case e as UNARY(__) then daeExpUnary(e, context, &preExp, &varDecls, &auxFunction)
Expand Down Expand Up @@ -4343,6 +4343,17 @@ end getTempDeclMatchOutputName;
else error(sourceInfo(), 'Unknown expression: <%ExpressionDumpTpl.dumpExp(exp,"\"")%>')
end daeExp;

/* public */ template daeExpSimpleLiteral(Exp exp)
"Generates code for a simple literal expression."
::=
match exp
case e as ICONST(__) then '((modelica_integer) <%integer%>)' /* Yes, we need to cast int to long on 64-bit arch... */
case e as RCONST(__) then real
case e as BCONST(__) then boolStrC(bool)
case e as ENUM_LITERAL(__) then index
else error(sourceInfo(), 'Not a simple literal expression: <%ExpressionDumpTpl.dumpExp(exp,"\"")%>')
end daeExpSimpleLiteral;

/* public */ template daeExpAsLValue(Exp exp, Context context, Text &preExp, Text &varDecls, Text &auxFunction)
"Generates code for an expression. Makes sure that the output is an lvalue (so you can take the address of it)."
::=
Expand Down
16 changes: 16 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -1005,6 +1005,22 @@ package SimCodeUtil
input SimCodeFunction.Context context;
output DAE.Exp outExp;
end codegenExpSanityCheck;

function selectScalarLiteralAssignments
input list<SimCode.SimEqSystem> inEqs;
output list<SimCode.SimEqSystem> eqs;
end selectScalarLiteralAssignments;

function filterScalarLiteralAssignments
input list<SimCode.SimEqSystem> inEqs;
output list<SimCode.SimEqSystem> eqs;
end filterScalarLiteralAssignments;

function sortSimpleAssignmentBasedOnLhs
input list<SimCode.SimEqSystem> inEqs;
output list<SimCode.SimEqSystem> eqs;
end sortSimpleAssignmentBasedOnLhs;

end SimCodeUtil;

package SimCodeFunctionUtil
Expand Down

0 comments on commit aad32e0

Please sign in to comment.