Quellcode durchsuchen

* also perform "SSA" for certain loads (currently derefn, righthand side of
assignmentn and callparan), reduces number of long lived conflicts.
Mainly helpful on register-starved cpus such as i386.

git-svn-id: trunk@4606 -

Jonas Maebe vor 19 Jahren
Ursprung
Commit
6997121c18
6 geänderte Dateien mit 54 neuen und 5 gelöschten Zeilen
  1. 7 0
      compiler/ncgadd.pas
  2. 2 0
      compiler/ncgcal.pas
  3. 5 1
      compiler/ncginl.pas
  4. 2 1
      compiler/ncgld.pas
  5. 1 0
      compiler/ncgmem.pas
  6. 37 3
      compiler/ncgutil.pas

+ 7 - 0
compiler/ncgadd.pas

@@ -375,6 +375,7 @@ interface
       var
         cgop    : TOpCg;
         otl,ofl : tasmlabel;
+        oldflowcontrol : tflowcontrol;
       begin
         { And,Or will only evaluate from left to right only the
           needed nodes unless full boolean evaluation is enabled }
@@ -405,8 +406,14 @@ interface
               else
                 internalerror(200307044);
             end;
+            { these jumps mean we're now in a flow control construct }
+            oldflowcontrol:=flowcontrol;
+            include(flowcontrol,fc_inflowcontrol);
+
             secondpass(right);
             maketojumpbool(current_asmdata.CurrAsmList,right,lr_load_regvars);
+
+            flowcontrol:=oldflowcontrol+(flowcontrol-[fc_inflowcontrol]);
           end
         else
           begin

+ 2 - 0
compiler/ncgcal.pas

@@ -370,6 +370,8 @@ implementation
              current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
              secondpass(left);
 
+             maybechangeloadnodereg(current_asmdata.CurrAsmList,left,true);
+
              { release memory for refcnt out parameters }
              if (parasym.varspez=vs_out) and
                 (left.resulttype.def.needs_inittable) then

+ 5 - 1
compiler/ncginl.pas

@@ -400,6 +400,11 @@ implementation
         begin
           { set defaults }
           addconstant:=true;
+          { first secondpass second argument, because if the first arg }
+          { is used in that expression then SSL may move it to another }
+          { register                                                   }
+          if assigned(tcallparanode(left).right) then
+            secondpass(tcallparanode(tcallparanode(left).right).left);
           { load first parameter, must be a reference }
           secondpass(tcallparanode(left).left);
           cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
@@ -421,7 +426,6 @@ implementation
           { second_ argument specified?, must be a s32bit in register }
           if assigned(tcallparanode(left).right) then
             begin
-              secondpass(tcallparanode(tcallparanode(left).right).left);
               { when constant, just multiply the addvalue }
               if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
                  addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)

+ 2 - 1
compiler/ncgld.pas

@@ -558,7 +558,8 @@ implementation
         else
           begin
             { SSA support }
-            maybechangeloadnodereg(left);
+            maybechangeloadnodereg(current_asmdata.CurrAsmList,left,false);
+            maybechangeloadnodereg(current_asmdata.CurrAsmList,right,true);
             case right.location.loc of
               LOC_CONSTANT :
                 begin

+ 1 - 0
compiler/ncgmem.pas

@@ -188,6 +188,7 @@ implementation
             LOC_CREGISTER,
             LOC_REGISTER:
               begin
+                maybechangeloadnodereg(current_asmdata.CurrAsmList,left,true);
               {$ifdef cpu_uses_separate_address_registers}
                 if getregtype(left.location.register)<>R_ADDRESSREGISTER then
                   begin

+ 37 - 3
compiler/ncgutil.pas

@@ -102,8 +102,9 @@ interface
     procedure gen_sync_regvars(list:TAsmList; var rv: tusedregvars);
 
     { if the result of n is a LOC_C(..)REGISTER, try to find the corresponding }
-    { loadn and change its location to a new register (= SSA)                  }
-    procedure maybechangeloadnodereg(var n: tnode);
+    { loadn and change its location to a new register (= SSA). In case reload  }
+    { is true, transfer the old to the new register                            }
+    procedure maybechangeloadnodereg(list: TAsmList; var n: tnode; reload: boolean);
 
    {#
       Allocate the buffers for exception management and setjmp environment.
@@ -2466,11 +2467,21 @@ implementation
                   result := fen_norecurse_true;
                 end;
             end;
+          { optimize the searching a bit }
+          derefn,addrn,
+          calln,inlinen,casen,
+          addn,subn,muln,
+          andn,orn,xorn,
+          ltn,lten,gtn,gten,equaln,unequaln,
+          slashn,divn,shrn,shln,notn,
+          inn,
+          asn,isn:
+            result := fen_norecurse_false;
         end;
       end;
 
 
-    procedure maybechangeloadnodereg(var n: tnode);
+    procedure maybechangeloadnodereg(list: TAsmList; var n: tnode; reload: boolean);
       var
         rr: treplaceregrec;
       begin
@@ -2519,6 +2530,29 @@ implementation
         if not foreachnodestatic(n,@doreplace,@rr) then
           exit;
 
+        if reload then
+          case n.location.loc of
+            LOC_CREGISTER:
+              begin
+      {$ifndef cpu64bit}
+                if (n.location.size in [OS_64,OS_S64]) then
+                  cg64.a_load64_reg_reg(list,n.location.register64,joinreg64(rr.new,rr.newhi))
+                else
+      {$endif cpu64bit}
+                  cg.a_load_reg_reg(list,n.location.size,n.location.size,n.location.register,rr.new);
+              end;
+            LOC_CFPUREGISTER:
+              cg.a_loadfpu_reg_reg(list,n.location.size,n.location.register,rr.new);
+      {$ifdef SUPPORT_MMX}
+            LOC_CMMXREGISTER:
+              cg.a_loadmm_reg_reg(list,OS_M64,OS_M64,n.location.register,rr.new,nil);
+      {$endif SUPPORT_MMX}
+            LOC_CMMREGISTER:
+              cg.a_loadmm_reg_reg(list,n.location.size,n.location.size,n.location.register,rr.new,nil);
+            else
+              internalerror(2006090920);
+          end;
+
         { now that we've change the loadn/temp, also change the node result location }
       {$ifndef cpu64bit}
         if (n.location.size in [OS_64,OS_S64]) then