diff options
author | Tim Northover <tnorthover@apple.com> | 2014-03-29 13:42:40 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-03-29 13:42:40 +0000 |
commit | 238b508aafd6199a98c09e5a600452e3496f03c3 (patch) | |
tree | 1bef5376c70b7a720a6b0ed7687425e68d1b175c /clang/lib/CodeGen | |
parent | e77cc39afff8b9bedbd5a3be6fdbeef5e786184f (diff) | |
download | bcm5719-llvm-238b508aafd6199a98c09e5a600452e3496f03c3.tar.gz bcm5719-llvm-238b508aafd6199a98c09e5a600452e3496f03c3.zip |
ARM64: parametrise IVar offset type (long on ARM64, int elsewhere).
This is part of the ARM64 patch, but can only be tested properly when
the full codegen gets committed.
llvm-svn: 205098
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 51fbbed32c6..8f5969c919c 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -174,6 +174,7 @@ protected: public: llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy; llvm::Type *Int8PtrTy, *Int8PtrPtrTy; + llvm::Type *IvarOffsetVarTy; /// ObjectPtrTy - LLVM type for object handles (typeof(id)) llvm::Type *ObjectPtrTy; @@ -5028,6 +5029,13 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) Int8PtrTy = CGM.Int8PtrTy; Int8PtrPtrTy = CGM.Int8PtrPtrTy; + // arm64 targets use "int" ivar offset variables. All others, + // including OS X x86_64 and Windows x86_64, use "long" ivar offsets. + if (CGM.getTarget().getTriple().getArch() == llvm::Triple::arm64) + IvarOffsetVarTy = IntTy; + else + IvarOffsetVarTy = LongTy; + ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); @@ -5331,16 +5339,15 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); // struct _ivar_t { - // unsigned long int *offset; // pointer to ivar offset location + // unsigned [long] int *offset; // pointer to ivar offset location // char *name; // char *type; // uint32_t alignment; // uint32_t size; // } - IvarnfABITy = - llvm::StructType::create("struct._ivar_t", - llvm::PointerType::getUnqual(LongTy), - Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL); + IvarnfABITy = llvm::StructType::create( + "struct._ivar_t", llvm::PointerType::getUnqual(IvarOffsetVarTy), + Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL); // struct _ivar_list_t { // uint32 entsize; // sizeof(struct _ivar_t) @@ -6093,12 +6100,9 @@ CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name); if (!IvarOffsetGV) - IvarOffsetGV = - new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy, - false, - llvm::GlobalValue::ExternalLinkage, - 0, - Name); + IvarOffsetGV = new llvm::GlobalVariable( + CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false, + llvm::GlobalValue::ExternalLinkage, 0, Name); return IvarOffsetGV; } @@ -6107,10 +6111,10 @@ CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar, unsigned long int Offset) { llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); - IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, - Offset)); + IvarOffsetGV->setInitializer( + llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset)); IvarOffsetGV->setAlignment( - CGM.getDataLayout().getABITypeAlignment(ObjCTypes.LongTy)); + CGM.getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy)); // FIXME: This matches gcc, but shouldn't the visibility be set on the use as // well (i.e., in ObjCIvarOffsetVariable). @@ -6128,7 +6132,7 @@ CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, /// implementation. The return value has type /// IvarListnfABIPtrTy. /// struct _ivar_t { -/// unsigned long int *offset; // pointer to ivar offset location +/// unsigned [long] int *offset; // pointer to ivar offset location /// char *name; /// char *type; /// uint32_t alignment; @@ -6444,12 +6448,6 @@ LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( unsigned CVRQualifiers) { ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface(); llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar); - - if (IsIvarOffsetKnownIdempotent(CGF, Ivar)) - if (llvm::LoadInst *LI = cast<llvm::LoadInst>(Offset)) - LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), - llvm::MDNode::get(VMContext, ArrayRef<llvm::Value*>())); - return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, Offset); } @@ -6458,7 +6456,20 @@ llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset( CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar) { - return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar"); + llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar); + IvarOffsetValue = CGF.Builder.CreateLoad(IvarOffsetValue, "ivar"); + if (IsIvarOffsetKnownIdempotent(CGF, Ivar)) + cast<llvm::LoadInst>(IvarOffsetValue) + ->setMetadata(CGM.getModule().getMDKindID("invariant.load"), + llvm::MDNode::get(VMContext, ArrayRef<llvm::Value *>())); + + // This could be 32bit int or 64bit integer depending on the architecture. + // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value + // as this is what caller always expectes. + if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy) + IvarOffsetValue = CGF.Builder.CreateIntCast( + IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv"); + return IvarOffsetValue; } static void appendSelectorForMessageRefTable(std::string &buffer, |