From 58703324a94f7051e331716b17533930006e6edf Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Wed, 21 Jun 2006 17:11:52 +0000 Subject: [PATCH] * fixed issue #6913 (old bug id: #5086) git-svn-id: trunk@3912 - --- .gitattributes | 2 + compiler/i386/csopt386.pas | 32 ++++-- tests/webtbs/tw5086.in | 2 + tests/webtbs/tw5086.pp | 209 +++++++++++++++++++++++++++++++++++++ 4 files changed, 236 insertions(+), 9 deletions(-) create mode 100644 tests/webtbs/tw5086.in create mode 100644 tests/webtbs/tw5086.pp diff --git a/.gitattributes b/.gitattributes index 833a82e4c2..fb94789188 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7179,6 +7179,8 @@ tests/webtbs/tw5015.pp svneol=native#text/plain tests/webtbs/tw5023.pp svneol=native#text/plain tests/webtbs/tw5036.pp svneol=native#text/plain tests/webtbs/tw5082.pp -text svneol=unset#text/plain +tests/webtbs/tw5086.in -text +tests/webtbs/tw5086.pp -text tests/webtbs/tw5094.pp -text tests/webtbs/tw6435.pp svneol=native#text/plain tests/webtbs/tw6491.pp svneol=native#text/plain diff --git a/compiler/i386/csopt386.pas b/compiler/i386/csopt386.pas index c1673ae0c4..ba4350b79a 100644 --- a/compiler/i386/csopt386.pas +++ b/compiler/i386/csopt386.pas @@ -556,17 +556,23 @@ a) movl -4(%ebp),%edx b) tests/webtbs/tw4266.pp } + { hp2 = instruction after previous sequence, pprev = instruction before } + { current sequence, prev = instruction where the loads of the registers } + { will be inserted } for regCounter2 := RS_EAX to RS_EDI do if (reginfo.new2OldReg[regCounter2] <> RS_INVALID) and - (regCounter2 in ptaiprop(hp3.optinfo)^.usedRegs) and { case a) above } - ((not regLoadedWithNewValue(regCounter2,false,hp3) and - lastregloadremoved[regcounter2]) or + (((regCounter2 in ptaiprop(hp3.optinfo)^.usedRegs) and + (not regLoadedWithNewValue(regCounter2,false,hp3) and + lastregloadremoved[regcounter2])) or { case b) above } - ((ptaiprop(pprev.optinfo)^.regs[regcounter2].wstate <> - ptaiprop(hp2.optinfo)^.regs[regcounter2].wstate))) then + ((ptaiprop(hp2.optinfo)^.regs[regCounter2].wstate <> + ptaiprop(pprev.optinfo)^.regs[regcounter2].wstate)) or + ((ptaiprop(hp2.optinfo)^.regs[reginfo.new2OldReg[regCounter2]].wstate <> + ptaiprop(prev.optinfo)^.regs[reginfo.new2OldReg[regCounter2]].wstate))) then begin found := 0; + break; end; if checkingPrevSequences then @@ -1687,7 +1693,7 @@ var regloads, reguses: array[RS_EAX..RS_EDI] of tai; regcounter, substreg: tsuperregister; hp, hp2: tai; - insertpos, prevseq_next: tai; + insertpos, insertoptinfo, prevseq_next: tai; i: longint; opc: tasmop; begin @@ -1727,14 +1733,22 @@ begin getLastInstruction(curseqend,hp); opc := A_MOV; insertpos := prevseq_next; + insertoptinfo := prevseqstart; if assigned(reguses[regcounter]) then if assigned(regloads[reginfo.new2oldreg[regcounter]]) then opc := A_XCHG else - insertpos := tai(reguses[regcounter].next) + begin + insertoptinfo := reguses[regcounter]; + insertpos := tai(insertoptinfo.next) + end else if assigned(regloads[reginfo.new2oldreg[regcounter]]) then - insertpos := regloads[reginfo.new2oldreg[regcounter]]; + begin + insertpos := regloads[reginfo.new2oldreg[regcounter]]; + if not getlastinstruction(insertpos,insertoptinfo) then + internalerror(2006060701); + end; hp := Tai_Marker.Create(mark_NoPropInfoStart); InsertLLItem(asml, insertpos.previous,insertpos, hp); hp2 := taicpu.Op_Reg_Reg(opc, S_L, @@ -1751,7 +1765,7 @@ begin regloads[regcounter] := hp2; reguses[reginfo.new2oldreg[regcounter]] := hp2; new(ptaiprop(hp2.optinfo)); - ptaiprop(hp2.optinfo)^ := ptaiprop(insertpos.optinfo)^; + ptaiprop(hp2.optinfo)^ := ptaiprop(insertoptinfo.optinfo)^; ptaiprop(hp2.optinfo)^.canBeRemoved := false; InsertLLItem(asml, insertpos.previous, insertpos, hp2); hp := Tai_Marker.Create(mark_NoPropInfoEnd); diff --git a/tests/webtbs/tw5086.in b/tests/webtbs/tw5086.in new file mode 100644 index 0000000000..ddf12120cb --- /dev/null +++ b/tests/webtbs/tw5086.in @@ -0,0 +1,2 @@ +180 6 +37 78 59 100 64 128 diff --git a/tests/webtbs/tw5086.pp b/tests/webtbs/tw5086.pp new file mode 100644 index 0000000000..109f55430c --- /dev/null +++ b/tests/webtbs/tw5086.pp @@ -0,0 +1,209 @@ +{ +TASK:water +LANG:PASCAL +} +program water; + +const + MAXV = 200; + +type + Byte = Integer; + TMove = record + a, b, c : Byte; + end; + +var + used : Array [0 .. MAXV, 0 .. MAXV, 0 .. MAXV] of Boolean; + v, k, a1, a2, b1, b2, c1, c2 : Byte; + answ : LongInt; + +procedure readInput; +begin + assign(input,'tw5086.in'); + reset(input); + readln(v, k); + readln(a1, a2, b1, b2, c1, c2); +end; + +procedure dfs(a, b, c, k1: Byte); +var + x : Byte; + d : Array [1 .. 100] of TMove; + dn, i : Byte; + +procedure add(a, b, c: Byte); +var + i : Integer; + fnd : Boolean; +begin + fnd := False; + for i := 1 to dn do + if (d[i].a = a) and (d[i].b = b) and (d[i].c = c) then begin + fnd := True; + break; + end; + if (not fnd) then begin + dn := dn + 1; + d[dn].a := a; d[dn].b := b; d[dn].c := c; + end; +end; + +begin + if (k1 > k) then Exit; + if (a = 1) or (b = 1) or (c = 1) then begin + answ := answ + 1; + Exit; + end; + used[a, b, c] := True; + dn := 0; + if (a > 0) then begin + if (b+a <= v) and (not used[0, b+a, c]) then + add(0, b+a, c); + if (c+a <= v) and (not used[0, b, c+a]) then + add(0, b, c+a); + if (a-a1 > 0) then begin + x := a-a1; + if (b+x <= v) and (not used[a1, b+x, c]) then + add(a1, b+x, c); + if (c+x <= v) and (not used[a1, b, c+x]) then + add(a1, b, c+x); + end; + if (a-a2 > 0) then begin + x := a-a2; + if (b+x <= v) and (not used[a2, b+x, c]) then + add(a2, b+x, c); + if (c+x <= v) and (not used[a2, b, c+x]) then + add(a2, b, c+x); + end; + if (b1-b > 0) then begin + x := b1-b; + if (a-x > 0) and (not used[a-x, b1, c]) then + add(a-x, b1, c); + end; + if (b2-b > 0) then begin + x := b2-b; + if (a-x > 0) and (not used[a-x, b2, c]) then + add(a-x, b2, c); + end; + if (c1-c > 0) then begin + x := c1-c; + if (a-x > 0) and (not used[a-x, b, c1]) then + add(a-x, b, c1); + end; + if (c2-c > 0) then begin + x := c2-c; + if (a-x > 0) and (not used[a-x, b, c2]) then + add(a-x, b, c2); + end; + end; + for i := 1 to dn do + dfs(d[i].a, d[i].b, d[i].c, k1+1); + dn := 0; + if (b > 0) then begin + if (b+a <= v) and (not used[a+b, 0, c]) then + add(a+b, 0, c); + if (c+b <= v) and (not used[a, 0, c+b]) then + add(a, 0, c+b); + if (b-b1 > 0) then begin + x := b-b1; + if (a+x <= v) and (not used[a+x, b1, c]) then + add(a+x, b1, c); + if (c+x <= v) and (not used[a, b1, c+x]) then + add(a, b1, c+x); + end; + if (b-b2 > 0) then begin + x := b-b2; + if (a+x <= v) and (not used[a+x, b2, c]) then + add(a+x, b2, c); + if (c+x <= v) and (not used[a, b2, c+x]) then + add(a, b2, c+x); + end; + if (a1-a > 0) then begin + x := a1-a; + if (b-x > 0) and (not used[a1, b-x, c]) then + add(a1, b-x, c); + end; + if (a2-a > 0) then begin + x := a2-a; + if (b-x > 0) and (not used[a2, b-x, c]) then + add(a2, b-x, c); + end; + if (c1-c > 0) then begin + x := c1-c; + if (b-x > 0) and (not used[a, b-x, c1]) then + add(a, b-x, c1); + end; + if (c2-c > 0) then begin + x := c2-c; + if (b-x > 0) and (not used[a, b-x, c2]) then + add(a, b-x, c2); + end; + end; + for i := 1 to dn do + dfs(d[i].a, d[i].b, d[i].c, k1+1); + dn := 0; + if (c > 0) then begin + if (b+c <= v) and (not used[a, b+c, 0]) then + add(a, b+c, 0); + if (c+a <= v) and (not used[a+c, b, 0]) then + add(a+c, b, 0); + if (c-c1 > 0) then begin + x := c-c1; + if (a+x <= v) and (not used[a+x, b, c1]) then + add(a+x, b, c1); + if (b+x <= v) and (not used[a, b+x, c1]) then + add(a, b+x, c1); + end; + if (c-c2 > 0) then begin + x := c-c2; + if (a+x <= v) and (not used[a+x, b, c2]) then + add(a+x, b, c2); + if (b+x <= v) and (not used[a, b+x, c2]) then + add(a, b+x, c2); + end; + if (b1-b > 0) then begin + x := b1-b; + if (c-x > 0) and (not used[a, b1, c-x]) then + add(a, b1, c-x); + end; + if (b2-b > 0) then begin + x := b2-b; + if (c-x > 0) and (not used[a, b2, c-x]) then + add(a, b2, c-x); + end; + if (a1-a > 0) then begin + x := a1-a; + if (c-x > 0) and (not used[a1, b, c-x]) then + add(a1, b, c-x); + end; + if (a2-a > 0) then begin + x := a2-a; + if (c-x > 0) and (not used[a2, b, c-x]) then + add(a2, b, c-x); + end; + end; + for i := 1 to dn do + dfs(d[i].a, d[i].b, d[i].c, k1+1); + used[a, b, c] := False; +end; + +procedure Solve; +var + i,j,k : Byte; +begin + for i := 0 to v do + for j := 0 to v do + for k := 0 to v do + used[i, j, k] := False; + answ := 0; + dfs(v, 0, 0, 0); + writeln(answ); + if (answ <> 2216) then + halt(1); +end; + +begin + readInput; + Solve; +end.