|
From: <sv...@va...> - 2005-04-05 01:55:05
|
Author: sewardj
Date: 2005-04-05 02:54:19 +0100 (Tue, 05 Apr 2005)
New Revision: 1119
Modified:
trunk/priv/guest-x86/toIR.c
Log:
Whenever the flags thunk is set, fill in all the fields, even NDEP
which isn't usually used. This makes redundant-PUT elimination work
better, fixing a rather subtle optimisation bug. For at least one
floating-point case this gives a significant speedup. Consider a bb
like this:
(no flag setting insns before inc)
inc ...
(no flag setting insns)
add ...
inc sets CC_OP, CC_DEP1 and CC_NDEP; the latter is expensive because a
call to calculate_eflags_c is required.
add sets CC_OP, CC_DEP1 and CC_DEP2. The CC_NDEP value is now
irrelevant, but because CC_NDEP is not overwritten, iropt cannot
remove the previous assignment to it, and so the expensive helper call
remains even though it is irrelevant.
This commit fixes that: By always setting NDEP to zero whenever its
value will be unused, any previous assignment to it will be removed by
iropt.
This change should be propagated to the amd64 front end too.
Modified: trunk/priv/guest-x86/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-x86/toIR.c 2005-04-04 23:12:54 UTC (rev 1118)
+++ trunk/priv/guest-x86/toIR.c 2005-04-05 01:54:19 UTC (rev 1119)
@@ -1007,6 +1007,9 @@
stmt( IRStmt_Put( OFFB_CC_OP, mkU32(ccOp)) );
stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(dep1))) );
stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(mkexpr(dep2))) );
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
}
=20
=20
@@ -1029,6 +1032,9 @@
stmt( IRStmt_Put( OFFB_CC_OP, mkU32(ccOp)) );
stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(dep1))) );
stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0)) );
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
}
=20
=20
@@ -1070,6 +1076,9 @@
IRExpr_Mux0X( mkexpr(guard),
IRExpr_Get(OFFB_CC_DEP2,Ity_I32),
widenUto32(mkexpr(resUS)))) );
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
}
=20
=20
@@ -1114,6 +1123,9 @@
}
stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(arg1)) ));
stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(mkexpr(arg2)) ));
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
}
=20
=20
@@ -1792,6 +1804,9 @@
stmt( IRStmt_Put( OFFB_CC_OP, mkU32(X86G_CC_OP_COPY) ));
stmt( IRStmt_Put( OFFB_CC_DEP1, mkU32(X86G_CC_MASK_Z|X86G_CC_MASK_P) =
));
stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
DIP("xor%c %s, %s\n", nameISize(size),
nameIReg(size,ge_reg), nameIReg(size,ge_reg) );
}
@@ -2376,6 +2391,9 @@
stmt( IRStmt_Put( OFFB_CC_OP, mkU32(X86G_CC_OP_COPY) ));
stmt( IRStmt_Put( OFFB_CC_DEP1, unop(Iop_64HIto32, mkexpr(r64)) ))=
;
stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
}
=20
if (isShift) {
@@ -2607,6 +2625,9 @@
binop(Iop_Shr32, mkexpr(t2), mkU8(src_val)),
mkU32(1))
));
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
=20
/* Compute the new value into t2m, if non-BT. */
switch (gregOfRM(modrm)) {
@@ -3574,6 +3595,9 @@
binop(Iop_CmpF64, get_ST(0), get_ST(i)),
mkU32(0x45)
)));
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
if (pop_after)
fp_pop();
}
@@ -5882,6 +5906,9 @@
mkexpr(t_bitno2)),
mkU32(1)))
);
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
=20
/* Move reg operand from stack back to reg */
if (epartIsReg(modrm)) {
@@ -5954,6 +5981,9 @@
mkU32(0)
)
));
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
=20
/* Result: iff source value is zero, we can't use
Iop_Clz32/Iop_Ctz32 as they have no defined result in that case.
@@ -6042,6 +6072,9 @@
mkU32(mask_SZACP))
)
));
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
}
=20
=20
@@ -7315,7 +7348,9 @@
unop(Iop_F32toF64,mkexpr(argR))),
mkU32(0x45)
)));
-
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
goto decode_success;
}
=20
@@ -8324,7 +8359,9 @@
binop(Iop_CmpF64, mkexpr(argL), mkexpr(argR)),
mkU32(0x45)
)));
-
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
goto decode_success;
}
=20
@@ -11033,6 +11070,9 @@
)
)
);
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
=20
/* Also need to set the D flag, which is held in bit 10 of t1.
If zero, put 1 in OFFB_DFLAG, else -1 in OFFB_DFLAG. */
|