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-28 21:10:58
|
Author: iraisr
Date: Tue Mar 28 22:10:37 2017
New Revision: 3336
Log:
Last few fixes for the new approach with single global IRTypeEnv.
Now all tests for none and memcheck tools pass as they did in the baseline.
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/priv/ir_opt.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 Tue Mar 28 22:10:37 2017
@@ -2423,7 +2423,7 @@
{
IRStmtVecID next = irsb->id_seq;
irsb->id_seq += 1;
- vassert(irsb->id_seq < IRStmtVecID_INVALID);
+ vassert(irsb->id_seq != IRStmtVecID_INVALID);
return next;
}
@@ -2616,13 +2616,12 @@
IRTempDefSet* deepCopyIRTempDefSet(const IRTempDefSet* def_set)
{
IRTempDefSet* def_set2 = LibVEX_Alloc_inline(sizeof(IRTempDefSet));
- def_set2->slots_used = def_set->slots_used;
- def_set2->slots_size = def_set->slots_size;
+ def_set2->slots_used = def_set2->slots_size = def_set->slots_used;
UChar* set2 = LibVEX_Alloc_inline(def_set2->slots_used * sizeof(UChar));
for (UInt i = 0; i < def_set2->slots_used; i++) {
set2[i] = def_set->set[i];
}
- def_set2->set = set2;
+ def_set2->set = set2;
return def_set2;
}
@@ -3778,12 +3777,14 @@
UInt slots_required = (tmp + sizeof(UChar)) / sizeof(UChar);
if (slots_required >= def_set->slots_size) {
- UChar* new_set = LibVEX_Alloc_inline(2 * def_set->slots_size);
+ UInt new_size = (slots_required > 2 * def_set->slots_size) ?
+ slots_required : 2 * def_set->slots_size;
+ UChar* new_set = LibVEX_Alloc_inline(new_size * sizeof(UChar));
for (UInt i = 0; i < def_set->slots_used; i++) {
new_set[i] = def_set->set[i];
}
def_set->set = new_set;
- def_set->slots_size *= 2;
+ def_set->slots_size = new_size;
}
if (slots_required > def_set->slots_used) {
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 Tue Mar 28 22:10:37 2017
@@ -5114,11 +5114,11 @@
bb2 = deepCopyIRSB(bb1);
- /* 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
- IRTemp is defined and that can be set only during traversal. So we do
- only types here and deal with IDs and def_set during statement
- traversal. */
+ /* This is tricky. We need to copy types. We also need to increase IDs for
+ nested IRStmtVec's. This can be achieved here. But we also need to keep
+ track in which IRStmtVec each IRTemp is defined and that can be set
+ only during traversal. So we do only types here and deal with IDs and
+ def_set during statement traversal. */
ensureSpaceInIRTypeEnv(bb1->tyenv, bb1->tyenv->used + n_vars);
for (i = 0; i < n_vars; i++) {
bb1->tyenv->types[n_vars + i] = bb2->tyenv->types[i];
@@ -5134,7 +5134,8 @@
addStmtToIRStmtVec(bb1->stmts, bb2->stmts->stmts[i]);
}
- bb1->id_seq += n_ids;
+ /* Account for duplicated nested IRStmtVec's */
+ bb1->id_seq += (n_ids - 1);
}
if (DEBUG_IROPT) {
|
|
From: Carl E. L. <ce...@us...> - 2017-03-28 20:43:25
|
Julian:
I know you mentioned the possibility of having a follow on release for
release 3.12.0 in the Nov 2016 time frame. Mark and I were talking
about a couple of bug fixes I recently did for the PPC64 ISA 3.0
support. He is back porting them for the next RHEL point release.
We were wondering if you had decided if you were going to do an
incremental release or not? If so, the following PPC fixes should be
included.
VEX svn r3308
PowerPC: Fix incorrect register pair check for lxv, stxv, stxsd, stxssp, lxsd,
lxssp instructions
The lfdpx, stdpx, lfdp and stfdp instructions work on a register pair. The
register pair test must only be applied to these instructions in the
dis_fp_pair() function.
bugzilla 377427
VEX svn r3317
The mask64 value, in file VEX/priv/guest_ppc_toIR.c is missing the
HWCAPS bit for ISA3.0.
bugzilla 377478
valgrind commit 16254.
PPC64, remove R2 from the clobber list
bugzilla 376729
These are not critical fixes at this point, but should be included in any incremental
release.
When do you plan/expect the next major release (3.13.0) will occur?
Carl Love
|
|
From: <sv...@va...> - 2017-03-28 14:57:24
|
Author: sewardj
Date: Tue Mar 28 15:57:17 2017
New Revision: 3335
Log:
Implement the most important cases for amd64 direct-reload optimisation:
cmpq $imm32, %vreg -> cmpq $imm32, (stack-slot-of-vreg)
orq %vreg, %reg -> orq (stack-slot-of-vreg), %reg
This is in support of "Bug 375839 - Temporary storage exhausted, when long
sequence of vfmadd231ps instructions to be executed", and reduces code size by
around 3% in that case.
Modified:
trunk/priv/host_amd64_defs.c
trunk/priv/host_amd64_defs.h
trunk/priv/main_main.c
Modified: trunk/priv/host_amd64_defs.c
==============================================================================
--- trunk/priv/host_amd64_defs.c (original)
+++ trunk/priv/host_amd64_defs.c Tue Mar 28 15:57:17 2017
@@ -1995,6 +1995,43 @@
}
}
+AMD64Instr* directReload_AMD64( AMD64Instr* i, HReg vreg, Short spill_off )
+{
+ vassert(spill_off >= 0 && spill_off < 10000); /* let's say */
+
+ /* Deal with form: src=RMI_Reg, dst=Reg where src == vreg
+ Convert to: src=RMI_Mem, dst=Reg
+ */
+ if (i->tag == Ain_Alu64R
+ && (i->Ain.Alu64R.op == Aalu_MOV || i->Ain.Alu64R.op == Aalu_OR
+ || i->Ain.Alu64R.op == Aalu_XOR)
+ && i->Ain.Alu64R.src->tag == Armi_Reg
+ && sameHReg(i->Ain.Alu64R.src->Armi.Reg.reg, vreg)) {
+ vassert(! sameHReg(i->Ain.Alu64R.dst, vreg));
+ return AMD64Instr_Alu64R(
+ i->Ain.Alu64R.op,
+ AMD64RMI_Mem( AMD64AMode_IR( spill_off, hregAMD64_RBP())),
+ i->Ain.Alu64R.dst
+ );
+ }
+
+ /* Deal with form: src=RMI_Imm, dst=Reg where dst == vreg
+ Convert to: src=RI_Imm, dst=Mem
+ */
+ if (i->tag == Ain_Alu64R
+ && (i->Ain.Alu64R.op == Aalu_CMP)
+ && i->Ain.Alu64R.src->tag == Armi_Imm
+ && sameHReg(i->Ain.Alu64R.dst, vreg)) {
+ return AMD64Instr_Alu64M(
+ i->Ain.Alu64R.op,
+ AMD64RI_Imm( i->Ain.Alu64R.src->Armi.Imm.imm32 ),
+ AMD64AMode_IR( spill_off, hregAMD64_RBP())
+ );
+ }
+
+ return NULL;
+}
+
/* --------- The amd64 assembler (bleh.) --------- */
@@ -2607,6 +2644,39 @@
goto bad;
}
}
+ /* ADD/SUB/ADC/SBB/AND/OR/XOR/CMP. MUL is not
+ allowed here. (This is derived from the x86 version of same). */
+ opc = subopc_imm = opc_imma = 0;
+ switch (i->Ain.Alu64M.op) {
+ case Aalu_CMP: opc = 0x39; subopc_imm = 7; break;
+ default: goto bad;
+ }
+ switch (i->Ain.Alu64M.src->tag) {
+ /*
+ case Xri_Reg:
+ *p++ = toUChar(opc);
+ p = doAMode_M(p, i->Xin.Alu32M.src->Xri.Reg.reg,
+ i->Xin.Alu32M.dst);
+ goto done;
+ */
+ case Ari_Imm:
+ if (fits8bits(i->Ain.Alu64M.src->Ari.Imm.imm32)) {
+ *p++ = rexAMode_M_enc(subopc_imm, i->Ain.Alu64M.dst);
+ *p++ = 0x83;
+ p = doAMode_M_enc(p, subopc_imm, i->Ain.Alu64M.dst);
+ *p++ = toUChar(0xFF & i->Ain.Alu64M.src->Ari.Imm.imm32);
+ goto done;
+ } else {
+ *p++ = rexAMode_M_enc(subopc_imm, i->Ain.Alu64M.dst);
+ *p++ = 0x81;
+ p = doAMode_M_enc(p, subopc_imm, i->Ain.Alu64M.dst);
+ p = emit32(p, i->Ain.Alu64M.src->Ari.Imm.imm32);
+ goto done;
+ }
+ default:
+ goto bad;
+ }
+
break;
case Ain_Sh64:
Modified: trunk/priv/host_amd64_defs.h
==============================================================================
--- trunk/priv/host_amd64_defs.h (original)
+++ trunk/priv/host_amd64_defs.h Tue Mar 28 15:57:17 2017
@@ -802,6 +802,9 @@
extern void genReload_AMD64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
HReg rreg, Int offset, Bool );
+extern AMD64Instr* directReload_AMD64 ( AMD64Instr* i,
+ HReg vreg, Short spill_off );
+
extern const RRegUniverse* getRRegUniverse_AMD64 ( void );
extern HInstrArray* iselSB_AMD64 ( const IRSB*,
Modified: trunk/priv/main_main.c
==============================================================================
--- trunk/priv/main_main.c (original)
+++ trunk/priv/main_main.c Tue Mar 28 15:57:17 2017
@@ -433,6 +433,7 @@
mapRegs = (__typeof__(mapRegs)) AMD64FN(mapRegs_AMD64Instr);
genSpill = (__typeof__(genSpill)) AMD64FN(genSpill_AMD64);
genReload = (__typeof__(genReload)) AMD64FN(genReload_AMD64);
+ directReload = (__typeof__(directReload)) AMD64FN(directReload_AMD64);
ppInstr = (__typeof__(ppInstr)) AMD64FN(ppAMD64Instr);
ppReg = (__typeof__(ppReg)) AMD64FN(ppHRegAMD64);
iselSB = AMD64FN(iselSB_AMD64);
|
|
From: <sv...@va...> - 2017-03-28 08:53:28
|
Author: iraisr
Date: Tue Mar 28 09:53:20 2017
New Revision: 16288
Log:
Fit also coregrind and memcheck into new approach with single global tyenv.
Modified:
branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c
branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c
branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
Modified: branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c (original)
+++ branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c Tue Mar 28 09:53:20 2017
@@ -1282,6 +1282,8 @@
{
IRStmtVec* stmts_out = emptyIRStmtVec();
stmts_out->parent = parent;
+ stmts_out->id = stmts_in->id;
+ stmts_out->def_set = deepCopyIRTempDefSet(stmts_in->def_set);
for (UInt i = 0; i < stmts_in->stmts_used; i++) {
IRStmt* st = stmts_in->stmts[i];
Modified: branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c (original)
+++ branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c Tue Mar 28 09:53:20 2017
@@ -159,7 +159,7 @@
{
Int i;
for (i = 0; i < N_ALIASES; i++) {
- SP_aliases[i].temp = IRTemp_INVALID();
+ SP_aliases[i].temp = IRTemp_INVALID;
SP_aliases[i].delta = 0;
}
next_SP_alias_slot = 0;
@@ -167,7 +167,7 @@
static void add_SP_alias(IRTemp temp, Long delta)
{
- vg_assert(!isIRTempInvalid(temp));
+ vg_assert(temp != IRTemp_INVALID);
SP_aliases[ next_SP_alias_slot ].temp = temp;
SP_aliases[ next_SP_alias_slot ].delta = delta;
next_SP_alias_slot++;
@@ -177,17 +177,17 @@
static Bool get_SP_delta(IRTemp temp, Long* delta)
{
Int i; // i must be signed!
- vg_assert(!isIRTempInvalid(temp));
+ vg_assert(temp != IRTemp_INVALID);
// Search backwards between current buffer position and the start.
for (i = next_SP_alias_slot-1; i >= 0; i--) {
- if (eqIRTemp(temp, SP_aliases[i].temp)) {
+ if (temp == SP_aliases[i].temp) {
*delta = SP_aliases[i].delta;
return True;
}
}
// Search backwards between the end and the current buffer position.
for (i = N_ALIASES-1; i >= next_SP_alias_slot; i--) {
- if (eqIRTemp(temp, SP_aliases[i].temp)) {
+ if (temp == SP_aliases[i].temp) {
*delta = SP_aliases[i].delta;
return True;
}
@@ -199,7 +199,7 @@
{
Int i;
for (i = 0; i < N_ALIASES; i++) {
- if (isIRTempInvalid(SP_aliases[i].temp)) {
+ if (SP_aliases[i].temp == IRTemp_INVALID) {
return;
}
SP_aliases[i].delta += delta;
@@ -269,6 +269,7 @@
*/
static
IRStmtVec* vg_SP_update_IRStmtVec(void* closureV,
+ IRTypeEnv* tyenv,
IRStmtVec* stmts_in,
IRStmtVec* parent,
const VexGuestLayout* layout,
@@ -290,8 +291,9 @@
/* Set up new IRStmtVec */
IRStmtVec* out = emptyIRStmtVec();
- out->tyenv = deepCopyIRTypeEnv(stmts_in->tyenv);
out->parent = parent;
+ out->id = stmts_in->id;
+ out->def_set = deepCopyIRTempDefSet(stmts_in->def_set);
delta = 0;
@@ -406,7 +408,7 @@
if (e->tag != Iex_Get) goto case2;
if (e->Iex.Get.offset != offset_SP) goto case2;
if (e->Iex.Get.ty != typeof_SP) goto case2;
- vg_assert( typeOfIRTemp(out, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
add_SP_alias(st->Ist.WrTmp.tmp, 0);
addStmtToIRStmtVec(out, st);
continue;
@@ -421,7 +423,7 @@
if (e->Iex.Binop.arg2->tag != Iex_Const) goto case3;
if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3;
con = GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
- vg_assert( typeOfIRTemp(out, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
if (IS_ADD(e->Iex.Binop.op)) {
add_SP_alias(st->Ist.WrTmp.tmp, delta + con);
} else {
@@ -436,7 +438,7 @@
e = st->Ist.WrTmp.data;
if (e->tag != Iex_RdTmp) goto case4;
if (!get_SP_delta(e->Iex.RdTmp.tmp, &delta)) goto case4;
- vg_assert( typeOfIRTemp(out, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
add_SP_alias(st->Ist.WrTmp.tmp, delta);
addStmtToIRStmtVec(out, st);
continue;
@@ -451,7 +453,7 @@
last_SP = first_SP + sizeof_SP - 1;
first_Put = st->Ist.Put.offset;
last_Put = first_Put
- + sizeofIRType(typeOfIRExpr(out, st->Ist.Put.data))
+ + sizeofIRType(typeOfIRExpr(tyenv, st->Ist.Put.data))
- 1;
vg_assert(first_SP <= last_SP);
vg_assert(first_Put <= last_Put);
@@ -469,7 +471,7 @@
put_SP_alias is immediately preceded by an assertion that
we are putting in a binding for a correctly-typed
temporary. */
- vg_assert( typeOfIRTemp(out, tttmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(tyenv, tttmp) == typeof_SP );
/* From the same type-and-offset-correctness argument, if
we found a useable alias, it must for an "exact" write of SP. */
vg_assert(first_SP == first_Put);
@@ -521,7 +523,7 @@
generic:
/* Pass both the old and new SP values to this helper. Also,
pass an origin tag, even if it isn't needed. */
- old_SP = newIRTemp(out->tyenv, typeof_SP);
+ old_SP = newIRTemp(tyenv, out, typeof_SP);
addStmtToIRStmtVec(
out,
IRStmt_WrTmp( old_SP, IRExpr_Get(offset_SP, typeof_SP) )
@@ -568,7 +570,7 @@
/* 1 */
addStmtToIRStmtVec(out, st);
/* 2 */
- new_SP = newIRTemp(out->tyenv, typeof_SP);
+ new_SP = newIRTemp(tyenv, out, typeof_SP);
addStmtToIRStmtVec(
out,
IRStmt_WrTmp( new_SP, IRExpr_Get(offset_SP, typeof_SP) )
@@ -609,7 +611,7 @@
if (first_Put == first_SP && last_Put == last_SP
&& st->Ist.Put.data->tag == Iex_RdTmp) {
- vg_assert( typeOfIRTemp(out, st->Ist.Put.data->Iex.RdTmp.tmp)
+ vg_assert( typeOfIRTemp(tyenv, st->Ist.Put.data->Iex.RdTmp.tmp)
== typeof_SP );
add_SP_alias(st->Ist.Put.data->Iex.RdTmp.tmp, 0);
}
@@ -648,10 +650,12 @@
if (st->tag == Ist_IfThenElse) {
st = IRStmt_IfThenElse(
st->Ist.IfThenElse.cond,
- vg_SP_update_IRStmtVec(closureV, st->Ist.IfThenElse.then_leg,
- out, layout, vge, vai, gWordTy, hWordTy),
- vg_SP_update_IRStmtVec(closureV, st->Ist.IfThenElse.else_leg,
- out, layout, vge, vai, gWordTy, hWordTy),
+ vg_SP_update_IRStmtVec(closureV, tyenv,
+ st->Ist.IfThenElse.then_leg, out,
+ layout, vge, vai, gWordTy, hWordTy),
+ vg_SP_update_IRStmtVec(closureV, tyenv,
+ st->Ist.IfThenElse.else_leg, out,
+ layout, vge, vai, gWordTy, hWordTy),
st->Ist.IfThenElse.phi_nodes);
}
@@ -684,13 +688,14 @@
{
/* Set up BB */
IRSB* bb = emptyIRSB();
+ bb->tyenv = deepCopyIRTypeEnv(sb_in->tyenv);
bb->id_seq = sb_in->id_seq;
bb->next = deepCopyIRExpr(sb_in->next);
bb->jumpkind = sb_in->jumpkind;
bb->offsIP = sb_in->offsIP;
- bb->stmts = vg_SP_update_IRStmtVec(closureV, sb_in->stmts, NULL, layout,
- vge, vai, gWordTy, hWordTy);
+ bb->stmts = vg_SP_update_IRStmtVec(closureV, bb->tyenv, sb_in->stmts, NULL,
+ layout, vge, vai, gWordTy, hWordTy);
return bb;
}
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 Tue Mar 28 09:53:20 2017
@@ -206,7 +206,6 @@
/* MODIFIED: the stmts being constructed. IRStmts are added. */
IRStmtVec* stmts;
IRTypeEnv* tyenv;
- IRTyEnvID id;
UInt depth; /* for indenting properly nested statements */
/* MODIFIED: a table [0 .. #temps_in_sb-1] which gives the
@@ -221,7 +220,7 @@
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->stmts, ...)" at various places in the
+ "typeOfIRExpr(mce->tyenv, ...)" at various places in the
instrumentation process. */
XArray* /* of TempMapEnt */ tmpMap;
@@ -263,12 +262,12 @@
{
Word newIx;
TempMapEnt ent;
- IRTemp tmp = newIRTemp(mce->tyenv, ty);
+ IRTemp tmp = newIRTemp(mce->tyenv, mce->stmts, 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 == tmp.index);
+ tl_assert(newIx == tmp);
return tmp;
}
@@ -277,23 +276,16 @@
so far exists, allocate one. */
static IRTemp findShadowTmpV ( MCEnv* mce, IRTemp orig )
{
- while (mce->id != orig.id) {
- mce = mce->parent;
- tl_assert(mce != NULL);
- }
- tl_assert(mce->id == orig.id);
-
/* VG_(indexXA) range-checks 'orig', hence no need to check here. */
- TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig);
tl_assert(ent->kind == Orig);
- if (isIRTempInvalid(ent->shadowV)) {
- IRTemp tmpV = newTemp(mce, shadowTypeV(mce->tyenv->types[orig.index]),
- VSh);
+ if (ent->shadowV == IRTemp_INVALID) {
+ IRTemp tmpV = newTemp(mce, shadowTypeV(mce->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, orig.index);
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig);
tl_assert(ent->kind == Orig);
- tl_assert(isIRTempInvalid(ent->shadowV));
+ tl_assert(ent->shadowV == IRTemp_INVALID);
ent->shadowV = tmpV;
}
return ent->shadowV;
@@ -311,18 +303,15 @@
regardless. */
static void newShadowTmpV ( MCEnv* mce, IRTemp orig )
{
- tl_assert(mce->id == orig.id);
-
/* VG_(indexXA) range-checks 'orig', hence no need to check
here. */
- TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig);
tl_assert(ent->kind == Orig);
if (1) {
- IRTemp tmpV
- = newTemp(mce, shadowTypeV(mce->tyenv->types[orig.index]), VSh);
+ IRTemp tmpV = newTemp(mce, shadowTypeV(mce->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, orig.index);
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig);
tl_assert(ent->kind == Orig);
ent->shadowV = tmpV;
}
@@ -331,37 +320,38 @@
/* 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)
+static void initMCEnv(IRTypeEnv* tyenv, IRStmtVec* stmts_in, MCEnv* mce,
+ MCEnv* parent_mce)
{
IRStmtVec* stmts_out = emptyIRStmtVec();
- stmts_out->tyenv = deepCopyIRTypeEnv(stmts_in->tyenv);
stmts_out->parent = (parent_mce != NULL) ? parent_mce->stmts : NULL;
+ stmts_out->id = stmts_in->id;
+ stmts_out->def_set = deepCopyIRTempDefSet(stmts_in->def_set);
mce->stmts = stmts_out;
- mce->tyenv = stmts_out->tyenv;
- mce->id = mce->tyenv->id;
+ mce->tyenv = tyenv;
mce->depth = (parent_mce != NULL) ? parent_mce->depth + 1 : 0;
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++) {
+ VG_(hintSizeXA)(mce->tmpMap, mce->tyenv->used);
+ for (UInt i = 0; i < mce->tyenv->used; i++) {
TempMapEnt ent;
ent.kind = Orig;
- ent.shadowV = IRTemp_INVALID();
- ent.shadowB = IRTemp_INVALID();
+ ent.shadowV = IRTemp_INVALID;
+ ent.shadowB = IRTemp_INVALID;
VG_(addToXA)(mce->tmpMap, &ent);
}
- tl_assert(VG_(sizeXA)(mce->tmpMap) == stmts_in->tyenv->types_used);
+ tl_assert(VG_(sizeXA)(mce->tmpMap) == tyenv->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);
+ tl_assert(VG_(sizeXA)(mce->tmpMap) == mce->tyenv->used);
VG_(deleteXA)(mce->tmpMap);
}
@@ -386,13 +376,7 @@
if (a1->tag == Iex_Const)
return True;
if (a1->tag == Iex_RdTmp) {
- while (mce->id != a1->Iex.RdTmp.tmp.id) {
- mce = mce->parent;
- tl_assert(mce != NULL);
- }
- tl_assert(mce->id == a1->Iex.RdTmp.tmp.id);
-
- TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp.index);
+ TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp);
return ent->kind == Orig;
}
return False;
@@ -405,13 +389,7 @@
if (a1->tag == Iex_Const)
return True;
if (a1->tag == Iex_RdTmp) {
- while (mce->id != a1->Iex.RdTmp.tmp.id) {
- mce = mce->parent;
- tl_assert(mce != NULL);
- }
- tl_assert(mce->id == a1->Iex.RdTmp.tmp.id);
-
- TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp.index);
+ TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp);
return ent->kind == VSh || ent->kind == BSh;
}
return False;
@@ -533,7 +511,7 @@
{
TempKind k;
IRTemp t;
- IRType tyE = typeOfIRExpr(mce->stmts, e);
+ IRType tyE = typeOfIRExpr(mce->tyenv, e);
tl_assert(tyE == ty); /* so 'ty' is redundant (!) */
switch (cat) {
@@ -837,7 +815,7 @@
/* Note, dst_ty is a shadow type, not an original type. */
tl_assert(isShadowAtom(mce,vbits));
- src_ty = typeOfIRExpr(mce->stmts, vbits);
+ src_ty = typeOfIRExpr(mce->tyenv, vbits);
/* Fast-track some common cases */
if (src_ty == Ity_I32 && dst_ty == Ity_I32)
@@ -1327,7 +1305,7 @@
tl_assert(isShadowAtom(mce, vatom));
tl_assert(sameKindedAtoms(atom, vatom));
- ty = typeOfIRExpr(mce->stmts, vatom);
+ ty = typeOfIRExpr(mce->tyenv, vatom);
/* sz is only used for constructing the error message */
sz = ty==Ity_I1 ? 0 : sizeofIRType(ty);
@@ -1540,7 +1518,7 @@
tl_assert(isShadowAtom(mce, vatom));
}
- ty = typeOfIRExpr(mce->stmts, vatom);
+ ty = typeOfIRExpr(mce->tyenv, vatom);
tl_assert(ty != Ity_I1);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* later: no ... */
@@ -1667,8 +1645,8 @@
IRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->stmts, va1);
- IRType t2 = typeOfIRExpr(mce->stmts, va2);
+ IRType t1 = typeOfIRExpr(mce->tyenv, va1);
+ IRType t2 = typeOfIRExpr(mce->tyenv, va2);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
@@ -1724,9 +1702,9 @@
IRAtom* va1, IRAtom* va2, IRAtom* va3 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->stmts, va1);
- IRType t2 = typeOfIRExpr(mce->stmts, va2);
- IRType t3 = typeOfIRExpr(mce->stmts, 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));
@@ -1858,10 +1836,10 @@
IRAtom* va1, IRAtom* va2, IRAtom* va3, IRAtom* va4 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->stmts, va1);
- IRType t2 = typeOfIRExpr(mce->stmts, va2);
- IRType t3 = typeOfIRExpr(mce->stmts, va3);
- IRType t4 = typeOfIRExpr(mce->stmts, 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));
@@ -1960,7 +1938,7 @@
tl_assert(isOriginalAtom(mce, exprvec[i]));
if (cee->mcx_mask & (1<<i))
continue;
- if (typeOfIRExpr(mce->stmts, exprvec[i]) != Ity_I64)
+ if (typeOfIRExpr(mce->tyenv, exprvec[i]) != Ity_I64)
mergeTy64 = False;
}
@@ -5036,7 +5014,7 @@
vbitsC = expr2vbits(mce, cond);
vbits1 = expr2vbits(mce, iftrue);
vbits0 = expr2vbits(mce, iffalse);
- ty = typeOfIRExpr(mce->stmts, vbits0);
+ ty = typeOfIRExpr(mce->tyenv, vbits0);
return
mkUifU(mce, ty, assignNew('V', mce, ty,
@@ -5062,7 +5040,7 @@
return IRExpr_RdTmp( findShadowTmpV(mce, e->Iex.RdTmp.tmp) );
case Iex_Const:
- return definedOfType(shadowTypeV(typeOfIRExpr(mce->stmts, e)));
+ return definedOfType(shadowTypeV(typeOfIRExpr(mce->tyenv, e)));
case Iex_Qop:
return expr2vbits_Qop(
@@ -5127,7 +5105,7 @@
/* vatom is vbits-value and as such can only have a shadow type. */
tl_assert(isShadowAtom(mce,vatom));
- ty = typeOfIRExpr(mce->stmts, vatom);
+ ty = typeOfIRExpr(mce->tyenv, vatom);
tyH = mce->settings->hWordTy;
if (tyH == Ity_I32) {
@@ -5207,10 +5185,10 @@
if (guard) {
tl_assert(isOriginalAtom(mce, guard));
- tl_assert(typeOfIRExpr(mce->stmts, guard) == Ity_I1);
+ tl_assert(typeOfIRExpr(mce->tyenv, guard) == Ity_I1);
}
- ty = typeOfIRExpr(mce->stmts, 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
@@ -5538,7 +5516,7 @@
tl_assert(d->mAddr);
complainIfUndefined(mce, d->mAddr, d->guard);
- tyAddr = typeOfIRExpr(mce->stmts, d->mAddr);
+ tyAddr = typeOfIRExpr(mce->tyenv, d->mAddr);
tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
tl_assert(tyAddr == mce->settings->hWordTy); /* not really right */
}
@@ -5587,9 +5565,9 @@
results to all destinations. */
/* Outputs: the destination temporary, if there is one. */
- if (!isIRTempInvalid(d->tmp)) {
+ if (d->tmp != IRTemp_INVALID) {
dst = findShadowTmpV(mce, d->tmp);
- tyDst = typeOfIRTemp(mce->stmts, d->tmp);
+ tyDst = typeOfIRTemp(mce->tyenv, d->tmp);
assign( 'V', mce, dst, mkPCastTo( mce, tyDst, curr) );
}
@@ -5897,7 +5875,7 @@
definedness test for "expected == old" was removed at r10432 of
this file.
*/
- if (isIRTempInvalid(cas->oldHi)) {
+ if (cas->oldHi == IRTemp_INVALID) {
do_shadow_CAS_single( mce, cas );
} else {
do_shadow_CAS_double( mce, cas );
@@ -5917,11 +5895,11 @@
Bool otrak = MC_(clo_mc_level) >= 3; /* a shorthand */
/* single CAS */
- tl_assert(isIRTempInvalid(cas->oldHi));
+ tl_assert(cas->oldHi == IRTemp_INVALID);
tl_assert(cas->expdHi == NULL);
tl_assert(cas->dataHi == NULL);
- elemTy = typeOfIRExpr(mce->stmts, 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;
@@ -6011,11 +5989,11 @@
Bool otrak = MC_(clo_mc_level) >= 3; /* a shorthand */
/* double CAS */
- tl_assert(!isIRTempInvalid(cas->oldHi));
+ tl_assert(cas->oldHi != IRTemp_INVALID);
tl_assert(cas->expdHi != NULL);
tl_assert(cas->dataHi != NULL);
- elemTy = typeOfIRExpr(mce->stmts, cas->expdLo);
+ elemTy = typeOfIRExpr(mce->tyenv, cas->expdLo);
switch (elemTy) {
case Ity_I8:
opCasCmpEQ = Iop_CasCmpEQ8; opOr = Iop_Or8; opXor = Iop_Xor8;
@@ -6169,7 +6147,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->stmts, stResult);
+ IRType resTy = typeOfIRTemp(mce->tyenv, stResult);
IRTemp resTmp = findShadowTmpV(mce, stResult);
tl_assert(isIRAtom(stAddr));
@@ -6190,7 +6168,7 @@
} else {
/* Store Conditional */
/* Stay sane */
- IRType dataTy = typeOfIRExpr(mce->stmts,
+ IRType dataTy = typeOfIRExpr(mce->tyenv,
stStoredata);
tl_assert(dataTy == Ity_I64 || dataTy == Ity_I32
|| dataTy == Ity_I16 || dataTy == Ity_I8);
@@ -6294,11 +6272,11 @@
complainIfUndefined(mce, cond, NULL);
MCEnv then_mce;
- initMCEnv(then_leg, &then_mce, mce);
+ initMCEnv(mce->tyenv, then_leg, &then_mce, mce);
instrument_IRStmtVec(then_leg, 0, &then_mce);
MCEnv else_mce;
- initMCEnv(else_leg, &else_mce, mce);
+ initMCEnv(mce->tyenv, else_leg, &else_mce, mce);
instrument_IRStmtVec(else_leg, 0, &else_mce);
IRPhiVec* phi_nodes_out = emptyIRPhiVec();
@@ -6672,7 +6650,7 @@
# endif
MCEnv mce;
- initMCEnv(sb_in->stmts, &mce, NULL);
+ initMCEnv(sb_out->tyenv, sb_in->stmts, &mce, NULL);
mce.settings = &settings;
sb_out->stmts = mce.stmts;
@@ -6732,11 +6710,11 @@
no need to assert that here. */
IRTemp tmp_o = sb_in->stmts->stmts[j]->Ist.WrTmp.tmp;
IRTemp tmp_v = findShadowTmpV(&mce, tmp_o);
- IRType ty_v = typeOfIRTemp(mce.stmts, tmp_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(mce.stmts, tmp_b) == Ity_I32);
+ tl_assert(typeOfIRTemp(mce.tyenv, tmp_b) == Ity_I32);
assign('B', &mce, tmp_b, mkU32(0)/* UNKNOWN ORIGIN */);
}
if (0) {
@@ -6877,7 +6855,7 @@
return e1->Iex.Unop.op == e2->Iex.Unop.op
&& sameIRValue(e1->Iex.Unop.arg, e2->Iex.Unop.arg);
case Iex_RdTmp:
- return eqIRTemp(e1->Iex.RdTmp.tmp, e2->Iex.RdTmp.tmp);
+ return 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 )
@@ -7051,22 +7029,16 @@
/* Almost identical to findShadowTmpV. */
static IRTemp findShadowTmpB ( MCEnv* mce, IRTemp orig )
{
- while (mce->id != orig.id) {
- mce = mce->parent;
- tl_assert(mce != NULL);
- }
- tl_assert(mce->id == orig.id);
-
/* VG_(indexXA) range-checks 'orig', hence no need to check here. */
- TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig);
tl_assert(ent->kind == Orig);
- if (isIRTempInvalid(ent->shadowB)) {
+ 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, orig.index);
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig);
tl_assert(ent->kind == Orig);
- tl_assert(isIRTempInvalid(ent->shadowB));
+ tl_assert(ent->shadowB == IRTemp_INVALID);
ent->shadowB = tmpB;
}
return ent->shadowB;
@@ -7094,7 +7066,7 @@
const HChar* hName;
IRTemp bTmp;
IRDirty* di;
- IRType aTy = typeOfIRExpr(mce->stmts, baseaddr);
+ IRType aTy = typeOfIRExpr(mce->tyenv, baseaddr);
IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
IRAtom* ea = baseaddr;
if (offset != 0) {
@@ -7209,12 +7181,12 @@
void* hFun;
const HChar* hName;
IRDirty* di;
- IRType aTy = typeOfIRExpr(mce->stmts, 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->stmts, guard) == Ity_I1);
+ tl_assert(typeOfIRExpr(mce->tyenv, guard) == Ity_I1);
}
if (offset != 0) {
IRAtom* off = aTy == Ity_I32 ? mkU32( offset )
@@ -7257,7 +7229,7 @@
}
static IRAtom* narrowTo32 ( MCEnv* mce, IRAtom* e ) {
- IRType eTy = typeOfIRExpr(mce->stmts, 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)
@@ -7266,7 +7238,7 @@
}
static IRAtom* zWidenFrom32 ( MCEnv* mce, IRType dstTy, IRAtom* e ) {
- IRType eTy = typeOfIRExpr(mce->stmts, 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) );
@@ -7536,7 +7508,7 @@
Now we need to re-distribute the results to all destinations. */
/* Outputs: the destination temporary, if there is one. */
- if (!isIRTempInvalid(d->tmp)) {
+ if (d->tmp != IRTemp_INVALID) {
dst = findShadowTmpB(mce, d->tmp);
assign( 'V', mce, dst, curr );
}
@@ -7632,7 +7604,7 @@
XXXX how does this actually ensure that?? */
tl_assert(isIRAtom(stAddr));
tl_assert(isIRAtom(stData));
- dszB = sizeofIRType( typeOfIRExpr(mce->stmts, stData ) );
+ dszB = sizeofIRType( typeOfIRExpr(mce->tyenv, stData ) );
dataB = schemeE( mce, stData );
gen_store_b( mce, dszB, stAddr, 0/*offset*/, dataB, guard );
}
@@ -7751,7 +7723,7 @@
if (st->Ist.LLSC.storedata == NULL) {
/* Load Linked */
IRType resTy
- = typeOfIRTemp(mce->stmts, 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
@@ -7777,7 +7749,7 @@
Int b_offset
= MC_(get_otrack_shadow_offset)(
st->Ist.Put.offset,
- sizeofIRType(typeOfIRExpr(mce->stmts, st->Ist.Put.data))
+ sizeofIRType(typeOfIRExpr(mce->tyenv, st->Ist.Put.data))
);
if (b_offset >= 0) {
/* FIXME: this isn't an atom! */
|
|
From: <sv...@va...> - 2017-03-28 08:52:27
|
Author: iraisr
Date: Tue Mar 28 09:52:20 2017
New Revision: 3334
Log:
Obvious fixes for the new approach
Modified:
branches/VEX_JIT_HACKS/priv/host_x86_isel.c
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/priv/ir_opt.c
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 Tue Mar 28 09:52:20 2017
@@ -4458,7 +4458,8 @@
/* Copy BB's type env. */
/* TODO-JIT: Currently works only with no if-then-else statements. */
vassert(bb->id_seq == 1);
- env->stmts = bb->stmts;
+ env->type_env = bb->tyenv;
+ env->stmts = bb->stmts;
/* Make up an IRTemp -> virtual HReg mapping. This doesn't
change as we go along. */
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 Tue Mar 28 09:52:20 2017
@@ -3775,9 +3775,9 @@
void setIRTempDefined(IRTempDefSet* def_set, IRTemp tmp)
{
- vassert(!isIRTempDefined(def_set, tmp));
+ UInt slots_required = (tmp + sizeof(UChar)) / sizeof(UChar);
- if (tmp / sizeof(UChar) >= def_set->slots_size) {
+ if (slots_required >= def_set->slots_size) {
UChar* new_set = LibVEX_Alloc_inline(2 * def_set->slots_size);
for (UInt i = 0; i < def_set->slots_used; i++) {
new_set[i] = def_set->set[i];
@@ -3786,13 +3786,15 @@
def_set->slots_size *= 2;
}
- if (tmp / sizeof(UChar) >= def_set->slots_used) {
- for (UInt i = def_set->slots_used; i < tmp / sizeof(UChar); i++) {
+ if (slots_required > def_set->slots_used) {
+ for (UInt i = def_set->slots_used; i < slots_required; i++) {
def_set->set[i] = 0;
}
- def_set->slots_used = tmp / sizeof(UChar);
+ def_set->slots_used = slots_required;
}
+ vassert(!isIRTempDefined(def_set, tmp));
+
UInt mask = (1 << (tmp % sizeof(UChar)));
def_set->set[tmp / sizeof(UChar)] |= mask;
}
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 Tue Mar 28 09:52:20 2017
@@ -3030,6 +3030,7 @@
{
SubstEnv* env = newSubstEnv(in->tyenv, in->stmts, NULL);
IRSB* out = emptyIRSB();
+ out->tyenv = deepCopyIRTypeEnv(in->tyenv);
out->stmts = subst_and_fold_Stmts(env, in->stmts);
out->id_seq = in->id_seq;
out->next = subst_Expr( env, in->next );
|
|
From: Matthias S. <zz...@ge...> - 2017-03-28 05:46:40
|
Hi! I appreciate that my request to get rid of the compiler warning about VALGRIND_PRINTF was followed. See https://bugs.kde.org/show_bug.cgi?id=356817. But I am not so happy about the result: Now in NVALGRIND case valgrind.h uses a volatile read in VALGRIND_PRINTF and VALGRIND_PRINTF_BACKTRACE to silence the unused argument warning. http://sourceware.org/git/?p=valgrind.git;a=blob;f=include/valgrind.h;h=dc7dca7b8b0f02978dc297718d362488ebf63da2;hb=HEAD#l6772 That means if one disables all instrumentation (maybe for performance reasons) an unneeded volatile memory access remains in the code (of the client application). I vote for finding a different solution to tell the compiler to not show a warning. See https://bugs.kde.org/show_bug.cgi?id=358697 Regards Matthias |
|
From: <sv...@va...> - 2017-03-28 05:34:06
|
Author: iraisr
Date: Tue Mar 28 06:33:58 2017
New Revision: 3333
Log:
Implement the missing function in VEX/priv/ir_defs.c.
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/useful/test_main.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 Tue Mar 28 06:33:58 2017
@@ -2604,10 +2604,6 @@
IRPhiVec* deepCopyIRPhiVec(const IRPhiVec* vec)
{
- if (vec == NULL) {
- return NULL;
- }
-
IRPhiVec* vec2 = LibVEX_Alloc_inline(sizeof(IRPhiVec));
vec2->phis_used = vec2->phis_size = vec->phis_used;
IRPhi **phis2 = LibVEX_Alloc_inline(vec2->phis_used * sizeof(IRPhi*));
@@ -2617,6 +2613,19 @@
return vec2;
}
+IRTempDefSet* deepCopyIRTempDefSet(const IRTempDefSet* def_set)
+{
+ IRTempDefSet* def_set2 = LibVEX_Alloc_inline(sizeof(IRTempDefSet));
+ def_set2->slots_used = def_set->slots_used;
+ def_set2->slots_size = def_set->slots_size;
+ UChar* set2 = LibVEX_Alloc_inline(def_set2->slots_used * sizeof(UChar));
+ for (UInt i = 0; i < def_set2->slots_used; i++) {
+ set2[i] = def_set->set[i];
+ }
+ def_set2->set = set2;
+ return def_set2;
+}
+
IRStmt* deepCopyIRStmt(const IRStmt* s, IRStmtVec* parent)
{
switch (s->tag) {
Modified: branches/VEX_JIT_HACKS/useful/test_main.c
==============================================================================
--- branches/VEX_JIT_HACKS/useful/test_main.c (original)
+++ branches/VEX_JIT_HACKS/useful/test_main.c Tue Mar 28 06:33:58 2017
@@ -387,7 +387,7 @@
addr = st->Ist.STle.addr;
assert(isIRAtom(data));
assert(isIRAtom(addr));
- sz = sizeofIRType(typeOfIRExpr(bb_in->stmts, data));
+ sz = sizeofIRType(typeOfIRExpr(bb_in->tyenv, data));
needSz = False;
switch (sz) {
case 4: helper = mkIRCallee(1, "ac_helperc_STORE4",
@@ -609,13 +609,13 @@
so far exists, allocate one. */
static IRTemp findShadowTmp ( MCEnv* mce, IRTemp orig )
{
- tl_assert(orig.index < mce->n_originalTmps);
- if (isIRTempInvalid(mce->tmpMap[orig.index])) {
- mce->tmpMap[orig.index]
- = newIRTemp(mce->bb->stmts->tyenv,
- shadowType(mce->bb->stmts->tyenv->types[orig.index]));
+ tl_assert(orig < mce->n_originalTmps);
+ if (mce->tmpMap[orig] == IRTemp_INVALID) {
+ mce->tmpMap[orig]
+ = newIRTemp(mce->bb->tyenv, mce->bb->stmts,
+ shadowType(mce->bb->tyenv->types[orig]));
}
- return mce->tmpMap[orig.index];
+ return mce->tmpMap[orig];
}
/* Allocate a new shadow for the given original tmp. This means any
@@ -626,10 +626,10 @@
and use that instead. */
static void newShadowTmp ( MCEnv* mce, IRTemp orig )
{
- tl_assert(orig.index < mce->n_originalTmps);
- mce->tmpMap[orig.index]
- = newIRTemp(mce->bb->stmts->tyenv,
- shadowType(mce->bb->stmts->tyenv->types[orig.index]));
+ tl_assert(orig < mce->n_originalTmps);
+ mce->tmpMap[orig]
+ = newIRTemp(mce->bb->tyenv, mce->bb->stmts,
+ shadowType(mce->bb->tyenv->types[orig]));
}
@@ -652,7 +652,7 @@
{
if (a1->tag == Iex_Const)
return True;
- if (a1->tag == Iex_RdTmp && a1->Iex.RdTmp.tmp.index < mce->n_originalTmps)
+ if (a1->tag == Iex_RdTmp && a1->Iex.RdTmp.tmp < mce->n_originalTmps)
return True;
return False;
}
@@ -663,7 +663,7 @@
{
if (a1->tag == Iex_Const)
return True;
- if (a1->tag == Iex_RdTmp && a1->Iex.RdTmp.tmp.index >= mce->n_originalTmps)
+ if (a1->tag == Iex_RdTmp && a1->Iex.RdTmp.tmp >= mce->n_originalTmps)
return True;
return False;
}
@@ -725,12 +725,12 @@
/*------------------------------------------------------------*/
/* assign value to tmp */
-#define assign(_stmts,_tmp,_expr) \
- addStmtToIRStmtVec((_stmts), IRStmt_WrTmp((_tmp),(_expr)))
+#define assign(_bb,_tmp,_expr) \
+ addStmtToIRStmtVec((_bb->stmts), IRStmt_WrTmp((_tmp),(_expr)))
/* add stmt to a bb */
-#define stmt(_stmts,_stmt) \
- addStmtToIRStmtVec((_stmts), (_stmt))
+#define stmt(_bb,_stmt) \
+ addStmtToIRStmtVec((_bb->stmts), (_stmt))
/* build various kinds of expressions */
#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2))
@@ -746,8 +746,8 @@
temporary. This effectively converts an arbitrary expression into
an atom. */
static IRAtom* assignNew ( MCEnv* mce, IRType ty, IRExpr* e ) {
- IRTemp t = newIRTemp(mce->bb->stmts->tyenv, ty);
- assign(mce->bb->stmts, t, e);
+ IRTemp t = newIRTemp(mce->bb->tyenv, mce->bb->stmts, ty);
+ assign(mce->bb, t, e);
return mkexpr(t);
}
@@ -982,7 +982,7 @@
/* Note, dst_ty is a shadow type, not an original type. */
/* First of all, collapse vbits down to a single bit. */
tl_assert(isShadowAtom(mce,vbits));
- ty = typeOfIRExpr(mce->bb->stmts, vbits);
+ ty = typeOfIRExpr(mce->bb->tyenv, vbits);
tmp1 = NULL;
switch (ty) {
case Ity_I1:
@@ -1074,7 +1074,7 @@
tl_assert(isShadowAtom(mce, vatom));
tl_assert(sameKindedAtoms(atom, vatom));
- ty = typeOfIRExpr(mce->bb->stmts, vatom);
+ ty = typeOfIRExpr(mce->bb->tyenv, vatom);
/* sz is only used for constructing the error message */
sz = ty==Ity_I1 ? 0 : sizeofIRType(ty);
@@ -1114,7 +1114,7 @@
}
di->guard = cond;
setHelperAnns( mce, di );
- stmt( mce->bb->stmts, IRStmt_Dirty(di));
+ stmt( mce->bb, IRStmt_Dirty(di));
/* Set the shadow tmp to be defined. First, update the
orig->shadow tmp mapping to reflect the fact that this shadow is
@@ -1124,8 +1124,8 @@
if (vatom->tag == Iex_RdTmp) {
tl_assert(atom->tag == Iex_RdTmp);
newShadowTmp(mce, atom->Iex.RdTmp.tmp);
- assign(mce->bb->stmts, findShadowTmp(mce, atom->Iex.RdTmp.tmp),
- definedOfType(ty));
+ assign(mce->bb, findShadowTmp(mce, atom->Iex.RdTmp.tmp),
+ definedOfType(ty));
}
}
@@ -1184,7 +1184,7 @@
tl_assert(isShadowAtom(mce, vatom));
}
- ty = typeOfIRExpr(mce->bb->stmts, vatom);
+ ty = typeOfIRExpr(mce->bb->tyenv, vatom);
tl_assert(ty != Ity_I1);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* later: no ... */
@@ -1192,7 +1192,7 @@
/* complainIfUndefined(mce, atom); */
} else {
/* Do a plain shadow Put. */
- stmt(mce->bb->stmts, IRStmt_Put(offset + mce->layout->total_sizeB, vatom));
+ stmt( mce->bb, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ) );
}
}
@@ -1227,7 +1227,7 @@
IRRegArray* new_descr
= mkIRRegArray( descr->base + mce->layout->total_sizeB,
tyS, descr->nElems);
- stmt(mce->bb->stmts, IRStmt_PutI(mkIRPutI(new_descr, ix, bias, vatom)));
+ stmt( mce->bb, IRStmt_PutI( mkIRPutI( new_descr, ix, bias, vatom ) ));
}
}
@@ -2096,12 +2096,12 @@
/* We need to have a place to park the V bits we're just about to
read. */
- datavbits = newIRTemp(mce->bb->stmts->tyenv, ty);
+ datavbits = newIRTemp(mce->bb->tyenv, mce->bb->stmts, ty);
di = unsafeIRDirty_1_N( datavbits,
1/*regparms*/, hname, helper,
mkIRExprVec_1( addrAct ));
setHelperAnns( mce, di );
- stmt(mce->bb->stmts, IRStmt_Dirty(di));
+ stmt( mce->bb, IRStmt_Dirty(di) );
return mkexpr(datavbits);
}
@@ -2147,7 +2147,7 @@
vbitsC = expr2vbits(mce, cond);
vbits0 = expr2vbits(mce, iffalse);
vbits1 = expr2vbits(mce, iftrue);
- ty = typeOfIRExpr(mce->bb->stmts, vbits0);
+ ty = typeOfIRExpr(mce->bb->tyenv, vbits0);
return
mkUifU(mce, ty, assignNew(mce, ty, IRExpr_ITE(cond, vbits1, vbits0)),
@@ -2172,7 +2172,7 @@
return IRExpr_RdTmp( findShadowTmp(mce, e->Iex.RdTmp.tmp) );
case Iex_Const:
- return definedOfType(shadowType(typeOfIRExpr(mce->bb->stmts, e)));
+ return definedOfType(shadowType(typeOfIRExpr(mce->bb->tyenv, e)));
case Iex_Binop:
return expr2vbits_Binop(
@@ -2219,7 +2219,7 @@
/* vatom is vbits-value and as such can only have a shadow type. */
tl_assert(isShadowAtom(mce,vatom));
- ty = typeOfIRExpr(mce->bb->stmts, vatom);
+ ty = typeOfIRExpr(mce->bb->tyenv, vatom);
tyH = mce->hWordTy;
if (tyH == Ity_I32) {
@@ -2277,7 +2277,7 @@
tl_assert(isOriginalAtom(mce,addr));
tl_assert(isShadowAtom(mce,vdata));
- ty = typeOfIRExpr(mce->bb->stmts, vdata);
+ ty = typeOfIRExpr(mce->bb->tyenv, vdata);
/* First, emit a definedness test for the address. This also sets
the address (shadow) to 'defined' following the test. */
@@ -2322,8 +2322,8 @@
setHelperAnns( mce, diLo64 );
setHelperAnns( mce, diHi64 );
- stmt(mce->bb->stmts, IRStmt_Dirty(diLo64));
- stmt(mce->bb->stmts, IRStmt_Dirty(diHi64));
+ stmt( mce->bb, IRStmt_Dirty(diLo64) );
+ stmt( mce->bb, IRStmt_Dirty(diHi64) );
} else {
@@ -2350,7 +2350,7 @@
zwidenToHostWord( mce, vdata )));
}
setHelperAnns( mce, di );
- stmt(mce->bb->stmts, IRStmt_Dirty(di));
+ stmt( mce->bb, IRStmt_Dirty(di) );
}
}
@@ -2443,7 +2443,7 @@
tl_assert(d->mAddr);
complainIfUndefined(mce, d->mAddr);
- tyAddr = typeOfIRExpr(mce->bb->stmts, d->mAddr);
+ tyAddr = typeOfIRExpr(mce->bb->tyenv, d->mAddr);
tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
tl_assert(tyAddr == mce->hWordTy); /* not really right */
}
@@ -2480,10 +2480,10 @@
results to all destinations. */
/* Outputs: the destination temporary, if there is one. */
- if (!isIRTempInvalid(d->tmp)) {
+ if (d->tmp != IRTemp_INVALID) {
dst = findShadowTmp(mce, d->tmp);
- tyDst = typeOfIRTemp(mce->bb->stmts, d->tmp);
- assign(mce->bb->stmts, dst, mkPCastTo(mce, tyDst, curr));
+ tyDst = typeOfIRTemp(mce->bb->tyenv, d->tmp);
+ assign( mce->bb, dst, mkPCastTo( mce, tyDst, curr) );
}
/* Outputs: guest state that we write or modify. */
@@ -2619,25 +2619,24 @@
/* Bool hasBogusLiterals = False; */
- Int first_stmt;
MCEnv mce;
/* Set up BB */
- IRSB* bb = emptyIRSB();
- bb->id_seq = bb_in->id_seq;
- bb->stmts->tyenv = deepCopyIRTypeEnv(bb_in->stmts->tyenv);
- bb->next = deepCopyIRExpr(bb_in->next);
- bb->jumpkind = bb_in->jumpkind;
+ IRSB* bb = emptyIRSB();
+ bb->tyenv = deepCopyIRTypeEnv(bb_in->tyenv);
+ bb->id_seq = bb_in->id_seq;
+ bb->next = deepCopyIRExpr(bb_in->next);
+ bb->jumpkind = bb_in->jumpkind;
/* Set up the running environment. Only .bb is modified as we go
along. */
mce.bb = bb;
mce.layout = layout;
- mce.n_originalTmps = bb->stmts->tyenv->types_used;
+ mce.n_originalTmps = bb->tyenv->used;
mce.hWordTy = hWordTy;
mce.tmpMap = LibVEX_Alloc(mce.n_originalTmps * sizeof(IRTemp));
for (UInt i = 0; i < mce.n_originalTmps; i++)
- mce.tmpMap[i] = IRTemp_INVALID();
+ mce.tmpMap[i] = IRTemp_INVALID;
tl_assert(isFlatIRSB(bb_in));
@@ -2657,7 +2656,7 @@
}
}
*/
- first_stmt = bb->stmts->stmts_used;
+ UInt first_stmt = bb->stmts->stmts_used;
if (verboze) {
ppIRStmt(st);
@@ -2667,8 +2666,8 @@
switch (st->tag) {
case Ist_WrTmp:
- assign(bb->stmts, findShadowTmp(&mce, st->Ist.WrTmp.tmp),
- expr2vbits( &mce, st->Ist.WrTmp.data));
+ assign( bb, findShadowTmp(&mce, st->Ist.WrTmp.tmp),
+ expr2vbits( &mce, st->Ist.WrTmp.data) );
break;
case Ist_Put:
@@ -2715,7 +2714,8 @@
if (verboze) {
for (UInt j = first_stmt; j < bb->stmts->stmts_used; j++) {
- ppIRStmt_wrk(bb->stmts->stmts[j], 1);
+ VG_(printf)(" ");
+ ppIRStmt(bb->stmts->stmts[j]);
VG_(printf)("\n");
}
VG_(printf)("\n");
@@ -2726,7 +2726,7 @@
}
/* Now we need to complain if the jump target is undefined. */
- first_stmt = bb->stmts->stmts_used;
+ UInt first_stmt = bb->stmts->stmts_used;
if (verboze) {
VG_(printf)("bb->next = ");
@@ -2738,7 +2738,8 @@
if (verboze) {
for (UInt j = first_stmt; j < bb->stmts->stmts_used; j++) {
- ppIRStmt_wrk(bb->stmts->stmts[j], 1);
+ VG_(printf)(" ");
+ ppIRStmt(bb->stmts->stmts[j]);
VG_(printf)("\n");
}
VG_(printf)("\n");
|
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...
[truncated message content] |
|
From: <sv...@va...> - 2017-03-27 18:32:18
|
Author: sewardj
Date: Mon Mar 27 19:32:10 2017
New Revision: 3331
Log:
Rewrite dis_FMA so it generates not-quite-so-terrible code. It's still terrible
(breaks vectors into scalars) but this rewrite does it in a way which makes it
interact better with put-to-get forwarding. It also removes all the
Iop_Reinterp casting involved. For long sequences of FMA instructions this
reduces the amount of memcheck-generated code to about 75% of what it was
before. Improves the situation for
Bug 375839 - Temporary storage exhusted , when long sequence of vfmadd231ps instructions to be executed
but isn't a convincing fix.
Modified:
trunk/priv/guest_amd64_toIR.c
Modified: trunk/priv/guest_amd64_toIR.c
==============================================================================
--- trunk/priv/guest_amd64_toIR.c (original)
+++ trunk/priv/guest_amd64_toIR.c Mon Mar 27 19:32:10 2017
@@ -1533,11 +1533,21 @@
return IRExpr_Get( ymmGuestRegLane128offset(ymmreg,laneno), Ity_V128 );
}
+static IRExpr* getYMMRegLane64F ( UInt ymmreg, Int laneno )
+{
+ return IRExpr_Get( ymmGuestRegLane64offset(ymmreg,laneno), Ity_F64 );
+}
+
static IRExpr* getYMMRegLane64 ( UInt ymmreg, Int laneno )
{
return IRExpr_Get( ymmGuestRegLane64offset(ymmreg,laneno), Ity_I64 );
}
+static IRExpr* getYMMRegLane32F ( UInt ymmreg, Int laneno )
+{
+ return IRExpr_Get( ymmGuestRegLane32offset(ymmreg,laneno), Ity_F32 );
+}
+
static IRExpr* getYMMRegLane32 ( UInt ymmreg, Int laneno )
{
return IRExpr_Get( ymmGuestRegLane32offset(ymmreg,laneno), Ity_I32 );
@@ -27545,11 +27555,7 @@
UInt rV = getVexNvvvv(pfx);
Bool scalar = (opc & 0xF) > 7 && (opc & 1);
IRType ty = getRexW(pfx) ? Ity_F64 : Ity_F32;
- IRType vty = scalar ? ty : getVexL(pfx) ? Ity_V256 : Ity_V128;
- IRTemp vX = newTemp(vty);
- IRTemp vY = newTemp(vty);
- IRTemp vZ = newTemp(vty);
- IRExpr *x[8], *y[8], *z[8];
+ IRType vty = scalar ? ty : (getVexL(pfx) ? Ity_V256 : Ity_V128);
IRTemp addr = IRTemp_INVALID;
HChar dis_buf[50];
Int alen = 0;
@@ -27559,76 +27565,60 @@
Bool negateRes = False;
Bool negateZeven = False;
Bool negateZodd = False;
- Int i, j;
- Int count;
- static IROp ops[] = { Iop_V256to64_0, Iop_V256to64_1,
- Iop_V256to64_2, Iop_V256to64_3,
- Iop_V128to64, Iop_V128HIto64 };
+ UInt count = 0;
switch (opc & 0xF) {
- case 0x6:
- name = "addsub";
- negateZeven = True;
- break;
- case 0x7:
- name = "subadd";
- negateZodd = True;
- break;
- case 0x8:
- case 0x9:
- name = "add";
- break;
- case 0xA:
- case 0xB:
- name = "sub";
- negateZeven = True;
- negateZodd = True;
- break;
- case 0xC:
- case 0xD:
- name = "add";
- negateRes = True;
- negateZeven = True;
- negateZodd = True;
- break;
- case 0xE:
- case 0xF:
- name = "sub";
- negateRes = True;
- break;
- default:
- vpanic("dis_FMA(amd64)");
- break;
+ case 0x6: name = "addsub"; negateZeven = True; break;
+ case 0x7: name = "subadd"; negateZodd = True; break;
+ case 0x8:
+ case 0x9: name = "add"; break;
+ case 0xA:
+ case 0xB: name = "sub"; negateZeven = True; negateZodd = True;
+ break;
+ case 0xC:
+ case 0xD: name = "add"; negateRes = True; negateZeven = True;
+ negateZodd = True; break;
+ case 0xE:
+ case 0xF: name = "sub"; negateRes = True; break;
+ default: vpanic("dis_FMA(amd64)"); break;
}
switch (opc & 0xF0) {
- case 0x90: order = "132"; break;
- case 0xA0: order = "213"; break;
- case 0xB0: order = "231"; break;
- default: vpanic("dis_FMA(amd64)"); break;
+ case 0x90: order = "132"; break;
+ case 0xA0: order = "213"; break;
+ case 0xB0: order = "231"; break;
+ default: vpanic("dis_FMA(amd64)"); break;
}
- if (scalar)
+ if (scalar) {
suffix = ty == Ity_F64 ? "sd" : "ss";
- else
+ } else {
suffix = ty == Ity_F64 ? "pd" : "ps";
+ }
- if (scalar) {
- assign( vX, ty == Ity_F64
- ? getXMMRegLane64F(rG, 0) : getXMMRegLane32F(rG, 0) );
- assign( vZ, ty == Ity_F64
- ? getXMMRegLane64F(rV, 0) : getXMMRegLane32F(rV, 0) );
- } else {
- assign( vX, vty == Ity_V256 ? getYMMReg(rG) : getXMMReg(rG) );
- assign( vZ, vty == Ity_V256 ? getYMMReg(rV) : getXMMReg(rV) );
+ // Figure out |count| (the number of elements) by considering |vty| and |ty|.
+ count = sizeofIRType(vty) / sizeofIRType(ty);
+ vassert(count == 1 || count == 2 || count == 4 || count == 8);
+
+ // Fetch operands into the first |count| elements of |sX|, |sY| and |sZ|.
+ UInt i;
+ IRExpr *sX[8], *sY[8], *sZ[8], *res[8];
+ for (i = 0; i < 8; i++) sX[i] = sY[i] = sZ[i] = res[i] = NULL;
+
+ IRExpr* (*getYMMRegLane)(UInt,Int)
+ = ty == Ity_F32 ? getYMMRegLane32F : getYMMRegLane64F;
+ void (*putYMMRegLane)(UInt,Int,IRExpr*)
+ = ty == Ity_F32 ? putYMMRegLane32F : putYMMRegLane64F;
+
+ for (i = 0; i < count; i++) {
+ sX[i] = getYMMRegLane(rG, i);
+ sZ[i] = getYMMRegLane(rV, i);
}
if (epartIsReg(modrm)) {
UInt rE = eregOfRexRM(pfx, modrm);
delta += 1;
- if (scalar)
- assign( vY, ty == Ity_F64
- ? getXMMRegLane64F(rE, 0) : getXMMRegLane32F(rE, 0) );
- else
- assign( vY, vty == Ity_V256 ? getYMMReg(rE) : getXMMReg(rE) );
+ for (i = 0; i < count; i++) {
+ sY[i] = getYMMRegLane(rE, i);
+ }
if (vty == Ity_V256) {
DIP("vf%sm%s%s%s %s,%s,%s\n", negateRes ? "n" : "",
name, order, suffix, nameYMMReg(rE), nameYMMReg(rV),
@@ -27641,7 +27631,10 @@
} else {
addr = disAMode( &alen, vbi, pfx, delta, dis_buf, 0 );
delta += alen;
- assign(vY, loadLE(vty, mkexpr(addr)));
+ for (i = 0; i < count; i++) {
+ sY[i] = loadLE(ty, binop(Iop_Add64, mkexpr(addr),
+ mkU64(i * sizeofIRType(ty))));
+ }
if (vty == Ity_V256) {
DIP("vf%sm%s%s%s %s,%s,%s\n", negateRes ? "n" : "",
name, order, suffix, dis_buf, nameYMMReg(rV),
@@ -27653,73 +27646,50 @@
}
}
- /* vX/vY/vZ now in 132 order. If it is different order, swap the
- arguments. */
+ /* vX/vY/vZ are now in 132 order. If the instruction requires a different
+ order, swap them around. */
+
+# define COPY_ARR(_dst, _src) \
+ do { for (int j = 0; j < 8; j++) { _dst[j] = _src[j]; } } while (0)
+
if ((opc & 0xF0) != 0x90) {
- IRTemp tem = vX;
+ IRExpr* temp[8];
+ COPY_ARR(temp, sX);
if ((opc & 0xF0) == 0xA0) {
- vX = vZ;
- vZ = vY;
- vY = tem;
+ COPY_ARR(sX, sZ);
+ COPY_ARR(sZ, sY);
+ COPY_ARR(sY, temp);
} else {
- vX = vZ;
- vZ = tem;
+ COPY_ARR(sX, sZ);
+ COPY_ARR(sZ, temp);
}
}
- if (scalar) {
- count = 1;
- x[0] = mkexpr(vX);
- y[0] = mkexpr(vY);
- z[0] = mkexpr(vZ);
- } else if (ty == Ity_F32) {
- count = vty == Ity_V256 ? 8 : 4;
- j = vty == Ity_V256 ? 0 : 4;
- for (i = 0; i < count; i += 2) {
- IRTemp tem = newTemp(Ity_I64);
- assign(tem, unop(ops[i / 2 + j], mkexpr(vX)));
- x[i] = unop(Iop_64to32, mkexpr(tem));
- x[i + 1] = unop(Iop_64HIto32, mkexpr(tem));
- tem = newTemp(Ity_I64);
- assign(tem, unop(ops[i / 2 + j], mkexpr(vY)));
- y[i] = unop(Iop_64to32, mkexpr(tem));
- y[i + 1] = unop(Iop_64HIto32, mkexpr(tem));
- tem = newTemp(Ity_I64);
- assign(tem, unop(ops[i / 2 + j], mkexpr(vZ)));
- z[i] = unop(Iop_64to32, mkexpr(tem));
- z[i + 1] = unop(Iop_64HIto32, mkexpr(tem));
- }
- } else {
- count = vty == Ity_V256 ? 4 : 2;
- j = vty == Ity_V256 ? 0 : 4;
- for (i = 0; i < count; i++) {
- x[i] = unop(ops[i + j], mkexpr(vX));
- y[i] = unop(ops[i + j], mkexpr(vY));
- z[i] = unop(ops[i + j], mkexpr(vZ));
+# undef COPY_ARR
+
+ for (i = 0; i < count; i++) {
+ IROp opNEG = ty == Ity_F64 ? Iop_NegF64 : Iop_NegF32;
+ if ((i & 1) ? negateZodd : negateZeven) {
+ sZ[i] = unop(opNEG, sZ[i]);
+ }
+ res[i] = IRExpr_Qop(ty == Ity_F64 ? Iop_MAddF64 : Iop_MAddF32,
+ get_FAKE_roundingmode(), sX[i], sY[i], sZ[i]);
+ if (negateRes) {
+ res[i] = unop(opNEG, res[i]);
}
}
- if (!scalar)
- for (i = 0; i < count; i++) {
- IROp op = ty == Ity_F64
- ? Iop_ReinterpI64asF64 : Iop_ReinterpI32asF32;
- x[i] = unop(op, x[i]);
- y[i] = unop(op, y[i]);
- z[i] = unop(op, z[i]);
- }
+
for (i = 0; i < count; i++) {
- if ((i & 1) ? negateZodd : negateZeven)
- z[i] = unop(ty == Ity_F64 ? Iop_NegF64 : Iop_NegF32, z[i]);
- x[i] = IRExpr_Qop(ty == Ity_F64 ? Iop_MAddF64 : Iop_MAddF32,
- get_FAKE_roundingmode(), x[i], y[i], z[i]);
- if (negateRes)
- x[i] = unop(ty == Ity_F64 ? Iop_NegF64 : Iop_NegF32, x[i]);
- if (ty == Ity_F64)
- putYMMRegLane64F( rG, i, x[i] );
- else
- putYMMRegLane32F( rG, i, x[i] );
+ putYMMRegLane(rG, i, res[i]);
+ }
+
+ switch (vty) {
+ case Ity_F32: putYMMRegLane32(rG, 1, mkU32(0)); /*fallthru*/
+ case Ity_F64: putYMMRegLane64(rG, 1, mkU64(0)); /*fallthru*/
+ case Ity_V128: putYMMRegLane128(rG, 1, mkV128(0)); /*fallthru*/
+ case Ity_V256: break;
+ default: vassert(0);
}
- if (vty != Ity_V256)
- putYMMRegLane128( rG, 1, mkV128(0) );
return delta;
}
|
|
From: <sv...@va...> - 2017-03-27 05:07:00
|
Author: iraisr
Date: Mon Mar 27 06:06:32 2017
New Revision: 16287
Log:
fcntl syscall wrapper was missing flock structure check on Linux.
Fixes BZ#377930.
Modified:
trunk/NEWS
trunk/coregrind/m_syswrap/syswrap-linux.c
trunk/include/vki/vki-linux.h
trunk/memcheck/tests/arm64-linux/scalar.c
trunk/memcheck/tests/arm64-linux/scalar.stderr.exp
trunk/memcheck/tests/x86-linux/scalar.c
trunk/memcheck/tests/x86-linux/scalar.stderr.exp
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Mon Mar 27 06:06:32 2017
@@ -151,6 +151,7 @@
and FUTEX_WAKE_BITSET, check only 4 args for FUTEX_WAKE_BITSET,
and 2 args for FUTEX_TRYLOCK_PI
377717 Fix massive space leak when reading compressed debuginfo sections
+377930 fcntl syscall wrapper is missing flock structure check
Release 3.12.0 (20 October 2016)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Mon Mar 27 06:06:32 2017
@@ -5898,19 +5898,45 @@
case VKI_F_GETLK:
case VKI_F_SETLK:
case VKI_F_SETLKW:
+ case VKI_F_OFD_GETLK:
+ case VKI_F_OFD_SETLK:
+ case VKI_F_OFD_SETLKW:
+ PRINT("sys_fcntl[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "fcntl",
+ unsigned int, fd, unsigned int, cmd,
+ struct vki_flock *, lock);
+ {
+ struct vki_flock *lock = (struct vki_flock *) ARG3;
+ PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
+ PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
+ PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
+ PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
+ if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
+ PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
+ }
+ }
+ break;
+
# if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
case VKI_F_GETLK64:
case VKI_F_SETLK64:
case VKI_F_SETLKW64:
-# endif
- case VKI_F_OFD_GETLK:
- case VKI_F_OFD_SETLK:
- case VKI_F_OFD_SETLKW:
PRINT("sys_fcntl[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
PRE_REG_READ3(long, "fcntl",
unsigned int, fd, unsigned int, cmd,
struct flock64 *, lock);
+ {
+ struct vki_flock64 *lock = (struct vki_flock64 *) ARG3;
+ PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
+ PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
+ PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
+ PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
+ if (ARG2 == VKI_F_GETLK64) {
+ PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
+ }
+ }
break;
+# endif
case VKI_F_SETOWN_EX:
PRINT("sys_fcntl[F_SETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
@@ -5965,6 +5991,14 @@
}
} else if (ARG2 == VKI_F_GETOWN_EX) {
POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
+ } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
+ struct vki_flock *lock = (struct vki_flock *) ARG3;
+ POST_FIELD_WRITE(lock->l_pid);
+# if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
+ } else if (ARG2 == VKI_F_GETLK64) {
+ struct vki_flock64 *lock = (struct vki_flock64 *) ARG3;
+ PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
+# endif
}
}
Modified: trunk/include/vki/vki-linux.h
==============================================================================
--- trunk/include/vki/vki-linux.h (original)
+++ trunk/include/vki/vki-linux.h Mon Mar 27 06:06:32 2017
@@ -1416,6 +1416,22 @@
#define VKI_F_SETPIPE_SZ (VKI_F_LINUX_SPECIFIC_BASE + 7)
#define VKI_F_GETPIPE_SZ (VKI_F_LINUX_SPECIFIC_BASE + 8)
+struct vki_flock {
+ short l_type;
+ short l_whence;
+ __vki_kernel_off_t l_start;
+ __vki_kernel_off_t l_len;
+ __vki_kernel_pid_t l_pid;
+};
+
+struct vki_flock64 {
+ short l_type;
+ short l_whence;
+ __vki_kernel_loff_t l_start;
+ __vki_kernel_loff_t l_len;
+ __vki_kernel_pid_t l_pid;
+};
+
//----------------------------------------------------------------------
// From linux-2.6.8.1/include/linux/sysctl.h
//----------------------------------------------------------------------
Modified: trunk/memcheck/tests/arm64-linux/scalar.c
==============================================================================
--- trunk/memcheck/tests/arm64-linux/scalar.c (original)
+++ trunk/memcheck/tests/arm64-linux/scalar.c Mon Mar 27 06:06:32 2017
@@ -279,7 +279,7 @@
// For F_GETLK the 3rd arg is 'lock'. On x86, this fails w/EBADF. But
// on amd64 in 32-bit mode it fails w/EFAULT. We don't check the 1st two
// args for the reason given above.
- GO(__NR_fcntl, "(GETLK) 1s 0m");
+ GO(__NR_fcntl, "(GETLK) 1s 5m");
SY(__NR_fcntl, -1, F_GETLK, x0); FAIL; //FAILx(EBADF);
// __NR_mpx arm64 doesn't implement mpx
Modified: trunk/memcheck/tests/arm64-linux/scalar.stderr.exp
==============================================================================
--- trunk/memcheck/tests/arm64-linux/scalar.stderr.exp (original)
+++ trunk/memcheck/tests/arm64-linux/scalar.stderr.exp Mon Mar 27 06:06:32 2017
@@ -271,12 +271,37 @@
by 0x........: main (scalar.c:277)
-----------------------------------------------------
- 25: __NR_fcntl (GETLK) 1s 0m
+ 25: __NR_fcntl (GETLK) 1s 5m
-----------------------------------------------------
Syscall param fcntl(lock) contains uninitialised byte(s)
...
by 0x........: main (scalar.c:283)
+Syscall param fcntl(lock->l_type) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param fcntl(lock->l_whence) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param fcntl(lock->l_start) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param fcntl(lock->l_len) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param fcntl(lock->l_pid) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
-----------------------------------------------------
154: __NR_setpgid 2s 0m
-----------------------------------------------------
@@ -555,6 +580,9 @@
...
by 0x........: main (scalar.c:458)
+
+More than 100 errors detected. Subsequent errors
+will still be recorded, but in less detail than before.
Syscall param setpriority(who) contains uninitialised byte(s)
...
by 0x........: main (scalar.c:458)
@@ -579,9 +607,6 @@
by 0x........: main (scalar.c:466)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-
-More than 100 errors detected. Subsequent errors
-will still be recorded, but in less detail than before.
Syscall param statfs(buf) points to unaddressable byte(s)
...
by 0x........: main (scalar.c:466)
Modified: trunk/memcheck/tests/x86-linux/scalar.c
==============================================================================
--- trunk/memcheck/tests/x86-linux/scalar.c (original)
+++ trunk/memcheck/tests/x86-linux/scalar.c Mon Mar 27 06:06:32 2017
@@ -279,7 +279,7 @@
// For F_GETLK the 3rd arg is 'lock'. On x86, this fails w/EBADF. But
// on amd64 in 32-bit mode it fails w/EFAULT. We don't check the 1st two
// args for the reason given above.
- GO(__NR_fcntl, "(GETLK) 1s 0m");
+ GO(__NR_fcntl, "(GETLK) 1s 5m");
SY(__NR_fcntl, -1, F_GETLK, x0); FAIL; //FAILx(EBADF);
// __NR_mpx 56
Modified: trunk/memcheck/tests/x86-linux/scalar.stderr.exp
==============================================================================
--- trunk/memcheck/tests/x86-linux/scalar.stderr.exp (original)
+++ trunk/memcheck/tests/x86-linux/scalar.stderr.exp Mon Mar 27 06:06:32 2017
@@ -598,21 +598,46 @@
by 0x........: main (scalar.c:277)
-----------------------------------------------------
- 55: __NR_fcntl (GETLK) 1s 0m
+ 55: __NR_fcntl (GETLK) 1s 5m
-----------------------------------------------------
Syscall param fcntl(lock) contains uninitialised byte(s)
...
by 0x........: main (scalar.c:283)
+
+More than 100 errors detected. Subsequent errors
+will still be recorded, but in less detail than before.
+Syscall param fcntl(lock->l_type) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param fcntl(lock->l_whence) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param fcntl(lock->l_start) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param fcntl(lock->l_len) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param fcntl(lock->l_pid) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:283)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
-----------------------------------------------------
56: __NR_mpx ni
-----------------------------------------------------
-----------------------------------------------------
57: __NR_setpgid 2s 0m
-----------------------------------------------------
-
-More than 100 errors detected. Subsequent errors
-will still be recorded, but in less detail than before.
Syscall param setpgid(pid) contains uninitialised byte(s)
...
by 0x........: main (scalar.c:291)
|
|
From: <sv...@va...> - 2017-03-25 08:02:45
|
Author: iraisr
Date: Sat Mar 25 08:02:31 2017
New Revision: 3330
Log:
Rework the VEX IR interface a bit.
Previous iteration had a design flaw which would make
certain transformations too expensive (lifting a leg of
"if-then-else" in case of constant condition).
Now we have a single global IRTypeEnv. Every IRStmtVec
has an IRTempDefSet which keeps track of IRTemp's defined
there.
So far these two files have been fitted. More will follow.
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 Sat Mar 25 08:02:31 2017
@@ -113,10 +113,10 @@
void ppIRTemp ( IRTemp tmp )
{
- if (isIRTempInvalid(tmp))
+ if (tmp == IRTemp_INVALID)
vex_printf("IRTemp_INVALID");
else
- vex_printf("t%u:%u", tmp.id, tmp.index);
+ vex_printf("t%u", tmp);
}
void ppIROp ( IROp op )
@@ -1411,7 +1411,7 @@
void ppIRDirty ( const IRDirty* d )
{
Int i;
- if (!isIRTempInvalid(d->tmp)) {
+ if (d->tmp != IRTemp_INVALID) {
ppIRTemp(d->tmp);
vex_printf(" = ");
}
@@ -1453,7 +1453,7 @@
{
/* Print even structurally invalid constructions, as an aid to
debugging. */
- if (!isIRTempInvalid(cas->oldHi)) {
+ if (cas->oldHi != IRTemp_INVALID) {
ppIRTemp(cas->oldHi);
vex_printf(",");
}
@@ -1599,6 +1599,39 @@
ppIRPhiVec_wrk(phis, 0);
}
+static void ppIRTempDefSet_wrk(const IRTempDefSet* defd, UInt depth)
+{
+ UInt tmps_printed = 0;
+
+ for (UInt slot = 0; slot < defd->slots_used; slot++) {
+ UChar slot_value = defd->set[slot];
+ for (UInt bit = 0; bit < sizeof(UChar); bit++) {
+ if (slot_value & (1 << bit)) {
+ if (tmps_printed % 8 == 0)
+ print_depth(depth);
+
+ IRTemp tmp = slot * sizeof(UChar) + bit;
+ ppIRTemp(tmp);
+
+ if (tmps_printed % 8 == 7)
+ vex_printf("\n");
+ else
+ vex_printf(" ");
+
+ tmps_printed += 1;
+ }
+ }
+ }
+
+ if (tmps_printed > 0 && tmps_printed % 8 != 7)
+ vex_printf("\n");
+}
+
+void ppIRTempDefSet(const IRTempDefSet* defd)
+{
+ ppIRTempDefSet_wrk(defd, 0);
+}
+
void ppIRStmt_wrk(const IRStmt* s, UInt depth)
{
print_depth(depth);
@@ -1705,32 +1738,26 @@
ppIRStmt_wrk(s, 0);
}
-static void ppIRTypeEnv_wrk(const IRTypeEnv* env, UInt depth)
+void ppIRTypeEnv(const IRTypeEnv* env)
{
- for (UInt i = 0; i < env->types_used; i++) {
+ for (UInt i = 0; i < env->used; i++) {
if (i % 8 == 0)
- print_depth(depth);
- IRTemp temp = mkIRTemp(env->id, i);
- ppIRTemp(temp);
- vex_printf("=");
+ print_depth(1);
+ ppIRTemp(i);
+ vex_printf(":%u=", env->ids[i]);
ppIRType(env->types[i]);
if (i % 8 == 7)
vex_printf( "\n");
else
vex_printf( " ");
}
- if (env->types_used > 0 && env->types_used % 8 != 7)
+ if (env->used > 0 && env->used % 8 != 7)
vex_printf( "\n");
}
-void ppIRTypeEnv(const IRTypeEnv* env)
-{
- ppIRTypeEnv_wrk(env, 0);
-}
-
void ppIRStmtVec_wrk(const IRStmtVec* stmts, UInt depth)
{
- ppIRTypeEnv_wrk(stmts->tyenv, depth);
+ ppIRTempDefSet_wrk(stmts->def_set, depth);
vex_printf("\n");
for (UInt i = 0; i < stmts->stmts_used; i++) {
ppIRStmt_wrk(stmts->stmts[i], depth);
@@ -1748,6 +1775,7 @@
UInt depth = 0;
vex_printf("IRSB {\n");
+ ppIRTypeEnv(bb->tyenv);
ppIRStmtVec_wrk(bb->stmts, depth + 1);
print_depth(depth + 1);
vex_printf("PUT(%d) = ", bb->offsIP);
@@ -2123,16 +2151,15 @@
/* Constructors -- IRDirty */
IRDirty* emptyIRDirty ( void ) {
- IRDirty* d = LibVEX_Alloc_inline(sizeof(IRDirty));
- d->cee = NULL;
- d->guard = NULL;
- d->args = NULL;
- d->tmp.id = IRTyEnvID_INVALID;
- d->tmp.index = IRTyEnvIndex_INVALID;
- d->mFx = Ifx_None;
- d->mAddr = NULL;
- d->mSize = 0;
- d->nFxState = 0;
+ IRDirty* d = LibVEX_Alloc_inline(sizeof(IRDirty));
+ d->cee = NULL;
+ d->guard = NULL;
+ d->args = NULL;
+ d->tmp = IRTemp_INVALID;
+ d->mFx = Ifx_None;
+ d->mAddr = NULL;
+ d->mSize = 0;
+ d->nFxState = 0;
return d;
}
@@ -2217,6 +2244,16 @@
return vec;
}
+IRTempDefSet* emptyIRTempDefSet(void)
+{
+ IRTempDefSet* defset = LibVEX_Alloc_inline(sizeof(IRTempDefSet));
+ defset->slots_used = 0;
+ defset->slots_size = 8 / sizeof(UChar);
+ vassert(defset->slots_size >= 1);
+ defset->set = LibVEX_Alloc_inline(defset->slots_size * sizeof(UChar));
+ return defset;
+}
+
IRStmt* IRStmt_NoOp ( void )
{
/* Just use a single static closure. */
@@ -2340,13 +2377,13 @@
/* Constructors -- IRTypeEnv */
-IRTypeEnv* emptyIRTypeEnv ( void )
+static IRTypeEnv* emptyIRTypeEnv ( void )
{
IRTypeEnv* env = LibVEX_Alloc_inline(sizeof(IRTypeEnv));
env->types = LibVEX_Alloc_inline(8 * sizeof(IRType));
- env->types_size = 8;
- env->types_used = 0;
- env->id = IRTyEnvID_INVALID;
+ env->ids = LibVEX_Alloc_inline(8 * sizeof(IRStmtVecID));
+ env->size = 8;
+ env->used = 0;
return env;
}
@@ -2356,11 +2393,12 @@
IRStmtVec* emptyIRStmtVec(void)
{
IRStmtVec* stmts = LibVEX_Alloc_inline(sizeof(IRStmtVec));
- stmts->tyenv = emptyIRTypeEnv();
stmts->stmts_used = 0;
stmts->stmts_size = 8;
stmts->stmts = LibVEX_Alloc_inline(stmts->stmts_size * sizeof(IRStmt*));
+ stmts->id = IRStmtVecID_INVALID;
stmts->parent = NULL;
+ stmts->def_set = emptyIRTempDefSet();
return stmts;
}
@@ -2370,21 +2408,22 @@
IRSB* emptyIRSB ( void )
{
IRSB* bb = LibVEX_Alloc_inline(sizeof(IRSB));
+ bb->tyenv = emptyIRTypeEnv();
bb->stmts = emptyIRStmtVec();
bb->id_seq = 0;
bb->next = NULL;
bb->jumpkind = Ijk_Boring;
bb->offsIP = 0;
- bb->stmts->tyenv->id = nextIRTyEnvID(bb);
+ bb->stmts->id = nextIRStmtVecID(bb);
return bb;
}
-IRTyEnvID nextIRTyEnvID(IRSB* irsb)
+IRStmtVecID nextIRStmtVecID(IRSB* irsb)
{
- IRTyEnvID next = irsb->id_seq;
+ IRStmtVecID next = irsb->id_seq;
irsb->id_seq += 1;
- vassert(irsb->id_seq < IRTyEnvID_INVALID);
+ vassert(irsb->id_seq < IRStmtVecID_INVALID);
return next;
}
@@ -2648,8 +2687,9 @@
IRStmtVec* deepCopyIRStmtVec(const IRStmtVec* src, IRStmtVec* parent)
{
IRStmtVec* vec2 = LibVEX_Alloc_inline(sizeof(IRStmtVec));
- vec2->tyenv = deepCopyIRTypeEnv(src->tyenv);
+ vec2->id = src->id;
vec2->parent = parent;
+ vec2->def_set = deepCopyIRTempDefSet(src->def_set);
vec2->stmts_used = vec2->stmts_size = src->stmts_used;
IRStmt **stmts2 = LibVEX_Alloc_inline(vec2->stmts_used * sizeof(IRStmt*));
for (UInt i = 0; i < vec2->stmts_used; i++) {
@@ -2661,33 +2701,33 @@
IRTypeEnv* deepCopyIRTypeEnv(const IRTypeEnv* src)
{
- IRTypeEnv* dst = LibVEX_Alloc_inline(sizeof(IRTypeEnv));
- dst->types_size = src->types_size;
- dst->types_used = src->types_used;
- dst->types = LibVEX_Alloc_inline(dst->types_size * sizeof(IRType));
- for (UInt i = 0; i < src->types_used; i++)
+ IRTypeEnv* dst = LibVEX_Alloc_inline(sizeof(IRTypeEnv));
+ dst->size = src->size;
+ dst->used = src->used;
+ dst->types = LibVEX_Alloc_inline(dst->size * sizeof(IRType));
+ dst->ids = LibVEX_Alloc_inline(dst->size * sizeof(IRStmtVecID));
+ for (UInt i = 0; i < src->used; i++) {
dst->types[i] = src->types[i];
- dst->id = src->id;
+ dst->ids[i] = src->ids[i];
+ }
return dst;
}
IRSB* deepCopyIRSB ( const IRSB* bb )
{
IRSB* bb2 = deepCopyIRSBExceptStmts(bb);
- // TODO-JIT: does a deep copy of bb->stmts->tyenv once more
bb2->stmts = deepCopyIRStmtVec(bb->stmts, NULL);
return bb2;
}
IRSB* deepCopyIRSBExceptStmts ( const IRSB* bb )
{
- IRSB* bb2 = emptyIRSB();
- bb2->stmts = emptyIRStmtVec();
- bb2->stmts->tyenv = deepCopyIRTypeEnv(bb->stmts->tyenv);
- bb2->id_seq = bb->id_seq;
- bb2->next = deepCopyIRExpr(bb->next);
- bb2->jumpkind = bb->jumpkind;
- bb2->offsIP = bb->offsIP;
+ IRSB* bb2 = emptyIRSB();
+ bb2->tyenv = deepCopyIRTypeEnv(bb->tyenv);
+ bb2->id_seq = bb->id_seq;
+ bb2->next = deepCopyIRExpr(bb->next);
+ bb2->jumpkind = bb->jumpkind;
+ bb2->offsIP = bb->offsIP;
return bb2;
}
@@ -3721,6 +3761,34 @@
/*---------------------------------------------------------------*/
+/*--- Helper functions for the IR -- IR Temp Defined Set ---*/
+/*---------------------------------------------------------------*/
+
+void setIRTempDefined(IRTempDefSet* def_set, IRTemp tmp)
+{
+ vassert(!isIRTempDefined(def_set, tmp));
+
+ if (tmp / sizeof(UChar) >= def_set->slots_size) {
+ UChar* new_set = LibVEX_Alloc_inline(2 * def_set->slots_size);
+ for (UInt i = 0; i < def_set->slots_used; i++) {
+ new_set[i] = def_set->set[i];
+ }
+ def_set->set = new_set;
+ def_set->slots_size *= 2;
+ }
+
+ if (tmp / sizeof(UChar) >= def_set->slots_used) {
+ for (UInt i = def_set->slots_used; i < tmp / sizeof(UChar); i++) {
+ def_set->set[i] = 0;
+ }
+ def_set->slots_used = tmp / sizeof(UChar);
+ }
+
+ UInt mask = (1 << (tmp % sizeof(UChar)));
+ def_set->set[tmp / sizeof(UChar)] |= mask;
+}
+
+/*---------------------------------------------------------------*/
/*--- Helper functions for the IR -- IR Basic Blocks ---*/
/*---------------------------------------------------------------*/
@@ -3747,11 +3815,11 @@
IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond)
{
IRStmtVec* then_leg = emptyIRStmtVec();
- then_leg->tyenv->id = nextIRTyEnvID(bb);
+ then_leg->id = nextIRStmtVecID(bb);
then_leg->parent = parent;
IRStmtVec* else_leg = emptyIRStmtVec();
- else_leg->tyenv->id = nextIRTyEnvID(bb);
+ else_leg->id = nextIRStmtVecID(bb);
else_leg->parent = parent;
IRStmt* st = IRStmt_IfThenElse(cond, then_leg, else_leg, emptyIRPhiVec());
@@ -3763,30 +3831,33 @@
/*--- Helper functions for the IR -- IR Type Environments ---*/
/*---------------------------------------------------------------*/
-/* Allocate a new IRTemp, given its type. */
-
-IRTemp newIRTemp ( IRTypeEnv* env, IRType ty )
+IRTemp newIRTemp(IRTypeEnv* env, IRStmtVec* stmts, IRType ty)
{
- vassert(env);
- vassert(env->types_used >= 0);
- vassert(env->types_size >= 0);
- vassert(env->types_used <= env->types_size);
- vassert(env->id != IRTyEnvID_INVALID);
-
- if (env->types_used < env->types_size) {
- env->types[env->types_used] = ty;
- return mkIRTemp(env->id, env->types_used++);
- } else {
- Int i;
- Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
- IRType* new_types
- = LibVEX_Alloc_inline(new_size * sizeof(IRType));
- for (i = 0; i < env->types_used; i++)
+ 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;
+ 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++) {
new_types[i] = env->types[i];
- env->types = new_types;
- env->types_size = new_size;
- return newIRTemp(env, ty);
+ new_ids[i] = env->ids[i];
+ }
+ env->types = new_types;
+ env->ids = new_ids;
+ env->size = new_size;
}
+
+ IRTemp tmp = env->used;
+ env->used += 1;
+ env->types[tmp] = ty;
+ env->ids[tmp] = stmts->id;
+ setIRTempDefined(stmts->def_set, tmp);
+ return tmp;
}
@@ -3795,19 +3866,11 @@
/*---------------------------------------------------------------*/
inline
-IRType typeOfIRTemp(const IRStmtVec* stmts, IRTemp tmp)
+IRType typeOfIRTemp ( const IRTypeEnv* env, IRTemp tmp )
{
- const IRTypeEnv* tyenv = stmts->tyenv;
- while (tyenv->id != tmp.id) {
- stmts = stmts->parent;
- vassert(stmts != NULL);
- tyenv = stmts->tyenv;
- }
-
- vassert(tyenv->id == tmp.id);
- vassert(tmp.index >= 0);
- vassert(tmp.index < tyenv->types_used);
- return tyenv->types[tmp.index];
+ vassert(tmp >= 0);
+ vassert(tmp < env->used);
+ return env->types[tmp];
}
IRType typeOfIRConst ( const IRConst* con )
@@ -3847,7 +3910,7 @@
}
}
-IRType typeOfIRExpr ( const IRStmtVec* stmts, const IRExpr* e )
+IRType typeOfIRExpr ( const IRTypeEnv* tyenv, const IRExpr* e )
{
IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
start:
@@ -3859,7 +3922,7 @@
case Iex_GetI:
return e->Iex.GetI.descr->elemTy;
case Iex_RdTmp:
- return typeOfIRTemp(stmts, e->Iex.RdTmp.tmp);
+ return typeOfIRTemp(tyenv, e->Iex.RdTmp.tmp);
case Iex_Const:
return typeOfIRConst(e->Iex.Const.con);
case Iex_Qop:
@@ -3883,7 +3946,7 @@
case Iex_ITE:
e = e->Iex.ITE.iffalse;
goto start;
- /* return typeOfIRExpr(stmts, e->Iex.ITE.iffalse); */
+ /* return typeOfIRExpr(tyenv, e->Iex.ITE.iffalse); */
case Iex_Binder:
vpanic("typeOfIRExpr: Binder is not a valid expression");
case Iex_VECRET:
@@ -4074,10 +4137,10 @@
bit expression, depending on the guest's word size.
Each temp is assigned only once, before its uses.
- Each temp is referenced from the right scope.
+ Each temp assigned and referenced is in scope.
Phi functions refer to existing, already assigned temporaries from
- [parent, then leg, else leg] type environments.
+ [parent, then leg, else leg].
*/
static inline Int countArgs ( IRExpr** args )
@@ -4141,62 +4204,60 @@
def_count is zero. Report any which are assigned more than once or assigned
after being used. */
-static Bool inRangeIRTemp(const IRStmtVec* stmts, IRTemp tmp)
+static Bool inRangeIRTemp(const IRTypeEnv* tyenv, IRTemp tmp)
{
- vassert(tmp.id != IRTyEnvID_INVALID);
-
- if (tmp.index >= 0 || tmp.index < stmts->tyenv->types_used) {
+ if (tmp >= 0 || tmp < tyenv->used) {
return True;
}
return False;
}
-static Bool inScopeIRTemp(const IRStmtVec* stmts, IRTemp tmp)
+static Bool inScopeIRTemp(const IRTypeEnv* tyenv, const IRStmtVec* stmts,
+ IRTemp tmp)
{
- vassert(tmp.id != IRTyEnvID_INVALID);
+ IRStmtVecID id = tyenv->ids[tmp];
+ vassert(id != IRStmtVecID_INVALID);
- const IRTypeEnv* tyenv = stmts->tyenv;
- while (tyenv->id != tmp.id) {
+ while (!(isIRTempDefined(stmts->def_set, tmp))) {
stmts = stmts->parent;
if (stmts == NULL)
return False;
- tyenv = stmts->tyenv;
}
- vassert(tyenv->id == tmp.id);
return True;
}
static
void useBeforeDef_Temp(const IRSB* bb, const IRStmtVec* stmts,
- const IRStmt* stmt, IRTemp tmp, UInt* def_counts[])
+ const IRStmt* stmt, IRTemp tmp, UInt def_counts[])
{
- vassert(tmp.id != IRTyEnvID_INVALID);
+ const IRTypeEnv* tyenv = bb->tyenv;
- if (!inRangeIRTemp(stmts, tmp))
+ if (!inRangeIRTemp(tyenv, tmp))
sanityCheckFail(bb, stmt, "out of range Temp in IRExpr");
- if (!inScopeIRTemp(stmts, tmp))
+ if (!inScopeIRTemp(tyenv, stmts, tmp))
sanityCheckFail(bb, stmt, "out of scope Temp in IRExpr");
- if (def_counts[tmp.id][tmp.index] < 1)
+
+ if (def_counts[tmp] < 1)
sanityCheckFail(bb, stmt, "IRTemp use before def in IRExpr");
}
static
void assignedOnce_Temp(const IRSB* bb, const IRStmtVec* stmts,
- const IRStmt* stmt, IRTemp tmp, UInt* def_counts[],
+ const IRStmt* stmt, IRTemp tmp, UInt def_counts[],
const HChar* err_msg_out_of_range,
const HChar* err_msg_out_of_scope,
const HChar* err_msg_assigned_more_than_once)
{
- vassert(tmp.id != IRTyEnvID_INVALID);
+ const IRTypeEnv* tyenv = bb->tyenv;
- if (!inRangeIRTemp(stmts, tmp))
+ if (!inRangeIRTemp(tyenv, tmp))
sanityCheckFail(bb, stmt, err_msg_out_of_range);
- if (!inScopeIRTemp(stmts, tmp))
+ if (!inScopeIRTemp(tyenv, stmts, tmp))
sanityCheckFail(bb, stmt, err_msg_out_of_scope);
- def_counts[tmp.id][tmp.index]++;
- if (def_counts[tmp.id][tmp.index] > 1) {
+ def_counts[tmp]++;
+ if (def_counts[tmp] > 1) {
sanityCheckFail(bb, stmt, err_msg_assigned_more_than_once);
}
}
@@ -4204,7 +4265,7 @@
static
void useBeforeDef_Expr(const IRSB *bb, const IRStmtVec* stmts,
const IRStmt* stmt, const IRExpr* expr,
- UInt* def_counts[])
+ UInt def_counts[])
{
Int i;
switch (expr->tag) {
@@ -4269,7 +4330,7 @@
static void useBeforeDef_IRPhi(const IRSB* bb, const IRStmtVec* stmts,
const IRStmt* stmt, const IRPhi* phi,
- UInt* def_counts[])
+ UInt def_counts[])
{
vassert(stmt->tag == Ist_IfThenElse);
@@ -4281,15 +4342,16 @@
/* Check also that referenced IRStmtVec's actually exist and belong to
"parent", "then", and "else", respectively. */
- if (phi->dst.id != stmts->tyenv->id) {
+ const IRTypeEnv* tyenv = bb->tyenv;
+ if (tyenv->ids[phi->dst] != stmts->id) {
sanityCheckFail(bb, stmt, "Istmt.IfThenElse.Phi.dst does not "
"reference parent IRStmtVec");
}
- if (phi->srcThen.id != then_leg->tyenv->id) {
+ if (tyenv->ids[phi->srcThen] != then_leg->id) {
sanityCheckFail(bb, stmt, "Istmt.IfThenElse.Phi.srcThen does not "
"reference \"then\" IRStmtVec leg");
}
- if (phi->srcElse.id != else_leg->tyenv->id) {
+ if (tyenv->ids[phi->srcElse] != else_leg->id) {
sanityCheckFail(bb, stmt, "Istmt.IfThenElse.Phi.srcElse does not "
"reference \"else\" IRStmtVec leg");
}
@@ -4297,7 +4359,7 @@
static
void useBeforeDef_Stmt(const IRSB* bb, const IRStmtVec* stmts,
- const IRStmt* stmt, UInt* def_counts[])
+ const IRStmt* stmt, UInt def_counts[])
{
Int i;
const IRDirty* d;
@@ -4388,7 +4450,7 @@
static
void assignedOnce_Stmt(const IRSB* bb, const IRStmtVec* stmts,
- const IRStmt* stmt, UInt* def_counts[])
+ const IRStmt* stmt, UInt def_counts[])
{
switch (stmt->tag) {
case Ist_WrTmp:
@@ -4406,7 +4468,7 @@
"IRStmt.LoadG: destination tmp is assigned more than once");
break;
case Ist_Dirty:
- if (!isIRTempInvalid(stmt->Ist.Dirty.details->tmp)) {
+ if (stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
assignedOnce_Temp(
bb, stmts, stmt, stmt->Ist.Dirty.details->tmp, def_counts,
"IRStmt.Dirty: destination tmp is out of range",
@@ -4415,7 +4477,7 @@
}
break;
case Ist_CAS:
- if (!isIRTempInvalid(stmt->Ist.CAS.details->oldHi)) {
+ if (stmt->Ist.CAS.details->oldHi != IRTemp_INVALID) {
assignedOnce_Temp(
bb, stmts, stmt, stmt->Ist.CAS.details->oldHi, def_counts,
"IRStmt.CAS: destination tmpHi is out of range",
@@ -4451,7 +4513,7 @@
static void assignedOnce_IRPhi(const IRSB* bb, const IRStmtVec* stmts,
const IRStmt* stmt, const IRPhi* phi,
- UInt* def_counts[])
+ UInt def_counts[])
{
assignedOnce_Temp(bb, stmts, stmt, phi->dst, def_counts,
"IRStmt.IfThenElse.Phi: destination tmp is out of range",
@@ -4463,15 +4525,16 @@
void tcExpr(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
const IRExpr* expr, IRType gWordTy)
{
- Int i;
- IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
+ Int i;
+ IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
+ const IRTypeEnv* tyenv = bb->tyenv;
switch (expr->tag) {
case Iex_Get:
case Iex_RdTmp:
break;
case Iex_GetI:
tcExpr(bb, stmts, stmt, expr->Iex.GetI.ix, gWordTy);
- if (typeOfIRExpr(stmts, expr->Iex.GetI.ix) != Ity_I32)
+ if (typeOfIRExpr(tyenv, expr->Iex.GetI.ix) != Ity_I32)
sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
if (!saneIRRegArray(expr->Iex.GetI.descr))
sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
@@ -4494,10 +4557,10 @@
"Iex.Qop: wrong arity op\n"
"... name of op precedes BB printout\n");
}
- ttarg1 = typeOfIRExpr(stmts, qop->arg1);
- ttarg2 = typeOfIRExpr(stmts, qop->arg2);
- ttarg3 = typeOfIRExpr(stmts, qop->arg3);
- ttarg4 = typeOfIRExpr(stmts, qop->arg4);
+ ttarg1 = typeOfIRExpr(tyenv, qop->arg1);
+ ttarg2 = typeOfIRExpr(tyenv, qop->arg2);
+ ttarg3 = typeOfIRExpr(tyenv, qop->arg3);
+ ttarg4 = typeOfIRExpr(tyenv, qop->arg4);
if (t_arg1 != ttarg1 || t_arg2 != ttarg2
|| t_arg3 != ttarg3 || t_arg4 != ttarg4) {
vex_printf(" op name: ");
@@ -4545,9 +4608,9 @@
"Iex.Triop: wrong arity op\n"
"... name of op precedes BB printout\n");
}
- ttarg1 = typeOfIRExpr(stmts, triop->arg1);
- ttarg2 = typeOfIRExpr(stmts, triop->arg2);
- ttarg3 = typeOfIRExpr(stmts, triop->arg3);
+ ttarg1 = typeOfIRExpr(tyenv, triop->arg1);
+ ttarg2 = typeOfIRExpr(tyenv, triop->arg2);
+ ttarg3 = typeOfIRExpr(tyenv, triop->arg3);
if (t_arg1 != ttarg1 || t_arg2 != ttarg2 || t_arg3 != ttarg3) {
vex_printf(" op name: ");
ppIROp(triop->op);
@@ -4588,8 +4651,8 @@
"Iex.Binop: wrong arity op\n"
"... name of op precedes BB printout\n");
}
- ttarg1 = typeOfIRExpr(stmts, expr->Iex.Binop.arg1);
- ttarg2 = typeOfIRExpr(stmts, expr->Iex.Binop.arg2);
+ ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
+ ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
vex_printf(" op name: ");
ppIROp(expr->Iex.Binop.op);
@@ -4618,12 +4681,12 @@
if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID
|| t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID)
sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
- if (t_arg1 != typeOfIRExpr(stmts, expr->Iex.Unop.arg))
+ if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
break;
case Iex_Load:
tcExpr(bb, stmts, stmt, expr->Iex.Load.addr, gWordTy);
- if (typeOfIRExpr(stmts, expr->Iex.Load.addr) != gWordTy)
+ if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy)
sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type");
if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE)
sanityCheckFail(bb,stmt,"Iex.Load.end: bogus endianness");
@@ -4645,7 +4708,7 @@
sanityCheckFail(bb,stmt,
"Iex.CCall.retty: cannot return :: Ity_I1");
for (i = 0; expr->Iex.CCall.args[i]; i++)
- if (typeOfIRExpr(stmts, expr->Iex.CCall.args[i]) == Ity_I1)
+ if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
break;
case Iex_Const:
@@ -4656,10 +4719,10 @@
tcExpr(bb, stmts, stmt, expr->Iex.ITE.cond, gWordTy);
tcExpr(bb, stmts, stmt, expr->Iex.ITE.iftrue, gWordTy);
tcExpr(bb, stmts, stmt, expr->Iex.ITE.iffalse, gWordTy);
- if (typeOfIRExpr(stmts, expr->Iex.ITE.cond) != Ity_I1)
+ if (typeOfIRExpr(tyenv, expr->Iex.ITE.cond) != Ity_I1)
sanityCheckFail(bb,stmt,"Iex.ITE.cond: cond :: Ity_I1");
- if (typeOfIRExpr(stmts, expr->Iex.ITE.iftrue)
- != typeOfIRExpr(stmts, expr->Iex.ITE.iffalse))
+ if (typeOfIRExpr(tyenv, expr->Iex.ITE.iftrue)
+ != typeOfIRExpr(tyenv, expr->Iex.ITE.iffalse))
sanityCheckFail(bb,stmt,"Iex.ITE: iftrue/iffalse mismatch");
break;
default:
@@ -4672,16 +4735,14 @@
const IRPhi* phi)
{
vassert(stmt->tag == Ist_IfThenElse);
- const IRStmtVec* then_leg = stmt->Ist.IfThenElse.then_leg;
- const IRStmtVec* else_leg = stmt->Ist.IfThenElse.else_leg;
+ const IRTypeEnv* tyenv = bb->tyenv;
- if (typeOfIRTemp(then_leg, phi->srcThen)
- != typeOfIRTemp(else_leg, phi->srcElse)) {
- sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.Phi: 'then' and 'else' "
+ if (typeOfIRTemp(tyenv, phi->srcThen) != typeOfIRTemp(tyenv, phi->srcElse)) {
+ sanityCheckFail(bb, stmt, "IRStmt.IfThenElse.Phi: 'then' and 'else' "
"tmp do not match");
}
- if (typeOfIRTemp(stmts, phi->dst) != typeOfIRTemp(then_leg, phi->srcThen)) {
- sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.Phi: 'dst' and 'then' "
+ if (typeOfIRTemp(tyenv, phi->dst) != typeOfIRTemp(tyenv, phi->srcThen)) {
+ sanityCheckFail(bb, stmt, "IRStmt.IfThenElse.Phi: 'dst' and 'then' "
"tmp do not match");
}
}
@@ -4690,7 +4751,8 @@
void tcStmt(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
Bool require_flat, IRType gWordTy)
{
- IRType tyExpd, tyData;
+ IRType tyExpd, tyData;
+ const IRTypeEnv* tyenv = bb->tyenv;
switch (stmt->tag) {
case Ist_IMark:
/* Somewhat heuristic, but rule out totally implausible
@@ -4701,28 +4763,28 @@
sanityCheckFail(bb,stmt,"IRStmt.IMark.delta: implausible");
break;
case Ist_AbiHint:
- if (typeOfIRExpr(stmts, stmt->Ist.AbiHint.base) != gWordTy)
+ if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.base) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmt.AbiHint.base: "
"not :: guest word type");
- if (typeOfIRExpr(stmts, stmt->Ist.AbiHint.nia) != gWordTy)
+ if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.nia) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmt.AbiHint.nia: "
"not :: guest word type");
break;
case Ist_Put:
tcExpr(bb, stmts, stmt, stmt->Ist.Put.data, gWordTy);
- if (typeOfIRExpr(stmts, stmt->Ist.Put.data) == Ity_I1)
+ if (typeOfIRExpr(tyenv, stmt->Ist.Put.data) == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
break;
case Ist_PutI:{
const IRPutI* puti = stmt->Ist.PutI.details;
tcExpr(bb, stmts, stmt, puti->data, gWordTy);
tcExpr(bb, stmts, stmt, puti->ix, gWordTy);
- if (typeOfIRExpr(stmts, puti->data) == Ity_I1)
+ if (typeOfIRExpr(tyenv, puti->data) == Ity_I1)
sanityCheckFail(bb,stmt,
"IRStmt.PutI.data: cannot PutI :: Ity_I1");
- if (typeOfIRExpr(stmts, puti->data) != puti->descr->elemTy)
+ if (typeOfIRExpr(tyenv, puti->data) != puti->descr->elemTy)
sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
- if (typeOfIRExpr(stmts, puti->ix) != Ity_I32)
+ if (typeOfIRExpr(tyenv, puti->ix) != Ity_I32)
sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
if (!saneIRRegArray(puti->descr))
sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
@@ -4730,18 +4792,18 @@
}
case Ist_WrTmp:
tcExpr(bb, stmts, stmt, stmt->Ist.WrTmp.data, gWordTy);
- if (typeOfIRTemp(stmts, stmt->Ist.WrTmp.tmp)
- != typeOfIRExpr(stmts, stmt->Ist.WrTmp.data))
+ if (typeOfIRTemp(tyenv, stmt->Ist.WrTmp.tmp)
+ != typeOfIRExpr(tyenv, stmt->Ist.WrTmp.data))
sanityCheckFail(bb,stmt,
"IRStmt.Put.Tmp: tmp and expr do not match");
break;
case Ist_Store:
tcExpr(bb, stmts, stmt, stmt->Ist.Store.addr, gWordTy);
tcExpr(bb, stmts, stmt, stmt->Ist.Store.data, gWordTy);
- if (typeOfIRExpr(stmts, stmt->Ist.Store.addr) != gWordTy)
+ if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy)
sanityCheckFail(bb,stmt,
"IRStmt.Store.addr: not :: guest word type");
- if (typeOfIRExpr(stmts, stmt->Ist.Store.data) == Ity_I1)
+ if (typeOfIRExpr(tyenv, stmt->Ist.Store.data) == Ity_I1)
sanityCheckFail(bb,stmt,
"IRStmt.Store.data: cannot Store :: Ity_I1");
if (stmt->Ist.Store.end != Iend_LE && stmt->Ist.Store.end != Iend_BE)
@@ -4752,11 +4814,11 @@
tcExpr(bb, stmts, stmt, sg->addr, gWordTy);
tcExpr(bb, stmts, stmt, sg->data, gWordTy);
tcExpr(bb, stmts, stmt, sg->guard, gWordTy);
- if (typeOfIRExpr(stmts, sg->addr) != gWordTy)
+ if (typeOfIRExpr(tyenv, sg->addr) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmtG...addr: not :: guest word type");
- if (typeOfIRExpr(stmts, sg->data) == Ity_I1)
+ if (typeOfIRExpr(tyenv, sg->data) == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmtG...data: cannot Store :: Ity_I1");
- if (typeOfIRExpr(stmts, sg->guard) != Ity_I1)
+ if (typeOfIRExpr(tyenv, sg->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmtG...guard: not :: Ity_I1");
if (sg->end != Iend_LE && sg->end != Iend_BE)
sanityCheckFail(bb,stmt,"IRStmtG...end: bogus endianness");
@@ -4767,28 +4829,28 @@
tcExpr(bb, stmts, stmt, lg->addr, gWordTy);
tcExpr(bb, stmts, stmt, lg->alt, gWordTy);
tcExpr(bb, stmts, stmt, lg->guard, gWordTy);
- if (typeOfIRExpr(stmts, lg->guard) != Ity_I1)
+ if (typeOfIRExpr(tyenv, lg->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.LoadG.guard: not :: Ity_I1");
- if (typeOfIRExpr(stmts, lg->addr) != gWordTy)
+ if (typeOfIRExpr(tyenv, lg->addr) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmt.LoadG.addr: not "
":: guest word type");
- if (typeOfIRExpr(stmts, lg->alt) != typeOfIRTemp(stmts, lg->dst))
+ if (typeOfIRExpr(tyenv, lg->alt) != typeOfIRTemp(tyenv, lg->dst))
sanityCheckFail(bb,stmt,"IRStmt.LoadG: dst/alt type mismatch");
IRType cvtRes = Ity_INVALID, cvtArg = Ity_INVALID;
typeOfIRLoadGOp(lg->cvt, &cvtRes, &cvtArg);
- if (cvtRes != typeOfIRTemp(stmts, lg->dst))
+ if (cvtRes != typeOfIRTemp(tyenv, lg->dst))
sanityCheckFail(bb,stmt,"IRStmt.LoadG: dst/loaded type mismatch");
break;
}
case Ist_CAS: {
const IRCAS* cas = stmt->Ist.CAS.details;
/* make sure it's definitely either a CAS or a DCAS */
- if (isIRTempInvalid(cas->oldHi)
+ if (cas->oldHi == IRTemp_INVALID
&& cas->expdHi == NULL && cas->dataHi == NULL) {
/* fine; it's a single cas */
}
else
- if (!isIRTempInvalid(cas->oldHi)
+ if (cas->oldHi != IRTemp_INVALID
&& cas->expdHi != NULL && cas->dataHi != NULL) {
/* fine; it's a double cas */
}
@@ -4798,12 +4860,12 @@
}
/* check the address type */
tcExpr(bb, stmts, stmt, cas->addr, gWordTy);
- if (typeOfIRExpr(stmts, cas->addr) != gWordTy) goto bad_cas;
+ if (typeOfIRExpr(tyenv, cas->addr) != gWordTy) goto bad_cas;
/* check types on the {old,expd,data}Lo components agree */
- tyExpd = typeOfIRExpr(stmts, cas->expdLo);
- tyData = typeOfIRExpr(stmts, cas->dataLo);
+ tyExpd = typeOfIRExpr(tyenv, cas->expdLo);
+ tyData = typeOfIRExpr(tyenv, cas->dataLo);
if (tyExpd != tyData) goto bad_cas;
- if (tyExpd != typeOfIRTemp(stmts, cas->oldLo))
+ if (tyExpd != typeOfIRTemp(tyenv, cas->oldLo))
goto bad_cas;
/* check the base element type is sane */
if (tyExpd == Ity_I8 || tyExpd == Ity_I16 || tyExpd == Ity_I32
@@ -4814,16 +4876,16 @@
}
/* If it's a DCAS, check types on the {old,expd,data}Hi
components too */
- if (!isIRTempInvalid(cas->oldHi)) {
- tyExpd = typeOfIRExpr(stmts, cas->expdHi);
- tyData = typeOfIRExpr(stmts, cas->dataHi);
+ if (cas->oldHi != IRTemp_INVALID) {
+ tyExpd = typeOfIRExpr(tyenv, cas->expdHi);
+ tyData = typeOfIRExpr(tyenv, cas->dataHi);
if (tyExpd != tyData) goto bad_cas;
- if (tyExpd != typeOfIRTemp(stmts, cas->oldHi))
+ if (tyExpd != typeOfIRTemp(tyenv, cas->oldHi))
goto bad_cas;
/* and finally check that oldLo and oldHi have the same
type. This forces equivalence amongst all 6 types. */
- if (typeOfIRTemp(stmts, cas->oldHi)
- != typeOfIRTemp(stmts, cas->oldLo))
+ if (typeOfIRTemp(tyenv, cas->oldHi)
+ != typeOfIRTemp(tyenv, cas->oldLo))
goto bad_cas;
}
break;
@@ -4833,11 +4895,11 @@
}
case Ist_LLSC: {
IRType tyRes;
- if (typeOfIRExpr(stmts, stmt->Ist.LLSC.addr) != gWordTy)
+ if (typeOfIRExpr(tyenv, stmt->Ist.LLSC.addr) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmt.LLSC.addr: not :: guest word type");
if (stmt->Ist.LLSC.end != Iend_LE && stmt->Ist.LLSC.end != Iend_BE)
sanityCheckFail(bb,stmt,"Ist.LLSC.end: bogus endianness");
- tyRes = typeOfIRTemp(stmts, stmt->Ist.LLSC.result);
+ tyRes = typeOfIRTemp(tyenv, stmt->Ist.LLSC.result);
if (stmt->Ist.LLSC.storedata == NULL) {
/* it's a LL */
if (tyRes != Ity_I64 && tyRes != Ity_I32
@@ -4847,7 +4909,7 @@
/* it's a SC */
if (tyRes != Ity_I1)
sanityCheckFail(bb,stmt,"Ist.LLSC(SC).result: not :: Ity_I1");
- tyData = typeOfIRExpr(stmts, stmt->Ist.LLSC.storedata);
+ tyData = typeOfIRExpr(tyenv, stmt->Ist.LLSC.storedata);
if (tyData != Ity_I64 && tyData != Ity_I32
&& tyData != Ity_I16 && tyData != Ity_I8)
sanityCheckFail(bb,stmt,
@@ -4886,12 +4948,12 @@
/* check guard */
if (d->guard == NULL) goto bad_dirty;
tcExpr(bb, stmts, stmt, d->guard, gWordTy);
- if (typeOfIRExpr(stmts, d->guard) != Ity_I1)
+ if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
/* check types, minimally */
IRType retTy = Ity_INVALID;
- if (!isIRTempInvalid(d->tmp)) {
- retTy = typeOfIRTemp(stmts, d->tmp);
+ if (d->tmp != IRTemp_INVALID) {
+ retTy = typeOfIRTemp(tyenv, d->tmp);
if (retTy == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
}
@@ -4905,7 +4967,7 @@
} else if (UNLIKELY(arg->tag == Iex_GSPTR)) {
nGSPTRs++;
} else {
- if (typeOfIRExpr(stmts, arg) == Ity_I1)
+ if (typeOfIRExpr(tyenv, arg) == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
}
if (nGSPTRs > 1) {
@@ -4956,7 +5018,7 @@
break;
case Ist_Exit:
tcExpr(bb, stmts, stmt, stmt->Ist.Exit.guard, gWordTy);
- if (typeOfIRExpr(stmts,stmt->Ist.Exit.guard) != Ity_I1)
+ if (typeOfIRExpr(tyenv, stmt->Ist.Exit.guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
if (!saneIRConst(stmt->Ist.Exit.dst))
sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst");
@@ -4968,7 +5030,7 @@
break;
case Ist_IfThenElse:
tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond, gWordTy);
- if (typeOfIRExpr(stmts, stmt->Ist.IfThenElse.cond) != Ity_I1)
+ if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.cond) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.cond: not :: Ity_I1");
/* Traversing into legs and phi nodes driven from
sanityCheckIRStmtVec(). */
@@ -4979,7 +5041,7 @@
}
static void sanityCheckIRPhiNodes(const IRSB* bb, const IRStmtVec* stmts,
- const IRStmt* stmt, const IRPhiVec* phi_nodes, UInt *def_counts[])
+ const IRStmt* stmt, const IRPhiVec* phi_nodes, UInt def_counts[])
{
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
const IRPhi* phi = phi_nodes->phis[i];
@@ -4991,51 +5053,32 @@
static
void sanityCheckIRStmtVec(const IRSB* bb, const IRStmtVec* stmts,
- Bool require_flat, UInt* def_counts[],
- UInt n_stmt_vecs, UInt id_counts[],
- IRType gWordTy)
-{
- const IRTypeEnv* tyenv = stmts->tyenv;
- IRTyEnvID id = tyenv->id;
- if (id == IRTyEnvID_INVALID) {
- vpanic("sanityCheckIRStmtVec: invalid IRTypeEnv ID");
+ Bool require_flat, UInt def_counts[],
+ UInt id_counts[], UInt n_ids, IRType gWordTy)
+{
+ IRStmtVecID id = stmts->id;
+ if (id == IRStmtVecID_INVALID) {
+ vpanic("sanityCheckIRStmtVec: invalid IRStmtVec ID");
}
- if (id >= n_stmt_vecs) {
- vex_printf("IRTypeEnv's ID (%u) is larger than number of IRStmtVec's "
- "(%u)\n", id, n_stmt_vecs);
- sanityCheckFail(bb, NULL, "IRTypeEnv's ID larger than number of "
+ if (id >= n_ids) {
+ vex_printf("IRStmtVec's ID (%u) is larger than number of IRStmtVec's "
+ "(%u)\n", id, n_ids);
+ sanityCheckFail(bb, NULL, "IRStmtVec's ID larger than number of "
"IRStmtVec's");
}
id_counts[id] += 1;
if (id_counts[id] > 1) {
- sanityCheckFail(bb, NULL, "the same IRTyEnv ID used more than once");
+ sanityCheckFail(bb, NULL, "the same IRStmtVec ID used more than once");
}
- UInt n_temps = tyenv->types_used;
- def_counts[id] = LibVEX_Alloc_inline(n_temps * sizeof(UInt));
- for (UInt i = 0; i < n_temps; i++)
- def_counts[id][i] = 0;
-
if (stmts->stmts_used < 0 || stmts->stmts_size < 8
|| stmts->stmts_used > stmts->stmts_size) {
/* this IRStmtVec is so strange we can't even print it */
vpanic("sanityCheckIRStmtVec: stmts array limits wierd");
}
- /* Ensure each temp has a plausible type. */
- for (UInt i = 0; i < n_temps; i++) {
- IRTemp temp = mkIRTemp(id, i);
- IRType ty = typeOfIRTemp(stmts, temp);
- if (!isPlausibleIRType(ty)) {
- vex_printf("Temp ");
- ppIRTemp(temp);
- vex_printf(" declared with implausible type 0x%x\n", (UInt) ty);
- sanityCheckFail(bb, NULL, "Temp declared with implausible type");
- }
- }
-
for (UInt i = 0; i < stmts->stmts_used; i++) {
const IRStmt *stmt = stmts->stmts[i];
if (stmt == NULL)
@@ -5074,36 +5117,52 @@
}
sanityCheckIRStmtVec(bb, then_leg, require_flat, def_counts,
- n_stmt_vecs, id_counts, gWordTy);
+ id_counts, n_ids, gWordTy);
sanityCheckIRStmtVec(bb, else_leg, require_flat, def_counts,
- n_stmt_vecs, id_counts, gWordTy);
+ id_counts, n_ids, gWordTy);
sanityCheckIRPhiNodes(bb, stmts, stmt,
stmt->Ist.IfThenElse.phi_nodes, def_counts);
}
}
}
-
/* Sanity checks basic block of IR.
Also checks for IRTyEnvID uniqueness. */
void sanityCheckIRSB(const IRSB* bb, const HChar* caller, Bool require_flat,
IRType gWordTy)
{
- UInt n_stmt_vecs = bb->id_seq;
- UInt **def_counts = LibVEX_Alloc_inline(n_stmt_vecs * sizeof(UInt *));
- UInt *id_counts = LibVEX_Alloc_inline(n_stmt_vecs * sizeof(UInt));
- for (UInt i = 0; i < n_stmt_vecs; i++) {
- def_counts[i] = NULL;
+ UInt n_ids = bb->id_seq + 1;
+ UInt *id_counts = LibVEX_Alloc_inline(n_ids * sizeof(UInt));
+ for (UInt i = 0; i < n_ids; i++) {
id_counts[i] = 0;
}
+ const IRTypeEnv* tyenv = bb->tyenv;
+ UInt n_temps = tyenv->used;
+ UInt *def_counts = LibVEX_Alloc_inline(n_temps * sizeof(UInt));
+ for (UInt i = 0; i < n_temps; i++) {
+ def_counts[i] = 0;
+ }
+
if (0)
vex_printf("sanityCheck: %s\n", caller);
vassert(gWordTy == Ity_I32 || gWordTy == Ity_I64);
- sanityCheckIRStmtVec(bb, bb->stmts, require_flat, def_counts, n_stmt_vecs,
- id_counts, gWordTy);
+ /* Ensure each temp has a plausible type. */
+ for (UInt i = 0; i < n_temps; i++) {
+ IRTemp temp = (IRTemp) i;
+ IRType ty = typeOfIRTemp(tyenv, temp);
+ if (!isPlausibleIRType(ty)) {
+ vex_printf("Temp ");
+ ppIRTemp(temp);
+ vex_printf(" declared with implausible type 0x%x\n", (UInt) ty);
+ sanityCheckFail(bb, NULL, "Temp declared with implausible type");
+ }
+ }
+
+ sanityCheckIRStmtVec(bb, bb->stmts, require_flat, def_counts, id_counts,
+ n_ids, gWordTy);
if (require_flat) {
if (!isIRAtom(bb->next)) {
@@ -5112,7 +5171,7 @@
}
/* Typecheck also next destination. */
- if (typeOfIRExpr(bb->stmts, bb->next) != gWordTy) {
+ if (typeOfIRExpr(bb->tyenv, bb->next) != gWordTy) {
sanityCheckFail(bb, NULL, "bb->next field has wrong type");
}
/* because it would intersect with host_EvC_* */
@@ -5231,7 +5290,7 @@
vassert(isIRAtom(a1));
vassert(isIRAtom(a2));
if (a1->tag == Iex_RdTmp && a2->tag == Iex_RdTmp)
- return eqIRTemp(a1->Iex.RdTmp.tmp, a2->Iex.RdTmp.tmp);
+ return toBool(a1->Iex.RdTmp.tmp == a2->Iex.RdTmp.tmp);
if (a1->tag == Iex_Const && a2->tag == Iex_Const)
return eqIRConst(a1->Iex.Const.con, a2->Iex.Const.con);
return False;
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 Sat Mar 25 08:02:31 2017
@@ -54,13 +54,13 @@
'IRSB'). Each code block typically represents from 1 to perhaps 50
instructions. IRSBs are single-entry, multiple-exit code blocks.
Each IRSB contains three things:
- - a vector of statements, which represent code, together with the associated
- type environment (which indicates the type of each temporary value present
- in statements)
+ - a type environment, which indicates the type of each temporary
+ value present in the IRSB
+ - a vector of statements, which represent code
- a jump that exits from the end of the IRSB
Flow control can leave the IRSB before the final exit only in a leg of an
- "if-then-else" statement. A leg of an "if-then-else" statement is de facto
- another vector of statements and as such has also its type environment.
+ "if-then-else" statement. A leg of an "if-then-else" statement is just
+ another vector of statements.
"If-then-else" statements can be nested, however this is currently not
supported.
IRSBs can cover multiple non-consecutive sequences of code (up to 3).
@@ -107,10 +107,10 @@
One Vex IR translation for this code would be this:
------ IMark(0x24F275, 7, 0) ------
- t0:3 = GET:I32(0) # get %eax, a 32-bit integer
- t0:2 = GET:I32(12) # get %ebx, a 32-bit integer
- t0:1 = Add32(t0:3,t0:2) # addl
- PUT(0) = t1:1 # put %eax
+ t3 = GET:I32(0) # get %eax, a 32-bit integer
+ t2 = GET:I32(12) # get %ebx, a 32-bit integer
+ t1 = Add32(t3,t2) # addl
+ PUT(0) = t1 # put %eax
(For simplicity, this ignores the effects on the condition codes, and
the update of the instruction pointer.)
@@ -124,7 +124,7 @@
The five statements in this example are:
- the IMark
- - three assignments to temporaries (they all belong to type environment ID 0)
+ - three assignments to temporaries
- one register write (put)
The six expressions in this example are:
@@ -150,11 +150,11 @@
updates):
------ IMark(0x4000ABA, 3, 0) ------
- t0:3 = Add32(GET:I32(0),0x4:I32)
- t0:2 = LDle:I32(t0:3)
- t0:1 = GET:I32(8)
- t0:0 = Add32(t0:2,t0:1)
- STle(t0:3) = t0:0
+ t3 = Add32(GET:I32(0),0x4:I32)
+ t2 = LDle:I32(t3)
+ t1 = GET:I32(8)
+ t0 = Add32(t2,t1)
+ STle(t3) = t0
The "le" in "LDle" and "STle" is short for "little-endian".
@@ -391,51 +391,17 @@
/* ------------------ Temporaries ------------------ */
-/* These represent IR SSA temporaries. A temporary is uniquely identified by its
- type environment id and local index, such as (3, 1). Such a temporary belongs
- to type environment id 3 and its local index within this type environment
- is 1. Shorter representation would be t3:1.
-
- The IR optimiser relies on the fact that IRTemps are 32-bit ints (16 bits for
- type environment id and 16 bits for local index). Do not change them to
- be ints of any other size. */
+/* This represents a temporary, eg. t1. The IR optimiser relies on the
+ fact that IRTemps are 32-bit ints. Do not change them to be ints of
+ any other size. */
-typedef UShort IRTyEnvID;
-typedef UShort IRTyEnvIndex;
-
-#define IRTyEnvID_INVALID ((IRTyEnvID) 0xFFFF)
-#define IRTyEnvIndex_INVALID ((IRTyEnvIndex) 0xFFFF)
-
-typedef
- struct {
- IRTyEnvID id;
- IRTyEnvIndex index;
- }
- IRTemp;
-
-static inline IRTemp mkIRTemp(IRTyEnvID id, IRTyEnvIndex index)
-{
- IRTemp tmp = {id, index};
- return tmp;
-}
-
-static inline IRTemp IRTemp_INVALID(void)
-{
- return mkIRTemp(IRTyEnvID_INVALID, IRTyEnvIndex_INVALID);
-}
+typedef UInt IRTemp;
/* Pretty-print an IRTemp. */
extern void ppIRTemp ( IRTemp );
-static inline Bool isIRTempInvalid(IRTemp tmp)
-{
- return (tmp.id == IRTyEnvID_INVALID && tmp.index == IRTyEnvIndex_INVALID);
-}
+#define IRTemp_INVALID ((IRTemp) 0xFFFFFFFF)
-static inline Bool eqIRTemp(IRTemp t1, IRTemp t2)
-{
- return toBool(t1.id == t2.id && t1.index == t2.index);
-}
/* --------------- Primops (arity 1,2,3 and 4) --------------- */
@@ -2730,18 +2696,18 @@
A "phi" function is special "phony" function that does not have its
corresponding machine operation. Let's consider this example:
if (cond) {
- t0:1 = 3
+ t1 = 0x3:I64
} else {
- t0:1 = 4
+ t1 = 0x4:I64
}
However this is not possible under SSA rules (a temporary cannot be assigned
more than once). Now the "phi" function comes handy:
if (cond) {
- t1:1 = 3
+ t2 = 0x3:I64
} else {
- t2:1 = 4
+ t3 = 0x4:I64
}
- t0:1 = phi(t1:1,t2:1)
+ t1 = phi(t2,t3)
*/
typedef
struct {
@@ -2768,33 +2734,47 @@
extern void addIRPhiToIRPhiVec(IRPhiVec* , IRPhi*);
+/* ----------------- IRTemp Defined Set ----------------- */
-/* ------------------ Type Environments ------------------ */
+/* An IRTemp is defined in an IRStmtVec. By keeping track of where every IRTemp
+ is defined, it is possible to reason about IRTemp's scope.
-/* Type environments: a bunch of statements, expressions, etc, are incomplete
- without an environment indicating the type of each IRTemp. So this provides
- one. The array, 0 .. n_types_used-1, is indexed by "local index" component
- of IR temporaries. The type environment ID is used to uniquely identify
- temporaries across multiple IRStmtVec in an IRSB.
-*/
+ Let's have this IRStmtVec hierarchy:
+ IRSB
+ |- IRStmtVec #0
+ |- IRStmtVec #1
+ |- IRStmtVec #2
+ |- IRStmtVec #3
+ So an IRTemp defined in IRStmtVec #2 is valid (in scope) only
+ in IRStmtVec's #2 and #3; and out of scope in IRStmtVec's #0 and #1.
+
+ Every IRStmtVec has its IRTempDefSet structure. This is a bit set indexed
+ by IRTemp; value 1 means that a particular IRTemp is defined there.
+
+ 'bits' array does not grow each time an IRTemp is added to IRSB; it grows
+ lazily only when an IRTemp is marked as defined in a particular IRStmtVec.
+ */
typedef
struct {
- IRType* types;
- Int types_size;
- Int types_used;
- IRTyEnvID id;
+ UChar* set; // a bit set, use isIRTempDefined() for access
+ UInt slots_used;
+ UInt slots_size;
}
- IRTypeEnv;
-
-/* Obtain a new IRTemp */
-extern IRTemp newIRTemp(IRTypeEnv*, IRType);
+ IRTempDefSet;
-/* Deep-copy a type environment */
-extern IRTypeEnv* deepCopyIRTypeEnv(const IRTypeEnv* src);
-
-/* Pretty-print a type environment */
-extern void ppIRTypeEnv(const IRTypeEnv*);
+static inline Bool isIRTempDefined(const IRTempDefSet* defd, IRTemp tmp)
+{
+ if (tmp / sizeof(UChar) < defd->slots_size) {
+ UInt mask = (1 << (tmp % sizeof(UChar)));
+ return toBool(defd->set[tmp / sizeof(UChar)] & mask);
+ }
+ return False;
+}
+extern void setIRTempDefined(IRTempDefSet* defd, IRTemp tmp);
+extern void ppIRTempDefSet(const IRTempDefSet* defd);
+extern IRTempDefSet* emptyIRTempDefSet(void);
+extern IRTempDefSet* deepCopyIRTempDefSet(const IRTempDefSet* defd);
/* ------------------ Statements ------------------ */
@@ -2803,30 +2783,36 @@
struct _IRStmt
IRStmt;
+/* Uniquely identifies IRStmtVec in an IRSB, no matter how deeply nested. */
+typedef UShort IRStmtVecID;
+
+#define IRStmtVecID_INVALID ((IRStmtVecID) 0xFFFF)
+
/* Vector of statements which contains:
- - Type environment
- - Statements
- - A unique IRTyEnvID
+ - Statements themselves
+ - A unique IRStmtVecID
- Parent, which points to the parent IRStmtVec. Because "if-then-else"
statements cannot be currently nested, the parent is either NULL or points
- to IRStmtVec with type environment ID #0.
+ to IRStmtVec #0.
+ - A set which keeps track of which IRTemp's are defined in this IRStmtVec.
*/
typedef
struct _IRStmtVec {
- IRTypeEnv* tyenv;
IRStmt** stmts;
UInt stmts_size;
UInt stmts_used;
+ IRStmtVecID id;
struct _IRStmtVec* parent;
+ IRTempDefSet* def_set;
}
IRStmtVec;
extern void ppIRStmtVec(const IRStmtVec*);
extern void ppIRStmtVec_wrk(const IRStmtVec*, UInt depth);
-/* Allocates an empty IRStmtVec with an invalid IRTyEnvID.
- Such an IRStmtVec needs to have a valid IRTyEnvId - get it from
- nextIRTyEnvID(). Only after this is done, then such an IRStmtVec is ready
+/* Allocates an empty IRStmtVec with an invalid IRStmtVecID.
+ Such an IRStmtVec needs to have a valid IRStmtVecID - get it from
+ nextIRStmtVecID(). Only after this is done, then such an IRStmtVec is ready
for newIRTemp() to give out new temporaries.
Nested IRStmtVec also needs to have correctly set its parent.
@@ -2927,7 +2913,7 @@
to help Memcheck to origin tracking.
ppIRStmt output: ====== AbiHint(<base>, <len>, <nia>) ======
- eg. ====== AbiHint(t1:7, 16, t1:2) ======
+ eg. ====== AbiHint(t1, 16, t2) ======
*/
struct {
IRExpr* base; /* Start of undefined chunk */
@@ -2936,7 +2922,7 @@
} AbiHint;
/* Write a guest register, at a fixed offset in the guest state.
- ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1:7
+ ppIRStmt output: PUT(<offset>) = <data>, eg. PUT(60) = t1
*/
struct {
Int offset; /* Offset into the guest state */
@@ -2948,7 +2934,7 @@
information.
ppIRStmt output: PUTI<descr>[<ix>,<bias>] = <data>,
- eg. PUTI(64:8xF64)[t5,0] = t1:7
+ eg. PUTI(64:8xF64)[t5,0] = t1
*/
struct {
IRPutI* details;
@@ -2959,7 +2945,7 @@
reject any block containing a temporary which is not assigned
to exactly once.
- ppIRStmt output: t<tmp> = <data>, eg. t1:7 = 3
+ ppIRStmt output: t<tmp> = <data>, eg. t1 = 3
*/
struct {
IRTemp tmp; /* Temporary (LHS of assignment) */
@@ -2969,7 +2955,7 @@
/* Write a value to memory. This is a normal store, not a
Store-Conditional. To represent a Store-Conditional,
instead use IRStmt.LLSC.
- ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1:7) = t1:6
+ ppIRStmt output: ST<end>(<addr>) = <data>, eg. STle(t1) = t2
*/
struct {
IREndness end; /* Endianness of the store */
@@ -3001,7 +2987,7 @@
ppIRStmt output:
t<tmp> = CAS<end>(<addr> :: <expected> -> <new>)
eg
- t0:1 = CASle(t0:2 :: t0:3->Add32(t0:3,1))
+ t1 = CASle(t2 :: t3->Add32(t3,1))
which denotes a 32-bit atomic increment
of a value at address t2
@@ -3026,7 +3012,7 @@
The data transfer type is the type of RESULT (I32, I64,
etc). ppIRStmt output:
- result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1:7)
+ result = LD<end>-Linked(<addr>), eg. LDbe-Linked(t1)
If STOREDATA is not NULL then this is a Store-Conditional,
hence:
@@ -3040,7 +3026,7 @@
if it fails. eg ppIRStmt output:
result = ( ST<end>-Cond(<addr>) = <storedata> )
- eg t3 = ( STbe-Cond(t1:1, t1:2) )
+ eg t3 = ( STbe-Cond(t1, t2) )
In all cases, the address must be naturally aligned for
the transfer type -- any misaligned addresses should be
@@ -3073,7 +3059,7 @@
::: <callee>(<args>)
eg.
t1 = DIRTY t27 RdFX-gst(16,4) RdFX-gst(60,4)
- ::: foo{0x380035f4}(t1:2)
+ ::: foo{0x380035f4}(t2)
*/
struct {
IRDirty* details;
@@ -3107,8 +3093,7 @@
/* 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
+ - "then" and "else" legs with vectors of statements
At the moment, nested "if-then-else" statements are not supported.
- Phi nodes, which are used to merge temporaries from "then" and
"else" legs
@@ -3119,7 +3104,7 @@
ppIRIfThenElse output:
if (<cond>) then { <IRStmtVec> } else { <IRStmtVec> }
- eg. if (t0:3) then { <then-statements> } else { <else-statements> }
+ eg. if (t3) then { <then-statements> } else { <else-statements> }
*/
struct {
IRExpr* cond;
@@ -3160,13 +3145,43 @@
extern void ppIRStmt ( const IRStmt* );
extern void ppIRStmt_wrk(const IRStmt*, UInt depth);
+
/* ------------------ Basic Blocks ------------------ */
+/* Type environments: a bunch of statements, expressions, etc, are incomplete
+ without an environment indicating the type of each IRTemp and its scope.
+ So this provides one. IR temporaries are really just unsigned ints so they
+ can used to index these two arrays:
+ - 'types' which gives IRTemp's type
+ - 'ids' which gives ID of the defining IRStmtVec
+*/
+
+typedef
+ struct {
+ IRType* types;
+ IRStmtVecID* ids;
+ UInt size;
+ UInt used;
+ }
+ IRTypeEnv;
+
+/* Obtain a new IRTemp. New IRTemp is allocated from 'tyenv' and is marked
+ as defined in 'stmts'->def_set. */
+extern IRTemp newIRTemp(IRTypeEnv* tyenv, IRStmtVec* stmts, IRType);
+
+/* Deep-copy a type environment */
+extern IRTypeEnv* deepCopyIRTypeEnv ( const IRTypeEnv* );
+
+/* Pretty-print a type environment */
+extern void ppIRTypeEnv ( const IRTypeEnv* );
+
+
/* Code blocks, which in proper compiler terminology are superblocks
(single entry, multiple exit code sequences) contain:
- - A vector of statements, together with its type environment
- - A sequence used to get a unique IRTyEnvID for nested IRStmtVec's
+ - A type environment (giving type for each temp and where it is defined)
+ - A vector of statements
+ - A sequence used to get a unique IRStmtVecID for nested IRStmtVec's
- An expression of type 32 or 64 bits, depending on the
guest's word size, indicating the next destination if the block
executes all the way to the end, without a side exit
@@ -3179,15 +3194,16 @@
*/
typedef
struct {
- IRStmtVec* stmts;
- IRTyEnvID id_seq;
- IRExpr* next;
- IRJumpKind jumpkind;
- Int offsIP;
+ IRTypeEnv* tyenv;
+ IRStmtVec* stmts;
+ IRStmtVecID id_seq;
+ IRExpr* next;
+ IRJumpKind jumpkind;
+ Int offsIP;
}
IRSB;
-/* Allocates an empty IRSB. The corresponding type environment has ID #0. */
+/* Allocates an empty IRSB. The corresponding IRStmtVec has ID #0. */
extern IRSB* emptyIRSB ( void );
/* Deep-copy an IRSB */
@@ -3206,9 +3222,9 @@
extern void addStmtToIRStmtVec(IRStmtVec*, IRStmt*);
-extern IRTyEnvID nextIRTyEnvID(IRSB*);
+extern IRStmtVecID nextIRStmtVecID(IRSB*);
-/* Allocates an empty IfThenElse, assigns it a valid IRTyEnvID
+/* Allocates an empty IfThenElse, assigns it a valid IRStmtVecID
and sets the parent for both then and else legs.
The returned IRStmt is added to the parent IRStmtVec and ready to be used. */
extern IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond);
@@ -3217,15 +3233,10 @@
/*--- Helper functions for the IR ---*/
/*---------------------------------------------------------------*/
-/* Creates a new IR type environment with an invalid IRTyEnvID.
- Consult nextIRTyEnvID() function for getting a valid IRTyEnvID.
- Useful for messing with IR type environments. */
-extern IRTypeEnv *emptyIRTypeEnv(void);
-
/* What is the type of this expression? */
extern IRType typeOfIRConst ( const IRConst* );
-extern IRType typeOfIRTemp ( const IRStmtVec*, IRTemp );
-extern IRType typeOfIRExpr ( const IRStmtVec*, const IRExpr* );
+extern IRType typeOfIRTemp ( const IRTypeEnv*, IRTemp );
+extern IRType typeOfIRExpr ( const IRTypeEnv*, const IRExpr* );
/* What are the arg and result type for this IRLoadGOp? */
extern void typeOfIRLoadGOp ( IRLoadGOp cvt,
|
|
From: <sv...@va...> - 2017-03-24 13:46:24
|
Author: iraisr
Date: Fri Mar 24 13:46:15 2017
New Revision: 3329
Log:
Use consistently chase1() in MSVC specific transformation hacks.
This code is experimental and not used by default but should be self-consistent.
n-i-bz
Modified:
trunk/priv/ir_opt.c
Modified: trunk/priv/ir_opt.c
==============================================================================
--- trunk/priv/ir_opt.c (original)
+++ trunk/priv/ir_opt.c Fri Mar 24 13:46:15 2017
@@ -6007,7 +6007,7 @@
case Iex_RdTmp:
ppIRTemp(e->Iex.RdTmp.tmp);
vex_printf("=");
- print_flat_expr(env, chase(env, e));
+ print_flat_expr(env, chase1(env, e));
break;
case Iex_Const:
case Iex_CCall:
|
|
From: <sv...@va...> - 2017-03-24 02:07:21
|
Author: bart
Date: Fri Mar 24 02:07:14 2017
New Revision: 16286
Log:
memcheck/tests/unit_oset.c: Fix compiler warnings
Avoid that the compiler warns about using the result of an assignment
as a truth value.
Modified:
trunk/memcheck/tests/unit_oset.c
Modified: trunk/memcheck/tests/unit_oset.c
==============================================================================
--- trunk/memcheck/tests/unit_oset.c (original)
+++ trunk/memcheck/tests/unit_oset.c Fri Mar 24 02:07:14 2017
@@ -208,7 +208,8 @@
// Check that we can remove half of the elements, and that their values
// are as expected.
for (i = 0; i < NN; i += 2) {
- assert( pv = VG_(OSetGen_Remove)(oset, vs[i]) );
+ pv = VG_(OSetGen_Remove)(oset, vs[i]);
+ assert( pv );
assert( pv == vs[i] );
}
@@ -217,7 +218,8 @@
// Check we can find the remaining elements (with the right values).
for (i = 1; i < NN; i += 2) {
- assert( pv = VG_(OSetGen_LookupWithCmp)(oset, vs[i], NULL) );
+ pv = VG_(OSetGen_LookupWithCmp)(oset, vs[i], NULL);
+ assert( pv );
assert( pv == vs[i] );
}
@@ -229,7 +231,8 @@
// Check that we can remove the remaining half of the elements, and that
// their values are as expected.
for (i = 1; i < NN; i += 2) {
- assert( pv = VG_(OSetGen_Remove)(oset, vs[i]) );
+ pv = VG_(OSetGen_Remove)(oset, vs[i]);
+ assert( pv );
assert( pv == vs[i] );
}
|
|
From: <sv...@va...> - 2017-03-23 23:22:29
|
Author: iraisr
Date: Thu Mar 23 23:22:21 2017
New Revision: 16285
Log:
Fix for 377698 - Missing memory check for futex() uaddr arg for FUTEX_WAKE,
and FUTEX_WAKE_BITSET, check only 4 args for FUTEX_WAKE_BITSET,
and 2 args for FUTEX_TRYLOCK_PI.
Fixes BZ#377698.
Patch by: dia...@or...
Modified:
trunk/NEWS
trunk/coregrind/m_syswrap/syswrap-linux.c
trunk/memcheck/tests/arm64-linux/scalar.c
trunk/memcheck/tests/arm64-linux/scalar.stderr.exp
trunk/memcheck/tests/darwin/scalar.c
trunk/memcheck/tests/x86-linux/scalar.c
trunk/memcheck/tests/x86-linux/scalar.stderr.exp
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Thu Mar 23 23:22:21 2017
@@ -147,6 +147,9 @@
377376 memcheck/tests/linux/getregset fails with glibc2.24
377427 PPC64, lxv instruction failing on odd destination register
377478 PPC64: ISA 3.0 setup fixes
+377698 Missing memory check for futex() uaddr arg for FUTEX_WAKE
+ and FUTEX_WAKE_BITSET, check only 4 args for FUTEX_WAKE_BITSET,
+ and 2 args for FUTEX_TRYLOCK_PI
377717 Fix massive space leak when reading compressed debuginfo sections
Release 3.12.0 (20 October 2016)
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Thu Mar 23 23:22:21 2017
@@ -1610,9 +1610,11 @@
}
break;
case VKI_FUTEX_WAKE_BITSET:
- PRE_REG_READ6(long, "futex",
- vki_u32 *, futex, int, op, int, val,
- int, dummy, int, dummy2, int, val3);
+ PRE_REG_READ3(long, "futex",
+ vki_u32 *, futex, int, op, int, val);
+ if (VG_(tdict).track_pre_reg_read) {
+ PRA6("futex", int, val3);
+ }
break;
case VKI_FUTEX_WAIT:
case VKI_FUTEX_LOCK_PI:
@@ -1622,10 +1624,10 @@
break;
case VKI_FUTEX_WAKE:
case VKI_FUTEX_FD:
- case VKI_FUTEX_TRYLOCK_PI:
PRE_REG_READ3(long, "futex",
vki_u32 *, futex, int, op, int, val);
break;
+ case VKI_FUTEX_TRYLOCK_PI:
case VKI_FUTEX_UNLOCK_PI:
default:
PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
@@ -1655,13 +1657,10 @@
case VKI_FUTEX_FD:
case VKI_FUTEX_TRYLOCK_PI:
case VKI_FUTEX_UNLOCK_PI:
- PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
- break;
-
case VKI_FUTEX_WAKE:
case VKI_FUTEX_WAKE_BITSET:
- /* no additional pointers */
- break;
+ PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
+ break;
default:
SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
Modified: trunk/memcheck/tests/arm64-linux/scalar.c
==============================================================================
--- trunk/memcheck/tests/arm64-linux/scalar.c (original)
+++ trunk/memcheck/tests/arm64-linux/scalar.c Thu Mar 23 23:22:21 2017
@@ -1068,8 +1068,8 @@
#define FUTEX_WAIT 0
#endif
// XXX: again, glibc not doing 6th arg means we have only 5s errors
- GO(__NR_futex, "5s 2m");
- SY(__NR_futex, x0+FUTEX_WAIT, x0, x0, x0+1, x0, x0); FAIL;
+ GO(__NR_futex, "4s 2m");
+ SY(__NR_futex, x0+FUTEX_WAIT, x0, x0, x0+1); FAIL;
// __NR_sched_setaffinity 241
GO(__NR_sched_setaffinity, "3s 1m");
Modified: trunk/memcheck/tests/arm64-linux/scalar.stderr.exp
==============================================================================
--- trunk/memcheck/tests/arm64-linux/scalar.stderr.exp (original)
+++ trunk/memcheck/tests/arm64-linux/scalar.stderr.exp Thu Mar 23 23:22:21 2017
@@ -1958,7 +1958,7 @@
130: __NR_tkill n/a
-----------------------------------------------------
-----------------------------------------------------
- 98: __NR_futex 5s 2m
+ 98: __NR_futex 4s 2m
-----------------------------------------------------
Syscall param futex(futex) contains uninitialised byte(s)
...
Modified: trunk/memcheck/tests/darwin/scalar.c
==============================================================================
--- trunk/memcheck/tests/darwin/scalar.c (original)
+++ trunk/memcheck/tests/darwin/scalar.c Thu Mar 23 23:22:21 2017
@@ -1654,8 +1654,8 @@
#define FUTEX_WAIT 0
#endif
// XXX: again, glibc not doing 6th arg means we have only 5s errors
- GO(__NR_futex, "5s 2m");
- SY(__NR_futex, x0+FUTEX_WAIT, x0, x0, x0+1, x0, x0); FAIL;
+ GO(__NR_futex, "4s 2m");
+ SY(__NR_futex, x0+FUTEX_WAIT, x0, x0, x0+1); FAIL;
// __NR_sched_setaffinity 241
GO(__NR_sched_setaffinity, "3s 1m");
Modified: trunk/memcheck/tests/x86-linux/scalar.c
==============================================================================
--- trunk/memcheck/tests/x86-linux/scalar.c (original)
+++ trunk/memcheck/tests/x86-linux/scalar.c Thu Mar 23 23:22:21 2017
@@ -1068,8 +1068,8 @@
#define FUTEX_WAIT 0
#endif
// XXX: again, glibc not doing 6th arg means we have only 5s errors
- GO(__NR_futex, "5s 2m");
- SY(__NR_futex, x0+FUTEX_WAIT, x0, x0, x0+1, x0, x0); FAIL;
+ GO(__NR_futex, "4s 2m");
+ SY(__NR_futex, x0+FUTEX_WAIT, x0, x0, x0+1); FAIL;
// __NR_sched_setaffinity 241
GO(__NR_sched_setaffinity, "3s 1m");
Modified: trunk/memcheck/tests/x86-linux/scalar.stderr.exp
==============================================================================
--- trunk/memcheck/tests/x86-linux/scalar.stderr.exp (original)
+++ trunk/memcheck/tests/x86-linux/scalar.stderr.exp Thu Mar 23 23:22:21 2017
@@ -3300,7 +3300,7 @@
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-240: __NR_futex 5s 2m
+240: __NR_futex 4s 2m
-----------------------------------------------------
Syscall param futex(futex) contains uninitialised byte(s)
...
|
|
From: <sv...@va...> - 2017-03-23 22:12:10
|
Author: iraisr
Date: Thu Mar 23 22:12:03 2017
New Revision: 16284
Log:
Announce fix for bug 377717 in the NEWS
Modified:
trunk/NEWS
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Thu Mar 23 22:12:03 2017
@@ -147,6 +147,7 @@
377376 memcheck/tests/linux/getregset fails with glibc2.24
377427 PPC64, lxv instruction failing on odd destination register
377478 PPC64: ISA 3.0 setup fixes
+377717 Fix massive space leak when reading compressed debuginfo sections
Release 3.12.0 (20 October 2016)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
From: <sv...@va...> - 2017-03-23 21:57:07
|
Author: iraisr
Date: Thu Mar 23 21:56:58 2017
New Revision: 3328
Log:
Fix constant propagation and folding for IfThenElse statements.
Modified:
branches/VEX_JIT_HACKS/priv/ir_opt.c
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 Thu Mar 23 21:56:58 2017
@@ -1064,8 +1064,62 @@
#define NODE_LIMIT 30
-/* The env in this section is a map from IRTemp to IRExpr*,
- that is, an array indexed by IRTemp. */
+/* 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
+ - 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)
+{
+ IRStmtVec* stmts_out = emptyIRStmtVec();
+ stmts_out->tyenv = deepCopyIRTypeEnv(stmts_in->tyenv);
+ stmts_out->parent = (parent_env != NULL) ? parent_env->stmts : NULL;
+
+ FoldEnv* env = LibVEX_Alloc_inline(sizeof(FoldEnv));
+ env->id = stmts_out->tyenv->id;
+ env->stmts = stmts_out;
+ env->parent = parent_env;
+
+ UInt n_tmps = stmts_out->tyenv->types_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
@@ -1084,17 +1138,20 @@
slower out of line general case. Saves a few insns. */
__attribute__((noinline))
-static Bool sameIRExprs_aux2(IRExpr* env[], IRExpr* e1, IRExpr* e2);
+static Bool sameIRExprs_aux2(const FoldEnv* env, const IRExpr* e1,
+ const IRExpr* e2);
inline
-static Bool sameIRExprs_aux(IRExpr* env[], IRExpr* e1, IRExpr* e2)
+static Bool sameIRExprs_aux(const FoldEnv* env, const IRExpr* e1,
+ const IRExpr* e2)
{
if (e1->tag != e2->tag) return False;
return sameIRExprs_aux2(env, e1, e2);
}
__attribute__((noinline))
-static Bool sameIRExprs_aux2(IRExpr* env[], IRExpr* e1, IRExpr* e2)
+static Bool sameIRExprs_aux2(const FoldEnv* env, const IRExpr* e1,
+ const IRExpr* e2)
{
if (num_nodes_visited++ > NODE_LIMIT) return False;
@@ -1102,12 +1159,12 @@
case Iex_RdTmp: {
IRTemp tmp1 = e1->Iex.RdTmp.tmp;
IRTemp tmp2 = e2->Iex.RdTmp.tmp;
- vassert(tmp1.id == tmp2.id);
- if (tmp1.index == tmp2.index) return True;
-
- if (env[tmp1.index] && env[tmp2.index]) {
- Bool same = sameIRExprs_aux(env, env[tmp1.index], env[tmp2.index]);
+ if (eqIRTemp(tmp1, tmp2)) return True;
+ const IRExpr* subst1 = findIRExpr(env, tmp1);
+ const IRExpr* subst2 = findIRExpr(env, tmp2);
+ if (subst1 != NULL && subst2 != NULL) {
+ Bool same = sameIRExprs_aux(env, subst1, subst2);
#if STATS_IROPT
recursed = True;
if (same) recursion_helped = True;
@@ -1176,7 +1233,7 @@
}
inline
-static Bool sameIRExprs(IRExpr* env[], IRExpr* e1, IRExpr* e2)
+static Bool sameIRExprs(const FoldEnv* env, const IRExpr* e1, const IRExpr* e2)
{
Bool same;
@@ -1205,8 +1262,8 @@
--vex-iropt-level > 0, that is, vex_control.iropt_verbosity > 0.
Bad because it duplicates functionality from typeOfIRExpr. See
comment on the single use point below for rationale. */
-static
-Bool debug_only_hack_sameIRExprs_might_assert ( IRExpr* e1, IRExpr* e2 )
+static Bool
+debug_only_hack_sameIRExprs_might_assert(const IRExpr* e1, const IRExpr* e2)
{
if (e1->tag != e2->tag) return False;
switch (e1->tag) {
@@ -1224,7 +1281,7 @@
/* Is this literally IRExpr_Const(IRConst_U32(0)) ? */
-static Bool isZeroU32 ( IRExpr* e )
+static Bool isZeroU32(const IRExpr* e)
{
return toBool( e->tag == Iex_Const
&& e->Iex.Const.con->tag == Ico_U32
@@ -1234,7 +1291,7 @@
/* Is this literally IRExpr_Const(IRConst_U64(0)) ?
Currently unused; commented out to avoid compiler warning */
#if 0
-static Bool isZeroU64 ( IRExpr* e )
+static Bool isZeroU64(const IRExpr* e)
{
return toBool( e->tag == Iex_Const
&& e->Iex.Const.con->tag == Ico_U64
@@ -1243,7 +1300,7 @@
#endif
/* Is this literally IRExpr_Const(IRConst_V128(0)) ? */
-static Bool isZeroV128 ( IRExpr* e )
+static Bool isZeroV128(const IRExpr* e)
{
return toBool( e->tag == Iex_Const
&& e->Iex.Const.con->tag == Ico_V128
@@ -1251,7 +1308,7 @@
}
/* Is this literally IRExpr_Const(IRConst_V256(0)) ? */
-static Bool isZeroV256 ( IRExpr* e )
+static Bool isZeroV256(const IRExpr* e)
{
return toBool( e->tag == Iex_Const
&& e->Iex.Const.con->tag == Ico_V256
@@ -1259,7 +1316,7 @@
}
/* Is this an integer constant with value 0 ? */
-static Bool isZeroU ( IRExpr* e )
+static Bool isZeroU(const IRExpr* e)
{
if (e->tag != Iex_Const) return False;
switch (e->Iex.Const.con->tag) {
@@ -1274,7 +1331,7 @@
}
/* Is this an integer constant with value 1---1b ? */
-static Bool isOnesU ( IRExpr* e )
+static Bool isOnesU(const IRExpr* e)
{
if (e->tag != Iex_Const) return False;
switch (e->Iex.Const.con->tag) {
@@ -1391,14 +1448,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(IRExpr* env[], IRExpr* e)
+static IRExpr* chase(FoldEnv* 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 = env[e->Iex.RdTmp.tmp.index];
+ e = findIRExpr(env, e->Iex.RdTmp.tmp);
if (e == NULL) break;
}
return e;
@@ -1413,7 +1470,7 @@
return env[e->Iex.RdTmp.tmp.index];
}
-static IRExpr* fold_Expr(IRExpr* env[], IRExpr* e)
+static IRExpr* fold_Expr(FoldEnv* env, IRExpr* e)
{
Int shift;
IRExpr* e2 = e; /* e2 is the result of folding e, if possible */
@@ -2473,13 +2530,12 @@
/* Apply the subst to a simple 1-level expression -- guaranteed to be
1-level due to previous flattening pass. */
-
-static IRExpr* subst_Expr(IRExpr* env[], IRExpr* ex)
+static IRExpr* subst_Expr(FoldEnv* env, IRExpr* ex)
{
switch (ex->tag) {
- case Iex_RdTmp:
- if (env[ex->Iex.RdTmp.tmp.index] != NULL) {
- IRExpr *rhs = env[ex->Iex.RdTmp.tmp.index];
+ case Iex_RdTmp: {
+ IRExpr* rhs = findIRExpr(env, ex->Iex.RdTmp.tmp);
+ if (rhs != NULL) {
if (rhs->tag == Iex_RdTmp)
return rhs;
if (rhs->tag == Iex_Const
@@ -2488,6 +2544,7 @@
}
/* not bound in env */
return ex;
+ }
case Iex_Const:
case Iex_Get:
@@ -2584,27 +2641,13 @@
}
}
-/* Set up the cprop env with which travels forward for the current IRStmtVec.
- This holds a substitution, mapping IRTemp.indices to IRExprs.
- Keys are IRTemp.indices. Values are IRExpr*s.
-*/
-static IRExpr** new_cprop_env(const IRTypeEnv* tyenv)
-{
- UInt n_tmps = tyenv->types_used;
- IRExpr** env = LibVEX_Alloc_inline(n_tmps * sizeof(IRExpr*));
- for (UInt i = 0; i < n_tmps; i++)
- env[i] = NULL;
- return env;
-}
-
-static IRStmtVec* subst_and_fold_Stmts(IRExpr* env[], IRStmtVec* in,
- IRStmtVec* parent);
+static IRStmtVec* subst_and_fold_Stmts(FoldEnv* 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(IRExpr* env[], IRStmt* st, IRStmtVec* parent)
+static IRStmt* subst_and_fold_Stmt(FoldEnv* env, IRStmt* st)
{
# if 0
vex_printf("\nsubst and fold stmt\n");
@@ -2832,16 +2875,17 @@
It is necessary to rewrite indices of all IRTemp's in scope.
Not sure if this is possible or feasible. */
}
- return IRStmt_IfThenElse(fcond,
- subst_and_fold_Stmts(
- new_cprop_env(st->Ist.IfThenElse.then_leg->tyenv),
- st->Ist.IfThenElse.then_leg,
- parent),
- subst_and_fold_Stmts(
- new_cprop_env(st->Ist.IfThenElse.then_leg->tyenv),
- st->Ist.IfThenElse.else_leg,
- parent),
- st->Ist.IfThenElse.phi_nodes);
+
+ 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);
+
+ return IRStmt_IfThenElse(fcond, then_stmts, else_stmts,
+ st->Ist.IfThenElse.phi_nodes);
}
default:
@@ -2850,8 +2894,8 @@
}
}
-static
-IRStmtVec* subst_and_fold_Stmts(IRExpr* env[], IRStmtVec* in, IRStmtVec* parent)
+/* Is to be called with already created FoldEnv as per newFoldEnv(). */
+static IRStmtVec* subst_and_fold_Stmts(FoldEnv* env, IRStmtVec* in)
{
/* Keep track of IRStmt_LoadGs that we need to revisit after
processing all the other statements. */
@@ -2859,9 +2903,7 @@
Int fixups[N_FIXUPS]; /* indices in the stmt array of 'out' */
Int n_fixups = 0;
- IRStmtVec* out = emptyIRStmtVec();
- out->tyenv = deepCopyIRTypeEnv( in->tyenv );
- out->parent = parent;
+ IRStmtVec* out = env->stmts;
/* For each original SSA-form stmt ... */
for (UInt i = 0; i < in->stmts_used; i++) {
@@ -2876,7 +2918,7 @@
/* perhaps st2 is already a no-op? */
if (st2->tag == Ist_NoOp) continue;
- st2 = subst_and_fold_Stmt(env, st2, out);
+ st2 = subst_and_fold_Stmt(env, st2);
/* Deal with some post-folding special cases. */
switch (st2->tag) {
@@ -2891,8 +2933,7 @@
propagation and to allow sameIRExpr look through
IRTemps. */
case Ist_WrTmp: {
- vassert(env[st2->Ist.WrTmp.tmp.index] == NULL);
- env[st2->Ist.WrTmp.tmp.index] = st2->Ist.WrTmp.data;
+ setIRExpr(env, 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)
@@ -2993,9 +3034,10 @@
IRSB* cprop_BB ( IRSB* in )
{
- IRExpr** env = new_cprop_env(in->stmts->tyenv);
+ FoldEnv* env = newFoldEnv(in->stmts, NULL);
IRSB* out = emptyIRSB();
- out->stmts = subst_and_fold_Stmts(env, in->stmts, NULL);
+ out->stmts = subst_and_fold_Stmts(env, in->stmts);
+ out->id_seq = in->id_seq;
out->next = subst_Expr( env, in->next );
out->jumpkind = in->jumpkind;
out->offsIP = in->offsIP;
@@ -6247,7 +6289,7 @@
case Iex_RdTmp:
ppIRTemp(e->Iex.RdTmp.tmp);
vex_printf("=");
- print_flat_expr(env, chase(env, e));
+ print_flat_expr(env, chase1(env, e));
break;
case Iex_Const:
case Iex_CCall:
|
|
From: <sv...@va...> - 2017-03-23 17:12:55
|
Author: iraisr
Date: Thu Mar 23 17:12:48 2017
New Revision: 16283
Log:
Use iteration rathen than recursion for accessing parent stuff.
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 Thu Mar 23 17:12:48 2017
@@ -277,24 +277,26 @@
so far exists, allocate one. */
static IRTemp findShadowTmpV ( MCEnv* mce, IRTemp 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);
+ while (mce->id != orig.id) {
+ mce = mce->parent;
+ tl_assert(mce != NULL);
+ }
+ tl_assert(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);
+ 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);
- 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);
+ tl_assert(isIRTempInvalid(ent->shadowV));
+ ent->shadowV = tmpV;
}
+ return ent->shadowV;
}
/* Allocate a new shadow for the given original tmp. This means any
@@ -384,12 +386,14 @@
if (a1->tag == Iex_Const)
return True;
if (a1->tag == Iex_RdTmp) {
- 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);
+ while (mce->id != a1->Iex.RdTmp.tmp.id) {
+ mce = mce->parent;
+ tl_assert(mce != NULL);
}
+ tl_assert(mce->id == a1->Iex.RdTmp.tmp.id);
+
+ TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp.index);
+ return ent->kind == Orig;
}
return False;
}
@@ -401,12 +405,14 @@
if (a1->tag == Iex_Const)
return True;
if (a1->tag == Iex_RdTmp) {
- 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);
+ while (mce->id != a1->Iex.RdTmp.tmp.id) {
+ mce = mce->parent;
+ tl_assert(mce != NULL);
}
+ tl_assert(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;
}
return False;
}
@@ -7045,23 +7051,25 @@
/* Almost identical to findShadowTmpV. */
static IRTemp findShadowTmpB ( MCEnv* mce, IRTemp 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);
+ while (mce->id != orig.id) {
+ mce = mce->parent;
+ tl_assert(mce != NULL);
+ }
+ tl_assert(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);
+ 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);
- 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);
+ tl_assert(isIRTempInvalid(ent->shadowB));
+ ent->shadowB = tmpB;
}
+ return ent->shadowB;
}
static IRAtom* gen_maxU32 ( MCEnv* mce, IRAtom* b1, IRAtom* b2 )
|
|
From: <sv...@va...> - 2017-03-23 17:12:17
|
Author: iraisr
Date: Thu Mar 23 17:12:09 2017
New Revision: 3327
Log:
Use iteration rather than recursion for accessing parent stuff.
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 Thu Mar 23 17:12:09 2017
@@ -3798,15 +3798,16 @@
IRType typeOfIRTemp(const IRStmtVec* stmts, IRTemp tmp)
{
const IRTypeEnv* tyenv = stmts->tyenv;
- if (tyenv->id == tmp.id) {
- vassert(tmp.index >= 0);
- vassert(tmp.index < tyenv->types_used);
- return tyenv->types[tmp.index];
- } else if (stmts->parent != NULL) {
- return typeOfIRTemp(stmts->parent, tmp);
- } else {
- vpanic("typeOfIRTemp");
+ while (tyenv->id != tmp.id) {
+ stmts = stmts->parent;
+ vassert(stmts != NULL);
+ tyenv = stmts->tyenv;
}
+
+ vassert(tyenv->id == tmp.id);
+ vassert(tmp.index >= 0);
+ vassert(tmp.index < tyenv->types_used);
+ return tyenv->types[tmp.index];
}
IRType typeOfIRConst ( const IRConst* con )
@@ -4154,13 +4155,16 @@
{
vassert(tmp.id != IRTyEnvID_INVALID);
- if (stmts->tyenv->id == tmp.id) {
- return True;
- }
- if (stmts->parent != NULL) {
- return inScopeIRTemp(stmts->parent, tmp);
+ const IRTypeEnv* tyenv = stmts->tyenv;
+ while (tyenv->id != tmp.id) {
+ stmts = stmts->parent;
+ if (stmts == NULL)
+ return False;
+ tyenv = stmts->tyenv;
}
- return False;
+
+ vassert(tyenv->id == tmp.id);
+ return True;
}
static
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 Thu Mar 23 17:12:09 2017
@@ -2828,7 +2828,9 @@
Such an IRStmtVec needs to have a valid IRTyEnvId - get it from
nextIRTyEnvID(). Only after this is done, then such an IRStmtVec is ready
for newIRTemp() to give out new temporaries.
- Nested IRStmtVec also needs to have correctly set its parent. */
+ Nested IRStmtVec also needs to have correctly set its parent.
+
+ Function addEmptyIfThenElse() can be used conveniently instead. */
extern IRStmtVec* emptyIRStmtVec(void);
extern IRStmtVec* deepCopyIRStmtVec(const IRStmtVec* src, IRStmtVec* parent);
@@ -3206,6 +3208,11 @@
extern IRTyEnvID nextIRTyEnvID(IRSB*);
+/* Allocates an empty IfThenElse, assigns it a valid IRTyEnvID
+ and sets the parent for both then and else legs.
+ The returned IRStmt is added to the parent IRStmtVec and ready to be used. */
+extern IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond);
+
/*---------------------------------------------------------------*/
/*--- Helper functions for the IR ---*/
/*---------------------------------------------------------------*/
|
|
From: <sv...@va...> - 2017-03-23 09:17:00
|
Author: iraisr
Date: Thu Mar 23 09:16:52 2017
New Revision: 16282
Log:
Make phi_nodes non-optional for IfThenElse.
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 Thu Mar 23 09:16:52 2017
@@ -6295,17 +6295,14 @@
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);
- }
+ IRPhiVec* 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,
|
|
From: <sv...@va...> - 2017-03-23 09:16:33
|
Author: iraisr
Date: Thu Mar 23 09:16:25 2017
New Revision: 3326
Log:
Add new function addEmptyIfThenElse().
Make phi_nodes non-optional for IfThenElse.
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/priv/ir_opt.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 Thu Mar 23 09:16:25 2017
@@ -1693,10 +1693,7 @@
ppIRStmtVec_wrk(s->Ist.IfThenElse.else_leg, depth + 1);
print_depth(depth);
vex_printf("}\n");
- IRPhiVec* phi_nodes = s->Ist.IfThenElse.phi_nodes;
- if (phi_nodes != NULL) {
- ppIRPhiVec_wrk(phi_nodes, depth);
- }
+ ppIRPhiVec_wrk(s->Ist.IfThenElse.phi_nodes, depth);
break;
default:
vpanic("ppIRStmt");
@@ -3747,6 +3744,20 @@
addStmtToIRStmtVec(bb->stmts, st);
}
+IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond)
+{
+ IRStmtVec* then_leg = emptyIRStmtVec();
+ then_leg->tyenv->id = nextIRTyEnvID(bb);
+ then_leg->parent = parent;
+
+ IRStmtVec* else_leg = emptyIRStmtVec();
+ else_leg->tyenv->id = nextIRTyEnvID(bb);
+ else_leg->parent = parent;
+
+ IRStmt* st = IRStmt_IfThenElse(cond, then_leg, else_leg, emptyIRPhiVec());
+ addStmtToIRStmtVec(parent, st);
+ return st;
+}
/*---------------------------------------------------------------*/
/*--- Helper functions for the IR -- IR Type Environments ---*/
@@ -5062,10 +5073,8 @@
n_stmt_vecs, id_counts, gWordTy);
sanityCheckIRStmtVec(bb, else_leg, require_flat, def_counts,
n_stmt_vecs, id_counts, gWordTy);
- if (stmt->Ist.IfThenElse.phi_nodes != NULL) {
- sanityCheckIRPhiNodes(bb, stmts, stmt,
- stmt->Ist.IfThenElse.phi_nodes, def_counts);
- }
+ sanityCheckIRPhiNodes(bb, stmts, stmt,
+ stmt->Ist.IfThenElse.phi_nodes, def_counts);
}
}
}
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 Thu Mar 23 09:16:25 2017
@@ -3166,12 +3166,10 @@
Bool* else_set = new_deadcode_set(st->Ist.IfThenElse.then_leg->tyenv);
IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- if (phi_nodes != NULL) {
- 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);
- }
+ 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);
}
Int i_unconditional_exit; // TODO-JIT: unused at the moment
@@ -4852,10 +4850,8 @@
deltaIRStmtVec(st->Ist.IfThenElse.else_leg, delta, id);
IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- if (phi_nodes != NULL) {
- for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- deltaIRTemp(&phi_nodes->phis[i]->dst, delta, id);
- }
+ for (UInt i = 0; i < phi_nodes->phis_used; i++) {
+ deltaIRTemp(&phi_nodes->phis[i]->dst, delta, id);
}
break;
}
@@ -5409,10 +5405,8 @@
case Ist_IfThenElse: {
aoccCount_Expr(uses, st->Ist.IfThenElse.cond);
IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- if (phi_nodes != NULL) {
- for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- uses[phi_nodes->phis[i]->dst.index]++;
- }
+ for (UInt i = 0; i < phi_nodes->phis_used; i++) {
+ uses[phi_nodes->phis[i]->dst.index]++;
}
return;
}
@@ -6177,14 +6171,12 @@
IRStmtVec* then_leg = st->Ist.IfThenElse.then_leg;
IRStmtVec* else_leg = st->Ist.IfThenElse.else_leg;
IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- if (phi_nodes != NULL) {
- for (UInt j = 0; j < phi_nodes->phis_used; j++) {
- IRPhi* phi = phi_nodes->phis[j];
- addStmtToIRStmtVec(then_leg, IRStmt_WrTmp(phi->dst,
- IRExpr_RdTmp(phi->srcThen)));
- addStmtToIRStmtVec(else_leg, IRStmt_WrTmp(phi->dst,
- IRExpr_RdTmp(phi->srcElse)));
- }
+ for (UInt j = 0; j < phi_nodes->phis_used; j++) {
+ IRPhi* phi = phi_nodes->phis[j];
+ addStmtToIRStmtVec(then_leg, IRStmt_WrTmp(phi->dst,
+ IRExpr_RdTmp(phi->srcThen)));
+ addStmtToIRStmtVec(else_leg, IRStmt_WrTmp(phi->dst,
+ IRExpr_RdTmp(phi->srcElse)));
}
deconstruct_phi_nodes_IRStmtVec(then_leg);
|
|
From: <sv...@va...> - 2017-03-23 08:58:01
|
Author: iraisr
Date: Thu Mar 23 08:57:52 2017
New Revision: 3325
Log:
Use ppIRStmt_wrk() also in VEX/priv/guest_amd64_toIR.c.
Modified:
branches/VEX_JIT_HACKS/priv/guest_amd64_toIR.c
Modified: branches/VEX_JIT_HACKS/priv/guest_amd64_toIR.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/guest_amd64_toIR.c (original)
+++ branches/VEX_JIT_HACKS/priv/guest_amd64_toIR.c Thu Mar 23 08:57:52 2017
@@ -32374,8 +32374,7 @@
callback_opaque,
delta, archinfo, abiinfo, sigill_diag_IN );
for (i = x1; i < x2; i++) {
- vex_printf("\t\t");
- ppIRStmt(irsb_IN->stmts[i]);
+ ppIRStmt_wrk(irsb_IN->stmts[i], 4);
vex_printf("\n");
}
/* Failure of this assertion is serious and denotes a bug in
|
|
From: <sv...@va...> - 2017-03-22 23:42:02
|
Author: iraisr
Date: Wed Mar 22 23:41:55 2017
New Revision: 16281
Log:
Necessary changes in Memcheck for pretty printing nested IRStmt's.
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 Wed Mar 22 23:41:55 2017
@@ -207,6 +207,7 @@
IRStmtVec* stmts;
IRTypeEnv* tyenv;
IRTyEnvID id;
+ UInt depth; /* for indenting properly nested statements */
/* MODIFIED: a table [0 .. #temps_in_sb-1] which gives the
current kind and possibly shadow temps for each temp in the
@@ -337,6 +338,7 @@
mce->stmts = stmts_out;
mce->tyenv = stmts_out->tyenv;
mce->id = mce->tyenv->id;
+ mce->depth = (parent_mce != NULL) ? parent_mce->depth + 1 : 0;
mce->parent = parent_mce;
mce->settings = (parent_mce != NULL) ? parent_mce->settings : NULL;
@@ -6497,7 +6499,7 @@
if (mce->settings->trace) {
VG_(printf)("\n");
- ppIRStmt(st);
+ ppIRStmt_wrk(st, mce->depth);
VG_(printf)("\n");
}
@@ -6604,8 +6606,7 @@
if (0 && mce->settings->trace) {
for (UInt j = first_stmt; j < mce->stmts->stmts_used; j++) {
- VG_(printf)(" ");
- ppIRStmt(mce->stmts->stmts[j]);
+ ppIRStmt_wrk(mce->stmts->stmts[j], mce->depth + 1);
VG_(printf)("\n");
}
VG_(printf)("\n");
@@ -6763,8 +6764,7 @@
if (0 && verboze) {
for (UInt j = first_stmt; j < sb_out->stmts->stmts_used; j++) {
- VG_(printf)(" ");
- ppIRStmt(sb_out->stmts->stmts[j]);
+ ppIRStmt_wrk(sb_out->stmts->stmts[j], 1);
VG_(printf)("\n");
}
VG_(printf)("\n");
|
|
From: <sv...@va...> - 2017-03-22 23:40:52
|
Author: iraisr
Date: Wed Mar 22 23:40:44 2017
New Revision: 3324
Log:
Support pretty printing IRStmt's with proper indentation depth.
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/ir_defs.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h
branches/VEX_JIT_HACKS/useful/test_main.c
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 Wed Mar 22 23:40:44 2017
@@ -392,10 +392,9 @@
imark->Ist.IMark.len = dres.len;
/* Print the resulting IR, if needed. */
- if (vex_traceflags & VEX_TRACE_FE) {
+ if (debug_print) {
for (i = first_stmt_idx; i < irsb->stmts->stmts_used; i++) {
- vex_printf(" ");
- ppIRStmt(irsb->stmts->stmts[i]);
+ ppIRStmt_wrk(irsb->stmts->stmts[i], 3);
vex_printf("\n");
}
}
@@ -753,7 +752,7 @@
Print it if necessary.*/
vassert(irsb->next != NULL);
if (debug_print) {
- vex_printf(" ");
+ vex_printf(" ");
vex_printf( "PUT(%d) = ", irsb->offsIP);
ppIRExpr( irsb->next );
vex_printf( "; exit-");
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 Wed Mar 22 23:40:44 2017
@@ -15475,8 +15475,7 @@
callback_opaque,
delta, archinfo, abiinfo, sigill_diag_IN );
for (i = x1; i < x2; i++) {
- vex_printf("\t\t");
- ppIRStmt(irsb_IN->stmts->stmts[i]);
+ ppIRStmt_wrk(irsb_IN->stmts->stmts[i], 4);
vex_printf("\n");
}
/* Failure of this assertion is serious and denotes a bug in
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 Wed Mar 22 23:40:44 2017
@@ -1579,17 +1579,30 @@
vex_printf(")");
}
-void ppIRPhiVec(const IRPhiVec* phis)
+static void print_depth(UInt depth) {
+ for (UInt i = 0; i < depth; i++) {
+ vex_printf(" ");
+ }
+}
+
+static void ppIRPhiVec_wrk(const IRPhiVec* phis, UInt depth)
{
for (UInt i = 0; i < phis->phis_used; i++) {
- vex_printf(" ");
+ print_depth(depth);
ppIRPhi(phis->phis[i]);
vex_printf("\n");
}
}
-void ppIRStmt ( const IRStmt* s )
+void ppIRPhiVec(const IRPhiVec* phis)
{
+ ppIRPhiVec_wrk(phis, 0);
+}
+
+void ppIRStmt_wrk(const IRStmt* s, UInt depth)
+{
+ print_depth(depth);
+
if (!s) {
vex_printf("!!! IRStmt* which is NULL !!!");
return;
@@ -1674,13 +1687,15 @@
vex_printf("if (");
ppIRExpr(s->Ist.IfThenElse.cond);
vex_printf(") then {\n");
- ppIRStmtVec(s->Ist.IfThenElse.then_leg); // TODO-JIT: indent properly
+ ppIRStmtVec_wrk(s->Ist.IfThenElse.then_leg, depth + 1);
+ print_depth(depth);
vex_printf("} else {\n");
- ppIRStmtVec(s->Ist.IfThenElse.else_leg); // TODO-JIT: indent properly
+ ppIRStmtVec_wrk(s->Ist.IfThenElse.else_leg, depth + 1);
+ print_depth(depth);
vex_printf("}\n");
IRPhiVec* phi_nodes = s->Ist.IfThenElse.phi_nodes;
if (phi_nodes != NULL) {
- ppIRPhiVec(phi_nodes);
+ ppIRPhiVec_wrk(phi_nodes, depth);
}
break;
default:
@@ -1688,11 +1703,16 @@
}
}
-void ppIRTypeEnv ( const IRTypeEnv* env )
+void ppIRStmt(const IRStmt* s)
+{
+ ppIRStmt_wrk(s, 0);
+}
+
+static void ppIRTypeEnv_wrk(const IRTypeEnv* env, UInt depth)
{
for (UInt i = 0; i < env->types_used; i++) {
if (i % 8 == 0)
- vex_printf( " ");
+ print_depth(depth);
IRTemp temp = mkIRTemp(env->id, i);
ppIRTemp(temp);
vex_printf("=");
@@ -1706,23 +1726,34 @@
vex_printf( "\n");
}
-/* TODO-JIT: account for indentation */
-void ppIRStmtVec(const IRStmtVec* stmts)
+void ppIRTypeEnv(const IRTypeEnv* env)
+{
+ ppIRTypeEnv_wrk(env, 0);
+}
+
+void ppIRStmtVec_wrk(const IRStmtVec* stmts, UInt depth)
{
- ppIRTypeEnv(stmts->tyenv);
+ ppIRTypeEnv_wrk(stmts->tyenv, depth);
vex_printf("\n");
for (UInt i = 0; i < stmts->stmts_used; i++) {
- vex_printf( " ");
- ppIRStmt(stmts->stmts[i]);
+ ppIRStmt_wrk(stmts->stmts[i], depth);
vex_printf("\n");
}
}
+void ppIRStmtVec(const IRStmtVec* stmts)
+{
+ ppIRStmtVec_wrk(stmts, 0);
+}
+
void ppIRSB ( const IRSB* bb )
{
+ UInt depth = 0;
+
vex_printf("IRSB {\n");
- ppIRStmtVec(bb->stmts);
- vex_printf( " PUT(%d) = ", bb->offsIP );
+ ppIRStmtVec_wrk(bb->stmts, depth + 1);
+ print_depth(depth + 1);
+ vex_printf("PUT(%d) = ", bb->offsIP);
ppIRExpr( bb->next );
vex_printf( "; exit-");
ppIRJumpKind(bb->jumpkind);
@@ -4053,7 +4084,7 @@
ppIRSB(bb);
if (stmt) {
vex_printf("\nIN STATEMENT:\n\n");
- ppIRStmt(stmt);
+ ppIRStmt_wrk(stmt, 1);
}
vex_printf("\n\nERROR = %s\n\n", what );
vpanic("sanityCheckFail: exiting due to bad IR");
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 Wed Mar 22 23:40:44 2017
@@ -2822,6 +2822,7 @@
IRStmtVec;
extern void ppIRStmtVec(const IRStmtVec*);
+extern void ppIRStmtVec_wrk(const IRStmtVec*, UInt depth);
/* Allocates an empty IRStmtVec with an invalid IRTyEnvID.
Such an IRStmtVec needs to have a valid IRTyEnvId - get it from
@@ -3155,6 +3156,7 @@
/* Pretty-print an IRStmt. */
extern void ppIRStmt ( const IRStmt* );
+extern void ppIRStmt_wrk(const IRStmt*, UInt depth);
/* ------------------ Basic Blocks ------------------ */
Modified: branches/VEX_JIT_HACKS/useful/test_main.c
==============================================================================
--- branches/VEX_JIT_HACKS/useful/test_main.c (original)
+++ branches/VEX_JIT_HACKS/useful/test_main.c Wed Mar 22 23:40:44 2017
@@ -2715,8 +2715,7 @@
if (verboze) {
for (UInt j = first_stmt; j < bb->stmts->stmts_used; j++) {
- VG_(printf)(" ");
- ppIRStmt(bb->stmts->stmts[j]);
+ ppIRStmt_wrk(bb->stmts->stmts[j], 1);
VG_(printf)("\n");
}
VG_(printf)("\n");
@@ -2739,8 +2738,7 @@
if (verboze) {
for (UInt j = first_stmt; j < bb->stmts->stmts_used; j++) {
- VG_(printf)(" ");
- ppIRStmt(bb->stmts->stmts[j]);
+ ppIRStmt_wrk(bb->stmts->stmts[j], 1);
VG_(printf)("\n");
}
VG_(printf)("\n");
|
|
From: <sv...@va...> - 2017-03-22 22:02:20
|
Author: iraisr
Date: Wed Mar 22 22:02:13 2017
New Revision: 16280
Log:
Necessary changes for typeOfIRTemp() and typeOfIRExpr()
in coregrind and memcheck.
Modified:
branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c
branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
Modified: branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c (original)
+++ branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c Wed Mar 22 22:02:13 2017
@@ -406,7 +406,7 @@
if (e->tag != Iex_Get) goto case2;
if (e->Iex.Get.offset != offset_SP) goto case2;
if (e->Iex.Get.ty != typeof_SP) goto case2;
- vg_assert( typeOfIRTemp(out->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(out, st->Ist.WrTmp.tmp) == typeof_SP );
add_SP_alias(st->Ist.WrTmp.tmp, 0);
addStmtToIRStmtVec(out, st);
continue;
@@ -421,7 +421,7 @@
if (e->Iex.Binop.arg2->tag != Iex_Const) goto case3;
if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3;
con = GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
- vg_assert( typeOfIRTemp(out->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(out, st->Ist.WrTmp.tmp) == typeof_SP );
if (IS_ADD(e->Iex.Binop.op)) {
add_SP_alias(st->Ist.WrTmp.tmp, delta + con);
} else {
@@ -436,7 +436,7 @@
e = st->Ist.WrTmp.data;
if (e->tag != Iex_RdTmp) goto case4;
if (!get_SP_delta(e->Iex.RdTmp.tmp, &delta)) goto case4;
- vg_assert( typeOfIRTemp(out->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(out, st->Ist.WrTmp.tmp) == typeof_SP );
add_SP_alias(st->Ist.WrTmp.tmp, delta);
addStmtToIRStmtVec(out, st);
continue;
@@ -451,7 +451,7 @@
last_SP = first_SP + sizeof_SP - 1;
first_Put = st->Ist.Put.offset;
last_Put = first_Put
- + sizeofIRType(typeOfIRExpr(out->tyenv, st->Ist.Put.data))
+ + sizeofIRType(typeOfIRExpr(out, st->Ist.Put.data))
- 1;
vg_assert(first_SP <= last_SP);
vg_assert(first_Put <= last_Put);
@@ -469,7 +469,7 @@
put_SP_alias is immediately preceded by an assertion that
we are putting in a binding for a correctly-typed
temporary. */
- vg_assert( typeOfIRTemp(out->tyenv, tttmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(out, tttmp) == typeof_SP );
/* From the same type-and-offset-correctness argument, if
we found a useable alias, it must for an "exact" write of SP. */
vg_assert(first_SP == first_Put);
@@ -609,7 +609,7 @@
if (first_Put == first_SP && last_Put == last_SP
&& st->Ist.Put.data->tag == Iex_RdTmp) {
- vg_assert( typeOfIRTemp(out->tyenv, st->Ist.Put.data->Iex.RdTmp.tmp)
+ vg_assert( typeOfIRTemp(out, st->Ist.Put.data->Iex.RdTmp.tmp)
== typeof_SP );
add_SP_alias(st->Ist.Put.data->Iex.RdTmp.tmp, 0);
}
@@ -1029,11 +1029,11 @@
static IRExpr* mkU8 ( UChar n ) {
return IRExpr_Const(IRConst_U8(n));
}
-static IRExpr* narrowTo32 ( IRTypeEnv* tyenv, IRExpr* e ) {
- if (typeOfIRExpr(tyenv, e) == Ity_I32) {
+static IRExpr* narrowTo32 ( IRStmtVec* stmts, IRExpr* e ) {
+ if (typeOfIRExpr(stmts, e) == Ity_I32) {
return e;
} else {
- vg_assert(typeOfIRExpr(tyenv, e) == Ity_I64);
+ vg_assert(typeOfIRExpr(stmts, e) == Ity_I64);
return IRExpr_Unop(Iop_64to32, e);
}
}
@@ -1086,7 +1086,7 @@
t1 = newIRTemp( bb->tyenv, ty_Word );
one = mkU(1);
- vg_assert(typeOfIRExpr(bb->tyenv, e) == ty_Word);
+ vg_assert(typeOfIRExpr(bb->stmts, e) == ty_Word);
/* t1 = guest_REDIR_SP + 1 */
addStmtToIRSB(
@@ -1132,7 +1132,7 @@
addStmtToIRSB(
bb,
IRStmt_PutI(mkIRPutI(descr,
- narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0, e)));
+ narrowTo32(bb->stmts, IRExpr_RdTmp(t1)), 0, e)));
}
@@ -1212,7 +1212,7 @@
bb,
IRStmt_WrTmp(
res,
- IRExpr_GetI(descr, narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0)
+ IRExpr_GetI(descr, narrowTo32(bb->stmts, IRExpr_RdTmp(t1)), 0)
)
);
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 Wed Mar 22 22:02:13 2017
@@ -220,7 +220,7 @@
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
+ "typeOfIRExpr(mce->stmts, ...)" at various places in the
instrumentation process. */
XArray* /* of TempMapEnt */ tmpMap;
@@ -525,7 +525,7 @@
{
TempKind k;
IRTemp t;
- IRType tyE = typeOfIRExpr(mce->tyenv, e);
+ IRType tyE = typeOfIRExpr(mce->stmts, e);
tl_assert(tyE == ty); /* so 'ty' is redundant (!) */
switch (cat) {
@@ -829,7 +829,7 @@
/* Note, dst_ty is a shadow type, not an original type. */
tl_assert(isShadowAtom(mce,vbits));
- src_ty = typeOfIRExpr(mce->tyenv, vbits);
+ src_ty = typeOfIRExpr(mce->stmts, vbits);
/* Fast-track some common cases */
if (src_ty == Ity_I32 && dst_ty == Ity_I32)
@@ -1319,7 +1319,7 @@
tl_assert(isShadowAtom(mce, vatom));
tl_assert(sameKindedAtoms(atom, vatom));
- ty = typeOfIRExpr(mce->tyenv, vatom);
+ ty = typeOfIRExpr(mce->stmts, vatom);
/* sz is only used for constructing the error message */
sz = ty==Ity_I1 ? 0 : sizeofIRType(ty);
@@ -1532,7 +1532,7 @@
tl_assert(isShadowAtom(mce, vatom));
}
- ty = typeOfIRExpr(mce->tyenv, vatom);
+ ty = typeOfIRExpr(mce->stmts, vatom);
tl_assert(ty != Ity_I1);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* later: no ... */
@@ -1659,8 +1659,8 @@
IRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->tyenv, va2);
+ IRType t1 = typeOfIRExpr(mce->stmts, va1);
+ IRType t2 = typeOfIRExpr(mce->stmts, va2);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
@@ -1716,9 +1716,9 @@
IRAtom* va1, IRAtom* va2, IRAtom* va3 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->tyenv, va2);
- IRType t3 = typeOfIRExpr(mce->tyenv, va3);
+ IRType t1 = typeOfIRExpr(mce->stmts, va1);
+ IRType t2 = typeOfIRExpr(mce->stmts, va2);
+ IRType t3 = typeOfIRExpr(mce->stmts, va3);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
tl_assert(isShadowAtom(mce,va3));
@@ -1850,10 +1850,10 @@
IRAtom* va1, IRAtom* va2, IRAtom* va3, IRAtom* va4 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->tyenv, va2);
- IRType t3 = typeOfIRExpr(mce->tyenv, va3);
- IRType t4 = typeOfIRExpr(mce->tyenv, va4);
+ IRType t1 = typeOfIRExpr(mce->stmts, va1);
+ IRType t2 = typeOfIRExpr(mce->stmts, va2);
+ IRType t3 = typeOfIRExpr(mce->stmts, va3);
+ IRType t4 = typeOfIRExpr(mce->stmts, va4);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
tl_assert(isShadowAtom(mce,va3));
@@ -1952,7 +1952,7 @@
tl_assert(isOriginalAtom(mce, exprvec[i]));
if (cee->mcx_mask & (1<<i))
continue;
- if (typeOfIRExpr(mce->tyenv, exprvec[i]) != Ity_I64)
+ if (typeOfIRExpr(mce->stmts, exprvec[i]) != Ity_I64)
mergeTy64 = False;
}
@@ -5028,7 +5028,7 @@
vbitsC = expr2vbits(mce, cond);
vbits1 = expr2vbits(mce, iftrue);
vbits0 = expr2vbits(mce, iffalse);
- ty = typeOfIRExpr(mce->tyenv, vbits0);
+ ty = typeOfIRExpr(mce->stmts, vbits0);
return
mkUifU(mce, ty, assignNew('V', mce, ty,
@@ -5054,7 +5054,7 @@
return IRExpr_RdTmp( findShadowTmpV(mce, e->Iex.RdTmp.tmp) );
case Iex_Const:
- return definedOfType(shadowTypeV(typeOfIRExpr(mce->tyenv, e)));
+ return definedOfType(shadowTypeV(typeOfIRExpr(mce->stmts, e)));
case Iex_Qop:
return expr2vbits_Qop(
@@ -5119,7 +5119,7 @@
/* vatom is vbits-value and as such can only have a shadow type. */
tl_assert(isShadowAtom(mce,vatom));
- ty = typeOfIRExpr(mce->tyenv, vatom);
+ ty = typeOfIRExpr(mce->stmts, vatom);
tyH = mce->settings->hWordTy;
if (tyH == Ity_I32) {
@@ -5199,10 +5199,10 @@
if (guard) {
tl_assert(isOriginalAtom(mce, guard));
- tl_assert(typeOfIRExpr(mce->tyenv, guard) == Ity_I1);
+ tl_assert(typeOfIRExpr(mce->stmts, guard) == Ity_I1);
}
- ty = typeOfIRExpr(mce->tyenv, vdata);
+ ty = typeOfIRExpr(mce->stmts, 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
@@ -5530,7 +5530,7 @@
tl_assert(d->mAddr);
complainIfUndefined(mce, d->mAddr, d->guard);
- tyAddr = typeOfIRExpr(mce->tyenv, d->mAddr);
+ tyAddr = typeOfIRExpr(mce->stmts, d->mAddr);
tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
tl_assert(tyAddr == mce->settings->hWordTy); /* not really right */
}
@@ -5581,7 +5581,7 @@
/* Outputs: the destination temporary, if there is one. */
if (!isIRTempInvalid(d->tmp)) {
dst = findShadowTmpV(mce, d->tmp);
- tyDst = typeOfIRTemp(mce->tyenv, d->tmp);
+ tyDst = typeOfIRTemp(mce->stmts, d->tmp);
assign( 'V', mce, dst, mkPCastTo( mce, tyDst, curr) );
}
@@ -5913,7 +5913,7 @@
tl_assert(cas->expdHi == NULL);
tl_assert(cas->dataHi == NULL);
- elemTy = typeOfIRExpr(mce->tyenv, cas->expdLo);
+ elemTy = typeOfIRExpr(mce->stmts, cas->expdLo);
switch (elemTy) {
case Ity_I8: elemSzB = 1; opCasCmpEQ = Iop_CasCmpEQ8; break;
case Ity_I16: elemSzB = 2; opCasCmpEQ = Iop_CasCmpEQ16; break;
@@ -6007,7 +6007,7 @@
tl_assert(cas->expdHi != NULL);
tl_assert(cas->dataHi != NULL);
- elemTy = typeOfIRExpr(mce->tyenv, cas->expdLo);
+ elemTy = typeOfIRExpr(mce->stmts, cas->expdLo);
switch (elemTy) {
case Ity_I8:
opCasCmpEQ = Iop_CasCmpEQ8; opOr = Iop_Or8; opXor = Iop_Xor8;
@@ -6161,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->tyenv, stResult);
+ IRType resTy = typeOfIRTemp(mce->stmts, stResult);
IRTemp resTmp = findShadowTmpV(mce, stResult);
tl_assert(isIRAtom(stAddr));
@@ -6182,7 +6182,7 @@
} else {
/* Store Conditional */
/* Stay sane */
- IRType dataTy = typeOfIRExpr(mce->tyenv,
+ IRType dataTy = typeOfIRExpr(mce->stmts,
stStoredata);
tl_assert(dataTy == Ity_I64 || dataTy == Ity_I32
|| dataTy == Ity_I16 || dataTy == Ity_I8);
@@ -6728,11 +6728,11 @@
no need to assert that here. */
IRTemp tmp_o = sb_in->stmts->stmts[j]->Ist.WrTmp.tmp;
IRTemp tmp_v = findShadowTmpV(&mce, tmp_o);
- IRType ty_v = typeOfIRTemp(mce.tyenv, tmp_v);
+ IRType ty_v = typeOfIRTemp(mce.stmts, 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(mce.tyenv, tmp_b) == Ity_I32);
+ tl_assert(typeOfIRTemp(mce.stmts, tmp_b) == Ity_I32);
assign('B', &mce, tmp_b, mkU32(0)/* UNKNOWN ORIGIN */);
}
if (0) {
@@ -7089,7 +7089,7 @@
const HChar* hName;
IRTemp bTmp;
IRDirty* di;
- IRType aTy = typeOfIRExpr( mce->tyenv, baseaddr );
+ IRType aTy = typeOfIRExpr(mce->stmts, baseaddr);
IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
IRAtom* ea = baseaddr;
if (offset != 0) {
@@ -7204,12 +7204,12 @@
void* hFun;
const HChar* hName;
IRDirty* di;
- IRType aTy = typeOfIRExpr( mce->tyenv, baseaddr );
+ IRType aTy = typeOfIRExpr(mce->stmts, baseaddr);
IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
IRAtom* ea = baseaddr;
if (guard) {
tl_assert(isOriginalAtom(mce, guard));
- tl_assert(typeOfIRExpr(mce->tyenv, guard) == Ity_I1);
+ tl_assert(typeOfIRExpr(mce->stmts, guard) == Ity_I1);
}
if (offset != 0) {
IRAtom* off = aTy == Ity_I32 ? mkU32( offset )
@@ -7252,7 +7252,7 @@
}
static IRAtom* narrowTo32 ( MCEnv* mce, IRAtom* e ) {
- IRType eTy = typeOfIRExpr(mce->tyenv, e);
+ IRType eTy = typeOfIRExpr(mce->stmts, e);
if (eTy == Ity_I64)
return assignNew( 'B', mce, Ity_I32, unop(Iop_64to32, e) );
if (eTy == Ity_I32)
@@ -7261,7 +7261,7 @@
}
static IRAtom* zWidenFrom32 ( MCEnv* mce, IRType dstTy, IRAtom* e ) {
- IRType eTy = typeOfIRExpr(mce->tyenv, e);
+ IRType eTy = typeOfIRExpr(mce->stmts, e);
tl_assert(eTy == Ity_I32);
if (dstTy == Ity_I64)
return assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, e) );
@@ -7627,7 +7627,7 @@
XXXX how does this actually ensure that?? */
tl_assert(isIRAtom(stAddr));
tl_assert(isIRAtom(stData));
- dszB = sizeofIRType( typeOfIRExpr(mce->tyenv, stData ) );
+ dszB = sizeofIRType( typeOfIRExpr(mce->stmts, stData ) );
dataB = schemeE( mce, stData );
gen_store_b( mce, dszB, stAddr, 0/*offset*/, dataB, guard );
}
@@ -7746,7 +7746,7 @@
if (st->Ist.LLSC.storedata == NULL) {
/* Load Linked */
IRType resTy
- = typeOfIRTemp(mce->tyenv, st->Ist.LLSC.result);
+ = typeOfIRTemp(mce->stmts, 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
@@ -7772,7 +7772,7 @@
Int b_offset
= MC_(get_otrack_shadow_offset)(
st->Ist.Put.offset,
- sizeofIRType(typeOfIRExpr(mce->tyenv, st->Ist.Put.data))
+ sizeofIRType(typeOfIRExpr(mce->stmts, st->Ist.Put.data))
);
if (b_offset >= 0) {
/* FIXME: this isn't an atom! */
|
Author: iraisr
Date: Wed Mar 22 22:00:23 2017
New Revision: 3323
Log:
Let typeOfIRTemp() and typeOfIRExpr() figure out the type of any
IRTemp or IRExpr within the scope of current IRStmtVec.
Modified:
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
branches/VEX_JIT_HACKS/useful/test_main.c
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 Wed Mar 22 22:00:23 2017
@@ -548,7 +548,7 @@
/* Ditto, but write to a reg instead. */
static void putIReg ( Int sz, UInt archreg, IRExpr* e )
{
- IRType ty = typeOfIRExpr(irsb->stmts->tyenv, e);
+ IRType ty = typeOfIRExpr(irsb->stmts, e);
switch (sz) {
case 1: vassert(ty == Ity_I8); break;
case 2: vassert(ty == Ity_I16); break;
@@ -566,7 +566,7 @@
static void putSReg ( UInt sreg, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I16);
stmt( IRStmt_Put( segmentGuestRegOffset(sreg), e ) );
}
@@ -597,37 +597,37 @@
static void putXMMReg ( UInt xmmreg, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_V128);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_V128);
stmt( IRStmt_Put( xmmGuestRegOffset(xmmreg), e ) );
}
static void putXMMRegLane64 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I64);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I64);
stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );
}
static void putXMMRegLane64F ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_F64);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_F64);
stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );
}
static void putXMMRegLane32F ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_F32);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_F32);
stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );
}
static void putXMMRegLane32 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I32);
stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );
}
static void putXMMRegLane16 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I16);
stmt( IRStmt_Put( xmmGuestRegLane16offset(xmmreg,laneno), e ) );
}
@@ -735,8 +735,8 @@
static IRExpr* mkAnd1 ( IRExpr* x, IRExpr* y )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, x) == Ity_I1);
- vassert(typeOfIRExpr(irsb->stmts->tyenv, y) == Ity_I1);
+ vassert(typeOfIRExpr(irsb->stmts, x) == Ity_I1);
+ vassert(typeOfIRExpr(irsb->stmts, y) == Ity_I1);
return unop(Iop_32to1,
binop(Iop_And32,
unop(Iop_1Uto32,x),
@@ -753,8 +753,8 @@
Addr32 restart_point )
{
IRCAS* cas;
- IRType tyE = typeOfIRExpr(irsb->stmts->tyenv, expVal);
- IRType tyN = typeOfIRExpr(irsb->stmts->tyenv, newVal);
+ IRType tyE = typeOfIRExpr(irsb->stmts, expVal);
+ IRType tyN = typeOfIRExpr(irsb->stmts, newVal);
IRTemp oldTmp = newTemp(tyE);
IRTemp expTmp = newTemp(tyE);
vassert(tyE == tyN);
@@ -868,7 +868,7 @@
/* U-widen 8/16/32 bit int expr to 32. */
static IRExpr* widenUto32 ( IRExpr* e )
{
- switch (typeOfIRExpr(irsb->stmts->tyenv, e)) {
+ switch (typeOfIRExpr(irsb->stmts, e)) {
case Ity_I32: return e;
case Ity_I16: return unop(Iop_16Uto32,e);
case Ity_I8: return unop(Iop_8Uto32,e);
@@ -879,7 +879,7 @@
/* S-widen 8/16/32 bit int expr to 32. */
static IRExpr* widenSto32 ( IRExpr* e )
{
- switch (typeOfIRExpr(irsb->stmts->tyenv, e)) {
+ switch (typeOfIRExpr(irsb->stmts, e)) {
case Ity_I32: return e;
case Ity_I16: return unop(Iop_16Sto32,e);
case Ity_I8: return unop(Iop_8Sto32,e);
@@ -891,7 +891,7 @@
of these combinations make sense. */
static IRExpr* narrowTo ( IRType dst_ty, IRExpr* e )
{
- IRType src_ty = typeOfIRExpr(irsb->stmts->tyenv, e);
+ IRType src_ty = typeOfIRExpr(irsb->stmts, e);
if (src_ty == dst_ty)
return e;
if (src_ty == Ity_I32 && dst_ty == Ity_I16)
@@ -1133,7 +1133,7 @@
IROp plus = mkSizedOp(ty, Iop_Add8);
IROp xor = mkSizedOp(ty, Iop_Xor8);
- vassert(typeOfIRTemp(irsb->stmts->tyenv, tres) == ty);
+ vassert(typeOfIRTemp(irsb->stmts, 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);
@@ -1156,7 +1156,7 @@
vassert(restart_point == 0);
storeLE( mkexpr(taddr), mkexpr(tres) );
} else {
- vassert(typeOfIRTemp(irsb->stmts->tyenv, texpVal) == ty);
+ vassert(typeOfIRTemp(irsb->stmts, texpVal) == ty);
/* .. and hence 'texpVal' has the same type as 'tres'. */
casLE( mkexpr(taddr),
mkexpr(texpVal), mkexpr(tres), restart_point );
@@ -1187,7 +1187,7 @@
IROp minus = mkSizedOp(ty, Iop_Sub8);
IROp xor = mkSizedOp(ty, Iop_Xor8);
- vassert(typeOfIRTemp(irsb->stmts->tyenv, tres) == ty);
+ vassert(typeOfIRTemp(irsb->stmts, 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);
@@ -1210,7 +1210,7 @@
vassert(restart_point == 0);
storeLE( mkexpr(taddr), mkexpr(tres) );
} else {
- vassert(typeOfIRTemp(irsb->stmts->tyenv, texpVal) == ty);
+ vassert(typeOfIRTemp(irsb->stmts, texpVal) == ty);
/* .. and hence 'texpVal' has the same type as 'tres'. */
casLE( mkexpr(taddr),
mkexpr(texpVal), mkexpr(tres), restart_point );
@@ -3451,7 +3451,7 @@
static void put_emwarn ( IRExpr* e /* :: Ity_I32 */ )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I32);
stmt( IRStmt_Put( OFFB_EMNOTE, e ) );
}
@@ -3475,7 +3475,7 @@
static void put_ftop ( IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->stmts, 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->tyenv, value) == Ity_I8);
+ vassert(typeOfIRExpr(irsb->stmts, 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->tyenv, value) == Ity_F64);
+ vassert(typeOfIRExpr(irsb->stmts, 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->tyenv, sw) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->stmts, 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->tyenv, e) == Ity_I64);
+ vassert(typeOfIRExpr(irsb->stmts, e) == Ity_I64);
stmt( IRStmt_Put( OFFB_FPREGS + 8 * archreg, e ) );
}
@@ -7542,7 +7542,7 @@
static void put_sse_roundingmode ( IRExpr* sseround )
{
- vassert(typeOfIRExpr(irsb->stmts->tyenv, sseround) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->stmts, sseround) == Ity_I32);
stmt( IRStmt_Put( OFFB_SSEROUND, sseround ) );
}
@@ -7642,7 +7642,7 @@
Bool emit_AC_emwarn,
Addr32 next_insn_EIP )
{
- vassert(typeOfIRTemp(irsb->stmts->tyenv,t1) == Ity_I32);
+ vassert(typeOfIRTemp(irsb->stmts,t1) == Ity_I32);
/* t1 is the flag word. Mask out everything except OSZACP and set
the flags thunk to X86G_CC_OP_COPY. */
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 Wed Mar 22 22:00:23 2017
@@ -172,7 +172,7 @@
typedef
struct {
/* Constant -- are set at the start and do not change. */
- IRTypeEnv* type_env;
+ IRStmtVec* stmts;
HReg* vregmap;
HReg* vregmapHI;
@@ -359,7 +359,7 @@
return 1;
}
/* Else it's a "normal" expression. */
- IRType arg_ty = typeOfIRExpr(env->type_env, arg);
+ IRType arg_ty = typeOfIRExpr(env->stmts, arg);
if (arg_ty == Ity_I32) {
addInstr(env, X86Instr_Push(iselIntExpr_RMI(env, arg)));
return 1;
@@ -593,7 +593,7 @@
else if (UNLIKELY(arg->tag == Iex_GSPTR)) {
vassert(0); //ATC
} else {
- vassert(typeOfIRExpr(env->type_env, arg) == Ity_I32);
+ vassert(typeOfIRExpr(env->stmts, arg) == Ity_I32);
tmpregs[argreg] = iselIntExpr_R(env, arg);
}
not_done_yet--;
@@ -620,7 +620,7 @@
else if (UNLIKELY(arg->tag == Iex_GSPTR)) {
vassert(0); //ATC
} else {
- vassert(typeOfIRExpr(env->type_env, arg) == Ity_I32);
+ vassert(typeOfIRExpr(env->stmts, arg) == Ity_I32);
addInstr(env, X86Instr_Alu32R(Xalu_MOV,
iselIntExpr_RMI(env, arg),
argregs[argreg]));
@@ -854,7 +854,7 @@
{
MatchInfo mi;
- IRType ty = typeOfIRExpr(env->type_env,e);
+ IRType ty = typeOfIRExpr(env->stmts, e);
vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
switch (e->tag) {
@@ -1495,7 +1495,7 @@
/* --------- MULTIPLEX --------- */
case Iex_ITE: { // VFD
if ((ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8)
- && typeOfIRExpr(env->type_env,e->Iex.ITE.cond) == Ity_I1) {
+ && typeOfIRExpr(env->stmts, 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 +1558,7 @@
/* DO NOT CALL THIS DIRECTLY ! */
static X86AMode* iselIntExpr_AMode_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->type_env,e);
+ IRType ty = typeOfIRExpr(env->stmts, e);
vassert(ty == Ity_I32);
/* Add32( Add32(expr1, Shl32(expr2, simm)), imm32 ) */
@@ -1645,7 +1645,7 @@
/* DO NOT CALL THIS DIRECTLY ! */
static X86RMI* iselIntExpr_RMI_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->type_env,e);
+ IRType ty = typeOfIRExpr(env->stmts, e);
vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
/* special case: immediate */
@@ -1705,7 +1705,7 @@
/* DO NOT CALL THIS DIRECTLY ! */
static X86RI* iselIntExpr_RI_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->type_env,e);
+ IRType ty = typeOfIRExpr(env->stmts, e);
vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
/* special case: immediate */
@@ -1753,7 +1753,7 @@
/* DO NOT CALL THIS DIRECTLY ! */
static X86RM* iselIntExpr_RM_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->type_env,e);
+ IRType ty = typeOfIRExpr(env->stmts, e);
vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
/* special case: 32-bit GET */
@@ -1790,7 +1790,7 @@
MatchInfo mi;
vassert(e);
- vassert(typeOfIRExpr(env->type_env,e) == Ity_I1);
+ vassert(typeOfIRExpr(env->stmts, e) == Ity_I1);
/* var */
if (e->tag == Iex_RdTmp) {
@@ -2091,7 +2091,7 @@
MatchInfo mi;
HWord fn = 0; /* helper fn for most SIMD64 stuff */
vassert(e);
- vassert(typeOfIRExpr(env->type_env,e) == Ity_I64);
+ vassert(typeOfIRExpr(env->stmts, e) == Ity_I64);
/* 64-bit literal */
if (e->tag == Iex_Const) {
@@ -2889,7 +2889,7 @@
/* DO NOT CALL THIS DIRECTLY */
static HReg iselFltExpr_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->type_env,e);
+ IRType ty = typeOfIRExpr(env->stmts, e);
vassert(ty == Ity_F32);
if (e->tag == Iex_RdTmp) {
@@ -3006,7 +3006,7 @@
/* DO NOT CALL THIS DIRECTLY */
static HReg iselDblExpr_wrk ( ISelEnv* env, const IRExpr* e )
{
- IRType ty = typeOfIRExpr(env->type_env,e);
+ IRType ty = typeOfIRExpr(env->stmts, e);
vassert(e);
vassert(ty == Ity_F64);
@@ -3223,7 +3223,7 @@
/* --------- MULTIPLEX --------- */
if (e->tag == Iex_ITE) { // VFD
if (ty == Ity_F64
- && typeOfIRExpr(env->type_env,e->Iex.ITE.cond) == Ity_I1) {
+ && typeOfIRExpr(env->stmts, 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 +3277,7 @@
MatchInfo mi;
Bool arg1isEReg = False;
X86SseOp op = Xsse_INVALID;
- IRType ty = typeOfIRExpr(env->type_env,e);
+ IRType ty = typeOfIRExpr(env->stmts, e);
vassert(e);
vassert(ty == Ity_V128);
@@ -3873,8 +3873,8 @@
/* --------- STORE --------- */
case Ist_Store: {
- IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
- IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
+ IRType tya = typeOfIRExpr(env->stmts, stmt->Ist.Store.addr);
+ IRType tyd = typeOfIRExpr(env->stmts, stmt->Ist.Store.data);
IREndness end = stmt->Ist.Store.end;
if (tya != Ity_I32 || end != Iend_LE)
@@ -3926,7 +3926,7 @@
/* --------- PUT --------- */
case Ist_Put: {
- IRType ty = typeOfIRExpr(env->type_env, stmt->Ist.Put.data);
+ IRType ty = typeOfIRExpr(env->stmts, stmt->Ist.Put.data);
if (ty == Ity_I32) {
/* We're going to write to memory, so compute the RHS into an
X86RI. */
@@ -3989,7 +3989,7 @@
env, puti->descr,
puti->ix, puti->bias );
- IRType ty = typeOfIRExpr(env->type_env, puti->data);
+ IRType ty = typeOfIRExpr(env->stmts, puti->data);
if (ty == Ity_F64) {
HReg val = iselDblExpr(env, puti->data);
addInstr(env, X86Instr_FpLdSt( False/*store*/, 8, val, am ));
@@ -4019,7 +4019,7 @@
/* --------- TMP --------- */
case Ist_WrTmp: {
IRTemp tmp = stmt->Ist.WrTmp.tmp;
- IRType ty = typeOfIRTemp(env->type_env, tmp);
+ IRType ty = typeOfIRTemp(env->stmts, tmp);
/* optimisation: if stmt->Ist.WrTmp.data is Add32(..,..),
compute it into an AMode and then use LEA. This usually
@@ -4092,7 +4092,7 @@
/* Figure out the return type, if any. */
IRType retty = Ity_INVALID;
if (!isIRTempInvalid(d->tmp))
- retty = typeOfIRTemp(env->type_env, d->tmp);
+ retty = typeOfIRTemp(env->stmts, d->tmp);
Bool retty_ok = False;
switch (retty) {
@@ -4180,7 +4180,7 @@
/* "normal" singleton CAS */
UChar sz;
IRCAS* cas = stmt->Ist.CAS.details;
- IRType ty = typeOfIRExpr(env->type_env, cas->dataLo);
+ IRType ty = typeOfIRExpr(env->stmts, 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 +4205,7 @@
} else {
/* double CAS */
IRCAS* cas = stmt->Ist.CAS.details;
- IRType ty = typeOfIRExpr(env->type_env, cas->dataLo);
+ IRType ty = typeOfIRExpr(env->stmts, 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 */
@@ -4457,9 +4457,9 @@
env->code = newHInstrArray();
/* Copy BB's type env. */
- /* TODO-JIT: Works only with IRTypeEnv ID #0. */
- vassert(bb->stmts->tyenv->id == 0);
- env->type_env = bb->stmts->tyenv;
+ /* TODO-JIT: Currently works only with no if-then-else statements. */
+ vassert(bb->id_seq == 1);
+ env->stmts = bb->stmts;
/* Make up an IRTemp -> virtual HReg mapping. This doesn't
change as we go along. */
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 Wed Mar 22 22:00:23 2017
@@ -3753,12 +3753,18 @@
/*---------------------------------------------------------------*/
inline
-IRType typeOfIRTemp ( const IRTypeEnv* env, IRTemp tmp )
+IRType typeOfIRTemp(const IRStmtVec* stmts, IRTemp tmp)
{
- vassert(tmp.id == env->id);
- vassert(tmp.index >= 0);
- vassert(tmp.index < env->types_used);
- return env->types[tmp.index];
+ const IRTypeEnv* tyenv = stmts->tyenv;
+ if (tyenv->id == tmp.id) {
+ vassert(tmp.index >= 0);
+ vassert(tmp.index < tyenv->types_used);
+ return tyenv->types[tmp.index];
+ } else if (stmts->parent != NULL) {
+ return typeOfIRTemp(stmts->parent, tmp);
+ } else {
+ vpanic("typeOfIRTemp");
+ }
}
IRType typeOfIRConst ( const IRConst* con )
@@ -3798,7 +3804,7 @@
}
}
-IRType typeOfIRExpr ( const IRTypeEnv* tyenv, const IRExpr* e )
+IRType typeOfIRExpr ( const IRStmtVec* stmts, const IRExpr* e )
{
IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
start:
@@ -3810,7 +3816,7 @@
case Iex_GetI:
return e->Iex.GetI.descr->elemTy;
case Iex_RdTmp:
- return typeOfIRTemp(tyenv, e->Iex.RdTmp.tmp);
+ return typeOfIRTemp(stmts, e->Iex.RdTmp.tmp);
case Iex_Const:
return typeOfIRConst(e->Iex.Const.con);
case Iex_Qop:
@@ -3834,7 +3840,7 @@
case Iex_ITE:
e = e->Iex.ITE.iffalse;
goto start;
- /* return typeOfIRExpr(tyenv, e->Iex.ITE.iffalse); */
+ /* return typeOfIRExpr(stmts, e->Iex.ITE.iffalse); */
case Iex_Binder:
vpanic("typeOfIRExpr: Binder is not a valid expression");
case Iex_VECRET:
@@ -4411,16 +4417,15 @@
void tcExpr(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
const IRExpr* expr, IRType gWordTy)
{
- Int i;
- IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
- const IRTypeEnv* tyenv = stmts->tyenv;
+ Int i;
+ IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
switch (expr->tag) {
case Iex_Get:
case Iex_RdTmp:
break;
case Iex_GetI:
tcExpr(bb, stmts, stmt, expr->Iex.GetI.ix, gWordTy);
- if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
+ if (typeOfIRExpr(stmts, expr->Iex.GetI.ix) != Ity_I32)
sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
if (!saneIRRegArray(expr->Iex.GetI.descr))
sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr");
@@ -4443,10 +4448,10 @@
"Iex.Qop: wrong arity op\n"
"... name of op precedes BB printout\n");
}
- ttarg1 = typeOfIRExpr(tyenv, qop->arg1);
- ttarg2 = typeOfIRExpr(tyenv, qop->arg2);
- ttarg3 = typeOfIRExpr(tyenv, qop->arg3);
- ttarg4 = typeOfIRExpr(tyenv, qop->arg4);
+ ttarg1 = typeOfIRExpr(stmts, qop->arg1);
+ ttarg2 = typeOfIRExpr(stmts, qop->arg2);
+ ttarg3 = typeOfIRExpr(stmts, qop->arg3);
+ ttarg4 = typeOfIRExpr(stmts, qop->arg4);
if (t_arg1 != ttarg1 || t_arg2 != ttarg2
|| t_arg3 != ttarg3 || t_arg4 != ttarg4) {
vex_printf(" op name: ");
@@ -4494,9 +4499,9 @@
"Iex.Triop: wrong arity op\n"
"... name of op precedes BB printout\n");
}
- ttarg1 = typeOfIRExpr(tyenv, triop->arg1);
- ttarg2 = typeOfIRExpr(tyenv, triop->arg2);
- ttarg3 = typeOfIRExpr(tyenv, triop->arg3);
+ ttarg1 = typeOfIRExpr(stmts, triop->arg1);
+ ttarg2 = typeOfIRExpr(stmts, triop->arg2);
+ ttarg3 = typeOfIRExpr(stmts, triop->arg3);
if (t_arg1 != ttarg1 || t_arg2 != ttarg2 || t_arg3 != ttarg3) {
vex_printf(" op name: ");
ppIROp(triop->op);
@@ -4537,8 +4542,8 @@
"Iex.Binop: wrong arity op\n"
"... name of op precedes BB printout\n");
}
- ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
- ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
+ ttarg1 = typeOfIRExpr(stmts, expr->Iex.Binop.arg1);
+ ttarg2 = typeOfIRExpr(stmts, expr->Iex.Binop.arg2);
if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
vex_printf(" op name: ");
ppIROp(expr->Iex.Binop.op);
@@ -4567,12 +4572,12 @@
if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID
|| t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID)
sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op");
- if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
+ if (t_arg1 != typeOfIRExpr(stmts, expr->Iex.Unop.arg))
sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
break;
case Iex_Load:
tcExpr(bb, stmts, stmt, expr->Iex.Load.addr, gWordTy);
- if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy)
+ if (typeOfIRExpr(stmts, expr->Iex.Load.addr) != gWordTy)
sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type");
if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE)
sanityCheckFail(bb,stmt,"Iex.Load.end: bogus endianness");
@@ -4594,7 +4599,7 @@
sanityCheckFail(bb,stmt,
"Iex.CCall.retty: cannot return :: Ity_I1");
for (i = 0; expr->Iex.CCall.args[i]; i++)
- if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
+ if (typeOfIRExpr(stmts, expr->Iex.CCall.args[i]) == Ity_I1)
sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
break;
case Iex_Const:
@@ -4605,10 +4610,10 @@
tcExpr(bb, stmts, stmt, expr->Iex.ITE.cond, gWordTy);
tcExpr(bb, stmts, stmt, expr->Iex.ITE.iftrue, gWordTy);
tcExpr(bb, stmts, stmt, expr->Iex.ITE.iffalse, gWordTy);
- if (typeOfIRExpr(tyenv, expr->Iex.ITE.cond) != Ity_I1)
+ if (typeOfIRExpr(stmts, expr->Iex.ITE.cond) != Ity_I1)
sanityCheckFail(bb,stmt,"Iex.ITE.cond: cond :: Ity_I1");
- if (typeOfIRExpr(tyenv, expr->Iex.ITE.iftrue)
- != typeOfIRExpr(tyenv, expr->Iex.ITE.iffalse))
+ if (typeOfIRExpr(stmts, expr->Iex.ITE.iftrue)
+ != typeOfIRExpr(stmts, expr->Iex.ITE.iffalse))
sanityCheckFail(bb,stmt,"Iex.ITE: iftrue/iffalse mismatch");
break;
default:
@@ -4620,12 +4625,16 @@
void tcPhi(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
const IRPhi* phi)
{
- const IRTypeEnv* tyenv = stmts->tyenv;
- if (typeOfIRTemp(tyenv, phi->srcThen) != typeOfIRTemp(tyenv, phi->srcElse)) {
+ vassert(stmt->tag == Ist_IfThenElse);
+ const IRStmtVec* then_leg = stmt->Ist.IfThenElse.then_leg;
+ const IRStmtVec* else_leg = stmt->Ist.IfThenElse.else_leg;
+
+ if (typeOfIRTemp(then_leg, phi->srcThen)
+ != typeOfIRTemp(else_leg, phi->srcElse)) {
sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.Phi: 'then' and 'else' "
"tmp do not match");
}
- if (typeOfIRTemp(tyenv, phi->dst) != typeOfIRTemp(tyenv, phi->srcThen)) {
+ if (typeOfIRTemp(stmts, phi->dst) != typeOfIRTemp(then_leg, phi->srcThen)) {
sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.Phi: 'dst' and 'then' "
"tmp do not match");
}
@@ -4635,8 +4644,7 @@
void tcStmt(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
Bool require_flat, IRType gWordTy)
{
- IRType tyExpd, tyData;
- const IRTypeEnv* tyenv = stmts->tyenv;
+ IRType tyExpd, tyData;
switch (stmt->tag) {
case Ist_IMark:
/* Somewhat heuristic, but rule out totally implausible
@@ -4647,28 +4655,28 @@
sanityCheckFail(bb,stmt,"IRStmt.IMark.delta: implausible");
break;
case Ist_AbiHint:
- if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.base) != gWordTy)
+ if (typeOfIRExpr(stmts, stmt->Ist.AbiHint.base) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmt.AbiHint.base: "
"not :: guest word type");
- if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.nia) != gWordTy)
+ if (typeOfIRExpr(stmts, stmt->Ist.AbiHint.nia) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmt.AbiHint.nia: "
"not :: guest word type");
break;
case Ist_Put:
tcExpr(bb, stmts, stmt, stmt->Ist.Put.data, gWordTy);
- if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
+ if (typeOfIRExpr(stmts, stmt->Ist.Put.data) == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
break;
case Ist_PutI:{
const IRPutI* puti = stmt->Ist.PutI.details;
tcExpr(bb, stmts, stmt, puti->data, gWordTy);
tcExpr(bb, stmts, stmt, puti->ix, gWordTy);
- if (typeOfIRExpr(tyenv,puti->data) == Ity_I1)
+ if (typeOfIRExpr(stmts, puti->data) == Ity_I1)
sanityCheckFail(bb,stmt,
"IRStmt.PutI.data: cannot PutI :: Ity_I1");
- if (typeOfIRExpr(tyenv,puti->data) != puti->descr->elemTy)
+ if (typeOfIRExpr(stmts, puti->data) != puti->descr->elemTy)
sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
- if (typeOfIRExpr(tyenv,puti->ix) != Ity_I32)
+ if (typeOfIRExpr(stmts, puti->ix) != Ity_I32)
sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
if (!saneIRRegArray(puti->descr))
sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr");
@@ -4676,18 +4684,18 @@
}
case Ist_WrTmp:
tcExpr(bb, stmts, stmt, stmt->Ist.WrTmp.data, gWordTy);
- if (typeOfIRTemp(tyenv, stmt->Ist.WrTmp.tmp)
- != typeOfIRExpr(tyenv, stmt->Ist.WrTmp.data))
+ if (typeOfIRTemp(stmts, stmt->Ist.WrTmp.tmp)
+ != typeOfIRExpr(stmts, stmt->Ist.WrTmp.data))
sanityCheckFail(bb,stmt,
"IRStmt.Put.Tmp: tmp and expr do not match");
break;
case Ist_Store:
tcExpr(bb, stmts, stmt, stmt->Ist.Store.addr, gWordTy);
tcExpr(bb, stmts, stmt, stmt->Ist.Store.data, gWordTy);
- if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy)
+ if (typeOfIRExpr(stmts, stmt->Ist.Store.addr) != gWordTy)
sanityCheckFail(bb,stmt,
"IRStmt.Store.addr: not :: guest word type");
- if (typeOfIRExpr(tyenv, stmt->Ist.Store.data) == Ity_I1)
+ if (typeOfIRExpr(stmts, stmt->Ist.Store.data) == Ity_I1)
sanityCheckFail(bb,stmt,
"IRStmt.Store.data: cannot Store :: Ity_I1");
if (stmt->Ist.Store.end != Iend_LE && stmt->Ist.Store.end != Iend_BE)
@@ -4698,11 +4706,11 @@
tcExpr(bb, stmts, stmt, sg->addr, gWordTy);
tcExpr(bb, stmts, stmt, sg->data, gWordTy);
tcExpr(bb, stmts, stmt, sg->guard, gWordTy);
- if (typeOfIRExpr(tyenv, sg->addr) != gWordTy)
+ if (typeOfIRExpr(stmts, sg->addr) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmtG...addr: not :: guest word type");
- if (typeOfIRExpr(tyenv, sg->data) == Ity_I1)
+ if (typeOfIRExpr(stmts, sg->data) == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmtG...data: cannot Store :: Ity_I1");
- if (typeOfIRExpr(tyenv, sg->guard) != Ity_I1)
+ if (typeOfIRExpr(stmts, sg->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmtG...guard: not :: Ity_I1");
if (sg->end != Iend_LE && sg->end != Iend_BE)
sanityCheckFail(bb,stmt,"IRStmtG...end: bogus endianness");
@@ -4713,16 +4721,16 @@
tcExpr(bb, stmts, stmt, lg->addr, gWordTy);
tcExpr(bb, stmts, stmt, lg->alt, gWordTy);
tcExpr(bb, stmts, stmt, lg->guard, gWordTy);
- if (typeOfIRExpr(tyenv, lg->guard) != Ity_I1)
+ if (typeOfIRExpr(stmts, lg->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.LoadG.guard: not :: Ity_I1");
- if (typeOfIRExpr(tyenv, lg->addr) != gWordTy)
+ if (typeOfIRExpr(stmts, lg->addr) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmt.LoadG.addr: not "
":: guest word type");
- if (typeOfIRExpr(tyenv, lg->alt) != typeOfIRTemp(tyenv, lg->dst))
+ if (typeOfIRExpr(stmts, lg->alt) != typeOfIRTemp(stmts, lg->dst))
sanityCheckFail(bb,stmt,"IRStmt.LoadG: dst/alt type mismatch");
IRType cvtRes = Ity_INVALID, cvtArg = Ity_INVALID;
typeOfIRLoadGOp(lg->cvt, &cvtRes, &cvtArg);
- if (cvtRes != typeOfIRTemp(tyenv, lg->dst))
+ if (cvtRes != typeOfIRTemp(stmts, lg->dst))
sanityCheckFail(bb,stmt,"IRStmt.LoadG: dst/loaded type mismatch");
break;
}
@@ -4744,12 +4752,12 @@
}
/* check the address type */
tcExpr(bb, stmts, stmt, cas->addr, gWordTy);
- if (typeOfIRExpr(tyenv, cas->addr) != gWordTy) goto bad_cas;
+ if (typeOfIRExpr(stmts, cas->addr) != gWordTy) goto bad_cas;
/* check types on the {old,expd,data}Lo components agree */
- tyExpd = typeOfIRExpr(tyenv, cas->expdLo);
- tyData = typeOfIRExpr(tyenv, cas->dataLo);
+ tyExpd = typeOfIRExpr(stmts, cas->expdLo);
+ tyData = typeOfIRExpr(stmts, cas->dataLo);
if (tyExpd != tyData) goto bad_cas;
- if (tyExpd != typeOfIRTemp(tyenv, cas->oldLo))
+ if (tyExpd != typeOfIRTemp(stmts, cas->oldLo))
goto bad_cas;
/* check the base element type is sane */
if (tyExpd == Ity_I8 || tyExpd == Ity_I16 || tyExpd == Ity_I32
@@ -4761,15 +4769,15 @@
/* If it's a DCAS, check types on the {old,expd,data}Hi
components too */
if (!isIRTempInvalid(cas->oldHi)) {
- tyExpd = typeOfIRExpr(tyenv, cas->expdHi);
- tyData = typeOfIRExpr(tyenv, cas->dataHi);
+ tyExpd = typeOfIRExpr(stmts, cas->expdHi);
+ tyData = typeOfIRExpr(stmts, cas->dataHi);
if (tyExpd != tyData) goto bad_cas;
- if (tyExpd != typeOfIRTemp(tyenv, cas->oldHi))
+ if (tyExpd != typeOfIRTemp(stmts, cas->oldHi))
goto bad_cas;
/* and finally check that oldLo and oldHi have the same
type. This forces equivalence amongst all 6 types. */
- if (typeOfIRTemp(tyenv, cas->oldHi)
- != typeOfIRTemp(tyenv, cas->oldLo))
+ if (typeOfIRTemp(stmts, cas->oldHi)
+ != typeOfIRTemp(stmts, cas->oldLo))
goto bad_cas;
}
break;
@@ -4779,11 +4787,11 @@
}
case Ist_LLSC: {
IRType tyRes;
- if (typeOfIRExpr(tyenv, stmt->Ist.LLSC.addr) != gWordTy)
+ if (typeOfIRExpr(stmts, stmt->Ist.LLSC.addr) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmt.LLSC.addr: not :: guest word type");
if (stmt->Ist.LLSC.end != Iend_LE && stmt->Ist.LLSC.end != Iend_BE)
sanityCheckFail(bb,stmt,"Ist.LLSC.end: bogus endianness");
- tyRes = typeOfIRTemp(tyenv, stmt->Ist.LLSC.result);
+ tyRes = typeOfIRTemp(stmts, stmt->Ist.LLSC.result);
if (stmt->Ist.LLSC.storedata == NULL) {
/* it's a LL */
if (tyRes != Ity_I64 && tyRes != Ity_I32
@@ -4793,7 +4801,7 @@
/* it's a SC */
if (tyRes != Ity_I1)
sanityCheckFail(bb,stmt,"Ist.LLSC(SC).result: not :: Ity_I1");
- tyData = typeOfIRExpr(tyenv, stmt->Ist.LLSC.storedata);
+ tyData = typeOfIRExpr(stmts, stmt->Ist.LLSC.storedata);
if (tyData != Ity_I64 && tyData != Ity_I32
&& tyData != Ity_I16 && tyData != Ity_I8)
sanityCheckFail(bb,stmt,
@@ -4832,12 +4840,12 @@
/* check guard */
if (d->guard == NULL) goto bad_dirty;
tcExpr(bb, stmts, stmt, d->guard, gWordTy);
- if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
+ if (typeOfIRExpr(stmts, d->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
/* check types, minimally */
IRType retTy = Ity_INVALID;
if (!isIRTempInvalid(d->tmp)) {
- retTy = typeOfIRTemp(tyenv, d->tmp);
+ retTy = typeOfIRTemp(stmts, d->tmp);
if (retTy == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
}
@@ -4851,7 +4859,7 @@
} else if (UNLIKELY(arg->tag == Iex_GSPTR)) {
nGSPTRs++;
} else {
- if (typeOfIRExpr(tyenv, arg) == Ity_I1)
+ if (typeOfIRExpr(stmts, arg) == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
}
if (nGSPTRs > 1) {
@@ -4902,7 +4910,7 @@
break;
case Ist_Exit:
tcExpr(bb, stmts, stmt, stmt->Ist.Exit.guard, gWordTy);
- if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
+ if (typeOfIRExpr(stmts,stmt->Ist.Exit.guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
if (!saneIRConst(stmt->Ist.Exit.dst))
sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst");
@@ -4914,7 +4922,7 @@
break;
case Ist_IfThenElse:
tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond, gWordTy);
- if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.cond) != Ity_I1)
+ if (typeOfIRExpr(stmts, stmt->Ist.IfThenElse.cond) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.cond: not :: Ity_I1");
/* Traversing into legs and phi nodes driven from
sanityCheckIRStmtVec(). */
@@ -4973,7 +4981,7 @@
/* Ensure each temp has a plausible type. */
for (UInt i = 0; i < n_temps; i++) {
IRTemp temp = mkIRTemp(id, i);
- IRType ty = typeOfIRTemp(tyenv, temp);
+ IRType ty = typeOfIRTemp(stmts, temp);
if (!isPlausibleIRType(ty)) {
vex_printf("Temp ");
ppIRTemp(temp);
@@ -5060,7 +5068,7 @@
}
/* Typecheck also next destination. */
- if (typeOfIRExpr(bb->stmts->tyenv, bb->next) != gWordTy) {
+ if (typeOfIRExpr(bb->stmts, bb->next) != gWordTy) {
sanityCheckFail(bb, NULL, "bb->next field has wrong type");
}
/* because it would intersect with host_EvC_* */
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 Wed Mar 22 22:00:23 2017
@@ -125,13 +125,13 @@
static void
store_aux(IRSB *irsb, IREndness endian, IRExpr *addr, IRExpr *data)
{
- if (typeOfIRExpr(irsb->stmts->tyenv, data) == Ity_D64) {
+ if (typeOfIRExpr(irsb->stmts, 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->tyenv, data) == Ity_I1) {
+ if (typeOfIRExpr(irsb->stmts, 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->tyenv, data);
+ IRType type = typeOfIRExpr(irsb->stmts, 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 Wed Mar 22 22:00:23 2017
@@ -287,7 +287,7 @@
Int i;
IRExpr** newargs;
IRTypeEnv* tyenv = stmts->tyenv;
- IRType ty = typeOfIRExpr(tyenv, ex);
+ IRType ty = typeOfIRExpr(stmts, ex);
IRTemp t1;
switch (ex->tag) {
@@ -652,7 +652,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->tyenv,valE)
+ Bool typesOK = toBool( typeOfIRExpr(stmts, valE)
== st->Ist.WrTmp.data->Iex.Get.ty );
if (typesOK && DEBUG_IROPT) {
vex_printf("rGET: "); ppIRExpr(get);
@@ -676,7 +676,7 @@
UInt k_lo, k_hi;
if (st->tag == Ist_Put) {
key = mk_key_GetPut( st->Ist.Put.offset,
- typeOfIRExpr(stmts->tyenv,st->Ist.Put.data) );
+ typeOfIRExpr(stmts, st->Ist.Put.data) );
} else {
vassert(st->tag == Ist_PutI);
key = mk_key_GetIPutI( st->Ist.PutI.details->descr );
@@ -960,7 +960,7 @@
case Ist_Put:
isPut = True;
key = mk_key_GetPut( st->Ist.Put.offset,
- typeOfIRExpr(stmts->tyenv,st->Ist.Put.data) );
+ typeOfIRExpr(stmts, st->Ist.Put.data) );
vassert(isIRAtom(st->Ist.Put.data));
break;
case Ist_PutI:
@@ -1024,7 +1024,7 @@
writes the IP (or, whatever it claims to write. We don't
care.) */
UInt key = mk_key_GetPut(bb->offsIP,
- typeOfIRExpr(bb->stmts->tyenv, bb->next));
+ typeOfIRExpr(bb->stmts, bb->next));
addToHHW(env, (HWord)key, 0);
redundant_put_removal_IRStmtVec(bb->stmts, preciseMemExnsFn, pxControl, env);
@@ -4086,7 +4086,7 @@
ae->u.GetIt.descr,
IRExpr_RdTmp(ae->u.GetIt.ix),
st->Ist.Put.offset,
- typeOfIRExpr(stmts->tyenv,st->Ist.Put.data)
+ typeOfIRExpr(stmts, st->Ist.Put.data)
) != NoAlias)
invalidate = True;
}
@@ -4399,7 +4399,7 @@
= getAliasingRelation_IC(
descrG, ixG,
st->Ist.Put.offset,
- typeOfIRExpr(stmts->tyenv,st->Ist.Put.data) );
+ typeOfIRExpr(stmts, st->Ist.Put.data) );
if (relation == NoAlias) {
/* we're OK; keep going */
@@ -4489,7 +4489,7 @@
static
Bool guestAccessWhichMightOverlapPutI (
- IRTypeEnv* tyenv, IRStmt* pi, IRStmt* s2
+ IRStmtVec* stmts, IRStmt* pi, IRStmt* s2
)
{
GSAliasing relation;
@@ -4531,7 +4531,7 @@
= getAliasingRelation_IC(
p1->descr, p1->ix,
s2->Ist.Put.offset,
- typeOfIRExpr(tyenv,s2->Ist.Put.data)
+ typeOfIRExpr(stmts, s2->Ist.Put.data)
);
goto have_relation;
@@ -4612,7 +4612,7 @@
if (replacement
&& isIRAtom(replacement)
/* Make sure we're doing a type-safe transformation! */
- && typeOfIRExpr(stmts->tyenv, replacement) == descr->elemTy) {
+ && typeOfIRExpr(stmts, replacement) == descr->elemTy) {
if (DEBUG_IROPT) {
vex_printf("rGI: ");
ppIRExpr(st->Ist.WrTmp.data);
@@ -4679,7 +4679,7 @@
if (st->tag == Ist_Dirty)
/* give up; could do better here */
break;
- if (guestAccessWhichMightOverlapPutI(stmts->tyenv, st, stj))
+ if (guestAccessWhichMightOverlapPutI(stmts, st, stj))
/* give up */
break;
}
@@ -5879,7 +5879,7 @@
switch (st->tag) {
case Ist_Put: {
Int offset = st->Ist.Put.offset;
- Int size = sizeofIRType(typeOfIRExpr(bb->stmts->tyenv, st->Ist.Put.data));
+ Int size = sizeofIRType(typeOfIRExpr(bb->stmts, st->Ist.Put.data));
*requiresPreciseMemExns
= preciseMemExnsFn(offset, offset + size - 1, pxControl);
@@ -6736,7 +6736,7 @@
case Ist_WrTmp:
if (st->Ist.WrTmp.data->tag == Iex_GetI)
*hasGetIorPutI = True;
- switch (typeOfIRTemp(stmts->tyenv, st->Ist.WrTmp.tmp)) {
+ switch (typeOfIRTemp(stmts, st->Ist.WrTmp.tmp)) {
case Ity_I1: case Ity_I8: case Ity_I16:
case Ity_I32: case Ity_I64: case Ity_I128:
break;
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 Wed Mar 22 22:00:23 2017
@@ -3215,8 +3215,8 @@
/* What is the type of this expression? */
extern IRType typeOfIRConst ( const IRConst* );
-extern IRType typeOfIRTemp ( const IRTypeEnv*, IRTemp );
-extern IRType typeOfIRExpr ( const IRTypeEnv*, const IRExpr* );
+extern IRType typeOfIRTemp ( const IRStmtVec*, IRTemp );
+extern IRType typeOfIRExpr ( const IRStmtVec*, const IRExpr* );
/* What are the arg and result type for this IRLoadGOp? */
extern void typeOfIRLoadGOp ( IRLoadGOp cvt,
Modified: branches/VEX_JIT_HACKS/useful/test_main.c
==============================================================================
--- branches/VEX_JIT_HACKS/useful/test_main.c (original)
+++ branches/VEX_JIT_HACKS/useful/test_main.c Wed Mar 22 22:00:23 2017
@@ -387,7 +387,7 @@
addr = st->Ist.STle.addr;
assert(isIRAtom(data));
assert(isIRAtom(addr));
- sz = sizeofIRType(typeOfIRExpr(bb_in->tyenv, data));
+ sz = sizeofIRType(typeOfIRExpr(bb_in->stmts, data));
needSz = False;
switch (sz) {
case 4: helper = mkIRCallee(1, "ac_helperc_STORE4",
@@ -982,7 +982,7 @@
/* Note, dst_ty is a shadow type, not an original type. */
/* First of all, collapse vbits down to a single bit. */
tl_assert(isShadowAtom(mce,vbits));
- ty = typeOfIRExpr(mce->bb->stmts->tyenv, vbits);
+ ty = typeOfIRExpr(mce->bb->stmts, vbits);
tmp1 = NULL;
switch (ty) {
case Ity_I1:
@@ -1074,7 +1074,7 @@
tl_assert(isShadowAtom(mce, vatom));
tl_assert(sameKindedAtoms(atom, vatom));
- ty = typeOfIRExpr(mce->bb->stmts->tyenv, vatom);
+ ty = typeOfIRExpr(mce->bb->stmts, vatom);
/* sz is only used for constructing the error message */
sz = ty==Ity_I1 ? 0 : sizeofIRType(ty);
@@ -1184,7 +1184,7 @@
tl_assert(isShadowAtom(mce, vatom));
}
- ty = typeOfIRExpr(mce->bb->stmts->tyenv, vatom);
+ ty = typeOfIRExpr(mce->bb->stmts, vatom);
tl_assert(ty != Ity_I1);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* later: no ... */
@@ -2147,7 +2147,7 @@
vbitsC = expr2vbits(mce, cond);
vbits0 = expr2vbits(mce, iffalse);
vbits1 = expr2vbits(mce, iftrue);
- ty = typeOfIRExpr(mce->bb->stmts->tyenv, vbits0);
+ ty = typeOfIRExpr(mce->bb->stmts, vbits0);
return
mkUifU(mce, ty, assignNew(mce, ty, IRExpr_ITE(cond, vbits1, vbits0)),
@@ -2172,7 +2172,7 @@
return IRExpr_RdTmp( findShadowTmp(mce, e->Iex.RdTmp.tmp) );
case Iex_Const:
- return definedOfType(shadowType(typeOfIRExpr(mce->bb->stmts->tyenv, e)));
+ return definedOfType(shadowType(typeOfIRExpr(mce->bb->stmts, e)));
case Iex_Binop:
return expr2vbits_Binop(
@@ -2219,7 +2219,7 @@
/* vatom is vbits-value and as such can only have a shadow type. */
tl_assert(isShadowAtom(mce,vatom));
- ty = typeOfIRExpr(mce->bb->stmts->tyenv, vatom);
+ ty = typeOfIRExpr(mce->bb->stmts, vatom);
tyH = mce->hWordTy;
if (tyH == Ity_I32) {
@@ -2277,7 +2277,7 @@
tl_assert(isOriginalAtom(mce,addr));
tl_assert(isShadowAtom(mce,vdata));
- ty = typeOfIRExpr(mce->bb->stmts->tyenv, vdata);
+ ty = typeOfIRExpr(mce->bb->stmts, vdata);
/* First, emit a definedness test for the address. This also sets
the address (shadow) to 'defined' following the test. */
@@ -2443,7 +2443,7 @@
tl_assert(d->mAddr);
complainIfUndefined(mce, d->mAddr);
- tyAddr = typeOfIRExpr(mce->bb->stmts->tyenv, d->mAddr);
+ tyAddr = typeOfIRExpr(mce->bb->stmts, d->mAddr);
tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
tl_assert(tyAddr == mce->hWordTy); /* not really right */
}
@@ -2482,7 +2482,7 @@
/* Outputs: the destination temporary, if there is one. */
if (!isIRTempInvalid(d->tmp)) {
dst = findShadowTmp(mce, d->tmp);
- tyDst = typeOfIRTemp(mce->bb->stmts->tyenv, d->tmp);
+ tyDst = typeOfIRTemp(mce->bb->stmts, d->tmp);
assign(mce->bb->stmts, dst, mkPCastTo(mce, tyDst, curr));
}
|