diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index ebace3395ac..55fa0b5bd5e 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -194,6 +194,14 @@ public: CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); } + FunctionType *getFunctionType() const { + CALLSITE_DELEGATE_GETTER(getFunctionType()); + } + + void mutateFunctionType(FunctionType *Ty) const { + CALLSITE_DELEGATE_SETTER(mutateFunctionType(Ty)); + } + /// getAttributes/setAttributes - get or set the parameter attributes of /// the call. const AttributeSet &getAttributes() const { diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 2571faf3836..7c60945fad6 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1284,14 +1284,26 @@ public: /// class CallInst : public Instruction { AttributeSet AttributeList; ///< parameter attributes for call + FunctionType *FTy; CallInst(const CallInst &CI); - void init(Value *Func, ArrayRef Args, const Twine &NameStr); + void init(Value *Func, ArrayRef Args, const Twine &NameStr) { + init(cast( + cast(Func->getType())->getElementType()), + Func, Args, NameStr); + } + void init(FunctionType *FTy, Value *Func, ArrayRef Args, + const Twine &NameStr); void init(Value *Func, const Twine &NameStr); /// Construct a CallInst given a range of arguments. /// \brief Construct a CallInst from a range of arguments - inline CallInst(Value *Func, ArrayRef Args, + inline CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore); + inline CallInst(Value *Func, ArrayRef Args, const Twine &NameStr, + Instruction *InsertBefore) + : CallInst(cast( + cast(Func->getType())->getElementType()), + Func, Args, NameStr, InsertBefore) {} /// Construct a CallInst given a range of arguments. /// \brief Construct a CallInst from a range of arguments @@ -1308,8 +1320,15 @@ public: ArrayRef Args, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return new(unsigned(Args.size() + 1)) - CallInst(Func, Args, NameStr, InsertBefore); + return Create(cast( + cast(Func->getType())->getElementType()), + Func, Args, NameStr, InsertBefore); + } + static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef Args, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + return new (unsigned(Args.size() + 1)) + CallInst(Ty, Func, Args, NameStr, InsertBefore); } static CallInst *Create(Value *Func, ArrayRef Args, @@ -1347,9 +1366,11 @@ public: ~CallInst() override; - FunctionType *getFunctionType() const { - return cast( - cast(getCalledValue()->getType())->getElementType()); + FunctionType *getFunctionType() const { return FTy; } + + void mutateFunctionType(FunctionType *FTy) { + mutateType(FTy->getReturnType()); + this->FTy = FTy; } // Note that 'musttail' implies 'tail'. @@ -1533,6 +1554,14 @@ public: /// setCalledFunction - Set the function called. void setCalledFunction(Value* Fn) { + setCalledFunction( + cast(cast(Fn->getType())->getElementType()), + Fn); + } + void setCalledFunction(FunctionType *FTy, Value *Fn) { + this->FTy = FTy; + assert(FTy == cast( + cast(Fn->getType())->getElementType())); Op<-1>() = Fn; } @@ -1573,14 +1602,12 @@ CallInst::CallInst(Value *Func, ArrayRef Args, init(Func, Args, NameStr); } -CallInst::CallInst(Value *Func, ArrayRef Args, +CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore) - : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, - OperandTraits::op_end(this) - (Args.size() + 1), - unsigned(Args.size() + 1), InsertBefore) { - init(Func, Args, NameStr); + : Instruction(Ty->getReturnType(), Instruction::Call, + OperandTraits::op_end(this) - (Args.size() + 1), + unsigned(Args.size() + 1), InsertBefore) { + init(Ty, Func, Args, NameStr); } @@ -3034,6 +3061,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value) /// class InvokeInst : public TerminatorInst { AttributeSet AttributeList; + FunctionType *FTy; InvokeInst(const InvokeInst &BI); void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr); @@ -3074,6 +3102,13 @@ public: /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + FunctionType *getFunctionType() const { return FTy; } + + void mutateFunctionType(FunctionType *FTy) { + mutateType(FTy->getReturnType()); + this->FTy = FTy; + } + /// getNumArgOperands - Return the number of invoke arguments. /// unsigned getNumArgOperands() const { return getNumOperands() - 3; } @@ -3223,6 +3258,14 @@ public: /// setCalledFunction - Set the function called. void setCalledFunction(Value* Fn) { + setCalledFunction( + cast(cast(Fn->getType())->getElementType()), + Fn); + } + void setCalledFunction(FunctionType *FTy, Value *Fn) { + this->FTy = FTy; + assert(FTy == cast( + cast(Fn->getType())->getElementType())); Op<-3>() = Fn; } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index be098c1b128..2e8008b96e7 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -5224,7 +5224,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, // Finish off the Attribute and check them AttributeSet PAL = AttributeSet::get(Context, Attrs); - CallInst *CI = CallInst::Create(Callee, Args); + CallInst *CI = CallInst::Create(Ty, Callee, Args); CI->setTailCallKind(TCK); CI->setCallingConv(CC); CI->setAttributes(PAL); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index bc78a71efad..f3446b73f93 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -4184,12 +4184,11 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { PointerType *OpTy = dyn_cast(Callee->getType()); if (!OpTy) return Error("Callee is not a pointer type"); - FunctionType *PFTy = dyn_cast(OpTy->getElementType()); - if (!PFTy) - return Error("Callee is not of pointer to function type"); - if (!FTy) - FTy = PFTy; - if (PFTy != FTy) + if (!FTy) { + FTy = dyn_cast(OpTy->getElementType()); + if (!FTy) + return Error("Callee is not of pointer to function type"); + } else if (OpTy->getElementType() != FTy) return Error("Explicit call type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) @@ -4220,7 +4219,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { } } - I = CallInst::Create(Callee, Args); + I = CallInst::Create(FTy, Callee, Args); InstructionList.push_back(I); cast(I)->setCallingConv( static_cast((~(1U << 14) & CCInfo) >> 1)); diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index b2898429239..aa878ea436e 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -263,14 +263,13 @@ void LandingPadInst::addClause(Constant *Val) { CallInst::~CallInst() { } -void CallInst::init(Value *Func, ArrayRef Args, const Twine &NameStr) { +void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef Args, + const Twine &NameStr) { + this->FTy = FTy; assert(NumOperands == Args.size() + 1 && "NumOperands not set up?"); Op<-1>() = Func; #ifndef NDEBUG - FunctionType *FTy = - cast(cast(Func->getType())->getElementType()); - assert((Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"); @@ -286,15 +285,12 @@ void CallInst::init(Value *Func, ArrayRef Args, const Twine &NameStr) { } void CallInst::init(Value *Func, const Twine &NameStr) { + FTy = + cast(cast(Func->getType())->getElementType()); assert(NumOperands == 1 && "NumOperands not set up?"); Op<-1>() = Func; -#ifndef NDEBUG - FunctionType *FTy = - cast(cast(Func->getType())->getElementType()); - assert(FTy->getNumParams() == 0 && "Calling a function with bad signature"); -#endif setName(NameStr); } @@ -320,10 +316,10 @@ CallInst::CallInst(Value *Func, const Twine &Name, } CallInst::CallInst(const CallInst &CI) - : Instruction(CI.getType(), Instruction::Call, - OperandTraits::op_end(this) - CI.getNumOperands(), - CI.getNumOperands()) { - setAttributes(CI.getAttributes()); + : Instruction(CI.getType(), Instruction::Call, + OperandTraits::op_end(this) - CI.getNumOperands(), + CI.getNumOperands()), + AttributeList(CI.AttributeList), FTy(CI.FTy) { setTailCallKind(CI.getTailCallKind()); setCallingConv(CI.getCallingConv()); @@ -543,15 +539,14 @@ Instruction* CallInst::CreateFree(Value* Source, BasicBlock *InsertAtEnd) { void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef Args, const Twine &NameStr) { + FTy = cast(cast(Fn->getType())->getElementType()); + assert(NumOperands == 3 + Args.size() && "NumOperands not set up?"); Op<-3>() = Fn; Op<-2>() = IfNormal; Op<-1>() = IfException; #ifndef NDEBUG - FunctionType *FTy = - cast(cast(Fn->getType())->getElementType()); - assert(((Args.size() == FTy->getNumParams()) || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Invoking a function with bad signature"); @@ -567,11 +562,11 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, } InvokeInst::InvokeInst(const InvokeInst &II) - : TerminatorInst(II.getType(), Instruction::Invoke, - OperandTraits::op_end(this) - - II.getNumOperands(), - II.getNumOperands()) { - setAttributes(II.getAttributes()); + : TerminatorInst(II.getType(), Instruction::Invoke, + OperandTraits::op_end(this) - + II.getNumOperands(), + II.getNumOperands()), + AttributeList(II.AttributeList), FTy(II.FTy) { setCallingConv(II.getCallingConv()); std::copy(II.op_begin(), II.op_end(), op_begin()); SubclassOptionalData = II.SubclassOptionalData; diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index e14f1036912..7001c556d20 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -2120,7 +2120,11 @@ void Verifier::VerifyCallSite(CallSite CS) { Assert(FPTy->getElementType()->isFunctionTy(), "Called function is not pointer to function type!", I); - FunctionType *FTy = cast(FPTy->getElementType()); + + Assert(FPTy->getElementType() == CS.getFunctionType(), + "Called function is not the same type as the call!", I); + + FunctionType *FTy = CS.getFunctionType(); // Verify that the correct number of arguments are being passed if (FTy->isVarArg()) diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index 54c76887234..a70d6d769b7 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/ValueMapper.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/InlineAsm.h" @@ -384,6 +385,16 @@ void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap, } // If the instruction's type is being remapped, do so now. - if (TypeMapper) + if (auto CS = CallSite(I)) { + SmallVector Tys; + FunctionType *Old = CS.getFunctionType(); + unsigned NumOld = Old->getNumParams(); + assert(NumOld <= CS.arg_size()); + for (unsigned i = 0; i != NumOld; ++i) + Tys.push_back(CS.getArgument(i)->getType()); + CS.mutateFunctionType(FunctionType::get( + TypeMapper ? TypeMapper->remapType(I->getType()) : I->getType(), Tys, + Old->isVarArg())); + } else if (TypeMapper) I->mutateType(TypeMapper->remapType(I->getType())); } diff --git a/lib/Transforms/Vectorize/BBVectorize.cpp b/lib/Transforms/Vectorize/BBVectorize.cpp index 29fb01f1b2e..6f0180e7db0 100644 --- a/lib/Transforms/Vectorize/BBVectorize.cpp +++ b/lib/Transforms/Vectorize/BBVectorize.cpp @@ -3103,7 +3103,17 @@ namespace { else if (H->hasName()) K->takeName(H); - if (!isa(K)) + if (auto CS = CallSite(K)) { + SmallVector Tys; + FunctionType *Old = CS.getFunctionType(); + unsigned NumOld = Old->getNumParams(); + assert(NumOld <= ReplacedOperands.size()); + for (unsigned i = 0; i != NumOld; ++i) + Tys.push_back(ReplacedOperands[i]->getType()); + CS.mutateFunctionType( + FunctionType::get(getVecTypeForPair(L->getType(), H->getType()), + Tys, Old->isVarArg())); + } else if (!isa(K)) K->mutateType(getVecTypeForPair(L->getType(), H->getType())); unsigned KnownIDs[] = {