Bug 527754 - CseFilter not able to handle downstream modification of instructions (take 2). r=gal,rreitmai.

--HG--
extra : convert_revision : b9640e93e1efe3c24e90afef0127e71ecef47ac4
This commit is contained in:
Nicholas Nethercote 2009-12-21 12:41:22 +11:00
parent 7c3a5b4e1e
commit 979b04de2a
2 changed files with 46 additions and 34 deletions

View File

@ -1117,15 +1117,6 @@ namespace nanojit
return _hashfinish(_hash32(hash, uint32_t(a)));
}
inline uint32_t LInsHashSet::hashImmf(double d) {
union {
double d;
uint64_t u64;
} u;
u.d = d;
return hashImmq(u.u64);
}
inline uint32_t LInsHashSet::hash1(LOpcode op, LInsp a) {
uint32_t hash = _hash8(0,uint8_t(op));
return _hashfinish(_hashptr(hash, a));
@ -1234,22 +1225,15 @@ namespace nanojit
return k;
}
LInsp LInsHashSet::findImmf(double a, uint32_t &k)
LInsp LInsHashSet::findImmf(uint64_t a, uint32_t &k)
{
// We must pun 'a' as a uint64_t otherwise 0 and -0 will be treated as
// equal, which breaks things (see bug 527288).
union {
double d;
uint64_t u64;
} u;
u.d = a;
LInsHashKind kind = LInsImmf;
const uint32_t bitmask = (m_cap[kind] - 1) & ~0x1;
uint32_t hash = hashImmf(a) & bitmask;
uint32_t hash = hashImmq(a) & bitmask;
uint32_t n = 7 << 1;
LInsp ins;
while ((ins = m_list[kind][hash]) != NULL &&
(ins->imm64() != u.u64))
(ins->imm64() != a))
{
NanoAssert(ins->isconstf());
hash = (hash + (n += 2)) & bitmask; // quadratic probe
@ -1261,7 +1245,7 @@ namespace nanojit
uint32_t LInsHashSet::findImmf(LInsp ins)
{
uint32_t k;
findImmf(ins->imm64f(), k);
findImmf(ins->imm64(), k);
return k;
}
@ -1985,7 +1969,11 @@ namespace nanojit
LInsp ins = exprs->findImm(imm, k);
if (ins)
return ins;
return exprs->add(LInsImm, out->insImm(imm), k);
ins = out->insImm(imm);
// We assume that downstream stages do not modify the instruction, so
// that we can insert 'ins' into slot 'k'. Check this.
NanoAssert(ins->opcode() == LIR_int && ins->imm32() == imm);
return exprs->add(LInsImm, ins, k);
}
LIns* CseFilter::insImmq(uint64_t q)
@ -1994,16 +1982,27 @@ namespace nanojit
LInsp ins = exprs->findImmq(q, k);
if (ins)
return ins;
return exprs->add(LInsImmq, out->insImmq(q), k);
ins = out->insImmq(q);
NanoAssert(ins->opcode() == LIR_quad && ins->imm64() == q);
return exprs->add(LInsImmq, ins, k);
}
LIns* CseFilter::insImmf(double d)
{
uint32_t k;
LInsp ins = exprs->findImmf(d, k);
// We must pun 'd' as a uint64_t otherwise 0 and -0 will be treated as
// equal, which breaks things (see bug 527288).
union {
double d;
uint64_t u64;
} u;
u.d = d;
LInsp ins = exprs->findImmf(u.u64, k);
if (ins)
return ins;
return exprs->add(LInsImmf, out->insImmf(d), k);
ins = out->insImmf(d);
NanoAssert(ins->opcode() == LIR_float && ins->imm64() == u.u64);
return exprs->add(LInsImmf, ins, k);
}
LIns* CseFilter::ins0(LOpcode v)
@ -2020,7 +2019,9 @@ namespace nanojit
LInsp ins = exprs->find1(v, a, k);
if (ins)
return ins;
return exprs->add(LIns1, out->ins1(v,a), k);
ins = out->ins1(v, a);
NanoAssert(ins->opcode() == v && ins->oprnd1() == a);
return exprs->add(LIns1, ins, k);
}
return out->ins1(v,a);
}
@ -2032,7 +2033,9 @@ namespace nanojit
LInsp ins = exprs->find2(v, a, b, k);
if (ins)
return ins;
return exprs->add(LIns2, out->ins2(v,a,b), k);
ins = out->ins2(v, a, b);
NanoAssert(ins->opcode() == v && ins->oprnd1() == a && ins->oprnd2() == b);
return exprs->add(LIns2, ins, k);
}
return out->ins2(v,a,b);
}
@ -2044,7 +2047,10 @@ namespace nanojit
LInsp ins = exprs->find3(v, a, b, c, k);
if (ins)
return ins;
return exprs->add(LIns3, out->ins3(v,a,b,c), k);
ins = out->ins3(v, a, b, c);
NanoAssert(ins->opcode() == v && ins->oprnd1() == a && ins->oprnd2() == b &&
ins->oprnd3() == c);
return exprs->add(LIns3, ins, k);
}
LIns* CseFilter::insLoad(LOpcode v, LInsp base, int32_t disp)
@ -2054,9 +2060,11 @@ namespace nanojit
LInsp ins = exprs->findLoad(v, base, disp, k);
if (ins)
return ins;
return exprs->add(LInsLoad, out->insLoad(v,base,disp), k);
ins = out->insLoad(v, base, disp);
NanoAssert(ins->opcode() == v && ins->oprnd1() == base && ins->disp() == disp);
return exprs->add(LInsLoad, ins, k);
}
return out->insLoad(v,base,disp);
return out->insLoad(v, base, disp);
}
LInsp CseFilter::insGuard(LOpcode v, LInsp c, GuardRecord *gr)
@ -2084,7 +2092,9 @@ namespace nanojit
LInsp ins = exprs->find1(v, c, k);
if (ins)
return 0;
return exprs->add(LIns1, out->insGuard(v,c,gr), k);
ins = out->insGuard(v, c, gr);
NanoAssert(ins->opcode() == v && ins->oprnd1() == c);
return exprs->add(LIns1, ins, k);
}
return out->insGuard(v, c, gr);
}
@ -2097,7 +2107,9 @@ namespace nanojit
LInsp ins = exprs->findCall(ci, argc, args, k);
if (ins)
return ins;
return exprs->add(LInsCall, out->insCall(ci, args), k);
ins = out->insCall(ci, args);
NanoAssert(ins->isCall() && ins->callInfo() == ci && argsmatch(ins, argc, args));
return exprs->add(LInsCall, ins, k);
}
return out->insCall(ci, args);
}
@ -2258,7 +2270,8 @@ namespace nanojit
LInsp ins = exprs->findLoad(v, base, disp, k);
if (ins)
return ins;
return exprs->add(LInsLoad, out->insLoad(v,base,disp), k);
ins = out->insLoad(v, base, disp);
return exprs->add(LInsLoad, ins, k);
}
default:
// fall thru

View File

@ -1301,7 +1301,6 @@ namespace nanojit
static uint32_t hashImm(int32_t);
static uint32_t hashImmq(uint64_t);
static uint32_t hashImmf(double);
static uint32_t hash1(LOpcode v, LInsp);
static uint32_t hash2(LOpcode v, LInsp, LInsp);
static uint32_t hash3(LOpcode v, LInsp, LInsp, LInsp);
@ -1328,7 +1327,7 @@ namespace nanojit
// These public versions are used before an LIns has been created.
LInsp findImm(int32_t a, uint32_t &k);
LInsp findImmq(uint64_t a, uint32_t &k);
LInsp findImmf(double d, uint32_t &k);
LInsp findImmf(uint64_t d, uint32_t &k);
LInsp find1(LOpcode v, LInsp a, uint32_t &k);
LInsp find2(LOpcode v, LInsp a, LInsp b, uint32_t &k);
LInsp find3(LOpcode v, LInsp a, LInsp b, LInsp c, uint32_t &k);