瀏覽代碼

* Ifdefs around a lot of calls to cleartempgen
* Fixed registers that are allocated but not freed in several nodes
* Tweak to register allocator to cause less spills
* 8-bit registers now interfere with esi,edi and ebp
Compiler can now compile rtl successfully when using new register
allocator

daniel 22 年之前
父節點
當前提交
6aa01a99a9
共有 11 個文件被更改,包括 229 次插入52 次删除
  1. 15 5
      compiler/aasmtai.pas
  2. 11 2
      compiler/i386/cpubase.pas
  3. 23 3
      compiler/i386/n386set.pas
  4. 25 2
      compiler/i386/rgcpu.pas
  5. 11 1
      compiler/ncgcal.pas
  6. 11 3
      compiler/ncginl.pas
  7. 15 1
      compiler/ncgset.pas
  8. 37 1
      compiler/nflw.pas
  9. 15 1
      compiler/nset.pas
  10. 11 1
      compiler/pstatmnt.pas
  11. 55 32
      compiler/rgobj.pas

+ 15 - 5
compiler/aasmtai.pas

@@ -1793,10 +1793,12 @@ uses
                   else if Taicpu_abstract(p).oper[i].typ=Top_ref then
                     begin
                       r:=Taicpu_abstract(p).oper[i].ref;
-                      r^.base.number:=(r^.base.number and $ff) or
-                                      (table[r^.base.number shr 8] shl 8);
-                      r^.index.number:=(r^.index.number and $ff) or
-                                       (table[r^.index.number shr 8] shl 8);
+                      if r^.base.number<>NR_NO then
+                        r^.base.number:=(r^.base.number and $ff) or
+                                        (table[r^.base.number shr 8] shl 8);
+                      if r^.index.number<>NR_NO then
+                        r^.index.number:=(r^.index.number and $ff) or
+                                         (table[r^.index.number shr 8] shl 8);
                     end;
                 if Taicpu_abstract(p).is_nop then
                   begin
@@ -1814,7 +1816,15 @@ uses
 end.
 {
   $Log$
-  Revision 1.24  2003-04-24 13:03:01  florian
+  Revision 1.25  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.24  2003/04/24 13:03:01  florian
     * comp is now written with its bit pattern to the ppu instead as an extended
 
   Revision 1.23  2003/04/22 14:33:38  peter

+ 11 - 2
compiler/i386/cpubase.pas

@@ -682,7 +682,8 @@ implementation
           NR_ES:  r.enum:=R_ES;         NR_FS:  r.enum:=R_FS;
           NR_GS:  r.enum:=R_GS;         NR_SS:  r.enum:=R_SS;
         else
-          internalerror(200301082);
+{          internalerror(200301082);}
+          r.enum:=R_TR3;
         end;
     end;
 
@@ -798,7 +799,15 @@ implementation
 end.
 {
   $Log$
-  Revision 1.49  2003-04-22 23:50:23  peter
+  Revision 1.50  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.49  2003/04/22 23:50:23  peter
     * firstpass uses expectloc
     * checks if there are differences between the expectloc and
       location.loc from secondpass in EXTDEBUG

+ 23 - 3
compiler/i386/n386set.pas

@@ -254,6 +254,7 @@ implementation
              {$endif}
                opsize := S_L;
                emit_ref_reg(A_MOVZX,S_BL,left.location.reference,pleftreg);
+               location_release(exprasmlist,left.location);
              end;
 
             { Get a label to jump to the end }
@@ -272,6 +273,7 @@ implementation
             { "x in [y..z]" expression                               }
             adjustment := 0;
 
+            r.enum:=R_NO;
             for i:=1 to numparts do
              if setparts[i].range then
               { use fact that a <= x <= b <=> cardinal(x-a) <= cardinal(b-a) }
@@ -285,13 +287,17 @@ implementation
                       { so in case of a LOC_CREGISTER first move the value }
                       { to edi (not done before because now we can do the  }
                       { move and substract in one instruction with LEA)    }
-                      if (pleftreg.number <> NR_EDI) and
+                      if {$ifndef newra}(pleftreg.number <> NR_EDI) and{$endif}
                          (left.location.loc = LOC_CREGISTER) then
                         begin
+                          rg.ungetregister(exprasmlist,pleftreg);
+                        {$ifdef newra}
+                          r:=rg.getregisterint(exprasmlist,OS_INT);
+                        {$else}
                           r.enum:=R_INTREGISTER;
                           r.number:=NR_EDI;
-                          rg.ungetregister(exprasmlist,pleftreg);
                           rg.getexplicitregisterint(exprasmlist,NR_EDI);
+                        {$endif}
                           reference_reset_base(href,pleftreg,-setparts[i].start);
                           emit_ref_reg(A_LEA,S_L,href,r);
                           { only now change pleftreg since previous value is }
@@ -352,6 +358,11 @@ implementation
              right.location.reference.symbol:=nil;
              { Now place the end label }
              cg.a_label(exprasmlist,l);
+          {$ifdef newra}
+             rg.ungetregisterint(exprasmlist,pleftreg);
+             if r.enum=R_INTREGISTER then
+              rg.ungetregisterint(exprasmlist,r);
+          {$else}
              case left.location.loc of
                LOC_REGISTER,
                LOC_CREGISTER :
@@ -364,6 +375,7 @@ implementation
                    rg.ungetregisterint(exprasmlist,r);
                  end;
              end;
+          {$endif}
           end
          else
           begin
@@ -726,7 +738,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.55  2003-04-23 09:51:16  daniel
+  Revision 1.56  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.55  2003/04/23 09:51:16  daniel
     * Removed usage of edi in a lot of places when new register allocator used
     + Added newra versions of g_concatcopy and secondadd_float
 

+ 25 - 2
compiler/i386/rgcpu.pas

@@ -39,8 +39,8 @@ unit rgcpu;
           fpuvaroffset : byte;
 
           { to keep the same allocation order as with the old routines }
-{$ifndef newra}
           function getregisterint(list:Taasmoutput;size:Tcgsize):Tregister;override;
+{$ifndef newra}
           function getaddressregister(list:Taasmoutput):Tregister;override;
           procedure ungetregisterint(list:Taasmoutput;r:Tregister); override;
           function getexplicitregisterint(list:Taasmoutput;r:Tnewregister):Tregister;override;
@@ -167,6 +167,21 @@ unit rgcpu;
 {                               trgcpu                                   }
 {************************************************************************}
 
+{$ifdef newra}
+    function Trgcpu.getregisterint(list:Taasmoutput;size:Tcgsize):Tregister;
+
+    begin
+      getregisterint:=inherited getregisterint(list,size);
+      if size in [OS_8,OS_S8] then
+        begin
+          {These registers have no 8-bit subregister, so add interferences.}
+          add_edge(getregisterint.number shr 8,RS_ESI);
+          add_edge(getregisterint.number shr 8,RS_EDI);
+          add_edge(getregisterint.number shr 8,RS_EBP);
+        end;
+    end;
+{$endif}
+
 {$ifndef newra}
     function trgcpu.getregisterint(list:Taasmoutput;size:Tcgsize):Tregister;
 
@@ -566,7 +581,15 @@ end.
 
 {
   $Log$
-  Revision 1.20  2003-04-23 14:42:08  daniel
+  Revision 1.21  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.20  2003/04/23 14:42:08  daniel
     * Further register allocator work. Compiler now smaller with new
       allocator than without.
     * Somebody forgot to adjust ppu version number

+ 11 - 1
compiler/ncgcal.pas

@@ -1314,7 +1314,9 @@ implementation
               { inlined code block are (JM)                                    }
               rg.resetusableregisters;
               rg.clearregistercount;
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               if assigned(inlineprocdef.regvarinfo) then
                 with pregvarinfo(inlineprocdef.regvarinfo)^ do
                   for i := 1 to maxvarregs do
@@ -1465,7 +1467,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.51  2003-04-22 23:50:22  peter
+  Revision 1.52  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.51  2003/04/22 23:50:22  peter
     * firstpass uses expectloc
     * checks if there are differences between the expectloc and
       location.loc from secondpass in EXTDEBUG

+ 11 - 3
compiler/ncginl.pas

@@ -349,7 +349,6 @@ implementation
         else
           cg.a_op_const_reg(exprasmlist,cgop,1,location.register);
 
-        cg.g_overflowcheck(exprasmlist,self);
         cg.g_rangecheck(exprasmlist,self,resulttype.def);
       end;
 
@@ -433,8 +432,9 @@ implementation
 {$endif cpu64bit}
                  cg.a_op_reg_loc(exprasmlist,addsubop[inlinenumber],
                    hregister,tcallparanode(left).left.location);
-                 location_release(exprasmlist,tcallparanode(tcallparanode(left).right).left.location);
+               location_release(exprasmlist,tcallparanode(tcallparanode(left).right).left.location);
              end;
+          location_release(exprasmlist,tcallparanode(left).left.location);
           cg.g_overflowcheck(exprasmlist,tcallparanode(left).left);
           cg.g_rangecheck(exprasmlist,tcallparanode(left).left,tcallparanode(left).left.resulttype.def);
         end;
@@ -671,7 +671,15 @@ end.
 
 {
   $Log$
-  Revision 1.26  2003-04-24 22:29:57  florian
+  Revision 1.27  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.26  2003/04/24 22:29:57  florian
     * fixed a lot of PowerPC related stuff
 
   Revision 1.25  2003/04/22 23:50:22  peter

+ 15 - 1
compiler/ncgset.pas

@@ -948,7 +948,9 @@ implementation
               jmp_lt:=OC_B;
               jmp_le:=OC_BE;
            end;
+        {$ifndef newra}
          rg.cleartempgen;
+        {$endif}
          { save current truelabel and falselabel }
          isjump:=false;
          if left.location.loc=LOC_JUMP then
@@ -1070,7 +1072,9 @@ implementation
          hp:=tstatementnode(right);
          while assigned(hp) do
            begin
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               { relabel when inlining }
               if inlining_procedure then
                 begin
@@ -1089,7 +1093,9 @@ implementation
          { ...and the else block }
          if assigned(elseblock) then
            begin
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               secondpass(elseblock);
               load_all_regvars(exprasmlist);
            end;
@@ -1115,7 +1121,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.30  2003-04-22 23:50:23  peter
+  Revision 1.31  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.30  2003/04/22 23:50:23  peter
     * firstpass uses expectloc
     * checks if there are differences between the expectloc and
       location.loc from secondpass in EXTDEBUG

+ 37 - 1
compiler/nflw.pas

@@ -400,7 +400,9 @@ implementation
          { calc register weight }
          if not(cs_littlesize in aktglobalswitches ) then
            rg.t_times:=rg.t_times*8;
+       {$ifndef newra}
          rg.cleartempgen;
+       {$endif}
 
          firstpass(left);
          if codegenerror then
@@ -414,7 +416,9 @@ implementation
          { loop instruction }
          if assigned(right) then
            begin
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               firstpass(right);
               if codegenerror then
                 exit;
@@ -560,7 +564,9 @@ implementation
          result:=nil;
          expectloc:=LOC_VOID;
          old_t_times:=rg.t_times;
+      {$ifndef newra}
          rg.cleartempgen;
+      {$endif}
          firstpass(left);
          registers32:=left.registers32;
          registersfpu:=left.registersfpu;
@@ -577,7 +583,9 @@ implementation
          { if path }
          if assigned(right) then
            begin
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               firstpass(right);
 
               if registers32<right.registers32 then
@@ -593,7 +601,9 @@ implementation
          { else path }
          if assigned(t1) then
            begin
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               firstpass(t1);
 
               if registers32<t1.registers32 then
@@ -768,10 +778,14 @@ implementation
          if not(cs_littlesize in aktglobalswitches) then
            rg.t_times:=rg.t_times*8;
 
+        {$ifndef newra}
          rg.cleartempgen;
+        {$endif}
          firstpass(left);
 
+        {$ifndef newra}
          rg.cleartempgen;
+        {$endif}
          if assigned(t1) then
           begin
             firstpass(t1);
@@ -793,7 +807,9 @@ implementation
 {$endif SUPPORT_MMX}
 
          { process count var }
+        {$ifndef newra}
          rg.cleartempgen;
+        {$endif}
          firstpass(t2);
          if codegenerror then
           exit;
@@ -806,7 +822,9 @@ implementation
            registersmmx:=t2.registersmmx;
 {$endif SUPPORT_MMX}
 
+        {$ifndef newra}
          rg.cleartempgen;
+        {$endif}
          firstpass(right);
       {$ifdef loopvar_dont_mind}
          { Check count var, record fields are also allowed in tp7 }
@@ -1100,7 +1118,9 @@ implementation
          expectloc:=LOC_VOID;
          if assigned(left) then
           begin
+          {$ifndef newra}
             rg.cleartempgen;
+          {$endif}
             firstpass(left);
             registers32:=left.registers32;
             registersfpu:=left.registersfpu;
@@ -1266,12 +1286,16 @@ implementation
       begin
          result:=nil;
          expectloc:=LOC_VOID;
+        {$ifndef newra}
          rg.cleartempgen;
+        {$endif}
          firstpass(left);
          { on statements }
          if assigned(right) then
            begin
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               firstpass(right);
               registers32:=max(registers32,right.registers32);
               registersfpu:=max(registersfpu,right.registersfpu);
@@ -1319,10 +1343,14 @@ implementation
       begin
          result:=nil;
          expectloc:=LOC_VOID;
+        {$ifndef newra}
          rg.cleartempgen;
+        {$endif}
          firstpass(left);
 
+        {$ifndef newra}
          rg.cleartempgen;
+        {$endif}
          firstpass(right);
          left_right_max;
       end;
@@ -1466,7 +1494,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.66  2003-04-22 23:50:23  peter
+  Revision 1.67  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.66  2003/04/22 23:50:23  peter
     * firstpass uses expectloc
     * checks if there are differences between the expectloc and
       location.loc from secondpass in EXTDEBUG

+ 15 - 1
compiler/nset.pas

@@ -590,7 +590,9 @@ implementation
          result:=nil;
          expectloc:=LOC_VOID;
          { evalutes the case expression }
+       {$ifndef newra}
          rg.cleartempgen;
+       {$endif}
          firstpass(left);
          set_varstate(left,true);
          if codegenerror then
@@ -615,7 +617,9 @@ implementation
          hp:=tstatementnode(right);
          while assigned(hp) do
            begin
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               firstpass(hp.left);
 
               { searchs max registers }
@@ -634,7 +638,9 @@ implementation
          { may be handle else tree }
          if assigned(elseblock) then
            begin
+            {$ifndef newra}
               rg.cleartempgen;
+            {$endif}
               firstpass(elseblock);
               if codegenerror then
                 exit;
@@ -708,7 +714,15 @@ begin
 end.
 {
   $Log$
-  Revision 1.39  2003-04-22 23:50:23  peter
+  Revision 1.40  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.39  2003/04/22 23:50:23  peter
     * firstpass uses expectloc
     * checks if there are differences between the expectloc and
       location.loc from secondpass in EXTDEBUG

+ 11 - 1
compiler/pstatmnt.pas

@@ -187,7 +187,9 @@ implementation
          consume(_CASE);
          caseexpr:=comp_expr(true);
        { determines result type }
+       {$ifndef newra}
          rg.cleartempgen;
+       {$endif}
          do_resulttypepass(caseexpr);
          casedeferror:=false;
          casedef:=caseexpr.resulttype.def;
@@ -1123,7 +1125,15 @@ implementation
 end.
 {
   $Log$
-  Revision 1.88  2003-03-28 19:16:57  peter
+  Revision 1.89  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.88  2003/03/28 19:16:57  peter
     * generic constructor working for i386
     * remove fixed self register
     * esi added as address register for i386

+ 55 - 32
compiler/rgobj.pas

@@ -1511,15 +1511,29 @@ unit rgobj;
     procedure Trgobj.simplify;
 
     var adj:Pstring;
-        i:byte;
+        i,min,p:byte;
         m:char;
         n:Tsuperregister;
 
     begin
-      {We need to take a random element out of the simplifyworklist. We take
-       the last element. Dirty code!}
-      n:=Tsuperregister(simplifyworklist[byte(simplifyworklist[0])]);
-      dec(simplifyworklist[0]);
+      {We the element with the least interferences out of the 
+       simplifyworklist.}
+      min:=$ff;
+      p:=1;
+      for i:=1 to length(simplifyworklist) do
+        begin
+          adj:=igraph.adjlist[Tsuperregister(simplifyworklist[i])];
+          if (adj<>nil) and (length(adj^)<min) then
+            begin
+              min:=length(adj^);
+              if min=0 then
+                break;  {We won't find smaller ones.}
+              p:=i;
+            end;
+        end;
+      n:=Tsuperregister(simplifyworklist[p]);
+      delete(simplifyworklist,p,1);
+          
       {Push it on the selectstack.}
       selectstack:=selectstack+char(n);
       adj:=igraph.adjlist[n];
@@ -1728,32 +1742,33 @@ unit rgobj;
         v,x,y:Tsuperregister;
 
     begin
-      for i:=0 to movelist[u]^.count-1 do
-        begin
-          m:=movelist[u]^.data[i];
-          if Tmoveins(m).moveset in [ms_worklist_moves,ms_active_moves] then
-            begin
-              x:=Tmoveins(m).instruction.oper[0].reg.number shr 8;
-              y:=Tmoveins(m).instruction.oper[1].reg.number shr 8;
-              if get_alias(y)=get_alias(u) then
-                v:=get_alias(x)
-              else
-                v:=get_alias(y);
-              {Move m from active_moves/worklist_moves to frozen_moves.}
-              if Tmoveins(m).moveset=ms_active_moves then
-                active_moves.remove(m)
-              else
-                worklist_moves.remove(m);
-              Tmoveins(m).moveset:=ms_frozen_moves;
-              frozen_moves.insert(m);
-
-              if not(move_related(v)) and (degree[v]<cpu_registers) then
-                begin
-                  delete(freezeworklist,pos(char(v),freezeworklist),1);
-                  simplifyworklist:=simplifyworklist+char(v);
-                end;
-            end;
-        end;
+      if movelist[u]<>nil then
+        for i:=0 to movelist[u]^.count-1 do
+          begin
+            m:=movelist[u]^.data[i];
+            if Tmoveins(m).moveset in [ms_worklist_moves,ms_active_moves] then
+              begin
+                x:=Tmoveins(m).instruction.oper[0].reg.number shr 8;
+                y:=Tmoveins(m).instruction.oper[1].reg.number shr 8;
+                if get_alias(y)=get_alias(u) then
+                  v:=get_alias(x)
+                else
+                  v:=get_alias(y);
+                {Move m from active_moves/worklist_moves to frozen_moves.}
+                if Tmoveins(m).moveset=ms_active_moves then
+                  active_moves.remove(m)
+                else
+                  worklist_moves.remove(m);
+                Tmoveins(m).moveset:=ms_frozen_moves;
+                frozen_moves.insert(m);
+  
+                if not(move_related(v)) and (degree[v]<cpu_registers) then
+                  begin
+                    delete(freezeworklist,pos(char(v),freezeworklist),1);
+                    simplifyworklist:=simplifyworklist+char(v);
+                  end;
+              end;
+          end;
     end;
 
     procedure Trgobj.freeze;
@@ -2001,7 +2016,15 @@ end.
 
 {
   $Log$
-  Revision 1.39  2003-04-23 20:23:06  peter
+  Revision 1.40  2003-04-25 08:25:26  daniel
+    * Ifdefs around a lot of calls to cleartempgen
+    * Fixed registers that are allocated but not freed in several nodes
+    * Tweak to register allocator to cause less spills
+    * 8-bit registers now interfere with esi,edi and ebp
+      Compiler can now compile rtl successfully when using new register
+      allocator
+
+  Revision 1.39  2003/04/23 20:23:06  peter
     * compile fix for no-newra
 
   Revision 1.38  2003/04/23 14:42:07  daniel