Discussion:
vex: r3332 - in /branches/VEX_JIT_HACKS: priv/guest_generic_bb_to_IR.c priv/guest_x86_toIR.c priv/host_x86_isel.c priv/ir_defs.c priv/ir_inject.c priv/ir_opt.c pub/libvex_ir.h
(too old to reply)
s***@valgrind.org
2017-03-27 19:44:34 UTC
Permalink
Raw Message
Author: iraisr
Date: Mon Mar 27 20:44:33 2017
New Revision: 3332

Log:
Progress further with a next iteration where we have only single global
type environment.

Modified:
branches/VEX_JIT_HACKS/priv/guest_generic_bb_to_IR.c
branches/VEX_JIT_HACKS/priv/guest_x86_toIR.c
branches/VEX_JIT_HACKS/priv/host_x86_isel.c
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/priv/ir_inject.c
branches/VEX_JIT_HACKS/priv/ir_opt.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h

Modified: branches/VEX_JIT_HACKS/priv/guest_generic_bb_to_IR.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/guest_generic_bb_to_IR.c (original)
+++ branches/VEX_JIT_HACKS/priv/guest_generic_bb_to_IR.c Mon Mar 27 20:44:33 2017
@@ -668,8 +668,8 @@
the area of guest code to invalidate should we exit with a
self-check failure. */

- tistart_tmp = newIRTemp(irsb->stmts->tyenv, guest_word_type);
- tilen_tmp = newIRTemp(irsb->stmts->tyenv, guest_word_type);
+ tistart_tmp = newIRTemp(irsb->tyenv, irsb->stmts, guest_word_type);
+ tilen_tmp = newIRTemp(irsb->tyenv, irsb->stmts, guest_word_type);

IRConst* base2check_IRConst
= guest_word_type==Ity_I32 ? IRConst_U32(toUInt(base2check))

Modified: branches/VEX_JIT_HACKS/priv/guest_x86_toIR.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/guest_x86_toIR.c (original)
+++ branches/VEX_JIT_HACKS/priv/guest_x86_toIR.c Mon Mar 27 20:44:33 2017
@@ -316,11 +316,12 @@
addStmtToIRStmtVec(irsb->stmts, st);
}

-/* Generate a new temporary of the given type. */
+/* Generate a new temporary of the given type.
+ Works only for the main IRStmtVec #0. */
static IRTemp newTemp ( IRType ty )
{
vassert(isPlausibleIRType(ty));
- return newIRTemp(irsb->stmts->tyenv, ty);
+ return newIRTemp(irsb->tyenv, irsb->stmts, ty);
}

/* Various simple conversions */
@@ -548,7 +549,7 @@
/* Ditto, but write to a reg instead. */
static void putIReg ( Int sz, UInt archreg, IRExpr* e )
{
- IRType ty = typeOfIRExpr(irsb->stmts, e);
+ IRType ty = typeOfIRExpr(irsb->tyenv, e);
switch (sz) {
case 1: vassert(ty == Ity_I8); break;
case 2: vassert(ty == Ity_I16); break;
@@ -566,7 +567,7 @@

static void putSReg ( UInt sreg, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I16);
stmt( IRStmt_Put( segmentGuestRegOffset(sreg), e ) );
}

@@ -597,37 +598,37 @@

static void putXMMReg ( UInt xmmreg, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_V128);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_V128);
stmt( IRStmt_Put( xmmGuestRegOffset(xmmreg), e ) );
}

static void putXMMRegLane64 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I64);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );
}

static void putXMMRegLane64F ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_F64);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );
}

static void putXMMRegLane32F ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_F32);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F32);
stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );
}

static void putXMMRegLane32 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I32);
stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );
}

static void putXMMRegLane16 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I16);
stmt( IRStmt_Put( xmmGuestRegLane16offset(xmmreg,laneno), e ) );
}

@@ -735,8 +736,8 @@

static IRExpr* mkAnd1 ( IRExpr* x, IRExpr* y )
{
- vassert(typeOfIRExpr(irsb->stmts, x) == Ity_I1);
- vassert(typeOfIRExpr(irsb->stmts, y) == Ity_I1);
+ vassert(typeOfIRExpr(irsb->tyenv, x) == Ity_I1);
+ vassert(typeOfIRExpr(irsb->tyenv, y) == Ity_I1);
return unop(Iop_32to1,
binop(Iop_And32,
unop(Iop_1Uto32,x),
@@ -753,14 +754,14 @@
Addr32 restart_point )
{
IRCAS* cas;
- IRType tyE = typeOfIRExpr(irsb->stmts, expVal);
- IRType tyN = typeOfIRExpr(irsb->stmts, newVal);
+ IRType tyE = typeOfIRExpr(irsb->tyenv, expVal);
+ IRType tyN = typeOfIRExpr(irsb->tyenv, newVal);
IRTemp oldTmp = newTemp(tyE);
IRTemp expTmp = newTemp(tyE);
vassert(tyE == tyN);
vassert(tyE == Ity_I32 || tyE == Ity_I16 || tyE == Ity_I8);
assign(expTmp, expVal);
- cas = mkIRCAS(IRTemp_INVALID(), oldTmp, Iend_LE, addr,
+ cas = mkIRCAS(IRTemp_INVALID, oldTmp, Iend_LE, addr,
NULL, mkexpr(expTmp), NULL, newVal);
stmt( IRStmt_CAS(cas) );
stmt( IRStmt_Exit(
@@ -868,7 +869,7 @@
/* U-widen 8/16/32 bit int expr to 32. */
static IRExpr* widenUto32 ( IRExpr* e )
{
- switch (typeOfIRExpr(irsb->stmts, e)) {
+ switch (typeOfIRExpr(irsb->tyenv, e)) {
case Ity_I32: return e;
case Ity_I16: return unop(Iop_16Uto32,e);
case Ity_I8: return unop(Iop_8Uto32,e);
@@ -879,7 +880,7 @@
/* S-widen 8/16/32 bit int expr to 32. */
static IRExpr* widenSto32 ( IRExpr* e )
{
- switch (typeOfIRExpr(irsb->stmts, e)) {
+ switch (typeOfIRExpr(irsb->tyenv, e)) {
case Ity_I32: return e;
case Ity_I16: return unop(Iop_16Sto32,e);
case Ity_I8: return unop(Iop_8Sto32,e);
@@ -891,7 +892,7 @@
of these combinations make sense. */
static IRExpr* narrowTo ( IRType dst_ty, IRExpr* e )
{
- IRType src_ty = typeOfIRExpr(irsb->stmts, e);
+ IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
if (src_ty == dst_ty)
return e;
if (src_ty == Ity_I32 && dst_ty == Ity_I16)
@@ -971,7 +972,7 @@
Int ccOp = ty==Ity_I8 ? 2 : (ty==Ity_I16 ? 1 : 0);

vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
- vassert(!isIRTempInvalid(guard));
+ vassert(guard != IRTemp_INVALID);

/* Both kinds of right shifts are handled by the same thunk
operation. */
@@ -1133,7 +1134,7 @@
IROp plus = mkSizedOp(ty, Iop_Add8);
IROp xor = mkSizedOp(ty, Iop_Xor8);

- vassert(typeOfIRTemp(irsb->stmts, tres) == ty);
+ vassert(typeOfIRTemp(irsb->tyenv, tres) == ty);
vassert(sz == 1 || sz == 2 || sz == 4);
thunkOp = sz==4 ? X86G_CC_OP_ADCL
: (sz==2 ? X86G_CC_OP_ADCW : X86G_CC_OP_ADCB);
@@ -1151,12 +1152,12 @@

/* Possibly generate a store of 'tres' to 'taddr'. See comment at
start of this function. */
- if (!isIRTempInvalid(taddr)) {
- if (isIRTempInvalid(texpVal)) {
+ if (taddr != IRTemp_INVALID) {
+ if (texpVal == IRTemp_INVALID) {
vassert(restart_point == 0);
storeLE( mkexpr(taddr), mkexpr(tres) );
} else {
- vassert(typeOfIRTemp(irsb->stmts, texpVal) == ty);
+ vassert(typeOfIRTemp(irsb->tyenv, texpVal) == ty);
/* .. and hence 'texpVal' has the same type as 'tres'. */
casLE( mkexpr(taddr),
mkexpr(texpVal), mkexpr(tres), restart_point );
@@ -1187,7 +1188,7 @@
IROp minus = mkSizedOp(ty, Iop_Sub8);
IROp xor = mkSizedOp(ty, Iop_Xor8);

- vassert(typeOfIRTemp(irsb->stmts, tres) == ty);
+ vassert(typeOfIRTemp(irsb->tyenv, tres) == ty);
vassert(sz == 1 || sz == 2 || sz == 4);
thunkOp = sz==4 ? X86G_CC_OP_SBBL
: (sz==2 ? X86G_CC_OP_SBBW : X86G_CC_OP_SBBB);
@@ -1205,12 +1206,12 @@

/* Possibly generate a store of 'tres' to 'taddr'. See comment at
start of this function. */
- if (!isIRTempInvalid(taddr)) {
- if (isIRTempInvalid(texpVal)) {
+ if (taddr != IRTemp_INVALID) {
+ if (texpVal == IRTemp_INVALID) {
vassert(restart_point == 0);
storeLE( mkexpr(taddr), mkexpr(tres) );
} else {
- vassert(typeOfIRTemp(irsb->stmts, texpVal) == ty);
+ vassert(typeOfIRTemp(irsb->tyenv, texpVal) == ty);
/* .. and hence 'texpVal' has the same type as 'tres'. */
casLE( mkexpr(taddr),
mkexpr(texpVal), mkexpr(tres), restart_point );
@@ -1838,7 +1839,7 @@
IRTemp src = newTemp(ty);
IRTemp dst0 = newTemp(ty);
UChar rm = getUChar(delta0);
- IRTemp addr = IRTemp_INVALID();
+ IRTemp addr = IRTemp_INVALID;

/* addSubCarry == True indicates the intended operation is
add-with-carry or subtract-with-borrow. */
@@ -1861,12 +1862,12 @@

if (addSubCarry && op8 == Iop_Add8) {
helper_ADC( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
putIReg(size, gregOfRM(rm), mkexpr(dst1));
} else
if (addSubCarry && op8 == Iop_Sub8) {
helper_SBB( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
putIReg(size, gregOfRM(rm), mkexpr(dst1));
} else {
assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
@@ -1890,12 +1891,12 @@

if (addSubCarry && op8 == Iop_Add8) {
helper_ADC( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
putIReg(size, gregOfRM(rm), mkexpr(dst1));
} else
if (addSubCarry && op8 == Iop_Sub8) {
helper_SBB( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
putIReg(size, gregOfRM(rm), mkexpr(dst1));
} else {
assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
@@ -1951,7 +1952,7 @@
IRTemp src = newTemp(ty);
IRTemp dst0 = newTemp(ty);
UChar rm = getIByte(delta0);
- IRTemp addr = IRTemp_INVALID();
+ IRTemp addr = IRTemp_INVALID;

/* addSubCarry == True indicates the intended operation is
add-with-carry or subtract-with-borrow. */
@@ -1974,12 +1975,12 @@

if (addSubCarry && op8 == Iop_Add8) {
helper_ADC( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
putIReg(size, eregOfRM(rm), mkexpr(dst1));
} else
if (addSubCarry && op8 == Iop_Sub8) {
helper_SBB( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
putIReg(size, eregOfRM(rm), mkexpr(dst1));
} else {
assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
@@ -2011,7 +2012,7 @@
} else {
/* normal store */
helper_ADC( size, dst1, dst0, src,
- /*store*/addr, IRTemp_INVALID(), 0 );
+ /*store*/addr, IRTemp_INVALID, 0 );
}
} else
if (addSubCarry && op8 == Iop_Sub8) {
@@ -2022,7 +2023,7 @@
} else {
/* normal store */
helper_SBB( size, dst1, dst0, src,
- /*store*/addr, IRTemp_INVALID(), 0 );
+ /*store*/addr, IRTemp_INVALID, 0 );
}
} else {
assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
@@ -2168,12 +2169,12 @@
else
if (op8 == Iop_Add8 && carrying) {
helper_ADC( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
}
else
if (op8 == Iop_Sub8 && carrying) {
helper_SBB( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
}
else
vpanic("dis_op_imm_A(x86,guest)");
@@ -2291,7 +2292,7 @@
IRTemp dst1 = newTemp(ty);
IRTemp src = newTemp(ty);
IRTemp dst0 = newTemp(ty);
- IRTemp addr = IRTemp_INVALID();
+ IRTemp addr = IRTemp_INVALID;
IROp op8 = Iop_INVALID;
UInt mask = sz==1 ? 0xFF : (sz==2 ? 0xFFFF : 0xFFFFFFFF);

@@ -2313,11 +2314,11 @@

if (gregOfRM(modrm) == 2 /* ADC */) {
helper_ADC( sz, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
} else
if (gregOfRM(modrm) == 3 /* SBB */) {
helper_SBB( sz, dst1, dst0, src,
- /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
+ /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
} else {
assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
if (isAddSub(op8))
@@ -2346,7 +2347,7 @@
} else {
/* normal store */
helper_ADC( sz, dst1, dst0, src,
- /*store*/addr, IRTemp_INVALID(), 0 );
+ /*store*/addr, IRTemp_INVALID, 0 );
}
} else
if (gregOfRM(modrm) == 3 /* SBB */) {
@@ -2357,7 +2358,7 @@
} else {
/* normal store */
helper_SBB( sz, dst1, dst0, src,
- /*store*/addr, IRTemp_INVALID(), 0 );
+ /*store*/addr, IRTemp_INVALID, 0 );
}
} else {
assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
@@ -2400,7 +2401,7 @@
IRType ty = szToITy(sz);
IRTemp dst0 = newTemp(ty);
IRTemp dst1 = newTemp(ty);
- IRTemp addr = IRTemp_INVALID();
+ IRTemp addr = IRTemp_INVALID;

*decode_OK = True;

@@ -2638,7 +2639,7 @@
IRType ty = szToITy(sz);
IRTemp t2 = newTemp(Ity_I32);
IRTemp t2m = newTemp(Ity_I32);
- IRTemp t_addr = IRTemp_INVALID();
+ IRTemp t_addr = IRTemp_INVALID;
HChar dis_buf[50];
UInt mask;

@@ -3043,10 +3044,10 @@
Int len;
UChar modrm;
HChar dis_buf[50];
- IRTemp addr = IRTemp_INVALID();
+ IRTemp addr = IRTemp_INVALID;
IRType ty = szToITy(sz);
IRTemp t1 = newTemp(ty);
- IRTemp t2 = IRTemp_INVALID();
+ IRTemp t2 = IRTemp_INVALID;

*decode_OK = True;

@@ -3432,7 +3433,6 @@
mkU32(8 * sizeofIRType(ty)),
unop(Iop_Clz32, mkexpr(src32x))
));
-
IRTemp res = newTemp(ty);
assign(res, narrowTo(ty, mkexpr(res32)));
return res;
@@ -3451,7 +3451,7 @@

static void put_emwarn ( IRExpr* e /* :: Ity_I32 */ )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I32);
stmt( IRStmt_Put( OFFB_EMNOTE, e ) );
}

@@ -3475,7 +3475,7 @@

static void put_ftop ( IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I32);
stmt( IRStmt_Put( OFFB_FTOP, e ) );
}

@@ -3527,7 +3527,7 @@
static void put_ST_TAG ( Int i, IRExpr* value )
{
IRRegArray* descr;
- vassert(typeOfIRExpr(irsb->stmts, value) == Ity_I8);
+ vassert(typeOfIRExpr(irsb->tyenv, value) == Ity_I8);
descr = mkIRRegArray( OFFB_FPTAGS, Ity_I8, 8 );
stmt( IRStmt_PutI( mkIRPutI(descr, get_ftop(), i, value) ) );
}
@@ -3551,7 +3551,7 @@
static void put_ST_UNCHECKED ( Int i, IRExpr* value )
{
IRRegArray* descr;
- vassert(typeOfIRExpr(irsb->stmts, value) == Ity_F64);
+ vassert(typeOfIRExpr(irsb->tyenv, value) == Ity_F64);
descr = mkIRRegArray( OFFB_FPREGS, Ity_F64, 8 );
stmt( IRStmt_PutI( mkIRPutI(descr, get_ftop(), i, value) ) );
/* Mark the register as in-use. */
@@ -5141,7 +5141,7 @@

case 7: { /* FNSTSW m16 */
IRExpr* sw = get_FPU_sw();
- vassert(typeOfIRExpr(irsb->stmts, sw) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->tyenv, sw) == Ity_I16);
storeLE( mkexpr(addr), sw );
DIP("fnstsw %s\n", dis_buf);
break;
@@ -5543,7 +5543,7 @@
static void putMMXReg ( UInt archreg, IRExpr* e )
{
vassert(archreg < 8);
- vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I64);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
stmt( IRStmt_Put( OFFB_FPREGS + 8 * archreg, e ) );
}

@@ -6193,11 +6193,11 @@
IRType ty = szToITy(sz);
IRTemp gsrc = newTemp(ty);
IRTemp esrc = newTemp(ty);
- IRTemp addr = IRTemp_INVALID();
+ IRTemp addr = IRTemp_INVALID;
IRTemp tmpSH = newTemp(Ity_I8);
- IRTemp tmpL = IRTemp_INVALID();
- IRTemp tmpRes = IRTemp_INVALID();
- IRTemp tmpSubSh = IRTemp_INVALID();
+ IRTemp tmpL = IRTemp_INVALID;
+ IRTemp tmpRes = IRTemp_INVALID;
+ IRTemp tmpSubSh = IRTemp_INVALID;
IROp mkpair;
IROp getres;
IROp shift;
@@ -6325,7 +6325,7 @@

t_fetched = t_bitno0 = t_bitno1 = t_bitno2
= t_addr0 = t_addr1 = t_esp
- = t_mask = t_new = IRTemp_INVALID();
+ = t_mask = t_new = IRTemp_INVALID;

t_fetched = newTemp(Ity_I8);
t_new = newTemp(Ity_I8);
@@ -6652,7 +6652,7 @@
IRTemp dest2 = newTemp(ty);
IRTemp acc2 = newTemp(ty);
IRTemp cond = newTemp(Ity_I1);
- IRTemp addr = IRTemp_INVALID();
+ IRTemp addr = IRTemp_INVALID;
UChar rm = getUChar(delta0);

/* There are 3 cases to consider:
@@ -6708,7 +6708,7 @@
assign( src, getIReg(size, gregOfRM(rm)) );
assign( acc, getIReg(size, R_EAX) );
stmt( IRStmt_CAS(
- mkIRCAS( IRTemp_INVALID(), dest, Iend_LE, mkexpr(addr),
+ mkIRCAS( IRTemp_INVALID, dest, Iend_LE, mkexpr(addr),
NULL, mkexpr(acc), NULL, mkexpr(src) )
));
setFlags_DEP1_DEP2(Iop_Sub8, acc, dest, ty);
@@ -7542,7 +7542,7 @@

static void put_sse_roundingmode ( IRExpr* sseround )
{
- vassert(typeOfIRExpr(irsb->stmts, sseround) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->tyenv, sseround) == Ity_I32);
stmt( IRStmt_Put( OFFB_SSEROUND, sseround ) );
}

@@ -7558,10 +7558,10 @@
assign( hi64, unop(Iop_V128HIto64, mkexpr(t128)) );
assign( lo64, unop(Iop_V128to64, mkexpr(t128)) );

- vassert(t0 && isIRTempInvalid(*t0));
- vassert(t1 && isIRTempInvalid(*t1));
- vassert(t2 && isIRTempInvalid(*t2));
- vassert(t3 && isIRTempInvalid(*t3));
+ vassert(t0 && *t0 == IRTemp_INVALID);
+ vassert(t1 && *t1 == IRTemp_INVALID);
+ vassert(t2 && *t2 == IRTemp_INVALID);
+ vassert(t3 && *t3 == IRTemp_INVALID);

*t0 = newTemp(Ity_I32);
*t1 = newTemp(Ity_I32);
@@ -7597,10 +7597,10 @@
assign( hi32, unop(Iop_64HIto32, mkexpr(t64)) );
assign( lo32, unop(Iop_64to32, mkexpr(t64)) );

- vassert(t0 && isIRTempInvalid(*t0));
- vassert(t1 && isIRTempInvalid(*t1));
- vassert(t2 && isIRTempInvalid(*t2));
- vassert(t3 && isIRTempInvalid(*t3));
+ vassert(t0 && *t0 == IRTemp_INVALID);
+ vassert(t1 && *t1 == IRTemp_INVALID);
+ vassert(t2 && *t2 == IRTemp_INVALID);
+ vassert(t3 && *t3 == IRTemp_INVALID);

*t0 = newTemp(Ity_I16);
*t1 = newTemp(Ity_I16);
@@ -7642,7 +7642,7 @@
Bool emit_AC_emwarn,
Addr32 next_insn_EIP )
{
- vassert(typeOfIRTemp(irsb->stmts,t1) == Ity_I32);
+ vassert(typeOfIRTemp(irsb->tyenv,t1) == Ity_I32);

/* t1 is the flag word. Mask out everything except OSZACP and set
the flags thunk to X86G_CC_OP_COPY. */
@@ -8116,7 +8116,7 @@

*expect_CAS = False;

- addr = t0 = t1 = t2 = t3 = t4 = t5 = t6 = IRTemp_INVALID();
+ addr = t0 = t1 = t2 = t3 = t4 = t5 = t6 = IRTemp_INVALID;

vassert(guest_EIP_bbstart + delta == guest_EIP_curr_instr);
DIP("\t0x%x: ", guest_EIP_bbstart+delta);
@@ -9044,7 +9044,7 @@
if (sz == 4 && insn[0] == 0x0F && insn[1] == 0x70) {
Int order;
IRTemp sV, dV, s3, s2, s1, s0;
- s3 = s2 = s1 = s0 = IRTemp_INVALID();
+ s3 = s2 = s1 = s0 = IRTemp_INVALID;
sV = newTemp(Ity_I64);
dV = newTemp(Ity_I64);
do_MMX_preamble();
@@ -9395,7 +9395,7 @@
IRTemp s3, s2, s1, s0, d3, d2, d1, d0;
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
- s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID();
+ s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID;
modrm = insn[2];
assign( dV, getXMMReg(gregOfRM(modrm)) );

@@ -9496,7 +9496,7 @@
Bool hi = toBool(insn[1] == 0x15);
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
- s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID();
+ s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID;
modrm = insn[2];
assign( dV, getXMMReg(gregOfRM(modrm)) );

@@ -11155,7 +11155,7 @@
IRTemp s3, s2, s1, s0, d3, d2, d1, d0;
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
- s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID();
+ s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID;
t1 = newTemp(Ity_I64);
t0 = newTemp(Ity_I64);
modrm = insn[2];
@@ -11241,7 +11241,7 @@
if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x70) {
Int order;
IRTemp sV, dV, s3, s2, s1, s0;
- s3 = s2 = s1 = s0 = IRTemp_INVALID();
+ s3 = s2 = s1 = s0 = IRTemp_INVALID;
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
modrm = insn[2];
@@ -11279,7 +11279,7 @@
if (insn[0] == 0xF3 && insn[1] == 0x0F && insn[2] == 0x70) {
Int order;
IRTemp sVhi, dVhi, sV, dV, s3, s2, s1, s0;
- s3 = s2 = s1 = s0 = IRTemp_INVALID();
+ s3 = s2 = s1 = s0 = IRTemp_INVALID;
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
sVhi = newTemp(Ity_I64);
@@ -11323,7 +11323,7 @@
if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0x70) {
Int order;
IRTemp sVlo, dVlo, sV, dV, s3, s2, s1, s0;
- s3 = s2 = s1 = s0 = IRTemp_INVALID();
+ s3 = s2 = s1 = s0 = IRTemp_INVALID;
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
sVlo = newTemp(Ity_I64);
@@ -11800,7 +11800,7 @@
IRTemp s3, s2, s1, s0;
IRTemp sV = newTemp(Ity_V128);
Bool isH = insn[2] == 0x16;
- s3 = s2 = s1 = s0 = IRTemp_INVALID();
+ s3 = s2 = s1 = s0 = IRTemp_INVALID;

modrm = insn[3];
if (epartIsReg(modrm)) {
@@ -11859,7 +11859,7 @@
IRTemp addV = newTemp(Ity_V128);
IRTemp subV = newTemp(Ity_V128);
IRTemp rm = newTemp(Ity_I32);
- a3 = a2 = a1 = a0 = s3 = s2 = s1 = s0 = IRTemp_INVALID();
+ a3 = a2 = a1 = a0 = s3 = s2 = s1 = s0 = IRTemp_INVALID;

modrm = insn[3];
if (epartIsReg(modrm)) {
@@ -11938,7 +11938,7 @@
IRTemp rm = newTemp(Ity_I32);
Bool isAdd = insn[2] == 0x7C;
const HChar* str = isAdd ? "add" : "sub";
- e3 = e2 = e1 = e0 = g3 = g2 = g1 = g0 = IRTemp_INVALID();
+ e3 = e2 = e1 = e0 = g3 = g2 = g1 = g0 = IRTemp_INVALID;

modrm = insn[3];
if (epartIsReg(modrm)) {

Modified: branches/VEX_JIT_HACKS/priv/host_x86_isel.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_x86_isel.c (original)
+++ branches/VEX_JIT_HACKS/priv/host_x86_isel.c Mon Mar 27 20:44:33 2017
@@ -172,6 +172,7 @@
typedef
struct {
/* Constant -- are set at the start and do not change. */
+ IRTypeEnv* type_env;
IRStmtVec* stmts;

HReg* vregmap;
@@ -192,20 +193,18 @@

static HReg lookupIRTemp ( ISelEnv* env, IRTemp tmp )
{
- vassert(tmp.id == 0); // TODO-JIT: assume now only IRTypeEnv ID #0
- vassert(tmp.index >= 0);
- vassert(tmp.index < env->n_vregmap);
- return env->vregmap[tmp.index];
+ vassert(tmp >= 0);
+ vassert(tmp < env->n_vregmap);
+ return env->vregmap[tmp];
}

static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp )
{
- vassert(tmp.id == 0); // TODO-JIT: assume now only IRTypeEnv ID #0
- vassert(tmp.index >= 0);
- vassert(tmp.index < env->n_vregmap);
- vassert(! hregIsInvalid(env->vregmapHI[tmp.index]));
- *vrLO = env->vregmap[tmp.index];
- *vrHI = env->vregmapHI[tmp.index];
+ vassert(tmp >= 0);
+ vassert(tmp < env->n_vregmap);
+ vassert(! hregIsInvalid(env->vregmapHI[tmp]));
+ *vrLO = env->vregmap[tmp];
+ *vrHI = env->vregmapHI[tmp];
}

static void addInstr ( ISelEnv* env, X86Instr* instr )
@@ -359,7 +358,7 @@
return 1;
}
/* Else it's a "normal" expression. */
- IRType arg_ty = typeOfIRExpr(env->stmts, arg);
+ IRType arg_ty = typeOfIRExpr(env->type_env, arg);
if (arg_ty == Ity_I32) {
addInstr(env, X86Instr_Push(iselIntExpr_RMI(env, arg)));
return 1;
@@ -593,7 +592,7 @@
else if (UNLIKELY(arg->tag == Iex_GSPTR)) {
vassert(0); //ATC
} else {
- vassert(typeOfIRExpr(env->stmts, arg) == Ity_I32);
+ vassert(typeOfIRExpr(env->type_env, arg) == Ity_I32);
tmpregs[argreg] = iselIntExpr_R(env, arg);
}
not_done_yet--;
@@ -620,7 +619,7 @@
else if (UNLIKELY(arg->tag == Iex_GSPTR)) {
vassert(0); //ATC
} else {
- vassert(typeOfIRExpr(env->stmts, arg) == Ity_I32);
+ vassert(typeOfIRExpr(env->type_env, arg) == Ity_I32);
addInstr(env, X86Instr_Alu32R(Xalu_MOV,
iselIntExpr_RMI(env, arg),
argregs[argreg]));
@@ -854,7 +853,7 @@
{
MatchInfo mi;

- IRType ty = typeOfIRExpr(env->stmts, e);
+ IRType ty = typeOfIRExpr(env->type_env, e);
vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);

switch (e->tag) {
@@ -1495,7 +1494,7 @@
/* --------- MULTIPLEX --------- */
case Iex_ITE: { // VFD
if ((ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8)
- && typeOfIRExpr(env->stmts, e->Iex.ITE.cond) == Ity_I1) {
+ && typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1) {
HReg r1 = iselIntExpr_R(env, e->Iex.ITE.iftrue);
X86RM* r0 = iselIntExpr_RM(env, e->Iex.ITE.iffalse);
HReg dst = newVRegI(env);
@@ -1558,7 +1557,7 @@
/* DO NOT CALL THIS DIRECTLY ! */
static X86AMode* iselIntExpr_AMode_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->stmts, e);
+ IRType ty = typeOfIRExpr(env->type_env, e);
vassert(ty == Ity_I32);

/* Add32( Add32(expr1, Shl32(expr2, simm)), imm32 ) */
@@ -1645,7 +1644,7 @@
/* DO NOT CALL THIS DIRECTLY ! */
static X86RMI* iselIntExpr_RMI_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->stmts, e);
+ IRType ty = typeOfIRExpr(env->type_env, e);
vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);

/* special case: immediate */
@@ -1705,7 +1704,7 @@
/* DO NOT CALL THIS DIRECTLY ! */
static X86RI* iselIntExpr_RI_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->stmts, e);
+ IRType ty = typeOfIRExpr(env->type_env, e);
vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);

/* special case: immediate */
@@ -1753,7 +1752,7 @@
/* DO NOT CALL THIS DIRECTLY ! */
static X86RM* iselIntExpr_RM_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->stmts, e);
+ IRType ty = typeOfIRExpr(env->type_env, e);
vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);

/* special case: 32-bit GET */
@@ -1790,7 +1789,7 @@
MatchInfo mi;

vassert(e);
- vassert(typeOfIRExpr(env->stmts, e) == Ity_I1);
+ vassert(typeOfIRExpr(env->type_env, e) == Ity_I1);

/* var */
if (e->tag == Iex_RdTmp) {
@@ -2091,7 +2090,7 @@
MatchInfo mi;
HWord fn = 0; /* helper fn for most SIMD64 stuff */
vassert(e);
- vassert(typeOfIRExpr(env->stmts, e) == Ity_I64);
+ vassert(typeOfIRExpr(env->type_env, e) == Ity_I64);

/* 64-bit literal */
if (e->tag == Iex_Const) {
@@ -2889,7 +2888,7 @@
/* DO NOT CALL THIS DIRECTLY */
static HReg iselFltExpr_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->stmts, e);
+ IRType ty = typeOfIRExpr(env->type_env, e);
vassert(ty == Ity_F32);

if (e->tag == Iex_RdTmp) {
@@ -3006,7 +3005,7 @@
/* DO NOT CALL THIS DIRECTLY */
static HReg iselDblExpr_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->stmts, e);
+ IRType ty = typeOfIRExpr(env->type_env, e);
vassert(e);
vassert(ty == Ity_F64);

@@ -3223,7 +3222,7 @@
/* --------- MULTIPLEX --------- */
if (e->tag == Iex_ITE) { // VFD
if (ty == Ity_F64
- && typeOfIRExpr(env->stmts, e->Iex.ITE.cond) == Ity_I1) {
+ && typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1) {
HReg r1 = iselDblExpr(env, e->Iex.ITE.iftrue);
HReg r0 = iselDblExpr(env, e->Iex.ITE.iffalse);
HReg dst = newVRegF(env);
@@ -3277,7 +3276,7 @@
MatchInfo mi;
Bool arg1isEReg = False;
X86SseOp op = Xsse_INVALID;
- IRType ty = typeOfIRExpr(env->stmts, e);
+ IRType ty = typeOfIRExpr(env->type_env, e);
vassert(e);
vassert(ty == Ity_V128);

@@ -3873,8 +3872,8 @@

/* --------- STORE --------- */
case Ist_Store: {
- IRType tya = typeOfIRExpr(env->stmts, stmt->Ist.Store.addr);
- IRType tyd = typeOfIRExpr(env->stmts, stmt->Ist.Store.data);
+ IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
+ IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
IREndness end = stmt->Ist.Store.end;

if (tya != Ity_I32 || end != Iend_LE)
@@ -3926,7 +3925,7 @@

/* --------- PUT --------- */
case Ist_Put: {
- IRType ty = typeOfIRExpr(env->stmts, stmt->Ist.Put.data);
+ IRType ty = typeOfIRExpr(env->type_env, stmt->Ist.Put.data);
if (ty == Ity_I32) {
/* We're going to write to memory, so compute the RHS into an
X86RI. */
@@ -3989,7 +3988,7 @@
env, puti->descr,
puti->ix, puti->bias );

- IRType ty = typeOfIRExpr(env->stmts, puti->data);
+ IRType ty = typeOfIRExpr(env->type_env, puti->data);
if (ty == Ity_F64) {
HReg val = iselDblExpr(env, puti->data);
addInstr(env, X86Instr_FpLdSt( False/*store*/, 8, val, am ));
@@ -4019,7 +4018,7 @@
/* --------- TMP --------- */
case Ist_WrTmp: {
IRTemp tmp = stmt->Ist.WrTmp.tmp;
- IRType ty = typeOfIRTemp(env->stmts, tmp);
+ IRType ty = typeOfIRTemp(env->type_env, tmp);

/* optimisation: if stmt->Ist.WrTmp.data is Add32(..,..),
compute it into an AMode and then use LEA. This usually
@@ -4091,8 +4090,8 @@

/* Figure out the return type, if any. */
IRType retty = Ity_INVALID;
- if (!isIRTempInvalid(d->tmp))
- retty = typeOfIRTemp(env->stmts, d->tmp);
+ if (d->tmp != IRTemp_INVALID)
+ retty = typeOfIRTemp(env->type_env, d->tmp);

Bool retty_ok = False;
switch (retty) {
@@ -4118,7 +4117,7 @@
switch (retty) {
case Ity_INVALID: {
/* No return value. Nothing to do. */
- vassert(isIRTempInvalid(d->tmp));
+ vassert(d->tmp == IRTemp_INVALID);
vassert(rloc.pri == RLPri_None);
vassert(addToSp == 0);
return;
@@ -4176,11 +4175,11 @@

/* --------- ACAS --------- */
case Ist_CAS:
- if (isIRTempInvalid(stmt->Ist.CAS.details->oldHi)) {
+ if (stmt->Ist.CAS.details->oldHi == IRTemp_INVALID) {
/* "normal" singleton CAS */
UChar sz;
IRCAS* cas = stmt->Ist.CAS.details;
- IRType ty = typeOfIRExpr(env->stmts, cas->dataLo);
+ IRType ty = typeOfIRExpr(env->type_env, cas->dataLo);
/* get: cas->expdLo into %eax, and cas->dataLo into %ebx */
X86AMode* am = iselIntExpr_AMode(env, cas->addr);
HReg rDataLo = iselIntExpr_R(env, cas->dataLo);
@@ -4205,7 +4204,7 @@
} else {
/* double CAS */
IRCAS* cas = stmt->Ist.CAS.details;
- IRType ty = typeOfIRExpr(env->stmts, cas->dataLo);
+ IRType ty = typeOfIRExpr(env->type_env, cas->dataLo);
/* only 32-bit allowed in this case */
/* get: cas->expdLo into %eax, and cas->dataLo into %ebx */
/* get: cas->expdHi into %edx, and cas->dataHi into %ecx */
@@ -4463,7 +4462,7 @@

/* Make up an IRTemp -> virtual HReg mapping. This doesn't
change as we go along. */
- env->n_vregmap = bb->stmts->tyenv->types_used;
+ env->n_vregmap = bb->tyenv->used;
env->vregmap = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
env->vregmapHI = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));

@@ -4477,7 +4476,7 @@
j = 0;
for (i = 0; i < env->n_vregmap; i++) {
hregHI = hreg = INVALID_HREG;
- switch (bb->stmts->tyenv->types[i]) {
+ switch (bb->tyenv->types[i]) {
case Ity_I1:
case Ity_I8:
case Ity_I16:
@@ -4487,7 +4486,7 @@
case Ity_F32:
case Ity_F64: hreg = mkHReg(True, HRcFlt64, 0, j++); break;
case Ity_V128: hreg = mkHReg(True, HRcVec128, 0, j++); break;
- default: ppIRType(bb->stmts->tyenv->types[i]);
+ default: ppIRType(bb->tyenv->types[i]);
vpanic("iselBB: IRTemp type");
}
env->vregmap[i] = hreg;

Modified: branches/VEX_JIT_HACKS/priv/ir_defs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_defs.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_defs.c Mon Mar 27 20:44:33 2017
@@ -3788,6 +3788,13 @@
def_set->set[tmp / sizeof(UChar)] |= mask;
}

+void clearIRTempDefSet(IRTempDefSet* def_set)
+{
+ for (UInt i = 0; i < def_set->slots_used; i++) {
+ def_set->set[i] = 0;
+ }
+}
+
/*---------------------------------------------------------------*/
/*--- Helper functions for the IR -- IR Basic Blocks ---*/
/*---------------------------------------------------------------*/
@@ -3831,16 +3838,11 @@
/*--- Helper functions for the IR -- IR Type Environments ---*/
/*---------------------------------------------------------------*/

-IRTemp newIRTemp(IRTypeEnv* env, IRStmtVec* stmts, IRType ty)
+void ensureSpaceInIRTypeEnv(IRTypeEnv* env, UInt new_size)
{
vassert(env != NULL);
- vassert(stmts != NULL);
- vassert(env->used >= 0);
- vassert(env->size >= 0);
- vassert(env->used <= env->size);

- if (env->used == env->size) {
- UInt new_size = 2 * env->size;
+ if (new_size > env->size) {
IRType* new_types = LibVEX_Alloc_inline(new_size * sizeof(IRType));
IRStmtVecID* new_ids = LibVEX_Alloc_inline(new_size * sizeof(IRStmtVecID));
for (UInt i = 0; i < env->used; i++) {
@@ -3851,6 +3853,19 @@
env->ids = new_ids;
env->size = new_size;
}
+}
+
+IRTemp newIRTemp(IRTypeEnv* env, IRStmtVec* stmts, IRType ty)
+{
+ vassert(env != NULL);
+ vassert(stmts != NULL);
+ vassert(env->used >= 0);
+ vassert(env->size >= 0);
+ vassert(env->used <= env->size);
+
+ if (env->used == env->size) {
+ ensureSpaceInIRTypeEnv(env, 2 * env->size);
+ }

IRTemp tmp = env->used;
env->used += 1;
@@ -5131,7 +5146,7 @@
void sanityCheckIRSB(const IRSB* bb, const HChar* caller, Bool require_flat,
IRType gWordTy)
{
- UInt n_ids = bb->id_seq + 1;
+ UInt n_ids = bb->id_seq;
UInt *id_counts = LibVEX_Alloc_inline(n_ids * sizeof(UInt));
for (UInt i = 0; i < n_ids; i++) {
id_counts[i] = 0;

Modified: branches/VEX_JIT_HACKS/priv/ir_inject.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_inject.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_inject.c Mon Mar 27 20:44:33 2017
@@ -125,13 +125,13 @@
static void
store_aux(IRSB *irsb, IREndness endian, IRExpr *addr, IRExpr *data)
{
- if (typeOfIRExpr(irsb->stmts, data) == Ity_D64) {
+ if (typeOfIRExpr(irsb->tyenv, data) == Ity_D64) {
/* The insn selectors do not support writing a DFP value to memory.
So we need to fix it here by reinterpreting the DFP value as an
integer and storing that. */
data = unop(Iop_ReinterpD64asI64, data);
}
- if (typeOfIRExpr(irsb->stmts, data) == Ity_I1) {
+ if (typeOfIRExpr(irsb->tyenv, data) == Ity_I1) {
/* We cannot store a single bit. So we store it in a 32-bit container.
See also load_aux. */
data = unop(Iop_1Uto32, data);
@@ -158,7 +158,7 @@
vpanic("invalid #bytes for address");
}

- IRType type = typeOfIRExpr(irsb->stmts, data);
+ IRType type = typeOfIRExpr(irsb->tyenv, data);

vassert(type == Ity_I1 || sizeofIRType(type) <= 16);


Modified: branches/VEX_JIT_HACKS/priv/ir_opt.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_opt.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_opt.c Mon Mar 27 20:44:33 2017
@@ -282,80 +282,79 @@
the same value, after having appended extra IRTemp assignments to
the end of 'stmts'. */

-static IRExpr* flatten_Expr(IRStmtVec* stmts, IRExpr* ex)
+static IRExpr* flatten_Expr(IRTypeEnv* tyenv, IRStmtVec* stmts, IRExpr* ex)
{
Int i;
IRExpr** newargs;
- IRTypeEnv* tyenv = stmts->tyenv;
- IRType ty = typeOfIRExpr(stmts, ex);
+ IRType ty = typeOfIRExpr(tyenv, ex);
IRTemp t1;

switch (ex->tag) {

case Iex_GetI:
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_GetI(ex->Iex.GetI.descr,
- flatten_Expr(stmts, ex->Iex.GetI.ix),
+ flatten_Expr(tyenv, stmts, ex->Iex.GetI.ix),
ex->Iex.GetI.bias)));
return IRExpr_RdTmp(t1);

case Iex_Get:
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1, ex));
return IRExpr_RdTmp(t1);

case Iex_Qop: {
IRQop* qop = ex->Iex.Qop.details;
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Qop(qop->op,
- flatten_Expr(stmts, qop->arg1),
- flatten_Expr(stmts, qop->arg2),
- flatten_Expr(stmts, qop->arg3),
- flatten_Expr(stmts, qop->arg4))));
+ flatten_Expr(tyenv, stmts, qop->arg1),
+ flatten_Expr(tyenv, stmts, qop->arg2),
+ flatten_Expr(tyenv, stmts, qop->arg3),
+ flatten_Expr(tyenv, stmts, qop->arg4))));
return IRExpr_RdTmp(t1);
}

case Iex_Triop: {
IRTriop* triop = ex->Iex.Triop.details;
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Triop(triop->op,
- flatten_Expr(stmts, triop->arg1),
- flatten_Expr(stmts, triop->arg2),
- flatten_Expr(stmts, triop->arg3))));
+ flatten_Expr(tyenv, stmts, triop->arg1),
+ flatten_Expr(tyenv, stmts, triop->arg2),
+ flatten_Expr(tyenv, stmts, triop->arg3))));
return IRExpr_RdTmp(t1);
}

case Iex_Binop:
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Binop(ex->Iex.Binop.op,
- flatten_Expr(stmts, ex->Iex.Binop.arg1),
- flatten_Expr(stmts, ex->Iex.Binop.arg2))));
+ flatten_Expr(tyenv, stmts, ex->Iex.Binop.arg1),
+ flatten_Expr(tyenv, stmts, ex->Iex.Binop.arg2))));
return IRExpr_RdTmp(t1);

case Iex_Unop:
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Unop(ex->Iex.Unop.op,
- flatten_Expr(stmts, ex->Iex.Unop.arg))));
+ flatten_Expr(tyenv, stmts, ex->Iex.Unop.arg))));
return IRExpr_RdTmp(t1);

case Iex_Load:
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Load(ex->Iex.Load.end,
ex->Iex.Load.ty,
- flatten_Expr(stmts, ex->Iex.Load.addr))));
+ flatten_Expr(tyenv, stmts, ex->Iex.Load.addr))));
return IRExpr_RdTmp(t1);

case Iex_CCall:
newargs = shallowCopyIRExprVec(ex->Iex.CCall.args);
for (i = 0; newargs[i]; i++)
- newargs[i] = flatten_Expr(stmts, newargs[i]);
- t1 = newIRTemp(tyenv, ty);
+ newargs[i] = flatten_Expr(tyenv, stmts, newargs[i]);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_CCall(ex->Iex.CCall.cee,
ex->Iex.CCall.retty,
@@ -363,18 +362,18 @@
return IRExpr_RdTmp(t1);

case Iex_ITE:
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
- IRExpr_ITE(flatten_Expr(stmts, ex->Iex.ITE.cond),
- flatten_Expr(stmts, ex->Iex.ITE.iftrue),
- flatten_Expr(stmts, ex->Iex.ITE.iffalse))));
+ IRExpr_ITE(flatten_Expr(tyenv, stmts, ex->Iex.ITE.cond),
+ flatten_Expr(tyenv, stmts, ex->Iex.ITE.iftrue),
+ flatten_Expr(tyenv, stmts, ex->Iex.ITE.iffalse))));
return IRExpr_RdTmp(t1);

case Iex_Const:
/* Lift F64i constants out onto temps so they can be CSEd
later. */
if (ex->Iex.Const.con->tag == Ico_F64i) {
- t1 = newIRTemp(tyenv, ty);
+ t1 = newIRTemp(tyenv, stmts, ty);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Const(ex->Iex.Const.con)));
return IRExpr_RdTmp(t1);
@@ -394,10 +393,12 @@
}
}

-static IRStmtVec* flatten_IRStmtVec(IRStmtVec* in, IRStmtVec* parent);
+static IRStmtVec* flatten_IRStmtVec(IRTypeEnv* tyenv, IRStmtVec* in,
+ IRStmtVec* parent);

/* Append a completely flattened form of 'st' to the end of 'stmts'. */
-static void flatten_Stmt(IRStmtVec* stmts, IRStmt* st, IRStmtVec* parent)
+static void flatten_Stmt(IRTypeEnv* tyenv, IRStmtVec* stmts, IRStmt* st,
+ IRStmtVec* parent)
{
Int i;
IRExpr *e1, *e2, *e3, *e4, *e5;
@@ -414,14 +415,14 @@
addStmtToIRStmtVec(stmts, st);
} else {
/* general case, always correct */
- e1 = flatten_Expr(stmts, st->Ist.Put.data);
+ e1 = flatten_Expr(tyenv, stmts, st->Ist.Put.data);
addStmtToIRStmtVec(stmts, IRStmt_Put(st->Ist.Put.offset, e1));
}
break;
case Ist_PutI:
puti = st->Ist.PutI.details;
- e1 = flatten_Expr(stmts, puti->ix);
- e2 = flatten_Expr(stmts, puti->data);
+ e1 = flatten_Expr(tyenv, stmts, puti->ix);
+ e2 = flatten_Expr(tyenv, stmts, puti->data);
puti2 = mkIRPutI(puti->descr, e1, puti->bias, e2);
addStmtToIRStmtVec(stmts, IRStmt_PutI(puti2));
break;
@@ -432,45 +433,45 @@
addStmtToIRStmtVec(stmts, st);
} else {
/* general case, always correct */
- e1 = flatten_Expr(stmts, st->Ist.WrTmp.data);
+ e1 = flatten_Expr(tyenv, stmts, st->Ist.WrTmp.data);
addStmtToIRStmtVec(stmts, IRStmt_WrTmp(st->Ist.WrTmp.tmp, e1));
}
break;
case Ist_Store:
- e1 = flatten_Expr(stmts, st->Ist.Store.addr);
- e2 = flatten_Expr(stmts, st->Ist.Store.data);
+ e1 = flatten_Expr(tyenv, stmts, st->Ist.Store.addr);
+ e2 = flatten_Expr(tyenv, stmts, st->Ist.Store.data);
addStmtToIRStmtVec(stmts, IRStmt_Store(st->Ist.Store.end, e1,e2));
break;
case Ist_StoreG:
sg = st->Ist.StoreG.details;
- e1 = flatten_Expr(stmts, sg->addr);
- e2 = flatten_Expr(stmts, sg->data);
- e3 = flatten_Expr(stmts, sg->guard);
+ e1 = flatten_Expr(tyenv, stmts, sg->addr);
+ e2 = flatten_Expr(tyenv, stmts, sg->data);
+ e3 = flatten_Expr(tyenv, stmts, sg->guard);
addStmtToIRStmtVec(stmts, IRStmt_StoreG(sg->end, e1, e2, e3));
break;
case Ist_LoadG:
lg = st->Ist.LoadG.details;
- e1 = flatten_Expr(stmts, lg->addr);
- e2 = flatten_Expr(stmts, lg->alt);
- e3 = flatten_Expr(stmts, lg->guard);
+ e1 = flatten_Expr(tyenv, stmts, lg->addr);
+ e2 = flatten_Expr(tyenv, stmts, lg->alt);
+ e3 = flatten_Expr(tyenv, stmts, lg->guard);
addStmtToIRStmtVec(stmts, IRStmt_LoadG(lg->end, lg->cvt, lg->dst,
e1, e2, e3));
break;
case Ist_CAS:
cas = st->Ist.CAS.details;
- e1 = flatten_Expr(stmts, cas->addr);
- e2 = cas->expdHi ? flatten_Expr(stmts, cas->expdHi) : NULL;
- e3 = flatten_Expr(stmts, cas->expdLo);
- e4 = cas->dataHi ? flatten_Expr(stmts, cas->dataHi) : NULL;
- e5 = flatten_Expr(stmts, cas->dataLo);
+ e1 = flatten_Expr(tyenv, stmts, cas->addr);
+ e2 = cas->expdHi ? flatten_Expr(tyenv, stmts, cas->expdHi) : NULL;
+ e3 = flatten_Expr(tyenv, stmts, cas->expdLo);
+ e4 = cas->dataHi ? flatten_Expr(tyenv, stmts, cas->dataHi) : NULL;
+ e5 = flatten_Expr(tyenv, stmts, cas->dataLo);
cas2 = mkIRCAS( cas->oldHi, cas->oldLo, cas->end,
e1, e2, e3, e4, e5 );
addStmtToIRStmtVec(stmts, IRStmt_CAS(cas2));
break;
case Ist_LLSC:
- e1 = flatten_Expr(stmts, st->Ist.LLSC.addr);
+ e1 = flatten_Expr(tyenv, stmts, st->Ist.LLSC.addr);
e2 = st->Ist.LLSC.storedata
- ? flatten_Expr(stmts, st->Ist.LLSC.storedata)
+ ? flatten_Expr(tyenv, stmts, st->Ist.LLSC.storedata)
: NULL;
addStmtToIRStmtVec(stmts, IRStmt_LLSC(st->Ist.LLSC.end,
st->Ist.LLSC.result, e1, e2));
@@ -481,15 +482,15 @@
*d2 = *d;
d2->args = shallowCopyIRExprVec(d2->args);
if (d2->mFx != Ifx_None) {
- d2->mAddr = flatten_Expr(stmts, d2->mAddr);
+ d2->mAddr = flatten_Expr(tyenv, stmts, d2->mAddr);
} else {
vassert(d2->mAddr == NULL);
}
- d2->guard = flatten_Expr(stmts, d2->guard);
+ d2->guard = flatten_Expr(tyenv, stmts, d2->guard);
for (i = 0; d2->args[i]; i++) {
IRExpr* arg = d2->args[i];
if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg)))
- d2->args[i] = flatten_Expr(stmts, arg);
+ d2->args[i] = flatten_Expr(tyenv, stmts, arg);
}
addStmtToIRStmtVec(stmts, IRStmt_Dirty(d2));
break;
@@ -499,22 +500,23 @@
addStmtToIRStmtVec(stmts, st);
break;
case Ist_AbiHint:
- e1 = flatten_Expr(stmts, st->Ist.AbiHint.base);
- e2 = flatten_Expr(stmts, st->Ist.AbiHint.nia);
+ e1 = flatten_Expr(tyenv, stmts, st->Ist.AbiHint.base);
+ e2 = flatten_Expr(tyenv, stmts, st->Ist.AbiHint.nia);
addStmtToIRStmtVec(stmts, IRStmt_AbiHint(e1, st->Ist.AbiHint.len, e2));
break;
case Ist_Exit:
- e1 = flatten_Expr(stmts, st->Ist.Exit.guard);
+ e1 = flatten_Expr(tyenv, stmts, st->Ist.Exit.guard);
addStmtToIRStmtVec(stmts, IRStmt_Exit(e1, st->Ist.Exit.jk,
st->Ist.Exit.dst,
st->Ist.Exit.offsIP));
break;
case Ist_IfThenElse:
- e1 = flatten_Expr(stmts, st->Ist.IfThenElse.cond);
- addStmtToIRStmtVec(stmts, IRStmt_IfThenElse(e1,
- flatten_IRStmtVec(st->Ist.IfThenElse.then_leg, parent),
- flatten_IRStmtVec(st->Ist.IfThenElse.else_leg, parent),
- st->Ist.IfThenElse.phi_nodes));
+ e1 = flatten_Expr(tyenv, stmts, st->Ist.IfThenElse.cond);
+ addStmtToIRStmtVec(
+ stmts, IRStmt_IfThenElse(e1,
+ flatten_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg, parent),
+ flatten_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg, parent),
+ st->Ist.IfThenElse.phi_nodes));
break;
default:
vex_printf("\n");
@@ -524,13 +526,15 @@
}
}

-static IRStmtVec* flatten_IRStmtVec(IRStmtVec* in, IRStmtVec* parent)
+static IRStmtVec* flatten_IRStmtVec(IRTypeEnv* tyenv, IRStmtVec* in,
+ IRStmtVec* parent)
{
IRStmtVec* out = emptyIRStmtVec();
- out->tyenv = deepCopyIRTypeEnv(in->tyenv);
out->parent = parent;
+ out->id = in->id;
+ out->def_set = deepCopyIRTempDefSet(in->def_set);
for (UInt i = 0; i < in->stmts_used; i++) {
- flatten_Stmt(out, in->stmts[i], out);
+ flatten_Stmt(tyenv, out, in->stmts[i], out);
}
return out;
}
@@ -538,9 +542,10 @@
static IRSB* flatten_BB ( IRSB* in )
{
IRSB* out = emptyIRSB();
+ out->tyenv = deepCopyIRTypeEnv(in->tyenv);
out->id_seq = in->id_seq;
- out->stmts = flatten_IRStmtVec(in->stmts, NULL);
- out->next = flatten_Expr(out->stmts, in->next);
+ out->stmts = flatten_IRStmtVec(out->tyenv, in->stmts, NULL);
+ out->next = flatten_Expr(out->tyenv, out->stmts, in->next);
out->jumpkind = in->jumpkind;
out->offsIP = in->offsIP;
return out;
@@ -623,7 +628,8 @@
}
}

-static void redundant_get_removal_IRStmtVec(IRStmtVec* stmts)
+static
+void redundant_get_removal_IRStmtVec(const IRTypeEnv* tyenv, IRStmtVec* stmts)
{
HashHW* env = newHHW();
UInt key = 0; /* keep gcc -O happy */
@@ -652,7 +658,7 @@
be to stick in a reinterpret-style cast, although that
would make maintaining flatness more difficult. */
IRExpr* valE = (IRExpr*)val;
- Bool typesOK = toBool( typeOfIRExpr(stmts, valE)
+ Bool typesOK = toBool( typeOfIRExpr(tyenv, valE)
== st->Ist.WrTmp.data->Iex.Get.ty );
if (typesOK && DEBUG_IROPT) {
vex_printf("rGET: "); ppIRExpr(get);
@@ -676,7 +682,7 @@
UInt k_lo, k_hi;
if (st->tag == Ist_Put) {
key = mk_key_GetPut( st->Ist.Put.offset,
- typeOfIRExpr(stmts, st->Ist.Put.data) );
+ typeOfIRExpr(tyenv, st->Ist.Put.data) );
} else {
vassert(st->tag == Ist_PutI);
key = mk_key_GetIPutI( st->Ist.PutI.details->descr );
@@ -714,8 +720,8 @@

if (st->tag == Ist_IfThenElse) {
/* Consider "then" and "else" legs in isolation. */
- redundant_get_removal_IRStmtVec(st->Ist.IfThenElse.then_leg);
- redundant_get_removal_IRStmtVec(st->Ist.IfThenElse.else_leg);
+ redundant_get_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg);
+ redundant_get_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg);
}

} /* for (UInt i = 0; i < stmts->stmts_used; i++) */
@@ -723,7 +729,7 @@

static void redundant_get_removal_BB(IRSB* bb)
{
- redundant_get_removal_IRStmtVec(bb->stmts);
+ redundant_get_removal_IRStmtVec(bb->tyenv, bb->stmts);
}


@@ -909,8 +915,8 @@
and loads/stores.
*/

-static void redundant_put_removal_IRStmtVec(
- IRStmtVec* stmts,
+static void redundant_put_removal_IRStmtVec(
+ IRTypeEnv* tyenv, IRStmtVec* stmts,
Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates),
VexRegisterUpdates pxControl,
HashHW* env)
@@ -960,7 +966,7 @@
case Ist_Put:
isPut = True;
key = mk_key_GetPut( st->Ist.Put.offset,
- typeOfIRExpr(stmts, st->Ist.Put.data) );
+ typeOfIRExpr(tyenv, st->Ist.Put.data) );
vassert(isIRAtom(st->Ist.Put.data));
break;
case Ist_PutI:
@@ -1003,9 +1009,9 @@

/* Consider "then" and "else" legs in isolation. They get a new env. */
if (st->tag == Ist_IfThenElse) {
- redundant_put_removal_IRStmtVec(st->Ist.IfThenElse.then_leg,
+ redundant_put_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg,
preciseMemExnsFn, pxControl, newHHW());
- redundant_put_removal_IRStmtVec(st->Ist.IfThenElse.else_leg,
+ redundant_put_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg,
preciseMemExnsFn, pxControl, newHHW());
}
}
@@ -1024,10 +1030,11 @@
writes the IP (or, whatever it claims to write. We don't
care.) */
UInt key = mk_key_GetPut(bb->offsIP,
- typeOfIRExpr(bb->stmts, bb->next));
+ typeOfIRExpr(bb->tyenv, bb->next));
addToHHW(env, (HWord)key, 0);

- redundant_put_removal_IRStmtVec(bb->stmts, preciseMemExnsFn, pxControl, env);
+ redundant_put_removal_IRStmtVec(bb->tyenv, bb->stmts, preciseMemExnsFn,
+ pxControl, env);
}


@@ -1067,60 +1074,41 @@
/* The env in this section is a structure which holds:
- A map from IRTemp to IRExpr*, that is, an array indexed by IRTemp.
Keys are IRTemp.indices. Values are IRExpr*s.
- - IRTypeEnv ID
+ - IR Type Environment
- Current IRStmtVec* which is being constructed.
- A pointer to the parent env (or NULL). */
typedef
- struct _FoldEnv {
- IRExpr** map;
- IRTyEnvID id;
- IRStmtVec* stmts;
- struct _FoldEnv* parent;
- }
- FoldEnv;
-
-/* Sets up the constant propagation and folding environment. */
-static FoldEnv* newFoldEnv(IRStmtVec* stmts_in, FoldEnv* parent_env)
+ struct _SubstEnv {
+ IRExpr** map;
+ IRTypeEnv* tyenv;
+ IRStmtVec* stmts;
+ struct _SubstEnv* parent;
+ }
+ SubstEnv;
+
+/* Sets up the substitution environment.
+ Note that the map is established fresh new for every IRStmtVec (which are
+ thus considered in isolation). */
+static SubstEnv* newSubstEnv(IRTypeEnv* tyenv, IRStmtVec* stmts_in,
+ SubstEnv* parent_env)
{
IRStmtVec* stmts_out = emptyIRStmtVec();
- stmts_out->tyenv = deepCopyIRTypeEnv(stmts_in->tyenv);
+ stmts_out->id = stmts_in->id;
stmts_out->parent = (parent_env != NULL) ? parent_env->stmts : NULL;
+ stmts_out->def_set = deepCopyIRTempDefSet(stmts_in->def_set);

- FoldEnv* env = LibVEX_Alloc_inline(sizeof(FoldEnv));
- env->id = stmts_out->tyenv->id;
- env->stmts = stmts_out;
- env->parent = parent_env;
+ SubstEnv* env = LibVEX_Alloc_inline(sizeof(SubstEnv));
+ env->tyenv = tyenv;
+ env->stmts = stmts_out;
+ env->parent = parent_env;

- UInt n_tmps = stmts_out->tyenv->types_used;
+ UInt n_tmps = tyenv->used;
env->map = LibVEX_Alloc_inline(n_tmps * sizeof(IRExpr*));
for (UInt i = 0; i < n_tmps; i++)
env->map[i] = NULL;
return env;
}

-static inline IRExpr* findIRExpr(const FoldEnv* env, IRTemp tmp)
-{
- while (env->id != tmp.id) {
- env = env->parent;
- vassert(env != NULL);
- }
- vassert(env->id == tmp.id);
-
- return env->map[tmp.index];
-}
-
-static void setIRExpr(FoldEnv* env, IRTemp tmp, IRExpr* e)
-{
- while (env->id != tmp.id) {
- env = env->parent;
- vassert(env != NULL);
- }
- vassert(env->id == tmp.id);
-
- vassert(env->map[tmp.index] == NULL);
- env->map[tmp.index] = e;
-}
-
/* Do both expressions compute the same value? The answer is generally
conservative, i.e. it will report that the expressions do not compute
the same value when in fact they do. The reason is that we do not
@@ -1138,11 +1126,11 @@
slower out of line general case. Saves a few insns. */

__attribute__((noinline))
-static Bool sameIRExprs_aux2(const FoldEnv* env, const IRExpr* e1,
+static Bool sameIRExprs_aux2(const SubstEnv* env, const IRExpr* e1,
const IRExpr* e2);

inline
-static Bool sameIRExprs_aux(const FoldEnv* env, const IRExpr* e1,
+static Bool sameIRExprs_aux(const SubstEnv* env, const IRExpr* e1,
const IRExpr* e2)
{
if (e1->tag != e2->tag) return False;
@@ -1150,7 +1138,7 @@
}

__attribute__((noinline))
-static Bool sameIRExprs_aux2(const FoldEnv* env, const IRExpr* e1,
+static Bool sameIRExprs_aux2(const SubstEnv* env, const IRExpr* e1,
const IRExpr* e2)
{
if (num_nodes_visited++ > NODE_LIMIT) return False;
@@ -1160,9 +1148,9 @@
IRTemp tmp1 = e1->Iex.RdTmp.tmp;
IRTemp tmp2 = e2->Iex.RdTmp.tmp;

- if (eqIRTemp(tmp1, tmp2)) return True;
- const IRExpr* subst1 = findIRExpr(env, tmp1);
- const IRExpr* subst2 = findIRExpr(env, tmp2);
+ if (tmp1 == tmp2) return True;
+ const IRExpr* subst1 = env->map[tmp1];
+ const IRExpr* subst2 = env->map[tmp2];
if (subst1 != NULL && subst2 != NULL) {
Bool same = sameIRExprs_aux(env, subst1, subst2);
#if STATS_IROPT
@@ -1233,7 +1221,7 @@
}

inline
-static Bool sameIRExprs(const FoldEnv* env, const IRExpr* e1, const IRExpr* e2)
+static Bool sameIRExprs(const SubstEnv* env, const IRExpr* e1, const IRExpr* e2)
{
Bool same;

@@ -1448,14 +1436,14 @@
return NULL if it can't resolve 'e' to a new expression, which will
be the case if 'e' is instead defined by an IRStmt (IRDirty or
LLSC). */
-static IRExpr* chase(FoldEnv* env, IRExpr* e)
+static IRExpr* chase(SubstEnv* env, IRExpr* e)
{
/* Why is this loop guaranteed to terminate? Because all tmps must
have definitions before use, hence a tmp cannot be bound
(directly or indirectly) to itself. */
while (e->tag == Iex_RdTmp) {
if (0) { vex_printf("chase "); ppIRExpr(e); vex_printf("\n"); }
- e = findIRExpr(env, e->Iex.RdTmp.tmp);
+ e = env->map[e->Iex.RdTmp.tmp];
if (e == NULL) break;
}
return e;
@@ -1467,10 +1455,10 @@
if (e == NULL || e->tag != Iex_RdTmp)
return e;
else
- return env[e->Iex.RdTmp.tmp.index];
+ return env[e->Iex.RdTmp.tmp];
}

-static IRExpr* fold_Expr(FoldEnv* env, IRExpr* e)
+static IRExpr* fold_Expr(SubstEnv* env, IRExpr* e)
{
Int shift;
IRExpr* e2 = e; /* e2 is the result of folding e, if possible */
@@ -2530,11 +2518,11 @@

/* Apply the subst to a simple 1-level expression -- guaranteed to be
1-level due to previous flattening pass. */
-static IRExpr* subst_Expr(FoldEnv* env, IRExpr* ex)
+static IRExpr* subst_Expr(SubstEnv* env, IRExpr* ex)
{
switch (ex->tag) {
case Iex_RdTmp: {
- IRExpr* rhs = findIRExpr(env, ex->Iex.RdTmp.tmp);
+ IRExpr* rhs = env->map[ex->Iex.RdTmp.tmp];
if (rhs != NULL) {
if (rhs->tag == Iex_RdTmp)
return rhs;
@@ -2641,13 +2629,13 @@
}
}

-static IRStmtVec* subst_and_fold_Stmts(FoldEnv* env, IRStmtVec* in);
+static IRStmtVec* subst_and_fold_Stmts(SubstEnv* env, IRStmtVec* in);

/* Apply the subst to stmt, then fold the result as much as possible.
Much simplified due to stmt being previously flattened. As a
result of this, the stmt may wind up being turned into a no-op.
*/
-static IRStmt* subst_and_fold_Stmt(FoldEnv* env, IRStmt* st)
+static IRStmt* subst_and_fold_Stmt(SubstEnv* env, IRStmt* st)
{
# if 0
vex_printf("\nsubst and fold stmt\n");
@@ -2872,17 +2860,23 @@
"unconditional\n");
}
/* TODO-JIT: Pull the only remaining leg into the current IRStmtVec.
- It is necessary to rewrite indices of all IRTemp's in scope.
- Not sure if this is possible or feasible. */
- }
-
- FoldEnv* then_env = newFoldEnv(st->Ist.IfThenElse.then_leg, env);
- IRStmtVec* then_stmts = subst_and_fold_Stmts(then_env,
- st->Ist.IfThenElse.then_leg);
-
- FoldEnv* else_env = newFoldEnv(st->Ist.IfThenElse.else_leg, env);
- IRStmtVec* else_stmts = subst_and_fold_Stmts(else_env,
- st->Ist.IfThenElse.else_leg);
+ Here is what needs to be done:
+ 1. Rewrite ID of all IRTemp's (in tyenv->ids) defined in the
+ pulled leg. These are tracked in leg's def_set.
+ 2. Insert all statements from the leg in the env->stmts_out
+ at the current position. */
+ vpanic("IfThenElse leg lifting unimplemented");
+ }
+
+ SubstEnv* then_env
+ = newSubstEnv(env->tyenv, st->Ist.IfThenElse.then_leg, env);
+ IRStmtVec* then_stmts
+ = subst_and_fold_Stmts(then_env, st->Ist.IfThenElse.then_leg);
+
+ SubstEnv* else_env
+ = newSubstEnv(env->tyenv, st->Ist.IfThenElse.else_leg, env);
+ IRStmtVec* else_stmts
+ = subst_and_fold_Stmts(else_env, st->Ist.IfThenElse.else_leg);

return IRStmt_IfThenElse(fcond, then_stmts, else_stmts,
st->Ist.IfThenElse.phi_nodes);
@@ -2894,8 +2888,8 @@
}
}

-/* Is to be called with already created FoldEnv as per newFoldEnv(). */
-static IRStmtVec* subst_and_fold_Stmts(FoldEnv* env, IRStmtVec* in)
+/* Is to be called with already created SubstEnv as per newSubstEnv(). */
+static IRStmtVec* subst_and_fold_Stmts(SubstEnv* env, IRStmtVec* in)
{
/* Keep track of IRStmt_LoadGs that we need to revisit after
processing all the other statements. */
@@ -2932,8 +2926,9 @@
running environment. This is for the benefit of copy
propagation and to allow sameIRExpr look through
IRTemps. */
- case Ist_WrTmp: {
- setIRExpr(env, st2->Ist.WrTmp.tmp, st2->Ist.WrTmp.data);
+ case Ist_WrTmp:
+ vassert(env->map[st2->Ist.WrTmp.tmp] == NULL);
+ env->map[st2->Ist.WrTmp.tmp] = st2->Ist.WrTmp.data;

/* 't1 = t2' -- don't add to BB; will be optimized out */
if (st2->Ist.WrTmp.data->tag == Iex_RdTmp)
@@ -2949,7 +2944,6 @@
}
/* else add it to the output, as normal */
break;
- }

case Ist_LoadG: {
IRLoadG* lg = st2->Ist.LoadG.details;
@@ -3016,7 +3010,7 @@
}
/* Replace the placeholder NoOp by the required unconditional
load. */
- IRTemp tLoaded = newIRTemp(out->tyenv, cvtArg);
+ IRTemp tLoaded = newIRTemp(env->tyenv, out, cvtArg);
out->stmts[ix]
= IRStmt_WrTmp(tLoaded,
IRExpr_Load(lg->end, cvtArg, lg->addr));
@@ -3034,7 +3028,7 @@

IRSB* cprop_BB ( IRSB* in )
{
- FoldEnv* env = newFoldEnv(in->stmts, NULL);
+ SubstEnv* env = newSubstEnv(in->tyenv, in->stmts, NULL);
IRSB* out = emptyIRSB();
out->stmts = subst_and_fold_Stmts(env, in->stmts);
out->id_seq = in->id_seq;
@@ -3066,7 +3060,7 @@
inline
static void addUses_Temp ( Bool* set, IRTemp tmp )
{
- set[tmp.index] = True;
+ set[tmp] = True;
}

static void addUses_Expr ( Bool* set, IRExpr* e )
@@ -3119,15 +3113,6 @@
}
}

-static Bool* new_deadcode_set(const IRTypeEnv* tyenv)
-{
- UInt n_tmps = tyenv->types_used;
- Bool* set = LibVEX_Alloc_inline(n_tmps * sizeof(Bool));
- for (UInt i = 0; i < n_tmps; i++)
- set[i] = False;
- return set;
-}
-
static void do_deadcode_IRStmtVec(Bool* set, IRStmtVec* stmts,
Int* i_unconditional_exit);

@@ -3204,20 +3189,19 @@
case Ist_IfThenElse: {
addUses_Expr(set, st->Ist.IfThenElse.cond);

- Bool* then_set = new_deadcode_set(st->Ist.IfThenElse.then_leg->tyenv);
- Bool* else_set = new_deadcode_set(st->Ist.IfThenElse.then_leg->tyenv);
-
IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
const IRPhi* phi = phi_nodes->phis[i];
- addUses_Temp(then_set, phi->srcThen);
- addUses_Temp(else_set, phi->srcElse);
+ addUses_Temp(set, phi->srcThen);
+ addUses_Temp(set, phi->srcElse);
}

Int i_unconditional_exit; // TODO-JIT: unused at the moment
- do_deadcode_IRStmtVec(then_set, st->Ist.IfThenElse.then_leg,
+ /* Consider both legs simultaneously. If either of them reports an
+ IRTemp in use, then it won't be eliminated. */
+ do_deadcode_IRStmtVec(set, st->Ist.IfThenElse.then_leg,
&i_unconditional_exit);
- do_deadcode_IRStmtVec(else_set, st->Ist.IfThenElse.else_leg,
+ do_deadcode_IRStmtVec(set, st->Ist.IfThenElse.else_leg,
&i_unconditional_exit);
return;
}
@@ -3271,11 +3255,9 @@
if (st->tag == Ist_NoOp)
continue;
/* take note of any unconditional exits */
- if (st->tag == Ist_Exit
- && isOneU1(st->Ist.Exit.guard))
+ if (st->tag == Ist_Exit && isOneU1(st->Ist.Exit.guard))
*i_unconditional_exit = i;
- if (st->tag == Ist_WrTmp
- && set[st->Ist.WrTmp.tmp.index] == False) {
+ if (st->tag == Ist_WrTmp && set[st->Ist.WrTmp.tmp] == False) {
/* it's an IRTemp which never got used. Delete it. */
if (DEBUG_IROPT) {
vex_printf("DEAD: ");
@@ -3301,8 +3283,11 @@

void do_deadcode_BB(IRSB* bb)
{
- Bool* set = new_deadcode_set(bb->stmts->tyenv);
Int i_unconditional_exit;
+ UInt n_tmps = bb->tyenv->used;
+ Bool* set = LibVEX_Alloc_inline(n_tmps * sizeof(Bool));
+ for (UInt i = 0; i < n_tmps; i++)
+ set[i] = False;

/* start off by recording IRTemp uses in the next field. */
addUses_Expr(set, bb->next);
@@ -3531,7 +3516,7 @@
case TCc:
return eqIRConst(tc1->u.con, tc2->u.con);
case TCt:
- return eqIRTemp(tc1->u.tmp, tc2->u.tmp);
+ return tc1->u.tmp == tc2->u.tmp;
default:
vpanic("eqTmpOrConst");
}
@@ -3686,43 +3671,43 @@
case Ut:
return toBool(
a1->u.Ut.op == a2->u.Ut.op
- && eqIRTemp(a1->u.Ut.arg, a2->u.Ut.arg));
+ && a1->u.Ut.arg == a2->u.Ut.arg);
case Btt:
return toBool(
a1->u.Btt.op == a2->u.Btt.op
- && eqIRTemp(a1->u.Btt.arg1, a2->u.Btt.arg1)
- && eqIRTemp(a1->u.Btt.arg2, a2->u.Btt.arg2));
+ && a1->u.Btt.arg1 == a2->u.Btt.arg1
+ && a1->u.Btt.arg2 == a2->u.Btt.arg2);
case Btc:
return toBool(
a1->u.Btc.op == a2->u.Btc.op
- && eqIRTemp(a1->u.Btc.arg1, a2->u.Btc.arg1)
+ && a1->u.Btc.arg1 == a2->u.Btc.arg1
&& eqIRConst(&a1->u.Btc.con2, &a2->u.Btc.con2));
case Bct:
return toBool(
a1->u.Bct.op == a2->u.Bct.op
- && eqIRTemp(a1->u.Bct.arg2, a2->u.Bct.arg2)
+ && a1->u.Bct.arg2 == a2->u.Bct.arg2
&& eqIRConst(&a1->u.Bct.con1, &a2->u.Bct.con1));
case Cf64i:
return toBool(a1->u.Cf64i.f64i == a2->u.Cf64i.f64i);
case Ittt:
- return toBool(eqIRTemp(a1->u.Ittt.co, a2->u.Ittt.co)
- && eqIRTemp(a1->u.Ittt.e1, a2->u.Ittt.e1)
- && eqIRTemp(a1->u.Ittt.e0, a2->u.Ittt.e0));
+ return toBool(a1->u.Ittt.co == a2->u.Ittt.co
+ && a1->u.Ittt.e1 == a2->u.Ittt.e1
+ && a1->u.Ittt.e0 == a2->u.Ittt.e0);
case Ittc:
- return toBool(eqIRTemp(a1->u.Ittc.co, a2->u.Ittc.co)
- && eqIRTemp(a1->u.Ittc.e1, a2->u.Ittc.e1)
+ return toBool(a1->u.Ittc.co == a2->u.Ittc.co
+ && a1->u.Ittc.e1 == a2->u.Ittc.e1
&& eqIRConst(&a1->u.Ittc.con0, &a2->u.Ittc.con0));
case Itct:
- return toBool(eqIRTemp(a1->u.Itct.co, a2->u.Itct.co)
+ return toBool(a1->u.Itct.co == a2->u.Itct.co
&& eqIRConst(&a1->u.Itct.con1, &a2->u.Itct.con1)
- && eqIRTemp(a1->u.Itct.e0, a2->u.Itct.e0));
+ && a1->u.Itct.e0 == a2->u.Itct.e0);
case Itcc:
- return toBool(eqIRTemp(a1->u.Itcc.co, a2->u.Itcc.co)
+ return toBool(a1->u.Itcc.co == a2->u.Itcc.co
&& eqIRConst(&a1->u.Itcc.con1, &a2->u.Itcc.con1)
&& eqIRConst(&a1->u.Itcc.con0, &a2->u.Itcc.con0));
case GetIt:
return toBool(eqIRRegArray(a1->u.GetIt.descr, a2->u.GetIt.descr)
- && eqIRTemp(a1->u.GetIt.ix, a2->u.GetIt.ix)
+ && a1->u.GetIt.ix == a2->u.GetIt.ix
&& a1->u.GetIt.bias == a2->u.GetIt.bias);
case CCall: {
Int i, n;
@@ -3830,11 +3815,10 @@
{
HWord res;
/* env :: IRTemp -> IRTemp */
- if (lookupHHW(env, &res, (HWord) tmp.index)) {
- return mkIRTemp(tmp.id, res);
- } else {
+ if (lookupHHW( env, &res, (HWord)tmp ))
+ return (IRTemp)res;
+ else
return tmp;
- }
}

inline
@@ -4042,7 +4026,8 @@
return NULL;
}

-static Bool do_cse_IRStmtVec(IRStmtVec* stmts, Bool allowLoadsToBeCSEd)
+static Bool do_cse_IRStmtVec(const IRTypeEnv* tyenv, IRStmtVec* stmts,
+ Bool allowLoadsToBeCSEd)
{
Int j, paranoia;
AvailExpr* eprime;
@@ -4092,9 +4077,9 @@
case Ist_WrTmp: case Ist_Exit: case Ist_LoadG:
paranoia = 0; break;
case Ist_IfThenElse:
- anyDone |= do_cse_IRStmtVec(st->Ist.IfThenElse.then_leg,
+ anyDone |= do_cse_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg,
allowLoadsToBeCSEd);
- anyDone |= do_cse_IRStmtVec(st->Ist.IfThenElse.else_leg,
+ anyDone |= do_cse_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg,
allowLoadsToBeCSEd);
paranoia = 0; break;
default:
@@ -4126,7 +4111,7 @@
ae->u.GetIt.descr,
IRExpr_RdTmp(ae->u.GetIt.ix),
st->Ist.Put.offset,
- typeOfIRExpr(stmts, st->Ist.Put.data)
+ typeOfIRExpr(tyenv, st->Ist.Put.data)
) != NoAlias)
invalidate = True;
}
@@ -4180,16 +4165,16 @@
/* A binding E' -> q was found. Replace stmt by "t = q" and
note the t->q binding in tenv. */
/* (this is the core of the CSE action) */
- IRTemp q = mkIRTemp(stmts->tyenv->id, (IRTyEnvIndex) aenv->val[j]);
+ IRTemp q = (IRTemp) aenv->val[j];
stmts->stmts[i] = IRStmt_WrTmp(t, IRExpr_RdTmp(q));
- addToHHW(tenv, (HWord) t.index, (HWord) q.index);
+ addToHHW(tenv, (HWord) t, (HWord) q);
anyDone = True;
} else {
/* No binding was found, so instead we add E' -> t to our
collection of available expressions, replace this stmt
with "t = E'", and move on. */
stmts->stmts[i] = IRStmt_WrTmp(t, availExpr_to_IRExpr(eprime));
- addToHHW(aenv, (HWord) eprime, (HWord) t.index);
+ addToHHW(aenv, (HWord) eprime, (HWord) t);
}
}
return anyDone;
@@ -4207,7 +4192,7 @@

if (0) { ppIRSB(bb); vex_printf("\n\n"); }

- Bool anyDone = do_cse_IRStmtVec(bb->stmts, allowLoadsToBeCSEd);
+ Bool anyDone = do_cse_IRStmtVec(bb->tyenv, bb->stmts, allowLoadsToBeCSEd);

/*
ppIRSB(bb);
@@ -4268,7 +4253,7 @@
IRStmt* st = stmts->stmts[j];
if (st->tag != Ist_WrTmp)
continue;
- if (!eqIRTemp(st->Ist.WrTmp.tmp, var))
+ if (st->Ist.WrTmp.tmp != var)
continue;
e = st->Ist.WrTmp.data;
if (!isAdd32OrSub32(e, &vv, &ii))
@@ -4281,7 +4266,7 @@
vpanic("collapseChain");

/* so, did we find anything interesting? */
- if (eqIRTemp(var, tmp))
+ if (var == tmp)
return False; /* no .. */

*tmp2 = var;
@@ -4409,7 +4394,7 @@
that the PutI writes. This is the core of PutI-GetI forwarding. */

static
-IRExpr* findPutI(IRStmtVec* stmts, Int startHere,
+IRExpr* findPutI(const IRTypeEnv* tyenv, IRStmtVec* stmts, Int startHere,
IRRegArray* descrG, IRExpr* ixG, Int biasG)
{
GSAliasing relation;
@@ -4439,7 +4424,7 @@
= getAliasingRelation_IC(
descrG, ixG,
st->Ist.Put.offset,
- typeOfIRExpr(stmts, st->Ist.Put.data) );
+ typeOfIRExpr(tyenv, st->Ist.Put.data) );

if (relation == NoAlias) {
/* we're OK; keep going */
@@ -4526,11 +4511,9 @@
/* Assuming pi is a PutI stmt, is s2 a Get/GetI/Put/PutI which might
overlap it? Safe answer: True. Note, we could do a lot better
than this if needed. */
-
static
-Bool guestAccessWhichMightOverlapPutI (
- IRStmtVec* stmts, IRStmt* pi, IRStmt* s2
- )
+Bool guestAccessWhichMightOverlapPutI(const IRTypeEnv* tyenv, IRStmtVec* stmts,
+ IRStmt* pi, IRStmt* s2)
{
GSAliasing relation;
UInt minoffP, maxoffP;
@@ -4571,7 +4554,7 @@
= getAliasingRelation_IC(
p1->descr, p1->ix,
s2->Ist.Put.offset,
- typeOfIRExpr(stmts, s2->Ist.Put.data)
+ typeOfIRExpr(tyenv, s2->Ist.Put.data)
);
goto have_relation;

@@ -4635,7 +4618,7 @@
bb is modified in-place. */

static
-void do_redundant_GetI_elimination(IRStmtVec* stmts)
+void do_redundant_GetI_elimination(const IRTypeEnv* tyenv, IRStmtVec* stmts)
{
for (Int i = stmts->stmts_used - 1; i >= 0; i--) {
IRStmt* st = stmts->stmts[i];
@@ -4645,14 +4628,14 @@
if (st->tag == Ist_WrTmp
&& st->Ist.WrTmp.data->tag == Iex_GetI
&& st->Ist.WrTmp.data->Iex.GetI.ix->tag == Iex_RdTmp) {
- IRRegArray* descr = st->Ist.WrTmp.data->Iex.GetI.descr;
- IRExpr* ix = st->Ist.WrTmp.data->Iex.GetI.ix;
- Int bias = st->Ist.WrTmp.data->Iex.GetI.bias;
- IRExpr* replacement = findPutI(stmts, i - 1, descr, ix, bias);
+ IRRegArray* descr = st->Ist.WrTmp.data->Iex.GetI.descr;
+ IRExpr* ix = st->Ist.WrTmp.data->Iex.GetI.ix;
+ Int bias = st->Ist.WrTmp.data->Iex.GetI.bias;
+ IRExpr* replacement = findPutI(tyenv, stmts, i - 1, descr, ix, bias);
if (replacement
&& isIRAtom(replacement)
/* Make sure we're doing a type-safe transformation! */
- && typeOfIRExpr(stmts, replacement) == descr->elemTy) {
+ && typeOfIRExpr(tyenv, replacement) == descr->elemTy) {
if (DEBUG_IROPT) {
vex_printf("rGI: ");
ppIRExpr(st->Ist.WrTmp.data);
@@ -4665,8 +4648,8 @@
}

if (st->tag == Ist_IfThenElse) {
- do_redundant_GetI_elimination(st->Ist.IfThenElse.then_leg);
- do_redundant_GetI_elimination(st->Ist.IfThenElse.else_leg);
+ do_redundant_GetI_elimination(tyenv, st->Ist.IfThenElse.then_leg);
+ do_redundant_GetI_elimination(tyenv, st->Ist.IfThenElse.else_leg);
}
}
}
@@ -4675,8 +4658,9 @@
/* Remove redundant PutIs, to the extent which they can be detected.
bb is modified in-place. */

-static void do_redundant_PutI_elimination(IRStmtVec* stmts,
- VexRegisterUpdates pxControl)
+static
+void do_redundant_PutI_elimination(const IRTypeEnv* tyenv, IRStmtVec* stmts,
+ VexRegisterUpdates pxControl)
{
vassert(pxControl < VexRegUpdAllregsAtEachInsn);

@@ -4684,8 +4668,10 @@
IRStmt* st = stmts->stmts[i];

if (st->tag == Ist_IfThenElse) {
- do_redundant_PutI_elimination(st->Ist.IfThenElse.then_leg, pxControl);
- do_redundant_PutI_elimination(st->Ist.IfThenElse.else_leg, pxControl);
+ do_redundant_PutI_elimination(tyenv, st->Ist.IfThenElse.then_leg,
+ pxControl);
+ do_redundant_PutI_elimination(tyenv, st->Ist.IfThenElse.else_leg,
+ pxControl);
}

if (st->tag != Ist_PutI)
@@ -4719,7 +4705,7 @@
if (st->tag == Ist_Dirty)
/* give up; could do better here */
break;
- if (guestAccessWhichMightOverlapPutI(stmts, st, stj))
+ if (guestAccessWhichMightOverlapPutI(tyenv, stmts, st, stj))
/* give up */
break;
}
@@ -4740,60 +4726,51 @@
/*--- Loop unrolling ---*/
/*---------------------------------------------------------------*/

-/* Adjust IRTemp index (name) by delta but only if its 'id' is equal
- to the passed 'id'. */
-static void deltaIRTemp(IRTemp* tmp, Int delta, IRTyEnvID id)
-{
- if (tmp->id == id) {
- tmp->index += delta;
- }
-}
+/* Adjust all tmp values (names) in e by delta. e is destructively
+ modified. */

-/* Adjust all tmp indices (names) in e by delta. Only temporaries
- with id equal to passed 'id' are adjusted.
- e is destructively modified. */
-static void deltaIRExpr(IRExpr* e, Int delta, IRTyEnvID id)
+static void deltaIRExpr ( IRExpr* e, Int delta )
{
Int i;
switch (e->tag) {
case Iex_RdTmp:
- deltaIRTemp(&e->Iex.RdTmp.tmp, delta, id);
+ e->Iex.RdTmp.tmp += delta;
break;
case Iex_Get:
case Iex_Const:
break;
case Iex_GetI:
- deltaIRExpr(e->Iex.GetI.ix, delta, id);
+ deltaIRExpr(e->Iex.GetI.ix, delta);
break;
case Iex_Qop:
- deltaIRExpr(e->Iex.Qop.details->arg1, delta, id);
- deltaIRExpr(e->Iex.Qop.details->arg2, delta, id);
- deltaIRExpr(e->Iex.Qop.details->arg3, delta, id);
- deltaIRExpr(e->Iex.Qop.details->arg4, delta, id);
+ deltaIRExpr(e->Iex.Qop.details->arg1, delta);
+ deltaIRExpr(e->Iex.Qop.details->arg2, delta);
+ deltaIRExpr(e->Iex.Qop.details->arg3, delta);
+ deltaIRExpr(e->Iex.Qop.details->arg4, delta);
break;
case Iex_Triop:
- deltaIRExpr(e->Iex.Triop.details->arg1, delta, id);
- deltaIRExpr(e->Iex.Triop.details->arg2, delta, id);
- deltaIRExpr(e->Iex.Triop.details->arg3, delta, id);
+ deltaIRExpr(e->Iex.Triop.details->arg1, delta);
+ deltaIRExpr(e->Iex.Triop.details->arg2, delta);
+ deltaIRExpr(e->Iex.Triop.details->arg3, delta);
break;
case Iex_Binop:
- deltaIRExpr(e->Iex.Binop.arg1, delta, id);
- deltaIRExpr(e->Iex.Binop.arg2, delta, id);
+ deltaIRExpr(e->Iex.Binop.arg1, delta);
+ deltaIRExpr(e->Iex.Binop.arg2, delta);
break;
case Iex_Unop:
- deltaIRExpr(e->Iex.Unop.arg, delta, id);
+ deltaIRExpr(e->Iex.Unop.arg, delta);
break;
case Iex_Load:
- deltaIRExpr(e->Iex.Load.addr, delta, id);
+ deltaIRExpr(e->Iex.Load.addr, delta);
break;
case Iex_CCall:
for (i = 0; e->Iex.CCall.args[i]; i++)
- deltaIRExpr(e->Iex.CCall.args[i], delta, id);
+ deltaIRExpr(e->Iex.CCall.args[i], delta);
break;
case Iex_ITE:
- deltaIRExpr(e->Iex.ITE.cond, delta, id);
- deltaIRExpr(e->Iex.ITE.iftrue, delta, id);
- deltaIRExpr(e->Iex.ITE.iffalse, delta, id);
+ deltaIRExpr(e->Iex.ITE.cond, delta);
+ deltaIRExpr(e->Iex.ITE.iftrue, delta);
+ deltaIRExpr(e->Iex.ITE.iffalse, delta);
break;
default:
vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
@@ -4801,12 +4778,23 @@
}
}

-static void deltaIRStmtVec(IRStmtVec* stmts, Int delta, IRTyEnvID id);
+static void deltaIRTemp(IRTypeEnv* tyenv, IRStmtVec* stmts, IRTemp *tmp,
+ UInt delta)
+{
+ *tmp += delta;

-/* Adjust all tmp indices (names) in 'st' by delta. Only temporaries
- with id equal to passed 'id' are adjusted.
- st is destructively modified. */
-static void deltaIRStmt(IRStmt* st, Int delta, IRTyEnvID id)
+ /* Adjust IRTemp's ID and also def_set of the current IRStmtVec. */
+ tyenv->ids[*tmp] = stmts->id;
+ setIRTempDefined(stmts->def_set, *tmp);
+}
+
+static void deltaIRStmtVec(IRTypeEnv* tyenv, IRStmtVec* stmts,
+ UInt delta_tmp, UInt delta_id, IRStmtVec* parent);
+
+/* Adjust all tmp values (names) in st by delta_tmp. st is destructively
+ modified. */
+static void deltaIRStmt(IRTypeEnv* tyenv, IRStmtVec* stmts, IRStmt* st,
+ UInt delta_tmp, UInt delta_id)
{
IRDirty* d;
switch (st->tag) {
@@ -4815,85 +4803,87 @@
case Ist_MBE:
break;
case Ist_AbiHint:
- deltaIRExpr(st->Ist.AbiHint.base, delta, id);
- deltaIRExpr(st->Ist.AbiHint.nia, delta, id);
+ deltaIRExpr(st->Ist.AbiHint.base, delta_tmp);
+ deltaIRExpr(st->Ist.AbiHint.nia, delta_tmp);
break;
case Ist_Put:
- deltaIRExpr(st->Ist.Put.data, delta, id);
+ deltaIRExpr(st->Ist.Put.data, delta_tmp);
break;
case Ist_PutI:
- deltaIRExpr(st->Ist.PutI.details->ix, delta, id);
- deltaIRExpr(st->Ist.PutI.details->data, delta, id);
+ deltaIRExpr(st->Ist.PutI.details->ix, delta_tmp);
+ deltaIRExpr(st->Ist.PutI.details->data, delta_tmp);
break;
- case Ist_WrTmp:
- deltaIRTemp(&st->Ist.WrTmp.tmp, delta, id);
- deltaIRExpr(st->Ist.WrTmp.data, delta, id);
+ case Ist_WrTmp:
+ deltaIRTemp(tyenv, stmts, &st->Ist.WrTmp.tmp, delta_tmp);
+ deltaIRExpr(st->Ist.WrTmp.data, delta_tmp);
break;
case Ist_Exit:
- deltaIRExpr(st->Ist.Exit.guard, delta, id);
+ deltaIRExpr(st->Ist.Exit.guard, delta_tmp);
break;
case Ist_Store:
- deltaIRExpr(st->Ist.Store.addr, delta, id);
- deltaIRExpr(st->Ist.Store.data, delta, id);
+ deltaIRExpr(st->Ist.Store.addr, delta_tmp);
+ deltaIRExpr(st->Ist.Store.data, delta_tmp);
break;
case Ist_StoreG: {
IRStoreG* sg = st->Ist.StoreG.details;
- deltaIRExpr(sg->addr, delta, id);
- deltaIRExpr(sg->data, delta, id);
- deltaIRExpr(sg->guard, delta, id);
+ deltaIRExpr(sg->addr, delta_tmp);
+ deltaIRExpr(sg->data, delta_tmp);
+ deltaIRExpr(sg->guard, delta_tmp);
break;
}
case Ist_LoadG: {
IRLoadG* lg = st->Ist.LoadG.details;
- deltaIRTemp(&lg->dst, delta, id);
- deltaIRExpr(lg->addr, delta, id);
- deltaIRExpr(lg->alt, delta, id);
- deltaIRExpr(lg->guard, delta, id);
+ deltaIRTemp(tyenv, stmts, &lg->dst, delta_tmp);
+ deltaIRExpr(lg->addr, delta_tmp);
+ deltaIRExpr(lg->alt, delta_tmp);
+ deltaIRExpr(lg->guard, delta_tmp);
break;
}
case Ist_CAS:
- if (!isIRTempInvalid(st->Ist.CAS.details->oldHi)) {
- deltaIRTemp(&st->Ist.CAS.details->oldHi, delta, id);
- }
- deltaIRTemp(&st->Ist.CAS.details->oldLo, delta, id);
- deltaIRExpr(st->Ist.CAS.details->addr, delta, id);
+ if (st->Ist.CAS.details->oldHi != IRTemp_INVALID)
+ deltaIRTemp(tyenv, stmts, &st->Ist.CAS.details->oldHi, delta_tmp);
+ deltaIRTemp(tyenv, stmts, &st->Ist.CAS.details->oldLo, delta_tmp);
+ deltaIRExpr(st->Ist.CAS.details->addr, delta_tmp);
if (st->Ist.CAS.details->expdHi)
- deltaIRExpr(st->Ist.CAS.details->expdHi, delta, id);
- deltaIRExpr(st->Ist.CAS.details->expdLo, delta, id);
+ deltaIRExpr(st->Ist.CAS.details->expdHi, delta_tmp);
+ deltaIRExpr(st->Ist.CAS.details->expdLo, delta_tmp);
if (st->Ist.CAS.details->dataHi)
- deltaIRExpr(st->Ist.CAS.details->dataHi, delta, id);
- deltaIRExpr(st->Ist.CAS.details->dataLo, delta, id);
+ deltaIRExpr(st->Ist.CAS.details->dataHi, delta_tmp);
+ deltaIRExpr(st->Ist.CAS.details->dataLo, delta_tmp);
break;
case Ist_LLSC:
- deltaIRTemp(&st->Ist.LLSC.result, delta, id);
- deltaIRExpr(st->Ist.LLSC.addr, delta, id);
+ deltaIRTemp(tyenv, stmts, &st->Ist.LLSC.result, delta_tmp);
+ deltaIRExpr(st->Ist.LLSC.addr, delta_tmp);
if (st->Ist.LLSC.storedata)
- deltaIRExpr(st->Ist.LLSC.storedata, delta, id);
+ deltaIRExpr(st->Ist.LLSC.storedata, delta_tmp);
break;
case Ist_Dirty:
d = st->Ist.Dirty.details;
- deltaIRExpr(d->guard, delta, id);
+ deltaIRExpr(d->guard, delta_tmp);
for (UInt i = 0; d->args[i]; i++) {
IRExpr* arg = d->args[i];
if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg)))
- deltaIRExpr(arg, delta, id);
+ deltaIRExpr(arg, delta_tmp);
}
- if (!isIRTempInvalid(d->tmp))
- deltaIRTemp(&d->tmp, delta, id);
+ if (d->tmp != IRTemp_INVALID)
+ deltaIRTemp(tyenv, stmts, &d->tmp, delta_tmp);
if (d->mAddr)
- deltaIRExpr(d->mAddr, delta, id);
+ deltaIRExpr(d->mAddr, delta_tmp);
break;
case Ist_IfThenElse: {
- deltaIRExpr(st->Ist.IfThenElse.cond, delta, id);
- /* Traverse "then" and "else" legs but change only IRTemp's with
- parent id. After all, loop unrolling is only about the main
- IRStmtVec. */
- deltaIRStmtVec(st->Ist.IfThenElse.then_leg, delta, id);
- deltaIRStmtVec(st->Ist.IfThenElse.else_leg, delta, id);
+ deltaIRExpr(st->Ist.IfThenElse.cond, delta_tmp);
+ /* Traverse "then" and "else" legs. Also nested IRStmtVec's need to
+ be unrolled otherwise the main IRStmtVec will break horribly. */
+ deltaIRStmtVec(tyenv, st->Ist.IfThenElse.then_leg, delta_tmp,
+ delta_id, stmts);
+ deltaIRStmtVec(tyenv, st->Ist.IfThenElse.else_leg, delta_tmp,
+ delta_id, stmts);

IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- deltaIRTemp(&phi_nodes->phis[i]->dst, delta, id);
+ phi_nodes->phis[i]->dst += delta_tmp;
+ phi_nodes->phis[i]->srcThen += delta_tmp;
+ phi_nodes->phis[i]->srcElse += delta_tmp;
}
break;
}
@@ -4903,10 +4893,18 @@
}
}

-static void deltaIRStmtVec(IRStmtVec* stmts, Int delta, IRTyEnvID id)
-{
+/* Called only for nested IRStmtVec's. */
+static void deltaIRStmtVec(IRTypeEnv* tyenv, IRStmtVec* stmts,
+ UInt delta_tmp, UInt delta_id, IRStmtVec* parent)
+{
+ /* Clear the def_set now. It still points to original IRTemp's however
+ we are now moving to another set of IRTemp's shifted by 'delta'. */
+ clearIRTempDefSet(stmts->def_set);
+ stmts->id += delta_id;
+ stmts->parent = parent;
+
for (UInt i = 0; i < stmts->stmts_used; i++) {
- deltaIRStmt(stmts->stmts[i], delta, id);
+ deltaIRStmt(tyenv, stmts, stmts->stmts[i], delta_tmp, delta_id);
}
}

@@ -4968,7 +4966,7 @@

static IRSB* maybe_loop_unroll_BB ( IRSB* bb0, Addr my_addr )
{
- Int i, j, jmax, n_vars;
+ Int i, j, jmax;
Bool xxx_known;
Addr64 xxx_value, yyy_value;
IRExpr* udst;
@@ -5110,19 +5108,32 @@

jmax = unroll_factor==8 ? 3 : (unroll_factor==4 ? 2 : 1);
for (j = 1; j <= jmax; j++) {
-
- n_vars = bb1->stmts->tyenv->types_used;
+ UInt n_vars = bb1->tyenv->used;
+ UInt n_ids = bb1->id_seq;

bb2 = deepCopyIRSB(bb1);
- for (i = 0; i < n_vars; i++)
- (void)newIRTemp(bb1->stmts->tyenv, bb2->stmts->tyenv->types[i]);
+
+ /* This is tricky. We need to copy types and increase IDs. This can be
+ achieved here. But we also need to keep track in which IRStmtVec each

[... 246 lines stripped ...]

Loading...