From 23c724f8859c3fe146c40ed0521250ea48803fa4 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 2 Mar 2014 19:47:05 +0000 Subject: [PATCH] * prevent a temp. register allocated during spilling being immediately spilled again, resolves #25164 git-svn-id: trunk@26930 - --- .gitattributes | 1 + compiler/rgobj.pas | 18 ++++++++++++++---- tests/webtbs/tw25164.pp | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 tests/webtbs/tw25164.pp diff --git a/.gitattributes b/.gitattributes index f140b3001d..d598e2ffa5 100644 --- a/.gitattributes +++ b/.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 diff --git a/compiler/rgobj.pas b/compiler/rgobj.pas index 4af32fb153..4c6f51f6de 100644 --- a/compiler/rgobj.pas +++ b/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; diff --git a/tests/webtbs/tw25164.pp b/tests/webtbs/tw25164.pp new file mode 100644 index 0000000000..0ba56e9ca8 --- /dev/null +++ b/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.