Преглед изворни кода

* 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

+ 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