r205098 - ARM64: parametrise IVar offset type (long on ARM64, int elsewhere).
Tim Northover
tnorthover at apple.com
Sat Mar 29 06:42:40 PDT 2014
Author: tnorthover
Date: Sat Mar 29 08:42:40 2014
New Revision: 205098
URL: http://llvm.org/viewvc/llvm-project?rev=205098&view=rev
Log:
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.
Modified:
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=205098&r1=205097&r2=205098&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sat Mar 29 08:42:40 2014
@@ -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::ObjCCommonTypesHe
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::ObjCNonFra
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::ObjCIvarOffsetVa
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::EmitIvarOffsetVa
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::EmitIvarOffsetVa
/// 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::EmitObjCV
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::Emi
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,
More information about the cfe-commits
mailing list