Browse Source

Merged revisions 2185,2193 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

r2185 (jonas)
* make sure live_start and live_end are correctly updated while
generating the initialisation and entry code


r2193 (jonas)
* fixed backwards extension of regalloc information

git-svn-id: branches/fixes_2_0@2205 -

Jonas Maebe 20 years ago
parent
commit
00043f5e7f
3 changed files with 73 additions and 3 deletions
  1. 14 0
      compiler/cgobj.pas
  2. 13 0
      compiler/psub.pas
  3. 46 3
      compiler/rgobj.pas

+ 14 - 0
compiler/cgobj.pas

@@ -68,6 +68,8 @@ unit cgobj;
           procedure init_register_allocators;virtual;
           procedure init_register_allocators;virtual;
           {# Clean up the register allocators needed for the codegenerator.}
           {# Clean up the register allocators needed for the codegenerator.}
           procedure done_register_allocators;virtual;
           procedure done_register_allocators;virtual;
+          {# Set whether live_start or live_end should be updated when allocating registers, needed when e.g. generating initcode after the rest of the code. }
+          procedure set_regalloc_extend_backwards(b: boolean);
 
 
        {$ifdef flowgraph}
        {$ifdef flowgraph}
           procedure init_flowgraph;
           procedure init_flowgraph;
@@ -660,6 +662,18 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tcg.set_regalloc_extend_backwards(b: boolean);
+      var
+        rt : tregistertype;
+      begin
+        for rt:=low(rg) to high(rg) do
+          begin
+            if assigned(rg[rt]) then
+              rg[rt].extend_live_range_backwards := b;;
+          end;
+      end;
+
+
     procedure tcg.do_register_allocation(list:Taasmoutput;headertai:tai);
     procedure tcg.do_register_allocation(list:Taasmoutput;headertai:tai);
       var
       var
         rt : tregistertype;
         rt : tregistertype;

+ 13 - 0
compiler/psub.pas

@@ -722,6 +722,9 @@ implementation
               position and switches }
               position and switches }
             aktfilepos:=entrypos;
             aktfilepos:=entrypos;
             aktlocalswitches:=entryswitches;
             aktlocalswitches:=entryswitches;
+
+            cg.set_regalloc_extend_backwards(true);
+
             gen_entry_code(templist);
             gen_entry_code(templist);
             aktproccode.insertlistafter(entry_asmnode.currenttai,templist);
             aktproccode.insertlistafter(entry_asmnode.currenttai,templist);
             gen_initialize_code(templist);
             gen_initialize_code(templist);
@@ -731,6 +734,9 @@ implementation
               and switches }
               and switches }
             aktfilepos:=exitpos;
             aktfilepos:=exitpos;
             aktlocalswitches:=exitswitches;
             aktlocalswitches:=exitswitches;
+
+            cg.set_regalloc_extend_backwards(false);
+
             gen_finalize_code(templist);
             gen_finalize_code(templist);
             { the finalcode must be concated if there was no position available,
             { the finalcode must be concated if there was no position available,
               using insertlistafter will result in an insert at the start
               using insertlistafter will result in an insert at the start
@@ -792,6 +798,13 @@ implementation
                 aktproccode.insertlistafter(stackcheck_asmnode.currenttai,templist)
                 aktproccode.insertlistafter(stackcheck_asmnode.currenttai,templist)
               end;
               end;
 
 
+{
+        reactivate in case got patch is merged back as well
+            cg.set_regalloc_extend_backwards(true);
+            gen_load_got();
+            cg.set_regalloc_extend_backwards(false);
+}
+
             { The procedure body is finished, we can now
             { The procedure body is finished, we can now
               allocate the registers }
               allocate the registers }
             cg.do_register_allocation(aktproccode,headertai);
             cg.do_register_allocation(aktproccode,headertai);

+ 46 - 3
compiler/rgobj.pas

@@ -170,6 +170,7 @@ unit rgobj;
                                       const r:Tsuperregisterset;
                                       const r:Tsuperregisterset;
                                       const spilltemplist:Tspill_temp_list): boolean;virtual;
                                       const spilltemplist:Tspill_temp_list): boolean;virtual;
       private
       private
+        do_extend_live_range_backwards: boolean;
         {# First imaginary register.}
         {# First imaginary register.}
         first_imaginary   : Tsuperregister;
         first_imaginary   : Tsuperregister;
         {# Highest register allocated until now.}
         {# Highest register allocated until now.}
@@ -191,6 +192,9 @@ unit rgobj;
         frozen_moves,
         frozen_moves,
         coalesced_moves,
         coalesced_moves,
         constrained_moves : Tlinkedlist;
         constrained_moves : Tlinkedlist;
+        extended_backwards,
+        backwards_was_first : tsuperregisterset;
+
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
         procedure writegraph(loopidx:longint);
         procedure writegraph(loopidx:longint);
 {$endif EXTDEBUG}
 {$endif EXTDEBUG}
@@ -227,6 +231,9 @@ unit rgobj;
         procedure select_spill;
         procedure select_spill;
         procedure assign_colours;
         procedure assign_colours;
         procedure clear_interferences(u:Tsuperregister);
         procedure clear_interferences(u:Tsuperregister);
+        procedure set_live_range_backwards(b: boolean);
+       public
+        property extend_live_range_backwards: boolean read do_extend_live_range_backwards write set_live_range_backwards;
       end;
       end;
 
 
     const
     const
@@ -358,6 +365,7 @@ unit rgobj;
          { empty super register sets can cause very strange problems }
          { empty super register sets can cause very strange problems }
          if high(Ausable)=0 then
          if high(Ausable)=0 then
            internalerror(200210181);
            internalerror(200210181);
+         extend_live_range_backwards := false;
          first_imaginary:=Afirst_imaginary;
          first_imaginary:=Afirst_imaginary;
          maxreg:=Afirst_imaginary;
          maxreg:=Afirst_imaginary;
          regtype:=Aregtype;
          regtype:=Aregtype;
@@ -662,6 +670,20 @@ unit rgobj;
     end;
     end;
 
 
 
 
+    procedure trgobj.set_live_range_backwards(b: boolean);
+      begin
+        if (b) then
+          begin
+            { new registers may be allocated }
+            supregset_reset(extended_backwards,false,high(tsuperregister));
+            supregset_reset(backwards_was_first,false,high(tsuperregister));
+            do_extend_live_range_backwards := true;
+          end
+        else
+          do_extend_live_range_backwards := false;
+      end;
+
+
     procedure trgobj.add_reg_instruction(instr:Tai;r:tregister);
     procedure trgobj.add_reg_instruction(instr:Tai;r:tregister);
       var
       var
         supreg : tsuperregister;
         supreg : tsuperregister;
@@ -674,9 +696,30 @@ unit rgobj;
         if supreg>=first_imaginary then
         if supreg>=first_imaginary then
           with reginfo[supreg] do
           with reginfo[supreg] do
             begin
             begin
-              if not assigned(live_start) then
-                live_start:=instr;
-              live_end:=instr;
+              if not(extend_live_range_backwards) then
+                begin
+                  if not assigned(live_start) then
+                    live_start:=instr;
+                  live_end:=instr;
+                end
+               else
+                 begin
+                   if not supregset_in(extended_backwards,supreg) then
+                     begin
+                       supregset_include(extended_backwards,supreg);
+                       live_start := instr;
+                       if not assigned(live_end) then
+                         begin
+                           supregset_include(backwards_was_first,supreg);
+                           live_end := instr;
+                         end;
+                     end
+                   else
+                     begin
+                       if supregset_in(backwards_was_first,supreg) then
+                         live_end := instr;
+                     end
+                 end
             end;
             end;
       end;
       end;