You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
1
(3) |
2
(2) |
3
|
4
(1) |
|
5
|
6
(2) |
7
|
8
(1) |
9
|
10
(2) |
11
(8) |
|
12
(2) |
13
(9) |
14
(2) |
15
(6) |
16
(5) |
17
(3) |
18
|
|
19
|
20
(1) |
21
(1) |
22
(6) |
23
(8) |
24
(2) |
25
(1) |
|
26
|
27
(3) |
28
(8) |
29
(17) |
30
(6) |
31
(3) |
|
|
From: <sv...@va...> - 2017-03-13 23:34:58
|
Author: iraisr
Date: Mon Mar 13 23:34:51 2017
New Revision: 16271
Log:
Fix initialization of MCEnv in Memcheck.
At this point, also all tests under 'memcheck' pass as in trunk.
Modified:
branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
Modified: branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c (original)
+++ branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c Mon Mar 13 23:34:51 2017
@@ -332,7 +332,7 @@
{
IRStmtVec* stmts_out = emptyIRStmtVec();
stmts_out->tyenv = deepCopyIRTypeEnv(stmts_in->tyenv);
- stmts_out->parent = parent_mce->stmts;
+ stmts_out->parent = (parent_mce != NULL) ? parent_mce->stmts : NULL;
mce->stmts = stmts_out;
mce->tyenv = stmts_out->tyenv;
@@ -6670,6 +6670,7 @@
MCEnv mce;
initMCEnv(sb_in->stmts, &mce, NULL);
mce.settings = &settings;
+ sb_out->stmts = mce.stmts;
tl_assert(isFlatIRSB(sb_in));
|
|
From: <sv...@va...> - 2017-03-13 23:12:34
|
Author: iraisr
Date: Mon Mar 13 23:12:27 2017
New Revision: 3318
Log:
Fix uninitialised IRTemp.id in CSE pass.
Fix backwards loops in ir_opt.c.
At this point, all tests under 'none' pass as in trunk.
Modified:
branches/VEX_JIT_HACKS/priv/ir_opt.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h
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 13 23:12:27 2017
@@ -916,7 +916,7 @@
HashHW* env)
{
/* And now scan backwards through the statements. */
- for (UInt i = stmts->stmts_used - 1; i >= 0; i--) {
+ for (Int i = stmts->stmts_used - 1; i >= 0; i--) {
IRStmt* st = stmts->stmts[i];
Bool isPut;
UInt key;
@@ -3226,7 +3226,7 @@
*i_unconditional_exit = -1;
/* Work backwards through the stmts */
- for (UInt i = stmts->stmts_used - 1; i >= 0; i--) {
+ for (Int i = stmts->stmts_used - 1; i >= 0; i--) {
IRStmt* st = stmts->stmts[i];
if (st->tag == Ist_NoOp)
continue;
@@ -3301,7 +3301,7 @@
{
IRExpr* ex;
- for (UInt i = stmts->stmts_used - 1; i >= 0; i--) {
+ for (Int i = stmts->stmts_used - 1; i >= 0; i--) {
IRStmt* st = stmts->stmts[i];
if (st->tag == Ist_IfThenElse) {
@@ -3790,7 +3790,7 @@
{
HWord res;
/* env :: IRTemp -> IRTemp */
- if (lookupHHW(env, &res, (HWord)tmp.index)) {
+ if (lookupHHW(env, &res, (HWord) tmp.index)) {
return mkIRTemp(tmp.id, res);
} else {
return tmp;
@@ -4005,7 +4005,6 @@
static Bool do_cse_IRStmtVec(IRStmtVec* stmts, Bool allowLoadsToBeCSEd)
{
Int j, paranoia;
- IRTemp t, q;
AvailExpr* eprime;
AvailExpr* ae;
Bool invalidate;
@@ -4059,7 +4058,7 @@
allowLoadsToBeCSEd);
paranoia = 0; break;
default:
- vpanic("do_cse_BB(1)");
+ vpanic("do_cse_IRStmtVec(1)");
}
if (paranoia > 0) {
@@ -4105,7 +4104,7 @@
invalidate = True;
}
else
- vpanic("do_cse_BB(2)");
+ vpanic("do_cse_IRStmtVec(2)");
}
if (invalidate) {
@@ -4121,7 +4120,7 @@
if (st->tag != Ist_WrTmp)
continue;
- t = st->Ist.WrTmp.tmp;
+ IRTemp t = st->Ist.WrTmp.tmp;
eprime = irExpr_to_AvailExpr(st->Ist.WrTmp.data, allowLoadsToBeCSEd);
/* ignore if not of AvailExpr form */
if (!eprime)
@@ -4141,7 +4140,7 @@
/* 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) */
- q.index = (IRTyEnvIndex) aenv->val[j];
+ IRTemp q = mkIRTemp(stmts->tyenv->id, (IRTyEnvIndex) aenv->val[j]);
stmts->stmts[i] = IRStmt_WrTmp(t, IRExpr_RdTmp(q));
addToHHW(tenv, (HWord) t.index, (HWord) q.index);
anyDone = True;
@@ -4258,7 +4257,7 @@
IRTemp var, var2;
Int con, con2;
- for (UInt i = stmts->stmts_used - 1; i >= 0; i--) {
+ for (Int i = stmts->stmts_used - 1; i >= 0; i--) {
IRStmt* st = stmts->stmts[i];
if (st->tag == Ist_NoOp)
continue;
@@ -4386,7 +4385,7 @@
/* Scan backwards in bb from startHere to find a suitable PutI
binding for (descrG, ixG, biasG), if any. */
- for (UInt j = startHere; j >= 0; j--) {
+ for (Int j = startHere; j >= 0; j--) {
IRStmt* st = stmts->stmts[j];
if (st->tag == Ist_NoOp)
continue;
@@ -4598,7 +4597,7 @@
static
void do_redundant_GetI_elimination(IRStmtVec* stmts)
{
- for (UInt i = stmts->stmts_used - 1; i >= 0; i--) {
+ for (Int i = stmts->stmts_used - 1; i >= 0; i--) {
IRStmt* st = stmts->stmts[i];
if (st->tag == Ist_NoOp)
continue;
Modified: branches/VEX_JIT_HACKS/pub/libvex_ir.h
==============================================================================
--- branches/VEX_JIT_HACKS/pub/libvex_ir.h (original)
+++ branches/VEX_JIT_HACKS/pub/libvex_ir.h Mon Mar 13 23:12:27 2017
@@ -3102,11 +3102,13 @@
} Exit;
/* If-Then-Else control flow diamond. It contains:
+ - Guard controling whether "then" or "else" leg is taken
- "then" and "else" legs with vectors of statements, together
with their associated type environments
At the moment, nested "if-then-else" statements are not supported.
- Phi nodes, which are used to merge temporaries from "then" and
"else" legs
+ - TODO-JIT: A hint which leg is more likely to be taken (hot path)
A leg can either end with an unconditional exit or join the main
flow.
|
|
From: <sv...@va...> - 2017-03-13 20:14:22
|
Author: carll
Date: Mon Mar 13 20:14:08 2017
New Revision: 16270
Log:
There is a typo in the configure.ac file that causes the HAS_ISA_3_00
variable to not be set.
The mask64 value, in file VEX/priv/guest_ppc_toIR.c is missing the
HWCAPS bit for ISA3.0.
vex commit 3317.
bugzilla 377478
Modified:
trunk/NEWS
trunk/configure.ac
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Mon Mar 13 20:14:08 2017
@@ -139,6 +139,7 @@
376729 PPC64, remove R2 from the clobber list
== 371668
377427 PPC64, lxv instruction failing on odd destination register
+377478 PPC64: ISA 3.0 setup fixes
Release 3.12.0 (20 October 2016)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Mon Mar 13 20:14:08 2017
@@ -1537,7 +1537,7 @@
AC_MSG_RESULT([no])
])
-AM_CONDITIONAL(HAS_ISA_3_00, test x$ac_asm_have_isa_3_00 = xyes \
+AM_CONDITIONAL(HAS_ISA_3_00, [test x$ac_asm_have_isa_3_00 = xyes \
-a x$HWCAP_HAS_ISA_3_00 = xyes])
# Check for pthread_create@GLIBC2.0
|
|
From: <sv...@va...> - 2017-03-13 20:10:47
|
Author: carll
Date: Mon Mar 13 20:10:40 2017
New Revision: 3317
Log:
The mask64 value, in file VEX/priv/guest_ppc_toIR.c is missing the
HWCAPS bit for ISA3.0.
bugzilla 377478
Modified:
trunk/priv/guest_ppc_toIR.c
Modified: trunk/priv/guest_ppc_toIR.c
==============================================================================
--- trunk/priv/guest_ppc_toIR.c (original)
+++ trunk/priv/guest_ppc_toIR.c Mon Mar 13 20:10:40 2017
@@ -29122,7 +29122,7 @@
mask64 = VEX_HWCAPS_PPC64_V | VEX_HWCAPS_PPC64_FX
| VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP
- | VEX_HWCAPS_PPC64_ISA2_07;
+ | VEX_HWCAPS_PPC64_ISA2_07 | VEX_HWCAPS_PPC64_ISA3_0;
if (mode64) {
vassert((hwcaps_guest & mask32) == 0);
|
|
From: <sv...@va...> - 2017-03-13 17:55:14
|
Author: petarj
Date: Mon Mar 13 17:55:07 2017
New Revision: 16269
Log:
mips: improve emulation of LL/SC
Follow up to VEX r3316.
Related issue KDE #344524.
Patch by Maran Pakkirisamy.
Modified:
trunk/coregrind/m_scheduler/scheduler.c
trunk/memcheck/mc_machine.c
Modified: trunk/coregrind/m_scheduler/scheduler.c
==============================================================================
--- trunk/coregrind/m_scheduler/scheduler.c (original)
+++ trunk/coregrind/m_scheduler/scheduler.c Mon Mar 13 17:55:07 2017
@@ -957,6 +957,10 @@
vg_assert(VG_(in_generated_code) == True);
VG_(in_generated_code) = False;
+#if defined(VGA_mips32) || defined(VGA_mips64)
+ tst->arch.vex.guest_LLaddr = (HWord)(-1);
+#endif
+
if (jumped != (HWord)0) {
/* We get here if the client took a fault that caused our signal
handler to longjmp. */
Modified: trunk/memcheck/mc_machine.c
==============================================================================
--- trunk/memcheck/mc_machine.c (original)
+++ trunk/memcheck/mc_machine.c Mon Mar 13 17:55:07 2017
@@ -1159,6 +1159,9 @@
if (o == GOF(ac2) && sz == 8) return o;
if (o == GOF(ac3) && sz == 8) return o;
+ if (o == GOF(LLaddr) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(LLdata) && sz == 4) return -1; /* slot unused */
+
VG_(printf)("MC_(get_otrack_shadow_offset)(mips)(off=%d,sz=%d)\n",
offset,szB);
tl_assert(0);
@@ -1238,6 +1241,9 @@
if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1;
+ if (o == GOF(LLaddr) && sz == 8) return -1; /* slot unused */
+ if (o == GOF(LLdata) && sz == 8) return -1; /* slot unused */
+
VG_(printf)("MC_(get_otrack_shadow_offset)(mips)(off=%d,sz=%d)\n",
offset,szB);
tl_assert(0);
|
Author: petarj
Date: Mon Mar 13 17:50:25 2017
New Revision: 3316
Log:
mips: emulate LL/SC w/ guest_LLaddr and guest_LLdata
Improve LL/SC emulation with introduction of LLaddr and LLdata in the
guest state. LLaddr gets invalidated when the threads switch.
More info at KDE #344524. This patch should fix the issue.
Currently, this is effective for Cavium boards only.
Patch by Maran Pakkirisamy.
Modified:
trunk/priv/guest_mips_defs.h
trunk/priv/guest_mips_helpers.c
trunk/priv/guest_mips_toIR.c
trunk/pub/libvex_guest_mips32.h
trunk/pub/libvex_guest_mips64.h
Modified: trunk/priv/guest_mips_defs.h
==============================================================================
--- trunk/priv/guest_mips_defs.h (original)
+++ trunk/priv/guest_mips_defs.h Mon Mar 13 17:50:25 2017
@@ -94,6 +94,12 @@
SUBS, SUBD, DIVS
} flt_op;
+#if defined (_MIPSEL)
+ #define MIPS_IEND Iend_LE
+#else
+ #define MIPS_IEND Iend_BE
+#endif
+
#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
extern UInt mips32_dirtyhelper_rdhwr ( UInt rt, UInt rd );
extern ULong mips64_dirtyhelper_rdhwr ( ULong rt, ULong rd );
Modified: trunk/priv/guest_mips_helpers.c
==============================================================================
--- trunk/priv/guest_mips_helpers.c (original)
+++ trunk/priv/guest_mips_helpers.c Mon Mar 13 17:50:25 2017
@@ -167,6 +167,9 @@
vex_state->guest_CP0_status = 0;
+ vex_state->guest_LLaddr = 0xFFFFFFFF;
+ vex_state->guest_LLdata = 0;
+
/* MIPS32 DSP ASE(r2) specific registers */
vex_state->guest_DSPControl = 0; /* DSPControl register */
vex_state->guest_ac0 = 0; /* Accumulator 0 */
@@ -276,6 +279,9 @@
vex_state->guest_COND = 0;
vex_state->guest_CP0_status = MIPS_CP0_STATUS_FR;
+
+ vex_state->guest_LLaddr = 0xFFFFFFFFFFFFFFFFULL;
+ vex_state->guest_LLdata = 0;
}
/*-----------------------------------------------------------*/
Modified: trunk/priv/guest_mips_toIR.c
==============================================================================
--- trunk/priv/guest_mips_toIR.c (original)
+++ trunk/priv/guest_mips_toIR.c Mon Mar 13 17:50:25 2017
@@ -549,6 +549,9 @@
dres.jk_StopHere = Ijk_SigILL; \
dres.whatNext = Dis_StopHere;
+#define LLADDR_INVALID \
+ (mode64 ? mkU64(0xFFFFFFFFFFFFFFFFULL) : mkU32(0xFFFFFFFF))
+
/*------------------------------------------------------------*/
/*--- Field helpers ---*/
/*------------------------------------------------------------*/
@@ -1087,6 +1090,22 @@
return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
}
+static IRExpr *getLLaddr(void)
+{
+ if (mode64)
+ return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LLaddr), Ity_I64);
+ else
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLaddr), Ity_I32);
+}
+
+static IRExpr *getLLdata(void)
+{
+ if (mode64)
+ return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LLdata), Ity_I64);
+ else
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLdata), Ity_I32);
+}
+
/* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
{
@@ -1109,6 +1128,22 @@
stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
}
+static void putLLaddr(IRExpr * e)
+{
+ if (mode64)
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LLaddr), e));
+ else
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLaddr), e));
+}
+
+static void putLLdata(IRExpr * e)
+{
+ if (mode64)
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LLdata), e));
+ else
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLdata), e));
+}
+
/* fs - fpu source register number.
inst - fpu instruction that needs to be executed.
sz32 - size of source register.
@@ -1339,6 +1374,16 @@
return src;
}
+/* Convenience function to move to next instruction on condition. */
+static void mips_next_insn_if(IRExpr *condition) {
+ vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
+
+ stmt(IRStmt_Exit(condition, Ijk_Boring,
+ mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
+ IRConst_U32(guest_PC_curr_instr + 4),
+ OFFB_PC));
+}
+
static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
{
ULong branch_offset;
@@ -16935,64 +16980,106 @@
putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False));
break;
- case 0x30: /* LL / LWC0 */
+ case 0x30: /* LL */
DIP("ll r%u, %u(r%u)", rt, imm, rs);
LOAD_STORE_PATTERN;
-
- t2 = newTemp(Ity_I32);
-#if defined (_MIPSEL)
- stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
-#elif defined (_MIPSEB)
- stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
-#endif
- if (mode64)
- putIReg(rt, unop(Iop_32Sto64, mkexpr(t2)));
- else
+ if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+ t2 = newTemp(ty);
+ assign(t2, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
+ putLLaddr(mkexpr(t1));
+ putLLdata(mkexpr(t2));
putIReg(rt, mkexpr(t2));
+ } else {
+ t2 = newTemp(Ity_I32);
+ stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), NULL));
+ putIReg(rt, mkWidenFrom32(ty, mkexpr(t2), True));
+ }
break;
case 0x34: /* Load Linked Doubleword - LLD; MIPS64 */
DIP("lld r%u, %u(r%u)", rt, imm, rs);
- LOAD_STORE_PATTERN;
-
- t2 = newTemp(Ity_I64);
-#if defined (_MIPSEL)
- stmt(IRStmt_LLSC
- (Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
-#elif defined (_MIPSEB)
- stmt(IRStmt_LLSC
- (Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
-#endif
-
- putIReg(rt, mkexpr(t2));
+ if (mode64) {
+ LOAD_STORE_PATTERN;
+ t2 = newTemp(Ity_I64);
+ if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+ assign(t2, load(Ity_I64, mkexpr(t1)));
+ putLLaddr(mkexpr(t1));
+ putLLdata(mkexpr(t2));
+ } else {
+ stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), NULL));
+ }
+ putIReg(rt, mkexpr(t2));
+ } else {
+ ILLEGAL_INSTRUCTON;
+ }
break;
- case 0x38: /* SC / SWC0 */
+ case 0x38: /* SC */
DIP("sc r%u, %u(r%u)", rt, imm, rs);
+ t2 = newTemp(Ity_I1);
LOAD_STORE_PATTERN;
+ if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+ t3 = newTemp(Ity_I32);
+ assign(t2, binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
+ mkexpr(t1), getLLaddr()));
+ assign(t3, mkNarrowTo32(ty, getIReg(rt)));
+ putLLaddr(LLADDR_INVALID);
+ putIReg(rt, getIReg(0));
- t2 = newTemp(Ity_I1);
-#if defined (_MIPSEL)
- stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
-#elif defined (_MIPSEB)
- stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
-#endif
+ mips_next_insn_if(mkexpr(t2));
+
+ t4 = newTemp(Ity_I32);
+ t5 = newTemp(Ity_I32);
+
+ assign(t5, mkNarrowTo32(ty, getLLdata()));
+
+ stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
+ MIPS_IEND, mkexpr(t1), /* addr */
+ NULL, mkexpr(t5), /* expected value */
+ NULL, mkexpr(t3) /* new value */)));
- putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
+ putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32,
+ binop(Iop_CmpEQ32, mkexpr(t4), mkexpr(t5))));
+ } else {
+ stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1),
+ mkNarrowTo32(ty, getIReg(rt))));
+ putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
+ }
break;
case 0x3C: /* Store Conditional Doubleword - SCD; MIPS64 */
- DIP("sdc r%u, %u(r%u)", rt, imm, rs);
- LOAD_STORE_PATTERN;
+ DIP("scd r%u, %u(r%u)", rt, imm, rs);
+ if (mode64) {
+ t2 = newTemp(Ity_I1);
+ LOAD_STORE_PATTERN;
+ if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+ t3 = newTemp(Ity_I64);
+ assign(t2, binop(Iop_CmpNE64, mkexpr(t1), getLLaddr()));
+ assign(t3, getIReg(rt));
+ putLLaddr(LLADDR_INVALID);
+ putIReg(rt, getIReg(0));
- t2 = newTemp(Ity_I1);
-#if defined (_MIPSEL)
- stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), getIReg(rt)));
-#elif defined (_MIPSEB)
- stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), getIReg(rt)));
-#endif
+ mips_next_insn_if(mkexpr(t2));
- putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
+ t4 = newTemp(Ity_I64);
+ t5 = newTemp(Ity_I64);
+
+ assign(t5, getLLdata());
+
+ stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
+ MIPS_IEND, mkexpr(t1), /* addr */
+ NULL, mkexpr(t5), /* expected value */
+ NULL, mkexpr(t3) /* new value */)));
+
+ putIReg(rt, unop(Iop_1Uto64,
+ binop(Iop_CmpEQ64, mkexpr(t4), mkexpr(t5))));
+ } else {
+ stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), getIReg(rt)));
+ putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
+ }
+ } else {
+ ILLEGAL_INSTRUCTON;
+ }
break;
case 0x37: /* Load Doubleword - LD; MIPS64 */
Modified: trunk/pub/libvex_guest_mips32.h
==============================================================================
--- trunk/pub/libvex_guest_mips32.h (original)
+++ trunk/pub/libvex_guest_mips32.h Mon Mar 13 17:50:25 2017
@@ -151,7 +151,10 @@
/* 488 */ UInt guest_CP0_status;
- /* 492 */ UInt _padding2;
+ /* 492 */ UInt guest_LLaddr;
+ /* 496 */ UInt guest_LLdata;
+
+ /* 500 */ UInt _padding2[3];
} VexGuestMIPS32State;
/*---------------------------------------------------------------*/
/*--- Utility functions for MIPS32 guest stuff. ---*/
Modified: trunk/pub/libvex_guest_mips64.h
==============================================================================
--- trunk/pub/libvex_guest_mips64.h (original)
+++ trunk/pub/libvex_guest_mips64.h Mon Mar 13 17:50:25 2017
@@ -148,7 +148,10 @@
/* 608 */ ULong guest_NRADDR;
- /* 616 */ ULong _padding2;
+ /* 616 */ ULong guest_LLaddr;
+ /* 624 */ ULong guest_LLdata;
+
+ /* 632 */ ULong _padding2;
} VexGuestMIPS64State;
/*---------------------------------------------------------------*/
|
|
From: <sv...@va...> - 2017-03-13 13:08:25
|
Author: iraisr
Date: Mon Mar 13 13:08:13 2017
New Revision: 3315
Log:
Fix IRSB traversal problem in sanityCheckIRSB()
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
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 13 13:08:13 2017
@@ -4006,6 +4006,11 @@
return True;
}
+Bool isFlatIRSB(const IRSB* irsb)
+{
+ return isFlatIRStmtVec(irsb->stmts);
+}
+
/*---------------------------------------------------------------*/
/*--- Sanity checking ---*/
/*---------------------------------------------------------------*/
@@ -4137,7 +4142,7 @@
def_counts[tmp.id][tmp.index]++;
if (def_counts[tmp.id][tmp.index] > 1) {
- sanityCheckFail(bb,stmt,err_msg_assigned_more_than_once);
+ sanityCheckFail(bb, stmt, err_msg_assigned_more_than_once);
}
}
@@ -4236,9 +4241,6 @@
}
}
-static void useBeforeDef_Stmts(const IRSB* bb, const IRStmtVec* stmts,
- UInt* def_counts[]);
-
static
void useBeforeDef_Stmt(const IRSB* bb, const IRStmtVec* stmts,
const IRStmt* stmt, UInt* def_counts[])
@@ -4322,8 +4324,7 @@
case Ist_IfThenElse:
useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond,
def_counts);
- useBeforeDef_Stmts(bb, stmt->Ist.IfThenElse.then_leg, def_counts);
- useBeforeDef_Stmts(bb, stmt->Ist.IfThenElse.else_leg, def_counts);
+ /* Traversing into legs driven from sanityCheckIRStmtVec(). */
if (stmt->Ist.IfThenElse.phi_nodes != NULL) {
useBeforeDef_PhiNodes(bb, stmts, stmt,
stmt->Ist.IfThenElse.phi_nodes, def_counts);
@@ -4335,18 +4336,6 @@
}
static
-void useBeforeDef_Stmts(const IRSB* bb, const IRStmtVec* stmts,
- UInt* def_counts[])
-{
- for (UInt i = 0; i < stmts->stmts_used; i++) {
- useBeforeDef_Stmt(bb, stmts, stmts->stmts[i], def_counts);
- }
-}
-
-static void assignedOnce_Stmts(const IRSB* bb, const IRStmtVec* stmts,
- UInt* def_counts[]);
-
-static
void assignedOnce_Stmt(const IRSB* bb, const IRStmtVec* stmts,
const IRStmt* stmt, UInt* def_counts[])
{
@@ -4396,8 +4385,7 @@
"IRStmt.LLSC: destination tmp is assigned more than once");
break;
case Ist_IfThenElse: {
- assignedOnce_Stmts(bb, stmt->Ist.IfThenElse.then_leg, def_counts);
- assignedOnce_Stmts(bb, stmt->Ist.IfThenElse.else_leg, def_counts);
+ /* Traversing into legs driven from sanityCheckIRStmtVec(). */
const IRPhiVec* phi_nodes = stmt->Ist.IfThenElse.phi_nodes;
if (phi_nodes != NULL) {
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
@@ -4420,15 +4408,6 @@
}
static
-void assignedOnce_Stmts(const IRSB* bb, const IRStmtVec* stmts,
- UInt* def_counts[])
-{
- for (UInt i = 0; i < stmts->stmts_used; i++) {
- assignedOnce_Stmt(bb, stmts, stmts->stmts[i], def_counts);
- }
-}
-
-static
void tcExpr(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
const IRExpr* expr, IRType gWordTy)
{
@@ -4652,9 +4631,6 @@
}
}
-static void tcStmts(const IRSB* bb, const IRStmtVec* stmts, Bool require_flat,
- IRType gWordTy);
-
static
void tcStmt(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
Bool require_flat, IRType gWordTy)
@@ -4940,8 +4916,7 @@
tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond, gWordTy);
if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.cond) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.cond: not :: Ity_I1");
- tcStmts(bb, stmt->Ist.IfThenElse.then_leg, require_flat, gWordTy);
- tcStmts(bb, stmt->Ist.IfThenElse.else_leg, require_flat, gWordTy);
+ /* Traversing into legs driven from sanityCheckIRStmtVec(). */
const IRPhiVec* phi_nodes = stmt->Ist.IfThenElse.phi_nodes;
if (phi_nodes != NULL) {
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
@@ -4955,18 +4930,10 @@
}
static
-void tcStmts(const IRSB* bb, const IRStmtVec* stmts, Bool require_flat,
- IRType gWordTy)
-{
- for (UInt i = 0; i < stmts->stmts_used; i++) {
- tcStmt(bb, stmts, stmts->stmts[i], require_flat, gWordTy);
- }
-}
-
-static
void sanityCheckIRStmtVec(const IRSB* bb, const IRStmtVec* stmts,
Bool require_flat, UInt* def_counts[],
- UInt n_stmt_vecs, UInt id_counts[])
+ UInt n_stmt_vecs, UInt id_counts[],
+ IRType gWordTy)
{
const IRTypeEnv* tyenv = stmts->tyenv;
IRTyEnvID id = tyenv->id;
@@ -5009,21 +4976,30 @@
}
}
- /* Check for flatness, if required. */
- if (require_flat) {
- for (UInt i = 0; i < stmts->stmts_used; i++) {
- const IRStmt *stmt = stmts->stmts[i];
- if (stmt == NULL)
- sanityCheckFail(bb,stmt,"IRStmt: is NULL");
- if (!isFlatIRStmt(stmt))
- sanityCheckFail(bb,stmt,"IRStmt: is not flat");
- if (stmt->tag == Ist_IfThenElse) {
- sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.then_leg,
- require_flat, def_counts, n_stmt_vecs, id_counts);
- sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.else_leg,
- require_flat, def_counts, n_stmt_vecs, id_counts);
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ const IRStmt *stmt = stmts->stmts[i];
+ if (stmt == NULL)
+ sanityCheckFail(bb, stmt, "IRStmt: is NULL");
+
+ /* Check for flatness, if required. */
+ if (require_flat) {
+ if (!isFlatIRStmt(stmt)) {
+ sanityCheckFail(bb, stmt, "IRStmt: is not flat");
}
}
+
+ /* Count the defs of each temp. Only one def is allowed.
+ Also, check that each used temp has already been defd. */
+ useBeforeDef_Stmt(bb, stmts, stmt, def_counts);
+ assignedOnce_Stmt(bb, stmts, stmt, def_counts);
+ tcStmt(bb, stmts, stmt, require_flat, gWordTy);
+
+ if (stmt->tag == Ist_IfThenElse) {
+ sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.then_leg, require_flat,
+ def_counts, n_stmt_vecs, id_counts, gWordTy);
+ sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.else_leg, require_flat,
+ def_counts, n_stmt_vecs, id_counts, gWordTy);
+ }
}
}
@@ -5047,13 +5023,7 @@
vassert(gWordTy == Ity_I32 || gWordTy == Ity_I64);
sanityCheckIRStmtVec(bb, bb->stmts, require_flat, def_counts, n_stmt_vecs,
- id_counts);
-
- /* Count the defs of each temp. Only one def is allowed.
- Also, check that each used temp has already been defd. */
- useBeforeDef_Stmts(bb, bb->stmts, def_counts);
- assignedOnce_Stmts(bb, bb->stmts, def_counts);
- tcStmts(bb, bb->stmts, require_flat, gWordTy);
+ id_counts, gWordTy);
if (require_flat) {
if (!isIRAtom(bb->next)) {
|
|
From: <sv...@va...> - 2017-03-13 10:31:12
|
Author: iraisr
Date: Mon Mar 13 10:31:02 2017
New Revision: 16268
Log:
Progress further with IfThenElse in memcheck/mc_translate.c
Modified:
branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
Modified: branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c (original)
+++ branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c Mon Mar 13 10:31:02 2017
@@ -174,30 +174,10 @@
TempMapEnt;
-/* Carries around state during memcheck instrumentation. */
typedef
- struct _MCEnv {
- /* MODIFIED: the superblock being constructed. IRStmts are
- added. */
- IRSB* sb;
+ struct _MCEnvSettings {
Bool trace;
- /* MODIFIED: a table [0 .. #temps_in_sb-1] which gives the
- current kind and possibly shadow temps for each temp in the
- IRSB being constructed. Note that it does not contain the
- type of each tmp. If you want to know the type, look at the
- relevant entry in sb->tyenv. It follows that at all times
- during the instrumentation process, the valid indices for
- tmpMap and sb->tyenv are identical, being 0 .. N-1 where N is
- total number of Orig, V- and B- temps allocated so far.
-
- The reason for this strange split (types in one place, all
- other info in another) is that we need the types to be
- attached to sb so as to make it possible to do
- "typeOfIRExpr(mce->bb->tyenv, ...)" at various places in the
- instrumentation process. */
- XArray* /* of TempMapEnt */ tmpMap;
-
/* MODIFIED: indicates whether "bogus" literals have so far been
found. Starts off False, and may change to True. */
Bool bogusLiterals;
@@ -217,6 +197,37 @@
Ity_I32 or Ity_I64 only. */
IRType hWordTy;
}
+ MCEnvSettings;
+
+/* Carries around state corresponding to one IRStmtVec during Memcheck
+ instrumentation. */
+typedef
+ struct _MCEnv {
+ /* MODIFIED: the stmts being constructed. IRStmts are added. */
+ IRStmtVec* stmts;
+ IRTypeEnv* tyenv;
+ IRTyEnvID id;
+
+ /* MODIFIED: a table [0 .. #temps_in_sb-1] which gives the
+ current kind and possibly shadow temps for each temp in the
+ IRStmtVec being constructed. Note that it does not contain the
+ type of each tmp. If you want to know the type, look at the
+ relevant entry in tyenv. It follows that at all times
+ during the instrumentation process, the valid indices for
+ tmpMap and tyenv are identical, being 0 .. N-1 where N is
+ total number of Orig, V- and B- temps allocated so far.
+
+ The reason for this strange split (types in one place, all
+ other info in another) is that we need the types to be
+ attached to sb so as to make it possible to do
+ "typeOfIRExpr(mce->tyenv, ...)" at various places in the
+ instrumentation process. */
+ XArray* /* of TempMapEnt */ tmpMap;
+
+ struct _MCEnv* parent;
+
+ MCEnvSettings* settings;
+ }
MCEnv;
/* SHADOW TMP MANAGEMENT. Shadow tmps are allocated lazily (on
@@ -251,12 +262,12 @@
{
Word newIx;
TempMapEnt ent;
- IRTemp tmp = newIRTemp(mce->sb->tyenv, ty);
+ IRTemp tmp = newIRTemp(mce->tyenv, ty);
ent.kind = kind;
- ent.shadowV = IRTemp_INVALID;
- ent.shadowB = IRTemp_INVALID;
+ ent.shadowV = IRTemp_INVALID();
+ ent.shadowB = IRTemp_INVALID();
newIx = VG_(addToXA)( mce->tmpMap, &ent );
- tl_assert(newIx == (Word)tmp);
+ tl_assert(newIx == tmp.index);
return tmp;
}
@@ -265,22 +276,24 @@
so far exists, allocate one. */
static IRTemp findShadowTmpV ( MCEnv* mce, IRTemp orig )
{
- TempMapEnt* ent;
- /* VG_(indexXA) range-checks 'orig', hence no need to check
- here. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
- tl_assert(ent->kind == Orig);
- if (ent->shadowV == IRTemp_INVALID) {
- IRTemp tmpV
- = newTemp( mce, shadowTypeV(mce->sb->tyenv->types[orig]), VSh );
- /* newTemp may cause mce->tmpMap to resize, hence previous results
- from VG_(indexXA) are invalid. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
+ if (mce->id == orig.id) {
+ /* VG_(indexXA) range-checks 'orig', hence no need to check here. */
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
tl_assert(ent->kind == Orig);
- tl_assert(ent->shadowV == IRTemp_INVALID);
- ent->shadowV = tmpV;
+ if (isIRTempInvalid(ent->shadowV)) {
+ IRTemp tmpV = newTemp(mce, shadowTypeV(mce->tyenv->types[orig.index]),
+ VSh);
+ /* newTemp may cause mce->tmpMap to resize, hence previous results
+ from VG_(indexXA) are invalid. */
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
+ tl_assert(ent->kind == Orig);
+ tl_assert(isIRTempInvalid(ent->shadowV));
+ ent->shadowV = tmpV;
+ }
+ return ent->shadowV;
+ } else {
+ return findShadowTmpV(mce->parent, orig);
}
- return ent->shadowV;
}
/* Allocate a new shadow for the given original tmp. This means any
@@ -295,22 +308,59 @@
regardless. */
static void newShadowTmpV ( MCEnv* mce, IRTemp orig )
{
- TempMapEnt* ent;
+ tl_assert(mce->id == orig.id);
+
/* VG_(indexXA) range-checks 'orig', hence no need to check
here. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
tl_assert(ent->kind == Orig);
if (1) {
IRTemp tmpV
- = newTemp( mce, shadowTypeV(mce->sb->tyenv->types[orig]), VSh );
+ = newTemp(mce, shadowTypeV(mce->tyenv->types[orig.index]), VSh);
/* newTemp may cause mce->tmpMap to resize, hence previous results
from VG_(indexXA) are invalid. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
tl_assert(ent->kind == Orig);
ent->shadowV = tmpV;
}
}
+/* Set up the running environment. Both .stmts and .tmpMap are modified as we go
+ along. Note that tmps are added to both .tyenv and .tmpMap together, so the
+ valid index-set for those two arrays should always be identical. */
+static void initMCEnv(IRStmtVec* stmts_in, MCEnv* mce, MCEnv* parent_mce)
+{
+ IRStmtVec* stmts_out = emptyIRStmtVec();
+ stmts_out->tyenv = deepCopyIRTypeEnv(stmts_in->tyenv);
+ stmts_out->parent = parent_mce->stmts;
+
+ mce->stmts = stmts_out;
+ mce->tyenv = stmts_out->tyenv;
+ mce->id = mce->tyenv->id;
+ mce->parent = parent_mce;
+ mce->settings = (parent_mce != NULL) ? parent_mce->settings : NULL;
+
+ mce->tmpMap = VG_(newXA)(VG_(malloc), "mc.createMCEnv.1", VG_(free),
+ sizeof(TempMapEnt));
+ VG_(hintSizeXA)(mce->tmpMap, mce->tyenv->types_used);
+ for (UInt i = 0; i < mce->tyenv->types_used; i++) {
+ TempMapEnt ent;
+ ent.kind = Orig;
+ ent.shadowV = IRTemp_INVALID();
+ ent.shadowB = IRTemp_INVALID();
+ VG_(addToXA)(mce->tmpMap, &ent);
+ }
+ tl_assert(VG_(sizeXA)(mce->tmpMap) == stmts_in->tyenv->types_used);
+}
+
+static void deinitMCEnv(MCEnv* mce)
+{
+ /* If this fails, there's been some serious snafu with tmp management,
+ that should be investigated. */
+ tl_assert(VG_(sizeXA)(mce->tmpMap) == mce->tyenv->types_used);
+ VG_(deleteXA)(mce->tmpMap);
+}
+
/*------------------------------------------------------------*/
/*--- IRAtoms -- a subset of IRExprs ---*/
@@ -332,8 +382,12 @@
if (a1->tag == Iex_Const)
return True;
if (a1->tag == Iex_RdTmp) {
- TempMapEnt* ent = VG_(indexXA)( mce->tmpMap, a1->Iex.RdTmp.tmp );
- return ent->kind == Orig;
+ if (mce->id == a1->Iex.RdTmp.tmp.id) {
+ TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp.index);
+ return ent->kind == Orig;
+ } else {
+ return isOriginalAtom(mce->parent, a1);
+ }
}
return False;
}
@@ -345,8 +399,12 @@
if (a1->tag == Iex_Const)
return True;
if (a1->tag == Iex_RdTmp) {
- TempMapEnt* ent = VG_(indexXA)( mce->tmpMap, a1->Iex.RdTmp.tmp );
- return ent->kind == VSh || ent->kind == BSh;
+ if (mce->id == a1->Iex.RdTmp.tmp.id) {
+ TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp.index);
+ return ent->kind == VSh || ent->kind == BSh;
+ } else {
+ return isShadowAtom(mce->parent, a1);
+ }
}
return False;
}
@@ -418,12 +476,12 @@
/* add stmt to a bb */
static inline void stmt ( HChar cat, MCEnv* mce, IRStmt* st ) {
- if (mce->trace) {
+ if (mce->settings->trace) {
VG_(printf)(" %c: ", cat);
ppIRStmt(st);
VG_(printf)("\n");
}
- addStmtToIRSB(mce->sb, st);
+ addStmtToIRStmtVec(mce->stmts, st);
}
/* assign value to tmp */
@@ -432,6 +490,16 @@
stmt(cat, mce, IRStmt_WrTmp(tmp,expr));
}
+static void phi(HChar cat, MCEnv* mce, IRPhiVec* phi_nodes, IRPhi *phi)
+{
+ if (mce->settings->trace) {
+ VG_(printf)(" %c: ", cat);
+ ppIRPhi(phi);
+ VG_(printf)("\n");
+ }
+ addIRPhiToIRPhiVec(phi_nodes, phi);
+}
+
/* build various kinds of expressions */
#define triop(_op, _arg1, _arg2, _arg3) \
IRExpr_Triop((_op),(_arg1),(_arg2),(_arg3))
@@ -457,7 +525,7 @@
{
TempKind k;
IRTemp t;
- IRType tyE = typeOfIRExpr(mce->sb->tyenv, e);
+ IRType tyE = typeOfIRExpr(mce->tyenv, e);
tl_assert(tyE == ty); /* so 'ty' is redundant (!) */
switch (cat) {
@@ -761,7 +829,7 @@
/* Note, dst_ty is a shadow type, not an original type. */
tl_assert(isShadowAtom(mce,vbits));
- src_ty = typeOfIRExpr(mce->sb->tyenv, vbits);
+ src_ty = typeOfIRExpr(mce->tyenv, vbits);
/* Fast-track some common cases */
if (src_ty == Ity_I32 && dst_ty == Ity_I32)
@@ -1185,16 +1253,19 @@
behaviour of all 'emit-a-complaint' style functions we might
call. */
-static void setHelperAnns ( MCEnv* mce, IRDirty* di ) {
+static void setHelperAnns ( MCEnv* mce, IRDirty* di )
+{
+ const VexGuestLayout* layout = mce->settings->layout;
+
di->nFxState = 2;
di->fxState[0].fx = Ifx_Read;
- di->fxState[0].offset = mce->layout->offset_SP;
- di->fxState[0].size = mce->layout->sizeof_SP;
+ di->fxState[0].offset = layout->offset_SP;
+ di->fxState[0].size = layout->sizeof_SP;
di->fxState[0].nRepeats = 0;
di->fxState[0].repeatLen = 0;
di->fxState[1].fx = Ifx_Read;
- di->fxState[1].offset = mce->layout->offset_IP;
- di->fxState[1].size = mce->layout->sizeof_IP;
+ di->fxState[1].offset = layout->offset_IP;
+ di->fxState[1].size = layout->sizeof_IP;
di->fxState[1].nRepeats = 0;
di->fxState[1].repeatLen = 0;
}
@@ -1248,7 +1319,7 @@
tl_assert(isShadowAtom(mce, vatom));
tl_assert(sameKindedAtoms(atom, vatom));
- ty = typeOfIRExpr(mce->sb->tyenv, vatom);
+ ty = typeOfIRExpr(mce->tyenv, vatom);
/* sz is only used for constructing the error message */
sz = ty==Ity_I1 ? 0 : sizeofIRType(ty);
@@ -1261,7 +1332,7 @@
zero origin. */
if (MC_(clo_mc_level) == 3) {
origin = schemeE( mce, atom );
- if (mce->hWordTy == Ity_I64) {
+ if (mce->settings->hWordTy == Ity_I64) {
origin = assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, origin) );
}
} else {
@@ -1408,15 +1479,16 @@
*/
static Bool isAlwaysDefd ( MCEnv* mce, Int offset, Int size )
{
+ const VexGuestLayout* layout = mce->settings->layout;
Int minoffD, maxoffD, i;
Int minoff = offset;
Int maxoff = minoff + size - 1;
tl_assert((minoff & ~0xFFFF) == 0);
tl_assert((maxoff & ~0xFFFF) == 0);
- for (i = 0; i < mce->layout->n_alwaysDefd; i++) {
- minoffD = mce->layout->alwaysDefd[i].offset;
- maxoffD = minoffD + mce->layout->alwaysDefd[i].size - 1;
+ for (i = 0; i < layout->n_alwaysDefd; i++) {
+ minoffD = layout->alwaysDefd[i].offset;
+ maxoffD = minoffD + layout->alwaysDefd[i].size - 1;
tl_assert((minoffD & ~0xFFFF) == 0);
tl_assert((maxoffD & ~0xFFFF) == 0);
@@ -1442,6 +1514,7 @@
void do_shadow_PUT ( MCEnv* mce, Int offset,
IRAtom* atom, IRAtom* vatom, IRExpr *guard )
{
+ const VexGuestLayout* layout = mce->settings->layout;
IRType ty;
// Don't do shadow PUTs if we're not doing undefined value checking.
@@ -1459,7 +1532,7 @@
tl_assert(isShadowAtom(mce, vatom));
}
- ty = typeOfIRExpr(mce->sb->tyenv, vatom);
+ ty = typeOfIRExpr(mce->tyenv, vatom);
tl_assert(ty != Ity_I1);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* later: no ... */
@@ -1474,10 +1547,10 @@
cond = assignNew('V', mce, Ity_I1, guard);
iffalse = assignNew('V', mce, ty,
- IRExpr_Get(offset + mce->layout->total_sizeB, ty));
+ IRExpr_Get(offset + layout->total_sizeB, ty));
vatom = assignNew('V', mce, ty, IRExpr_ITE(cond, vatom, iffalse));
}
- stmt( 'V', mce, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ));
+ stmt( 'V', mce, IRStmt_Put( offset + layout->total_sizeB, vatom ));
}
}
@@ -1519,7 +1592,7 @@
/* Do a cloned version of the Put that refers to the shadow
area. */
IRRegArray* new_descr
- = mkIRRegArray( descr->base + mce->layout->total_sizeB,
+ = mkIRRegArray( descr->base + mce->settings->layout->total_sizeB,
tyS, descr->nElems);
stmt( 'V', mce, IRStmt_PutI( mkIRPutI(new_descr, ix, bias, vatom) ));
}
@@ -1542,7 +1615,7 @@
/* return a cloned version of the Get that refers to the shadow
area. */
/* FIXME: this isn't an atom! */
- return IRExpr_Get( offset + mce->layout->total_sizeB, tyS );
+ return IRExpr_Get( offset + mce->settings->layout->total_sizeB, tyS );
}
}
@@ -1567,7 +1640,7 @@
/* return a cloned version of the Get that refers to the shadow
area. */
IRRegArray* new_descr
- = mkIRRegArray( descr->base + mce->layout->total_sizeB,
+ = mkIRRegArray( descr->base + mce->settings->layout->total_sizeB,
tyS, descr->nElems);
return IRExpr_GetI( new_descr, ix, bias );
}
@@ -1586,8 +1659,8 @@
IRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2);
+ IRType t1 = typeOfIRExpr(mce->tyenv, va1);
+ IRType t2 = typeOfIRExpr(mce->tyenv, va2);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
@@ -1643,9 +1716,9 @@
IRAtom* va1, IRAtom* va2, IRAtom* va3 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2);
- IRType t3 = typeOfIRExpr(mce->sb->tyenv, va3);
+ IRType t1 = typeOfIRExpr(mce->tyenv, va1);
+ IRType t2 = typeOfIRExpr(mce->tyenv, va2);
+ IRType t3 = typeOfIRExpr(mce->tyenv, va3);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
tl_assert(isShadowAtom(mce,va3));
@@ -1777,10 +1850,10 @@
IRAtom* va1, IRAtom* va2, IRAtom* va3, IRAtom* va4 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2);
- IRType t3 = typeOfIRExpr(mce->sb->tyenv, va3);
- IRType t4 = typeOfIRExpr(mce->sb->tyenv, va4);
+ IRType t1 = typeOfIRExpr(mce->tyenv, va1);
+ IRType t2 = typeOfIRExpr(mce->tyenv, va2);
+ IRType t3 = typeOfIRExpr(mce->tyenv, va3);
+ IRType t4 = typeOfIRExpr(mce->tyenv, va4);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
tl_assert(isShadowAtom(mce,va3));
@@ -1879,7 +1952,7 @@
tl_assert(isOriginalAtom(mce, exprvec[i]));
if (cee->mcx_mask & (1<<i))
continue;
- if (typeOfIRExpr(mce->sb->tyenv, exprvec[i]) != Ity_I64)
+ if (typeOfIRExpr(mce->tyenv, exprvec[i]) != Ity_I64)
mergeTy64 = False;
}
@@ -2971,6 +3044,7 @@
IROp op,
IRAtom* atom1, IRAtom* atom2 )
{
+ const MCEnvSettings* settings = mce->settings;
IRType and_or_ty;
IRAtom* (*uifu) (MCEnv*, IRAtom*, IRAtom*);
IRAtom* (*difd) (MCEnv*, IRAtom*, IRAtom*);
@@ -4025,13 +4099,13 @@
return mkLazy2(mce, Ity_I64, vatom1, vatom2);
case Iop_Add32:
- if (mce->bogusLiterals || mce->useLLVMworkarounds)
+ if (settings->bogusLiterals || settings->useLLVMworkarounds)
return expensiveAddSub(mce,True,Ity_I32,
vatom1,vatom2, atom1,atom2);
else
goto cheap_AddSub32;
case Iop_Sub32:
- if (mce->bogusLiterals)
+ if (settings->bogusLiterals)
return expensiveAddSub(mce,False,Ity_I32,
vatom1,vatom2, atom1,atom2);
else
@@ -4048,13 +4122,13 @@
return doCmpORD(mce, op, vatom1,vatom2, atom1,atom2);
case Iop_Add64:
- if (mce->bogusLiterals || mce->useLLVMworkarounds)
+ if (settings->bogusLiterals || settings->useLLVMworkarounds)
return expensiveAddSub(mce,True,Ity_I64,
vatom1,vatom2, atom1,atom2);
else
goto cheap_AddSub64;
case Iop_Sub64:
- if (mce->bogusLiterals)
+ if (settings->bogusLiterals)
return expensiveAddSub(mce,False,Ity_I64,
vatom1,vatom2, atom1,atom2);
else
@@ -4076,7 +4150,7 @@
case Iop_CmpEQ64:
case Iop_CmpNE64:
- if (mce->bogusLiterals)
+ if (settings->bogusLiterals)
goto expensive_cmp64;
else
goto cheap_cmp64;
@@ -4092,7 +4166,7 @@
case Iop_CmpEQ32:
case Iop_CmpNE32:
- if (mce->bogusLiterals)
+ if (settings->bogusLiterals)
goto expensive_cmp32;
else
goto cheap_cmp32;
@@ -4781,7 +4855,7 @@
} else {
IROp mkAdd;
IRAtom* eBias;
- IRType tyAddr = mce->hWordTy;
+ IRType tyAddr = mce->settings->hWordTy;
tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias);
@@ -4954,7 +5028,7 @@
vbitsC = expr2vbits(mce, cond);
vbits1 = expr2vbits(mce, iftrue);
vbits0 = expr2vbits(mce, iffalse);
- ty = typeOfIRExpr(mce->sb->tyenv, vbits0);
+ ty = typeOfIRExpr(mce->tyenv, vbits0);
return
mkUifU(mce, ty, assignNew('V', mce, ty,
@@ -4980,7 +5054,7 @@
return IRExpr_RdTmp( findShadowTmpV(mce, e->Iex.RdTmp.tmp) );
case Iex_Const:
- return definedOfType(shadowTypeV(typeOfIRExpr(mce->sb->tyenv, e)));
+ return definedOfType(shadowTypeV(typeOfIRExpr(mce->tyenv, e)));
case Iex_Qop:
return expr2vbits_Qop(
@@ -5045,8 +5119,8 @@
/* vatom is vbits-value and as such can only have a shadow type. */
tl_assert(isShadowAtom(mce,vatom));
- ty = typeOfIRExpr(mce->sb->tyenv, vatom);
- tyH = mce->hWordTy;
+ ty = typeOfIRExpr(mce->tyenv, vatom);
+ tyH = mce->settings->hWordTy;
if (tyH == Ity_I32) {
switch (ty) {
@@ -5106,7 +5180,7 @@
const HChar* hname = NULL;
IRConst* c;
- tyAddr = mce->hWordTy;
+ tyAddr = mce->settings->hWordTy;
mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
tl_assert( end == Iend_LE || end == Iend_BE );
@@ -5125,10 +5199,10 @@
if (guard) {
tl_assert(isOriginalAtom(mce, guard));
- tl_assert(typeOfIRExpr(mce->sb->tyenv, guard) == Ity_I1);
+ tl_assert(typeOfIRExpr(mce->tyenv, guard) == Ity_I1);
}
- ty = typeOfIRExpr(mce->sb->tyenv, vdata);
+ ty = typeOfIRExpr(mce->tyenv, vdata);
// If we're not doing undefined value checking, pretend that this value
// is "all valid". That lets Vex's optimiser remove some of the V bit
@@ -5456,9 +5530,9 @@
tl_assert(d->mAddr);
complainIfUndefined(mce, d->mAddr, d->guard);
- tyAddr = typeOfIRExpr(mce->sb->tyenv, d->mAddr);
+ tyAddr = typeOfIRExpr(mce->tyenv, d->mAddr);
tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
- tl_assert(tyAddr == mce->hWordTy); /* not really right */
+ tl_assert(tyAddr == mce->settings->hWordTy); /* not really right */
}
/* Deal with memory inputs (reads or modifies) */
@@ -5505,9 +5579,9 @@
results to all destinations. */
/* Outputs: the destination temporary, if there is one. */
- if (d->tmp != IRTemp_INVALID) {
+ if (!isIRTempInvalid(d->tmp)) {
dst = findShadowTmpV(mce, d->tmp);
- tyDst = typeOfIRTemp(mce->sb->tyenv, d->tmp);
+ tyDst = typeOfIRTemp(mce->tyenv, d->tmp);
assign( 'V', mce, dst, mkPCastTo( mce, tyDst, curr) );
}
@@ -5815,7 +5889,7 @@
definedness test for "expected == old" was removed at r10432 of
this file.
*/
- if (cas->oldHi == IRTemp_INVALID) {
+ if (isIRTempInvalid(cas->oldHi)) {
do_shadow_CAS_single( mce, cas );
} else {
do_shadow_CAS_double( mce, cas );
@@ -5835,11 +5909,11 @@
Bool otrak = MC_(clo_mc_level) >= 3; /* a shorthand */
/* single CAS */
- tl_assert(cas->oldHi == IRTemp_INVALID);
+ tl_assert(isIRTempInvalid(cas->oldHi));
tl_assert(cas->expdHi == NULL);
tl_assert(cas->dataHi == NULL);
- elemTy = typeOfIRExpr(mce->sb->tyenv, cas->expdLo);
+ elemTy = typeOfIRExpr(mce->tyenv, cas->expdLo);
switch (elemTy) {
case Ity_I8: elemSzB = 1; opCasCmpEQ = Iop_CasCmpEQ8; break;
case Ity_I16: elemSzB = 2; opCasCmpEQ = Iop_CasCmpEQ16; break;
@@ -5929,11 +6003,11 @@
Bool otrak = MC_(clo_mc_level) >= 3; /* a shorthand */
/* double CAS */
- tl_assert(cas->oldHi != IRTemp_INVALID);
+ tl_assert(!isIRTempInvalid(cas->oldHi));
tl_assert(cas->expdHi != NULL);
tl_assert(cas->dataHi != NULL);
- elemTy = typeOfIRExpr(mce->sb->tyenv, cas->expdLo);
+ elemTy = typeOfIRExpr(mce->tyenv, cas->expdLo);
switch (elemTy) {
case Ity_I8:
opCasCmpEQ = Iop_CasCmpEQ8; opOr = Iop_Or8; opXor = Iop_Xor8;
@@ -6087,7 +6161,7 @@
assignment of the loaded (shadow) data to the result temporary.
Treat a store-conditional like a normal store, and mark the
result temporary as defined. */
- IRType resTy = typeOfIRTemp(mce->sb->tyenv, stResult);
+ IRType resTy = typeOfIRTemp(mce->tyenv, stResult);
IRTemp resTmp = findShadowTmpV(mce, stResult);
tl_assert(isIRAtom(stAddr));
@@ -6108,7 +6182,7 @@
} else {
/* Store Conditional */
/* Stay sane */
- IRType dataTy = typeOfIRExpr(mce->sb->tyenv,
+ IRType dataTy = typeOfIRExpr(mce->tyenv,
stStoredata);
tl_assert(dataTy == Ity_I64 || dataTy == Ity_I32
|| dataTy == Ity_I16 || dataTy == Ity_I8);
@@ -6193,6 +6267,51 @@
}
+static void instrument_IRStmtVec(IRStmtVec* stmts_in, UInt stmts_in_first,
+ MCEnv* mce);
+
+static void do_shadow_IfThenElse(MCEnv* mce, IRExpr* cond, IRStmtVec* then_leg,
+ IRStmtVec* else_leg, IRPhiVec* phi_nodes_in)
+{
+ IRTemp (*findShadowTmp)(MCEnv* mce, IRTemp orig);
+ HChar category;
+ if (MC_(clo_mc_level) == 3) {
+ findShadowTmp = findShadowTmpB;
+ category = 'B';
+ } else {
+ findShadowTmp = findShadowTmpV;
+ category = 'V';
+ }
+
+ complainIfUndefined(mce, cond, NULL);
+
+ MCEnv then_mce;
+ initMCEnv(then_leg, &then_mce, mce);
+ instrument_IRStmtVec(then_leg, 0, &then_mce);
+
+ MCEnv else_mce;
+ initMCEnv(else_leg, &else_mce, mce);
+ instrument_IRStmtVec(else_leg, 0, &else_mce);
+
+ IRPhiVec* phi_nodes_out = NULL;
+ if (phi_nodes_in != NULL) {
+ phi_nodes_out = emptyIRPhiVec();
+ for (UInt i = 0; i < phi_nodes_in->phis_used; i++) {
+ IRPhi* phi_in = phi_nodes_in->phis[i];
+ IRPhi* phi_shadow = mkIRPhi(findShadowTmp(mce, phi_in->dst),
+ findShadowTmp(&then_mce, phi_in->srcThen),
+ findShadowTmp(&else_mce, phi_in->srcElse));
+ phi(category, mce, phi_nodes_out, phi_shadow);
+ phi('C', mce, phi_nodes_out, phi_in);
+ }
+ }
+
+ stmt(category, mce, IRStmt_IfThenElse(cond, then_mce.stmts, else_mce.stmts,
+ phi_nodes_out));
+ deinitMCEnv(&then_mce);
+ deinitMCEnv(&else_mce);
+}
+
/*------------------------------------------------------------*/
/*--- Memcheck main ---*/
/*------------------------------------------------------------*/
@@ -6236,7 +6355,9 @@
);
}
-static Bool checkForBogusLiterals ( /*FLAT*/ IRStmt* st )
+static Bool isBogusIRStmtVec(/*FLAT*/ IRStmtVec* stmts);
+
+static Bool isBogusIRStmt(/*FLAT*/ IRStmt* st)
{
Int i;
IRExpr* e;
@@ -6335,14 +6456,169 @@
|| (st->Ist.LLSC.storedata
? isBogusAtom(st->Ist.LLSC.storedata)
: False);
+ case Ist_IfThenElse:
+ return isBogusAtom(st->Ist.IfThenElse.cond)
+ || isBogusIRStmtVec(st->Ist.IfThenElse.then_leg)
+ || isBogusIRStmtVec(st->Ist.IfThenElse.else_leg);
default:
unhandled:
ppIRStmt(st);
- VG_(tool_panic)("hasBogusLiterals");
+ VG_(tool_panic)("isBogusIRStmt");
+ }
+}
+
+static Bool isBogusIRStmtVec(/*FLAT*/ IRStmtVec* stmts)
+{
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ IRStmt* st = stmts->stmts[i];
+
+ Bool bogus = isBogusIRStmt(st);
+ if (0 && bogus) {
+ VG_(printf)("bogus: ");
+ ppIRStmt(st);
+ VG_(printf)("\n");
+ }
+ if (bogus) {
+ return True;
+ }
}
+
+ return False;
}
+/* Is to be called with already created and setup MCEnv as per initMCEnv(). */
+static void instrument_IRStmtVec(IRStmtVec* stmts_in, UInt stmts_in_first,
+ MCEnv* mce)
+{
+ for (UInt i = stmts_in_first; i < stmts_in->stmts_used; i++) {
+ IRStmt* st = stmts_in->stmts[i];
+ UInt first_stmt = mce->stmts->stmts_used;
+
+ if (mce->settings->trace) {
+ VG_(printf)("\n");
+ ppIRStmt(st);
+ VG_(printf)("\n");
+ }
+
+ if (MC_(clo_mc_level) == 3) {
+ /* See comments on case Ist_CAS and Ist_IfThenElse below. */
+ if (st->tag != Ist_CAS && st->tag != Ist_IfThenElse)
+ schemeS(mce, st);
+ }
+
+ /* Generate instrumentation code for each stmt ... */
+
+ switch (st->tag) {
+
+ case Ist_WrTmp:
+ assign('V', mce, findShadowTmpV(mce, st->Ist.WrTmp.tmp),
+ expr2vbits(mce, st->Ist.WrTmp.data));
+ break;
+
+ case Ist_Put:
+ do_shadow_PUT( mce,
+ st->Ist.Put.offset,
+ st->Ist.Put.data,
+ NULL /* shadow atom */, NULL /* guard */ );
+ break;
+
+ case Ist_PutI:
+ do_shadow_PUTI(mce, st->Ist.PutI.details);
+ break;
+
+ case Ist_Store:
+ do_shadow_Store(mce, st->Ist.Store.end,
+ st->Ist.Store.addr, 0/* addr bias */,
+ st->Ist.Store.data,
+ NULL /* shadow data */,
+ NULL/*guard*/);
+ break;
+
+ case Ist_StoreG:
+ do_shadow_StoreG(mce, st->Ist.StoreG.details);
+ break;
+
+ case Ist_LoadG:
+ do_shadow_LoadG(mce, st->Ist.LoadG.details);
+ break;
+
+ case Ist_Exit:
+ complainIfUndefined(mce, st->Ist.Exit.guard, NULL);
+ break;
+
+ case Ist_IMark:
+ break;
+
+ case Ist_NoOp:
+ case Ist_MBE:
+ break;
+
+ case Ist_Dirty:
+ do_shadow_Dirty(mce, st->Ist.Dirty.details);
+ break;
+
+ case Ist_AbiHint:
+ do_AbiHint(mce, st->Ist.AbiHint.base,
+ st->Ist.AbiHint.len,
+ st->Ist.AbiHint.nia);
+ break;
+
+ case Ist_CAS:
+ do_shadow_CAS(mce, st->Ist.CAS.details);
+ /* Note, do_shadow_CAS copies the CAS itself to the output
+ stmts, because it needs to add instrumentation both
+ before and after it. Hence skip the copy below. Also
+ skip the origin-tracking stuff (call to schemeS) above,
+ since that's all tangled up with it too; do_shadow_CAS
+ does it all. */
+ break;
+
+ case Ist_LLSC:
+ do_shadow_LLSC( mce,
+ st->Ist.LLSC.end,
+ st->Ist.LLSC.result,
+ st->Ist.LLSC.addr,
+ st->Ist.LLSC.storedata );
+ break;
+
+ case Ist_IfThenElse:
+ do_shadow_IfThenElse(mce, st->Ist.IfThenElse.cond,
+ st->Ist.IfThenElse.then_leg,
+ st->Ist.IfThenElse.else_leg,
+ st->Ist.IfThenElse.phi_nodes);
+ /* Note, do_shadow_IfThenElse copies the IfThenElse itself to the
+ output stmts, because it needs to add instrumentation to the legs
+ and to phi nodes. Hence skip the copy below. Also skip the
+ origin-tracking stuff (call to schemeS) above, since that's all
+ tangled up with it too; do_shadow_IfThenElse does it all. */
+ break;
+
+ default:
+ VG_(printf)("\n");
+ ppIRStmt(st);
+ VG_(printf)("\n");
+ VG_(tool_panic)("memcheck: unhandled IRStmt");
+
+ } /* switch (st->tag) */
+
+ if (0 && mce->settings->trace) {
+ for (UInt j = first_stmt; j < mce->stmts->stmts_used; j++) {
+ VG_(printf)(" ");
+ ppIRStmt(mce->stmts->stmts[j]);
+ VG_(printf)("\n");
+ }
+ VG_(printf)("\n");
+ }
+
+ /* ... and finally copy the stmt itself to the output. Except,
+ skip the copy of IRCASs and IfThenElse; see comments on cases Ist_CAS
+ and Ist_IfThenElse above. */
+ if (st->tag != Ist_CAS && st->tag != Ist_IfThenElse)
+ stmt('C', mce, st);
+ }
+}
+
IRSB* MC_(instrument) ( VgCallbackClosure* closure,
IRSB* sb_in,
const VexGuestLayout* layout,
@@ -6350,11 +6626,7 @@
const VexArchInfo* archinfo_host,
IRType gWordTy, IRType hWordTy )
{
- Bool verboze = 0||False;
- Int i, j, first_stmt;
- IRStmt* st;
- MCEnv mce;
- IRSB* sb_out;
+ Bool verboze = 0 || False;
if (gWordTy != hWordTy) {
/* We don't currently support this case. */
@@ -6372,19 +6644,14 @@
tl_assert(MC_(clo_mc_level) >= 1 && MC_(clo_mc_level) <= 3);
- /* Set up SB */
- sb_out = deepCopyIRSBExceptStmts(sb_in);
+ /* Set up SB, MCEnv and MCEnvSettings. */
+ IRSB* sb_out = deepCopyIRSBExceptStmts(sb_in);
- /* Set up the running environment. Both .sb and .tmpMap are
- modified as we go along. Note that tmps are added to both
- .sb->tyenv and .tmpMap together, so the valid index-set for
- those two arrays should always be identical. */
- VG_(memset)(&mce, 0, sizeof(mce));
- mce.sb = sb_out;
- mce.trace = verboze;
- mce.layout = layout;
- mce.hWordTy = hWordTy;
- mce.bogusLiterals = False;
+ MCEnvSettings settings;
+ settings.trace = verboze;
+ settings.layout = layout;
+ settings.hWordTy = hWordTy;
+ settings.bogusLiterals = False;
/* Do expensive interpretation for Iop_Add32 and Iop_Add64 on
Darwin. 10.7 is mostly built with LLVM, which uses these for
@@ -6395,66 +6662,40 @@
interpretation, but that would require some way to tag them in
the _toIR.c front ends, which is a lot of faffing around. So
for now just use the slow and blunt-instrument solution. */
- mce.useLLVMworkarounds = False;
+ settings.useLLVMworkarounds = False;
# if defined(VGO_darwin)
- mce.useLLVMworkarounds = True;
+ settings.useLLVMworkarounds = True;
# endif
- mce.tmpMap = VG_(newXA)( VG_(malloc), "mc.MC_(instrument).1", VG_(free),
- sizeof(TempMapEnt));
- VG_(hintSizeXA) (mce.tmpMap, sb_in->tyenv->types_used);
- for (i = 0; i < sb_in->tyenv->types_used; i++) {
- TempMapEnt ent;
- ent.kind = Orig;
- ent.shadowV = IRTemp_INVALID;
- ent.shadowB = IRTemp_INVALID;
- VG_(addToXA)( mce.tmpMap, &ent );
- }
- tl_assert( VG_(sizeXA)( mce.tmpMap ) == sb_in->tyenv->types_used );
+ MCEnv mce;
+ initMCEnv(sb_in->stmts, &mce, NULL);
+ mce.settings = &settings;
+
+ tl_assert(isFlatIRSB(sb_in));
if (MC_(clo_expensive_definedness_checks)) {
- /* For expensive definedness checking skip looking for bogus
- literals. */
- mce.bogusLiterals = True;
+ /* For expensive definedness checking skip looking for bogus literals. */
+ settings.bogusLiterals = True;
} else {
/* Make a preliminary inspection of the statements, to see if there
are any dodgy-looking literals. If there are, we generate
- extra-detailed (hence extra-expensive) instrumentation in
- places. Scan the whole bb even if dodgyness is found earlier,
- so that the flatness assertion is applied to all stmts. */
- Bool bogus = False;
-
- for (i = 0; i < sb_in->stmts_used; i++) {
- st = sb_in->stmts[i];
- tl_assert(st);
- tl_assert(isFlatIRStmt(st));
-
- if (!bogus) {
- bogus = checkForBogusLiterals(st);
- if (0 && bogus) {
- VG_(printf)("bogus: ");
- ppIRStmt(st);
- VG_(printf)("\n");
- }
- if (bogus) break;
- }
- }
- mce.bogusLiterals = bogus;
+ extra-detailed (hence extra-expensive) instrumentation in places. */
+ settings.bogusLiterals = isBogusIRStmtVec(sb_in->stmts);
}
/* Copy verbatim any IR preamble preceding the first IMark */
- tl_assert(mce.sb == sb_out);
- tl_assert(mce.sb != sb_in);
+ tl_assert(mce.stmts == sb_out->stmts);
+ tl_assert(mce.stmts != sb_in->stmts);
- i = 0;
- while (i < sb_in->stmts_used && sb_in->stmts[i]->tag != Ist_IMark) {
+ UInt i = 0;
+ while (i < sb_in->stmts->stmts_used
+ && sb_in->stmts->stmts[i]->tag != Ist_IMark) {
- st = sb_in->stmts[i];
- tl_assert(st);
- tl_assert(isFlatIRStmt(st));
+ IRStmt* st = sb_in->stmts->stmts[i];
+ tl_assert(st != NULL);
- stmt( 'C', &mce, sb_in->stmts[i] );
+ stmt('C', &mce, sb_in->stmts->stmts[i]);
i++;
}
@@ -6480,18 +6721,18 @@
assignment for the corresponding origin (B) shadow, claiming
no-origin, as appropriate for a defined value.
*/
- for (j = 0; j < i; j++) {
- if (sb_in->stmts[j]->tag == Ist_WrTmp) {
+ for (UInt j = 0; j < i; j++) {
+ if (sb_in->stmts->stmts[j]->tag == Ist_WrTmp) {
/* findShadowTmpV checks its arg is an original tmp;
no need to assert that here. */
- IRTemp tmp_o = sb_in->stmts[j]->Ist.WrTmp.tmp;
+ IRTemp tmp_o = sb_in->stmts->stmts[j]->Ist.WrTmp.tmp;
IRTemp tmp_v = findShadowTmpV(&mce, tmp_o);
- IRType ty_v = typeOfIRTemp(sb_out->tyenv, tmp_v);
- assign( 'V', &mce, tmp_v, definedOfType( ty_v ) );
+ IRType ty_v = typeOfIRTemp(mce.tyenv, tmp_v);
+ assign('V', &mce, tmp_v, definedOfType(ty_v));
if (MC_(clo_mc_level) == 3) {
IRTemp tmp_b = findShadowTmpB(&mce, tmp_o);
- tl_assert(typeOfIRTemp(sb_out->tyenv, tmp_b) == Ity_I32);
- assign( 'B', &mce, tmp_b, mkU32(0)/* UNKNOWN ORIGIN */);
+ tl_assert(typeOfIRTemp(mce.tyenv, tmp_b) == Ity_I32);
+ assign('B', &mce, tmp_b, mkU32(0)/* UNKNOWN ORIGIN */);
}
if (0) {
VG_(printf)("create shadow tmp(s) for preamble tmp [%d] ty ", j);
@@ -6503,129 +6744,13 @@
/* Iterate over the remaining stmts to generate instrumentation. */
- tl_assert(sb_in->stmts_used > 0);
- tl_assert(i >= 0);
- tl_assert(i < sb_in->stmts_used);
- tl_assert(sb_in->stmts[i]->tag == Ist_IMark);
-
- for (/* use current i*/; i < sb_in->stmts_used; i++) {
-
- st = sb_in->stmts[i];
- first_stmt = sb_out->stmts_used;
-
- if (verboze) {
- VG_(printf)("\n");
- ppIRStmt(st);
- VG_(printf)("\n");
- }
-
- if (MC_(clo_mc_level) == 3) {
- /* See comments on case Ist_CAS below. */
- if (st->tag != Ist_CAS)
- schemeS( &mce, st );
- }
-
- /* Generate instrumentation code for each stmt ... */
-
- switch (st->tag) {
-
- case Ist_WrTmp:
- assign( 'V', &mce, findShadowTmpV(&mce, st->Ist.WrTmp.tmp),
- expr2vbits( &mce, st->Ist.WrTmp.data) );
- break;
-
- case Ist_Put:
- do_shadow_PUT( &mce,
- st->Ist.Put.offset,
- st->Ist.Put.data,
- NULL /* shadow atom */, NULL /* guard */ );
- break;
-
- case Ist_PutI:
- do_shadow_PUTI( &mce, st->Ist.PutI.details);
- break;
-
- case Ist_Store:
- do_shadow_Store( &mce, st->Ist.Store.end,
- st->Ist.Store.addr, 0/* addr bias */,
- st->Ist.Store.data,
- NULL /* shadow data */,
- NULL/*guard*/ );
- break;
-
- case Ist_StoreG:
- do_shadow_StoreG( &mce, st->Ist.StoreG.details );
- break;
-
- case Ist_LoadG:
- do_shadow_LoadG( &mce, st->Ist.LoadG.details );
- break;
-
- case Ist_Exit:
- complainIfUndefined( &mce, st->Ist.Exit.guard, NULL );
- break;
-
- case Ist_IMark:
- break;
-
- case Ist_NoOp:
- case Ist_MBE:
- break;
-
- case Ist_Dirty:
- do_shadow_Dirty( &mce, st->Ist.Dirty.details );
- break;
-
- case Ist_AbiHint:
- do_AbiHint( &mce, st->Ist.AbiHint.base,
- st->Ist.AbiHint.len,
- st->Ist.AbiHint.nia );
- break;
-
- case Ist_CAS:
- do_shadow_CAS( &mce, st->Ist.CAS.details );
- /* Note, do_shadow_CAS copies the CAS itself to the output
- block, because it needs to add instrumentation both
- before and after it. Hence skip the copy below. Also
- skip the origin-tracking stuff (call to schemeS) above,
- since that's all tangled up with it too; do_shadow_CAS
- does it all. */
- break;
-
- case Ist_LLSC:
- do_shadow_LLSC( &mce,
- st->Ist.LLSC.end,
- st->Ist.LLSC.result,
- st->Ist.LLSC.addr,
- st->Ist.LLSC.storedata );
- break;
-
- default:
- VG_(printf)("\n");
- ppIRStmt(st);
- VG_(printf)("\n");
- VG_(tool_panic)("memcheck: unhandled IRStmt");
-
- } /* switch (st->tag) */
-
- if (0 && verboze) {
- for (j = first_stmt; j < sb_out->stmts_used; j++) {
- VG_(printf)(" ");
- ppIRStmt(sb_out->stmts[j]);
- VG_(printf)("\n");
- }
- VG_(printf)("\n");
- }
-
- /* ... and finally copy the stmt itself to the output. Except,
- skip the copy of IRCASs; see comments on case Ist_CAS
- above. */
- if (st->tag != Ist_CAS)
- stmt('C', &mce, st);
- }
+ tl_assert(sb_in->stmts->stmts_used > 0);
+ tl_assert(i < sb_in->stmts->stmts_used);
+ tl_assert(sb_in->stmts->stmts[i]->tag == Ist_IMark);
+ instrument_IRStmtVec(sb_in->stmts, i, &mce);
/* Now we need to complain if the jump target is undefined. */
- first_stmt = sb_out->stmts_used;
+ UInt first_stmt = sb_out->stmts->stmts_used;
if (verboze) {
VG_(printf)("sb_in->next = ");
@@ -6633,23 +6758,20 @@
VG_(printf)("\n\n");
}
- complainIfUndefined( &mce, sb_in->next, NULL );
+ complainIfUndefined(&mce, sb_in->next, NULL);
if (0 && verboze) {
- for (j = first_stmt; j < sb_out->stmts_used; j++) {
+ for (UInt j = first_stmt; j < sb_out->stmts->stmts_used; j++) {
VG_(printf)(" ");
- ppIRStmt(sb_out->stmts[j]);
+ ppIRStmt(sb_out->stmts->stmts[j]);
VG_(printf)("\n");
}
VG_(printf)("\n");
}
- /* If this fails, there's been some serious snafu with tmp management,
- that should be investigated. */
- tl_assert( VG_(sizeXA)( mce.tmpMap ) == mce.sb->tyenv->types_used );
- VG_(deleteXA)( mce.tmpMap );
+ tl_assert(mce.stmts == sb_out->stmts);
+ deinitMCEnv(&mce);
- tl_assert(mce.sb == sb_out);
return sb_out;
}
@@ -6751,7 +6873,7 @@
return e1->Iex.Unop.op == e2->Iex.Unop.op
&& sameIRValue(e1->Iex.Unop.arg, e2->Iex.Unop.arg);
case Iex_RdTmp:
- return e1->Iex.RdTmp.tmp == e2->Iex.RdTmp.tmp;
+ return eqIRTemp(e1->Iex.RdTmp.tmp, e2->Iex.RdTmp.tmp);
case Iex_ITE:
return sameIRValue( e1->Iex.ITE.cond, e2->Iex.ITE.cond )
&& sameIRValue( e1->Iex.ITE.iftrue, e2->Iex.ITE.iftrue )
@@ -6860,16 +6982,9 @@
|| 0==VG_(strcmp)(name, "1_fail_w_o)");
}
-IRSB* MC_(final_tidy) ( IRSB* sb_in )
+static IRStmtVec* final_tidy_IRStmtVec(IRStmtVec* stmts)
{
- Int i;
- IRStmt* st;
- IRDirty* di;
- IRExpr* guard;
- IRCallee* cee;
- Bool alreadyPresent;
- Pairs pairs;
-
+ Pairs pairs;
pairs.pairsUsed = 0;
pairs.pairs[N_TIDYING_PAIRS].entry = (void*)0x123;
@@ -6879,25 +6994,33 @@
of the relevant helpers is seen, check if we have made a
previous call to the same helper using the same guard
expression, and if so, delete the call. */
- for (i = 0; i < sb_in->stmts_used; i++) {
- st = sb_in->stmts[i];
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ IRStmt* st = stmts->stmts[i];
tl_assert(st);
+
+ if (st->tag == Ist_IfThenElse) {
+ final_tidy_IRStmtVec(st->Ist.IfThenElse.then_leg);
+ final_tidy_IRStmtVec(st->Ist.IfThenElse.else_leg);
+ }
+
if (st->tag != Ist_Dirty)
continue;
- di = st->Ist.Dirty.details;
- guard = di->guard;
+
+ IRDirty* di = st->Ist.Dirty.details;
+ IRExpr* guard = di->guard;
tl_assert(guard);
if (0) { ppIRExpr(guard); VG_(printf)("\n"); }
- cee = di->cee;
+ IRCallee* cee = di->cee;
if (!is_helperc_value_checkN_fail( cee->name ))
continue;
+
/* Ok, we have a call to helperc_value_check0/1/4/8_fail with
guard 'guard'. Check if we have already seen a call to this
function with the same guard. If so, delete it. If not,
add it to the set of calls we do know about. */
- alreadyPresent = check_or_add( &pairs, guard, cee->addr );
+ Bool alreadyPresent = check_or_add( &pairs, guard, cee->addr );
if (alreadyPresent) {
- sb_in->stmts[i] = IRStmt_NoOp();
+ stmts->stmts[i] = IRStmt_NoOp();
if (0) VG_(printf)("XX\n");
}
}
@@ -6905,6 +7028,12 @@
tl_assert(pairs.pairs[N_TIDYING_PAIRS].entry == (void*)0x123);
tl_assert(pairs.pairs[N_TIDYING_PAIRS].guard == (IRExpr*)0x456);
+ return stmts;
+}
+
+IRSB* MC_(final_tidy) ( IRSB* sb_in )
+{
+ final_tidy_IRStmtVec(sb_in->stmts);
return sb_in;
}
@@ -6918,22 +7047,23 @@
/* Almost identical to findShadowTmpV. */
static IRTemp findShadowTmpB ( MCEnv* mce, IRTemp orig )
{
- TempMapEnt* ent;
- /* VG_(indexXA) range-checks 'orig', hence no need to check
- here. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
- tl_assert(ent->kind == Orig);
- if (ent->shadowB == IRTemp_INVALID) {
- IRTemp tmpB
- = newTemp( mce, Ity_I32, BSh );
- /* newTemp may cause mce->tmpMap to resize, hence previous results
- from VG_(indexXA) are invalid. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
+ if (mce->id == orig.id) {
+ /* VG_(indexXA) range-checks 'orig', hence no need to check here. */
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
tl_assert(ent->kind == Orig);
- tl_assert(ent->shadowB == IRTemp_INVALID);
- ent->shadowB = tmpB;
+ if (isIRTempInvalid(ent->shadowB)) {
+ IRTemp tmpB = newTemp( mce, Ity_I32, BSh );
+ /* newTemp may cause mce->tmpMap to resize, hence previous results
+ from VG_(indexXA) are invalid. */
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
+ tl_assert(ent->kind == Orig);
+ tl_assert(isIRTempInvalid(ent->shadowB));
+ ent->shadowB = tmpB;
+ }
+ return ent->shadowB;
+ } else {
+ return findShadowTmpB(mce->parent, orig);
}
- return ent->shadowB;
}
static IRAtom* gen_maxU32 ( MCEnv* mce, IRAtom* b1, IRAtom* b2 )
@@ -6958,7 +7088,7 @@
const HChar* hName;
IRTemp bTmp;
IRDirty* di;
- IRType aTy = typeOfIRExpr( mce->sb->tyenv, baseaddr );
+ IRType aTy = typeOfIRExpr( mce->tyenv, baseaddr );
IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
IRAtom* ea = baseaddr;
if (offset != 0) {
@@ -6966,7 +7096,7 @@
: mkU64( (Long)(Int)offset );
ea = assignNew( 'B', mce, aTy, binop(opAdd, ea, off));
}
- bTmp = newTemp(mce, mce->hWordTy, BSh);
+ bTmp = newTemp(mce, mce->settings->hWordTy, BSh);
switch (szB) {
case 1: hFun = (void*)&MC_(helperc_b_load1);
@@ -7007,7 +7137,7 @@
/* no need to mess with any annotations. This call accesses
neither guest state nor guest memory. */
stmt( 'B', mce, IRStmt_Dirty(di) );
- if (mce->hWordTy == Ity_I64) {
+ if (mce->settings->hWordTy == Ity_I64) {
/* 64-bit host */
IRTemp bTmp32 = newTemp(mce, Ity_I32, BSh);
assign( 'B', mce, bTmp32, unop(Iop_64to32, mkexpr(bTmp)) );
@@ -7073,19 +7203,19 @@
void* hFun;
const HChar* hName;
IRDirty* di;
- IRType aTy = typeOfIRExpr( mce->sb->tyenv, baseaddr );
+ IRType aTy = typeOfIRExpr( mce->tyenv, baseaddr );
IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
IRAtom* ea = baseaddr;
if (guard) {
tl_assert(isOriginalAtom(mce, guard));
- tl_assert(typeOfIRExpr(mce->sb->tyenv, guard) == Ity_I1);
+ tl_assert(typeOfIRExpr(mce->tyenv, guard) == Ity_I1);
}
if (offset != 0) {
IRAtom* off = aTy == Ity_I32 ? mkU32( offset )
: mkU64( (Long)(Int)offset );
ea = assignNew( 'B', mce, aTy, binop(opAdd, ea, off));
}
- if (mce->hWordTy == Ity_I64)
+ if (mce->settings->hWordTy == Ity_I64)
dataB = assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, dataB));
switch (szB) {
@@ -7121,7 +7251,7 @@
}
static IRAtom* narrowTo32 ( MCEnv* mce, IRAtom* e ) {
- IRType eTy = typeOfIRExpr(mce->sb->tyenv, e);
+ IRType eTy = typeOfIRExpr(mce->tyenv, e);
if (eTy == Ity_I64)
return assignNew( 'B', mce, Ity_I32, unop(Iop_64to32, e) );
if (eTy == Ity_I32)
@@ -7130,7 +7260,7 @@
}
static IRAtom* zWidenFrom32 ( MCEnv* mce, IRType dstTy, IRAtom* e ) {
- IRType eTy = typeOfIRExpr(mce->sb->tyenv, e);
+ IRType eTy = typeOfIRExpr(mce->tyenv, e);
tl_assert(eTy == Ity_I32);
if (dstTy == Ity_I64)
return assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, e) );
@@ -7142,6 +7272,8 @@
{
tl_assert(MC_(clo_mc_level) == 3);
+ const VexGuestLayout* layout = mce->settings->layout;
+
switch (e->tag) {
case Iex_GetI: {
@@ -7156,8 +7288,8 @@
return mkU32(0);
tl_assert(sizeofIRType(equivIntTy) >= 4);
tl_assert(sizeofIRType(equivIntTy) == sizeofIRType(descr->elemTy));
- descr_b = mkIRRegArray( descr->base + 2*mce->layout->total_sizeB,
- equivIntTy, descr->nElems );
+ descr_b = mkIRRegArray(descr->base + 2 * layout->total_sizeB,
+ equivIntTy, descr->nElems);
/* Do a shadow indexed get of the same size, giving t1. Take
the bottom 32 bits of it, giving t2. Compute into t3 the
origin for the index (almost certainly zero, but there's
@@ -7202,7 +7334,8 @@
/* assert that the B value for the address is already
available (somewhere) */
tl_assert(isIRAtom(e->Iex.Load.addr));
- tl_assert(mce->hWordTy == Ity_I32 || mce->hWordTy == Ity_I64);
+ tl_assert(mce->settings->hWordTy == Ity_I32
+ || mce->settings->hWordTy == Ity_I64);
return gen_load_b( mce, dszB, e->Iex.Load.addr, 0 );
}
case Iex_ITE: {
@@ -7257,12 +7390,10 @@
e->Iex.Get.offset,
sizeofIRType(e->Iex.Get.ty)
);
- tl_assert(b_offset >= -1
- && b_offset <= mce->layout->total_sizeB -4);
+ tl_assert(b_offset >= -1 && b_offset <= layout->total_sizeB -4);
if (b_offset >= 0) {
/* FIXME: this isn't an atom! */
- return IRExpr_Get( b_offset + 2*mce->layout->total_sizeB,
- Ity_I32 );
+ return IRExpr_Get(b_offset + 2 * layout->total_sizeB, Ity_I32);
}
return mkU32(0);
}
@@ -7276,6 +7407,8 @@
static void do_origins_Dirty ( MCEnv* mce, IRDirty* d )
{
+ const VexGuestLayout* layout = mce->settings->layout;
+
// This is a hacked version of do_shadow_Dirty
Int i, k, n, toDo, gSz, gOff;
IRAtom *here, *curr;
@@ -7338,7 +7471,7 @@
iffalse = mkU32(0);
iftrue = assignNew( 'B', mce, Ity_I32,
IRExpr_Get(b_offset
- + 2*mce->layout->total_sizeB,
+ + 2 * layout->total_sizeB,
Ity_I32));
here = assignNew( 'B', mce, Ity_I32,
IRExpr_ITE(cond, iftrue, iffalse));
@@ -7397,7 +7530,7 @@
Now we need to re-distribute the results to all destinations. */
/* Outputs: the destination temporary, if there is one. */
- if (d->tmp != IRTemp_INVALID) {
+ if (!isIRTempInvalid(d->tmp)) {
dst = findShadowTmpB(mce, d->tmp);
assign( 'V', mce, dst, curr );
}
@@ -7437,13 +7570,13 @@
d->guard);
iffalse = assignNew('B', mce, Ity_I32,
IRExpr_Get(b_offset +
- 2*mce->layout->total_sizeB,
+ 2 * layout->total_sizeB,
Ity_I32));
curr = assignNew('V', mce, Ity_I32,
IRExpr_ITE(cond, curr, iffalse));
stmt( 'B', mce, IRStmt_Put(b_offset
- + 2*mce->layout->total_sizeB,
+ + 2 * layout->total_sizeB,
curr ));
}
gSz -= n;
@@ -7493,7 +7626,7 @@
XXXX how does this actually ensure that?? */
tl_assert(isIRAtom(stAddr));
tl_assert(isIRAtom(stData));
- dszB = sizeofIRType( typeOfIRExpr(mce->sb->tyenv, stData ) );
+ dszB = sizeofIRType( typeOfIRExpr(mce->tyenv, stData ) );
dataB = schemeE( mce, stData );
gen_store_b( mce, dszB, stAddr, 0/*offset*/, dataB, guard );
}
@@ -7546,6 +7679,8 @@
{
tl_assert(MC_(clo_mc_level) == 3);
+ const VexGuestLayout* layout = mce->settings->layout;
+
switch (st->tag) {
case Ist_AbiHint:
@@ -7570,7 +7705,7 @@
tl_assert(sizeofIRType(equivIntTy) >= 4);
tl_assert(sizeofIRType(equivIntTy) == sizeofIRType(descr->elemTy));
descr_b
- = mkIRRegArray( descr->base + 2*mce->layout->total_sizeB,
+ = mkIRRegArray( descr->base + 2 * layout->total_sizeB,
equivIntTy, descr->nElems );
/* Compute a value to Put - the conjoinment of the origin for
the data to be Put-ted (obviously) and of the index value
@@ -7610,7 +7745,7 @@
if (st->Ist.LLSC.storedata == NULL) {
/* Load Linked */
IRType resTy
- = typeOfIRTemp(mce->sb->tyenv, st->Ist.LLSC.result);
+ = typeOfIRTemp(mce->tyenv, st->Ist.LLSC.result);
IRExpr* vanillaLoad
= IRExpr_Load(st->Ist.LLSC.end, resTy, st->Ist.LLSC.addr);
tl_assert(resTy == Ity_I64 || resTy == Ity_I32
@@ -7636,11 +7771,11 @@
Int b_offset
= MC_(get_otrack_shadow_offset)(
st->Ist.Put.offset,
- sizeofIRType(typeOfIRExpr(mce->sb->tyenv, st->Ist.Put.data))
+ sizeofIRType(typeOfIRExpr(mce->tyenv, st->Ist.Put.data))
);
if (b_offset >= 0) {
/* FIXME: this isn't an atom! */
- stmt( 'B', mce, IRStmt_Put(b_offset + 2*mce->layout->total_sizeB,
+ stmt( 'B', mce, IRStmt_Put(b_offset + 2 * layout->total_sizeB,
schemeE( mce, st->Ist.Put.data )) );
}
break;
|
|
From: <sv...@va...> - 2017-03-13 10:30:40
|
Author: iraisr
Date: Mon Mar 13 10:30:32 2017
New Revision: 3314
Log:
Small refinement in VEX IR interface
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h
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 13 10:30:32 2017
@@ -3675,16 +3675,8 @@
/*--- Helper functions for the IR -- IR Phi Nodes ---*/
/*---------------------------------------------------------------*/
-void addIRPhi(IRStmt* st, IRPhi* phi)
+void addIRPhiToIRPhiVec(IRPhiVec* phi_nodes, IRPhi* phi)
{
- vassert(st->tag == Ist_IfThenElse);
-
- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- if (phi_nodes == NULL) {
- phi_nodes = emptyIRPhiVec();
- st->Ist.IfThenElse.phi_nodes = phi_nodes;
- }
-
if (phi_nodes->phis_used == phi_nodes->phis_size) {
IRPhi** phis2 = LibVEX_Alloc_inline(2 * phi_nodes->phis_size * sizeof(IRPhi*));
for (UInt i = 0; i < phi_nodes->phis_size; i++)
Modified: branches/VEX_JIT_HACKS/pub/libvex_ir.h
==============================================================================
--- branches/VEX_JIT_HACKS/pub/libvex_ir.h (original)
+++ branches/VEX_JIT_HACKS/pub/libvex_ir.h Mon Mar 13 10:30:32 2017
@@ -2760,12 +2760,14 @@
IRPhiVec;
extern void ppIRPhi(const IRPhi*);
-extern IRPhi* mkIRPhi(IRTemp, IRTemp, IRTemp);
+extern IRPhi* mkIRPhi(IRTemp dst, IRTemp srcThen, IRTemp srcElse);
extern IRPhi* deepCopyIRPhi(const IRPhi*);
extern void ppIRPhiVec(const IRPhiVec*);
extern IRPhiVec* emptyIRPhiVec(void);
extern IRPhiVec* deepCopyIRPhiVec(const IRPhiVec*);
+extern void addIRPhiToIRPhiVec(IRPhiVec* , IRPhi*);
+
/* ------------------ Type Environments ------------------ */
@@ -3151,9 +3153,6 @@
/* Pretty-print an IRStmt. */
extern void ppIRStmt ( const IRStmt* );
-/* Adds a phi node to IfThenElse statement. */
-extern void addIRPhi(IRStmt* , IRPhi*);
-
/* ------------------ Basic Blocks ------------------ */
/* Code blocks, which in proper compiler terminology are superblocks
|