Fix arithmetic op uses of type paramters, get rid of gen{Sub,Mul,...}

These guys were determining their output type with DParam,
even though the output type was a function of the input types.  Fixed
this and then get rid of the genFoo wrappers.  Move binArithResultType
out of Type.  OpMod didn't need a type parameter.
Esse commit está contido em:
Jordan DeLong
2013-04-24 19:35:19 -07:00
commit de Sara Golemon
commit 0903f92a76
7 arquivos alterados com 48 adições e 72 exclusões
@@ -676,7 +676,7 @@ void HhbcTranslator::emitIncDecL(bool pre, bool inc, uint32_t id) {
SSATmp* HhbcTranslator::emitIncDec(bool pre, bool inc, SSATmp* src) {
assert(src->isA(Type::Int) || src->isA(Type::Dbl));
SSATmp* one = src->isA(Type::Int) ? cns(1) : cns(1.0);
SSATmp* res = inc ? m_tb->genAdd(src, one) : m_tb->genSub(src, one);
SSATmp* res = inc ? gen(OpAdd, src, one) : gen(OpSub, src, one);
// no incref necessary on push since result is an int
push(pre ? res : src);
return res;
@@ -724,9 +724,7 @@ void HhbcTranslator::emitSetOpL(Opcode subOpc, uint32_t id) {
loc->type(),
topC()->type())) {
SSATmp* val = popC();
Type resultType = Type::binArithResultType(loc->type(),
val->type());
SSATmp* result = gen(subOpc, resultType, loc, val);
SSATmp* result = gen(subOpc, loc, val);
push(m_tb->genStLoc(id, result, true, true, exitTrace));
} else {
PUNT(SetOpL);
@@ -2740,7 +2738,7 @@ void HhbcTranslator::emitBinaryArith(Opcode opc) {
if (isSupportedBinaryArith(opc, type1, type2)) {
SSATmp* tr = popC();
SSATmp* tl = popC();
push(gen(opc, Type::binArithResultType(type1, type2), tl, tr));
push(gen(opc, tl, tr));
} else if (isBitOp && (type1 == Type::Obj || type2 == Type::Obj)) {
// raise fatal
emitInterpOne(Type::Cell, 2);
@@ -2771,8 +2769,8 @@ void HhbcTranslator::emitNot() {
}
#define BINOP(Opp) \
void HhbcTranslator::emit ## Opp() { \
emitBinaryArith(Op ## Opp); \
void HhbcTranslator::emit ## Opp() { \
emitBinaryArith(Op ## Opp); \
}
BINOP(Add)
@@ -2824,7 +2822,7 @@ void HhbcTranslator::emitMod() {
bcOff()
);
gen(JmpZero, exit, r);
push(gen(OpMod, Type::Int, l, r));
push(gen(OpMod, l, r));
}
void HhbcTranslator::emitBitNot() {
@@ -2832,7 +2830,7 @@ void HhbcTranslator::emitBitNot() {
if (srcType == Type::Int) {
SSATmp* src = popC();
SSATmp* ones = cns(~uint64_t(0));
push(m_tb->genXor(src, ones));
push(gen(OpXor, src, ones));
} else if (srcType.subtypeOf(Type::Null | Type::Bool | Type::Arr | Type::Obj)) {
// raise fatal
emitInterpOne(Type::Cell, 1);
@@ -2852,7 +2850,7 @@ void HhbcTranslator::emitXor() {
SSATmp* btl = popC();
SSATmp* tr = m_tb->genConvToBool(btr);
SSATmp* tl = m_tb->genConvToBool(btl);
push(m_tb->genConvToBool(m_tb->genXor(tl, tr)));
push(m_tb->genConvToBool(gen(OpXor, tl, tr)));
m_tb->genDecRef(btl);
m_tb->genDecRef(btr);
}
+2
Ver Arquivo
@@ -105,6 +105,7 @@ namespace {
#define DUnbox(n) HasDest
#define DBox(n) HasDest
#define DParam HasDest
#define DArith HasDest
#define DMulti NaryDest
#define DVector HasDest
#define DStk(x) ModifiesStack|(x)
@@ -147,6 +148,7 @@ struct {
#undef DUnbox
#undef DBox
#undef DParam
#undef DArith
#undef DMulti
#undef DVector
#undef DStk
+5 -11
Ver Arquivo
@@ -108,6 +108,7 @@ static const TCA kIRDirectGuardActive = (TCA)0x03;
* DUnbox(N) single dst has unboxed type of src N
* DBox(N) single dst has boxed type of src N
* DParam single dst has type of the instruction's type parameter
* DArith single dst has a type based on arithmetic type rules
* DMulti multiple dests. type and number depend on instruction
* DVector single dst depends on semantics of the vector instruction
* DStk(x) up to two dests. x should be another D* macro and indicates
@@ -171,13 +172,13 @@ O(CastStk, D(StkPtr), S(StkPtr) C(Int), Mem|N|Er) \
O(AssertStk, D(StkPtr), S(StkPtr) C(Int), E) \
O(GuardRefs, ND, SUnk, E) \
O(AssertLoc, ND, S(FramePtr), E) \
O(OpAdd, DParam, SNum SNum, C) \
O(OpSub, DParam, SNum SNum, C) \
O(OpAdd, DArith, SNum SNum, C) \
O(OpSub, DArith, SNum SNum, C) \
O(OpAnd, D(Int), SNumInt SNumInt, C) \
O(OpOr, D(Int), SNum SNum, C) \
O(OpXor, D(Int), SNumInt SNumInt, C) \
O(OpMul, DParam, SNum SNum, C) \
O(OpDiv, DParam, SNum SNum, C) \
O(OpMul, DArith, SNum SNum, C) \
O(OpDiv, DArith, SNum SNum, C) \
O(OpMod, D(Int), SNumInt SNumInt, C|N) \
\
O(ConvBoolToArr, D(Arr), S(Bool), C|N) \
@@ -1277,13 +1278,6 @@ public:
return t1.subtypeOf(t2) ? t1 : t2;
}
static Type binArithResultType(Type t1, Type t2) {
if (t1.subtypeOf(Type::Dbl) || t2.subtypeOf(Type::Dbl)) {
return Type::Dbl;
}
return Type::Int;
}
bool isArray() const {
return subtypeOf(Arr);
}
+18 -18
Ver Arquivo
@@ -579,7 +579,7 @@ SSATmp* Simplifier::simplifyNot(SSATmp* src) {
#define SIMPLIFY_COMMUTATIVE(OP, NAME) do { \
SIMPLIFY_CONST(OP); \
if (src1->isConst() && !src2->isConst()) { \
return m_tb->gen##NAME(src2, src1); \
return gen(Op##NAME, src2, src1); \
} \
if (src1->isA(Type::Int) && src2->isA(Type::Int)) { \
IRInstruction* inst1 = src1->inst(); \
@@ -589,14 +589,14 @@ SSATmp* Simplifier::simplifyNot(SSATmp* src) {
if (src2->isConst()) { \
int64_t right = inst1->getSrc(1)->getValInt(); \
right OP##= src2->getValInt(); \
return m_tb->gen##NAME(inst1->getSrc(0), cns(right)); \
return gen(Op##NAME, inst1->getSrc(0), cns(right)); \
} \
/* (X + C1) + (Y + C2) --> X + Y + C3 */ \
if (inst2->op() == Op##NAME && inst2->getSrc(1)->isConst()) { \
int64_t right = inst1->getSrc(1)->getValInt(); \
right OP##= inst2->getSrc(1)->getValInt(); \
SSATmp* left = m_tb->gen##NAME(inst1->getSrc(0), inst2->getSrc(0)); \
return m_tb->gen##NAME(left, cns(right)); \
SSATmp* left = gen(Op##NAME, inst1->getSrc(0), inst2->getSrc(0)); \
return gen(Op##NAME, left, cns(right)); \
} \
} \
} \
@@ -612,20 +612,20 @@ SSATmp* Simplifier::simplifyNot(SSATmp* src) {
/* all combinations of X * Y + X * Z --> X * (Y + Z) */ \
if (op1 == Op##INNAME && op2 == Op##INNAME) { \
if (inst1->getSrc(0) == inst2->getSrc(0)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(1), inst2->getSrc(1)); \
return m_tb->gen##INNAME(inst1->getSrc(0), fold); \
SSATmp* fold = gen(Op##OUTNAME, inst1->getSrc(1), inst2->getSrc(1)); \
return gen(Op##INNAME, inst1->getSrc(0), fold); \
} \
if (inst1->getSrc(0) == inst2->getSrc(1)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(1), inst2->getSrc(0)); \
return m_tb->gen##INNAME(inst1->getSrc(0), fold); \
SSATmp* fold = gen(Op##OUTNAME, inst1->getSrc(1), inst2->getSrc(0)); \
return gen(Op##INNAME, inst1->getSrc(0), fold); \
} \
if (inst1->getSrc(1) == inst2->getSrc(0)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(0), inst2->getSrc(1)); \
return m_tb->gen##INNAME(inst1->getSrc(1), fold); \
SSATmp* fold = gen(Op##OUTNAME, inst1->getSrc(0), inst2->getSrc(1)); \
return gen(Op##INNAME, inst1->getSrc(1), fold); \
} \
if (inst1->getSrc(1) == inst2->getSrc(1)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(0), inst2->getSrc(0)); \
return m_tb->gen##INNAME(inst1->getSrc(1), fold); \
SSATmp* fold = gen(Op##OUTNAME, inst1->getSrc(0), inst2->getSrc(0)); \
return gen(Op##INNAME, inst1->getSrc(1), fold); \
} \
} \
} while (0)
@@ -643,7 +643,7 @@ SSATmp* Simplifier::simplifyAdd(SSATmp* src1, SSATmp* src2) {
}
// X + -C --> X - C
if (src2Val < 0) {
return m_tb->genSub(src1, cns(-src2Val));
return gen(OpSub, src1, cns(-src2Val));
}
}
// X + (0 - Y) --> X - Y
@@ -653,7 +653,7 @@ SSATmp* Simplifier::simplifyAdd(SSATmp* src1, SSATmp* src2) {
SSATmp* src = inst2->getSrc(0);
if (src->isConst() && src->type() == Type::Int) {
if (src->getValInt() == 0) {
return m_tb->genSub(src1, inst2->getSrc(1));
return gen(OpSub, src1, inst2->getSrc(1));
}
}
}
@@ -676,7 +676,7 @@ SSATmp* Simplifier::simplifySub(SSATmp* src1, SSATmp* src2) {
}
// X - -C --> X + C
if (src2Val < 0 && src2Val > std::numeric_limits<int64_t>::min()) {
return m_tb->genAdd(src1, cns(-src2Val));
return gen(OpAdd, src1, cns(-src2Val));
}
}
// X - (0 - Y) --> X + Y
@@ -686,7 +686,7 @@ SSATmp* Simplifier::simplifySub(SSATmp* src1, SSATmp* src2) {
SSATmp* src = inst2->getSrc(0);
if (src->isConst() && src->type() == Type::Int) {
if (src->getValInt() == 0) {
return m_tb->genAdd(src1, inst2->getSrc(1));
return gen(OpAdd, src1, inst2->getSrc(1));
}
}
}
@@ -701,7 +701,7 @@ SSATmp* Simplifier::simplifyMul(SSATmp* src1, SSATmp* src2) {
if (src2->isConst() && src2->type() == Type::Int) {
// X * (-1) --> -X
if (src2->getValInt() == -1) {
return m_tb->genSub(cns(0), src1);
return gen(OpSub, cns(0), src1);
}
// X * 0 --> 0
if (src2->getValInt() == 0) {
@@ -716,7 +716,7 @@ SSATmp* Simplifier::simplifyMul(SSATmp* src1, SSATmp* src2) {
}
// X * 2 --> X + X
if (src2->getValInt() == 2) {
return m_tb->genAdd(src1, src1);
return gen(OpAdd, src1, src1);
}
// TODO once IR has shifts
// X * 2^C --> X << C
+1 -26
Ver Arquivo
@@ -240,34 +240,9 @@ Trace* TraceBuilder::genExitTrace(uint32_t bcOff,
return exitTrace;
}
SSATmp* TraceBuilder::genAdd(SSATmp* src1, SSATmp* src2) {
Type resultType = Type::binArithResultType(src1->type(),
src2->type());
return gen(OpAdd, resultType, src1, src2);
}
SSATmp* TraceBuilder::genSub(SSATmp* src1, SSATmp* src2) {
Type resultType = Type::binArithResultType(src1->type(),
src2->type());
return gen(OpSub, resultType, src1, src2);
}
SSATmp* TraceBuilder::genAnd(SSATmp* src1, SSATmp* src2) {
return gen(OpAnd, src1, src2);
}
SSATmp* TraceBuilder::genOr(SSATmp* src1, SSATmp* src2) {
return gen(OpOr, src1, src2);
}
SSATmp* TraceBuilder::genXor(SSATmp* src1, SSATmp* src2) {
return gen(OpXor, src1, src2);
}
SSATmp* TraceBuilder::genMul(SSATmp* src1, SSATmp* src2) {
Type resultType = Type::binArithResultType(src1->type(),
src2->type());
return gen(OpMul, resultType, src1, src2);
}
SSATmp* TraceBuilder::genNot(SSATmp* src) {
assert(src->type() == Type::Bool);
return genConvToBool(genXor(src, genDefConst<int64_t>(1)));
return genConvToBool(gen(OpXor, src, genDefConst<int64_t>(1)));
}
SSATmp* TraceBuilder::genDefUninit() {
+1 -7
Ver Arquivo
@@ -124,13 +124,7 @@ public:
Type type,
bool override = false); // ignores conflict w/ prev type
SSATmp* genAdd(SSATmp* src1, SSATmp* src2);
SSATmp* genSub(SSATmp* src1, SSATmp* src2);
SSATmp* genMul(SSATmp* src1, SSATmp* src2);
SSATmp* genAnd(SSATmp* src1, SSATmp* src2);
SSATmp* genOr(SSATmp* src1, SSATmp* src2);
SSATmp* genXor(SSATmp* src1, SSATmp* src2);
// TODO(#2058865): we should have a real not opcode
SSATmp* genNot(SSATmp* src);
SSATmp* genDefUninit();
+13
Ver Arquivo
@@ -77,6 +77,13 @@ Type stkReturn(const IRInstruction* inst, int dstId,
return Type::StkPtr;
}
Type binArithResultType(Type t1, Type t2) {
if (t1.subtypeOf(Type::Dbl) || t2.subtypeOf(Type::Dbl)) {
return Type::Dbl;
}
return Type::Int;
}
}
Type outputType(const IRInstruction* inst, int dstId) {
@@ -92,6 +99,8 @@ Type outputType(const IRInstruction* inst, int dstId) {
#define DVector return vectorReturn(inst);
#define ND assert(0 && "outputType requires HasDest or NaryDest");
#define DBuiltin return builtinReturn(inst);
#define DArith return binArithResultType(inst->getSrc(0)->type(), \
inst->getSrc(1)->type());
#define O(name, dstinfo, srcinfo, flags) case name: dstinfo not_reached();
@@ -112,6 +121,7 @@ Type outputType(const IRInstruction* inst, int dstId) {
#undef DVector
#undef ND
#undef DBuiltin
#undef DArith
}
@@ -261,6 +271,8 @@ void assertOperandTypes(const IRInstruction* inst) {
#define DParam checkDst(inst->getTypeParam() != Type::None || \
inst->op() == DefConst /* for DefNone */, \
"DParam with paramType None");
#define DArith checkDst(inst->getTypeParam() == Type::None, \
"DArith should have no type parameter");
#define O(opcode, dstinfo, srcinfo, flags) \
case opcode: dstinfo srcinfo countCheck(); return;
@@ -288,6 +300,7 @@ void assertOperandTypes(const IRInstruction* inst) {
#undef DBox
#undef DofS
#undef DParam
#undef DArith
}