Skip to content

Commit

Permalink
- Added flag +d=checkSimplify, which tries to estimate if the simplif…
Browse files Browse the repository at this point in the history
…ied expression is actually simpler (usually the case) or not (more common than it should be)

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@10597 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Nov 29, 2011
1 parent bdb83cb commit 78cdd8a
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 20 deletions.
11 changes: 11 additions & 0 deletions Compiler/BackEnd/SimCode.mo
Expand Up @@ -12508,4 +12508,15 @@ algorithm
end match;
end setSimCodeLiterals;

protected function eqSystemWCET
"Calculate the estimated worst-case execution time of the system for partitioning"
input list<SimEqSystem> eqs;
output tuple<list<SimEqSystem>,Integer> tpl;
protected
Integer i;
algorithm
(_,i) := traverseExpsEqSystems(eqs, Expression.complexityTraverse, 0, {});
tpl := (eqs,i);
end eqSystemWCET;

end SimCode;
4 changes: 2 additions & 2 deletions Compiler/FrontEnd/DAE.mo
Expand Up @@ -1449,11 +1449,11 @@ uniontype Operator "Operators which are overloaded in the abstract syntax are he
ExpType ty "type of the array" ;
end POW_SCALAR_ARRAY;

record POW_ARR "Power of a matrix"
record POW_ARR "Power of a matrix: {{1,2,3},{4,5.0,6},{7,8,9}}^2"
ExpType ty "type of the array";
end POW_ARR;

record POW_ARR2 "elementwise power of arrays"
record POW_ARR2 "elementwise power of arrays: {1,2,3}.^{3,2,1}"
ExpType ty "type of the array";
end POW_ARR2;

Expand Down
246 changes: 246 additions & 0 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -6841,5 +6841,251 @@ algorithm
end match;
end isTailCall;

public function complexityTraverse
input tuple<DAE.Exp,Integer> tpl;
output tuple<DAE.Exp,Integer> otpl;
protected
DAE.Exp exp;
Integer i;
algorithm
(exp,i) := tpl;
((exp,i)) := traverseExp(exp,complexityTraverse2,i);
otpl := (exp,i);
end complexityTraverse;

protected function complexityTraverse2
input tuple<DAE.Exp,Integer> tpl;
output tuple<DAE.Exp,Integer> otpl;
protected
DAE.Exp exp;
Integer i;
algorithm
(exp,i) := tpl;
i := i+complexity(exp);
otpl := (exp,i);
end complexityTraverse2;

protected constant Integer complexityAlloc = 5;
protected constant Integer complexityVeryBig = 500000 "Things that are too hard to calculate :(";
protected constant Integer complexityDimLarge = 1000 "Unknown dimensions usually aren't big, but might be";

public function complexity
input DAE.Exp exp;
output Integer i;
algorithm
i := match exp
local
DAE.Operator op;
DAE.Exp e,e1,e2,e3;
Integer c1,c2,c3;
list<DAE.Exp> exps;
list<list<DAE.Exp>> matrix;
String str,name;
DAE.ExpType tp;
case DAE.ICONST(integer=_) then 0;
case DAE.RCONST(real=_) then 0;
case DAE.SCONST(string=_) then 0;
case DAE.BCONST(bool=_) then 0;
case DAE.SHARED_LITERAL(index=_) then 0;
case DAE.ENUM_LITERAL(index=_) then 0;
case DAE.CREF(ty=tp) then tpComplexity(tp);
case DAE.BINARY(exp1=e1,operator=op,exp2=e2)
equation
c1 = complexity(e1);
c2 = complexity(e2);
c3 = opComplexity(op);
then c1+c2+c3;
case DAE.UNARY(exp=e,operator=op)
equation
c1 = complexity(e);
c2 = opComplexity(op);
then c1+c2;
case DAE.LBINARY(exp1=e1,exp2=e2,operator=op)
equation
c1 = complexity(e1);
c2 = complexity(e2);
c3 = opComplexity(op);
then c1+c2+c3;
case DAE.LUNARY(exp=e,operator=op)
equation
c1 = complexity(e);
c2 = opComplexity(op);
then c1+c2;
case DAE.RELATION(exp1=e1,exp2=e2,operator=op)
equation
c1 = complexity(e1);
c2 = complexity(e2);
c3 = opComplexity(op);
then c1+c2+c3;
case DAE.IFEXP(expCond=e1,expThen=e2,expElse=e3)
equation
c1 = complexity(e1);
c2 = complexity(e2);
c3 = complexity(e3);
then c1+intMax(c2,c3);
case DAE.CALL(path=Absyn.IDENT(name),expLst=exps,attr=DAE.CALL_ATTR(ty=tp,builtin=true))
equation
c1 = List.fold(List.map(exps,complexity),intAdd,0);
c2 = complexityBuiltin(name,tp);
/* TODO: Cost is based on type and size of inputs. Maybe even name for builtins :) */
then c1+c2;
case DAE.CALL(expLst=exps)
equation
c1 = List.fold(List.map(exps,complexity),intAdd,0);
c2 = listLength(exps);
/* TODO: Cost is based on type and size of inputs. Maybe even name for builtins :) */
then c1+c2+25;
case DAE.PARTEVALFUNCTION(ty=_)
then complexityVeryBig; /* This should not be here anyway :) */
case DAE.ARRAY(array=exps,ty=tp)
equation
c1 = List.fold(List.map(exps,complexity),intAdd,Util.if_(isArrayType(tp),0,complexityAlloc));
c2 = listLength(exps);
then c1+c2;
case DAE.MATRIX(matrix=matrix as (exps::_))
equation
c1 = List.fold(List.map(List.flatten(matrix),complexity),intAdd,complexityAlloc);
c2 = listLength(exps)*listLength(matrix);
then c1 + c2;
case DAE.RANGE(exp=e1,range=e2,expOption=NONE())
then complexityDimLarge+complexity(e1)+complexity(e2); /* TODO: Check type maybe? */
case DAE.RANGE(exp=e1,range=e2,expOption=SOME(e3))
then complexityDimLarge+complexity(e1)+complexity(e2)+complexity(e3); /* TODO: Check type maybe? */
case DAE.TUPLE(PR=exps)
equation
c1 = List.fold(List.map(exps,complexity),intAdd,complexityAlloc);
c2 = listLength(exps);
then c1+c2;
case DAE.CAST(exp=e,ty=tp) then tpComplexity(tp)+complexity(e);
case DAE.ASUB(exp=e,sub=exps)
equation
c1 = List.fold(List.map(exps,complexity),intAdd,complexityAlloc);
c2 = listLength(exps);
c3 = complexity(e);
then c1+c2+c3;
case DAE.TSUB(exp=e) then complexity(e)+1;
case DAE.SIZE(exp=e,sz=NONE()) then complexity(e)+complexityAlloc+10; /* TODO: Cost is based on type (creating the array) */
case DAE.SIZE(exp=e1,sz=SOME(e2)) then complexity(e1)+complexity(e2)+1;
case DAE.CODE(ty=_) then complexityVeryBig;
case DAE.EMPTY(ty=_) then complexityVeryBig;
case DAE.REDUCTION(expr=_) then complexityVeryBig; /* TODO: We need a real traversal... */
case DAE.LIST(valList=exps)
equation
c1 = List.fold(List.map(exps,complexity),intAdd,complexityAlloc);
c2 = listLength(exps);
then c1+c2+complexityAlloc;
case DAE.CONS(car=e1,cdr=e2)
then complexityAlloc+complexity(e1)+complexity(e2);
case DAE.META_TUPLE(listExp=exps)
equation
c1 = List.fold(List.map(exps,complexity),intAdd,complexityAlloc);
c2 = listLength(exps);
then complexityAlloc+c1+c2;
case DAE.META_OPTION(exp=NONE()) then 0;
case DAE.META_OPTION(exp=SOME(e)) then complexity(e)+complexityAlloc;
case DAE.METARECORDCALL(args=exps)
equation
c1 = List.fold(List.map(exps,complexity),intAdd,complexityAlloc);
c2 = listLength(exps);
then c1+c2+complexityAlloc;
case DAE.MATCHEXPRESSION(inputs=_) then complexityVeryBig;
case DAE.BOX(exp=e) then complexityAlloc+complexity(e);
case DAE.UNBOX(exp=e) then 1+complexity(e);
case DAE.PATTERN(pattern=_) then 0;
else
equation
str = "Expression.complexityWork failed: " +& ExpressionDump.printExpStr(exp);
Error.addMessage(Error.INTERNAL_ERROR,{str});
then fail();
end match;
end complexity;

protected function complexityBuiltin
input String name;
input DAE.ExpType tp;
output Integer complexity;
algorithm
complexity := match (name,tp)
case ("identity",tp) then complexityAlloc+tpComplexity(tp);
case ("cross",tp) then 3*3;
else 25;
end match;
end complexityBuiltin;

protected function tpComplexity
input DAE.ExpType tp;
output Integer i;
algorithm
i := match tp
local
list<DAE.Dimension> dims;
case DAE.ET_ARRAY(arrayDimensions=dims)
equation
i = List.fold(List.map(dims,dimComplexity),intMul,1);
then i;
else 0;
end match;
end tpComplexity;

protected function dimComplexity
input DAE.Dimension dim;
output Integer i;
algorithm
i := match dim
case DAE.DIM_INTEGER(integer=i) then i;
case DAE.DIM_ENUM(size=i) then i;
else complexityDimLarge;
end match;
end dimComplexity;

protected function opComplexity
input DAE.Operator op;
output Integer i;
algorithm
i := match op
local
DAE.ExpType tp;
case DAE.ADD(ty=DAE.ET_STRING()) then 100;
case DAE.ADD(ty=tp) then 1;
case DAE.SUB(ty=tp) then 1;
case DAE.MUL(ty=tp) then 1;
case DAE.DIV(ty=tp) then 1;
case DAE.POW(ty=tp) then 30;
case DAE.UMINUS(ty=tp) then 1;
/* TODO: Array dims? */
case DAE.UMINUS_ARR(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.ADD_ARR(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.SUB_ARR(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.MUL_ARR(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.DIV_ARR(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.MUL_ARRAY_SCALAR(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.ADD_ARRAY_SCALAR(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.SUB_SCALAR_ARRAY(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.MUL_SCALAR_PRODUCT(ty=tp) then complexityAlloc+3*tpComplexity(tp);
case DAE.MUL_MATRIX_PRODUCT(ty=tp) then complexityAlloc+3*tpComplexity(tp);
case DAE.DIV_ARRAY_SCALAR(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.DIV_SCALAR_ARRAY(ty=tp) then complexityAlloc+tpComplexity(tp);
case DAE.POW_ARRAY_SCALAR(ty=tp) then complexityAlloc+30*tpComplexity(tp);
case DAE.POW_SCALAR_ARRAY(ty=tp) then complexityAlloc+30*tpComplexity(tp);
case DAE.POW_ARR(ty=tp) then complexityAlloc+30*tpComplexity(tp);
case DAE.POW_ARR2(ty=tp) then complexityAlloc+30*tpComplexity(tp);
/* TODO: Array ops? */
case DAE.AND(ty=tp) then 1;
case DAE.OR(ty=tp) then 1;
case DAE.NOT(ty=tp) then 1;
case DAE.LESS(ty=tp) then 1;
case DAE.LESSEQ(ty=tp) then 1;
case DAE.GREATER(ty=tp) then 1;
case DAE.GREATEREQ(ty=tp) then 1;
case DAE.EQUAL(ty=tp) then 1;
case DAE.NEQUAL(ty=tp) then 1;
case DAE.USERDEFINED(fqName=_) then 100;
else
equation
Error.addMessage(Error.INTERNAL_ERROR,{"SimCode.opWCET failed"});
then fail();
end match;
end opComplexity;

end Expression;

27 changes: 27 additions & 0 deletions Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -291,8 +291,35 @@ public function simplify1
output Boolean hasChanged;
algorithm
(outExp,hasChanged) := simplify1FixP(inExp,100,true);
checkSimplify(Flags.isSet(Flags.CHECK_SIMPLIFY),inExp,outExp);
end simplify1;

protected function checkSimplify
"Verifies that the complexity of the expression is lower or equal than before the simplification was performed"
input Boolean check;
input DAE.Exp before;
input DAE.Exp after;
algorithm
_ := matchcontinue (check,before,after)
local
Integer c1,c2;
Boolean b;
String s1,s2,s3,s4;
case (false,_,_) then ();
case (true,before,after)
equation
c1 = Expression.complexity(before);
c2 = Expression.complexity(after);
b = c1 < c2;
s1 = intString(c2);
s2 = intString(c1);
s3 = Debug.bcallret1(b,ExpressionDump.printExpStr,before,"");
s4 = Debug.bcallret1(b,ExpressionDump.printExpStr,after,"");
Error.assertionOrAddSourceMessage(not b, Error.SIMPLIFICATION_COMPLEXITY, {s1,s2,s3,s4}, Absyn.dummyInfo);
then ();
end matchcontinue;
end checkSimplify;

protected function simplify1FixP
"Does fixpoint simplify1 max n times"
input DAE.Exp inExp;
Expand Down
3 changes: 1 addition & 2 deletions Compiler/Script/Interactive.mo
Expand Up @@ -17921,8 +17921,7 @@ end loadFileInteractiveQualified;
/* Start getDefinitions */

protected function getDefinitions
"@author sjoelund.se
This function dumps the defined packages, classes and functions to a string.
"This function dumps the defined packages, classes and functions to a string.
The function is used by org.openmodelica.corba.parser.DefinitionsCreator."
input Absyn.Program ast "The AST to dump";
input Boolean addFunctions;
Expand Down
24 changes: 9 additions & 15 deletions Compiler/Util/Config.mo
Expand Up @@ -139,8 +139,7 @@ algorithm
end helpRequest;

public function acceptedGrammar
"@author: mahge 2011-11-28
returns: the flag number representing the accepted grammer. Instead of using
"returns: the flag number representing the accepted grammer. Instead of using
booleans. This way more extensions can be added easily.
usage: omc [+g=Modelica|MetaModelica|ParModelica] = [1|2|3], default to 'Modelica'."
output Integer outGrammer;
Expand All @@ -149,26 +148,23 @@ algorithm
end acceptedGrammar;

public function acceptMetaModelicaGrammar
"@author: adrpo 2007-06-11
returns: true if MetaModelica grammar is accepted or false otherwise
"returns: true if MetaModelica grammar is accepted or false otherwise
usage: omc [+g=Modelica|MetaModelica|ParModelica], default to 'Modelica'."
output Boolean outBoolean;
algorithm
outBoolean := intEq(Flags.getConfigEnum(Flags.GRAMMAR), Flags.METAMODELICA);
end acceptMetaModelicaGrammar;

public function acceptParModelicaGrammar
"@author: mahge 2011-11-28
returns: true if ParModelica grammar is accepted or false otherwise
"returns: true if ParModelica grammar is accepted or false otherwise
usage: omc [+g=Modelica|MetaModelica|ParModelica], default to 'Modelica'."
output Boolean outBoolean;
algorithm
outBoolean := intEq(Flags.getConfigEnum(Flags.GRAMMAR), Flags.PARMODELICA);
end acceptParModelicaGrammar;

public function getAnnotationVersion
"@author: adrpo 2008-11-28
returns what flag was given at start
"returns what flag was given at start
omc [+annotationVersion=3.x]
or via the API
setAnnotationVersion(\"3.x\");
Expand All @@ -179,20 +175,18 @@ algorithm
end getAnnotationVersion;

public function setAnnotationVersion
"@author: adrpo 2008-11-28
setAnnotationVersion(\"3.x\");
"setAnnotationVersion(\"3.x\");
for annotations: 1.x or 2.x or 3.x"
input String annotationVersion;
algorithm
Flags.setConfigString(Flags.ANNOTATION_VERSION, annotationVersion);
end setAnnotationVersion;

public function getNoSimplify
"@author: adrpo 2008-12-13
returns what flag was given at start
omc [+noSimplify]
or via the API
setNoSimplify(true|false);"
"returns what flag was given at start
omc [+noSimplify]
or via the API
setNoSimplify(true|false);"
output Boolean noSimplify;
algorithm
noSimplify := Flags.getConfigBool(Flags.NO_SIMPLIFY);
Expand Down

0 comments on commit 78cdd8a

Please sign in to comment.