diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 35 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 9 |
4 files changed, 42 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index b52a8977a7c..6690a69b8d6 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1593,6 +1593,16 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, args.add(EmitAnyExprToTemp(E), type); } +// In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC +// optimizer it can aggressively ignore unwind edges. +void +CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) { + if (CGM.getCodeGenOpts().OptimizationLevel != 0 && + !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions) + Inst->setMetadata("clang.arc.no_objc_arc_exceptions", + CGM.getNoObjCARCExceptionsMetadata()); +} + /// Emits a call or invoke instruction to the given function, depending /// on the current state of the EH stack. llvm::CallSite @@ -1600,14 +1610,22 @@ CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee, ArrayRef<llvm::Value *> Args, const Twine &Name) { llvm::BasicBlock *InvokeDest = getInvokeDest(); + + llvm::Instruction *Inst; if (!InvokeDest) - return Builder.CreateCall(Callee, Args, Name); + Inst = Builder.CreateCall(Callee, Args, Name); + else { + llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont"); + Inst = Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, Name); + EmitBlock(ContBB); + } + + // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC + // optimizer it can aggressively ignore unwind edges. + if (CGM.getLangOptions().ObjCAutoRefCount) + AddObjCARCExceptionMetadata(Inst); - llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont"); - llvm::InvokeInst *Invoke = Builder.CreateInvoke(Callee, ContBB, InvokeDest, - Args, Name); - EmitBlock(ContBB); - return Invoke; + return Inst; } llvm::CallSite @@ -1916,6 +1934,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, CS.setAttributes(Attrs); CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); + // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC + // optimizer it can aggressively ignore unwind edges. + if (CGM.getLangOptions().ObjCAutoRefCount) + AddObjCARCExceptionMetadata(CS.getInstruction()); + // If the call doesn't return, finish the basic block and clear the // insertion point; this allows the rest of IRgen to discard // unreachable code. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 9081ece6f8f..263a0639fa0 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2566,6 +2566,8 @@ private: CodeGenModule::ByrefHelpers * buildByrefHelpers(llvm::StructType &byrefType, const AutoVarEmission &emission); + + void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); }; /// Helper class with most of the code for saving a value for a diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 2ebea592641..dd613b4014f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -69,7 +69,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI, CGO), TBAA(0), VTables(*this), ObjCRuntime(0), OpenCLRuntime(0), CUDARuntime(0), - DebugInfo(0), ARCData(0), RRData(0), CFConstantStringClassRef(0), + DebugInfo(0), ARCData(0), NoObjCARCExceptionsMetadata(0), + RRData(0), CFConstantStringClassRef(0), ConstantStringClassRef(0), NSConstantStringType(0), VMContext(M.getContext()), NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 6813edd5f18..9b6931d5aa7 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -233,6 +233,7 @@ class CodeGenModule : public CodeGenTypeCache { CGCUDARuntime* CUDARuntime; CGDebugInfo* DebugInfo; ARCEntrypoints *ARCData; + llvm::MDNode *NoObjCARCExceptionsMetadata; RREntrypoints *RRData; // WeakRefReferences - A set of references that have only been seen via @@ -421,6 +422,14 @@ public: CGDebugInfo *getModuleDebugInfo() { return DebugInfo; } + llvm::MDNode *getNoObjCARCExceptionsMetadata() { + if (!NoObjCARCExceptionsMetadata) + NoObjCARCExceptionsMetadata = + llvm::MDNode::get(getLLVMContext(), + SmallVector<llvm::Value*,1>()); + return NoObjCARCExceptionsMetadata; + } + ASTContext &getContext() const { return Context; } const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; } const LangOptions &getLangOptions() const { return Features; } |