diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index a2cc33f0bf..730fb5da5c 100644 --- a/compiler/cgobj.pas +++ b/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; @@ -691,6 +693,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; diff --git a/compiler/psub.pas b/compiler/psub.pas index 8c6b45b0db..45b34750a8 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -805,6 +805,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); @@ -814,6 +817,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 @@ -876,10 +882,13 @@ implementation end; { load got if necessary } + cg.set_regalloc_extend_backwards(true); aktfilepos:=entrypos; gen_got_load(templist); aktproccode.insertlistafter(headertai,templist); + cg.set_regalloc_extend_backwards(false); + { The procedure body is finished, we can now allocate the registers } cg.do_register_allocation(aktproccode,headertai); diff --git a/compiler/rgobj.pas b/compiler/rgobj.pas index e499351454..e2b5763d3f 100644 --- a/compiler/rgobj.pas +++ b/compiler/rgobj.pas @@ -122,6 +122,7 @@ unit rgobj; --------------------------------------------------------------------} trgobj=class + extend_live_range_backwards: boolean; preserved_by_proc : tcpuregisterset; used_in_proc : tcpuregisterset; @@ -358,6 +359,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; @@ -674,9 +676,18 @@ 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 + live_start := instr; + if not assigned(live_end) then + live_end := instr; + end end; end;