Skip to content

Commit

Permalink
- Improved handling of slice arrays
Browse files Browse the repository at this point in the history
- Fixed slice array assignments
- Fix #3184

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@24924 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
mahge committed Mar 5, 2015
1 parent ae11989 commit 4d0c547
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 88 deletions.
21 changes: 11 additions & 10 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -6258,16 +6258,6 @@ algorithm
DAE.Type ty;
list<tuple<DAE.Exp, DAE.Exp>> exptl;

case (_, (BackendDAE.ARRAY_EQUATION(left=e1, right=e2, source=source))::_, BackendDAE.VAR(varName = cr)::_, _, _, _) equation
// We need to strip subs from the name since they are removed in cr.
cr_1 = ComponentReference.crefStripLastSubs(cr);
e1 = Expression.replaceDerOpInExp(e1);
e2 = Expression.replaceDerOpInExp(e2);
(e1, _) = BackendDAEUtil.collateArrExp(e1, NONE());
(e2, _) = BackendDAEUtil.collateArrExp(e2, NONE());
(e1, e2) = solveTrivialArrayEquation(cr_1, e1, e2);
(equation_, uniqueEqIndex) = createSingleArrayEqnCode2(cr_1, cr_1, e1, e2, iuniqueEqIndex, source);
then ({equation_}, {equation_}, uniqueEqIndex, itempvars);

// An array equation
// {z1,z2,..} = f(...) -> solved for {z1,z2,..}
Expand All @@ -6293,6 +6283,17 @@ algorithm

eqSystlst = SimCode.SES_ARRAY_CALL_ASSIGN(uniqueEqIndex, left, e2_1, source)::eqSystlst;
then (eqSystlst, eqSystlst, uniqueEqIndex+1, tempvars);

case (_, (BackendDAE.ARRAY_EQUATION(left=e1, right=e2, source=source))::_, BackendDAE.VAR(varName = cr)::_, _, _, _) equation
// We need to strip subs from the name since they are removed in cr.
cr_1 = ComponentReference.crefStripLastSubs(cr);
e1 = Expression.replaceDerOpInExp(e1);
e2 = Expression.replaceDerOpInExp(e2);
(e1, _) = BackendDAEUtil.collateArrExp(e1, NONE());
(e2, _) = BackendDAEUtil.collateArrExp(e2, NONE());
(e1, e2) = solveTrivialArrayEquation(cr_1, e1, e2);
(equation_, uniqueEqIndex) = createSingleArrayEqnCode2(cr_1, cr_1, e1, e2, iuniqueEqIndex, source);
then ({equation_}, {equation_}, uniqueEqIndex, itempvars);

case (_, (BackendDAE.ARRAY_EQUATION(left=e1, right=e2, source=source, attr=BackendDAE.EQUATION_ATTRIBUTES(kind=eqKind)))::_, vars, _, _, _) equation
true = Expression.isArray(e1) or Expression.isMatrix(e1);
Expand Down
172 changes: 94 additions & 78 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -3795,34 +3795,35 @@ template equationArrayCallAssign(SimEqSystem eq, Context context,
case eqn as SES_ARRAY_CALL_ASSIGN(__) then
let &preExp = buffer ""
let expPart = daeExp(exp, context, &preExp, &varDecls, &auxFunction)
let lhsstr = daeBareCrefArrayLhsSimContextArray(eqn.componentRef, expTypeFromExpShort(eqn.exp),
context, &preExp, &varDecls, &auxFunction)
match expTypeFromExpShort(eqn.exp)
case "boolean" then
<<
<%preExp%>
copy_boolean_array_data_mem(<%expPart%>, &<%cref(eqn.componentRef)%>);
copy_boolean_array_data(<%expPart%>, &<%lhsstr%>);
>>
case "integer" then
<<
<%preExp%>
copy_integer_array_data_mem(<%expPart%>, &<%cref(eqn.componentRef)%>);
copy_integer_array_data(<%expPart%>, &<%lhsstr%>);
>>
case "real" then
<<
<%preExp%>
copy_real_array_data_mem(<%expPart%>, &<%cref(eqn.componentRef)%>);
copy_real_array_data(<%expPart%>, &<%lhsstr%>);
>>
case "string" then
<<
<%preExp%>
copy_string_array_data_mem(<%expPart%>, &<%cref(eqn.componentRef)%>);
copy_string_array_data(<%expPart%>, &<%lhsstr%>);
>>
else error(sourceInfo(), 'No runtime support for this sort of array call: <%printExpStr(eqn.exp)%>')
%>
<%endModelicaLine()%>
>>
end equationArrayCallAssign;


template equationAlgorithm(SimEqSystem eq, Context context, Text &varDecls, Text &auxFunction)
"Generates an equation that is an algorithm."
::=
Expand Down Expand Up @@ -6898,7 +6899,7 @@ template algStmtAssign(DAE.Statement stmt, Context context, Text &varDecls, Text
<% varLst |> var as TYPES_VAR(__) =>
match var.ty
case T_ARRAY(__) then
copyArrayData(var.ty, '<%tmp%>._<%var.name%>', appendStringCref(var.name,cr), context)
copyArrayData(var.ty, '<%tmp%>._<%var.name%>', appendStringCref(var.name,cr), context, &preExp, &varDecls, &auxFunction)
else
let varPart = contextCref(appendStringCref(var.name,cr),context, &auxFunction)
'<%varPart%> = <%tmp%>._<%var.name%>;'
Expand Down Expand Up @@ -6963,43 +6964,38 @@ template algStmtAssignArr(DAE.Statement stmt, Context context,
"Generates an array assigment algorithm statement."
::=
match stmt
case STMT_ASSIGN_ARR(lhs=CREF(componentRef=cr), exp=RANGE(__), type_=t) then
case STMT_ASSIGN_ARR(lhs=lhsexp as CREF(componentRef=cr), exp=RANGE(__), type_=t) then
fillArrayFromRange(t,exp,cr,context,&varDecls,&auxFunction)
case STMT_ASSIGN_ARR(lhs=CREF(componentRef=cr), exp=e as CALL(__), type_=t) then
case STMT_ASSIGN_ARR(lhs=lhsexp as CREF(componentRef=cr), exp=e as CALL(__), type_=t) then
let &preExp = buffer ""
let expPart = daeExp(e, context, &preExp, &varDecls, &auxFunction)
let ispec = indexSpecFromCref(cr, context, &preExp, &varDecls, &auxFunction)
if ispec then
if crefSubIsScalar(cr) then
<<
<%preExp%>
<%indexedAssign(t, expPart, cr, ispec, context, &varDecls)%>
<%copyArrayDataAndFreeMemAfterCall(t, expPart, cr, context)%>
>>
else
let assign = indexedAssign(lhs, expPart, context, &preExp, &varDecls, &auxFunction)
<<
<%preExp%>
<%copyArrayDataAndFreeMemAfterCall(t, expPart, cr, context)%>
<%assign%>
>>

case STMT_ASSIGN_ARR(lhs=lhsexp as CREF(componentRef=cr), exp=e, type_=t) then
let &preExp = buffer ""
let expPart = daeExp(e, context, &preExp, &varDecls, &auxFunction)
let ispec = indexSpecFromCref(cr, context, &preExp, &varDecls, &auxFunction)
let lhs = daeExpCrefRhs(lhsexp, context, &preExp, &varDecls, &auxFunction)
let type = expTypeArray(t)
if ispec then
if crefSubIsScalar(cr) then
let lhs = daeExpCrefLhs(lhsexp, context, &preExp, &varDecls, &auxFunction)
<<
<%preExp%>
<%indexedAssign(t, expPart, cr, ispec, context, &varDecls)%>
copy_<%type%>_data(<%expPart%>, &<%lhs%>);
>>
else
/*
let assign = indexedAssign(lhs, expPart, context, &preExp, &varDecls, &auxFunction)
<<
<%preExp%>
<%copyArrayData(t, expPart, cr, context)%>
>>
*/
<<
<%preExp%>
copy_<%type%>_data(<%expPart%>, &<%lhs%>);
<%assign%>
>>
end algStmtAssignArr;

Expand All @@ -7022,34 +7018,36 @@ case RANGE(__) then

end fillArrayFromRange;

template indexedAssign(DAE.Type ty, String exp, DAE.ComponentRef cr,
String ispec, Context context, Text &varDecls)
template indexedAssign(DAE.Exp lhs, String exp, Context context,
Text &preExp, Text &varDecls, Text &auxFunction)
::=
let type = expTypeArray(ty)
let cref = contextArrayCref(cr, context)
match context
case FUNCTION_CONTEXT(__) then
'indexed_assign_<%type%>(<%exp%>, &<%cref%>, &<%ispec%>);'
case PARALLEL_FUNCTION_CONTEXT(__) then
'indexed_assign_<%type%>(<%exp%>, &<%cref%>, &<%ispec%>);'
match lhs
case ecr as CREF(componentRef=cr, ty=T_ARRAY(ty=aty, dims=dims)) then
let arrayType = expTypeArray(ty)
let ispec = daeExpCrefIndexSpec(crefSubs(cr), context, &preExp, &varDecls, &auxFunction)
match context
case FUNCTION_CONTEXT(__) then
let cref = contextArrayCref(cr, context)
'indexed_assign_<%arrayType%>(<%exp%>, &<%cref%>, &<%ispec%>);'
case PARALLEL_FUNCTION_CONTEXT(__) then
let cref = contextArrayCref(cr, context)
'indexed_assign_<%arrayType%>(<%exp%>, &<%cref%>, &<%ispec%>);'
else
let type = expTypeShort(aty)
let wrapperArray = tempDecl(arrayType, &varDecls)
let dimsLenStr = listLength(crefDims(cr))
let dimsValuesStr = (crefDims(cr) |> dim => dimension(dim) ;separator=", ")
let arrName = contextCref(crefStripSubs(cr), context,&auxFunction)
<<
<%type%>_array_create(&<%wrapperArray%>, (modelica_<%type%>*)&<%arrName%>, <%dimsLenStr%>, <%dimsValuesStr%>);<%\n%>
indexed_assign_<%arrayType%>(<%exp%>, &<%wrapperArray%>, &<%ispec%>);
>>
else
match cr
case CREF_IDENT(identType = T_ARRAY(ty = aty, dims = adims)) then
// let tmp = tempDecl("real_array", &varDecls)
let tmpArr = tempDecl(expTypeArray(aty), &varDecls)
let dimsLenStr = listLength(adims)
let dimsValuesStr = (adims |> dim => dimension(dim) ;separator=", ")
let atype = expTypeShort(aty)
<<
<%atype%>_array_create(&<%tmpArr%>, ((modelica_<%atype%>*)&(<%arrayCrefCStr(cr)%>)), <%dimsLenStr%>, <%dimsValuesStr%>);
indexed_assign_<%type%>(<%exp%>, &<%tmpArr%>, &<%ispec%>);
copy_<%type%>_data_mem(<%tmpArr%>, &<%cref%>);
>>
else
error(sourceInfo(), 'indexedAssign simulationContext failed')
error(sourceInfo(), 'indexedAssign simulationContext failed')
end indexedAssign;

template copyArrayData(DAE.Type ty, String exp, DAE.ComponentRef cr, Context context)
template copyArrayData(DAE.Type ty, String exp, DAE.ComponentRef cr, Context context,
Text &preExp, Text &varDecls, Text &auxFunction)
::=
let type = expTypeArray(ty)
let cref = contextArrayCref(cr, context)
Expand Down Expand Up @@ -7077,7 +7075,7 @@ template copyArrayDataAndFreeMemAfterCall(DAE.Type ty, String exp, DAE.Component
case PARALLEL_FUNCTION_CONTEXT(__) then
'copy_<%type%>_data(<%exp%>, &<%cref%>);'
else
'copy_<%type%>_data_mem(<%exp%>, &<%cref%>);'
'/*that*/copy_<%type%>_data_mem(<%exp%>, &<%cref%>);'
end copyArrayDataAndFreeMemAfterCall;

template algStmtTupleAssign(DAE.Statement stmt, Context context, Text &varDecls, Text &auxFunction)
Expand Down Expand Up @@ -7145,13 +7143,13 @@ template tupleReturnVariableUpdates(Exp inExp, Context context, Text &varDecls,
case CREF(componentRef = cr, ty = t as DAE.T_ARRAY(__)) then
let &preExp = buffer ""
let rhsStr = tempDecl("base_array_t", &varDecls)
let lhsStr = contextCref(cr, context, &auxFunction)
let lhsStr = daeExpCrefLhs(inExp, context, &preExp, &varDecls, &auxFunction)
let &varCopy +=
match context
case SIMULATION_CONTEXT(__) then
<<
<%preExp%>
copy_<%expTypeShort(t)%>_array_data_mem(<%rhsStr%>, &<%lhsStr%>);
copy_<%expTypeShort(t)%>_array_data(<%rhsStr%>, &<%lhsStr%>);
>>
else
/*TODO make this copy*/
Expand Down Expand Up @@ -7632,16 +7630,6 @@ template algStmtReinit(DAE.Statement stmt, Context context, Text &varDecls, Text
>>
end algStmtReinit;

template indexSpecFromCref(ComponentRef cr, Context context, Text &preExp,
Text &varDecls, Text &auxFunction)
"Helper to algStmtAssignArr.
Currently works only for CREF_IDENT."
::=
match cr
case CREF_IDENT(subscriptLst=subs as (_ :: _)) then
daeExpCrefIndexSpec(subs, context, &preExp, &varDecls, &auxFunction)
end indexSpecFromCref;

template elseExpr(DAE.Else else_, Context context, Text &varDecls, Text &auxFunction)
"Helper to algStmtIf."
::=
Expand Down Expand Up @@ -7807,8 +7795,9 @@ template daeExpCrefRhsSimContext(Exp ecr, Context context, Text &preExp,
'omc_<%record_type_name%>(threadData<%vars%>)'

case ecr as CREF(componentRef=cr, ty=T_ARRAY(ty=aty, dims=dims)) then
let wrapperArray = tempDecl(expTypeArray(aty), &varDecls)
let type = expTypeShort(aty)
let arrayType = type + "_array"
let wrapperArray = tempDecl(arrayType, &varDecls)
if crefSubIsScalar(cr) then
let dimsLenStr = listLength(dims)
let dimsValuesStr = (dims |> dim => dimension(dim) ;separator=", ")
Expand All @@ -7823,10 +7812,9 @@ template daeExpCrefRhsSimContext(Exp ecr, Context context, Text &preExp,
let dimsValuesStr = (crefDims(cr) |> dim => dimension(dim) ;separator=", ")
let arrName = contextCref(crefStripSubs(cr), context,&auxFunction)
let &preExp += '<%type%>_array_create(&<%wrapperArray%>, (modelica_<%type%>*)&<%arrName%>, <%dimsLenStr%>, <%dimsValuesStr%>);<%\n%>'
let arrayType = expTypeArray(ty)
let slicedArray = tempDecl(arrayType, &varDecls)
let spec1 = daeExpCrefIndexSpec(crefSubs(cr), context, &preExp, &varDecls, &auxFunction)
let &preExp += 'index_alloc_<%arrayType%>(&<%wrapperArray%>, &<%spec1%>, &<%slicedArray%>);<%\n%>'
let &preExp += 'index_alloc_<%type%>_array(&<%wrapperArray%>, &<%spec1%>, &<%slicedArray%>);<%\n%>'
slicedArray

case ecr as CREF(componentRef=cr, ty=ty) then
Expand All @@ -7844,7 +7832,7 @@ template daeExpCrefRhsSimContext(Exp ecr, Context context, Text &preExp,
'<%cast%><%nosubname%>_index(<%substring%>)'
else
error(sourceInfo(),'daeExpCrefRhsSimContext: UNHANDLED CREF: <%ExpressionDump.printExpStr(ecr)%>')
end daeExpCrefRhsSimContext;
end daeExpCrefRhsSimContext;

template daeExpCrefRhsFunContext(Exp ecr, Context context, Text &preExp,
Text &varDecls, Text &auxFunction)
Expand Down Expand Up @@ -7941,14 +7929,23 @@ template daeExpCrefLhsSimContext(Exp ecr, Context context, Text &preExp,
let record_type_name = underscorePath(ClassInf.getStateName(record_state))
// 'omc_<%record_type_name%>(threadData<%vars%>)'
error(sourceInfo(), 'daeExpCrefLhsSimContext got record <%crefStr(cr)%>. This does not make sense. Assigning to records is handled in a different way in the code generator, and reaching here is probably an error...') // '<%ret_var%>.c1'

case ecr as CREF(ty=T_ARRAY(ty=aty,dims=dims)) then
let tmpArr = tempDecl(expTypeArray(aty), &varDecls)
let dimsLenStr = listLength(dims)
let dimsValuesStr = (dims |> dim => dimension(dim) ;separator=", ")

case ecr as CREF(componentRef=cr, ty=T_ARRAY(ty=aty, dims=dims)) then
let type = expTypeShort(aty)
let &preExp += '<%type%>_array_create(&<%tmpArr%>, ((modelica_<%type%>*)&(<%arrayCrefCStr(ecr.componentRef)%>)), <%dimsLenStr%>, <%dimsValuesStr%>);<%\n%>'
tmpArr
let arrayType = type + "_array"
let wrapperArray = tempDecl(arrayType, &varDecls)
if crefSubIsScalar(cr) then
let dimsLenStr = listLength(dims)
let dimsValuesStr = (dims |> dim => dimension(dim) ;separator=", ")
let nosubname = contextCref(crefStripSubs(cr),context, &auxFunction)
let substring = (crefSubs(crefArrayGetFirstCref(cr)) |> INDEX(__) =>
daeSubscriptExp(exp, context, &preExp, &varDecls, &auxFunction)
;separator=", ")
let &preExp += '<%type%>_array_create(&<%wrapperArray%>, ((modelica_<%type%>*)&(<%nosubname%>_index(<%substring%>))), <%dimsLenStr%>, <%dimsValuesStr%>);<%\n%>'
wrapperArray
else
error(sourceInfo(),'daeExpCrefLhsSimContext: This should have been handled in indexed assign and should not have gotten here <%ExpressionDump.printExpStr(ecr)%>')


case ecr as CREF(componentRef=cr, ty=ty) then
if crefIsScalarWithAllConstSubs(cr) then
Expand All @@ -7963,6 +7960,31 @@ template daeExpCrefLhsSimContext(Exp ecr, Context context, Text &preExp,
error(sourceInfo(),'daeExpCrefLhsSimContext: UNHANDLED CREF: <%ExpressionDump.printExpStr(ecr)%>')
end daeExpCrefLhsSimContext;


/*This function is used in cases where there is a bare ComponentRef to be generated. That is a ComponentRef
not wraped in a DAE.Exp as DAE.CREF(). see SES_ARRAY_CALL_ASSIGN, SES_SIMPLE_ASSIGN. This records should be
updated to hold Exps instead of ComponentRef and then made to use daeExpCrefLhs. In the meantime we use this
function to handle cases where the ComponentRef are arrays.*/
template daeBareCrefArrayLhsSimContextArray(ComponentRef cr, String type, Context context, Text &preExp,
Text &varDecls, Text &auxFunction)
::=
match cr
case _ then
let arrayType = type + "_array"
let wrapperArray = tempDecl(arrayType, &varDecls)
if crefSubIsScalar(cr) then
let dimsLenStr = listLength(crefDims(cr))
let dimsValuesStr = (crefDims(cr) |> dim => dimension(dim) ;separator=", ")
let nosubname = contextCref(crefStripSubs(cr),context, &auxFunction)
let substring = (crefSubs(crefArrayGetFirstCref(cr)) |> INDEX(__) =>
daeSubscriptExp(exp, context, &preExp, &varDecls, &auxFunction)
;separator=", ")
let &preExp += '<%type%>_array_create(&<%wrapperArray%>, ((modelica_<%type%>*)&(<%nosubname%>_index(<%substring%>))), <%dimsLenStr%>, <%dimsValuesStr%>);<%\n%>'
wrapperArray
else
error(sourceInfo(),'daeBareCrefArrayLhsSimContextArray: This should have been handled in indexed assign and should not have gotten here <%crefStr(cr)%>')
end daeBareCrefArrayLhsSimContextArray;

template daeExpCrefLhsFunContext(Exp ecr, Context context, Text &preExp,
Text &varDecls, Text &auxFunction)
"Generates code for a component reference on the left hand side!"
Expand Down Expand Up @@ -7993,13 +8015,7 @@ template daeExpCrefLhsFunContext(Exp ecr, Context context, Text &preExp,
error(sourceInfo(),'This should have been handled in the new daeExpCrefLhsSimContext function. <%printExpStr(ecr)%>')

else
// The array subscript denotes a slice
let arrName = contextArrayCref(cr, context)
let arrayType = expTypeArray(ty)
let tmp = tempDecl(arrayType, &varDecls)
let spec1 = daeExpCrefIndexSpec(crefSubs(cr), context, &preExp, &varDecls, &auxFunction)
let &preExp += 'indexed_assign_<%arrayType%>(<%tmp%>, &<%arrName%>, &<%spec1%>);<%\n%>'
tmp
error(sourceInfo(),'This should have been handled in indexed assign and should not have gotten here. <%printExpStr(ecr)%>')

case ecr then
error(sourceInfo(), 'SimCodeC.tpl template: daeExpCrefLhsFunContext: UNHANDLED EXPRESSION: <%ExpressionDump.printExpStr(ecr)%>')
Expand Down

0 comments on commit 4d0c547

Please sign in to comment.