bool allowsAnyZeroElimination()

in vm/jitrino/src/optimizer/hashvaluenumberer.cpp [1530:1680]


bool allowsAnyZeroElimination(ComparisonModifier mod, Type::Tag comparisonType,
                              Opnd *src0, Opnd *src1, bool isTrueEdge,
                              Opnd **opnd)
{
    bool positive = false;
    switch (mod) {
    case Cmp_EQ:
        positive = true;
    case Cmp_NE_Un:
        {
            bool canelim = false;
            ConstInst::ConstValue cv;
            Opnd *constOpnd = 0;
            Opnd *otherOpnd = 0;
            if (ConstantFolder::isConstant(src0->getInst(), cv)) {
                constOpnd = src0;
                otherOpnd = src1;
            } else if (ConstantFolder::isConstant(src1->getInst(), cv)) {
                constOpnd = src1;
                otherOpnd = src0;
            } else {
                return false;
            }
            bool notEqual = isTrueEdge ^ positive; // we know (nonconst != const)
            switch (constOpnd->getInst()->getType()) {
            case Type::Int8: case Type::Int16: case Type::Int32:
            case Type::UInt8: case Type::UInt16: case Type::UInt32:
                canelim = (notEqual ? (cv.i4 == 0) : (cv.i4 != 0)); break;
            case Type::Int64:
            case Type::UInt64:
                canelim = (notEqual ? (cv.i8 == 0) : (cv.i8 != 0)); break;
            case Type::IntPtr: 
            case Type::UIntPtr:
            case Type::ManagedPtr: case Type::UnmanagedPtr:
            case Type::SystemObject: case Type::SystemClass: case Type::SystemString:
            case Type::Array: case Type::Object: 
            case Type::BoxedValue:
            case Type::MethodPtr: case Type::VTablePtr:
            case Type::CompressedSystemObject: 
            case Type::CompressedSystemClass: 
            case Type::CompressedSystemString:
            case Type::CompressedArray: case Type::CompressedObject:
                canelim = (notEqual ? (cv.i == 0) : (cv.i != 0)); break;
            case Type::NullObject:
            case Type::CompressedNullObject:
                canelim = notEqual; break;
            default:
                break;
            }
            if (canelim) {
                *opnd = otherOpnd;
                return true;
            }
        }
        break;
    case Cmp_GT:
    case Cmp_GT_Un:
        positive = true;
    case Cmp_GTE:
    case Cmp_GTE_Un:
        if (isTrueEdge) {
            Inst *src1inst = src1->getInst();
            ConstInst::ConstValue cv;
            if (ConstantFolder::isConstant(src1inst, cv)) {
                bool canelim = false;
                switch (src1inst->getType()) {
                case Type::Int8: case Type::Int16: case Type::Int32:
                    canelim = (positive ? (cv.i4 >= 0) : (cv.i4 > 0)); break;
                case Type::Int64:
                    canelim = (positive ? (cv.i8 >= 0) : (cv.i8 > 0)); break;
                case Type::IntPtr:
                    canelim = (positive ? true : (cv.i != 0)); break;
                case Type::UInt8: case Type::UInt16: case Type::UInt32:
                    canelim = (positive ? true : (cv.i4 != 0)); break;
                case Type::UInt64:
                    canelim = (positive ? true : (cv.i8 != 0)); break;
                case Type::UIntPtr:
                    canelim = (positive ? true : (cv.i != 0)); break;
                default:
                    break;
                }
                if (canelim) {
                    *opnd = src0;
                    return true;
                }
            }
        } else {
            Inst *src0inst = src0->getInst();
            ConstInst::ConstValue cv;
            if (ConstantFolder::isConstant(src0inst, cv)) {
                bool canelim = false;
                switch (src0inst->getType()) {
                case Type::Int8: case Type::Int16: case Type::Int32:
                    canelim = (positive ? (cv.i4 <= 0) : (cv.i4 < 0)); break;
                case Type::Int64:
                    canelim = (positive ? (cv.i8 <= 0) : (cv.i8 < 0)); break;
                case Type::IntPtr:
                    canelim = (positive ? true : (cv.i != 0)); break;
                case Type::UInt8: case Type::UInt16: case Type::UInt32:
                    canelim = (positive ? true : (cv.i4 != 0)); break;
                case Type::UInt64:
                    canelim = (positive ? true : (cv.i8 != 0)); break;
                case Type::UIntPtr:
                    canelim = (positive ? true : (cv.i != 0)); break;
                default:
                    break;
                }
                if (canelim) {
                    *opnd = src1;
                    return true;
                }
            }
        }
        break;
    case Cmp_Zero:
        positive = true;
    case Cmp_NonZero:
        {
            bool canelim = false;
            switch (src0->getInst()->getType()) {
            case Type::Int8: case Type::Int16: case Type::Int32:
            case Type::UInt8: case Type::UInt16: case Type::UInt32:
            case Type::Int64:
            case Type::UInt64:
            case Type::IntPtr: 
            case Type::UIntPtr:
            case Type::ManagedPtr: case Type::UnmanagedPtr:
            case Type::SystemObject: case Type::SystemClass: case Type::SystemString:
            case Type::Array: case Type::Object: case Type::BoxedValue:
            case Type::MethodPtr: case Type::VTablePtr:
            case Type::CompressedSystemObject: 
            case Type::CompressedSystemClass: 
            case Type::CompressedSystemString:
            case Type::CompressedArray: case Type::CompressedObject:
                canelim = positive ^ isTrueEdge; break;
            case Type::NullObject: case Type::CompressedNullObject:
            default:
                break;
            }
            if (canelim) {
                *opnd = src0;
                return true;
            }
        }
        break;
    default:
        assert(0);
        break;
    }
    return false;
}