Changeset f6051a17 in OpenModelica


Ignore:
Timestamp:
2016-04-07T13:46:47+02:00 (8 years ago)
Author:
vwaurich <volker.waurich@…>
Branches:
Added-citation-metadata, maintenance/v1.14, maintenance/v1.15, maintenance/v1.16, maintenance/v1.17, maintenance/v1.18, maintenance/v1.19, maintenance/v1.20, maintenance/v1.21, maintenance/v1.22, maintenance/v1.23, master, omlib-staging
Children:
c3cf1e92
Parents:
058fd5a
Message:
  • caching of evaluated functions
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Compiler/BackEnd/EvaluateFunctions.mo

    r9027e889 rf6051a17  
    8080end FuncInfo;
    8181
     82public uniontype Variability
     83  record CONST end CONST;
     84    record VARIABLE end VARIABLE;
     85end Variability;
     86
     87public uniontype CallSignature
     88  record SIGNATURE
     89    Absyn.Path path;
     90    list<Variability> inputsVari;//not scalar, take records, arrays, calls as a single input variability
     91    Boolean canBeEvaluated;
     92  end SIGNATURE;
     93end CallSignature;
     94
     95// =============================================================================
     96// caching of already evaluated functions
     97//
     98// =============================================================================
     99
     100protected function checkCallSignatureForExp
     101  input DAE.Exp expIn;
     102  input list<CallSignature> signLst;
     103  output Boolean continueEval;
     104protected
     105  CallSignature signature;
     106algorithm
     107  continueEval := true;
     108  signature := getCallSignatureForCall(expIn);
     109  if List.isMemberOnTrue(signature,signLst,callSignatureIsEqual) then
     110    SIGNATURE(canBeEvaluated = continueEval) := List.getMemberOnTrue(signature,signLst,callSignatureIsEqual);
     111  end if;
     112end checkCallSignatureForExp;
     113
     114protected function callSignatureStr "outputs a string representation for the CallSignature"
     115  input CallSignature signat;
     116  output String str;
     117protected
     118   Absyn.Path path;
     119   list<Variability> varis;
     120   Boolean b;
     121algorithm
     122  SIGNATURE(path=path,inputsVari=varis, canBeEvaluated=b) := signat;
     123  str := Absyn.pathString(path)+"[ "+stringDelimitList(List.map(varis,VariabilityString)," | ")+" ] "+boolString(b);
     124end callSignatureStr;
     125
     126protected function VariabilityString "outputs a string representation for the Variability"
     127  input Variability var;
     128  output String str;
     129algorithm
     130  str := match(var)
     131    case(CONST())
     132      then "CONST";
     133    else then "VARIABLE";
     134    end match;
     135end VariabilityString;
     136
     137protected function callSignatureIsEqual"outputs true if 2 CallSignatures are equal"
     138  input CallSignature signat1;
     139  input CallSignature signat2;
     140  output Boolean isEqual;
     141protected
     142  Absyn.Path path1,path2;
     143  list<Variability> vari1,vari2;
     144algorithm
     145  SIGNATURE(path=path1, inputsVari=vari1) := signat1;
     146  SIGNATURE(path=path2, inputsVari=vari2) := signat2;
     147  isEqual := false;
     148  if Absyn.pathEqual(path1,path2) then
     149    if List.isEqualOnTrue(vari1,vari2,VariabilityIsEqual) then
     150      isEqual := true;
     151    end if;
     152  end if;
     153end callSignatureIsEqual;
     154
     155protected function VariabilityIsEqual"outputs true if 2 Variabilites are equal"
     156  input Variability vari1;
     157  input Variability vari2;
     158  output Boolean isEqual;
     159algorithm
     160  isEqual := match(vari1,vari2)
     161    case(CONST(),CONST())
     162      then true;
     163    case(VARIABLE(),VARIABLE())
     164      then true;
     165    else
     166      then false;
     167   end match;
     168end VariabilityIsEqual;
     169
     170protected function getCallSignatureForCall"determines the callSignature for a function call expression"
     171  input DAE.Exp callExpIn;
     172  output CallSignature signatureOut;
     173protected
     174  Absyn.Path path;
     175  list<DAE.Exp> expLst;
     176  list<Variability> vari;
     177algorithm
     178  try
     179    DAE.CALL(path=path, expLst=expLst) := callExpIn;
     180    vari := List.map(expLst,getVariabilityForExp);
     181    signatureOut := SIGNATURE(path,vari,true);
     182  else
     183    print("evalFunc.getCallSignatureForCall failed for :\n"+ExpressionDump.printExpStr(callExpIn)+"\n");
     184    fail();
     185  end try;
     186end getCallSignatureForCall;
     187
     188protected function getVariabilityForExp"determines if the exp is either constant or variable"
     189  input DAE.Exp expIn;
     190  output Variability variOut;
     191algorithm
     192  variOut := match(expIn)
     193    local
     194      Variability vari;
     195  case(DAE.ICONST())
     196    then CONST();
     197  case(DAE.RCONST())
     198    then CONST();
     199  case(DAE.SCONST())
     200    then CONST();
     201  case(DAE.BCONST())
     202    then CONST();
     203  case(DAE.CLKCONST())
     204    then CONST();
     205  case(DAE.ENUM_LITERAL())
     206    then CONST();
     207  case(DAE.CREF())
     208    then VARIABLE();
     209  case(DAE.BINARY())
     210    equation
     211      if Expression.isConst(expIn) then
     212        vari = CONST();
     213      else
     214        vari=VARIABLE(); end if;
     215    then vari;
     216  case(DAE.UNARY())
     217   equation
     218      if Expression.isConst(expIn) then vari = CONST();
     219      else vari=VARIABLE(); end if;
     220    then vari;
     221  case(DAE.LBINARY())
     222    equation
     223      if Expression.isConst(expIn) then vari = CONST();
     224      else vari=VARIABLE(); end if;
     225    then vari;
     226  case(DAE.LUNARY())
     227    equation
     228    if Expression.isConst(expIn) then vari = CONST();
     229    else vari=VARIABLE(); end if;
     230    then vari;
     231  case(DAE.RELATION())
     232    then VARIABLE();
     233  case(DAE.IFEXP())
     234    then VARIABLE();
     235  case(DAE.CALL())
     236    then VARIABLE();
     237  case(DAE.RECORD())
     238    equation
     239    if Expression.isConst(expIn) then vari = CONST();
     240    else vari=VARIABLE(); end if;
     241    then vari;
     242  case(DAE.PARTEVALFUNCTION())
     243    then VARIABLE();
     244  case(DAE.ARRAY())
     245    equation
     246    if Expression.isConst(expIn) then vari = CONST();
     247    else vari=VARIABLE(); end if;
     248    then vari;
     249  case(DAE.MATRIX())
     250    equation
     251    if Expression.isConst(expIn) then vari = CONST();
     252    else vari=VARIABLE(); end if;
     253    then vari;
     254  case(DAE.RANGE())
     255    equation
     256    if Expression.isConst(expIn) then vari = CONST();
     257    else vari=VARIABLE(); end if;
     258    then vari;
     259  case(DAE.TUPLE())
     260    equation
     261    if Expression.isConst(expIn) then vari = CONST();
     262    else vari=VARIABLE(); end if;
     263    then vari;
     264  case(DAE.CAST())
     265    equation
     266    if Expression.isConst(expIn) then vari = CONST();
     267    else vari=VARIABLE(); end if;
     268    then vari;
     269  case(DAE.ASUB())
     270    equation
     271    if Expression.isConst(expIn) then vari = CONST();
     272    else vari=VARIABLE(); end if;
     273    then vari;
     274  case(DAE.TSUB())
     275    equation
     276    if Expression.isConst(expIn) then vari = CONST();
     277    else vari=VARIABLE(); end if;
     278    then vari;
     279  case(DAE.RSUB())
     280    equation
     281    if Expression.isConst(expIn) then vari = CONST();
     282    else vari=VARIABLE(); end if;
     283    then vari;
     284  case(DAE.SIZE())
     285    then VARIABLE();
     286  case(DAE.CODE())
     287    then VARIABLE();
     288  case(DAE.EMPTY())
     289    then VARIABLE();
     290  case(DAE.REDUCTION())
     291    then VARIABLE();
     292  else
     293     VARIABLE();
     294  end match;
     295end getVariabilityForExp;
     296
    82297// =============================================================================
    83298// evaluate functions
     
    97312  try
    98313    BackendDAE.DAE(eqs=eqSysts, shared=shared) := inDAE;
    99     (eqSysts, (shared, _, changed)) := List.mapFold(eqSysts, evalFunctions_main, (shared, 1, false));
     314    (eqSysts, (shared, _, changed, _)) := List.mapFold(eqSysts, evalFunctions_main, (shared, 1, false, {}));
    100315    //shared = evaluateShared(shared);
    101316
     
    141356        true = Expression.isCall(bindExp);
    142357        ExpressionDump.dumpExp(bindExp);
    143         ((bindExp,_,_,_,_,_)) = evaluateConstantFunction(bindExp,bindExp,funcTree,1);
     358        ((bindExp,_,_,_,_,_,_)) = evaluateConstantFunction(bindExp,bindExp,funcTree,1,{});
    144359        ExpressionDump.dumpExp(bindExp);
    145360      then
     
    151366protected function evalFunctions_main "traverses the eqSystems for function calls and tries to evaluate them"
    152367  input BackendDAE.EqSystem eqSysIn;
    153   input tuple<BackendDAE.Shared,Integer,Boolean> tplIn;
     368  input tuple<BackendDAE.Shared,Integer,Boolean, list<CallSignature>> tplIn;
    154369  output BackendDAE.EqSystem eqSysOut;
    155   output tuple<BackendDAE.Shared,Integer,Boolean> tplOut;
     370  output tuple<BackendDAE.Shared,Integer,Boolean, list<CallSignature>> tplOut;
    156371protected
    157372  Boolean changed;
     
    160375  BackendDAE.EquationArray eqs;
    161376  list<BackendDAE.Equation> eqLst, addEqs;
    162 algorithm
    163   (sharedIn,sysIdx,changed) := tplIn;
     377  list<CallSignature> callSign;
     378algorithm
     379  (sharedIn,sysIdx,changed,callSign) := tplIn;
    164380  BackendDAE.EQSYSTEM(orderedEqs=eqs) := eqSysIn;
    165381  eqLst := BackendEquation.equationList(eqs);
    166382
    167383  //traverse the eqSystem for function calls
    168   (eqLst, (shared, addEqs, _, changed)) := List.mapFold(eqLst, evalFunctions_findFuncs, (sharedIn, {}, 1, changed));
     384  (eqLst, (shared, addEqs, _, changed, callSign)) := List.mapFold(eqLst, evalFunctions_findFuncs, (sharedIn, {}, 1, changed, callSign));
    169385  eqLst := listAppend(eqLst, addEqs);
    170386  eqs := BackendEquation.listEquation(eqLst);
    171387  eqSysOut := BackendDAEUtil.setEqSystEqs(eqSysIn, eqs);
    172388
    173   tplOut := (shared, sysIdx+1, changed);
     389  tplOut := (shared, sysIdx+1, changed, callSign);
    174390end evalFunctions_main;
    175391
    176392protected function evalFunctions_findFuncs "traverses the lhs and rhs exps of an equation and tries to evaluate function calls "
    177393  input BackendDAE.Equation eqIn;
    178   input tuple<BackendDAE.Shared,list<BackendDAE.Equation>,Integer,Boolean> tplIn;
     394  input tuple<BackendDAE.Shared,list<BackendDAE.Equation>,Integer,Boolean, list<CallSignature>> tplIn;
    179395  output BackendDAE.Equation eqOut;
    180   output tuple<BackendDAE.Shared,list<BackendDAE.Equation>,Integer,Boolean> tplOut;
     396  output tuple<BackendDAE.Shared,list<BackendDAE.Equation>,Integer,Boolean, list<CallSignature>> tplOut;
    181397algorithm
    182398  (eqOut,tplOut) := matchcontinue(eqIn,tplIn)
     
    192408      list<BackendDAE.Equation> addEqs, addEqs1, addEqs2;
    193409      list<DAE.Exp> lhs;
     410      list<CallSignature> callSign;
    194411    case(BackendDAE.EQUATION(exp=exp1, scalar=exp2,source=source,attr=attr),_)
    195412      equation
     
    197414        b2 = Expression.containFunctioncall(exp2);
    198415        true = b1 or b2;
    199         (shared,addEqs,idx,changed) = tplIn;
     416        (shared,addEqs,idx,changed,callSign) = tplIn;
    200417        funcs = BackendDAEUtil.getFunctions(shared);
    201         ((rhsExp,lhsExp,addEqs1,funcs,idx,changed1)) = if b1 then evaluateConstantFunction(exp1,exp2,funcs,idx) else (exp2,exp1,{},funcs,idx,changed);
     418        ((rhsExp,lhsExp,addEqs1,funcs,idx,changed1,callSign)) = if b1 then evaluateConstantFunction(exp1,exp2,funcs,idx,callSign) else (exp2,exp1,{},funcs,idx,changed,callSign);
    202419        changed = changed1 or changed;
    203         ((rhsExp,lhsExp,addEqs2,funcs,idx,changed1)) = if b2 then evaluateConstantFunction(exp2,exp1,funcs,idx) else (rhsExp,lhsExp,{},funcs,idx,changed);
     420        ((rhsExp,lhsExp,addEqs2,funcs,idx,changed1,callSign)) = if b2 then evaluateConstantFunction(exp2,exp1,funcs,idx,callSign) else (rhsExp,lhsExp,{},funcs,idx,changed,callSign);
    204421        changed = changed1 or changed;
    205422        addEqs = listAppend(addEqs1,addEqs);
     
    208425        //if changed then print("FROM EQ "+BackendDump.equationString(eqIn)+"\n");print("GOT EQ "+BackendDump.equationString(eq)+"\n"); end if;
    209426      then
    210         (eq,(shared,addEqs,idx+1,changed));
     427        (eq,(shared,addEqs,idx+1,changed,callSign));
    211428    case(BackendDAE.ARRAY_EQUATION(),_)
    212429      equation
     
    221438        b2 = Expression.containFunctioncall(exp2);
    222439        true = b1 or b2;
    223         (shared,addEqs,idx,changed) = tplIn;
     440        (shared,addEqs,idx,changed,callSign) = tplIn;
    224441        funcs = BackendDAEUtil.getFunctions(shared);
    225         ((rhsExp,lhsExp,addEqs1,funcs,idx,changed1)) = if b1 then evaluateConstantFunction(exp1,exp2,funcs,idx) else (exp2,exp1,{},funcs,idx,changed);
     442        ((rhsExp,lhsExp,addEqs1,funcs,idx,changed1,callSign)) = if b1 then evaluateConstantFunction(exp1,exp2,funcs,idx,callSign) else (exp2,exp1,{},funcs,idx,changed,callSign);
    226443        changed = changed or changed1;
    227         ((rhsExp,lhsExp,addEqs2,funcs,idx,changed1)) = if b2 then evaluateConstantFunction(exp2,exp1,funcs,idx) else (rhsExp,lhsExp,{},funcs,idx,changed);
     444        ((rhsExp,lhsExp,addEqs2,funcs,idx,changed1,callSign)) = if b2 then evaluateConstantFunction(exp2,exp1,funcs,idx,callSign) else (rhsExp,lhsExp,{},funcs,idx,changed,callSign);
    228445        changed = changed or changed1;
    229446        addEqs = listAppend(addEqs1,addEqs);
     
    235452        //if changed then print("FROM EQ "+BackendDump.equationString(eqIn)+"\n");print("GOT EQ "+BackendDump.equationString(eq)+"\n"); end if;
    236453      then
    237         (eq,(shared,addEqs,idx+1,changed));
     454        (eq,(shared,addEqs,idx+1,changed,callSign));
    238455    else
    239456        (eqIn,tplIn);
     
    393610  input DAE.FunctionTree funcsIn;
    394611  input Integer eqIdx;
    395   output tuple<DAE.Exp, DAE.Exp, list<BackendDAE.Equation>, DAE.FunctionTree,Integer,Boolean> outTpl;  //rhs,lhs,addEqs,funcTre,idx,haschanged
    396 algorithm
    397   outTpl := matchcontinue(rhsExpIn,lhsExpIn,funcsIn,eqIdx)
     612  input list<CallSignature> callSignLstIn;
     613  output tuple<DAE.Exp, DAE.Exp, list<BackendDAE.Equation>, DAE.FunctionTree,Integer,Boolean, list<CallSignature>> outTpl;  //rhs,lhs,addEqs,funcTre,idx,haschanged
     614algorithm
     615  outTpl := matchcontinue(rhsExpIn,lhsExpIn,funcsIn,eqIdx,callSignLstIn)
    398616    local
    399617      Boolean funcIsConst, funcIsPartConst, isConstRec, hasAssert, hasReturn, hasTerminate, hasReinit, abort, changed;
     
    419637      list<String> outputVarNames;
    420638      list<list<DAE.ComponentRef>> scalarInputs, scalarOutputs;
    421     case(DAE.CALL(path=path, expLst=expsIn, attr=attr1),_,_,_)
     639      CallSignature signature;
     640      list<CallSignature> callSignLst;
     641      Boolean continueEval;
     642    case(DAE.CALL(path=path, expLst=expsIn, attr=attr1),_,_,_,callSignLst)
    422643      equation
    423644
     
    425646          print("\nStart function evaluation of:\n"+ExpressionDump.printExpStr(lhsExpIn)+" := "+ExpressionDump.printExpStr(rhsExpIn)+"\n\n");
    426647        end if;
     648
     649        //------------------------------------------------
     650        //Check if this particular call signature has been analysed before
     651        //------------------------------------------------
     652          //print(stringDelimitList(List.map(callSignLst,callSignatureStr),"\n"));
     653        continueEval = checkCallSignatureForExp(rhsExpIn,callSignLst);
     654        if not continueEval and Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("THIS FUNCTION CALL WITH THIS SPECIFIC SIGNATURE CANNOT BE EVALUTED\n"); end if;
     655        if not continueEval then fail(); end if;
    427656
    428657        //------------------------------------------------
     
    543772        funcIsPartConst = if hasAssert and funcIsConst then true else funcIsPartConst;
    544773        funcIsPartConst = if abort then false else funcIsPartConst;  // quit if there is a return or terminate
     774
    545775        true =  funcIsPartConst or funcIsConst;
     776
     777        signature = getCallSignatureForCall(rhsExpIn);
     778        signature.canBeEvaluated = true;
     779        callSignLst = signature::callSignLst;
    546780        changed = funcIsPartConst or funcIsConst;
    547781
     
    566800        funcs = if funcIsPartConst then DAEUtil.addDaeFunction({func},funcs) else funcs;
    567801        idx = if funcIsPartConst or funcIsConst then (idx+1) else idx;
     802
    568803
    569804        //decide which lhs to take (tuple or 1d)
     
    606841        end if;
    607842      then
    608         ((exp,outputExp,constEqs,funcs,idx,changed));
    609 
    610   case(DAE.ASUB(DAE.CALL(path=path, expLst=exps, attr=attr1),sub),_,_,_)
    611     equation
     843        ((exp,outputExp,constEqs,funcs,idx,changed,callSignLst));
     844
     845  case(DAE.ASUB(DAE.CALL(path=path, expLst=exps, attr=attr1),sub),_,_,_,callSignLst)
     846    equation
     847      exp = DAE.CALL(path=path, expLst=exps, attr=attr1);
     848
     849      //Check if this particular call signature has been analysed before
     850      continueEval = checkCallSignatureForExp(exp,callSignLst);
     851      if not continueEval and Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("THIS FUNCTION CALL WITH THIS SPECIFIC SIGNATURE CANNOT BE EVALUTED\n"); end if;
     852      if not continueEval then fail(); end if;
     853
    612854      //this ASUB stuff occurs in the flattened DAE, check this special case because of removeSimpleEquations
    613       exp = evaluateConstantFunctionCallExp(DAE.CALL(path=path, expLst=exps, attr=attr1),funcsIn);
     855      exp = evaluateConstantFunctionCallExp(exp,funcsIn);
    614856      (exp,_) = ExpressionSimplify.simplify(DAE.ASUB(exp,sub));
    615857
     
    619861        changed=false;
    620862      end if;
    621     then ((exp,lhsExpIn,{},funcsIn,eqIdx,changed));
     863    then ((exp,lhsExpIn,{},funcsIn,eqIdx,changed,callSignLst));
    622864
    623865    else
    624         ((rhsExpIn,lhsExpIn,{},funcsIn,eqIdx,false));
     866      equation
     867        callSignLst = callSignLstIn;
     868        if Expression.isCall(rhsExpIn) then
     869          //Add a call signature for the call that could not been evaluated
     870          signature = getCallSignatureForCall(rhsExpIn);
     871          signature.canBeEvaluated = false;
     872          if not List.isMemberOnTrue(signature,callSignLstIn,callSignatureIsEqual) then
     873            callSignLst = signature::callSignLst;
     874          end if;
     875        end if;
     876      then ((rhsExpIn,lhsExpIn,{},funcsIn,eqIdx,false,callSignLst));
    625877  end matchcontinue;
    626878end evaluateConstantFunction;
     
    18612113
    18622114        exp2 = DAE.TUPLE(expLst);
    1863         ((exp1,exp2,addEqs,funcTree2,idx,_)) = evaluateConstantFunction(exp1,exp2,funcTree,idx);
     2115        ((exp1,exp2,addEqs,funcTree2,idx,_,_)) = evaluateConstantFunction(exp1,exp2,funcTree,idx,{});
    18642116        //print("\nthe LHS after\n");
    18652117        //print(ExpressionDump.printExpStr(exp2));
     
    24682720      DAE.Exp rhs, lhs;
    24692721      DAE.FunctionTree funcs;
    2470       DAE.Type ty;
    24712722      list<BackendDAE.Equation> addEqs;
    24722723      list<DAE.Statement> stmts,stmtsIn;
    24732724  case (DAE.CALL(),(lhs,funcs,idx,stmtsIn))
    24742725    equation
    2475       ((rhs,lhs,addEqs,funcs,idx,_)) = evaluateConstantFunction(inExp,lhs,funcs,idx);
     2726      ((rhs,lhs,addEqs,funcs,idx,_,_)) = evaluateConstantFunction(inExp,lhs,funcs,idx,{});
    24762727      stmts = List.map(addEqs,equationToStmt);
    24772728      stmts = listAppend(stmts,stmtsIn);
    24782729    then (rhs,true,(lhs,funcs,idx,stmts));
    24792730
    2480   case (DAE.UNBOX(exp=rhs, ty=ty),(lhs,funcs,idx,stmts))
     2731  case (DAE.UNBOX(exp=rhs),_)
    24812732    equation
    24822733      (rhs,_,(lhs,funcs,idx,stmts)) = evaluateConstantFunctionWrapper(rhs,inTpl);
Note: See TracChangeset for help on using the changeset viewer.