Skip to content

Commit f47d6b3

Browse files
committed
[opaque pointer types] Add a FunctionCallee wrapper type, and use it.
The FunctionCallee type is effectively a {FunctionType*,Value*} pair, and is a useful convenience to enable code to continue passing the result of getOrInsertFunction() through to EmitCall, even once pointer types lose their pointee-type. Then: - update the CallInst/InvokeInst instruction creation functions to take a Callee, - modify getOrInsertFunction to return FunctionCallee, and - update all callers appropriately. One area of particular note is the change to the sanitizer code. Previously, they had been casting the result of `getOrInsertFunction` to a `Function*` via `checkSanitizerInterfaceFunction`, and storing that. That would report an error if someone had already inserted a function declaraction with a mismatching signature. However, in general, LLVM allows for such mismatches, as `getOrInsertFunction` will automatically insert a bitcast if needed. As part of this cleanup, cause the sanitizer code to do the same. (It will call its functions using the expected signature, however they may have been declared.) Finally, in a small number of locations, callers of `getOrInsertFunction` actually were expecting/requiring that a brand new function was being created. In such cases, I've switched them to Function::Create instead. Differential Revision: https://reviews.llvm.org/D57315 llvm-svn: 352791
1 parent e1b332e commit f47d6b3

File tree

70 files changed

+865
-897
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+865
-897
lines changed

clang/lib/CodeGen/CGExpr.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -3056,7 +3056,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
30563056
bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Kind);
30573057

30583058
llvm::CallInst *CheckCall;
3059-
llvm::Constant *SlowPathFn;
3059+
llvm::FunctionCallee SlowPathFn;
30603060
if (WithDiag) {
30613061
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
30623062
auto *InfoPtr =
@@ -3078,7 +3078,8 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
30783078
CheckCall = Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
30793079
}
30803080

3081-
CGM.setDSOLocal(cast<llvm::GlobalValue>(SlowPathFn->stripPointerCasts()));
3081+
CGM.setDSOLocal(
3082+
cast<llvm::GlobalValue>(SlowPathFn.getCallee()->stripPointerCasts()));
30823083
CheckCall->setDoesNotThrow();
30833084

30843085
EmitBlock(Cont);

llvm/docs/ProgrammersManual.rst

+11-5
Original file line numberDiff line numberDiff line change
@@ -3491,11 +3491,17 @@ Important Public Members of the ``Module`` class
34913491
Look up the specified function in the ``Module`` SymbolTable_. If it does not
34923492
exist, return ``null``.
34933493

3494-
* ``Function *getOrInsertFunction(const std::string &Name, const FunctionType
3495-
*T)``
3496-
3497-
Look up the specified function in the ``Module`` SymbolTable_. If it does not
3498-
exist, add an external declaration for the function and return it.
3494+
* ``FunctionCallee getOrInsertFunction(const std::string &Name,
3495+
const FunctionType *T)``
3496+
3497+
Look up the specified function in the ``Module`` SymbolTable_. If
3498+
it does not exist, add an external declaration for the function and
3499+
return it. Note that the function signature already present may not
3500+
match the requested signature. Thus, in order to enable the common
3501+
usage of passing the result directly to EmitCall, the return type is
3502+
a struct of ``{FunctionType *T, Constant *FunctionPtr}``, rather
3503+
than simply the ``Function*`` with potentially an unexpected
3504+
signature.
34993505

35003506
* ``std::string getTypeName(const Type *Ty)``
35013507

llvm/examples/BrainF/BrainF.cpp

+8-10
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,17 @@ void BrainF::header(LLVMContext& C) {
7272
Tys);
7373

7474
//declare i32 @getchar()
75-
getchar_func = cast<Function>(module->
76-
getOrInsertFunction("getchar", IntegerType::getInt32Ty(C)));
75+
getchar_func =
76+
module->getOrInsertFunction("getchar", IntegerType::getInt32Ty(C));
7777

7878
//declare i32 @putchar(i32)
79-
putchar_func = cast<Function>(module->
80-
getOrInsertFunction("putchar", IntegerType::getInt32Ty(C),
81-
IntegerType::getInt32Ty(C)));
79+
putchar_func = module->getOrInsertFunction(
80+
"putchar", IntegerType::getInt32Ty(C), IntegerType::getInt32Ty(C));
8281

8382
//Function header
8483

8584
//define void @brainf()
86-
brainf_func = cast<Function>(module->
87-
getOrInsertFunction("brainf", Type::getVoidTy(C)));
85+
brainf_func = module->getOrInsertFunction("brainf", Type::getVoidTy(C));
8886

8987
builder = new IRBuilder<>(BasicBlock::Create(C, label, brainf_func));
9088

@@ -153,9 +151,9 @@ void BrainF::header(LLVMContext& C) {
153151
"aberrormsg");
154152

155153
//declare i32 @puts(i8 *)
156-
Function *puts_func = cast<Function>(module->
157-
getOrInsertFunction("puts", IntegerType::getInt32Ty(C),
158-
PointerType::getUnqual(IntegerType::getInt8Ty(C))));
154+
FunctionCallee puts_func = module->getOrInsertFunction(
155+
"puts", IntegerType::getInt32Ty(C),
156+
PointerType::getUnqual(IntegerType::getInt8Ty(C)));
159157

160158
//brainf.aberror:
161159
aberrorbb = BasicBlock::Create(C, label, brainf_func);

llvm/examples/BrainF/BrainF.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ class BrainF {
7878
CompileFlags comflag;
7979
std::istream *in;
8080
Module *module;
81-
Function *brainf_func;
82-
Function *getchar_func;
83-
Function *putchar_func;
81+
FunctionCallee brainf_func;
82+
FunctionCallee getchar_func;
83+
FunctionCallee putchar_func;
8484
Value *ptr_arr;
8585
Value *ptr_arrmax;
8686
BasicBlock *endbb;

llvm/examples/BrainF/BrainFDriver.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ JIT("jit", cl::desc("Run program Just-In-Time"));
7272
//Add main function so can be fully compiled
7373
void addMainFunction(Module *mod) {
7474
//define i32 @main(i32 %argc, i8 **%argv)
75-
Function *main_func = cast<Function>(mod->
76-
getOrInsertFunction("main", IntegerType::getInt32Ty(mod->getContext()),
77-
IntegerType::getInt32Ty(mod->getContext()),
78-
PointerType::getUnqual(PointerType::getUnqual(
79-
IntegerType::getInt8Ty(mod->getContext())))));
75+
FunctionType *main_func_fty = FunctionType::get(
76+
Type::getInt32Ty(mod->getContext()),
77+
{Type::getInt32Ty(mod->getContext()),
78+
Type::getInt8Ty(mod->getContext())->getPointerTo()->getPointerTo()});
79+
Function *main_func =
80+
Function::create(main_func_fty, Function::ExternalLinkage, "main", mod);
81+
8082
{
8183
Function::arg_iterator args = main_func->arg_begin();
8284
Value *arg_0 = &*args++;

llvm/examples/Fibonacci/fibonacci.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ using namespace llvm;
5151
static Function *CreateFibFunction(Module *M, LLVMContext &Context) {
5252
// Create the fib function and insert it into module M. This function is said
5353
// to return an int and take an int parameter.
54+
FunctionType *FibFTy = FunctionType::get(Type::getInt32Ty(Context),
55+
{Type::getInt32Ty(Context)}, false);
5456
Function *FibF =
55-
cast<Function>(M->getOrInsertFunction("fib", Type::getInt32Ty(Context),
56-
Type::getInt32Ty(Context)));
57+
Function::Create(FibFTy, Function::ExternalLinkage, "fib", M);
5758

5859
// Add a basic block to the function.
5960
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", FibF);

llvm/examples/HowToUseJIT/HowToUseJIT.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ int main() {
6969
// Create the add1 function entry and insert this entry into module M. The
7070
// function will have a return type of "int" and take an argument of "int".
7171
Function *Add1F =
72-
cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context),
73-
Type::getInt32Ty(Context)));
72+
Function::Create(FunctionType::get(Type::getInt32Ty(Context),
73+
{Type::getInt32Ty(Context)}, false),
74+
Function::ExternalLinkage, "add1", M);
7475

7576
// Add a basic block to the function. As before, it automatically inserts
7677
// because of the last argument.
@@ -99,7 +100,8 @@ int main() {
99100
// Now we're going to create function `foo', which returns an int and takes no
100101
// arguments.
101102
Function *FooF =
102-
cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context)));
103+
Function::Create(FunctionType::get(Type::getInt32Ty(Context), {}, false),
104+
Function::ExternalLinkage, "foo", M);
103105

104106
// Add a basic block to the FooF function.
105107
BB = BasicBlock::Create(Context, "EntryBlock", FooF);

llvm/examples/ParallelJIT/ParallelJIT.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,10 @@ using namespace llvm;
4949
static Function* createAdd1(Module *M) {
5050
// Create the add1 function entry and insert this entry into module M. The
5151
// function will have a return type of "int" and take an argument of "int".
52-
// The '0' terminates the list of argument types.
5352
Function *Add1F =
54-
cast<Function>(M->getOrInsertFunction("add1",
55-
Type::getInt32Ty(M->getContext()),
56-
Type::getInt32Ty(M->getContext())));
53+
Function::Create(FunctionType::get(Type::getInt32Ty(Context),
54+
{Type::getInt32Ty(Context)}, false),
55+
Function::ExternalLinkage, "add1", M);
5756

5857
// Add a basic block to the function. As before, it automatically inserts
5958
// because of the last argument.
@@ -80,10 +79,10 @@ static Function* createAdd1(Module *M) {
8079
static Function *CreateFibFunction(Module *M) {
8180
// Create the fib function and insert it into module M. This function is said
8281
// to return an int and take an int parameter.
83-
Function *FibF =
84-
cast<Function>(M->getOrInsertFunction("fib",
85-
Type::getInt32Ty(M->getContext()),
86-
Type::getInt32Ty(M->getContext())));
82+
FunctionType *FibFTy = FunctionType::get(Type::getInt32Ty(Context),
83+
{Type::getInt32Ty(Context)}, false);
84+
Function *FibF =
85+
Function::Create(FibFTy, Function::ExternalLinkage, "fib", M);
8786

8887
// Add a basic block to the function.
8988
BasicBlock *BB = BasicBlock::Create(M->getContext(), "EntryBlock", FibF);

llvm/include/llvm/CodeGen/IntrinsicLowering.h

-4
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ class IntrinsicLowering {
3030
public:
3131
explicit IntrinsicLowering(const DataLayout &DL) : DL(DL), Warned(false) {}
3232

33-
/// Add all of the prototypes that might be needed by an intrinsic lowering
34-
/// implementation to be inserted into the module specified.
35-
void AddPrototypes(Module &M);
36-
3733
/// Replace a call to the specified intrinsic function.
3834
/// If an intrinsic function must be implemented by the code generator
3935
/// (such as va_start), this function should print a message and abort.

llvm/include/llvm/IR/DerivedTypes.h

+33
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,39 @@ unsigned Type::getFunctionNumParams() const {
157157
return cast<FunctionType>(this)->getNumParams();
158158
}
159159

160+
/// A handy container for a FunctionType+Callee-pointer pair, which can be
161+
/// passed around as a single entity. This assists in replacing the use of
162+
/// PointerType::getElementType() to access the function's type, since that's
163+
/// slated for removal as part of the [opaque pointer types] project.
164+
class FunctionCallee {
165+
public:
166+
// Allow implicit conversion from types which have a getFunctionType member
167+
// (e.g. Function and InlineAsm).
168+
template <typename T,
169+
typename U = std::enable_if<&T::getFunctionType != nullptr, void>>
170+
FunctionCallee(T *Fn)
171+
: FnTy(Fn ? Fn->getFunctionType() : nullptr), Callee(Fn) {}
172+
173+
FunctionCallee(FunctionType *FnTy, Value *Callee)
174+
: FnTy(FnTy), Callee(Callee) {
175+
assert((FnTy == nullptr) == (Callee == nullptr));
176+
}
177+
178+
FunctionCallee(std::nullptr_t) {}
179+
180+
FunctionCallee() = default;
181+
182+
FunctionType *getFunctionType() { return FnTy; }
183+
184+
Value *getCallee() { return Callee; }
185+
186+
explicit operator bool() { return Callee; }
187+
188+
private:
189+
FunctionType *FnTy = nullptr;
190+
Value *Callee = nullptr;
191+
};
192+
160193
/// Common super class of ArrayType, StructType and VectorType.
161194
class CompositeType : public Type {
162195
protected:

llvm/include/llvm/IR/IRBuilder.h

+12-11
Original file line numberDiff line numberDiff line change
@@ -905,20 +905,20 @@ class IRBuilder : public IRBuilderBase, public Inserter {
905905
Name);
906906
}
907907

908-
InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest,
908+
InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest,
909909
BasicBlock *UnwindDest, ArrayRef<Value *> Args,
910910
ArrayRef<OperandBundleDef> OpBundles,
911911
const Twine &Name = "") {
912-
return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest,
913-
UnwindDest, Args, OpBundles, Name);
912+
return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(),
913+
NormalDest, UnwindDest, Args, OpBundles, Name);
914914
}
915915

916-
InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest,
916+
InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest,
917917
BasicBlock *UnwindDest,
918918
ArrayRef<Value *> Args = None,
919919
const Twine &Name = "") {
920-
return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest,
921-
UnwindDest, Args, Name);
920+
return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(),
921+
NormalDest, UnwindDest, Args, Name);
922922
}
923923

924924
// Deprecated [opaque pointer types]
@@ -1988,16 +1988,17 @@ class IRBuilder : public IRBuilderBase, public Inserter {
19881988
return Insert(CI, Name);
19891989
}
19901990

1991-
CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args = None,
1991+
CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = None,
19921992
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
1993-
return CreateCall(Callee->getFunctionType(), Callee, Args, Name, FPMathTag);
1993+
return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args, Name,
1994+
FPMathTag);
19941995
}
19951996

1996-
CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args,
1997+
CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args,
19971998
ArrayRef<OperandBundleDef> OpBundles,
19981999
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
1999-
return CreateCall(Callee->getFunctionType(), Callee, Args, OpBundles, Name,
2000-
FPMathTag);
2000+
return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args,
2001+
OpBundles, Name, FPMathTag);
20012002
}
20022003

20032004
// Deprecated [opaque pointer types]

llvm/include/llvm/IR/InstrTypes.h

+5
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,11 @@ class CallBase : public Instruction {
12321232
Fn);
12331233
}
12341234

1235+
/// Sets the function called, including updating the function type.
1236+
void setCalledFunction(FunctionCallee Fn) {
1237+
setCalledFunction(Fn.getFunctionType(), Fn.getCallee());
1238+
}
1239+
12351240
/// Sets the function called, including updating to the specified function
12361241
/// type.
12371242
void setCalledFunction(FunctionType *FTy, Value *Fn) {

llvm/include/llvm/IR/Instructions.h

+39-20
Original file line numberDiff line numberDiff line change
@@ -1543,25 +1543,44 @@ class CallInst : public CallBase {
15431543
CallInst(Ty, Func, Args, Bundles, NameStr, InsertAtEnd);
15441544
}
15451545

1546-
static CallInst *Create(Function *Func, const Twine &NameStr = "",
1546+
static CallInst *Create(FunctionCallee Func, const Twine &NameStr = "",
15471547
Instruction *InsertBefore = nullptr) {
1548-
return Create(Func->getFunctionType(), Func, NameStr, InsertBefore);
1548+
return Create(Func.getFunctionType(), Func.getCallee(), NameStr,
1549+
InsertBefore);
15491550
}
15501551

1551-
static CallInst *Create(Function *Func, ArrayRef<Value *> Args,
1552+
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
1553+
ArrayRef<OperandBundleDef> Bundles = None,
15521554
const Twine &NameStr = "",
15531555
Instruction *InsertBefore = nullptr) {
1554-
return Create(Func->getFunctionType(), Func, Args, NameStr, InsertBefore);
1556+
return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles,
1557+
NameStr, InsertBefore);
1558+
}
1559+
1560+
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
1561+
const Twine &NameStr,
1562+
Instruction *InsertBefore = nullptr) {
1563+
return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr,
1564+
InsertBefore);
15551565
}
15561566

1557-
static CallInst *Create(Function *Func, const Twine &NameStr,
1567+
static CallInst *Create(FunctionCallee Func, const Twine &NameStr,
15581568
BasicBlock *InsertAtEnd) {
1559-
return Create(Func->getFunctionType(), Func, NameStr, InsertAtEnd);
1569+
return Create(Func.getFunctionType(), Func.getCallee(), NameStr,
1570+
InsertAtEnd);
15601571
}
15611572

1562-
static CallInst *Create(Function *Func, ArrayRef<Value *> Args,
1573+
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
15631574
const Twine &NameStr, BasicBlock *InsertAtEnd) {
1564-
return Create(Func->getFunctionType(), Func, Args, NameStr, InsertAtEnd);
1575+
return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr,
1576+
InsertAtEnd);
1577+
}
1578+
1579+
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
1580+
ArrayRef<OperandBundleDef> Bundles,
1581+
const Twine &NameStr, BasicBlock *InsertAtEnd) {
1582+
return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles,
1583+
NameStr, InsertAtEnd);
15651584
}
15661585

15671586
// Deprecated [opaque pointer types]
@@ -3704,36 +3723,36 @@ class InvokeInst : public CallBase {
37043723
NameStr, InsertAtEnd);
37053724
}
37063725

3707-
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
3726+
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
37083727
BasicBlock *IfException, ArrayRef<Value *> Args,
37093728
const Twine &NameStr,
37103729
Instruction *InsertBefore = nullptr) {
3711-
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
3712-
None, NameStr, InsertBefore);
3730+
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
3731+
IfException, Args, None, NameStr, InsertBefore);
37133732
}
37143733

3715-
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
3734+
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
37163735
BasicBlock *IfException, ArrayRef<Value *> Args,
37173736
ArrayRef<OperandBundleDef> Bundles = None,
37183737
const Twine &NameStr = "",
37193738
Instruction *InsertBefore = nullptr) {
3720-
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
3721-
Bundles, NameStr, InsertBefore);
3739+
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
3740+
IfException, Args, Bundles, NameStr, InsertBefore);
37223741
}
37233742

3724-
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
3743+
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
37253744
BasicBlock *IfException, ArrayRef<Value *> Args,
37263745
const Twine &NameStr, BasicBlock *InsertAtEnd) {
3727-
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
3728-
NameStr, InsertAtEnd);
3746+
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
3747+
IfException, Args, NameStr, InsertAtEnd);
37293748
}
37303749

3731-
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
3750+
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
37323751
BasicBlock *IfException, ArrayRef<Value *> Args,
37333752
ArrayRef<OperandBundleDef> Bundles,
37343753
const Twine &NameStr, BasicBlock *InsertAtEnd) {
3735-
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
3736-
Bundles, NameStr, InsertAtEnd);
3754+
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
3755+
IfException, Args, Bundles, NameStr, InsertAtEnd);
37373756
}
37383757

37393758
// Deprecated [opaque pointer types]

0 commit comments

Comments
 (0)