diff options
-rw-r--r-- | lib/CodeGen/ABIInfo.h | 13 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 34 | ||||
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGCUDANV.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 85 | ||||
-rw-r--r-- | lib/CodeGen/CGDeclCXX.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGException.cpp | 84 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 64 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 87 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 258 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCRuntime.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCRuntime.h | 10 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 18 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 6 | ||||
-rw-r--r-- | lib/CodeGen/ItaniumCXXABI.cpp | 10 | ||||
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 74 | ||||
-rw-r--r-- | test/CodeGenCXX/runtimecc.cpp | 53 | ||||
-rw-r--r-- | test/CodeGenObjC/arc-arm.m | 4 |
23 files changed, 525 insertions, 338 deletions
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h index 10e2f60c86..35780f1556 100644 --- a/lib/CodeGen/ABIInfo.h +++ b/lib/CodeGen/ABIInfo.h @@ -12,6 +12,7 @@ #include "clang/AST/Type.h" #include "llvm/IR/Type.h" +#include "llvm/IR/CallingConv.h" namespace llvm { class Value; @@ -184,14 +185,24 @@ namespace clang { class ABIInfo { public: CodeGen::CodeGenTypes &CGT; + protected: + llvm::CallingConv::ID RuntimeCC; + public: + ABIInfo(CodeGen::CodeGenTypes &cgt) + : CGT(cgt), RuntimeCC(llvm::CallingConv::C) {} - ABIInfo(CodeGen::CodeGenTypes &cgt) : CGT(cgt) {} virtual ~ABIInfo(); ASTContext &getContext() const; llvm::LLVMContext &getVMContext() const; const llvm::DataLayout &getDataLayout() const; + /// Return the calling convention to use for system runtime + /// functions. + llvm::CallingConv::ID getRuntimeCC() const { + return RuntimeCC; + } + virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; /// EmitVAArg - Emit the target dependent code to load a value of diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 2d51a154ad..23aa066dce 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Module.h" +#include "llvm/Support/CallSite.h" #include <algorithm> #include <cstdio> @@ -1398,8 +1399,24 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { } else { srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy); llvm::Value *dstAddr = Builder.CreateBitCast(dstField, VoidPtrTy); - Builder.CreateCall3(CGM.getBlockObjectAssign(), dstAddr, srcValue, - llvm::ConstantInt::get(Int32Ty, flags.getBitMask())); + llvm::Value *args[] = { + dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) + }; + + bool copyCanThrow = false; + if (ci->isByRef() && variable->getType()->getAsCXXRecordDecl()) { + const Expr *copyExpr = + CGM.getContext().getBlockVarCopyInits(variable); + if (copyExpr) { + copyCanThrow = true; // FIXME: reuse the noexcept logic + } + } + + if (copyCanThrow) { + EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args); + } else { + EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args); + } } } } @@ -1562,7 +1579,9 @@ public: llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags); llvm::Value *fn = CGF.CGM.getBlockObjectAssign(); - CGF.Builder.CreateCall3(fn, destField, srcValue, flagsVal); + + llvm::Value *args[] = { destField, srcValue, flagsVal }; + CGF.EmitNounwindRuntimeCall(fn, args); } void emitDispose(CodeGenFunction &CGF, llvm::Value *field) { @@ -2174,10 +2193,11 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags) { llvm::Value *F = CGM.getBlockObjectDispose(); - llvm::Value *N; - V = Builder.CreateBitCast(V, Int8PtrTy); - N = llvm::ConstantInt::get(Int32Ty, flags.getBitMask()); - Builder.CreateCall2(F, V, N); + llvm::Value *args[] = { + Builder.CreateBitCast(V, Int8PtrTy), + llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) + }; + EmitNounwindRuntimeCall(F, args); // FIXME: throwing destructors? } namespace { diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 9e09131a53..f55a8e5253 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -160,7 +160,7 @@ static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { false); llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName); - return CGF.Builder.CreateCall(Fn, V, "abs"); + return CGF.EmitNounwindRuntimeCall(Fn, V, "abs"); } static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn, @@ -1635,7 +1635,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); StringRef Name = FD->getName(); - return Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); + return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); } if (BuiltinID == ARM::BI__builtin_arm_ldrexd) { diff --git a/lib/CodeGen/CGCUDANV.cpp b/lib/CodeGen/CGCUDANV.cpp index ed70c7cfb2..0ebf1aaa44 100644 --- a/lib/CodeGen/CGCUDANV.cpp +++ b/lib/CodeGen/CGCUDANV.cpp @@ -104,7 +104,7 @@ void CGNVCUDARuntime::EmitDeviceStubBody(CodeGenFunction &CGF, Args[2] = CGF.Builder.CreateIntCast( llvm::ConstantExpr::getOffsetOf(ArgStackTy, I), SizeTy, false); - llvm::CallSite CS = CGF.EmitCallOrInvoke(cudaSetupArgFn, Args); + llvm::CallSite CS = CGF.EmitRuntimeCallOrInvoke(cudaSetupArgFn, Args); llvm::Constant *Zero = llvm::ConstantInt::get(IntTy, 0); llvm::Value *CSZero = CGF.Builder.CreateICmpEQ(CS.getInstruction(), Zero); CGF.Builder.CreateCondBr(CSZero, NextBlock, EndBlock); @@ -114,7 +114,7 @@ void CGNVCUDARuntime::EmitDeviceStubBody(CodeGenFunction &CGF, // Emit the call to cudaLaunch llvm::Constant *cudaLaunchFn = getLaunchFn(); llvm::Value *Arg = CGF.Builder.CreatePointerCast(CGF.CurFn, CharPtrTy); - CGF.EmitCallOrInvoke(cudaLaunchFn, Arg); + CGF.EmitRuntimeCallOrInvoke(cudaLaunchFn, Arg); CGF.EmitBranch(EndBlock); CGF.EmitBlock(EndBlock); diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 3bcf7d0f50..9f8aa39bc0 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1894,6 +1894,85 @@ CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) { CGM.getNoObjCARCExceptionsMetadata()); } +/// Emits a call to the given no-arguments nounwind runtime function. +llvm::CallInst * +CodeGenFunction::EmitNounwindRuntimeCall(llvm::Value *callee, + const llvm::Twine &name) { + return EmitNounwindRuntimeCall(callee, ArrayRef<llvm::Value*>(), name); +} + +/// Emits a call to the given nounwind runtime function. +llvm::CallInst * +CodeGenFunction::EmitNounwindRuntimeCall(llvm::Value *callee, + ArrayRef<llvm::Value*> args, + const llvm::Twine &name) { + llvm::CallInst *call = EmitRuntimeCall(callee, args, name); + call->setDoesNotThrow(); + return call; +} + +/// Emits a simple call (never an invoke) to the given no-arguments +/// runtime function. +llvm::CallInst * +CodeGenFunction::EmitRuntimeCall(llvm::Value *callee, + const llvm::Twine &name) { + return EmitRuntimeCall(callee, ArrayRef<llvm::Value*>(), name); +} + +/// Emits a simple call (never an invoke) to the given runtime +/// function. +llvm::CallInst * +CodeGenFunction::EmitRuntimeCall(llvm::Value *callee, + ArrayRef<llvm::Value*> args, + const llvm::Twine &name) { + llvm::CallInst *call = Builder.CreateCall(callee, args, name); + call->setCallingConv(getRuntimeCC()); + return call; +} + +/// Emits a call or invoke to the given noreturn runtime function. +void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, + ArrayRef<llvm::Value*> args) { + if (getInvokeDest()) { + llvm::InvokeInst *invoke = + Builder.CreateInvoke(callee, + getUnreachableBlock(), + getInvokeDest(), + args); + invoke->setDoesNotReturn(); + invoke->setCallingConv(getRuntimeCC()); + } else { + llvm::CallInst *call = Builder.CreateCall(callee, args); + call->setDoesNotReturn(); + call->setCallingConv(getRuntimeCC()); + Builder.CreateUnreachable(); + } +} + +/// Emits a call or invoke instruction to the given nullary runtime +/// function. +llvm::CallSite +CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::Value *callee, + const Twine &name) { + return EmitRuntimeCallOrInvoke(callee, ArrayRef<llvm::Value*>(), name); +} + +/// Emits a call or invoke instruction to the given runtime function. +llvm::CallSite +CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::Value *callee, + ArrayRef<llvm::Value*> args, + const Twine &name) { + llvm::CallSite callSite = EmitCallOrInvoke(callee, args, name); + callSite.setCallingConv(getRuntimeCC()); + return callSite; +} + +llvm::CallSite +CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee, + const Twine &Name) { + return EmitCallOrInvoke(Callee, ArrayRef<llvm::Value *>(), Name); +} + /// Emits a call or invoke instruction to the given function, depending /// on the current state of the EH stack. llvm::CallSite @@ -1919,12 +1998,6 @@ CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee, return Inst; } -llvm::CallSite -CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee, - const Twine &Name) { - return EmitCallOrInvoke(Callee, ArrayRef<llvm::Value *>(), Name); -} - static void checkArgMatches(llvm::Value *Elt, unsigned &ArgNo, llvm::FunctionType *FTy) { if (ArgNo < FTy->getNumParams()) diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index a5884e35db..9b6c5d7077 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -198,7 +198,7 @@ void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtor, if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit)) atexitFn->setDoesNotThrow(); - Builder.CreateCall(atexit, dtorStub)->setDoesNotThrow(); + EmitNounwindRuntimeCall(atexit, dtorStub); } void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, @@ -229,6 +229,8 @@ CreateGlobalInitOrDestructFunction(CodeGenModule &CGM, Fn->setSection(Section); } + Fn->setCallingConv(CGM.getRuntimeCC()); + if (!CGM.getLangOpts().Exceptions) Fn->setDoesNotThrow(); @@ -392,7 +394,7 @@ void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, for (unsigned i = 0; i != NumDecls; ++i) if (Decls[i]) - Builder.CreateCall(Decls[i]); + EmitRuntimeCall(Decls[i]); Scope.ForceCleanup(); diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 8dced6327b..9794ca4731 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -364,8 +364,7 @@ namespace { llvm::Value *exn; FreeException(llvm::Value *exn) : exn(exn) {} void Emit(CodeGenFunction &CGF, Flags flags) { - CGF.Builder.CreateCall(getFreeExceptionFn(CGF.CGM), exn) - ->setDoesNotThrow(); + CGF.EmitNounwindRuntimeCall(getFreeExceptionFn(CGF.CGM), exn); } }; } @@ -422,15 +421,8 @@ llvm::Value *CodeGenFunction::getSelectorFromSlot() { void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) { if (!E->getSubExpr()) { - if (getInvokeDest()) { - Builder.CreateInvoke(getReThrowFn(CGM), - getUnreachableBlock(), - getInvokeDest()) - ->setDoesNotReturn(); - } else { - Builder.CreateCall(getReThrowFn(CGM))->setDoesNotReturn(); - Builder.CreateUnreachable(); - } + EmitNoreturnRuntimeCallOrInvoke(getReThrowFn(CGM), + ArrayRef<llvm::Value*>()); // throw is an expression, and the expression emitters expect us // to leave ourselves at a valid insertion point. @@ -458,10 +450,9 @@ void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) { llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(CGM); llvm::CallInst *ExceptionPtr = - Builder.CreateCall(AllocExceptionFn, - llvm::ConstantInt::get(SizeTy, TypeSize), - "exception"); - ExceptionPtr->setDoesNotThrow(); + EmitNounwindRuntimeCall(AllocExceptionFn, + llvm::ConstantInt::get(SizeTy, TypeSize), + "exception"); EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr); @@ -482,18 +473,8 @@ void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) { } if (!Dtor) Dtor = llvm::Constant::getNullValue(Int8PtrTy); - if (getInvokeDest()) { - llvm::InvokeInst *ThrowCall = - Builder.CreateInvoke3(getThrowFn(CGM), - getUnreachableBlock(), getInvokeDest(), - ExceptionPtr, TypeInfo, Dtor); - ThrowCall->setDoesNotReturn(); - } else { - llvm::CallInst *ThrowCall = - Builder.CreateCall3(getThrowFn(CGM), ExceptionPtr, TypeInfo, Dtor); - ThrowCall->setDoesNotReturn(); - Builder.CreateUnreachable(); - } + llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor }; + EmitNoreturnRuntimeCallOrInvoke(getThrowFn(CGM), args); // throw is an expression, and the expression emitters expect us // to leave ourselves at a valid insertion point. @@ -563,7 +544,7 @@ static void emitFilterDispatchBlock(CodeGenFunction &CGF, // according to the last landing pad the exception was thrown // into. Seriously. llvm::Value *exn = CGF.getExceptionFromSlot(); - CGF.Builder.CreateCall(getUnexpectedFn(CGF.CGM), exn) + CGF.EmitRuntimeCall(getUnexpectedFn(CGF.CGM), exn) ->setDoesNotReturn(); CGF.Builder.CreateUnreachable(); } @@ -925,11 +906,11 @@ namespace { void Emit(CodeGenFunction &CGF, Flags flags) { if (!MightThrow) { - CGF.Builder.CreateCall(getEndCatchFn(CGF.CGM))->setDoesNotThrow(); + CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM)); return; } - CGF.EmitCallOrInvoke(getEndCatchFn(CGF.CGM)); + CGF.EmitRuntimeCallOrInvoke(getEndCatchFn(CGF.CGM)); } }; } @@ -941,12 +922,12 @@ namespace { static llvm::Value *CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow) { - llvm::CallInst *Call = CGF.Builder.CreateCall(getBeginCatchFn(CGF.CGM), Exn); - Call->setDoesNotThrow(); + llvm::CallInst *call = + CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn); CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow); - return Call; + return call; } /// A "special initializer" callback for initializing a catch @@ -1086,8 +1067,7 @@ static void InitCatchParam(CodeGenFunction &CGF, // We have to call __cxa_get_exception_ptr to get the adjusted // pointer before copying. llvm::CallInst *rawAdjustedExn = - CGF.Builder.CreateCall(getGetExceptionPtrFn(CGF.CGM), Exn); - rawAdjustedExn->setDoesNotThrow(); + CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn); // Cast that to the appropriate type. llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy); @@ -1310,7 +1290,7 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { // constructor function-try-block's catch handler (p14), so this // really only applies to destructors. if (doImplicitRethrow && HaveInsertPoint()) { - EmitCallOrInvoke(getReThrowFn(CGM)); + EmitRuntimeCallOrInvoke(getReThrowFn(CGM)); Builder.CreateUnreachable(); Builder.ClearInsertionPoint(); } @@ -1342,7 +1322,7 @@ namespace { CGF.Builder.CreateLoad(ForEHVar, "finally.endcatch"); CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB); CGF.EmitBlock(EndCatchBB); - CGF.EmitCallOrInvoke(EndCatchFn); // catch-all, so might throw + CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw CGF.EmitBlock(CleanupContBB); } }; @@ -1387,9 +1367,10 @@ namespace { CGF.EmitBlock(RethrowBB); if (SavedExnVar) { - CGF.EmitCallOrInvoke(RethrowFn, CGF.Builder.CreateLoad(SavedExnVar)); + CGF.EmitRuntimeCallOrInvoke(RethrowFn, + CGF.Builder.CreateLoad(SavedExnVar)); } else { - CGF.EmitCallOrInvoke(RethrowFn); + CGF.EmitRuntimeCallOrInvoke(RethrowFn); } CGF.Builder.CreateUnreachable(); @@ -1494,7 +1475,7 @@ void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) { // If there's a begin-catch function, call it. if (BeginCatchFn) { exn = CGF.getExceptionFromSlot(); - CGF.Builder.CreateCall(BeginCatchFn, exn)->setDoesNotThrow(); + CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn); } // If we need to remember the exception pointer to rethrow later, do so. @@ -1561,12 +1542,15 @@ static llvm::Constant *getClangCallTerminateFn(CodeGenModule &CGM) { llvm::Value *exn = &*fn->arg_begin(); // Call __cxa_begin_catch(exn). - builder.CreateCall(getBeginCatchFn(CGM), exn)->setDoesNotThrow(); + llvm::CallInst *catchCall = builder.CreateCall(getBeginCatchFn(CGM), exn); + catchCall->setDoesNotThrow(); + catchCall->setCallingConv(CGM.getRuntimeCC()); // Call std::terminate(). llvm::CallInst *termCall = builder.CreateCall(getTerminateFn(CGM)); termCall->setDoesNotThrow(); termCall->setDoesNotReturn(); + termCall->setCallingConv(CGM.getRuntimeCC()); // std::terminate cannot return. builder.CreateUnreachable(); @@ -1596,12 +1580,11 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() { if (useClangCallTerminate(CGM)) { // Extract out the exception pointer. llvm::Value *exn = Builder.CreateExtractValue(LPadInst, 0); - terminateCall = Builder.CreateCall(getClangCallTerminateFn(CGM), exn); + terminateCall = EmitNounwindRuntimeCall(getClangCallTerminateFn(CGM), exn); } else { - terminateCall = Builder.CreateCall(getTerminateFn(CGM)); + terminateCall = EmitNounwindRuntimeCall(getTerminateFn(CGM)); } terminateCall->setDoesNotReturn(); - terminateCall->setDoesNotThrow(); Builder.CreateUnreachable(); // Restore the saved insertion state. @@ -1620,9 +1603,8 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() { // end of the function by FinishFunction. TerminateHandler = createBasicBlock("terminate.handler"); Builder.SetInsertPoint(TerminateHandler); - llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(CGM)); + llvm::CallInst *TerminateCall = EmitNounwindRuntimeCall(getTerminateFn(CGM)); TerminateCall->setDoesNotReturn(); - TerminateCall->setDoesNotThrow(); Builder.CreateUnreachable(); // Restore the saved insertion state. @@ -1646,8 +1628,8 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) { // anything on the EH stack which needs our help. const char *RethrowName = Personality.CatchallRethrowFn; if (RethrowName != 0 && !isCleanup) { - Builder.CreateCall(getCatchallRethrowFn(CGM, RethrowName), - getExceptionFromSlot()) + EmitRuntimeCall(getCatchallRethrowFn(CGM, RethrowName), + getExceptionFromSlot()) ->setDoesNotReturn(); } else { switch (CleanupHackLevel) { @@ -1655,8 +1637,8 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) { // In mandatory-catchall mode, we need to use // _Unwind_Resume_or_Rethrow, or whatever the personality's // equivalent is. - Builder.CreateCall(getUnwindResumeOrRethrowFn(), - getExceptionFromSlot()) + EmitRuntimeCall(getUnwindResumeOrRethrowFn(), + getExceptionFromSlot()) ->setDoesNotReturn(); break; case CHL_MandatoryCleanup: { @@ -1680,7 +1662,7 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) { // In an idealized mode where we don't have to worry about the // optimizer combining landing pads, we should just use // _Unwind_Resume (or the personality's equivalent). - Builder.CreateCall(getUnwindResumeFn(), getExceptionFromSlot()) + EmitRuntimeCall(getUnwindResumeFn(), getExceptionFromSlot()) ->setDoesNotReturn(); break; } diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 85662069ea..9b3638a6e2 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2155,12 +2155,11 @@ void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName, llvm::AttributeSet::get(getLLVMContext(), llvm::AttributeSet::FunctionIndex, B)); - llvm::CallInst *HandlerCall = Builder.CreateCall(Fn, Args); + llvm::CallInst *HandlerCall = EmitNounwindRuntimeCall(Fn, Args); if (Recover) { Builder.CreateBr(Cont); } else { HandlerCall->setDoesNotReturn(); - HandlerCall->setDoesNotThrow(); Builder.CreateUnreachable(); } @@ -3021,7 +3020,7 @@ LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) { LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) { llvm::Value *V = - CGM.getObjCRuntime().GetSelector(Builder, E->getSelector(), true); + CGM.getObjCRuntime().GetSelector(*this, E->getSelector(), true); return MakeAddrLValue(V, E->getType()); } diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index e09e06c8e2..7ad497b886 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -1617,7 +1617,7 @@ static llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) { static void EmitBadTypeidCall(CodeGenFunction &CGF) { llvm::Value *Fn = getBadTypeidFn(CGF); - CGF.EmitCallOrInvoke(Fn).setDoesNotReturn(); + CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn(); CGF.Builder.CreateUnreachable(); } @@ -1710,7 +1710,7 @@ static llvm::Constant *getBadCastFn(CodeGenFunction &CGF) { static void EmitBadCastCall(CodeGenFunction &CGF) { llvm::Value *Fn = getBadCastFn(CGF); - CGF.EmitCallOrInvoke(Fn).setDoesNotReturn(); + CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn(); CGF.Builder.CreateUnreachable(); } @@ -1825,8 +1825,9 @@ EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value, // Emit the call to __dynamic_cast. Value = CGF.EmitCastToVoidPtr(Value); - Value = CGF.Builder.CreateCall4(getDynamicCastFn(CGF), Value, - SrcRTTI, DestRTTI, OffsetHint); + + llvm::Value *args[] = { Value, SrcRTTI, DestRTTI, OffsetHint }; + Value = CGF.EmitNounwindRuntimeCall(getDynamicCastFn(CGF), args); Value = CGF.Builder.CreateBitCast(Value, DestLTy); /// C++ [expr.dynamic.cast]p9: diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 3ec4040a64..1bfd4146de 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -2091,9 +2091,14 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { // Call the handler with the two arguments, the operation, and the size of // the result. - llvm::Value *handlerResult = Builder.CreateCall4(handler, lhs, rhs, - Builder.getInt8(OpID), - Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())); + llvm::Value *handlerArgs[] = { + lhs, + rhs, + Builder.getInt8(OpID), + Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth()) + }; + llvm::Value *handlerResult = + CGF.EmitNounwindRuntimeCall(handler, handlerArgs); // Truncate the result back to the desired size. handlerResult = Builder.CreateTrunc(handlerResult, opTy); diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index b2f5aa3ef1..540baa13b7 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -70,7 +70,7 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { // messaged (avoids pulling it out of the result type). CGObjCRuntime &Runtime = CGM.getObjCRuntime(); const ObjCInterfaceDecl *ClassDecl = BoxingMethod->getClassInterface(); - llvm::Value *Receiver = Runtime.GetClass(Builder, ClassDecl); + llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl); const ParmVarDecl *argDecl = *BoxingMethod->param_begin(); QualType ArgQT = argDecl->getType().getUnqualifiedType(); @@ -163,7 +163,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, ObjCInterfaceDecl *Class = InterfacePointerType->getObjectType()->getInterface(); CGObjCRuntime &Runtime = CGM.getObjCRuntime(); - llvm::Value *Receiver = Runtime.GetClass(Builder, Class); + llvm::Value *Receiver = Runtime.GetClass(*this, Class); // Generate the message send. RValue result @@ -191,12 +191,12 @@ llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) { // Note that this implementation allows for non-constant strings to be passed // as arguments to @selector(). Currently, the only thing preventing this // behaviour is the type checking in the front end. - return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector()); + return CGM.getObjCRuntime().GetSelector(*this, E->getSelector()); } llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { // FIXME: This should pass the Decl not the name. - return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol()); + return CGM.getObjCRuntime().GenerateProtocolRef(*this, E->getProtocol()); } /// \brief Adjust the type of the result of an Objective-C message send @@ -310,7 +310,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E, assert(ObjTy && "Invalid Objective-C class message send"); OID = ObjTy->getInterface(); assert(OID && "Invalid Objective-C class message send"); - Receiver = Runtime.GetClass(Builder, OID); + Receiver = Runtime.GetClass(*this, OID); isClassMessage = true; break; } @@ -1743,8 +1743,7 @@ static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF, value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy); // Call the function. - llvm::CallInst *call = CGF.Builder.CreateCall(fn, value); - call->setDoesNotThrow(); + llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value); if (isTailCall) call->setTailCall(); @@ -1770,11 +1769,9 @@ static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy); // Call the function. - llvm::CallInst *call = CGF.Builder.CreateCall(fn, addr); - call->setDoesNotThrow(); + llvm::Value *result = CGF.EmitNounwindRuntimeCall(fn, addr); // Cast the result back to a dereference of the original type. - llvm::Value *result = call; if (origType != CGF.Int8PtrPtrTy) result = CGF.Builder.CreateBitCast(result, cast<llvm::PointerType>(origType)->getElementType()); @@ -1803,11 +1800,11 @@ static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, llvm::Type *origType = value->getType(); - addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy); - value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy); - - llvm::CallInst *result = CGF.Builder.CreateCall2(fn, addr, value); - result->setDoesNotThrow(); + llvm::Value *args[] = { + CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy), + CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy) + }; + llvm::CallInst *result = CGF.EmitNounwindRuntimeCall(fn, args); if (ignored) return 0; @@ -1830,11 +1827,11 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName); } - dst = CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy); - src = CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy); - - llvm::CallInst *result = CGF.Builder.CreateCall2(fn, dst, src); - result->setDoesNotThrow(); + llvm::Value *args[] = { + CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy), + CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy) + }; + CGF.EmitNounwindRuntimeCall(fn, args); } /// Produce the code to do a retain. Based on the type, calls one of: @@ -1952,8 +1949,7 @@ void CodeGenFunction::EmitARCRelease(llvm::Value *value, bool precise) { value = Builder.CreateBitCast(value, Int8PtrTy); // Call objc_release. - llvm::CallInst *call = Builder.CreateCall(fn, value); - call->setDoesNotThrow(); + llvm::CallInst *call = EmitNounwindRuntimeCall(fn, value); if (!precise) { SmallVector<llvm::Value*,1> args; @@ -2000,10 +1996,11 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr, fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong"); } - addr = Builder.CreateBitCast(addr, Int8PtrPtrTy); - llvm::Value *castValue = Builder.CreateBitCast(value, Int8PtrTy); - - Builder.CreateCall2(fn, addr, castValue)->setDoesNotThrow(); + llvm::Value *args[] = { + Builder.CreateBitCast(addr, Int8PtrPtrTy), + Builder.CreateBitCast(value, Int8PtrTy) + }; + EmitNounwindRuntimeCall(fn, args); if (ignored) return 0; return value; @@ -2160,8 +2157,7 @@ void CodeGenFunction::EmitARCDestroyWeak(llvm::Value *addr) { // Cast the argument to 'id*'. addr = Builder.CreateBitCast(addr, Int8PtrPtrTy); - llvm::CallInst *call = Builder.CreateCall(fn, addr); - call->setDoesNotThrow(); + EmitNounwindRuntimeCall(fn, addr); } /// void \@objc_moveWeak(i8** %dest, i8** %src) @@ -2192,10 +2188,7 @@ llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush"); } - llvm::CallInst *call = Builder.CreateCall(fn); - call->setDoesNotThrow(); - - return call; + return EmitNounwindRuntimeCall(fn); } /// Produce the code to do a primitive release. @@ -2214,8 +2207,7 @@ void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) { fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop"); } - llvm::CallInst *call = Builder.CreateCall(fn, value); - call->setDoesNotThrow(); + EmitNounwindRuntimeCall(fn, value); } /// Produce the code to do an MRR version objc_autoreleasepool_push. @@ -2225,7 +2217,7 @@ void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) { /// llvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() { CGObjCRuntime &Runtime = CGM.getObjCRuntime(); - llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(Builder); + llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(*this); // [NSAutoreleasePool alloc] IdentifierInfo *II = &CGM.getContext().Idents.get("alloc"); Selector AllocSel = getContext().Selectors.getSelector(0, &II); @@ -2800,7 +2792,7 @@ void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) { /* side effects */ true); object = Builder.CreateBitCast(object, VoidPtrTy); - Builder.CreateCall(extender, object)->setDoesNotThrow(); + EmitNounwindRuntimeCall(extender, object); } /// GenerateObjCAtomicSetterCopyHelperFunction - Given a c++ object type with diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 1b575d98d6..fbf8a1abb0 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -273,7 +273,7 @@ protected: /// Ensures that the value has the required type, by inserting a bitcast if |