Skip to content

Commit

Permalink
- After suggestion by Adrian, order the pattern-matching in a smarter…
Browse files Browse the repository at this point in the history
… way: do cheap patterns before more complex ones

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@19074 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Feb 12, 2014
1 parent 4011c66 commit dfd56c5
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
66 changes: 66 additions & 0 deletions Compiler/FrontEnd/Patternm.mo
Expand Up @@ -2118,4 +2118,70 @@ algorithm
ctor := ix+3;
end getValueCtor;

public function sortPatternsByComplexity
input list<DAE.Pattern> inPatterns;
output list<tuple<DAE.Pattern,Integer>> outPatterns;
algorithm
outPatterns := List.toListWithPositions(inPatterns,0,{});
outPatterns := List.sort(outPatterns, sortPatternsByComplexityWork);
end sortPatternsByComplexity;

protected function sortPatternsByComplexityWork
input tuple<DAE.Pattern,Integer> tpl1;
input tuple<DAE.Pattern,Integer> tpl2;
output Boolean greater;
protected
DAE.Pattern pat1,pat2;
Integer i1,i2,c1,c2;
algorithm
(pat1,i1) := tpl1;
(pat2,i2) := tpl2;
((_,c1)) := traversePattern((pat1,0),patternComplexity);
((_,c2)) := traversePattern((pat2,0),patternComplexity);
// If both complexities are equal, keep the original ordering
// If c1 is 0, and c2 is not 0 we move the left pattern to the end.
// Else we move the cheaper pattern to the beginning
greater := Util.if_(c1 == c2, i1 > i2, Util.if_(c2 == 0, false, Util.if_(c1 == 0, true, c1 > c2)));
end sortPatternsByComplexityWork;

protected function patternComplexity
input tuple<DAE.Pattern,Integer> inTpl;
output tuple<DAE.Pattern,Integer> outTpl;
algorithm
outTpl := match inTpl
local
DAE.Pattern p;
DAE.Exp exp;
Integer i;
case ((p as DAE.PAT_CONSTANT(exp=exp),i))
equation
((_,i)) = Expression.traverseExp(exp,constantComplexity,i);
then ((p,i));
case ((p as DAE.PAT_CONS(head=_),i))
then ((p,i+5));
case ((p as DAE.PAT_CALL(knownSingleton=false),i))
then ((p,i+5));
case ((p as DAE.PAT_SOME(pat=_),i))
then ((p,i+5));
else inTpl;
end match;
end patternComplexity;

protected function constantComplexity
input tuple<DAE.Exp,Integer> inTpl;
output tuple<DAE.Exp,Integer> outTpl;
algorithm
outTpl := match inTpl
local
DAE.Exp e;
String str;
Integer i;
case ((e as DAE.SCONST(str),i)) then ((e,i+5+stringLength(str)));
case ((e as DAE.ICONST(_),i)) then ((e,i+1));
case ((e as DAE.BCONST(_),i)) then ((e,i+1));
case ((e as DAE.RCONST(_),i)) then ((e,i+2));
case ((e,i)) then ((e,i+5)); // lists and such; add a little something in addition to its members....
end match;
end constantComplexity;

end Patternm;
2 changes: 1 addition & 1 deletion Compiler/Template/CodegenC.tpl
Expand Up @@ -9307,7 +9307,7 @@ template daeExpMatchCases(list<MatchCase> cases, list<Exp> tupleAssignExps, DAE.
let &assignments = buffer ""
let &preRes = buffer ""
let &varFrees = buffer "" /*BUFF*/
let patternMatching = (c.patterns |> lhs hasindex i0 => patternMatch(lhs,'<%getTempDeclMatchInputName(inputs, prefix, startIndexInputs, i0)%>',onPatternFail,&varDeclsCaseInner,&assignments); empty)
let patternMatching = (sortPatternsByComplexity(c.patterns) |> (lhs,i0) => patternMatch(lhs,'<%getTempDeclMatchInputName(inputs, prefix, startIndexInputs, i0)%>',onPatternFail,&varDeclsCaseInner,&assignments); empty)
let() = System.tmpTickSetIndex(startTmpTickIndex,1)
let stmts = (c.body |> stmt => algStatement(stmt, context, &varDeclsCaseInner); separator="\n")
let &preGuardCheck = buffer ""
Expand Down
4 changes: 4 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -2582,6 +2582,10 @@ package Patternm
input Integer ix;
output Integer ctor;
end getValueCtor;
function sortPatternsByComplexity
input list<DAE.Pattern> inPatterns;
output list<tuple<DAE.Pattern,Integer>> outPatterns;
end sortPatternsByComplexity;
end Patternm;

package Error
Expand Down
16 changes: 15 additions & 1 deletion Compiler/Util/List.mo
Expand Up @@ -9454,7 +9454,6 @@ algorithm
end match;
end removeEqualPrefix2;


public function listIsLonger "outputs true if the lst1 is longer than lst2"
input list<ElementType> lst1;
input list<ElementType> lst2;
Expand All @@ -9463,4 +9462,19 @@ algorithm
isLonger := intGt(listLength(lst1),listLength(lst2));
end listIsLonger;

public function toListWithPositions
input list<ElementType> inList;
input Integer curPos;
input list<tuple<ElementType,Integer>> acc;
output list<tuple<ElementType,Integer>> outList;
algorithm
outList := match (inList,curPos,acc)
local
ElementType el;
list<ElementType> rest;
case ({},_,_) then listReverse(acc);
case (el::rest,_,_) then toListWithPositions(rest,curPos+1,(el,curPos)::acc);
end match;
end toListWithPositions;

end List;

0 comments on commit dfd56c5

Please sign in to comment.