diff options
author | Pete Cooper <peter_cooper@apple.com> | 2018-12-18 20:33:00 +0000 |
---|---|---|
committer | Pete Cooper <peter_cooper@apple.com> | 2018-12-18 20:33:00 +0000 |
commit | 2cd3596b1a48a3ff007f58f933e77442caeec746 (patch) | |
tree | 3d97406966339ee15d714a06df59b69b65e9b7d6 /clang/lib/CodeGen | |
parent | be4f5711073613115c036206db0d9a45fd0632ab (diff) | |
download | bcm5719-llvm-2cd3596b1a48a3ff007f58f933e77442caeec746.tar.gz bcm5719-llvm-2cd3596b1a48a3ff007f58f933e77442caeec746.zip |
Generate objc intrinsics instead of runtime calls as the ARC optimizer now works only on intrinsics
Differential Revision: https://reviews.llvm.org/D55802
Reviewers: rjmccall
llvm-svn: 349535
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 165 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 4 |
2 files changed, 94 insertions, 75 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index cc582b926be..3747f4920a8 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -1873,12 +1873,8 @@ void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) { EmitNounwindRuntimeCall(fn, values); } - -static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM, - llvm::FunctionType *FTy, - StringRef Name) { - llvm::Constant *RTF = CGM.CreateRuntimeFunction(FTy, Name); - +static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, + llvm::Constant *RTF) { if (auto *F = dyn_cast<llvm::Function>(RTF)) { // If the target runtime doesn't naturally support ARC, emit weak // references to the runtime support library. We don't really @@ -1886,14 +1882,8 @@ static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM, if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC() && !CGM.getTriple().isOSBinFormatCOFF()) { F->setLinkage(llvm::Function::ExternalWeakLinkage); - } else if (Name == "objc_retain" || Name == "objc_release") { - // If we have Native ARC, set nonlazybind attribute for these APIs for - // performance. - F->addFnAttr(llvm::Attribute::NonLazyBind); } } - - return RTF; } /// Perform an operation having the signature @@ -1903,15 +1893,14 @@ static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, llvm::Constant *&fn, - StringRef fnName, + llvm::Intrinsic::ID IntID, bool isTailCall = false) { if (isa<llvm::ConstantPointerNull>(value)) return value; if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, false); - fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); + fn = CGF.CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGF.CGM, fn); } // Cast the argument to 'id'. @@ -1932,11 +1921,10 @@ static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF, static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr, llvm::Constant *&fn, - StringRef fnName) { + llvm::Intrinsic::ID IntID) { if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrPtrTy, false); - fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); + fn = CGF.CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGF.CGM, fn); } // Cast the argument to 'id*'. @@ -1959,16 +1947,13 @@ static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr, llvm::Value *value, llvm::Constant *&fn, - StringRef fnName, + llvm::Intrinsic::ID IntID, bool ignored) { assert(addr.getElementType() == value->getType()); if (!fn) { - llvm::Type *argTypes[] = { CGF.Int8PtrPtrTy, CGF.Int8PtrTy }; - - llvm::FunctionType *fnType - = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false); - fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); + fn = CGF.CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGF.CGM, fn); } llvm::Type *origType = value->getType(); @@ -1990,15 +1975,12 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, llvm::Constant *&fn, - StringRef fnName) { + llvm::Intrinsic::ID IntID) { assert(dst.getType() == src.getType()); if (!fn) { - llvm::Type *argTypes[] = { CGF.Int8PtrPtrTy, CGF.Int8PtrPtrTy }; - - llvm::FunctionType *fnType - = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false); - fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); + fn = CGF.CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGF.CGM, fn); } llvm::Value *args[] = { @@ -2008,6 +1990,34 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, CGF.EmitNounwindRuntimeCall(fn, args); } +/// Perform an operation having the signature +/// i8* (i8*) +/// where a null input causes a no-op and returns null. +static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF, + llvm::Value *value, + llvm::Type *returnType, + llvm::Constant *&fn, + StringRef fnName) { + if (isa<llvm::ConstantPointerNull>(value)) + return value; + + if (!fn) { + llvm::FunctionType *fnType = + llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, false); + fn = CGF.CGM.CreateRuntimeFunction(fnType, fnName); + } + + // Cast the argument to 'id'. + llvm::Type *origType = returnType ? returnType : value->getType(); + value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy); + + // Call the function. + llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value); + + // Cast the result back to the original type. + return CGF.Builder.CreateBitCast(call, origType); +} + /// Produce the code to do a retain. Based on the type, calls one of: /// call i8* \@objc_retain(i8* %value) /// call i8* \@objc_retainBlock(i8* %value) @@ -2023,7 +2033,7 @@ llvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) { llvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retain, - "objc_retain"); + llvm::Intrinsic::objc_retain); } /// Retain the given block, with _Block_copy semantics. @@ -2037,7 +2047,7 @@ llvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value, llvm::Value *result = emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retainBlock, - "objc_retainBlock"); + llvm::Intrinsic::objc_retainBlock); // If the copy isn't mandatory, add !clang.arc.copy_on_escape to // tell the optimizer that it doesn't need to do this copy if the @@ -2107,7 +2117,7 @@ CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) { emitAutoreleasedReturnValueMarker(*this); return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue, - "objc_retainAutoreleasedReturnValue"); + llvm::Intrinsic::objc_retainAutoreleasedReturnValue); } /// Claim a possibly-autoreleased return value at +0. This is only @@ -2122,7 +2132,7 @@ CodeGenFunction::EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value) { emitAutoreleasedReturnValueMarker(*this); return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_unsafeClaimAutoreleasedReturnValue, - "objc_unsafeClaimAutoreleasedReturnValue"); + llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue); } /// Release the given object. @@ -2133,9 +2143,8 @@ void CodeGenFunction::EmitARCRelease(llvm::Value *value, llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_release; if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false); - fn = createARCRuntimeFunction(CGM, fnType, "objc_release"); + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_release); + setARCRuntimeFunctionLinkage(CGM, fn); } // Cast the argument to 'id'. @@ -2180,10 +2189,8 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr, llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_storeStrong; if (!fn) { - llvm::Type *argTypes[] = { Int8PtrPtrTy, Int8PtrTy }; - llvm::FunctionType *fnType - = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false); - fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong"); + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_storeStrong); + setARCRuntimeFunctionLinkage(CGM, fn); } llvm::Value *args[] = { @@ -2237,7 +2244,7 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst, llvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_autorelease, - "objc_autorelease"); + llvm::Intrinsic::objc_autorelease); } /// Autorelease the given object. @@ -2246,7 +2253,7 @@ llvm::Value * CodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_autoreleaseReturnValue, - "objc_autoreleaseReturnValue", + llvm::Intrinsic::objc_autoreleaseReturnValue, /*isTailCall*/ true); } @@ -2256,7 +2263,7 @@ llvm::Value * CodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retainAutoreleaseReturnValue, - "objc_retainAutoreleaseReturnValue", + llvm::Intrinsic::objc_retainAutoreleaseReturnValue, /*isTailCall*/ true); } @@ -2285,7 +2292,7 @@ llvm::Value * CodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) { return emitARCValueOperation(*this, value, nullptr, CGM.getObjCEntrypoints().objc_retainAutorelease, - "objc_retainAutorelease"); + llvm::Intrinsic::objc_retainAutorelease); } /// i8* \@objc_loadWeak(i8** %addr) @@ -2293,14 +2300,14 @@ CodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) { llvm::Value *CodeGenFunction::EmitARCLoadWeak(Address addr) { return emitARCLoadOperation(*this, addr, CGM.getObjCEntrypoints().objc_loadWeak, - "objc_loadWeak"); + llvm::Intrinsic::objc_loadWeak); } /// i8* \@objc_loadWeakRetained(i8** %addr) llvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(Address addr) { return emitARCLoadOperation(*this, addr, CGM.getObjCEntrypoints().objc_loadWeakRetained, - "objc_loadWeakRetained"); + llvm::Intrinsic::objc_loadWeakRetained); } /// i8* \@objc_storeWeak(i8** %addr, i8* %value) @@ -2310,7 +2317,7 @@ llvm::Value *CodeGenFunction::EmitARCStoreWeak(Address addr, bool ignored) { return emitARCStoreOperation(*this, addr, value, CGM.getObjCEntrypoints().objc_storeWeak, - "objc_storeWeak", ignored); + llvm::Intrinsic::objc_storeWeak, ignored); } /// i8* \@objc_initWeak(i8** %addr, i8* %value) @@ -2330,7 +2337,7 @@ void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) { emitARCStoreOperation(*this, addr, value, CGM.getObjCEntrypoints().objc_initWeak, - "objc_initWeak", /*ignored*/ true); + llvm::Intrinsic::objc_initWeak, /*ignored*/ true); } /// void \@objc_destroyWeak(i8** %addr) @@ -2338,9 +2345,8 @@ void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) { void CodeGenFunction::EmitARCDestroyWeak(Address addr) { llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_destroyWeak; if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrPtrTy, false); - fn = createARCRuntimeFunction(CGM, fnType, "objc_destroyWeak"); + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_destroyWeak); + setARCRuntimeFunctionLinkage(CGM, fn); } // Cast the argument to 'id*'. @@ -2355,7 +2361,7 @@ void CodeGenFunction::EmitARCDestroyWeak(Address addr) { void CodeGenFunction::EmitARCMoveWeak(Address dst, Address src) { emitARCCopyOperation(*this, dst, src, CGM.getObjCEntrypoints().objc_moveWeak, - "objc_moveWeak"); + llvm::Intrinsic::objc_moveWeak); } /// void \@objc_copyWeak(i8** %dest, i8** %src) @@ -2364,7 +2370,7 @@ void CodeGenFunction::EmitARCMoveWeak(Address dst, Address src) { void CodeGenFunction::EmitARCCopyWeak(Address dst, Address src) { emitARCCopyOperation(*this, dst, src, CGM.getObjCEntrypoints().objc_copyWeak, - "objc_copyWeak"); + llvm::Intrinsic::objc_copyWeak); } void CodeGenFunction::emitARCCopyAssignWeak(QualType Ty, Address DstAddr, @@ -2387,9 +2393,8 @@ void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr, llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush; if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(Int8PtrTy, false); - fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush"); + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush); + setARCRuntimeFunctionLinkage(CGM, fn); } return EmitNounwindRuntimeCall(fn); @@ -2400,18 +2405,28 @@ llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) { assert(value->getType() == Int8PtrTy); - llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop; - if (!fn) { - llvm::FunctionType *fnType = - llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false); + if (getInvokeDest()) { + // Call the runtime method not the intrinsic if we are handling exceptions + llvm::Constant *&fn = + CGM.getObjCEntrypoints().objc_autoreleasePoolPopInvoke; + if (!fn) { + llvm::FunctionType *fnType = + llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false); + fn = CGM.CreateRuntimeFunction(fnType, "objc_autoreleasePoolPop"); + setARCRuntimeFunctionLinkage(CGM, fn); + } - // We don't want to use a weak import here; instead we should not - // fall into this path. - fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop"); - } + // objc_autoreleasePoolPop can throw. + EmitRuntimeCallOrInvoke(fn, value); + } else { + llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop; + if (!fn) { + fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop); + setARCRuntimeFunctionLinkage(CGM, fn); + } - // objc_autoreleasePoolPop can throw. - EmitRuntimeCallOrInvoke(fn, value); + EmitRuntimeCall(fn, value); + } } /// Produce the code to do an MRR version objc_autoreleasepool_push. @@ -2446,18 +2461,18 @@ llvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() { /// call i8* \@objc_alloc(i8* %value) llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value, llvm::Type *resultType) { - return emitARCValueOperation(*this, value, resultType, - CGM.getObjCEntrypoints().objc_alloc, - "objc_alloc"); + return emitObjCValueOperation(*this, value, resultType, + CGM.getObjCEntrypoints().objc_alloc, + "objc_alloc"); } /// Allocate the given objc object. /// call i8* \@objc_allocWithZone(i8* %value) llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value, llvm::Type *resultType) { - return emitARCValueOperation(*this, value, resultType, - CGM.getObjCEntrypoints().objc_allocWithZone, - "objc_allocWithZone"); + return emitObjCValueOperation(*this, value, resultType, + CGM.getObjCEntrypoints().objc_allocWithZone, + "objc_allocWithZone"); } /// Produce the code to do a primitive release. diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 0f6c3bec9e7..f0d72af3ad8 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -128,6 +128,10 @@ struct ObjCEntrypoints { /// void objc_autoreleasePoolPop(void*); llvm::Constant *objc_autoreleasePoolPop; + /// void objc_autoreleasePoolPop(void*); + /// Note this method is used when we are using exception handling + llvm::Constant *objc_autoreleasePoolPopInvoke; + /// void *objc_autoreleasePoolPush(void); llvm::Constant *objc_autoreleasePoolPush; |