Skip to content

Commit

Permalink
[opaque pointer types] Update CallInst creation APIs to consistently
Browse files Browse the repository at this point in the history
accept a callee-type argument.

Note: this also adds a new C API and soft-deprecates the old C API.

Differential Revision: https://reviews.llvm.org/D56556

llvm-svn: 351121
  • Loading branch information
jyknight committed Jan 14, 2019
1 parent 93bfb99 commit f956390
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 80 deletions.
12 changes: 12 additions & 0 deletions llvm/include/llvm-c/Core.h
Expand Up @@ -3099,6 +3099,13 @@ void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
void LLVMRemoveCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
const char *K, unsigned KLen);

/**
* Obtain the function type called by this instruction.
*
* @see llvm::CallBase::getFunctionType()
*/
LLVMTypeRef LLVMGetCalledFunctionType(LLVMValueRef C);

/**
* Obtain the pointer to the function invoked by this instruction.
*
Expand Down Expand Up @@ -3661,9 +3668,14 @@ LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef, LLVMRealPredicate Op,

/* Miscellaneous instructions */
LLVMValueRef LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
// LLVMBuildCall is deprecated in favor of LLVMBuildCall2, in preparation for
// opaque pointer types.
LLVMValueRef LLVMBuildCall(LLVMBuilderRef, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
const char *Name);
LLVMValueRef LLVMBuildCall2(LLVMBuilderRef, LLVMTypeRef, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
const char *Name);
LLVMValueRef LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef If,
LLVMValueRef Then, LLVMValueRef Else,
const char *Name);
Expand Down
39 changes: 28 additions & 11 deletions llvm/include/llvm/IR/IRBuilder.h
Expand Up @@ -1880,36 +1880,53 @@ class IRBuilder : public IRBuilderBase, public Inserter {
return Insert(PHINode::Create(Ty, NumReservedValues), Name);
}

CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
auto *PTy = cast<PointerType>(Callee->getType());
auto *FTy = cast<FunctionType>(PTy->getElementType());
return CreateCall(FTy, Callee, Args, Name, FPMathTag);
}

CallInst *CreateCall(FunctionType *FTy, Value *Callee,
ArrayRef<Value *> Args, const Twine &Name = "",
ArrayRef<Value *> Args = None, const Twine &Name = "",
MDNode *FPMathTag = nullptr) {
CallInst *CI = CallInst::Create(FTy, Callee, Args, DefaultOperandBundles);
if (isa<FPMathOperator>(CI))
CI = cast<CallInst>(setFPAttrs(CI, FPMathTag, FMF));
return Insert(CI, Name);
}

CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
CallInst *CreateCall(FunctionType *FTy, Value *Callee, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> OpBundles,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
CallInst *CI = CallInst::Create(Callee, Args, OpBundles);
CallInst *CI = CallInst::Create(FTy, Callee, Args, OpBundles);
if (isa<FPMathOperator>(CI))
CI = cast<CallInst>(setFPAttrs(CI, FPMathTag, FMF));
return Insert(CI, Name);
}

CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args,
CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args = None,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
return CreateCall(Callee->getFunctionType(), Callee, Args, Name, FPMathTag);
}

CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> OpBundles,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
return CreateCall(Callee->getFunctionType(), Callee, Args, OpBundles, Name,
FPMathTag);
}

// Deprecated [opaque pointer types]
CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
return CreateCall(
cast<FunctionType>(Callee->getType()->getPointerElementType()), Callee,
Args, Name, FPMathTag);
}

// Deprecated [opaque pointer types]
CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> OpBundles,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
return CreateCall(
cast<FunctionType>(Callee->getType()->getPointerElementType()), Callee,
Args, OpBundles, Name, FPMathTag);
}

Value *CreateSelect(Value *C, Value *True, Value *False,
const Twine &Name = "", Instruction *MDFrom = nullptr) {
if (auto *CC = dyn_cast<Constant>(C))
Expand Down
140 changes: 91 additions & 49 deletions llvm/include/llvm/IR/Instructions.h
Expand Up @@ -1433,36 +1433,25 @@ class CallInst : public CallBase {
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
Instruction *InsertBefore);

inline CallInst(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
Instruction *InsertBefore)
: CallInst(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, Bundles, NameStr, InsertBefore) {}

inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr,
Instruction *InsertBefore)
: CallInst(Func, Args, None, NameStr, InsertBefore) {}
inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, Instruction *InsertBefore)
: CallInst(Ty, Func, Args, None, NameStr, InsertBefore) {}

/// Construct a CallInst given a range of arguments.
/// Construct a CallInst from a range of arguments
inline CallInst(Value *Func, ArrayRef<Value *> Args,
inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
BasicBlock *InsertAtEnd);

explicit CallInst(Value *F, const Twine &NameStr, Instruction *InsertBefore);
explicit CallInst(FunctionType *Ty, Value *F, const Twine &NameStr,
Instruction *InsertBefore);

CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd);
CallInst(FunctionType *ty, Value *F, const Twine &NameStr,
BasicBlock *InsertAtEnd);

void init(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr) {
init(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, Bundles, NameStr);
}
void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
void init(Value *Func, const Twine &NameStr);
void init(FunctionType *FTy, Value *Func, const Twine &NameStr);

/// Compute the number of operands to allocate.
static int ComputeNumOperands(int NumArgs, int NumBundleInputs = 0) {
Expand All @@ -1478,21 +1467,9 @@ class CallInst : public CallBase {
CallInst *cloneImpl() const;

public:
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = None,
const Twine &NameStr = "",
static CallInst *Create(FunctionType *Ty, Value *F, const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
return Create(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, Bundles, NameStr, InsertBefore);
}

static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr,
Instruction *InsertBefore = nullptr) {
return Create(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, None, NameStr, InsertBefore);
return new (ComputeNumOperands(0)) CallInst(Ty, F, NameStr, InsertBefore);
}

static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
Expand All @@ -1514,31 +1491,99 @@ class CallInst : public CallBase {
CallInst(Ty, Func, Args, Bundles, NameStr, InsertBefore);
}

static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
static CallInst *Create(FunctionType *Ty, Value *F, const Twine &NameStr,
BasicBlock *InsertAtEnd) {
return new (ComputeNumOperands(0)) CallInst(Ty, F, NameStr, InsertAtEnd);
}

static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new (ComputeNumOperands(Args.size()))
CallInst(Ty, Func, Args, None, NameStr, InsertAtEnd);
}

static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
const int NumOperands =
ComputeNumOperands(Args.size(), CountBundleInputs(Bundles));
const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo);

return new (NumOperands, DescriptorBytes)
CallInst(Func, Args, Bundles, NameStr, InsertAtEnd);
CallInst(Ty, Func, Args, Bundles, NameStr, InsertAtEnd);
}

static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
static CallInst *Create(Function *Func, const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
return Create(Func->getFunctionType(), Func, NameStr, InsertBefore);
}

static CallInst *Create(Function *Func, ArrayRef<Value *> Args,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
return Create(Func->getFunctionType(), Func, Args, NameStr, InsertBefore);
}

static CallInst *Create(Function *Func, const Twine &NameStr,
BasicBlock *InsertAtEnd) {
return Create(Func->getFunctionType(), Func, NameStr, InsertAtEnd);
}

static CallInst *Create(Function *Func, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new (ComputeNumOperands(Args.size()))
CallInst(Func, Args, None, NameStr, InsertAtEnd);
return Create(Func->getFunctionType(), Func, Args, NameStr, InsertAtEnd);
}

static CallInst *Create(Value *F, const Twine &NameStr = "",
// Deprecated [opaque pointer types]
static CallInst *Create(Value *Func, const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
return new (ComputeNumOperands(0)) CallInst(F, NameStr, InsertBefore);
return Create(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, NameStr, InsertBefore);
}

// Deprecated [opaque pointer types]
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr,
Instruction *InsertBefore = nullptr) {
return Create(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, NameStr, InsertBefore);
}

static CallInst *Create(Value *F, const Twine &NameStr,
// Deprecated [opaque pointer types]
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = None,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
return Create(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, Bundles, NameStr, InsertBefore);
}

// Deprecated [opaque pointer types]
static CallInst *Create(Value *Func, const Twine &NameStr,
BasicBlock *InsertAtEnd) {
return new (ComputeNumOperands(0)) CallInst(F, NameStr, InsertAtEnd);
return Create(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, NameStr, InsertAtEnd);
}

// Deprecated [opaque pointer types]
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return Create(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, NameStr, InsertAtEnd);
}

// Deprecated [opaque pointer types]
static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return Create(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType()),
Func, Args, Bundles, NameStr, InsertAtEnd);
}

/// Create a clone of \p CI with a different set of operand bundles and
Expand Down Expand Up @@ -1647,18 +1692,15 @@ class CallInst : public CallBase {
}
};

CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
BasicBlock *InsertAtEnd)
: CallBase(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType())
->getReturnType(),
Instruction::Call,
: CallBase(Ty->getReturnType(), Instruction::Call,
OperandTraits<CallBase>::op_end(this) -
(Args.size() + CountBundleInputs(Bundles) + 1),
unsigned(Args.size() + CountBundleInputs(Bundles) + 1),
InsertAtEnd) {
init(Func, Args, Bundles, NameStr);
init(Ty, Func, Args, Bundles, NameStr);
}

CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/IR/Module.h
Expand Up @@ -367,6 +367,11 @@ class Module {
return getOrInsertFunction(Name, AttributeList{}, RetTy, Args...);
}

// Avoid an incorrect ordering that'd otherwise compile incorrectly.
template <typename... ArgsTy>
Constant *getOrInsertFunction(StringRef Name, AttributeList AttributeList,
FunctionType *Invalid, ArgsTy... Args) = delete;

/// Look up the specified function in the module symbol table. If it does not
/// exist, return null.
Function *getFunction(StringRef Name) const;
Expand Down
21 changes: 18 additions & 3 deletions llvm/lib/IR/Core.cpp
Expand Up @@ -2728,6 +2728,10 @@ LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr) {
return wrap(unwrap<CallBase>(Instr)->getCalledValue());
}

LLVMTypeRef LLVMGetCalledFunctionType(LLVMValueRef Instr) {
return wrap(unwrap<CallBase>(Instr)->getFunctionType());
}

/*--.. Operations on call instructions (only) ..............................--*/

LLVMBool LLVMIsTailCall(LLVMValueRef Call) {
Expand Down Expand Up @@ -3582,9 +3586,20 @@ LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) {
LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
const char *Name) {
return wrap(unwrap(B)->CreateCall(unwrap(Fn),
makeArrayRef(unwrap(Args), NumArgs),
Name));
Value *V = unwrap(Fn);
FunctionType *FnT =
cast<FunctionType>(cast<PointerType>(V->getType())->getElementType());

return wrap(unwrap(B)->CreateCall(FnT, unwrap(Fn),
makeArrayRef(unwrap(Args), NumArgs), Name));
}

LLVMValueRef LLVMBuildCall2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
const char *Name) {
FunctionType *FTy = unwrap<FunctionType>(Ty);
return wrap(unwrap(B)->CreateCall(FTy, unwrap(Fn),
makeArrayRef(unwrap(Args), NumArgs), Name));
}

LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If,
Expand Down
29 changes: 12 additions & 17 deletions llvm/lib/IR/Instructions.cpp
Expand Up @@ -388,9 +388,8 @@ void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
setName(NameStr);
}

void CallInst::init(Value *Func, const Twine &NameStr) {
FTy =
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
void CallInst::init(FunctionType *FTy, Value *Func, const Twine &NameStr) {
this->FTy = FTy;
assert(getNumOperands() == 1 && "NumOperands not set up?");
setCalledOperand(Func);

Expand All @@ -399,22 +398,18 @@ void CallInst::init(Value *Func, const Twine &NameStr) {
setName(NameStr);
}

CallInst::CallInst(Value *Func, const Twine &Name, Instruction *InsertBefore)
: CallBase(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType())
->getReturnType(),
Instruction::Call, OperandTraits<CallBase>::op_end(this) - 1, 1,
InsertBefore) {
init(Func, Name);
CallInst::CallInst(FunctionType *Ty, Value *Func, const Twine &Name,
Instruction *InsertBefore)
: CallBase(Ty->getReturnType(), Instruction::Call,
OperandTraits<CallBase>::op_end(this) - 1, 1, InsertBefore) {
init(Ty, Func, Name);
}

CallInst::CallInst(Value *Func, const Twine &Name, BasicBlock *InsertAtEnd)
: CallBase(cast<FunctionType>(
cast<PointerType>(Func->getType())->getElementType())
->getReturnType(),
Instruction::Call, OperandTraits<CallBase>::op_end(this) - 1, 1,
InsertAtEnd) {
init(Func, Name);
CallInst::CallInst(FunctionType *Ty, Value *Func, const Twine &Name,
BasicBlock *InsertAtEnd)
: CallBase(Ty->getReturnType(), Instruction::Call,
OperandTraits<CallBase>::op_end(this) - 1, 1, InsertAtEnd) {
init(Ty, Func, Name);
}

CallInst::CallInst(const CallInst &CI)
Expand Down

0 comments on commit f956390

Please sign in to comment.