Implement loadNonPrimitiveObj.

Since we allow structs in SSA, the code is similar to that for loading
primitive types.

Change getPrimitiveAddress to getTypedAddress so that it can be used for
both primitive and non-primitive types.
This commit is contained in:
Eugene Rozenfeld 2015-04-17 20:03:01 -07:00
Родитель 1f1bdd6dcb
Коммит fa4aee12ba
2 изменённых файлов: 40 добавлений и 13 удалений

Просмотреть файл

@ -420,9 +420,8 @@ public:
IRNode *loadNonPrimitiveObj(IRNode *Addr, CORINFO_CLASS_HANDLE ClassHandle,
ReaderAlignType Alignment, bool IsVolatile,
bool AddressMayBeNull = true) override {
throw NotYetImplementedException("loadNonPrimitiveObj");
};
bool AddressMayBeNull = true) override;
IRNode *makeRefAny(CORINFO_RESOLVED_TOKEN *ResolvedToken,
IRNode *Object) override {
throw NotYetImplementedException("makeRefAny");
@ -880,8 +879,19 @@ private:
CORINFO_RESOLVED_TOKEN *ResolvedToken,
CORINFO_FIELD_INFO *FieldInfo) override;
IRNode *getPrimitiveAddress(IRNode *Addr, CorInfoType CorInfoType,
ReaderAlignType Alignment, uint32_t *Align);
/// Get a node with the same value as Addr but typed as a pointer to the type
/// corresponding to CorInfoType and ClassHandle.
///
/// \param Addr Address to change the type on.
/// \param CorInfoType Type that Addr should point to.
/// \param ClassHandle Class handle corresponding to CorInfoType.
/// \param ReaderAlignment Reader alignment of the Addr access.
/// \param Alignment [out] Converted alignment corresponding to
/// ReaderAlignment.
/// \returns Address pointing to a value of the specified type.
IRNode *getTypedAddress(IRNode *Addr, CorInfoType CorInfoType,
CORINFO_CLASS_HANDLE ClassHandle,
ReaderAlignType ReaderAlignment, uint32_t *Alignment);
/// Generate instructions for loading value of the specified type at the
/// specified address.
///

Просмотреть файл

@ -2996,7 +2996,9 @@ void GenIR::storePrimitiveType(IRNode *Value, IRNode *Addr,
ASSERTNR(isPrimitiveType(CorInfoType));
uint32_t Align;
IRNode *TypedAddr = getPrimitiveAddress(Addr, CorInfoType, Alignment, &Align);
const CORINFO_CLASS_HANDLE ClassHandle = nullptr;
IRNode *TypedAddr =
getTypedAddress(Addr, CorInfoType, ClassHandle, Alignment, &Align);
Type *ExpectedTy =
cast<PointerType>(TypedAddr->getType())->getPointerElementType();
IRNode *ValueToStore = convertFromStackType(Value, CorInfoType, ExpectedTy);
@ -4949,10 +4951,9 @@ IRNode *GenIR::loadVirtFunc(IRNode *Arg1, CORINFO_RESOLVED_TOKEN *ResolvedToken,
return CodeAddress;
}
IRNode *GenIR::getPrimitiveAddress(IRNode *Addr, CorInfoType CorInfoType,
ReaderAlignType Alignment, uint32_t *Align) {
ASSERTNR(isPrimitiveType(CorInfoType) || CorInfoType == CORINFO_TYPE_REFANY);
IRNode *GenIR::getTypedAddress(IRNode *Addr, CorInfoType CorInfoType,
CORINFO_CLASS_HANDLE ClassHandle,
ReaderAlignType Alignment, uint32_t *Align) {
// Get type of the result.
Type *AddressTy = Addr->getType();
IRNode *TypedAddr = Addr;
@ -4977,8 +4978,8 @@ IRNode *GenIR::getPrimitiveAddress(IRNode *Addr, CorInfoType CorInfoType,
// GC pointers are always naturally aligned
Alignment = Reader_AlignNatural;
} else {
// For the true primitve case we may need to cast the address.
Type *ExpectedTy = this->getType(CorInfoType, nullptr);
// For other cases we may need to cast the address.
Type *ExpectedTy = this->getType(CorInfoType, ClassHandle);
PointerType *PointerTy = dyn_cast<PointerType>(AddressTy);
if (PointerTy != nullptr) {
Type *ReferentTy = PointerTy->getPointerElementType();
@ -5004,13 +5005,29 @@ IRNode *GenIR::loadPrimitiveType(IRNode *Addr, CorInfoType CorInfoType,
ReaderAlignType Alignment, bool IsVolatile,
bool IsInterfReadOnly, bool AddressMayBeNull) {
uint32_t Align;
IRNode *TypedAddr = getPrimitiveAddress(Addr, CorInfoType, Alignment, &Align);
const CORINFO_CLASS_HANDLE ClassHandle = nullptr;
IRNode *TypedAddr =
getTypedAddress(Addr, CorInfoType, ClassHandle, Alignment, &Align);
LoadInst *LoadInst = makeLoad(TypedAddr, IsVolatile, AddressMayBeNull);
LoadInst->setAlignment(Align);
return convertToStackType((IRNode *)LoadInst, CorInfoType);
}
IRNode *GenIR::loadNonPrimitiveObj(IRNode *Addr,
CORINFO_CLASS_HANDLE ClassHandle,
ReaderAlignType Alignment, bool IsVolatile,
bool AddressMayBeNull) {
uint32_t Align;
CorInfoType CorType = JitContext->JitInfo->asCorInfoType(ClassHandle);
IRNode *TypedAddr =
getTypedAddress(Addr, CorType, ClassHandle, Alignment, &Align);
LoadInst *LoadInst = makeLoad(TypedAddr, IsVolatile, AddressMayBeNull);
LoadInst->setAlignment(Align);
return (IRNode *)LoadInst;
};
void GenIR::classifyCmpType(Type *Ty, uint32_t &Size, bool &IsPointer,
bool &IsFloat) {
switch (Ty->getTypeID()) {