Browse Source

* more spilling rewrites

peter 21 years ago
parent
commit
f5471aef6e

+ 14 - 5
compiler/aasmtai.pas

@@ -487,8 +487,12 @@ interface
        tai_regalloc = class(tai)
           reg     : tregister;
           ratype  : TRegAllocType;
-          constructor alloc(r : tregister);
-          constructor dealloc(r : tregister);
+          { reg(de)alloc belongs to this instruction, this
+            is only used for automatic inserted (de)alloc for
+            imaginary register and required for spilling code }
+          instr   : tai;
+          constructor alloc(r : tregister;ainstr:tai);
+          constructor dealloc(r : tregister;ainstr:tai);
           constructor sync(r : tregister);
           constructor resize(r : tregister);
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
@@ -1717,21 +1721,23 @@ implementation
                                  tai_regalloc
 *****************************************************************************}
 
-    constructor tai_regalloc.alloc(r : tregister);
+    constructor tai_regalloc.alloc(r : tregister;ainstr:tai);
       begin
         inherited create;
         typ:=ait_regalloc;
         ratype:=ra_alloc;
         reg:=r;
+        instr:=ainstr;
       end;
 
 
-    constructor tai_regalloc.dealloc(r : tregister);
+    constructor tai_regalloc.dealloc(r : tregister;ainstr:tai);
       begin
         inherited create;
         typ:=ait_regalloc;
         ratype:=ra_dealloc;
         reg:=r;
+        instr:=ainstr;
       end;
 
 
@@ -2224,7 +2230,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.89  2004-09-26 17:45:29  peter
+  Revision 1.90  2004-10-05 20:41:01  peter
+    * more spilling rewrites
+
+  Revision 1.89  2004/09/26 17:45:29  peter
     * simple regvar support, not yet finished
 
   Revision 1.88  2004/08/15 13:30:18  florian

+ 6 - 3
compiler/cgobj.pas

@@ -708,13 +708,13 @@ implementation
 
     procedure tcg.a_reg_alloc(list : taasmoutput;r : tregister);
       begin
-         list.concat(tai_regalloc.alloc(r));
+         list.concat(tai_regalloc.alloc(r,nil));
       end;
 
 
     procedure tcg.a_reg_dealloc(list : taasmoutput;r : tregister);
       begin
-         list.concat(tai_regalloc.dealloc(r));
+         list.concat(tai_regalloc.dealloc(r,nil));
       end;
 
 
@@ -2226,7 +2226,10 @@ finalization
 end.
 {
   $Log$
-  Revision 1.173  2004-09-29 18:55:40  florian
+  Revision 1.174  2004-10-05 20:41:01  peter
+    * more spilling rewrites
+
+  Revision 1.173  2004/09/29 18:55:40  florian
     * fixed more sparc overflow stuff
     * fixed some op64 stuff for sparc
 

+ 6 - 3
compiler/i386/cgcpu.pas

@@ -229,7 +229,7 @@ unit cgcpu;
       begin
         { Release PIC register }
         if cs_create_pic in aktmoduleswitches then
-          list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG));
+          list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil));
 
         { MMX needs to call EMMS }
         if assigned(rg[R_MMXREGISTER]) and
@@ -247,7 +247,7 @@ unit cgcpu;
               end
             else
               list.concat(Taicpu.op_none(A_LEAVE,S_NO));
-            list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG));
+            list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG,nil));
           end;
 
         { return from proc }
@@ -556,7 +556,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.53  2004-09-25 14:23:54  peter
+  Revision 1.54  2004-10-05 20:41:01  peter
+    * more spilling rewrites
+
+  Revision 1.53  2004/09/25 14:23:54  peter
     * ungetregister is now only used for cpuregisters, renamed to
       ungetcpuregister
     * renamed (get|unget)explicitregister(s) to ..cpuregister

+ 7 - 4
compiler/i386/daopt386.pas

@@ -469,7 +469,7 @@ begin
          (taicpu(hp1).opcode = A_JMP) and
          (tasmlabel(taicpu(hp1).oper[0]^.sym) = aktexit2label)) then }
     begin
-      p := tai_regalloc.deAlloc(reg);
+      p := tai_regalloc.deAlloc(reg,nil);
       insertLLItem(AsmL, hp1.previous, hp1, p);
     end;
 end;
@@ -1172,13 +1172,13 @@ begin
         include(ptaiprop(p1.OptInfo)^.UsedRegs,supreg);
       if lastRemovedWasDealloc then
         begin
-          hp := tai_regalloc.DeAlloc(reg);
+          hp := tai_regalloc.DeAlloc(reg,nil);
           insertLLItem(asmL,p1,p1.next,hp);
         end;
     end;
   if firstRemovedWasAlloc then
     begin
-      hp := tai_regalloc.Alloc(reg);
+      hp := tai_regalloc.Alloc(reg,nil);
       insertLLItem(asmL,start.previous,start,hp);
     end;
 end;
@@ -2719,7 +2719,10 @@ end.
 
 {
   $Log$
-  Revision 1.70  2004-10-04 20:46:22  peter
+  Revision 1.71  2004-10-05 20:41:01  peter
+    * more spilling rewrites
+
+  Revision 1.70  2004/10/04 20:46:22  peter
     * spilling code rewritten for x86. It now used the generic
       spilling routines. Special x86 optimization still needs
       to be added.

+ 5 - 2
compiler/i386/popt386.pas

@@ -1163,7 +1163,7 @@ begin
                                   { allocregbetween doesn't insert this because at }
                                   { this time, no regalloc info is available in    }
                                   { the optinfo field, so do it manually (JM)      }
-                                  hp2 := tai_regalloc.Alloc(taicpu(hp1).oper[1]^.reg);
+                                  hp2 := tai_regalloc.Alloc(taicpu(hp1).oper[1]^.reg,nil);
                                   insertllitem(asml,p.previous,p,hp2);
                                   taicpu(hp1).LoadReg(0,taicpu(hp1).oper[1]^.reg);
                                   taicpu(hp1).LoadRef(1,taicpu(p).oper[1]^.ref^);
@@ -2004,7 +2004,10 @@ end.
 
 {
   $Log$
-  Revision 1.62  2004-10-05 17:31:41  peter
+  Revision 1.63  2004-10-05 20:41:02  peter
+    * more spilling rewrites
+
+  Revision 1.62  2004/10/05 17:31:41  peter
     * range check errors fixed
 
   Revision 1.61  2004/06/20 08:55:31  florian

+ 196 - 102
compiler/rgobj.pas

@@ -169,11 +169,12 @@ unit rgobj;
         { can be overriden to add cpu specific interferences }
         procedure add_cpu_interferences(p : tai);virtual;
         procedure add_constraints(reg:Tregister);virtual;
-        procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister);
-        procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister);
-        function get_spill_subreg(r : tregister) : tsubregister;virtual;
-        procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual;
-        procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);virtual;
+        function  getregisterinline(list:Taasmoutput;subreg:Tsubregister):Tregister;
+        procedure ungetregisterinline(list:Taasmoutput;r:Tregister);
+        function  get_spill_subreg(r : tregister) : tsubregister;virtual;
+        function  do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;virtual;
+        procedure do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);virtual;
+        procedure do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);virtual;
 
         function instr_spill_register(list:Taasmoutput;
                                       instr:taicpu;
@@ -212,8 +213,8 @@ unit rgobj;
         procedure epilogue_colouring;
         {# Colour the registers; that is do the register allocation.}
         procedure colour_registers;
-        {# Spills certain registers in the specified assembler list.}
-        procedure insert_regalloc_info(list:Taasmoutput;headertai:tai);
+        procedure insert_regalloc_info(list:Taasmoutput;u:tsuperregister);
+        procedure insert_regalloc_info_all(list:Taasmoutput);
         procedure generate_interference_graph(list:Taasmoutput;headertai:tai);
         procedure translate_registers(list:Taasmoutput);
         function  spill_registers(list:Taasmoutput;headertai:tai):boolean;virtual;
@@ -478,7 +479,7 @@ unit rgobj;
       begin
         if (getsupreg(r)>=first_imaginary) then
           InternalError(2004020901);
-        list.concat(Tai_regalloc.dealloc(r));
+        list.concat(Tai_regalloc.dealloc(r,nil));
       end;
 
 
@@ -490,7 +491,7 @@ unit rgobj;
         if supreg>=first_imaginary then
           internalerror(2003121503);
         include(used_in_proc,supreg);
-        list.concat(Tai_regalloc.alloc(r));
+        list.concat(Tai_regalloc.alloc(r,nil));
       end;
 
 
@@ -523,7 +524,7 @@ unit rgobj;
         i:Tsuperregister;
       begin
         { Insert regalloc info for imaginary registers }
-        insert_regalloc_info(list,headertai);
+        insert_regalloc_info_all(list);
         ibitmap:=tinterferencebitmap.create;
         generate_interference_graph(list,headertai);
         { Don't do the real allocation when -sr is passed }
@@ -539,6 +540,8 @@ unit rgobj;
           if spillednodes.length<>0 then
             begin
               inc(spillingcounter);
+              if spillingcounter>maxspillingcounter then
+                exit;
               if spillingcounter>maxspillingcounter then
                 internalerror(200309041);
               endspill:=not spill_registers(list,headertai);
@@ -1370,81 +1373,80 @@ unit rgobj;
         end;
     end;
 
-    procedure trgobj.getregisterinline(list:Taasmoutput;
-                  position:Tai;subreg:Tsubregister;var result:Tregister);
-    var p:Tsuperregister;
-        r:Tregister;
-    begin
-       p:=getnewreg(subreg);
-       live_registers.add(p);
-       r:=newreg(regtype,p,subreg);
-       if position=nil then
-         list.insert(Tai_regalloc.alloc(r))
-       else
-         list.insertafter(Tai_regalloc.alloc(r),position);
-       add_edges_used(p);
-       add_constraints(r);
-       result:=r;
-    end;
 
+    function trgobj.getregisterinline(list:Taasmoutput;subreg:Tsubregister):Tregister;
+      var
+        p : Tsuperregister;
+        r : Tregister;
+      begin
+        p:=getnewreg(subreg);
+        live_registers.add(p);
+        result:=newreg(regtype,p,subreg);
+        add_edges_used(p);
+        add_constraints(result);
+      end;
 
-    procedure trgobj.ungetregisterinline(list:Taasmoutput;
-                position:Tai;r:Tregister);
-
-    var supreg:Tsuperregister;
 
-    begin
-      supreg:=getsupreg(r);
-      live_registers.delete(supreg);
-      if position=nil then
-        list.insert(Tai_regalloc.dealloc(r))
-      else
-        list.insertafter(Tai_regalloc.dealloc(r),position);
-    end;
+    procedure trgobj.ungetregisterinline(list:Taasmoutput;r:Tregister);
+      var
+        supreg:Tsuperregister;
+      begin
+        supreg:=getsupreg(r);
+        live_registers.delete(supreg);
+        insert_regalloc_info(list,supreg);
+      end;
 
 
-    procedure trgobj.insert_regalloc_info(list:Taasmoutput;headertai:tai);
+    procedure trgobj.insert_regalloc_info(list:Taasmoutput;u:tsuperregister);
       var
-        supreg : tsuperregister;
         p : tai;
         r : tregister;
       begin
         { Insert regallocs for all imaginary registers }
-        for supreg:=first_imaginary to maxreg-1 do
-          with reginfo[supreg] do
-            begin
-              r:=newreg(regtype,supreg,subreg);
-              if assigned(live_start) then
-                begin
+        with reginfo[u] do
+          begin
+            r:=newreg(regtype,u,subreg);
+            if assigned(live_start) then
+              begin
 {$ifdef EXTDEBUG}
-                  if live_start=live_end then
-                    Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
+                if live_start=live_end then
+                  Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
 {$endif EXTDEBUG}
-                  list.insertbefore(Tai_regalloc.alloc(r),live_start);
-                  { Insert live end deallocation before reg allocations
-                    to reduce conflicts }
-                  p:=live_end;
-                  while assigned(p) and
-                        assigned(p.previous) and
-                        (tai(p.previous).typ=ait_regalloc) and
-                        (tai_regalloc(p.previous).ratype=ra_alloc) and
-                        (tai_regalloc(p.previous).reg<>r) do
-                    p:=tai(p.previous);
-                  { , but add release after sync }
-                  if assigned(p) and
-                     (p.typ=ait_regalloc) and
-                     (tai_regalloc(p).ratype=ra_sync) then
-                    p:=tai(p.next);
-                  if assigned(p) then
-                    list.insertbefore(Tai_regalloc.dealloc(r),p)
-                  else
-                    list.concat(Tai_regalloc.dealloc(r));
-                end
+                list.insertbefore(Tai_regalloc.alloc(r,live_start),live_start);
+                { Insert live end deallocation before reg allocations
+                  to reduce conflicts }
+                p:=live_end;
+                while assigned(p) and
+                      assigned(p.previous) and
+                      (tai(p.previous).typ=ait_regalloc) and
+                      (tai_regalloc(p.previous).ratype=ra_alloc) and
+                      (tai_regalloc(p.previous).reg<>r) do
+                  p:=tai(p.previous);
+                { , but add release after sync }
+                if assigned(p) and
+                   (p.typ=ait_regalloc) and
+                   (tai_regalloc(p).ratype=ra_sync) then
+                  p:=tai(p.next);
+                if assigned(p) then
+                  list.insertbefore(Tai_regalloc.dealloc(r,live_end),p)
+                else
+                  list.concat(Tai_regalloc.dealloc(r,live_end));
+              end
 {$ifdef EXTDEBUG}
-              else
-                Comment(V_Warning,'Register '+std_regname(r)+' not used');
+            else
+              Comment(V_Warning,'Register '+std_regname(r)+' not used');
 {$endif EXTDEBUG}
-            end;
+          end;
+      end;
+
+
+    procedure trgobj.insert_regalloc_info_all(list:Taasmoutput);
+      var
+        supreg : tsuperregister;
+      begin
+        { Insert regallocs for all imaginary registers }
+        for supreg:=first_imaginary to maxreg-1 do
+          insert_regalloc_info(list,supreg);
       end;
 
 
@@ -1569,6 +1571,7 @@ unit rgobj;
               ait_instruction:
                 with Taicpu(p) do
                   begin
+                    aktfilepos:=fileinfo;
                     for i:=0 to ops-1 do
                       with oper[i]^ do
                         case typ of
@@ -1610,6 +1613,7 @@ unit rgobj;
             end;
             p:=Tai(p.next);
           end;
+        aktfilepos:=current_procinfo.exitpos;
       end;
 
 
@@ -1702,21 +1706,21 @@ unit rgobj;
       end;
 
 
-    procedure Trgobj.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
-      var
-        helpins : Tai;
+    function trgobj.do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
       begin
-        helpins:=spilling_create_load(spilltemp,tempreg);
-        list.insertbefore(helpins,instr);
+        result:=false;
       end;
 
 
-    procedure Trgobj.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
-      var
-        helpins : Tai;
+    procedure Trgobj.do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
+      begin
+        list.insertafter(spilling_create_load(spilltemp,tempreg),pos);
+      end;
+
+
+    procedure Trgobj.do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
       begin
-        helpins:=spilling_create_store(tempreg,spilltemp);
-        list.insertafter(helpins,instr);
+        list.insertafter(spilling_create_store(tempreg,spilltemp),pos);
       end;
 
 
@@ -1791,7 +1795,8 @@ unit rgobj;
         end;
 
       var
-        counter2 : longint;
+        loadpos,
+        storepos : tai;
         oldlive_registers : tsuperregisterworklist;
       begin
         result := false;
@@ -1837,42 +1842,124 @@ unit rgobj;
         if not spilled then
           exit;
 
-        { Add conflicts with all non-spilled registers }
+{$ifdef x86}
+        { Try replacing the register with the spilltemp. This is usefull only
+          for the i386,x86_64 that support memory locations for several instructions }
+        for counter := 0 to pred(regindex) do
+          with regs[counter] do
+            begin
+              if mustbespilled then
+                begin
+                  if do_spill_replace(list,instr,orgreg,spilltemplist[orgreg]) then
+                    mustbespilled:=false;
+                end;
+            end;
+{$endif x86}
+
+        {
+          There are registers that need are spilled. We generate the
+          following code for it. The used positions where code need
+          to be inserted are marked using #. Note that code is always inserted
+          before the positions using pos.previous. This way the position is always
+          the same since pos doesn't change, but pos.previous is modified everytime
+          new code is inserted.
+
+          [
+            - reg_allocs load spills
+            - load spills
+          ]
+          [#loadpos
+            - reg_deallocs
+            - reg_allocs
+          ]
+          [
+            - reg_deallocs for load-only spills
+            - reg_allocs for store-only spills
+          ]
+          [#instr
+            - original instruction
+          ]
+          [
+            - store spills
+            - reg_deallocs store spills
+          ]
+          [#storepos
+          ]
+        }
+
+        result := true;
         oldlive_registers.copyfrom(live_registers);
-        for counter2 := 0 to pred(regindex) do
+
+        { Process all tai_regallocs belonging to this instruction. All
+          released registers are also added to the live_registers because
+          they can't be used during the spilling }
+        loadpos:=tai(instr.previous);
+        while assigned(loadpos) and
+              (loadpos.typ=ait_regalloc) and
+              (tai_regalloc(loadpos).instr=instr) do
           begin
-            if (not regs[counter2].mustbespilled) then
-              live_registers.add(get_alias(regs[counter2].orgreg));
+            if tai_regalloc(loadpos).ratype=ra_dealloc then
+              live_registers.add(getsupreg(tai_regalloc(loadpos).reg));
+            loadpos:=tai(loadpos.previous);
           end;
+        loadpos:=tai(loadpos.next);
 
-        { generate the spilling code }
-        result := true;
+        { Load the spilled registers }
         for counter := 0 to pred(regindex) do
           with regs[counter] do
             begin
-              if mustbespilled then
+              if mustbespilled and regread then
                 begin
-                  getregisterinline(list,tai(instr.previous),get_spill_subreg(regs[counter].spillreg),tempreg);
+                  tempreg:=getregisterinline(list,get_spill_subreg(regs[counter].spillreg));
+                  do_spill_read(list,tai(loadpos.previous),spilltemplist[orgreg],tempreg);
+                end;
+            end;
 
-                  if regread then
-                    do_spill_read(list,instr,spilltemplist[orgreg],tempreg);
-                  if regwritten then
-                    do_spill_written(list,instr,spilltemplist[orgreg],tempreg);
+        { Release temp registers of read-only registers, and add reference of the instruction
+          to the reginfo }
+        for counter := 0 to pred(regindex) do
+          with regs[counter] do
+            begin
+              if mustbespilled and regread and (not regwritten) then
+                begin
+                  { The original instruction will be the next that uses this register }
+                  add_reg_instruction(instr,tempreg);
+                  ungetregisterinline(list,tempreg);
                 end;
             end;
 
-        { Release temp registers after all registers for the instruction are spilled }
+        { Allocate temp registers of write-only registers, and add reference of the instruction
+          to the reginfo }
         for counter := 0 to pred(regindex) do
           with regs[counter] do
             begin
-              if mustbespilled then
-                ungetregisterinline(list,instr,tempreg);
+              if mustbespilled and regwritten then
+                begin
+                  { When the register is also loaded there is already a register assigned }
+                  if (not regread) then
+                    tempreg:=getregisterinline(list,get_spill_subreg(regs[counter].spillreg));
+                  { The original instruction will be the next that uses this register, this
+                    also needs to be done for read-write registers }
+                  add_reg_instruction(instr,tempreg);
+                end;
             end;
 
-        { restore live registers }
+        { we are now at the original instruction, restore live registers }
         live_registers.done;
         live_registers:=oldlive_registers;
 
+        { store the spilled registers }
+        storepos:=tai(instr.next);
+        for counter := 0 to pred(regindex) do
+          with regs[counter] do
+            begin
+              if mustbespilled and regwritten then
+                begin
+                  do_spill_written(list,tai(storepos.previous),spilltemplist[orgreg],tempreg);
+                  ungetregisterinline(list,tempreg);
+                end;
+            end;
+
         { substitute registers }
         for counter:=0 to instr.ops-1 do
          with instr.oper[counter]^ do
@@ -1880,12 +1967,16 @@ unit rgobj;
             case typ of
               top_reg:
                 begin
-                  tryreplacereg(reg);
+                  if (getregtype(reg) = regtype) then
+                    tryreplacereg(reg);
                 end;
               top_ref:
                 begin
-                  tryreplacereg(ref^.base);
-                  tryreplacereg(ref^.index);
+                  if regtype in [R_INTREGISTER,R_ADDRESSREGISTER] then
+                    begin
+                      tryreplacereg(ref^.base);
+                      tryreplacereg(ref^.index);
+                    end;
                 end;
 {$ifdef ARM}
               top_shifterop:
@@ -1903,7 +1994,10 @@ unit rgobj;
 end.
 {
   $Log$
-  Revision 1.138  2004-10-04 20:46:22  peter
+  Revision 1.139  2004-10-05 20:41:01  peter
+    * more spilling rewrites
+
+  Revision 1.138  2004/10/04 20:46:22  peter
     * spilling code rewritten for x86. It now used the generic
       spilling routines. Special x86 optimization still needs
       to be added.

+ 6 - 1
compiler/sparc/cpupara.pas

@@ -162,6 +162,8 @@ implementation
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.register:=NR_FPU_RESULT_REG;
+            if retcgsize=OS_F64 then
+              setsubreg(paraloc^.register,R_SUBFD);
             paraloc^.size:=retcgsize;
           end
         else
@@ -316,7 +318,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.43  2004-09-27 21:24:17  peter
+  Revision 1.44  2004-10-05 20:41:02  peter
+    * more spilling rewrites
+
+  Revision 1.43  2004/09/27 21:24:17  peter
     * fixed passing of flaot parameters. The general size is still float,
       only the size of the locations is now OS_32
 

+ 11 - 6
compiler/sparc/itcpugas.pas

@@ -78,16 +78,18 @@ implementation
 
     function gas_regname(r:Tregister):string;
       var
-        p : longint;
+        hr : tregister;
+        p  : longint;
       begin
         { Double uses the same table as single }
-        case getsubreg(r) of
+        hr:=r;
+        case getsubreg(hr) of
           R_SUBFD:
-            setsubreg(r,R_SUBFS);
+            setsubreg(hr,R_SUBFS);
           R_SUBL,R_SUBW,R_SUBD,R_SUBQ:
-            setsubreg(r,R_SUBD);
+            setsubreg(hr,R_SUBD);
         end;
-        p:=findreg_by_number(r);
+        p:=findreg_by_number(hr);
         if p<>0 then
           result:=gas_regname_table[p]
         else
@@ -97,7 +99,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.5  2004-09-21 17:25:13  peter
+  Revision 1.6  2004-10-05 20:41:02  peter
+    * more spilling rewrites
+
+  Revision 1.5  2004/09/21 17:25:13  peter
     * paraloc branch merged
 
   Revision 1.4.4.1  2004/09/20 20:42:37  peter

+ 14 - 11
compiler/sparc/rgcpu.pas

@@ -36,8 +36,8 @@ unit rgcpu;
       trgcpu=class(trgobj)
         procedure add_constraints(reg:tregister);override;
         function get_spill_subreg(r : tregister) : tsubregister;override;
-        procedure do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);override;
-        procedure do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);override;
+        procedure do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override;
+        procedure do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);override;
       end;
 
 
@@ -87,7 +87,7 @@ implementation
       end;
 
 
-    procedure trgcpu.do_spill_read(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
+    procedure trgcpu.do_spill_read(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
       var
         helpins  : tai;
         tmpref   : treference;
@@ -115,14 +115,14 @@ implementation
 
             helpins:=spilling_create_load(spilltemp,tempreg);
             helplist.concat(helpins);
-            list.insertlistbefore(instr,helplist)
+            list.insertlistafter(pos,helplist)
           end
         else
-          inherited do_spill_read(list,instr,spilltemp,tempreg);
+          inherited do_spill_read(list,pos,spilltemp,tempreg);
       end;
 
 
-    procedure trgcpu.do_spill_written(list:Taasmoutput;instr:taicpu;const spilltemp:treference;const tempreg:tregister);
+    procedure trgcpu.do_spill_written(list:Taasmoutput;pos:tai;const spilltemp:treference;tempreg:tregister);
       var
         helpins  : tai;
         tmpref   : treference;
@@ -134,7 +134,7 @@ implementation
             helplist:=taasmoutput.create;
 
             if getregtype(tempreg)=R_INTREGISTER then
-              getregisterinline(helplist,tai(helplist.first),R_SUBWHOLE,hreg)
+              hreg:=getregisterinline(helplist,R_SUBWHOLE)
             else
               hreg:=cg.getintregister(helplist,OS_ADDR);
 
@@ -151,18 +151,21 @@ implementation
             helpins:=spilling_create_store(tempreg,spilltemp);
             helplist.concat(helpins);
             if getregtype(tempreg)=R_INTREGISTER then
-              ungetregisterinline(helplist,tai(helplist.last),hreg);
+              ungetregisterinline(helplist,hreg);
 
-            list.insertlistafter(instr,helplist)
+            list.insertlistafter(pos,helplist)
           end
         else
-          inherited do_spill_written(list,instr,spilltemp,tempreg);
+          inherited do_spill_written(list,pos,spilltemp,tempreg);
     end;
 
 end.
 {
   $Log$
-  Revision 1.28  2004-10-04 20:46:22  peter
+  Revision 1.29  2004-10-05 20:41:02  peter
+    * more spilling rewrites
+
+  Revision 1.28  2004/10/04 20:46:22  peter
     * spilling code rewritten for x86. It now used the generic
       spilling routines. Special x86 optimization still needs
       to be added.

+ 6 - 3
compiler/x86/cgx86.pas

@@ -1571,7 +1571,7 @@ unit cgx86;
               CGmessage(cg_d_stackframe_omited)
             else
               begin
-                list.concat(tai_regalloc.alloc(NR_FRAME_POINTER_REG));
+                list.concat(tai_regalloc.alloc(NR_FRAME_POINTER_REG,nil));
                 include(rg[R_INTREGISTER].preserved_by_proc,RS_FRAME_POINTER_REG);
                 list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG));
                 { Return address and FP are both on stack }
@@ -1593,7 +1593,7 @@ unit cgx86;
           begin
             a_call_name(list,'FPC_GETEIPINEBX');
             list.concat(taicpu.op_sym_ofs_reg(A_ADD,tcgsize2opsize[OS_ADDR],objectlibrary.newasmsymbol('_GLOBAL_OFFSET_TABLE_',AB_EXTERNAL,AT_DATA),0,NR_PIC_OFFSET_REG));
-            list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG));
+            list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
           end;
       end;
 
@@ -1675,7 +1675,10 @@ unit cgx86;
 end.
 {
   $Log$
-  Revision 1.127  2004-10-04 20:46:22  peter
+  Revision 1.128  2004-10-05 20:41:02  peter
+    * more spilling rewrites
+
+  Revision 1.127  2004/10/04 20:46:22  peter
     * spilling code rewritten for x86. It now used the generic
       spilling routines. Special x86 optimization still needs
       to be added.

+ 8 - 70
compiler/x86/rgx86.pas

@@ -36,21 +36,8 @@ unit rgx86;
 
     type
        trgx86 = class(trgobj)
-{$ifdef OLDRGX86}
-         function instr_spill_register(list:Taasmoutput;
-                                       instr:taicpu;
-                                       const r:Tsuperregisterset;
-                                       const spilltemplist:Tspill_temp_list): boolean;override;
-{$endif OLDRGX86}
-        function  get_spill_subreg(r : tregister) : tsubregister;override;
-{
-        procedure do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
-                                const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
-        procedure do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
-                                   const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
-        procedure do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
-                                       const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);override;
-}
+         function  get_spill_subreg(r : tregister) : tsubregister;override;
+         function  do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;override;
        end;
 
        tpushedsavedloc = record
@@ -506,66 +493,17 @@ implementation
       end;
 
 
-      (*
-    procedure trgx86.do_spill_read(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
-                                   const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
-      var
-        helpins: tai;
-        tmpref,ref : treference;
-        helplist : taasmoutput;
-        tmpreg : tregister;
+    function trgx86.do_spill_replace(list:Taasmoutput;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
       begin
-{        ref:=spilltemplist[regs[regidx].orgreg];
-        if abs(ref.offset)>4095 then
-          begin
-          end
-        else }
-          inherited do_spill_read(list,instr,pos,regidx,spilltemplist,regs);
+        result:=false;
       end;
 
 
-    procedure trgx86.do_spill_written(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
-                                      const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
-      var
-        helpins: tai;
-        ref,tmpref : treference;
-        helplist : taasmoutput;
-        tmpreg : tregister;
-      begin
-{        ref:=spilltemplist[regs[regidx].orgreg];
-        if abs(ref.offset)>4095 then
-          begin
-          end
-        else }
-          inherited do_spill_written(list,instr,pos,regidx,spilltemplist,regs);
-      end;
-
-
-    procedure trgx86.do_spill_readwritten(list : taasmoutput;instr : taicpu;pos: tai; regidx: word;
-                                          const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
-      var
-        helpins1, helpins2: tai;
-        tmpref,ref : treference;
-        helplist : taasmoutput;
-         tmpreg : tregister;
-      begin
-{        ref:=spilltemplist[regs[regidx].orgreg];
-        if abs(ref.offset)>4095 then
-          begin
-          end
-        else  }
-          inherited do_spill_readwritten(list,instr,pos,regidx,spilltemplist,regs);
-      end;
-*)
-
 {******************************************************************************
                                   Trgx86fpu
 ******************************************************************************}
 
     constructor Trgx86fpu.create;
-
-      var i:Tsuperregister;
-
       begin
         used_in_proc:=[];
         t_times := 0;
@@ -574,7 +512,6 @@ implementation
 
 
     function trgx86fpu.getregisterfpu(list: taasmoutput) : tregister;
-
       begin
         { note: don't return R_ST0, see comments above implementation of }
         { a_loadfpu_* methods in cgcpu (JM)                              }
@@ -583,7 +520,6 @@ implementation
 
 
     procedure trgx86fpu.ungetregisterfpu(list : taasmoutput; r : tregister);
-
       begin
         { nothing to do, fpu stack management is handled by the load/ }
         { store operations in cgcpu (JM)                              }
@@ -592,7 +528,6 @@ implementation
 
 
     function trgx86fpu.correct_fpuregister(r : tregister;ofs : byte) : tregister;
-
       begin
         correct_fpuregister:=r;
         setsupreg(correct_fpuregister,ofs);
@@ -690,7 +625,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.7  2004-10-04 20:46:22  peter
+  Revision 1.8  2004-10-05 20:41:02  peter
+    * more spilling rewrites
+
+  Revision 1.7  2004/10/04 20:46:22  peter
     * spilling code rewritten for x86. It now used the generic
       spilling routines. Special x86 optimization still needs
       to be added.

+ 6 - 3
compiler/x86_64/cgcpu.pas

@@ -82,7 +82,7 @@ unit cgcpu;
       begin
         { Release PIC register }
         if cs_create_pic in aktmoduleswitches then
-          list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG));
+          list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil));
 
         { remove stackframe }
         if not nostackframe then
@@ -95,7 +95,7 @@ unit cgcpu;
               end
             else
               list.concat(Taicpu.op_none(A_LEAVE,S_NO));
-            list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG));
+            list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG,nil));
           end;
 
         list.concat(Taicpu.Op_none(A_RET,S_NO));
@@ -109,7 +109,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.16  2004-09-21 17:25:13  peter
+  Revision 1.17  2004-10-05 20:41:02  peter
+    * more spilling rewrites
+
+  Revision 1.16  2004/09/21 17:25:13  peter
     * paraloc branch merged
 
   Revision 1.15.4.1  2004/08/31 20:43:06  peter