diff options
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 555 |
1 files changed, 445 insertions, 110 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 712ae89..f8783ad 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1,4 +1,4 @@ -//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===// +//===--- CGCall.cpp - Encapsulate calling convention details ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -25,6 +25,8 @@ #include "llvm/Attributes.h" #include "llvm/Support/CallSite.h" #include "llvm/Target/TargetData.h" +#include "llvm/InlineAsm.h" +#include "llvm/Transforms/Utils/Local.h" using namespace clang; using namespace CodeGen; @@ -65,31 +67,28 @@ static CanQualType GetReturnType(QualType RetTy) { } const CGFunctionInfo & -CodeGenTypes::getFunctionInfo(CanQual<FunctionNoProtoType> FTNP, - bool IsRecursive) { +CodeGenTypes::getFunctionInfo(CanQual<FunctionNoProtoType> FTNP) { return getFunctionInfo(FTNP->getResultType().getUnqualifiedType(), llvm::SmallVector<CanQualType, 16>(), - FTNP->getExtInfo(), IsRecursive); + FTNP->getExtInfo()); } /// \param Args - contains any initial parameters besides those /// in the formal type static const CGFunctionInfo &getFunctionInfo(CodeGenTypes &CGT, llvm::SmallVectorImpl<CanQualType> &ArgTys, - CanQual<FunctionProtoType> FTP, - bool IsRecursive = false) { + CanQual<FunctionProtoType> FTP) { // FIXME: Kill copy. for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTys.push_back(FTP->getArgType(i)); CanQualType ResTy = FTP->getResultType().getUnqualifiedType(); - return CGT.getFunctionInfo(ResTy, ArgTys, FTP->getExtInfo(), IsRecursive); + return CGT.getFunctionInfo(ResTy, ArgTys, FTP->getExtInfo()); } const CGFunctionInfo & -CodeGenTypes::getFunctionInfo(CanQual<FunctionProtoType> FTP, - bool IsRecursive) { +CodeGenTypes::getFunctionInfo(CanQual<FunctionProtoType> FTP) { llvm::SmallVector<CanQualType, 16> ArgTys; - return ::getFunctionInfo(*this, ArgTys, FTP, IsRecursive); + return ::getFunctionInfo(*this, ArgTys, FTP); } static CallingConv getCallingConventionForDecl(const Decl *D) { @@ -189,13 +188,15 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { e = MD->param_end(); i != e; ++i) { ArgTys.push_back(Context.getCanonicalParamType((*i)->getType())); } - return getFunctionInfo(GetReturnType(MD->getResultType()), - ArgTys, - FunctionType::ExtInfo( - /*NoReturn*/ false, - /*HasRegParm*/ false, - /*RegParm*/ 0, - getCallingConventionForDecl(MD))); + + FunctionType::ExtInfo einfo; + einfo = einfo.withCallingConv(getCallingConventionForDecl(MD)); + + if (getContext().getLangOptions().ObjCAutoRefCount && + MD->hasAttr<NSReturnsRetainedAttr>()) + einfo = einfo.withProducesResult(true); + + return getFunctionInfo(GetReturnType(MD->getResultType()), ArgTys, einfo); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(GlobalDecl GD) { @@ -240,8 +241,7 @@ const CGFunctionInfo &CodeGenTypes::getNullaryFunctionInfo() { const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy, const llvm::SmallVectorImpl<CanQualType> &ArgTys, - const FunctionType::ExtInfo &Info, - bool IsRecursive) { + const FunctionType::ExtInfo &Info) { #ifndef NDEBUG for (llvm::SmallVectorImpl<CanQualType>::const_iterator I = ArgTys.begin(), E = ArgTys.end(); I != E; ++I) @@ -252,8 +252,7 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy, // Lookup or create unique function info. llvm::FoldingSetNodeID ID; - CGFunctionInfo::Profile(ID, Info, ResTy, - ArgTys.begin(), ArgTys.end()); + CGFunctionInfo::Profile(ID, Info, ResTy, ArgTys.begin(), ArgTys.end()); void *InsertPos = 0; CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, InsertPos); @@ -261,10 +260,14 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy, return *FI; // Construct the function info. - FI = new CGFunctionInfo(CC, Info.getNoReturn(), Info.getHasRegParm(), Info.getRegParm(), ResTy, + FI = new CGFunctionInfo(CC, Info.getNoReturn(), Info.getProducesResult(), + Info.getHasRegParm(), Info.getRegParm(), ResTy, ArgTys.data(), ArgTys.size()); FunctionInfos.InsertNode(FI, InsertPos); + bool Inserted = FunctionsBeingProcessed.insert(FI); (void)Inserted; + assert(Inserted && "Recursively being processed?"); + // Compute ABI information. getABIInfo().computeInfo(*FI); @@ -273,30 +276,29 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy, // default now. ABIArgInfo &RetInfo = FI->getReturnInfo(); if (RetInfo.canHaveCoerceToType() && RetInfo.getCoerceToType() == 0) - RetInfo.setCoerceToType(ConvertTypeRecursive(FI->getReturnType())); + RetInfo.setCoerceToType(ConvertType(FI->getReturnType())); for (CGFunctionInfo::arg_iterator I = FI->arg_begin(), E = FI->arg_end(); I != E; ++I) if (I->info.canHaveCoerceToType() && I->info.getCoerceToType() == 0) - I->info.setCoerceToType(ConvertTypeRecursive(I->type)); - - // If this is a top-level call and ConvertTypeRecursive hit unresolved pointer - // types, resolve them now. These pointers may point to this function, which - // we *just* filled in the FunctionInfo for. - if (!IsRecursive && !PointersToResolve.empty()) - HandleLateResolvedPointers(); + I->info.setCoerceToType(ConvertType(I->type)); + bool Erased = FunctionsBeingProcessed.erase(FI); (void)Erased; + assert(Erased && "Not in set?"); + return *FI; } CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention, - bool _NoReturn, bool _HasRegParm, unsigned _RegParm, + bool _NoReturn, bool returnsRetained, + bool _HasRegParm, unsigned _RegParm, CanQualType ResTy, const CanQualType *ArgTys, unsigned NumArgTys) : CallingConvention(_CallingConvention), EffectiveCallingConvention(_CallingConvention), - NoReturn(_NoReturn), HasRegParm(_HasRegParm), RegParm(_RegParm) + NoReturn(_NoReturn), ReturnsRetained(returnsRetained), + HasRegParm(_HasRegParm), RegParm(_RegParm) { NumArgs = NumArgTys; @@ -310,8 +312,7 @@ CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention, /***/ void CodeGenTypes::GetExpandedTypes(QualType type, - llvm::SmallVectorImpl<const llvm::Type*> &expandedTypes, - bool isRecursive) { + llvm::SmallVectorImpl<llvm::Type*> &expandedTypes) { const RecordType *RT = type->getAsStructureType(); assert(RT && "Can only expand structure types."); const RecordDecl *RD = RT->getDecl(); @@ -326,9 +327,9 @@ void CodeGenTypes::GetExpandedTypes(QualType type, QualType fieldType = FD->getType(); if (fieldType->isRecordType()) - GetExpandedTypes(fieldType, expandedTypes, isRecursive); + GetExpandedTypes(fieldType, expandedTypes); else - expandedTypes.push_back(ConvertType(fieldType, isRecursive)); + expandedTypes.push_back(ConvertType(fieldType)); } } @@ -352,7 +353,7 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV, if (CodeGenFunction::hasAggregateLLVMType(FT)) { AI = ExpandTypeFromArgs(FT, LV, AI); } else { - EmitStoreThroughLValue(RValue::get(AI), LV, FT); + EmitStoreThroughLValue(RValue::get(AI), LV); ++AI; } } @@ -360,33 +361,6 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV, return AI; } -void -CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV, - llvm::SmallVector<llvm::Value*, 16> &Args) { - const RecordType *RT = Ty->getAsStructureType(); - assert(RT && "Can only expand structure types."); - - RecordDecl *RD = RT->getDecl(); - assert(RV.isAggregate() && "Unexpected rvalue during struct expansion"); - llvm::Value *Addr = RV.getAggregateAddr(); - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) { - FieldDecl *FD = *i; - QualType FT = FD->getType(); - - // FIXME: What are the right qualifiers here? - LValue LV = EmitLValueForField(Addr, FD, 0); - if (CodeGenFunction::hasAggregateLLVMType(FT)) { - ExpandTypeToArgs(FT, RValue::getAggregate(LV.getAddress()), Args); - } else { - RValue RV = EmitLoadOfLValue(LV, FT); - assert(RV.isScalar() && - "Unexpected non-scalar rvalue during struct expansion."); - Args.push_back(RV.getScalarVal()); - } - } -} - /// EnterStructPointerForCoercedAccess - Given a struct pointer that we are /// accessing some number of bytes out of it, try to gep into the struct to get /// at its inner goodness. Dive as deep as possible without entering an element @@ -622,7 +596,7 @@ bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) { return false; } -const llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) { +llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) { const CGFunctionInfo &FI = getFunctionInfo(GD); // For definition purposes, don't consider a K&R function variadic. @@ -631,13 +605,16 @@ const llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) { cast<FunctionDecl>(GD.getDecl())->getType()->getAs<FunctionProtoType>()) Variadic = FPT->isVariadic(); - return GetFunctionType(FI, Variadic, false); + return GetFunctionType(FI, Variadic); } -const llvm::FunctionType * -CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool isVariadic, - bool isRecursive) { - llvm::SmallVector<const llvm::Type*, 8> argTypes; +llvm::FunctionType * +CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool isVariadic) { + + bool Inserted = FunctionsBeingProcessed.insert(&FI); (void)Inserted; + assert(Inserted && "Recursively being processed?"); + + llvm::SmallVector<llvm::Type*, 8> argTypes; const llvm::Type *resultType = 0; const ABIArgInfo &retAI = FI.getReturnInfo(); @@ -655,7 +632,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool isVariadic, resultType = llvm::Type::getVoidTy(getLLVMContext()); QualType ret = FI.getReturnType(); - const llvm::Type *ty = ConvertType(ret, isRecursive); + const llvm::Type *ty = ConvertType(ret); unsigned addressSpace = Context.getTargetAddressSpace(ret); argTypes.push_back(llvm::PointerType::get(ty, addressSpace)); break; @@ -676,7 +653,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool isVariadic, case ABIArgInfo::Indirect: { // indirect arguments are always on the stack, which is addr space #0. - const llvm::Type *LTy = ConvertTypeForMem(it->type, isRecursive); + const llvm::Type *LTy = ConvertTypeForMem(it->type); argTypes.push_back(LTy->getPointerTo()); break; } @@ -686,7 +663,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool isVariadic, // If the coerce-to type is a first class aggregate, flatten it. Either // way is semantically identical, but fast-isel and the optimizer // generally likes scalar values better than FCAs. - const llvm::Type *argType = argAI.getCoerceToType(); + llvm::Type *argType = argAI.getCoerceToType(); if (const llvm::StructType *st = dyn_cast<llvm::StructType>(argType)) { for (unsigned i = 0, e = st->getNumElements(); i != e; ++i) argTypes.push_back(st->getElementType(i)); @@ -697,11 +674,14 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool isVariadic, } case ABIArgInfo::Expand: - GetExpandedTypes(it->type, argTypes, isRecursive); + GetExpandedTypes(it->type, argTypes); break; } } + bool Erased = FunctionsBeingProcessed.erase(&FI); (void)Erased; + assert(Erased && "Not in set?"); + return llvm::FunctionType::get(resultType, argTypes, isVariadic); } @@ -709,16 +689,15 @@ const llvm::Type *CodeGenTypes::GetFunctionTypeForVTable(GlobalDecl GD) { const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - if (!VerifyFuncTypeComplete(FPT)) { - const CGFunctionInfo *Info; - if (isa<CXXDestructorDecl>(MD)) - Info = &getFunctionInfo(cast<CXXDestructorDecl>(MD), GD.getDtorType()); - else - Info = &getFunctionInfo(MD); - return GetFunctionType(*Info, FPT->isVariadic(), false); - } - - return llvm::OpaqueType::get(getLLVMContext()); + if (!isFuncTypeConvertible(FPT)) + return llvm::StructType::get(getLLVMContext()); + + const CGFunctionInfo *Info; + if (isa<CXXDestructorDecl>(MD)) + Info = &getFunctionInfo(cast<CXXDestructorDecl>(MD), GD.getDtorType()); + else + Info = &getFunctionInfo(MD); + return GetFunctionType(*Info, FPT->isVariadic()); } void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, @@ -845,11 +824,11 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, continue; case ABIArgInfo::Expand: { - llvm::SmallVector<const llvm::Type*, 8> types; + llvm::SmallVector<llvm::Type*, 8> types; // FIXME: This is rather inefficient. Do we ever actually need to do // anything here? The result should be just reconstructed on the other // side, so extension should be a non-issue. - getTypes().GetExpandedTypes(ParamType, types, false); + getTypes().GetExpandedTypes(ParamType, types); Index += types.size(); continue; } @@ -1067,6 +1046,95 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, assert(AI == Fn->arg_end() && "Argument mismatch!"); } +/// Try to emit a fused autorelease of a return result. +static llvm::Value *tryEmitFusedAutoreleaseOfResult(CodeGenFunction &CGF, + llvm::Value *result) { + // We must be immediately followed the cast. + llvm::BasicBlock *BB = CGF.Builder.GetInsertBlock(); + if (BB->empty()) return 0; + if (&BB->back() != result) return 0; + + const llvm::Type *resultType = result->getType(); + + // result is in a BasicBlock and is therefore an Instruction. + llvm::Instruction *generator = cast<llvm::Instruction>(result); + + llvm::SmallVector<llvm::Instruction*,4> insnsToKill; + + // Look for: + // %generator = bitcast %type1* %generator2 to %type2* + while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) { + // We would have emitted this as a constant if the operand weren't + // an Instruction. + generator = cast<llvm::Instruction>(bitcast->getOperand(0)); + + // Require the generator to be immediately followed by the cast. + if (generator->getNextNode() != bitcast) + return 0; + + insnsToKill.push_back(bitcast); + } + + // Look for: + // %generator = call i8* @objc_retain(i8* %originalResult) + // or + // %generator = call i8* @objc_retainAutoreleasedReturnValue(i8* %originalResult) + llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator); + if (!call) return 0; + + bool doRetainAutorelease; + + if (call->getCalledValue() == CGF.CGM.getARCEntrypoints().objc_retain) { + doRetainAutorelease = true; + } else if (call->getCalledValue() == CGF.CGM.getARCEntrypoints() + .objc_retainAutoreleasedReturnValue) { + doRetainAutorelease = false; + + // Look for an inline asm immediately preceding the call and kill it, too. + llvm::Instruction *prev = call->getPrevNode(); + if (llvm::CallInst *asmCall = dyn_cast_or_null<llvm::CallInst>(prev)) + if (asmCall->getCalledValue() + == CGF.CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker) + insnsToKill.push_back(prev); + } else { + return 0; + } + + result = call->getArgOperand(0); + insnsToKill.push_back(call); + + // Keep killing bitcasts, for sanity. Note that we no longer care + // about precise ordering as long as there's exactly one use. + while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) { + if (!bitcast->hasOneUse()) break; + insnsToKill.push_back(bitcast); + result = bitcast->getOperand(0); + } + + // Delete all the unnecessary instructions, from latest to earliest. + for (llvm::SmallVectorImpl<llvm::Instruction*>::iterator + i = insnsToKill.begin(), e = insnsToKill.end(); i != e; ++i) + (*i)->eraseFromParent(); + + // Do the fused retain/autorelease if we were asked to. + if (doRetainAutorelease) + result = CGF.EmitARCRetainAutoreleaseReturnValue(result); + + // Cast back to the result type. + return CGF.Builder.CreateBitCast(result, resultType); +} + +/// Emit an ARC autorelease of the result of a function. +static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF, + llvm::Value *result) { + // At -O0, try to emit a fused retain/autorelease. + if (CGF.shouldUseFusedARCCalls()) + if (llvm::Value *fused = tryEmitFusedAutoreleaseOfResult(CGF, result)) + return fused; + + return CGF.EmitARCAutoreleaseReturnValue(result); +} + void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI) { // Functions with no result always return void. if (ReturnValue == 0) { @@ -1134,6 +1202,16 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI) { RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), *this); } + + // In ARC, end functions that return a retainable type with a call + // to objc_autoreleaseReturnValue. + if (AutoreleaseResult) { + assert(getLangOptions().ObjCAutoRefCount && + !FI.isReturnsRetained() && + RetTy->isObjCRetainableType()); + RV = emitAutoreleaseOfResult(*this, RV); + } + break; case ABIArgInfo::Ignore: @@ -1183,13 +1261,157 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, return args.add(RValue::get(value), type); } +static bool isProvablyNull(llvm::Value *addr) { + return isa<llvm::ConstantPointerNull>(addr); +} + +static bool isProvablyNonNull(llvm::Value *addr) { + return isa<llvm::AllocaInst>(addr); +} + +/// Emit the actual writing-back of a writeback. +static void emitWriteback(CodeGenFunction &CGF, + const CallArgList::Writeback &writeback) { + llvm::Value *srcAddr = writeback.Address; + assert(!isProvablyNull(srcAddr) && + "shouldn't have writeback for provably null argument"); + + llvm::BasicBlock *contBB = 0; + + // If the argument wasn't provably non-null, we need to null check + // before doing the store. + bool provablyNonNull = isProvablyNonNull(srcAddr); + if (!provablyNonNull) { + llvm::BasicBlock *writebackBB = CGF.createBasicBlock("icr.writeback"); + contBB = CGF.createBasicBlock("icr.done"); + + llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull"); + CGF.Builder.CreateCondBr(isNull, contBB, writebackBB); + CGF.EmitBlock(writebackBB); + } + + // Load the value to writeback. + llvm::Value *value = CGF.Builder.CreateLoad(writeback.Temporary); + + // Cast it back, in case we're writing an id to a Foo* or something. + value = CGF.Builder.CreateBitCast(value, + cast<llvm::PointerType>(srcAddr->getType())->getElementType(), + "icr.writeback-cast"); + + // Perform the writeback. + QualType srcAddrType = writeback.AddressType; + CGF.EmitStoreThroughLValue(RValue::get(value), + CGF.MakeAddrLValue(srcAddr, srcAddrType)); + + // Jump to the continuation block. + if (!provablyNonNull) + CGF.EmitBlock(contBB); +} + +static void emitWritebacks(CodeGenFunction &CGF, + const CallArgList &args) { + for (CallArgList::writeback_iterator + i = args.writeback_begin(), e = args.writeback_end(); i != e; ++i) + emitWriteback(CGF, *i); +} + +/// Emit an argument that's being passed call-by-writeback. That is, +/// we are passing the address of +static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, + const ObjCIndirectCopyRestoreExpr *CRE) { + llvm::Value *srcAddr = CGF.EmitScalarExpr(CRE->getSubExpr()); + + // The dest and src types don't necessarily match in LLVM terms + // because of the crazy ObjC compatibility rules. + + const llvm::PointerType *destType = + cast<llvm::PointerType>(CGF.ConvertType(CRE->getType())); + + // If the address is a constant null, just pass the appropriate null. + if (isProvablyNull(srcAddr)) { + args.add(RValue::get(llvm::ConstantPointerNull::get(destType)), + CRE->getType()); + return; + } + + QualType srcAddrType = + CRE->getSubExpr()->getType()->castAs<PointerType>()->getPointeeType(); + + // Create the temporary. + llvm::Value *temp = CGF.CreateTempAlloca(destType->getElementType(), + "icr.temp"); + + // Zero-initialize it if we're not doing a copy-initialization. + bool shouldCopy = CRE->shouldCopy(); + if (!shouldCopy) { + llvm::Value *null = + llvm::ConstantPointerNull::get( + cast<llvm::PointerType>(destType->getElementType())); + CGF.Builder.CreateStore(null, temp); + } + + llvm::BasicBlock *contBB = 0; + + // If the address is *not* known to be non-null, we need to switch. + llvm::Value *finalArgument; + + bool provablyNonNull = isProvablyNonNull(srcAddr); + if (provablyNonNull) { + finalArgument = temp; + } else { + llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull"); + + finalArgument = CGF.Builder.CreateSelect(isNull, + llvm::ConstantPointerNull::get(destType), + temp, "icr.argument"); + + // If we need to copy, then the load has to be conditional, which + // means we need control flow. + if (shouldCopy) { + contBB = CGF.createBasicBlock("icr.cont"); + llvm::BasicBlock *copyBB = CGF.createBasicBlock("icr.copy"); + CGF.Builder.CreateCondBr(isNull, contBB, copyBB); + CGF.EmitBlock(copyBB); + } + } + + // Perform a copy if necessary. + if (shouldCopy) { + LValue srcLV = CGF.MakeAddrLValue(srcAddr, srcAddrType); + RValue srcRV = CGF.EmitLoadOfLValue(srcLV); + assert(srcRV.isScalar()); + + llvm::Value *src = srcRV.getScalarVal(); + src = CGF.Builder.CreateBitCast(src, destType->getElementType(), + "icr.cast"); + + // Use an ordinary store, not a store-to-lvalue. + CGF.Builder.CreateStore(src, temp); + } + + // Finish the control flow if we needed it. + if (shouldCopy && !provablyNonNull) + CGF.EmitBlock(contBB); + + args.addWriteback(srcAddr, srcAddrType, temp); + args.add(RValue::get(finalArgument), CRE->getType()); +} + void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, QualType type) { + if (const ObjCIndirectCopyRestoreExpr *CRE + = dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) { + assert(getContext().getLangOptions().ObjCAutoRefCount); + assert(getContext().hasSameType(E->getType(), type)); + return emitWritebackArg(*this, args, CRE); + } + if (type->isReferenceType()) return args.add(EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0), type); - if (hasAggregateLLVMType(type) && isa<ImplicitCastExpr>(E) && + if (hasAggregateLLVMType(type) && !E->getType()->isAnyComplexType() && + isa<ImplicitCastExpr>(E) && cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue) { LValue L = EmitLValue(cast<CastExpr>(E)->getSubExpr()); assert(L.isSimple()); @@ -1205,20 +1427,71 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, /// on the current state of the EH stack. llvm::CallSite CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee, - llvm::Value * const *ArgBegin, - llvm::Value * const *ArgEnd, + llvm::ArrayRef<llvm::Value *> Args, const llvm::Twine &Name) { llvm::BasicBlock *InvokeDest = getInvokeDest(); if (!InvokeDest) - return Builder.CreateCall(Callee, ArgBegin, ArgEnd, Name); + return Builder.CreateCall(Callee, Args, Name); llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont"); llvm::InvokeInst *Invoke = Builder.CreateInvoke(Callee, ContBB, InvokeDest, - ArgBegin, ArgEnd, Name); + Args, Name); EmitBlock(ContBB); return Invoke; } +llvm::CallSite +CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee, + const llvm::Twine &Name) { + return EmitCallOrInvoke(Callee, llvm::ArrayRef<llvm::Value *>(), Name); +} + +static void checkArgMatches(llvm::Value *Elt, unsigned &ArgNo, + llvm::FunctionType *FTy) { + if (ArgNo < FTy->getNumParams()) + assert(Elt->getType() == FTy->getParamType(ArgNo)); + else + assert(FTy->isVarArg()); + ++ArgNo; +} + +void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV, + llvm::SmallVector<llvm::Value*,16> &Args, + llvm::FunctionType *IRFuncTy) { + const RecordType *RT = Ty->getAsStructureType(); + assert(RT && "Can only expand structure types."); + + RecordDecl *RD = RT->getDecl(); + assert(RV.isAggregate() && "Unexpected rvalue during struct expansion"); + llvm::Value *Addr = RV.getAggregateAddr(); + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i) { + FieldDecl *FD = *i; + QualType FT = FD->getType(); + + // FIXME: What are the right qualifiers here? + LValue LV = EmitLValueForField(Addr, FD, 0); + if (CodeGenFunction::hasAggregateLLVMType(FT)) { + ExpandTypeToArgs(FT, RValue::getAggregate(LV.getAddress()), + Args, IRFuncTy); + continue; + } + + RValue RV = EmitLoadOfLValue(LV); + assert(RV.isScalar() && + "Unexpected non-scalar rvalue during struct expansion."); + + // Insert a bitcast as needed. + llvm::Value *V = RV.getScalarVal(); + if (Args.size() < IRFuncTy->getNumParams() && + V->getType() != IRFuncTy->getParamType(Args.size())) + V = Builder.CreateBitCast(V, IRFuncTy->getParamType(Args.size())); + + Args.push_back(V); + } +} + + RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, @@ -1233,6 +1506,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, QualType RetTy = CallInfo.getReturnType(); const ABIArgInfo &RetAI = CallInfo.getReturnInfo(); + // IRArgNo - Keep track of the argument number in the callee we're looking at. + unsigned IRArgNo = 0; + llvm::FunctionType *IRFuncTy = + cast<llvm::FunctionType>( + cast<llvm::PointerType>(Callee->getType())->getElementType()); // If the call returns a temporary with struct return, create a temporary // alloca to hold the result, unless one is given to us. @@ -1241,6 +1519,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (!Value) Value = CreateMemTemp(RetTy); Args.push_back(Value); + checkArgMatches(Value, IRArgNo, IRFuncTy); } assert(CallInfo.arg_size() == CallArgs.size() && @@ -1251,24 +1530,54 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, const ABIArgInfo &ArgInfo = info_it->info; RValue RV = I->RV; - unsigned Alignment = + unsigned TypeAlign = getContext().getTypeAlignInChars(I->Ty).getQuantity(); switch (ArgInfo.getKind()) { case ABIArgInfo::Indirect: { if (RV.isScalar() || RV.isComplex()) { // Make a temporary alloca to pass the argument. - Args.push_back(CreateMemTemp(I->Ty)); + llvm::AllocaInst *AI = CreateMemTemp(I->Ty); + if (ArgInfo.getIndirectAlign() > AI->getAlignment()) + AI->setAlignment(ArgInfo.getIndirectAlign()); + Args.push_back(AI); + if (RV.isScalar()) EmitStoreOfScalar(RV.getScalarVal(), Args.back(), false, - Alignment, I->Ty); + TypeAlign, I->Ty); else StoreComplexToAddr(RV.getComplexVal(), Args.back(), false); - } else if (I->NeedsCopy && !ArgInfo.getIndirectByVal()) { - Args.push_back(CreateMemTemp(I->Ty)); - EmitAggregateCopy(Args.back(), RV.getAggregateAddr(), I->Ty, - RV.isVolatileQualified()); + + // Validate argument match. + checkArgMatches(AI, IRArgNo, IRFuncTy); } else { - Args.push_back(RV.getAggregateAddr()); + // We want to avoid creating an unnecessary temporary+copy here; + // however, we need one in two cases: + // 1. If the argument is not byval, and we are required to copy the + // source. (This case doesn't occur on any common architecture.) + // 2. If the argument is byval, RV is not sufficiently aligned, and + // we cannot force it to be sufficiently aligned. + llvm::Value *Addr = RV.getAggregateAddr(); + unsigned Align = ArgInfo.getIndirectAlign(); + const llvm::TargetData *TD = &CGM.getTargetData(); + if ((!ArgInfo.getIndirectByVal() && I->NeedsCopy) || + (ArgInfo.getIndirectByVal() && TypeAlign < Align && + llvm::getOrEnforceKnownAlignment(Addr, Align, TD) < Align)) { + // Create an aligned temporary, and copy to it. + llvm::AllocaInst *AI = CreateMemTemp(I->Ty); + if (Align > AI->getAlignment()) + AI->setAlignment(Align); + Args.push_back(AI); + EmitAggregateCopy(AI, Addr, I->Ty, RV.isVolatileQualified()); + + // Validate argument match. + checkArgMatches(AI, IRArgNo, IRFuncTy); + } else { + // Skip the extra memcpy call. + Args.push_back(Addr); + + // Validate argument match. + checkArgMatches(Addr, IRArgNo, IRFuncTy); + } } break; } @@ -1281,10 +1590,20 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (!isa<llvm::StructType>(ArgInfo.getCoerceToType()) && ArgInfo.getCoerceToType() == ConvertType(info_it->type) && ArgInfo.getDirectOffset() == 0) { + llvm::Value *V; if (RV.isScalar()) - Args.push_back(RV.getScalarVal()); + V = RV.getScalarVal(); else - Args.push_back(Builder.CreateLoad(RV.getAggregateAddr())); + V = Builder.CreateLoad(RV.getAggregateAddr()); + + // If the argument doesn't match, perform a bitcast to coerce it. This + // can happen due to trivial type mismatches. + if (IRArgNo < IRFuncTy->getNumParams() && + V->getType() != IRFuncTy->getParamType(IRArgNo)) + V = Builder.CreateBitCast(V, IRFuncTy->getParamType(IRArgNo)); + Args.push_back(V); + + checkArgMatches(V, IRArgNo, IRFuncTy); break; } @@ -1292,7 +1611,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::Value *SrcPtr; if (RV.isScalar()) { SrcPtr = CreateMemTemp(I->Ty, "coerce"); - EmitStoreOfScalar(RV.getScalarVal(), SrcPtr, false, Alignment, I->Ty); + EmitStoreOfScalar(RV.getScalarVal(), SrcPtr, false, TypeAlign, I->Ty); } else if (RV.isComplex()) { SrcPtr = CreateMemTemp(I->Ty, "coerce"); StoreComplexToAddr(RV.getComplexVal(), SrcPtr, false); @@ -1321,18 +1640,25 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // We don't know what we're loading from. LI->setAlignment(1); Args.push_back(LI); + + // Validate argument match. + checkArgMatches(LI, IRArgNo, IRFuncTy); } } else { // In the simple case, just pass the coerced loaded value. Args.push_back(CreateCoercedLoad(SrcPtr, ArgInfo.getCoerceToType(), *this)); + + // Validate argument match. + checkArgMatches(Args.back(), IRArgNo, IRFuncTy); } break; } case ABIArgInfo::Expand: - ExpandTypeToArgs(I->Ty, RV, Args); + ExpandTypeToArgs(I->Ty, RV, Args, IRFuncTy); + IRArgNo = Args.size(); break; } } @@ -1367,7 +1693,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } } - unsigned CallingConv; CodeGen::AttributeListType AttributeList; CGM.ConstructAttributeList(CallInfo, TargetDecl, AttributeList, CallingConv); @@ -1380,11 +1705,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::CallSite CS; if (!InvokeDest) { - CS = Builder.CreateCall(Callee, Args.data(), Args.data()+Args.size()); + CS = Builder.CreateCall(Callee, Args); } else { llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); - CS = Builder.CreateInvoke(Callee, Cont, InvokeDest, - Args.data(), Args.data()+Args.size()); + CS = Builder.CreateInvoke(Callee, Cont, InvokeDest, Args); EmitBlock(Cont); } if (callOrInvoke) @@ -1413,6 +1737,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (Builder.isNamePreserving() && !CI->getType()->isVoidTy()) CI->setName("call"); + // Emit any writebacks immediately. Arguably this should happen + // after any return-value munging. + if (CallArgs.hasWritebacks()) + emitWritebacks(*this, CallArgs); + switch (RetAI.getKind()) { case ABIArgInfo::Indirect: { unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity(); @@ -1430,8 +1759,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, case ABIArgInfo::Extend: case ABIArgInfo::Direct: { - if (RetAI.getCoerceToType() == ConvertType(RetTy) && - RetAI.getDirectOffset() == 0) { + llvm::Type *RetIRTy = ConvertType(RetTy); + if (RetAI.getCoerceToType() == RetIRTy && RetAI.getDirectOffset() == 0) { if (RetTy->isAnyComplexType()) { llvm::Value *Real = Builder.CreateExtractValue(CI, 0); llvm::Value *Imag = Builder.CreateExtractValue(CI, 1); @@ -1448,7 +1777,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, BuildAggStore(*this, CI, DestPtr, DestIsVolatile, false); return RValue::getAggregate(DestPtr); } - return RValue::get(CI); + + // If the argument doesn't match, perform a bitcast to coerce it. This + // can happen due to trivial type mismatches. + llvm::Value *V = CI; + if (V->getType() != RetIRTy) + V = Builder.CreateBitCast(V, RetIRTy); + return RValue::get(V); } llvm::Value *DestPtr = ReturnValue.getValue(); |