Browse Source

* TAddNode.Simplify now uses pruning methods

J. Gareth "Curious Kit" Moreton 2 years ago
parent
commit
9d8fd6d55e
1 changed files with 63 additions and 66 deletions
  1. 63 66
      compiler/nadd.pas

+ 63 - 66
compiler/nadd.pas

@@ -817,13 +817,13 @@ implementation
           end;
           end;
 
 
         { Add,Sub,Mul,Or,Xor,Andn with constant 0, 1 or -1?  }
         { Add,Sub,Mul,Or,Xor,Andn with constant 0, 1 or -1?  }
-        if is_constintnode(right) and (is_integer(left.resultdef) or is_pointer(left.resultdef)) then
+        if is_constintnode(right) and (is_integer(ld) or is_pointer(ld)) then
           begin
           begin
             if (tordconstnode(right).value = 0) and (nodetype in [addn,subn,orn,xorn,andn,muln]) then
             if (tordconstnode(right).value = 0) and (nodetype in [addn,subn,orn,xorn,andn,muln]) then
               begin
               begin
                 case nodetype of
                 case nodetype of
                   addn,subn,orn,xorn:
                   addn,subn,orn,xorn:
-                    result := left.getcopy;
+                    result := PruneKeepLeft();
                   andn,muln:
                   andn,muln:
                     begin
                     begin
                       if (cs_opt_level4 in current_settings.optimizerswitches) or
                       if (cs_opt_level4 in current_settings.optimizerswitches) or
@@ -839,10 +839,10 @@ implementation
               { insert type conversion in case it is a 32*32 to 64 bit multiplication optimization,
               { insert type conversion in case it is a 32*32 to 64 bit multiplication optimization,
                 the type conversion does not hurt because it is normally removed later on
                 the type conversion does not hurt because it is normally removed later on
               }
               }
-              result := ctypeconvnode.create_internal(left.getcopy,resultdef)
+              result := ctypeconvnode.create_internal(PruneKeepLeft(),resultdef)
 
 
             else if (tordconstnode(right).value = -1) and (nodetype=muln) then
             else if (tordconstnode(right).value = -1) and (nodetype=muln) then
-              result := ctypeconvnode.create_internal(cunaryminusnode.create(left.getcopy),left.resultdef)
+              result := ctypeconvnode.create_internal(cunaryminusnode.create(PruneKeepLeft()),ld)
 
 
             { try to fold
             { try to fold
                           op                         op
                           op                         op
@@ -854,7 +854,7 @@ implementation
             else if (left.nodetype=nodetype) and
             else if (left.nodetype=nodetype) and
               { there might be a mul operation e.g. longint*longint => int64 in this case
               { there might be a mul operation e.g. longint*longint => int64 in this case
                 we cannot do this optimziation, see e.g. tests/webtbs/tw36587.pp on arm }
                 we cannot do this optimziation, see e.g. tests/webtbs/tw36587.pp on arm }
-              (compare_defs(resultdef,left.resultdef,nothingn)=te_exact) then
+              (compare_defs(resultdef,ld,nothingn)=te_exact) then
               begin
               begin
                 if is_constintnode(taddnode(left).left) then
                 if is_constintnode(taddnode(left).left) then
                   begin
                   begin
@@ -886,15 +886,15 @@ implementation
             if assigned(result) then
             if assigned(result) then
               exit;
               exit;
           end;
           end;
-        if is_constintnode(left) and (is_integer(right.resultdef) or is_pointer(right.resultdef)) then
+        if is_constintnode(left) and (is_integer(rd) or is_pointer(rd)) then
           begin
           begin
             if (tordconstnode(left).value = 0) and (nodetype in [addn,orn,xorn,subn,andn,muln]) then
             if (tordconstnode(left).value = 0) and (nodetype in [addn,orn,xorn,subn,andn,muln]) then
               begin
               begin
                 case nodetype of
                 case nodetype of
                   addn,orn,xorn:
                   addn,orn,xorn:
-                    result := right.getcopy;
+                    result := PruneKeepRight();
                   subn:
                   subn:
-                    result := ctypeconvnode.create_internal(cunaryminusnode.create(right.getcopy),right.resultdef);
+                    result := ctypeconvnode.create_internal(cunaryminusnode.create(PruneKeepRight()),rd);
                   andn,muln:
                   andn,muln:
                     begin
                     begin
                       if (cs_opt_level4 in current_settings.optimizerswitches) or
                       if (cs_opt_level4 in current_settings.optimizerswitches) or
@@ -910,10 +910,10 @@ implementation
               { insert type conversion in case it is a 32*32 to 64 bit multiplication optimization,
               { insert type conversion in case it is a 32*32 to 64 bit multiplication optimization,
                 the type conversion does not hurt because it is normally removed later on
                 the type conversion does not hurt because it is normally removed later on
               }
               }
-              result :=  ctypeconvnode.create_internal(right.getcopy,resultdef)
+              result := ctypeconvnode.create_internal(PruneKeepRight(),resultdef)
 
 
             else if (tordconstnode(left).value = -1) and (nodetype=muln) then
             else if (tordconstnode(left).value = -1) and (nodetype=muln) then
-              result := ctypeconvnode.create_internal(cunaryminusnode.create(right.getcopy),right.resultdef)
+              result := ctypeconvnode.create_internal(cunaryminusnode.create(PruneKeepRight()),rd)
 
 
             { try to fold
             { try to fold
                           op
                           op
@@ -925,7 +925,7 @@ implementation
             else if (right.nodetype=nodetype) and
             else if (right.nodetype=nodetype) and
               { there might be a mul operation e.g. longint*longint => int64 in this case
               { there might be a mul operation e.g. longint*longint => int64 in this case
                 we cannot do this optimziation, see e.g. tests/webtbs/tw36587.pp on arm }
                 we cannot do this optimziation, see e.g. tests/webtbs/tw36587.pp on arm }
-              (compare_defs(resultdef,right.resultdef,nothingn)=te_exact)  then
+              (compare_defs(resultdef,rd,nothingn)=te_exact)  then
               begin
               begin
                 if is_constintnode(taddnode(right).left) then
                 if is_constintnode(taddnode(right).left) then
                   begin
                   begin
@@ -963,9 +963,16 @@ implementation
           (left.isequal(tmoddivnode(right).left)) and not(might_have_sideeffects(left)) { and
           (left.isequal(tmoddivnode(right).left)) and not(might_have_sideeffects(left)) { and
 	  not(cs_check_overflow in localswitches) } then
 	  not(cs_check_overflow in localswitches) } then
           begin
           begin
-            result:=caddnode.create(muln,cmoddivnode.create(divn,left,tmoddivnode(right).right.getcopy),tmoddivnode(right).right);
-            left:=nil;
-            tmoddivnode(right).right:=nil;
+            t := tmoddivnode(right).PruneKeepRight();
+            result := caddnode.create(
+              muln,
+              cmoddivnode.create(
+                divn,
+                PruneKeepLeft(),
+                t.getcopy
+              ),
+              t
+            );
             exit;
             exit;
           end;
           end;
 
 
@@ -1024,7 +1031,8 @@ implementation
                   this operation is always valid }
                   this operation is always valid }
                 if (left.nodetype=unaryminusn) then
                 if (left.nodetype=unaryminusn) then
                   begin
                   begin
-                    result:=caddnode.create(subn,right.getcopy,tunaryminusnode(left).left.getcopy);
+                    t := tunaryminusnode(left).PruneKeepLeft();
+                    result:=caddnode.create(subn,PruneKeepRight(),t);
                     exit;
                     exit;
                   end;
                   end;
 
 
@@ -1032,7 +1040,8 @@ implementation
                   this operation is always valid }
                   this operation is always valid }
                 if (right.nodetype=unaryminusn) then
                 if (right.nodetype=unaryminusn) then
                   begin
                   begin
-                    result:=caddnode.create(subn,left.getcopy,tunaryminusnode(right).left.getcopy);
+                    t := tunaryminusnode(right).PruneKeepLeft();
+                    result:=caddnode.create(subn,PruneKeepLeft(),t);
                     exit;
                     exit;
                   end;
                   end;
               end;
               end;
@@ -1041,23 +1050,18 @@ implementation
               this operation is always valid }
               this operation is always valid }
             if (nodetype=subn) and (right.nodetype=unaryminusn) then
             if (nodetype=subn) and (right.nodetype=unaryminusn) then
               begin
               begin
-                result:=caddnode.create(addn,left.getcopy,tunaryminusnode(right).left.getcopy);
-                exit;
-              end;
-
-            { (-left)*(-right) => left*right,
-              this operation is always valid }
-            if (nodetype=muln) and (left.nodetype=unaryminusn) and (right.nodetype=unaryminusn) then
-              begin
-                result:=caddnode.create(muln,tunaryminusnode(left).left.getcopy,tunaryminusnode(right).left.getcopy);
+                t := tunaryminusnode(right).PruneKeepLeft();
+                result:=caddnode.create(addn,PruneKeepLeft(),t);
                 exit;
                 exit;
               end;
               end;
 
 
-            { (-left)/(-right) => left/right,
-              this operation is always valid }
-            if (nodetype=slashn) and (left.nodetype=unaryminusn) and (right.nodetype=unaryminusn) then
+            { (-left)*(-right) => left*right, and
+              (-left)/(-right) => left/right,
+              these operations are always valid }
+            if (nodetype in [muln,slashn]) and (left.nodetype=unaryminusn) and (right.nodetype=unaryminusn) then
               begin
               begin
-                result:=caddnode.create(slashn,tunaryminusnode(left).left.getcopy,tunaryminusnode(right).left.getcopy);
+                t := tunaryminusnode(right).PruneKeepLeft();
+                result:=caddnode.create(nodetype,tunaryminusnode(left).PruneKeepLeft(),t);
                 exit;
                 exit;
               end;
               end;
 
 
@@ -1076,7 +1080,7 @@ implementation
                               { -0.0+(+0.0)=+0.0 so we cannot carry out this optimization if no fastmath is passed }
                               { -0.0+(+0.0)=+0.0 so we cannot carry out this optimization if no fastmath is passed }
                               if not(cs_opt_fastmath in current_settings.optimizerswitches) then
                               if not(cs_opt_fastmath in current_settings.optimizerswitches) then
                                 begin
                                 begin
-                                  result:=right.getcopy;
+                                  result:=PruneKeepRight();
                                   exit;
                                   exit;
                                 end;
                                 end;
                             end;
                             end;
@@ -1084,12 +1088,13 @@ implementation
                           muln:
                           muln:
                             if not(might_have_sideeffects(right,[mhs_exceptions])) then
                             if not(might_have_sideeffects(right,[mhs_exceptions])) then
                               begin
                               begin
-                                result:=left.getcopy;
+                                result:=PruneKeepLeft;
                                 exit;
                                 exit;
                               end;
                               end;
                           subn:
                           subn:
                             begin
                             begin
-                              result:=ctypeconvnode.create_internal(cunaryminusnode.create(right.getcopy),right.resultdef);
+                              t := PruneKeepRight();
+                              result:=ctypeconvnode.create_internal(cunaryminusnode.create(t),rd);
                               exit;
                               exit;
                             end;
                             end;
                           else
                           else
@@ -1149,9 +1154,9 @@ implementation
                   begin
                   begin
                     case nodetype of
                     case nodetype of
                       subn:
                       subn:
-                        result:=crealconstnode.create(0,left.resultdef);
+                        result:=crealconstnode.create(0,ld);
                       slashn:
                       slashn:
-                        result:=crealconstnode.create(1,left.resultdef);
+                        result:=crealconstnode.create(1,ld);
                       else
                       else
                         Internalerror(2020060901);
                         Internalerror(2020060901);
                     end;
                     end;
@@ -1168,9 +1173,9 @@ implementation
           folded }
           folded }
         if (nodetype=slashn) and
         if (nodetype=slashn) and
           { do not mess with currency and comp types }
           { do not mess with currency and comp types }
-          (not(is_currency(right.resultdef)) and
-           not((right.resultdef.typ=floatdef) and
-               (tfloatdef(right.resultdef).floattype=s64comp)
+          (not(is_currency(rd)) and
+           not((rd.typ=floatdef) and
+               (tfloatdef(rd).floattype=s64comp)
               )
               )
           ) and
           ) and
           (((cs_opt_fastmath in current_settings.optimizerswitches) and (rt=ordconstn)) or
           (((cs_opt_fastmath in current_settings.optimizerswitches) and (rt=ordconstn)) or
@@ -1381,7 +1386,7 @@ implementation
 
 
         { in case of expressions having no side effect, we can simplify boolean expressions
         { in case of expressions having no side effect, we can simplify boolean expressions
           containing constants }
           containing constants }
-        if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
+        if is_boolean(ld) and is_boolean(rd) then
           begin
           begin
             if is_constboolnode(left) then
             if is_constboolnode(left) then
               begin
               begin
@@ -1389,22 +1394,19 @@ implementation
                   ((nodetype=orn) and (tordconstnode(left).value=0)) or
                   ((nodetype=orn) and (tordconstnode(left).value=0)) or
                   ((nodetype=xorn) and (tordconstnode(left).value=0)) then
                   ((nodetype=xorn) and (tordconstnode(left).value=0)) then
                   begin
                   begin
-                    result:=right;
-                    right:=nil;
+                    Result := PruneKeepRight();
                     exit;
                     exit;
                   end
                   end
                 else if not(might_have_sideeffects(right)) and
                 else if not(might_have_sideeffects(right)) and
                   (((nodetype=orn) and (tordconstnode(left).value<>0)) or
                   (((nodetype=orn) and (tordconstnode(left).value<>0)) or
                   ((nodetype=andn) and (tordconstnode(left).value=0))) then
                   ((nodetype=andn) and (tordconstnode(left).value=0))) then
                   begin
                   begin
-                    result:=left;
-                    left:=nil;
+                    Result := PruneKeepLeft();
                     exit;
                     exit;
                   end
                   end
                 else if ((nodetype=xorn) and (tordconstnode(left).value<>0)) then
                 else if ((nodetype=xorn) and (tordconstnode(left).value<>0)) then
                   begin
                   begin
-                    result:=cnotnode.create(right);
-                    right:=nil;
+                    Result := cnotnode.create(PruneKeepRight());
                     exit;
                     exit;
                   end
                   end
               end
               end
@@ -1414,22 +1416,19 @@ implementation
                   ((nodetype=orn) and (tordconstnode(right).value=0)) or
                   ((nodetype=orn) and (tordconstnode(right).value=0)) or
                   ((nodetype=xorn) and (tordconstnode(right).value=0)) then
                   ((nodetype=xorn) and (tordconstnode(right).value=0)) then
                   begin
                   begin
-                    result:=left;
-                    left:=nil;
+                    result := PruneKeepLeft();
                     exit;
                     exit;
                   end
                   end
                 else if not(might_have_sideeffects(left)) and
                 else if not(might_have_sideeffects(left)) and
                   (((nodetype=orn) and (tordconstnode(right).value<>0)) or
                   (((nodetype=orn) and (tordconstnode(right).value<>0)) or
                    ((nodetype=andn) and (tordconstnode(right).value=0))) then
                    ((nodetype=andn) and (tordconstnode(right).value=0))) then
                   begin
                   begin
-                    result:=right;
-                    right:=nil;
+                    result := PruneKeepRight();
                     exit;
                     exit;
                   end
                   end
                 else if ((nodetype=xorn) and (tordconstnode(right).value<>0)) then
                 else if ((nodetype=xorn) and (tordconstnode(right).value<>0)) then
                   begin
                   begin
-                    result:=cnotnode.create(left);
-                    left:=nil;
+                    result := cnotnode.create(PruneKeepLeft());
                     exit;
                     exit;
                   end
                   end
               end;
               end;
@@ -1493,7 +1492,7 @@ implementation
                 if (left.nodetype=addn) and
                 if (left.nodetype=addn) and
                   (nodetype=subn) and
                   (nodetype=subn) and
                   (cs_opt_fastmath in current_settings.optimizerswitches) and (rt=realconstn) and (taddnode(left).right.nodetype=realconstn) and
                   (cs_opt_fastmath in current_settings.optimizerswitches) and (rt=realconstn) and (taddnode(left).right.nodetype=realconstn) and
-                  (compare_defs(resultdef,left.resultdef,nothingn)=te_exact) then
+                  (compare_defs(resultdef,ld,nothingn)=te_exact) then
                   begin
                   begin
                     Result:=getcopy;
                     Result:=getcopy;
                     Result.nodetype:=addn;
                     Result.nodetype:=addn;
@@ -1505,7 +1504,7 @@ implementation
                 if (left.nodetype=subn) and
                 if (left.nodetype=subn) and
                   (nodetype=addn) and
                   (nodetype=addn) and
                   (cs_opt_fastmath in current_settings.optimizerswitches) and (rt=realconstn) and (taddnode(left).right.nodetype=realconstn) and
                   (cs_opt_fastmath in current_settings.optimizerswitches) and (rt=realconstn) and (taddnode(left).right.nodetype=realconstn) and
-                  (compare_defs(resultdef,left.resultdef,nothingn)=te_exact) then
+                  (compare_defs(resultdef,ld,nothingn)=te_exact) then
                   begin
                   begin
                     Result:=getcopy;
                     Result:=getcopy;
                     taddnode(Result).left.nodetype:=addn;
                     taddnode(Result).left.nodetype:=addn;
@@ -1526,7 +1525,7 @@ implementation
                   (((nodetype=addn) and ((rt=stringconstn) or is_constcharnode(right)) and ((taddnode(left).right.nodetype=stringconstn) or is_constcharnode(taddnode(left).right))) or
                   (((nodetype=addn) and ((rt=stringconstn) or is_constcharnode(right)) and ((taddnode(left).right.nodetype=stringconstn) or is_constcharnode(taddnode(left).right))) or
                    ((nodetype in [addn,muln,subn]) and (cs_opt_fastmath in current_settings.optimizerswitches) and (rt=realconstn) and (taddnode(left).right.nodetype=realconstn))
                    ((nodetype in [addn,muln,subn]) and (cs_opt_fastmath in current_settings.optimizerswitches) and (rt=realconstn) and (taddnode(left).right.nodetype=realconstn))
                   ) and
                   ) and
-                  (compare_defs(resultdef,left.resultdef,nothingn)=te_exact) then
+                  (compare_defs(resultdef,ld,nothingn)=te_exact) then
                   begin
                   begin
                     { SwapRightWithLeftLeft moves the nodes around in way that we need to insert a minus
                     { SwapRightWithLeftLeft moves the nodes around in way that we need to insert a minus
                       on left.right: a-b-c becomes b-c-a so we
                       on left.right: a-b-c becomes b-c-a so we
@@ -1561,7 +1560,7 @@ implementation
                   (((nodetype=addn) and ((lt=stringconstn) or is_constcharnode(left)) and ((taddnode(right).left.nodetype=stringconstn) or is_constcharnode(taddnode(right).left))) or
                   (((nodetype=addn) and ((lt=stringconstn) or is_constcharnode(left)) and ((taddnode(right).left.nodetype=stringconstn) or is_constcharnode(taddnode(right).left))) or
                    ((nodetype in [addn,muln]) and (cs_opt_fastmath in current_settings.optimizerswitches) and (lt=realconstn) and (taddnode(right).left.nodetype=realconstn))
                    ((nodetype in [addn,muln]) and (cs_opt_fastmath in current_settings.optimizerswitches) and (lt=realconstn) and (taddnode(right).left.nodetype=realconstn))
                   ) and
                   ) and
-                  (compare_defs(resultdef,right.resultdef,nothingn)=te_exact) then
+                  (compare_defs(resultdef,rd,nothingn)=te_exact) then
                   begin
                   begin
                     Result:=SwapLeftWithRightRight;
                     Result:=SwapLeftWithRightRight;
                     exit;
                     exit;
@@ -1592,7 +1591,7 @@ implementation
               equal if some previous optimizations were done so don't check
               equal if some previous optimizations were done so don't check
               this simplification always
               this simplification always
             }
             }
-            if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
+            if is_boolean(ld) and is_boolean(rd) then
               begin
               begin
                 { transform unsigned comparisons of (v>=x) and (v<=y)
                 { transform unsigned comparisons of (v>=x) and (v<=y)
                   into (v-x)<=(y-x)
                   into (v-x)<=(y-x)
@@ -1687,8 +1686,7 @@ implementation
                     case nodetype of
                     case nodetype of
                       andn,orn:
                       andn,orn:
                         begin
                         begin
-                          result:=left;
-                          left:=nil;
+                          result:=PruneKeepLeft();
                           exit;
                           exit;
                         end;
                         end;
                       {
                       {
@@ -1726,7 +1724,7 @@ implementation
                   end
                   end
               end;
               end;
 
 
-            if is_integer(left.resultdef) and is_integer(right.resultdef) then
+            if is_integer(ld) and is_integer(rd) then
               begin
               begin
                 if (cs_opt_level3 in current_settings.optimizerswitches) and
                 if (cs_opt_level3 in current_settings.optimizerswitches) and
                    left.isequal(right) and not might_have_sideeffects(left) then
                    left.isequal(right) and not might_have_sideeffects(left) then
@@ -1734,8 +1732,7 @@ implementation
                     case nodetype of
                     case nodetype of
                       andn,orn:
                       andn,orn:
                         begin
                         begin
-                          result:=left;
-                          left:=nil;
+                          result:=PruneKeepLeft();
                           exit;
                           exit;
                         end;
                         end;
                       xorn,
                       xorn,
@@ -1776,13 +1773,12 @@ implementation
                (FPUXTENSA_DOUBLE in fpu_capabilities[current_settings.fputype]) and
                (FPUXTENSA_DOUBLE in fpu_capabilities[current_settings.fputype]) and
 {$endif xtensa}
 {$endif xtensa}
                (nodetype=muln) and
                (nodetype=muln) and
-               is_real(left.resultdef) and is_real(right.resultdef) and
+               is_real(ld) and is_real(rd) and
                left.isequal(right) and
                left.isequal(right) and
                not(might_have_sideeffects(left)) then
                not(might_have_sideeffects(left)) then
               begin
               begin
-                result:=cinlinenode.create(in_sqr_real,false,left);
+                result:=cinlinenode.create(in_sqr_real,false,PruneKeepLeft());
                 inserttypeconv(result,resultdef);
                 inserttypeconv(result,resultdef);
-                left:=nil;
                 exit;
                 exit;
               end;
               end;
 {$ifdef cpurox}
 {$ifdef cpurox}
@@ -1792,8 +1788,8 @@ implementation
                and (CPUM68K_HAS_ROLROR in cpu_capabilities[current_settings.cputype])
                and (CPUM68K_HAS_ROLROR in cpu_capabilities[current_settings.cputype])
 {$endif m68k}
 {$endif m68k}
 {$ifndef cpu64bitalu}
 {$ifndef cpu64bitalu}
-               and (left.resultdef.typ=orddef) and
-               not(torddef(left.resultdef).ordtype in [s64bit,u64bit,scurrency])
+               and (ld.typ=orddef) and
+               not(torddef(ld).ordtype in [s64bit,u64bit,scurrency])
 {$endif cpu64bitalu}
 {$endif cpu64bitalu}
               then
               then
               begin
               begin
@@ -1868,7 +1864,7 @@ implementation
                 c xor ((c xor a) and b)
                 c xor ((c xor a) and b)
             }
             }
             if (nodetype=orn) and
             if (nodetype=orn) and
-             (left.resultdef.typ=orddef) and
+             (ld.typ=orddef) and
              (left.nodetype=andn) and
              (left.nodetype=andn) and
              (right.nodetype=andn) and
              (right.nodetype=andn) and
              (not(is_boolean(resultdef)) or not(might_have_sideeffects(self,[mhs_exceptions])) or not(doshortbooleval(self))) and
              (not(is_boolean(resultdef)) or not(might_have_sideeffects(self,[mhs_exceptions])) or not(doshortbooleval(self))) and
@@ -1923,6 +1919,7 @@ implementation
                         else
                         else
                           nt:=equaln;
                           nt:=equaln;
                         result:=caddnode.create(nt,t,cordconstnode.create(0,vl.resultdef,false));
                         result:=caddnode.create(nt,t,cordconstnode.create(0,vl.resultdef,false));
+                        Include(flags, nf_do_not_execute);
                         if t=left then
                         if t=left then
                           left:=nil
                           left:=nil
                         else
                         else