Use the actual ABI-determined C calling convention for runtime

calls and declarations.

LLVM has a default CC determined by the target triple.  This is
not always the actual default CC for the ABI we've been asked to
target, and so we sometimes find ourselves annotating all user
functions with an explicit calling convention.  Since these
calling conventions usually agree for the simple set of argument
types passed to most runtime functions, using the LLVM-default CC
in principle has no effect.  However, the LLVM optimizer goes
into histrionics if it sees this kind of formal CC mismatch,
since it has no concept of CC compatibility.  Therefore, if this
module happens to define the "runtime" function, or got LTO'ed
with such a definition, we can miscompile;  so it's quite
important to get this right.

Defining runtime functions locally is quite common in embedded
applications.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176286 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2013-02-28 19:01:20 +00:00
Родитель 280b956c8e
Коммит bd7370a786
23 изменённых файлов: 528 добавлений и 341 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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);

Просмотреть файл

@ -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())

Просмотреть файл

@ -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();

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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());
}

Просмотреть файл

@ -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:

Просмотреть файл

@ -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);

Просмотреть файл

@ -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

Просмотреть файл

@ -273,7 +273,7 @@ protected:
/// Ensures that the value has the required type, by inserting a bitcast if
/// required. This function lets us avoid inserting bitcasts that are
/// redundant.
llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, llvm::Type *Ty){
llvm::Value* EnforceType(CGBuilderTy &B, llvm::Value *V, llvm::Type *Ty) {
if (V->getType() == Ty) return V;
return B.CreateBitCast(V, Ty);
}
@ -436,7 +436,7 @@ private:
ArrayRef<llvm::Constant *> MethodTypes);
/// Returns a selector with the specified type encoding. An empty string is
/// used to return an untyped selector (with the types field set to NULL).
llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
const std::string &TypeEncoding, bool lval);
/// Returns the variable used to store the offset of an instance variable.
llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
@ -446,7 +446,7 @@ private:
protected:
void EmitClassRef(const std::string &className);
/// Emits a pointer to the named class
virtual llvm::Value *GetClassNamed(CGBuilderTy &Builder,
virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF,
const std::string &Name, bool isWeak);
/// Looks up the method for sending a message to the specified object. This
/// mechanism differs between the GCC and GNU runtimes, so this method must be
@ -499,11 +499,11 @@ public:
bool IsClassMessage,
const CallArgList &CallArgs,
const ObjCMethodDecl *Method);
virtual llvm::Value *GetClass(CGBuilderTy &Builder,
virtual llvm::Value *GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *OID);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
bool lval = false);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
virtual llvm::Value *GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
*Method);
virtual llvm::Constant *GetEHType(QualType T);
@ -512,7 +512,7 @@ public:
virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD);
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD);
virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
virtual llvm::Function *ModuleInitFunction();
@ -557,7 +557,7 @@ public:
virtual llvm::Value *EmitIvarOffset(CodeGenFunction &CGF,
const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar);
virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF);
virtual llvm::Constant *BuildGCBlockLayout(CodeGenModule &CGM,
const CGBlockInfo &blockInfo) {
return NULLPtr;
@ -601,7 +601,7 @@ protected:
llvm::Value *args[] = {
EnforceType(Builder, Receiver, IdTy),
EnforceType(Builder, cmd, SelectorTy) };
llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args);
llvm::CallSite imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args);
imp->setMetadata(msgSendMDKind, node);
return imp.getInstruction();
}
@ -611,7 +611,7 @@ protected:
CGBuilderTy &Builder = CGF.Builder;
llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
PtrToObjCSuperTy), cmd};
return Builder.CreateCall(MsgLookupSuperFn, lookupArgs);
return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs);
}
public:
CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) {
@ -678,7 +678,7 @@ class CGObjCGNUstep : public CGObjCGNU {
EnforceType(Builder, ReceiverPtr, PtrToIdTy),
EnforceType(Builder, cmd, SelectorTy),
EnforceType(Builder, self, IdTy) };
llvm::CallSite slot = CGF.EmitCallOrInvoke(LookupFn, args);
llvm::CallSite slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args);
slot.setOnlyReadsMemory();
slot->setMetadata(msgSendMDKind, node);
@ -697,7 +697,8 @@ class CGObjCGNUstep : public CGObjCGNU {
CGBuilderTy &Builder = CGF.Builder;
llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
llvm::CallInst *slot = Builder.CreateCall(SlotLookupSuperFn, lookupArgs);
llvm::CallInst *slot =
CGF.EmitNounwindRuntimeCall(SlotLookupSuperFn, lookupArgs);
slot->setOnlyReadsMemory();
return Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
@ -809,7 +810,7 @@ protected:
llvm::Value *args[] = {
EnforceType(Builder, Receiver, IdTy),
EnforceType(Builder, cmd, SelectorTy) };
llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args);
llvm::CallSite imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args);
imp->setMetadata(msgSendMDKind, node);
return imp.getInstruction();
}
@ -820,13 +821,13 @@ protected:
CGBuilderTy &Builder = CGF.Builder;
llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
PtrToObjCSuperTy), cmd};
return Builder.CreateCall(MsgLookupSuperFn, lookupArgs);
return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs);
}
virtual llvm::Value *GetClassNamed(CGBuilderTy &Builder,
virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF,
const std::string &Name, bool isWeak) {
if (isWeak)
return CGObjCGNU::GetClassNamed(Builder, Name, isWeak);
return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
EmitClassRef(Name);
@ -1006,7 +1007,7 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
}
}
llvm::Value *CGObjCGNU::GetClassNamed(CGBuilderTy &Builder,
llvm::Value *CGObjCGNU::GetClassNamed(CodeGenFunction &CGF,
const std::string &Name,
bool isWeak) {
llvm::Value *ClassName = CGM.GetAddrOfConstantCString(Name);
@ -1019,25 +1020,25 @@ llvm::Value *CGObjCGNU::GetClassNamed(CGBuilderTy &Builder,
// with memoized versions or with static references if it's safe to do so.
if (!isWeak)
EmitClassRef(Name);
ClassName = Builder.CreateStructGEP(ClassName, 0);
ClassName = CGF.Builder.CreateStructGEP(ClassName, 0);
llvm::Constant *ClassLookupFn =
CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty, true),
"objc_lookup_class");
return Builder.CreateCall(ClassLookupFn, ClassName);
return CGF.EmitNounwindRuntimeCall(ClassLookupFn, ClassName);
}
// This has to perform the lookup every time, since posing and related
// techniques can modify the name -> class mapping.
llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder,
llvm::Value *CGObjCGNU::GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *OID) {
return GetClassNamed(Builder, OID->getNameAsString(), OID->isWeakImported());
return GetClassNamed(CGF, OID->getNameAsString(), OID->isWeakImported());
}
llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
return GetClassNamed(Builder, "NSAutoreleasePool", false);
llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
return GetClassNamed(CGF, "NSAutoreleasePool", false);
}
llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel,
llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel,
const std::string &TypeEncoding, bool lval) {
SmallVector<TypedSelector, 2> &Types = SelectorTable[Sel];
@ -1060,23 +1061,23 @@ llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel,
}
if (lval) {
llvm::Value *tmp = Builder.CreateAlloca(SelValue->getType());
Builder.CreateStore(SelValue, tmp);
llvm::Value *tmp = CGF.CreateTempAlloca(SelValue->getType());
CGF.Builder.CreateStore(SelValue, tmp);
return tmp;
}
return SelValue;
}
llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel,
llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel,
bool lval) {
return GetSelector(Builder, Sel, std::string(), lval);
return GetSelector(CGF, Sel, std::string(), lval);
}
llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
*Method) {
llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF,
const ObjCMethodDecl *Method) {
std::string SelTypes;
CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
return GetSelector(Builder, Method->getSelector(), SelTypes, false);
return GetSelector(CGF, Method->getSelector(), SelTypes, false);
}
llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
@ -1226,7 +1227,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
}
}
llvm::Value *cmd = GetSelector(Builder, Sel);
llvm::Value *cmd = GetSelector(CGF, Sel);
CallArgList ActualArgs;
@ -1361,9 +1362,9 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
llvm::Value *cmd;
if (Method)
cmd = GetSelector(Builder, Method);
cmd = GetSelector(CGF, Method);
else
cmd = GetSelector(Builder, Sel);
cmd = GetSelector(CGF, Sel);
cmd = EnforceType(Builder, cmd, SelectorTy);
Receiver = EnforceType(Builder, Receiver, IdTy);
@ -1706,12 +1707,12 @@ llvm::Constant *CGObjCGNU::GenerateProtocolList(ArrayRef<std::string>Protocols){
return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list");
}
llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder,
llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD) {
llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()];
llvm::Type *T =
CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
}
llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
@ -2687,7 +2688,7 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
}
ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
llvm::CallSite Throw =
CGF.EmitCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
Throw.setDoesNotReturn();
CGF.Builder.CreateUnreachable();
if (ClearInsertionPoint)
@ -2696,14 +2697,14 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF,
llvm::Value *AddrWeakObj) {
CGBuilderTy B = CGF.Builder;
CGBuilderTy &B = CGF.Builder;
AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
return B.CreateCall(WeakReadFn, AddrWeakObj);
}
void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dst) {
CGBuilderTy B = CGF.Builder;
CGBuilderTy &B = CGF.Builder;
src = EnforceType(B, src, IdTy);
dst = EnforceType(B, dst, PtrToIdTy);
B.CreateCall2(WeakAssignFn, src, dst);
@ -2712,7 +2713,7 @@ void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF,
void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dst,
bool threadlocal) {
CGBuilderTy B = CGF.Builder;
CGBuilderTy &B = CGF.Builder;
src = EnforceType(B, src, IdTy);
dst = EnforceType(B, dst, PtrToIdTy);
if (!threadlocal)
@ -2725,7 +2726,7 @@ void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF,
void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dst,
llvm::Value *ivarOffset) {
CGBuilderTy B = CGF.Builder;
CGBuilderTy &B = CGF.Builder;
src = EnforceType(B, src, IdTy);
dst = EnforceType(B, dst, IdTy);
B.CreateCall3(IvarAssignFn, src, dst, ivarOffset);
@ -2733,7 +2734,7 @@ void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF,
void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dst) {
CGBuilderTy B = CGF.Builder;
CGBuilderTy &B = CGF.Builder;
src = EnforceType(B, src, IdTy);
dst = EnforceType(B, dst, PtrToIdTy);
B.CreateCall2(StrongCastAssignFn, src, dst);
@ -2743,7 +2744,7 @@ void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF,
llvm::Value *DestPtr,
llvm::Value *SrcPtr,
llvm::Value *Size) {
CGBuilderTy B = CGF.Builder;
CGBuilderTy &B = CGF.Builder;
DestPtr = EnforceType(B, DestPtr, PtrTy);
SrcPtr = EnforceType(B, SrcPtr, PtrTy);

Просмотреть файл

@ -1086,13 +1086,13 @@ private:
/// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
/// for the given class.
llvm::Value *EmitClassRef(CGBuilderTy &Builder,
llvm::Value *EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
IdentifierInfo *II);
llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF);
/// EmitSuperClassRef - Emits reference to class's main metadata class.
llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
@ -1170,7 +1170,7 @@ private:
/// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
/// for the given selector.
llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,
bool lval=false);
public:
@ -1199,15 +1199,15 @@ public:
const CallArgList &CallArgs,
const ObjCMethodDecl *Method);
virtual llvm::Value *GetClass(CGBuilderTy &Builder,
virtual llvm::Value *GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
bool lval = false);
/// The NeXT/Apple runtimes do not support typed selectors; just emit an
/// untyped one.
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
const ObjCMethodDecl *Method);
virtual llvm::Constant *GetEHType(QualType T);
@ -1218,7 +1218,7 @@ public:
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD);
virtual llvm::Constant *GetPropertyGetFunction();
@ -1370,22 +1370,22 @@ private:
/// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
/// for the given class reference.
llvm::Value *EmitClassRef(CGBuilderTy &Builder,
llvm::Value *EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
llvm::Value *EmitClassRefFromId(CGBuilderTy &Builder,
llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
IdentifierInfo *II);
llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder);
llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF);
/// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
/// for the given super class reference.
llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder,
llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
/// EmitMetaClassRef - Return a Value * of the address of _class_t
/// meta-data
llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
@ -1397,7 +1397,7 @@ private:
/// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
/// for the given selector.
llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel,
llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,
bool lval=false);
/// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
@ -1477,18 +1477,18 @@ public:
const CallArgList &CallArgs,
const ObjCMethodDecl *Method);
virtual llvm::Value *GetClass(CGBuilderTy &Builder,
virtual llvm::Value *GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel,
virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
bool lvalue = false)
{ return EmitSelector(Builder, Sel, lvalue); }
{ return EmitSelector(CGF, Sel, lvalue); }
/// The NeXT/Apple runtimes do not support typed selectors; just emit an
/// untyped one.
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
const ObjCMethodDecl *Method)
{ return EmitSelector(Builder, Method->getSelector()); }
{ return EmitSelector(CGF, Method->getSelector()); }
virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
@ -1496,7 +1496,7 @@ public:
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD);
virtual llvm::Constant *GetEHType(QualType T);
@ -1715,19 +1715,19 @@ CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
/// GetClass - Return a reference to the class for the given interface
/// decl.
llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder,
llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID) {
return EmitClassRef(Builder, ID);
return EmitClassRef(CGF, ID);
}
/// GetSelector - Return the pointer to the unique'd string for this selector.
llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel,
llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel,
bool lval) {
return EmitSelector(Builder, Sel, lval);
return EmitSelector(CGF, Sel, lval);
}
llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
*Method) {
return EmitSelector(Builder, Method->getSelector());
return EmitSelector(CGF, Method->getSelector());
}
llvm::Constant *CGObjCMac::GetEHType(QualType T) {
@ -1810,7 +1810,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
// _metaclass_ for the current class, pointed at by
// the class's "isa" pointer. The following assumes that
// isa" is the first ivar in a class (which it must be).
Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
Target = EmitClassRef(CGF, Class->getSuperClass());
Target = CGF.Builder.CreateStructGEP(Target, 0);
Target = CGF.Builder.CreateLoad(Target);
} else {
@ -1821,7 +1821,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
}
}
else if (isCategoryImpl)
Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
Target = EmitClassRef(CGF, Class->getSuperClass());
else {
llvm::Value *ClassPtr = EmitSuperClassRef(Class);
ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
@ -1835,7 +1835,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
CGF.Builder.CreateStore(Target,
CGF.Builder.CreateStructGEP(ObjCSuper, 1));
return EmitMessageSend(CGF, Return, ResultType,
EmitSelector(CGF.Builder, Sel),
EmitSelector(CGF, Sel),
ObjCSuper, ObjCTypes.SuperPtrCTy,
true, CallArgs, Method, ObjCTypes);
}
@ -1850,7 +1850,7 @@ CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
const ObjCInterfaceDecl *Class,
const ObjCMethodDecl *Method) {
return EmitMessageSend(CGF, Return, ResultType,
EmitSelector(CGF.Builder, Sel),
EmitSelector(CGF, Sel),
Receiver, CGF.getContext().getObjCIdType(),
false, CallArgs, Method, ObjCTypes);
}
@ -2532,7 +2532,7 @@ llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
return nullPtr;
}
llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD) {
// FIXME: I don't understand why gcc generates this, or where it is
// resolved. Investigate. Its also wasteful to look this up over and over.
@ -3511,8 +3511,8 @@ namespace {
FinallyCallExit, FinallyNoCallExit);
CGF.EmitBlock(FinallyCallExit);
CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData)
->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),
ExceptionData);
CGF.EmitBlock(FinallyNoCallExit);
@ -3538,8 +3538,7 @@ namespace {
// Emit objc_sync_exit(expr); as finally's sole statement for
// @synchronized.
llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg)
->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);
}
}
};
@ -3616,12 +3615,14 @@ FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
void FragileHazards::emitWriteHazard() {
if (Locals.empty()) return;
CGF.Builder.CreateCall(WriteHazard, Locals)->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);
}
void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
assert(!Locals.empty());
Builder.CreateCall(ReadHazard, Locals)->setDoesNotThrow();
llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
call->setDoesNotThrow();
call->setCallingConv(CGF.getRuntimeCC());
}
/// Emit read hazards in all the protected blocks, i.e. all the blocks
@ -3826,8 +3827,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
llvm::Value *SyncArg =
CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg)
->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);
SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
@ -3869,8 +3869,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// Enter a try block:
// - Call objc_exception_try_enter to push ExceptionData on top of
// the EH stack.
CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
// - Call setjmp on the exception data buffer.
llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
@ -3878,8 +3877,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
llvm::Value *SetJmpBuffer =
CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer");
llvm::CallInst *SetJmpResult =
CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
SetJmpResult->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
SetJmpResult->setCanReturnTwice();
// If setjmp returned 0, enter the protected block; otherwise,
@ -3916,9 +3914,8 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// Retrieve the exception object. We may emit multiple blocks but
// nothing can cross this so the value is already in SSA form.
llvm::CallInst *Caught =
CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
ExceptionData, "caught");
Caught->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
ExceptionData, "caught");
// Push the exception to rethrow onto the EH value stack for the
// benefit of any @throws in the handlers.
@ -3939,13 +3936,12 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// Enter a new exception try block (in case a @catch block
// throws an exception).
CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData)
->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
ExceptionData);
llvm::CallInst *SetJmpResult =
CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp.result");
SetJmpResult->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(),
SetJmpBuffer, "setjmp.result");
SetJmpResult->setCanReturnTwice();
llvm::Value *Threw =
@ -4013,12 +4009,12 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
assert(IDecl && "Catch parameter must have Objective-C type!");
// Check if the @catch block matches the exception object.
llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl);
llvm::Value *Class = EmitClassRef(CGF, IDecl);
llvm::Value *matchArgs[] = { Class, Caught };
llvm::CallInst *Match =
CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(),
Class, Caught, "match");
Match->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionMatchFn(),
matchArgs, "match");
llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
@ -4075,9 +4071,8 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// propagating-exception slot.
assert(PropagatingExnVar);
llvm::CallInst *NewCaught =
CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
ExceptionData, "caught");
NewCaught->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
ExceptionData, "caught");
CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
// Don't pop the catch handler; the throw already did.
@ -4108,14 +4103,13 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// Otherwise, just look in the buffer for the exception to throw.
} else {
llvm::CallInst *Caught =
CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(),
ExceptionData);
Caught->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
ExceptionData);
PropagatingExn = Caught;
}
CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), PropagatingExn)
->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),
PropagatingExn);
CGF.Builder.CreateUnreachable();
}
@ -4137,7 +4131,7 @@ void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
ExceptionAsObject = CGF.ObjCEHValueStack.back();
}
CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
->setDoesNotReturn();
CGF.Builder.CreateUnreachable();
@ -4155,8 +4149,9 @@ llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
ObjCTypes.PtrObjectPtrTy);
llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
AddrWeakObj, "weakread");
llvm::Value *read_weak =
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
AddrWeakObj, "weakread");
read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
return read_weak;
}
@ -4176,8 +4171,9 @@ void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
}
src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
src, dst, "weakassign");
llvm::Value *args[] = { src, dst };
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
args, "weakassign");
return;
}
@ -4197,12 +4193,13 @@ void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
}
src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
llvm::Value *args[] = { src, dst };
if (!threadlocal)
CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
src, dst, "globalassign");
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
args, "globalassign");
else
CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
src, dst, "threadlocalassign");
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
args, "threadlocalassign");
return;
}
@ -4223,8 +4220,8 @@ void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
}
src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
src, dst, ivarOffset);
llvm::Value *args[] = { src, dst, ivarOffset };
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
return;
}
@ -4243,8 +4240,9 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
}
src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
src, dst, "weakassign");
llvm::Value *args[] = { src, dst };
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
args, "weakassign");
return;
}
@ -4254,9 +4252,8 @@ void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
llvm::Value *size) {
SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
DestPtr, SrcPtr, size);
return;
llvm::Value *args[] = { DestPtr, SrcPtr, size };
CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
}
/// EmitObjCValueForIvar - Code Gen for ivar reference.
@ -4420,8 +4417,8 @@ llvm::Constant *CGObjCMac::EmitModuleSymbols() {
return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
}
llvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder,
IdentifierInfo *II) {
llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
IdentifierInfo *II) {
LazySymbols.insert(II);
llvm::GlobalVariable *&Entry = ClassReferences[II];
@ -4436,20 +4433,20 @@ llvm::Value *CGObjCMac::EmitClassRefFromId(CGBuilderTy &Builder,
4, true);
}
return Builder.CreateLoad(Entry);
return CGF.Builder.CreateLoad(Entry);
}
llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder,
llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID) {
return EmitClassRefFromId(Builder, ID->getIdentifier());
return EmitClassRefFromId(CGF, ID->getIdentifier());
}
llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
return EmitClassRefFromId(Builder, II);
return EmitClassRefFromId(CGF, II);
}
llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel,
bool lvalue) {
llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
@ -4466,7 +4463,7 @@ llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel,
if (lvalue)
return Entry;
return Builder.CreateLoad(Entry);
return CGF.Builder.CreateLoad(Entry);
}
llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
@ -5928,7 +5925,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
/// which will hold address of the protocol meta-data.
///
llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD) {
// This routine is called for @protocol only. So, we must build definition
@ -5943,7 +5940,7 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
if (PTGV)
return Builder.CreateLoad(PTGV);
return CGF.Builder.CreateLoad(PTGV);
PTGV = new llvm::GlobalVariable(
CGM.getModule(),
Init->getType(), false,
@ -5953,7 +5950,7 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder,
PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
CGM.AddUsedGlobal(PTGV);
return Builder.CreateLoad(PTGV);
return CGF.Builder.CreateLoad(PTGV);
}
/// GenerateCategory - Build metadata for a category implementation.
@ -6635,7 +6632,7 @@ CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Receiver, CGF.getContext().getObjCIdType(),
false, CallArgs, Method)
: EmitMessageSend(CGF, Return, ResultType,
EmitSelector(CGF.Builder, Sel),
EmitSelector(CGF, Sel),
Receiver, CGF.getContext().getObjCIdType(),
false, CallArgs, Method, ObjCTypes);
}
@ -6653,7 +6650,7 @@ CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
return GV;
}
llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder,
llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
IdentifierInfo *II) {
llvm::GlobalVariable *&Entry = ClassReferences[II];
@ -6672,22 +6669,22 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder,
CGM.AddUsedGlobal(Entry);
}
return Builder.CreateLoad(Entry);
return CGF.Builder.CreateLoad(Entry);
}
llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder,
llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID) {
return EmitClassRefFromId(Builder, ID->getIdentifier());
return EmitClassRefFromId(CGF, ID->getIdentifier());
}
llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
CGBuilderTy &Builder) {
CodeGenFunction &CGF) {
IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
return EmitClassRefFromId(Builder, II);
return EmitClassRefFromId(CGF, II);
}
llvm::Value *
CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID) {
llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
@ -6706,17 +6703,17 @@ CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder,
CGM.AddUsedGlobal(Entry);
}
return Builder.CreateLoad(Entry);
return CGF.Builder.CreateLoad(Entry);
}
/// EmitMetaClassRef - Return a Value * of the address of _class_t
/// meta-data
///
llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID) {
llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
if (Entry)
return Builder.CreateLoad(Entry);
return CGF.Builder.CreateLoad(Entry);
std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
@ -6732,12 +6729,12 @@ llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder,
Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
CGM.AddUsedGlobal(Entry);
return Builder.CreateLoad(Entry);
return CGF.Builder.CreateLoad(Entry);
}
/// GetClass - Return a reference to the class for the given interface
/// decl.
llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID) {
if (ID->isWeakImported()) {
std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
@ -6745,7 +6742,7 @@ llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder,
ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
}
return EmitClassRef(Builder, ID);
return EmitClassRef(CGF, ID);
}
/// Generates a message send where the super is the receiver. This is
@ -6776,9 +6773,9 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
// If this is a class message the metaclass is passed as the target.
llvm::Value *Target;
if (IsClassMessage)
Target = EmitMetaClassRef(CGF.Builder, Class);
Target = EmitMetaClassRef(CGF, Class);
else
Target = EmitSuperClassRef(CGF.Builder, Class);
Target = EmitSuperClassRef(CGF, Class);
// FIXME: We shouldn't need to do this cast, rectify the ASTContext and
// ObjCTypes types.
@ -6793,12 +6790,12 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
ObjCSuper, ObjCTypes.SuperPtrCTy,
true, CallArgs, Method)
: EmitMessageSend(CGF, Return, ResultType,
EmitSelector(CGF.Builder, Sel),
EmitSelector(CGF, Sel),
ObjCSuper, ObjCTypes.SuperPtrCTy,
true, CallArgs, Method, ObjCTypes);
}
llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
Selector Sel, bool lval) {
llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
@ -6817,7 +6814,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder,
if (lval)
return Entry;
llvm::LoadInst* LI = Builder.CreateLoad(Entry);
llvm::LoadInst* LI = CGF.Builder.CreateLoad(Entry);
LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
llvm::MDNode::get(VMContext,
@ -6841,9 +6838,8 @@ void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
}
src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(),
src, dst, ivarOffset);
return;
llvm::Value *args[] = { src, dst, ivarOffset };
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
}
/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
@ -6862,9 +6858,9 @@ void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
}
src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(),
src, dst, "weakassign");
return;
llvm::Value *args[] = { src, dst };
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
args, "weakassign");
}
void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
@ -6874,9 +6870,8 @@ void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
llvm::Value *Size) {
SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(),
DestPtr, SrcPtr, Size);
return;
llvm::Value *args[] = { DestPtr, SrcPtr, Size };
CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
}
/// EmitObjCWeakRead - Code gen for loading value of a __weak
@ -6888,8 +6883,9 @@ llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
llvm::Type* DestTy =
cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(),
AddrWeakObj, "weakread");
llvm::Value *read_weak =
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
AddrWeakObj, "weakread");
read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
return read_weak;
}
@ -6909,9 +6905,9 @@ void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
}
src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(),
src, dst, "weakassign");
return;
llvm::Value *args[] = { src, dst };
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
args, "weakassign");
}
/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
@ -6930,13 +6926,13 @@ void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
}
src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
llvm::Value *args[] = { src, dst };
if (!threadlocal)
CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(),
src, dst, "globalassign");
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
args, "globalassign");
else
CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(),
src, dst, "threadlocalassign");
return;
CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
args, "threadlocalassign");
}
void
@ -6987,10 +6983,10 @@ void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
if (const Expr *ThrowExpr = S.getThrowExpr()) {
llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
.setDoesNotReturn();
} else {
CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
.setDoesNotReturn();
}

Просмотреть файл

@ -163,7 +163,7 @@ namespace {
return;
}
CGF.EmitCallOrInvoke(Fn);
CGF.EmitRuntimeCallOrInvoke(Fn);
}
};
}

Просмотреть файл

@ -119,11 +119,11 @@ public:
/// Get a selector for the specified name and type values. The
/// return value should have the LLVM type for pointer-to
/// ASTContext::getObjCSelType().
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
Selector Sel, bool lval=false) = 0;
/// Get a typed selector.
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
const ObjCMethodDecl *Method) = 0;
/// Get the type constant to catch for the given ObjC pointer type.
@ -179,7 +179,7 @@ public:
/// Emit the code to return the named protocol as an object, as in a
/// \@protocol expression.
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *OPD) = 0;
/// Generate the named protocol. Protocols contain method metadata but no
@ -218,11 +218,11 @@ public:
/// GetClass - Return a reference to the class for the given
/// interface decl.
virtual llvm::Value *GetClass(CGBuilderTy &Builder,
virtual llvm::Value *GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *OID) = 0;
virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CGBuilderTy &Builder) {
virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
llvm_unreachable("autoreleasepool unsupported in this ABI");
}

Просмотреть файл

@ -258,9 +258,12 @@ void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) {
llvm::ConstantInt::get(Int32Ty, 0),
"callsite");
Builder.CreateCall2(F,
llvm::ConstantExpr::getBitCast(CurFn, PointerTy),
CallSite);
llvm::Value *args[] = {
llvm::ConstantExpr::getBitCast(CurFn, PointerTy),
CallSite
};
EmitNounwindRuntimeCall(F, args);
}
void CodeGenFunction::EmitMCountInstrumentation() {
@ -268,7 +271,7 @@ void CodeGenFunction::EmitMCountInstrumentation() {
llvm::Constant *MCountFn = CGM.CreateRuntimeFunction(FTy,
Target.getMCountName());
Builder.CreateCall(MCountFn);
EmitNounwindRuntimeCall(MCountFn);
}
// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument

Просмотреть файл

@ -2301,11 +2301,29 @@ public:
RValue EmitCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue = ReturnValueSlot());
llvm::CallInst *EmitRuntimeCall(llvm::Value *callee,
const Twine &name = "");
llvm::CallInst *EmitRuntimeCall(llvm::Value *callee,
ArrayRef<llvm::Value*> args,
const Twine &name = "");
llvm::CallInst *EmitNounwindRuntimeCall(llvm::Value *callee,
const Twine &name = "");
llvm::CallInst *EmitNounwindRuntimeCall(llvm::Value *callee,
ArrayRef<llvm::Value*> args,
const Twine &name = "");
llvm::CallSite EmitCallOrInvoke(llvm::Value *Callee,
ArrayRef<llvm::Value *> Args,
const Twine &Name = "");
llvm::CallSite EmitCallOrInvoke(llvm::Value *Callee,
const Twine &Name = "");
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee,
ArrayRef<llvm::Value*> args,
const Twine &name = "");
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee,
const Twine &name = "");
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee,
ArrayRef<llvm::Value*> args);
llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
llvm::Type *Ty);

Просмотреть файл

@ -107,6 +107,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
Int8PtrTy = Int8Ty->getPointerTo(0);
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC();
if (LangOpts.ObjC1)
createObjCRuntime();
if (LangOpts.OpenCL)
@ -1354,8 +1356,13 @@ llvm::Constant *
CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy,
StringRef Name,
llvm::AttributeSet ExtraAttrs) {
return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
ExtraAttrs);
llvm::Constant *C
= GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
ExtraAttrs);
if (llvm::Function *F = dyn_cast<llvm::Function>(C))
if (F->empty())
F->setCallingConv(getRuntimeCC());
return C;
}
/// isTypeConstant - Determine whether an object of this type can be emitted

Просмотреть файл

@ -28,6 +28,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Transforms/Utils/BlackList.h"
@ -145,6 +146,11 @@ namespace CodeGen {
unsigned char PointerSizeInBytes;
unsigned char SizeSizeInBytes; // sizeof(size_t)
};
llvm::CallingConv::ID RuntimeCC;
llvm::CallingConv::ID getRuntimeCC() const {
return RuntimeCC;
}
};
struct RREntrypoints {

Просмотреть файл

@ -1043,8 +1043,8 @@ namespace {
CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
void Emit(CodeGenFunction &CGF, Flags flags) {
CGF.Builder.CreateCall(getGuardAbortFn(CGF.CGM, Guard->getType()), Guard)
->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()),
Guard);
}
};
}
@ -1163,7 +1163,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
if (threadsafe) {
// Call __cxa_guard_acquire.
llvm::Value *V
= Builder.CreateCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
= CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
@ -1184,7 +1184,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
CGF.PopCleanupBlock();
// Call __cxa_guard_release. This cannot throw.
Builder.CreateCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
} else {
Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
}
@ -1222,7 +1222,7 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
handle
};
CGF.Builder.CreateCall(atexit, args)->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(atexit, args);
}
/// Register a global destructor as best as we know how.

Просмотреть файл

@ -2961,7 +2961,9 @@ private:
ABIKind Kind;
public:
ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind) {}
ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind) {
setRuntimeCC();
}
bool isEABI() const {
StringRef Env =
@ -2983,6 +2985,10 @@ private:
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CGF) const;
llvm::CallingConv::ID getLLVMDefaultCC() const;
llvm::CallingConv::ID getABIDefaultCC() const;
void setRuntimeCC();
};
class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
@ -3052,32 +3058,41 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
if (FI.getCallingConvention() != llvm::CallingConv::C)
return;
// Calling convention as default by an ABI.
llvm::CallingConv::ID DefaultCC;
if (getContext().getTargetInfo().getTriple().getEnvironmentName()=="gnueabihf")
DefaultCC = llvm::CallingConv::ARM_AAPCS_VFP;
else if (isEABI())
DefaultCC = llvm::CallingConv::ARM_AAPCS;
else
DefaultCC = llvm::CallingConv::ARM_APCS;
llvm::CallingConv::ID cc = getRuntimeCC();
if (cc != llvm::CallingConv::C)
FI.setEffectiveCallingConvention(cc);
}
// If user did not ask for specific calling convention explicitly (e.g. via
// pcs attribute), set effective calling convention if it's different than ABI
// default.
/// Return the default calling convention that LLVM will use.
llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC() const {
// The default calling convention that LLVM will infer.
if (getContext().getTargetInfo().getTriple().getEnvironmentName()=="gnueabihf")
return llvm::CallingConv::ARM_AAPCS_VFP;
else if (isEABI())
return llvm::CallingConv::ARM_AAPCS;
else
return llvm::CallingConv::ARM_APCS;
}
/// Return the calling convention that our ABI would like us to use
/// as the C calling convention.
llvm::CallingConv::ID ARMABIInfo::getABIDefaultCC() const {
switch (getABIKind()) {
case APCS:
if (DefaultCC != llvm::CallingConv::ARM_APCS)
FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_APCS);
break;
case AAPCS:
if (DefaultCC != llvm::CallingConv::ARM_AAPCS)
FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS);
break;
case AAPCS_VFP:
if (DefaultCC != llvm::CallingConv::ARM_AAPCS_VFP)
FI.setEffectiveCallingConvention(llvm::CallingConv::ARM_AAPCS_VFP);
break;
case APCS: return llvm::CallingConv::ARM_APCS;
case AAPCS: return llvm::CallingConv::ARM_AAPCS;
case AAPCS_VFP: return llvm::CallingConv::ARM_AAPCS_VFP;
}
llvm_unreachable("bad ABI kind");
}
void ARMABIInfo::setRuntimeCC() {
assert(getRuntimeCC() == llvm::CallingConv::C);
// Don't muddy up the IR with a ton of explicit annotations if
// they'd just match what LLVM will infer from the triple.
llvm::CallingConv::ID abiCC = getABIDefaultCC();
if (abiCC != getLLVMDefaultCC())
RuntimeCC = abiCC;
}
/// isHomogeneousAggregate - Return true if a type is an AAPCS-VFP homogeneous
@ -4013,7 +4028,7 @@ namespace {
class NVPTXABIInfo : public ABIInfo {
public:
NVPTXABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
NVPTXABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) { setRuntimeCC(); }
ABIArgInfo classifyReturnType(QualType RetTy) const;
ABIArgInfo classifyArgumentType(QualType Ty) const;
@ -4021,6 +4036,8 @@ public:
virtual void computeInfo(CGFunctionInfo &FI) const;
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CFG) const;
private:
void setRuntimeCC();
};
class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo {
@ -4057,25 +4074,26 @@ void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
if (FI.getCallingConvention() != llvm::CallingConv::C)
return;
FI.setEffectiveCallingConvention(getRuntimeCC());
}
void NVPTXABIInfo::setRuntimeCC() {
// Calling convention as default by an ABI.
// We're still using the PTX_Kernel/PTX_Device calling conventions here,
// but we should switch to NVVM metadata later on.
llvm::CallingConv::ID DefaultCC;
const LangOptions &LangOpts = getContext().getLangOpts();
if (LangOpts.OpenCL || LangOpts.CUDA) {
// If we are in OpenCL or CUDA mode, then default to device functions
DefaultCC = llvm::CallingConv::PTX_Device;
RuntimeCC = llvm::CallingConv::PTX_Device;
} else {
// If we are in standard C/C++ mode, use the triple to decide on the default
StringRef Env =
getContext().getTargetInfo().getTriple().getEnvironmentName();
if (Env == "device")
DefaultCC = llvm::CallingConv::PTX_Device;
RuntimeCC = llvm::CallingConv::PTX_Device;
else
DefaultCC = llvm::CallingConv::PTX_Kernel;
RuntimeCC = llvm::CallingConv::PTX_Kernel;
}
FI.setEffectiveCallingConvention(DefaultCC);
}
llvm::Value *NVPTXABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,

Просмотреть файл

@ -0,0 +1,53 @@
// RUN: %clang_cc1 %s -triple=armv7-apple-darwin10 -emit-llvm -o - -fexceptions -fcxx-exceptions | FileCheck %s
// Check that we annotate all compiler-synthesized runtime calls and
// functions with the actual ABI-determined CC. This usually doesn't
// matter as long as we're internally consistent (and the LLVM-default
// CC is consistent with the real one), but it's possible for user
// translation units to define these runtime functions (or, equivalently,
// for us to get LTO'ed with such a translation unit), and then the
// mismatch will kill us.
//
// rdar://12818655
// CHECK: [[A:%.*]] = type { double }
namespace test0 {
struct A {
double d;
A();
~A();
};
A global;
// CHECK: define internal arm_aapcscc void @__cxx_global_var_init()
// CHECK: call arm_aapcscc [[A]]* @_ZN5test01AC1Ev([[A]]* @_ZN5test06globalE)
// CHECK-NEXT: call arm_aapcscc i32 @__cxa_atexit(void (i8*)* bitcast ([[A]]* ([[A]]*)* @_ZN5test01AD1Ev to void (i8*)*), i8* bitcast ([[A]]* @_ZN5test06globalE to i8*), i8* @__dso_handle) [[NOUNWIND:#[0-9]+]]
// CHECK-NEXT: ret void
}
// CHECK: declare arm_aapcscc i32 @__cxa_atexit(void (i8*)*, i8*, i8*) [[NOUNWIND]]
namespace test1 {
void test() {
throw 0;
}
// CHECK: define arm_aapcscc void @_ZN5test14testEv()
// CHECK: [[T0:%.*]] = call arm_aapcscc i8* @__cxa_allocate_exception(i32 4) [[NOUNWIND]]
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
// CHECK-NEXT: store i32 0, i32* [[T1]]
// CHECK-NEXT: call arm_aapcscc void @__cxa_throw(i8* [[T0]], i8* bitcast (i8** @_ZTIi to i8*), i8* null) [[NORETURN:#[0-9]+]]
// CHECK-NEXT: unreachable
}
// CHECK: declare arm_aapcscc i8* @__cxa_allocate_exception(i32)
// CHECK: declare arm_aapcscc void @__cxa_throw(i8*, i8*, i8*)
// CHECK: define internal arm_aapcscc void @_GLOBAL__I_a()
// CHECK: call arm_aapcscc void @__cxx_global_var_init()
// CHECK: attributes [[NOUNWIND]] = { nounwind }
// CHECK: attributes [[NORETURN]] = { noreturn }

Просмотреть файл

@ -11,9 +11,9 @@ void test1(void) {
extern id test1_helper(void);
// CHECK: [[T0:%.*]] = call arm_aapcscc i8* @test1_helper()
// CHECK-NEXT: call void asm sideeffect "mov\09r7, r7
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T1:%.*]] = call arm_aapcscc i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]],
// CHECK-NEXT: call void @objc_storeStrong(
// CHECK-NEXT: call arm_aapcscc void @objc_storeStrong(
// CHECK-NEXT: ret void
id x = test1_helper();
}