in vm/jitrino/src/optimizer/hashvaluenumberer.cpp [1967:2267]
void InstValueNumberer::addInfoFromBranchCompare(Node* targetNode,
ComparisonModifier mod,
Type::Tag comparisonType,
bool isTrueEdge,
U_32 numSrcOperands,
Opnd *src0,
Opnd *src1)
{
// add the branch
ComparisonModifier modhere
= (isTrueEdge
? mod
: negateComparison(mod, Type::isFloatingPoint(comparisonType)));
ComparisonModifier negModhere =
negateComparison(modhere,
Type::isFloatingPoint(comparisonType));
Operation cmpOperation(Op_Cmp, comparisonType, modhere);
Operation negCmpOperation(Op_Cmp, comparisonType, negModhere);
Operation branchOperation(Op_Branch, comparisonType, modhere);
Operation negBranchOperation(Op_Branch, comparisonType, negModhere);
switch (numSrcOperands) {
case 1:
{
if (Log::isEnabled()) {
Log::out() << "adding true comparison: ";
switch (modhere) {
case Cmp_Zero: Log::out() << "Cmp_Zero "; break;
case Cmp_NonZero: Log::out() << "Cmp_NonZero "; break;
default: assert(0); break;
}
src0->print(Log::out());
Log::out() << ::std::endl;
Log::out() << "branchOperation.hashcode() == "
<< (int) branchOperation.encodeForHashing()
<< ::std::endl;
Log::out() << "cmpOperation.hashcode() == "
<< (int) cmpOperation.encodeForHashing()
<< ::std::endl;
}
Inst *tauEdge = getBlockTauEdge(targetNode)->getInst();
setHashToInst(tauEdge, getKey(branchOperation, src0->getId()));
setHashToInst(tauEdge, getKey(cmpOperation, src0->getId()));
if (Log::isEnabled()) {
Log::out() << "adding false comparison: ";
switch (negModhere) {
case Cmp_Zero: Log::out() << "Cmp_Zero "; break;
case Cmp_NonZero: Log::out() << "Cmp_NonZero "; break;
default: assert(0); break;
}
src0->print(Log::out());
Log::out() << ::std::endl;
Log::out() << "negBranchOperation.hashcode() == "
<< (int) negBranchOperation.encodeForHashing()
<< ::std::endl;
Log::out() << "negCmpOperation.hashcode() == "
<< (int) negCmpOperation.encodeForHashing()
<< ::std::endl;
}
setHashToInst(getTauUnsafe(), getKey(negBranchOperation, src0->getId()));
setHashToInst(getTauUnsafe(), getKey(negCmpOperation, src0->getId()));
}
break;
case 2:
{
Opnd *posSrc0 = isTrueEdge ? src0 : src1;
Opnd *posSrc1 = isTrueEdge ? src1 : src0;
Opnd *negSrc0 = isTrueEdge ? src1 : src0;
Opnd *negSrc1 = isTrueEdge ? src0 : src1;
if (Log::isEnabled()) {
Log::out() << "adding true comparison: ";
switch (modhere) {
case Cmp_EQ: Log::out() << "Cmp_EQ "; break;
case Cmp_NE_Un: Log::out() << "Cmp_NE_Un "; break;
case Cmp_GT: Log::out() << "Cmp_GT "; break;
case Cmp_GT_Un: Log::out() << "Cmp_GT_Un "; break;
case Cmp_GTE: Log::out() << "Cmp_GTE "; break;
case Cmp_GTE_Un: Log::out() << "Cmp_GTE_Un "; break;
default: assert(0); break;
}
posSrc0->print(Log::out());
Log::out() << ", ";
posSrc1->print(Log::out());
Log::out() << ::std::endl;
}
Inst *tauEdge = getBlockTauEdge(targetNode)->getInst();
setHashToInst(tauEdge,
getKey(branchOperation, posSrc0->getId(), posSrc1->getId()));
setHashToInst(tauEdge,
getKey(cmpOperation, posSrc0->getId(), posSrc1->getId()));
if (Log::isEnabled()) {
Log::out() << "adding false comparison: ";
switch (negModhere) {
case Cmp_EQ: Log::out() << "Cmp_EQ "; break;
case Cmp_NE_Un: Log::out() << "Cmp_NE_Un "; break;
case Cmp_GT: Log::out() << "Cmp_GT "; break;
case Cmp_GT_Un: Log::out() << "Cmp_GT_Un "; break;
case Cmp_GTE: Log::out() << "Cmp_GTE "; break;
case Cmp_GTE_Un: Log::out() << "Cmp_GTE_Un "; break;
default: assert(0); break;
}
posSrc0->print(Log::out());
Log::out() << ", ";
posSrc1->print(Log::out());
Log::out() << ::std::endl;
}
setHashToInst(getTauUnsafe(),
getKey(negBranchOperation, negSrc0->getId(),
negSrc1->getId()));
setHashToInst(getTauUnsafe(),
getKey(negCmpOperation, negSrc0->getId(),
negSrc1->getId()));
}
break;
default:
assert(0);
break;
}
Opnd *opnd = 0;
Opnd *opnd2 = 0;
Type *type = 0;
Inst *tauEdge = 0;
if (allowsCheckZeroElimination(mod, comparisonType, src0, src1, isTrueEdge,
&opnd)) {
assert(opnd);
if (Log::isEnabled()) {
Log::out() << "can eliminate checkzero of ";
opnd->print(Log::out());
Log::out() << ::std::endl;
}
if (!tauEdge) tauEdge = getBlockTauEdge(targetNode)->getInst();
setHashToInst(tauEdge,
getKey(Operation(Op_TauCheckZero, opnd->getType()->tag,
Modifier(Exception_Sometimes)),
opnd->getId()));
}
if (allowsCheckNullElimination(mod, comparisonType, src0, src1, isTrueEdge,
&opnd)) {
bool repeat_it;
do {
repeat_it = false;
assert(opnd);
if (Log::isEnabled()) {
Log::out() << "can eliminate checknull of ";
opnd->print(Log::out());
Log::out() << ::std::endl;
}
if (!tauEdge) tauEdge = getBlockTauEdge(targetNode)->getInst();
setHashToInst(tauEdge,
getKey(Op_TauCheckNull,
opnd->getId()));
setHashToInst(tauEdge,
getKey(Operation(Op_TauIsNonNull,
opnd->getType()->tag,
Modifier()),
opnd->getId()));
Inst *opndInst = opnd->getInst();
Opcode opndInstOpcode = opndInst->getOpcode();
if (opndInstOpcode == Op_TauStaticCast) {
// if a static cast, source is also non-null
opnd = opndInst->getSrc(0);
repeat_it = true;
}
} while (repeat_it);
}
if (allowsCheckBoundsElimination(mod, comparisonType, src0, src1, isTrueEdge,
&opnd, &opnd2)) {
assert(opnd);
assert(opnd2);
if (Log::isEnabled()) {
Log::out() << "can eliminate checkbounds of ";
opnd->print(Log::out());
Log::out() << ", ";
opnd2->print(Log::out());
Log::out() << ::std::endl;
}
if (!tauEdge) tauEdge = getBlockTauEdge(targetNode)->getInst();
setHashToInst(tauEdge,
getKey(Operation(Op_TauCheckBounds, opnd->getType()->tag,
Modifier(Exception_Sometimes)),
opnd->getId(), opnd2->getId()));
}
if (allowsCheckCastElimination(mod, comparisonType, src0, src1, isTrueEdge,
&opnd, &type)) {
bool repeat_it;
do {
repeat_it = false;
assert(opnd);
assert(type);
if (Log::isEnabled()) {
Log::out() << "can eliminate checkcast of ";
opnd->print(Log::out());
Log::out() << ", ";
type->print(Log::out());
Log::out() << ::std::endl;
}
if (!tauEdge) tauEdge = getBlockTauEdge(targetNode)->getInst();
opnd2 = irManager.getOpndManager().createSsaTmpOpnd(type);
Inst* scast = irManager.getInstFactory().makeTauStaticCast(opnd2, opnd,
tauEdge->getDst(), type);
if(Log::isEnabled()) {
Log::out() << "Inserting staticCast inst ";
scast->print(Log::out());
Log::out() << " after tauEdge ";
tauEdge->print(Log::out());
Log::out() << ::std::endl;
}
scast->insertAfter(tauEdge);
if (!tauEdge) tauEdge = getBlockTauEdge(targetNode)->getInst();
// make checks available
recordHasTypeTau(opnd, type, tauEdge);
Inst *opndInst = opnd->getInst();
Opcode opndInstOpcode = opndInst->getOpcode();
if (opndInstOpcode == Op_TauStaticCast) {
// if a static cast, source is also in the type
opnd = opndInst->getSrc(0);
repeat_it = true;
}
} while (repeat_it);
}
if (allowsCheckElemTypeElimination(mod, comparisonType, src0, src1,
isTrueEdge,
&opnd, &opnd2)) {
bool repeat_it;
do {
repeat_it = false;
assert(opnd);
assert(opnd2);
if (Log::isEnabled()) {
Log::out() << "can eliminate checkelemtype of ";
opnd->print(Log::out());
Log::out() << ", ";
opnd2->print(Log::out());
Log::out() << ::std::endl;
}
if (!tauEdge) tauEdge = getBlockTauEdge(targetNode)->getInst();
setHashToInst(tauEdge,
getKey(Operation(Op_TauCheckElemType,
opnd->getType()->tag,
(Modifier(Exception_Sometimes))),
opnd->getId(),
opnd2->getId()));
Inst *opndInst = opnd->getInst();
Opcode opndInstOpcode = opndInst->getOpcode();
if (opndInstOpcode == Op_TauStaticCast) {
// if a static cast, source is also in the type
opnd = opndInst->getSrc(0);
repeat_it = true;
}
} while (repeat_it);
}
if (allowsConstantPropagation(mod, comparisonType, src0, src1, isTrueEdge,
&opnd, &opnd2)) {
bool repeat_it;
do {
repeat_it = false;
// opnd2 is a constant expression
if (constantTable)
constantTable->insert(opnd, opnd2);
// vtable comparison guarantees type safety
if (Type::isVTablePtr(comparisonType)) {
Inst *opnd2inst = opnd2->getInst();
assert(opnd2inst->getOpcode() == Op_GetVTableAddr);
Inst *opnd1inst = opnd->getInst();
if (opnd1inst->getOpcode() == Op_TauLdVTableAddr) {
TypeInst *opnd2typeInst = opnd2inst->asTypeInst();
Opnd *base = opnd1inst->getSrc(0);
if (!tauEdge) tauEdge = getBlockTauEdge(targetNode)->getInst();
Type *typeInfo = opnd2typeInst->getTypeInfo();
setHashToInst(tauEdge,
getKey(Op_TauHasExactType,
base->getId(),
opnd2typeInst->getType()));
recordHasTypeTau(base, typeInfo, tauEdge);
}
}
Inst *opndInst = opnd->getInst();
Opcode opndInstOpcode = opndInst->getOpcode();
if (opndInstOpcode == Op_TauStaticCast) {
// if a static cast, source is also the constant
opnd = opndInst->getSrc(0);
repeat_it = true;
}
} while (repeat_it);
}
}