diff options
author | Dan Gohman <gohman@apple.com> | 2012-02-16 00:57:37 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2012-02-16 00:57:37 +0000 |
commit | b49bd27b334a6c4e3bf9d810a7d5b022578f1194 (patch) | |
tree | 581c0e3a331d44255a09a3c38c7d4e2e707b8244 /lib/CodeGen/CGCall.cpp | |
parent | 9f02d6d2b7d62971ea619b4d0a6e68508e50ec24 (diff) |
Teach clang to add metadata tags to calls and invokes in ObjC with
-fno-objc-arc-exceptions. This will allow the optimizer to perform
optimizations which are only safe under that flag.
This is a part of rdar://10803830.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150644 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index b52a8977a7..6690a69b8d 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/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. |