AliasRep AliasManager::getReference()

in vm/jitrino/src/optimizer/memoryopt.cpp [1200:1387]


AliasRep AliasManager::getReference(Opnd *addr)
{
    // examine the address
    Inst *addri = addr->getInst();
    Opcode opcode = addri->getOpcode();
    switch (opcode) {
    case Op_LdFieldAddr: 
        {
            FieldAccessInst *faInst = addri->asFieldAccessInst();
            assert(faInst);
            Opnd *obj = faInst->getSrc(0);
            FieldDesc *field = faInst->getFieldDesc();
            return findOrInsertAlias(getObjectField(obj, field));
        }
    case Op_LdStaticAddr:
        {
            FieldAccessInst *faInst = addri->asFieldAccessInst();
            assert(faInst);
            FieldDesc *field = faInst->getFieldDesc();
            return findOrInsertAlias(getStaticField(field));
        }
    case Op_LdElemAddr:
        {
            Opnd *theArray = addri->getSrc(0);
            Type *theType = theArray->getType();
            assert(theType->isArrayType());
            ArrayType *arrayType = (ArrayType *)theType;
            NamedType *eltType = arrayType->getElementType();
            return findOrInsertAlias(getArrayElementByType(eltType));
        }
    case Op_LdArrayBaseAddr:
        {
            Opnd *theArray = addri->getSrc(0);
            Type *theType = theArray->getType();
            assert(theType->isArrayType());
            ArrayType *arrayType = (ArrayType *)theType;
            NamedType *eltType = arrayType->getElementType();
            return findOrInsertAlias(getArrayElementByType(eltType));
        }
    case Op_AddScaledIndex:
        {
            Type *eltType = NULL;
            Opnd *thePtr = addri->getSrc(0);
            Type *theType = thePtr->getType();
            if (theType->isManagedPtr() || theType->isUnmanagedPtr()) {
                PtrType *thePtrType = (PtrType *) theType;
                eltType = thePtrType->getPointedToType();
            } else {
                assert(0);
            }
            return findOrInsertAlias(getArrayElementByType(eltType));
        }
    case Op_TauLdVTableAddr:
        {
            Opnd *theObject = addri->getSrc(0);
            return findOrInsertAlias(getVtableOf(theObject));
        }
    case Op_GetVTableAddr:
        {
            TypeInst *typeInst = addri->asTypeInst();
            Type *theType = typeInst->getTypeInfo();
            return findOrInsertAlias(getVtableOf((NamedType *)theType));
        }
    case Op_TauLdIntfcVTableAddr:
        {
            Opnd *theObject = addri->getSrc(0);
            return findOrInsertAlias(getVtableOf(theObject));
        }
    case Op_TauLdVirtFunAddr:
        {
            Opnd *theObject = addri->getSrc(0);
            return findOrInsertAlias(getVtableOf(theObject));
        }
    case Op_TauLdVirtFunAddrSlot:
        {
            Opnd *theObject = addri->getSrc(0);
            return findOrInsertAlias(getVtableOf(theObject));
        }
    case Op_LdFunAddr: // static member function address
        {            
            MethodInst *mi = addri->asMethodInst();
            MethodDesc *mdesc = mi->getMethodDesc();
            NamedType *theType = mdesc->getParentType();
            return findOrInsertAlias(getVtableOf(theType));
        }
    case Op_LdFunAddrSlot:
        {            
            MethodInst *mi = addri->asMethodInst();
            MethodDesc *mdesc = mi->getMethodDesc();
            NamedType *theType = mdesc->getParentType();
            return findOrInsertAlias(getVtableOf(theType));
        }

    case Op_StVar:
    case Op_LdVar:
    case Op_UncompressRef:
    case Op_CompressRef:
    case Op_Copy:
        {
            return getReference(addri->getSrc(0));
        }

    case Op_LdFieldOffset:
    case Op_LdFieldOffsetPlusHeapbase:
        {
            FieldAccessInst *faInst = addri->asFieldAccessInst();
            assert(faInst);
            FieldDesc *field = faInst->getFieldDesc();
            return findOrInsertAlias(getObjectField(0, field));
        }

    case Op_LdArrayBaseOffset:
    case Op_LdArrayBaseOffsetPlusHeapbase:
        {
            TypeInst *tinst = addri->asTypeInst();
            assert(tinst);
            Type *eltType = tinst->getTypeInfo();
            NamedType *namedEltType = (NamedType *)eltType;
            return findOrInsertAlias(getArrayElementByType(namedEltType));
        }

    case Op_LdArrayLenOffset:
    case Op_LdArrayLenOffsetPlusHeapbase:
        {
            return findOrInsertAlias(getArrayLen(0));
        }

    case Op_AddOffset:
    case Op_AddOffsetPlusHeapbase:
        {
            Opnd *baseOpnd = addri->getSrc(0);
            Opnd *offsetOpnd = addri->getSrc(1);

            AliasRep offsetRep = getReference(offsetOpnd);
            switch (offsetRep.kind) {
            case AliasRep::ArrayLenKind:
                return findOrInsertAlias(getArrayLen(baseOpnd));
            case AliasRep::ArrayElementKind:
                return offsetRep;
            case AliasRep::ObjectFieldKind:
                {
                    TypeMemberDesc *desc = offsetRep.desc;
                    assert(offsetRep.opnd == 0);
                    return findOrInsertAlias(getObjectField(baseOpnd, desc));
                }
            case AliasRep::UnresolvedObjectFieldKind:
                {
                    assert(offsetRep.opnd == 0);
                    Opnd* enclClass = offsetRep.enclClass;
                    Opnd* cpIdx = offsetRep.idx;
                    assert(enclClass!=NULL &&  cpIdx!=NULL);
                    return findOrInsertAlias(getUnresolvedObjectField(baseOpnd, enclClass, cpIdx));
                }
            case AliasRep::LockKind:
                assert(offsetRep.opnd == 0);
                return findOrInsertAlias(getLock(baseOpnd));
            default:
                assert(0);
            }
        }

    case Op_LdVarAddr:
    case Op_Phi:
    case Op_DefArg: //magic as method param
        break;
    case Op_Conv: //the result of a conversion
    case Op_ConvZE:
    case Op_ConvUnmanaged:
    case Op_TauLdInd: // the result of static field load
    case Op_LdConstant:
        break;
    case Op_VMHelperCall:
        {
            VMHelperCallInst* callInst = addri->asVMHelperCallInst();
            assert(callInst->getVMHelperId() == VM_RT_GET_NONSTATIC_FIELD_OFFSET_WITHRESOLVE
                || callInst->getVMHelperId() == VM_RT_GET_STATIC_FIELD_ADDR_WITHRESOLVE);
            Opnd* enclClass = callInst->getSrc(0);
            Opnd* cpIdx = callInst->getSrc(1);
            return findOrInsertAlias(getUnresolvedObjectField(0, enclClass, cpIdx));
        }
        // break; unreachable because of the return above
    default:
        assert(0);
        break;
    }
    AliasRep theAlias = getAny(); // (AliasRep::UnknownKind);
    return findOrInsertAlias(theAlias);
}