void BuildInequalityGraphWalker::applyToInst()

in vm/jitrino/src/optimizer/abcd/classic_abcd.cpp [261:370]


void BuildInequalityGraphWalker::applyToInst(Inst* inst)
{
    assert(inst);

    Type::Tag inst_type = inst->getType();
    if ( !Type::isInteger(inst_type) && inst_type != Type::Boolean &&
         inst_type != Type::Char ) {
        // note: some operations of unsupported type can produce operands of
        // supported (int) types, for example,
        // inst-compare-two-unmanaged-pointers, we need these operands as
        // unconstrained in the graph
        Opnd* dst = inst->getDst();
        if ( dst && !dst->isNull() &&
                (dst->getType()->isInteger() ||
                 dst->getType()->isBoolean() ) ) {
            addOldOrCreateOpnd(dst)->setUnconstrained(true);
        }
        return;
    }
    if ( inst->isUnconditionalBranch() || inst->isConditionalBranch() || 
         inst->isReturn() ) {
        return;
    }
    IOpndProxy* proxy_dst;
    Opcode opc = inst->getOpcode();
    switch ( opc ) {
        case Op_Phi:
        {
            proxy_dst = addOldOrCreateOpnd(inst->getDst());
            addAllSrcOpndsForPhi(inst);
        }
            break;
        case Op_Copy:
        case Op_LdVar:
        case Op_StVar:
        {
            proxy_dst = addOldOrCreateOpnd(inst->getDst());
            addDistance(proxy_dst, findProxy(inst->getSrc(0)), 0, 
                        false /* negate */);
        }
            break;
        case Op_Conv:
        {
            // adding conversions int<->long as zero-length edges to the
            // inequality graph. This is a small enhancement to the paper's
            // algorithm, but it is safe. The proof is as follows: if we ensure
            // that a value of type 'long' is in good bounds for array access,
            // then is is proven to be not outside bounds for type 'int'
            Opnd* src = inst->getSrc(0);
            Opnd* dst = inst->getDst();
            if ( isIntOrLong(src->getType()) &&
                 isIntOrLong(dst->getType()) ) {
                proxy_dst = addOldOrCreateOpnd(inst->getDst());
                addDistance(proxy_dst, findProxy(inst->getSrc(0)), 0, 
                            false /* negate */);
            }else{
                addOldOrCreateOpnd(inst->getDst())->setUnconstrained(true);
            }
        }
            break;
        case Op_Add:
        {
            proxy_dst = addOldOrCreateOpnd(inst->getDst());
            Opnd* src0 = inst->getSrc(0);
            Opnd* src1 = inst->getSrc(1);
            addEdgeIfConstOpnd(proxy_dst, src0, src1, false /* negate */) 
            || addEdgeIfConstOpnd(proxy_dst, src1, src0, false /* negate */);
        }
            break;
        case Op_Sub:
        {
            proxy_dst = addOldOrCreateOpnd(inst->getDst());
            addEdgeIfConstOpnd(proxy_dst, inst->getSrc(1), inst->getSrc(0),
                               true /* negate */ );
        }
            break;
        case Op_TauPi:
        {
            proxy_dst = addOldOrCreateOpnd(inst->getDst());
            IOpndProxy* src0 = findProxy(inst->getSrc(0));
            addDistance(proxy_dst, src0, 0, false /* negate */);
            _map_opnd_to_pi_inst[src0] = inst->asTauPiInst();
            if ( Log::isEnabled() ) {
                Log::out() << "mapping (src->pi inst): src: ";
                src0->printName(Log::out());
                Log::out() << " inst: ";
                inst->print(Log::out());
                Log::out() << std::endl;
            }
        }
            break;
        case Op_TauArrayLen:
        case Op_LdConstant: case Op_LdStatic: case Op_TauLdInd:
        case Op_TauLdField: case Op_TauLdElem:
        case Op_DirectCall: case Op_TauVirtualCall: case Op_IndirectCall:
        case Op_IndirectMemoryCall: case Op_JitHelperCall: case Op_VMHelperCall:
        case Op_DefArg:
            // All these load instructions may potentially produce an operand
            // that would be a parameter to a newarray, hence we need it to be
            // reachable with inequality edges. Need to keep it constrained.
            addOldOrCreateOpnd(inst->getDst());
            break;
        case Op_TauStInd: case Op_TauStElem: case Op_TauStField:
        case Op_TauStRef: case Op_TauStStatic:
            break;
        default:
            addOldOrCreateOpnd(inst->getDst())->setUnconstrained(true);
            break;
    }
}