瀏覽代碼

* fixed issue #6913 (old bug id: #5086)

git-svn-id: trunk@3912 -
Jonas Maebe 19 年之前
父節點
當前提交
58703324a9
共有 4 個文件被更改,包括 236 次插入9 次删除
  1. 2 0
      .gitattributes
  2. 23 9
      compiler/i386/csopt386.pas
  3. 2 0
      tests/webtbs/tw5086.in
  4. 209 0
      tests/webtbs/tw5086.pp

+ 2 - 0
.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

+ 23 - 9
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);

+ 2 - 0
tests/webtbs/tw5086.in

@@ -0,0 +1,2 @@
+180 6
+37 78 59 100 64 128

+ 209 - 0
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.