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;
           {# Clean up the register allocators needed for the codegenerator.}
           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}
           procedure init_flowgraph;
@@ -660,6 +662,18 @@ implementation
       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);
       var
         rt : tregistertype;

+ 13 - 0
compiler/psub.pas

@@ -722,6 +722,9 @@ implementation
               position and switches }
             aktfilepos:=entrypos;
             aktlocalswitches:=entryswitches;
+
+            cg.set_regalloc_extend_backwards(true);
+
             gen_entry_code(templist);
             aktproccode.insertlistafter(entry_asmnode.currenttai,templist);
             gen_initialize_code(templist);
@@ -731,6 +734,9 @@ implementation
               and switches }
             aktfilepos:=exitpos;
             aktlocalswitches:=exitswitches;
+
+            cg.set_regalloc_extend_backwards(false);
+
             gen_finalize_code(templist);
             { the finalcode must be concated if there was no position available,
               using insertlistafter will result in an insert at the start
@@ -792,6 +798,13 @@ implementation
                 aktproccode.insertlistafter(stackcheck_asmnode.currenttai,templist)
               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
               allocate the registers }
             cg.do_register_allocation(aktproccode,headertai);

+ 46 - 3
compiler/rgobj.pas

@@ -170,6 +170,7 @@ unit rgobj;
                                       const r:Tsuperregisterset;
                                       const spilltemplist:Tspill_temp_list): boolean;virtual;
       private
+        do_extend_live_range_backwards: boolean;
         {# First imaginary register.}
         first_imaginary   : Tsuperregister;
         {# Highest register allocated until now.}
@@ -191,6 +192,9 @@ unit rgobj;
         frozen_moves,
         coalesced_moves,
         constrained_moves : Tlinkedlist;
+        extended_backwards,
+        backwards_was_first : tsuperregisterset;
+
 {$ifdef EXTDEBUG}
         procedure writegraph(loopidx:longint);
 {$endif EXTDEBUG}
@@ -227,6 +231,9 @@ unit rgobj;
         procedure select_spill;
         procedure assign_colours;
         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;
 
     const
@@ -358,6 +365,7 @@ unit rgobj;
          { empty super register sets can cause very strange problems }
          if high(Ausable)=0 then
            internalerror(200210181);
+         extend_live_range_backwards := false;
          first_imaginary:=Afirst_imaginary;
          maxreg:=Afirst_imaginary;
          regtype:=Aregtype;
@@ -662,6 +670,20 @@ unit rgobj;
     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);
       var
         supreg : tsuperregister;
@@ -674,9 +696,30 @@ unit rgobj;
         if supreg>=first_imaginary then
           with reginfo[supreg] do
             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;