Explorar el Código

* prevent a temp. register allocated during spilling being immediately spilled again, resolves #25164

git-svn-id: trunk@26930 -
florian hace 11 años
padre
commit
23c724f885
Se han modificado 3 ficheros con 30 adiciones y 4 borrados
  1. 1 0
      .gitattributes
  2. 14 4
      compiler/rgobj.pas
  3. 15 0
      tests/webtbs/tw25164.pp

+ 1 - 0
.gitattributes

@@ -13812,6 +13812,7 @@ tests/webtbs/tw25101.pp svneol=native#text/pascal
 tests/webtbs/tw25122.pp svneol=native#text/plain
 tests/webtbs/tw25132.pp svneol=native#text/pascal
 tests/webtbs/tw2514.pp svneol=native#text/plain
+tests/webtbs/tw25164.pp svneol=native#text/pascal
 tests/webtbs/tw25169.pp svneol=native#text/plain
 tests/webtbs/tw25170.pp svneol=native#text/plain
 tests/webtbs/tw25198.pp svneol=native#text/plain

+ 14 - 4
compiler/rgobj.pas

@@ -2229,8 +2229,13 @@ unit rgobj;
             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,1);
+                  { The original instruction will be the next that uses this register
+
+                    set weigth of the newly allocated register higher than the old one,
+                    so it will selected for spilling with a lower priority than
+                    the original one, this prevents an endless spilling loop if orgreg
+                    is short living, see e.g. tw25164.pp }
+                  add_reg_instruction(instr,tempreg,reginfo[orgreg].weight+1);
                   ungetregisterinline(list,tempreg);
                 end;
             end;
@@ -2246,8 +2251,13 @@ unit rgobj;
                   if (not regread) then
                     tempreg:=getregisterinline(list,regs[counter].spillregconstraints);
                   { 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,1);
+                    also needs to be done for read-write registers,
+
+                    set weigth of the newly allocated register higher than the old one,
+                    so it will selected for spilling with a lower priority than
+                    the original one, this prevents an endless spilling loop if orgreg
+                    is short living, see e.g. tw25164.pp }
+                  add_reg_instruction(instr,tempreg,reginfo[orgreg].weight+1);
                 end;
             end;
 

+ 15 - 0
tests/webtbs/tw25164.pp

@@ -0,0 +1,15 @@
+{ %opt=-Cg }
+{ %target=-linux,freebsd,darwin }
+{ %norun }
+{$mode objfpc}
+
+procedure permute({out} const _out: PByte; {in} const _in: PByte; {in} const p: PByte; {in} const n: Integer);
+var
+  i: Integer;
+begin
+  for i := 0 to n-1 do
+    _out[i] := _in[p[i]-1];
+end;
+
+begin
+end.