From 562a45f2e1e391ebe9a7ac86dbb4267c1e32a0a4 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 29 Jul 2012 21:29:07 +0000 Subject: [PATCH] * try to transform the tree to be able to do better cse git-svn-id: trunk@21986 - --- compiler/optcse.pas | 50 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/compiler/optcse.pas b/compiler/optcse.pas index e2a92703bd..3efaa92fa3 100644 --- a/compiler/optcse.pas +++ b/compiler/optcse.pas @@ -221,14 +221,60 @@ unit optcse; statements : tstatementnode; hp : ttempcreatenode; addrstored : boolean; + hp2 : tnode; begin result:=fen_false; if n.nodetype in cseinvariant then begin csedomain:=true; foreachnodestatic(pm_postprocess,n,@searchsubdomain,@csedomain); - { found a cse domain } - if csedomain then + if not(csedomain) then + begin + { try to transform the tree to get better cse domains, consider: + + + / \ + + C + / \ + A B + + if A is not cse'able but B and C are, then the compiler cannot do cse so the tree is transformed into + + + / \ + A + + / \ + B C + Because A could be another tree of this kind, the whole process is done in a while loop + } + if (n.nodetype in [andn,orn,addn,muln]) then + while n.nodetype=tbinarynode(n).left.nodetype do + begin + csedomain:=true; + foreachnodestatic(pm_postprocess,tbinarynode(n).right,@searchsubdomain,@csedomain); + if csedomain then + begin + csedomain:=true; + foreachnodestatic(pm_postprocess,tbinarynode(tbinarynode(n).left).right,@searchsubdomain,@csedomain); + if csedomain then + begin + hp2:=tbinarynode(tbinarynode(n).left).left; + tbinarynode(tbinarynode(n).left).left:=tbinarynode(tbinarynode(n).left).right; + tbinarynode(tbinarynode(n).left).right:=tbinarynode(n).right; + tbinarynode(n).right:=tbinarynode(n).left; + tbinarynode(n).left:=hp2; + + { the transformed tree could result in new possibilities to fold constants + so force a firstpass on the root node } + exclude(tbinarynode(n).right.flags,nf_pass1_done); + do_firstpass(tbinarynode(n).right); + end + else + break; + end + else + break; + end; + end + else begin statements:=nil; result:=fen_norecurse_true;