You've already forked llvm-project
mirror of
https://github.com/encounter/llvm-project.git
synced 2026-03-30 11:27:19 -07:00
[opaque pointer types] Add a FunctionCallee wrapper type, and use it.
Recommit r352791 after tweaking DerivedTypes.h slightly, so that gcc
doesn't choke on it, hopefully.
Original Message:
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: 352827
This commit is contained in:
@@ -3056,7 +3056,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
|
||||
bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Kind);
|
||||
|
||||
llvm::CallInst *CheckCall;
|
||||
llvm::Constant *SlowPathFn;
|
||||
llvm::FunctionCallee SlowPathFn;
|
||||
if (WithDiag) {
|
||||
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
|
||||
auto *InfoPtr =
|
||||
@@ -3078,7 +3078,8 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
|
||||
CheckCall = Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
|
||||
}
|
||||
|
||||
CGM.setDSOLocal(cast<llvm::GlobalValue>(SlowPathFn->stripPointerCasts()));
|
||||
CGM.setDSOLocal(
|
||||
cast<llvm::GlobalValue>(SlowPathFn.getCallee()->stripPointerCasts()));
|
||||
CheckCall->setDoesNotThrow();
|
||||
|
||||
EmitBlock(Cont);
|
||||
|
||||
@@ -3491,11 +3491,17 @@ Important Public Members of the ``Module`` class
|
||||
Look up the specified function in the ``Module`` SymbolTable_. If it does not
|
||||
exist, return ``null``.
|
||||
|
||||
* ``Function *getOrInsertFunction(const std::string &Name, const FunctionType
|
||||
*T)``
|
||||
* ``FunctionCallee getOrInsertFunction(const std::string &Name,
|
||||
const FunctionType *T)``
|
||||
|
||||
Look up the specified function in the ``Module`` SymbolTable_. If it does not
|
||||
exist, add an external declaration for the function and return it.
|
||||
Look up the specified function in the ``Module`` SymbolTable_. If
|
||||
it does not exist, add an external declaration for the function and
|
||||
return it. Note that the function signature already present may not
|
||||
match the requested signature. Thus, in order to enable the common
|
||||
usage of passing the result directly to EmitCall, the return type is
|
||||
a struct of ``{FunctionType *T, Constant *FunctionPtr}``, rather
|
||||
than simply the ``Function*`` with potentially an unexpected
|
||||
signature.
|
||||
|
||||
* ``std::string getTypeName(const Type *Ty)``
|
||||
|
||||
|
||||
@@ -72,19 +72,17 @@ void BrainF::header(LLVMContext& C) {
|
||||
Tys);
|
||||
|
||||
//declare i32 @getchar()
|
||||
getchar_func = cast<Function>(module->
|
||||
getOrInsertFunction("getchar", IntegerType::getInt32Ty(C)));
|
||||
getchar_func =
|
||||
module->getOrInsertFunction("getchar", IntegerType::getInt32Ty(C));
|
||||
|
||||
//declare i32 @putchar(i32)
|
||||
putchar_func = cast<Function>(module->
|
||||
getOrInsertFunction("putchar", IntegerType::getInt32Ty(C),
|
||||
IntegerType::getInt32Ty(C)));
|
||||
putchar_func = module->getOrInsertFunction(
|
||||
"putchar", IntegerType::getInt32Ty(C), IntegerType::getInt32Ty(C));
|
||||
|
||||
//Function header
|
||||
|
||||
//define void @brainf()
|
||||
brainf_func = cast<Function>(module->
|
||||
getOrInsertFunction("brainf", Type::getVoidTy(C)));
|
||||
brainf_func = module->getOrInsertFunction("brainf", Type::getVoidTy(C));
|
||||
|
||||
builder = new IRBuilder<>(BasicBlock::Create(C, label, brainf_func));
|
||||
|
||||
@@ -153,9 +151,9 @@ void BrainF::header(LLVMContext& C) {
|
||||
"aberrormsg");
|
||||
|
||||
//declare i32 @puts(i8 *)
|
||||
Function *puts_func = cast<Function>(module->
|
||||
getOrInsertFunction("puts", IntegerType::getInt32Ty(C),
|
||||
PointerType::getUnqual(IntegerType::getInt8Ty(C))));
|
||||
FunctionCallee puts_func = module->getOrInsertFunction(
|
||||
"puts", IntegerType::getInt32Ty(C),
|
||||
PointerType::getUnqual(IntegerType::getInt8Ty(C)));
|
||||
|
||||
//brainf.aberror:
|
||||
aberrorbb = BasicBlock::Create(C, label, brainf_func);
|
||||
|
||||
@@ -78,9 +78,9 @@ class BrainF {
|
||||
CompileFlags comflag;
|
||||
std::istream *in;
|
||||
Module *module;
|
||||
Function *brainf_func;
|
||||
Function *getchar_func;
|
||||
Function *putchar_func;
|
||||
FunctionCallee brainf_func;
|
||||
FunctionCallee getchar_func;
|
||||
FunctionCallee putchar_func;
|
||||
Value *ptr_arr;
|
||||
Value *ptr_arrmax;
|
||||
BasicBlock *endbb;
|
||||
|
||||
@@ -72,11 +72,13 @@ JIT("jit", cl::desc("Run program Just-In-Time"));
|
||||
//Add main function so can be fully compiled
|
||||
void addMainFunction(Module *mod) {
|
||||
//define i32 @main(i32 %argc, i8 **%argv)
|
||||
Function *main_func = cast<Function>(mod->
|
||||
getOrInsertFunction("main", IntegerType::getInt32Ty(mod->getContext()),
|
||||
IntegerType::getInt32Ty(mod->getContext()),
|
||||
PointerType::getUnqual(PointerType::getUnqual(
|
||||
IntegerType::getInt8Ty(mod->getContext())))));
|
||||
FunctionType *main_func_fty = FunctionType::get(
|
||||
Type::getInt32Ty(mod->getContext()),
|
||||
{Type::getInt32Ty(mod->getContext()),
|
||||
Type::getInt8Ty(mod->getContext())->getPointerTo()->getPointerTo()});
|
||||
Function *main_func =
|
||||
Function::create(main_func_fty, Function::ExternalLinkage, "main", mod);
|
||||
|
||||
{
|
||||
Function::arg_iterator args = main_func->arg_begin();
|
||||
Value *arg_0 = &*args++;
|
||||
|
||||
@@ -51,9 +51,10 @@ using namespace llvm;
|
||||
static Function *CreateFibFunction(Module *M, LLVMContext &Context) {
|
||||
// Create the fib function and insert it into module M. This function is said
|
||||
// to return an int and take an int parameter.
|
||||
FunctionType *FibFTy = FunctionType::get(Type::getInt32Ty(Context),
|
||||
{Type::getInt32Ty(Context)}, false);
|
||||
Function *FibF =
|
||||
cast<Function>(M->getOrInsertFunction("fib", Type::getInt32Ty(Context),
|
||||
Type::getInt32Ty(Context)));
|
||||
Function::Create(FibFTy, Function::ExternalLinkage, "fib", M);
|
||||
|
||||
// Add a basic block to the function.
|
||||
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", FibF);
|
||||
|
||||
@@ -69,8 +69,9 @@ int main() {
|
||||
// Create the add1 function entry and insert this entry into module M. The
|
||||
// function will have a return type of "int" and take an argument of "int".
|
||||
Function *Add1F =
|
||||
cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context),
|
||||
Type::getInt32Ty(Context)));
|
||||
Function::Create(FunctionType::get(Type::getInt32Ty(Context),
|
||||
{Type::getInt32Ty(Context)}, false),
|
||||
Function::ExternalLinkage, "add1", M);
|
||||
|
||||
// Add a basic block to the function. As before, it automatically inserts
|
||||
// because of the last argument.
|
||||
@@ -99,7 +100,8 @@ int main() {
|
||||
// Now we're going to create function `foo', which returns an int and takes no
|
||||
// arguments.
|
||||
Function *FooF =
|
||||
cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context)));
|
||||
Function::Create(FunctionType::get(Type::getInt32Ty(Context), {}, false),
|
||||
Function::ExternalLinkage, "foo", M);
|
||||
|
||||
// Add a basic block to the FooF function.
|
||||
BB = BasicBlock::Create(Context, "EntryBlock", FooF);
|
||||
|
||||
@@ -49,11 +49,10 @@ using namespace llvm;
|
||||
static Function* createAdd1(Module *M) {
|
||||
// Create the add1 function entry and insert this entry into module M. The
|
||||
// function will have a return type of "int" and take an argument of "int".
|
||||
// The '0' terminates the list of argument types.
|
||||
Function *Add1F =
|
||||
cast<Function>(M->getOrInsertFunction("add1",
|
||||
Type::getInt32Ty(M->getContext()),
|
||||
Type::getInt32Ty(M->getContext())));
|
||||
Function::Create(FunctionType::get(Type::getInt32Ty(Context),
|
||||
{Type::getInt32Ty(Context)}, false),
|
||||
Function::ExternalLinkage, "add1", M);
|
||||
|
||||
// Add a basic block to the function. As before, it automatically inserts
|
||||
// because of the last argument.
|
||||
@@ -80,10 +79,10 @@ static Function* createAdd1(Module *M) {
|
||||
static Function *CreateFibFunction(Module *M) {
|
||||
// Create the fib function and insert it into module M. This function is said
|
||||
// to return an int and take an int parameter.
|
||||
Function *FibF =
|
||||
cast<Function>(M->getOrInsertFunction("fib",
|
||||
Type::getInt32Ty(M->getContext()),
|
||||
Type::getInt32Ty(M->getContext())));
|
||||
FunctionType *FibFTy = FunctionType::get(Type::getInt32Ty(Context),
|
||||
{Type::getInt32Ty(Context)}, false);
|
||||
Function *FibF =
|
||||
Function::Create(FibFTy, Function::ExternalLinkage, "fib", M);
|
||||
|
||||
// Add a basic block to the function.
|
||||
BasicBlock *BB = BasicBlock::Create(M->getContext(), "EntryBlock", FibF);
|
||||
|
||||
@@ -30,10 +30,6 @@ class IntrinsicLowering {
|
||||
public:
|
||||
explicit IntrinsicLowering(const DataLayout &DL) : DL(DL), Warned(false) {}
|
||||
|
||||
/// Add all of the prototypes that might be needed by an intrinsic lowering
|
||||
/// implementation to be inserted into the module specified.
|
||||
void AddPrototypes(Module &M);
|
||||
|
||||
/// Replace a call to the specified intrinsic function.
|
||||
/// If an intrinsic function must be implemented by the code generator
|
||||
/// (such as va_start), this function should print a message and abort.
|
||||
|
||||
@@ -157,6 +157,38 @@ unsigned Type::getFunctionNumParams() const {
|
||||
return cast<FunctionType>(this)->getNumParams();
|
||||
}
|
||||
|
||||
/// A handy container for a FunctionType+Callee-pointer pair, which can be
|
||||
/// passed around as a single entity. This assists in replacing the use of
|
||||
/// PointerType::getElementType() to access the function's type, since that's
|
||||
/// slated for removal as part of the [opaque pointer types] project.
|
||||
class FunctionCallee {
|
||||
public:
|
||||
// Allow implicit conversion from types which have a getFunctionType member
|
||||
// (e.g. Function and InlineAsm).
|
||||
template <typename T, typename U = decltype(&T::getFunctionType)>
|
||||
FunctionCallee(T *Fn)
|
||||
: FnTy(Fn ? Fn->getFunctionType() : nullptr), Callee(Fn) {}
|
||||
|
||||
FunctionCallee(FunctionType *FnTy, Value *Callee)
|
||||
: FnTy(FnTy), Callee(Callee) {
|
||||
assert((FnTy == nullptr) == (Callee == nullptr));
|
||||
}
|
||||
|
||||
FunctionCallee(std::nullptr_t) {}
|
||||
|
||||
FunctionCallee() = default;
|
||||
|
||||
FunctionType *getFunctionType() { return FnTy; }
|
||||
|
||||
Value *getCallee() { return Callee; }
|
||||
|
||||
explicit operator bool() { return Callee; }
|
||||
|
||||
private:
|
||||
FunctionType *FnTy = nullptr;
|
||||
Value *Callee = nullptr;
|
||||
};
|
||||
|
||||
/// Common super class of ArrayType, StructType and VectorType.
|
||||
class CompositeType : public Type {
|
||||
protected:
|
||||
|
||||
@@ -905,20 +905,20 @@ public:
|
||||
Name);
|
||||
}
|
||||
|
||||
InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest,
|
||||
InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest,
|
||||
BasicBlock *UnwindDest, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> OpBundles,
|
||||
const Twine &Name = "") {
|
||||
return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest,
|
||||
UnwindDest, Args, OpBundles, Name);
|
||||
return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(),
|
||||
NormalDest, UnwindDest, Args, OpBundles, Name);
|
||||
}
|
||||
|
||||
InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest,
|
||||
InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest,
|
||||
BasicBlock *UnwindDest,
|
||||
ArrayRef<Value *> Args = None,
|
||||
const Twine &Name = "") {
|
||||
return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest,
|
||||
UnwindDest, Args, Name);
|
||||
return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(),
|
||||
NormalDest, UnwindDest, Args, Name);
|
||||
}
|
||||
|
||||
// Deprecated [opaque pointer types]
|
||||
@@ -1988,16 +1988,17 @@ public:
|
||||
return Insert(CI, Name);
|
||||
}
|
||||
|
||||
CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args = None,
|
||||
CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = None,
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
|
||||
return CreateCall(Callee->getFunctionType(), Callee, Args, Name, FPMathTag);
|
||||
return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args, Name,
|
||||
FPMathTag);
|
||||
}
|
||||
|
||||
CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args,
|
||||
CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> OpBundles,
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
|
||||
return CreateCall(Callee->getFunctionType(), Callee, Args, OpBundles, Name,
|
||||
FPMathTag);
|
||||
return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args,
|
||||
OpBundles, Name, FPMathTag);
|
||||
}
|
||||
|
||||
// Deprecated [opaque pointer types]
|
||||
|
||||
@@ -1232,6 +1232,11 @@ public:
|
||||
Fn);
|
||||
}
|
||||
|
||||
/// Sets the function called, including updating the function type.
|
||||
void setCalledFunction(FunctionCallee Fn) {
|
||||
setCalledFunction(Fn.getFunctionType(), Fn.getCallee());
|
||||
}
|
||||
|
||||
/// Sets the function called, including updating to the specified function
|
||||
/// type.
|
||||
void setCalledFunction(FunctionType *FTy, Value *Fn) {
|
||||
|
||||
@@ -1543,25 +1543,44 @@ public:
|
||||
CallInst(Ty, Func, Args, Bundles, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
static CallInst *Create(Function *Func, const Twine &NameStr = "",
|
||||
static CallInst *Create(FunctionCallee Func, const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func->getFunctionType(), Func, NameStr, InsertBefore);
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), NameStr,
|
||||
InsertBefore);
|
||||
}
|
||||
|
||||
static CallInst *Create(Function *Func, ArrayRef<Value *> Args,
|
||||
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> Bundles = None,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func->getFunctionType(), Func, Args, NameStr, InsertBefore);
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles,
|
||||
NameStr, InsertBefore);
|
||||
}
|
||||
|
||||
static CallInst *Create(Function *Func, const Twine &NameStr,
|
||||
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr,
|
||||
InsertBefore);
|
||||
}
|
||||
|
||||
static CallInst *Create(FunctionCallee Func, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return Create(Func->getFunctionType(), Func, NameStr, InsertAtEnd);
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), NameStr,
|
||||
InsertAtEnd);
|
||||
}
|
||||
|
||||
static CallInst *Create(Function *Func, ArrayRef<Value *> Args,
|
||||
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd) {
|
||||
return Create(Func->getFunctionType(), Func, Args, NameStr, InsertAtEnd);
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr,
|
||||
InsertAtEnd);
|
||||
}
|
||||
|
||||
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> Bundles,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles,
|
||||
NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
// Deprecated [opaque pointer types]
|
||||
@@ -3704,36 +3723,36 @@ public:
|
||||
NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
|
||||
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
|
||||
None, NameStr, InsertBefore);
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
|
||||
IfException, Args, None, NameStr, InsertBefore);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
|
||||
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> Bundles = None,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
|
||||
Bundles, NameStr, InsertBefore);
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
|
||||
IfException, Args, Bundles, NameStr, InsertBefore);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
|
||||
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd) {
|
||||
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
|
||||
NameStr, InsertAtEnd);
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
|
||||
IfException, Args, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
|
||||
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> Bundles,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd) {
|
||||
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
|
||||
Bundles, NameStr, InsertAtEnd);
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
|
||||
IfException, Args, Bundles, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
// Deprecated [opaque pointer types]
|
||||
|
||||
@@ -332,16 +332,18 @@ public:
|
||||
/// Look up the specified function in the module symbol table. Four
|
||||
/// possibilities:
|
||||
/// 1. If it does not exist, add a prototype for the function and return it.
|
||||
/// 2. If it exists, and has a local linkage, the existing function is
|
||||
/// renamed and a new one is inserted.
|
||||
/// 3. Otherwise, if the existing function has the correct prototype, return
|
||||
/// 2. Otherwise, if the existing function has the correct prototype, return
|
||||
/// the existing function.
|
||||
/// 4. Finally, the function exists but has the wrong prototype: return the
|
||||
/// 3. Finally, the function exists but has the wrong prototype: return the
|
||||
/// function with a constantexpr cast to the right prototype.
|
||||
Constant *getOrInsertFunction(StringRef Name, FunctionType *T,
|
||||
AttributeList AttributeList);
|
||||
///
|
||||
/// In all cases, the returned value is a FunctionCallee wrapper around the
|
||||
/// 'FunctionType *T' passed in, as well as a 'Value*' either of the Function or
|
||||
/// the bitcast to the function.
|
||||
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T,
|
||||
AttributeList AttributeList);
|
||||
|
||||
Constant *getOrInsertFunction(StringRef Name, FunctionType *T);
|
||||
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T);
|
||||
|
||||
/// Look up the specified function in the module symbol table. If it does not
|
||||
/// exist, add a prototype for the function and return it. This function
|
||||
@@ -349,11 +351,10 @@ public:
|
||||
/// or a ConstantExpr BitCast of that type if the named function has a
|
||||
/// different type. This version of the method takes a list of
|
||||
/// function arguments, which makes it easier for clients to use.
|
||||
template<typename... ArgsTy>
|
||||
Constant *getOrInsertFunction(StringRef Name,
|
||||
AttributeList AttributeList,
|
||||
Type *RetTy, ArgsTy... Args)
|
||||
{
|
||||
template <typename... ArgsTy>
|
||||
FunctionCallee getOrInsertFunction(StringRef Name,
|
||||
AttributeList AttributeList, Type *RetTy,
|
||||
ArgsTy... Args) {
|
||||
SmallVector<Type*, sizeof...(ArgsTy)> ArgTys{Args...};
|
||||
return getOrInsertFunction(Name,
|
||||
FunctionType::get(RetTy, ArgTys, false),
|
||||
@@ -361,15 +362,17 @@ public:
|
||||
}
|
||||
|
||||
/// Same as above, but without the attributes.
|
||||
template<typename... ArgsTy>
|
||||
Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ArgsTy... Args) {
|
||||
template <typename... ArgsTy>
|
||||
FunctionCallee getOrInsertFunction(StringRef Name, Type *RetTy,
|
||||
ArgsTy... Args) {
|
||||
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;
|
||||
FunctionCallee
|
||||
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.
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace llvm {
|
||||
template <typename T> class ArrayRef;
|
||||
class Module;
|
||||
class Function;
|
||||
class FunctionCallee;
|
||||
class GlobalValue;
|
||||
class GlobalVariable;
|
||||
class Constant;
|
||||
@@ -39,20 +40,14 @@ void appendToGlobalCtors(Module &M, Function *F, int Priority,
|
||||
void appendToGlobalDtors(Module &M, Function *F, int Priority,
|
||||
Constant *Data = nullptr);
|
||||
|
||||
// Validate the result of Module::getOrInsertFunction called for an interface
|
||||
// function of given sanitizer. If the instrumented module defines a function
|
||||
// with the same name, their prototypes must match, otherwise
|
||||
// getOrInsertFunction returns a bitcast.
|
||||
Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast);
|
||||
|
||||
Function *declareSanitizerInitFunction(Module &M, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes);
|
||||
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes);
|
||||
|
||||
/// Creates sanitizer constructor function, and calls sanitizer's init
|
||||
/// function from it.
|
||||
/// \return Returns pair of pointers to constructor, and init functions
|
||||
/// respectively.
|
||||
std::pair<Function *, Function *> createSanitizerCtorAndInitFunctions(
|
||||
std::pair<Function *, FunctionCallee> createSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
StringRef VersionCheckName = StringRef());
|
||||
@@ -64,10 +59,10 @@ std::pair<Function *, Function *> createSanitizerCtorAndInitFunctions(
|
||||
///
|
||||
/// \return Returns pair of pointers to constructor, and init functions
|
||||
/// respectively.
|
||||
std::pair<Function *, Function *> getOrCreateSanitizerCtorAndInitFunctions(
|
||||
std::pair<Function *, FunctionCallee> getOrCreateSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
function_ref<void(Function *, Function *)> FunctionsCreatedCallback,
|
||||
function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback,
|
||||
StringRef VersionCheckName = StringRef());
|
||||
|
||||
// Creates and returns a sanitizer init function without argument if it doesn't
|
||||
|
||||
@@ -1754,7 +1754,7 @@ bool AtomicExpand::expandAtomicOpToLibcall(
|
||||
for (Value *Arg : Args)
|
||||
ArgTys.push_back(Arg->getType());
|
||||
FunctionType *FnType = FunctionType::get(ResultTy, ArgTys, false);
|
||||
Constant *LibcallFn =
|
||||
FunctionCallee LibcallFn =
|
||||
M->getOrInsertFunction(TLI->getLibcallName(RTLibType), FnType, Attr);
|
||||
CallInst *Call = Builder.CreateCall(LibcallFn, Args);
|
||||
Call->setAttributes(Attr);
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace {
|
||||
|
||||
class DwarfEHPrepare : public FunctionPass {
|
||||
// RewindFunction - _Unwind_Resume or the target equivalent.
|
||||
Constant *RewindFunction = nullptr;
|
||||
FunctionCallee RewindFunction = nullptr;
|
||||
|
||||
DominatorTree *DT = nullptr;
|
||||
const TargetLowering *TLI = nullptr;
|
||||
|
||||
@@ -23,39 +23,6 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
template <class ArgIt>
|
||||
static void EnsureFunctionExists(Module &M, const char *Name,
|
||||
ArgIt ArgBegin, ArgIt ArgEnd,
|
||||
Type *RetTy) {
|
||||
// Insert a correctly-typed definition now.
|
||||
std::vector<Type *> ParamTys;
|
||||
for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
|
||||
ParamTys.push_back(I->getType());
|
||||
M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false));
|
||||
}
|
||||
|
||||
static void EnsureFPIntrinsicsExist(Module &M, Function &Fn,
|
||||
const char *FName,
|
||||
const char *DName, const char *LDName) {
|
||||
// Insert definitions for all the floating point types.
|
||||
switch((int)Fn.arg_begin()->getType()->getTypeID()) {
|
||||
case Type::FloatTyID:
|
||||
EnsureFunctionExists(M, FName, Fn.arg_begin(), Fn.arg_end(),
|
||||
Type::getFloatTy(M.getContext()));
|
||||
break;
|
||||
case Type::DoubleTyID:
|
||||
EnsureFunctionExists(M, DName, Fn.arg_begin(), Fn.arg_end(),
|
||||
Type::getDoubleTy(M.getContext()));
|
||||
break;
|
||||
case Type::X86_FP80TyID:
|
||||
case Type::FP128TyID:
|
||||
case Type::PPC_FP128TyID:
|
||||
EnsureFunctionExists(M, LDName, Fn.arg_begin(), Fn.arg_end(),
|
||||
Fn.arg_begin()->getType());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// This function is used when we want to lower an intrinsic call to a call of
|
||||
/// an external function. This handles hard cases such as when there was already
|
||||
/// a prototype for the external function, but that prototype doesn't match the
|
||||
@@ -71,8 +38,8 @@ static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI,
|
||||
std::vector<Type *> ParamTys;
|
||||
for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
|
||||
ParamTys.push_back((*I)->getType());
|
||||
Constant* FCache = M->getOrInsertFunction(NewFn,
|
||||
FunctionType::get(RetTy, ParamTys, false));
|
||||
FunctionCallee FCache =
|
||||
M->getOrInsertFunction(NewFn, FunctionType::get(RetTy, ParamTys, false));
|
||||
|
||||
IRBuilder<> Builder(CI->getParent(), CI->getIterator());
|
||||
SmallVector<Value *, 8> Args(ArgBegin, ArgEnd);
|
||||
@@ -91,75 +58,6 @@ static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI,
|
||||
# define setjmp_undefined_for_msvc
|
||||
#endif
|
||||
|
||||
void IntrinsicLowering::AddPrototypes(Module &M) {
|
||||
LLVMContext &Context = M.getContext();
|
||||
for (auto &F : M)
|
||||
if (F.isDeclaration() && !F.use_empty())
|
||||
switch (F.getIntrinsicID()) {
|
||||
default: break;
|
||||
case Intrinsic::setjmp:
|
||||
EnsureFunctionExists(M, "setjmp", F.arg_begin(), F.arg_end(),
|
||||
Type::getInt32Ty(M.getContext()));
|
||||
break;
|
||||
case Intrinsic::longjmp:
|
||||
EnsureFunctionExists(M, "longjmp", F.arg_begin(), F.arg_end(),
|
||||
Type::getVoidTy(M.getContext()));
|
||||
break;
|
||||
case Intrinsic::siglongjmp:
|
||||
EnsureFunctionExists(M, "abort", F.arg_end(), F.arg_end(),
|
||||
Type::getVoidTy(M.getContext()));
|
||||
break;
|
||||
case Intrinsic::memcpy:
|
||||
M.getOrInsertFunction("memcpy",
|
||||
Type::getInt8PtrTy(Context),
|
||||
Type::getInt8PtrTy(Context),
|
||||
Type::getInt8PtrTy(Context),
|
||||
DL.getIntPtrType(Context));
|
||||
break;
|
||||
case Intrinsic::memmove:
|
||||
M.getOrInsertFunction("memmove",
|
||||
Type::getInt8PtrTy(Context),
|
||||
Type::getInt8PtrTy(Context),
|
||||
Type::getInt8PtrTy(Context),
|
||||
DL.getIntPtrType(Context));
|
||||
break;
|
||||
case Intrinsic::memset:
|
||||
M.getOrInsertFunction("memset",
|
||||
Type::getInt8PtrTy(Context),
|
||||
Type::getInt8PtrTy(Context),
|
||||
Type::getInt32Ty(M.getContext()),
|
||||
DL.getIntPtrType(Context));
|
||||
break;
|
||||
case Intrinsic::sqrt:
|
||||
EnsureFPIntrinsicsExist(M, F, "sqrtf", "sqrt", "sqrtl");
|
||||
break;
|
||||
case Intrinsic::sin:
|
||||
EnsureFPIntrinsicsExist(M, F, "sinf", "sin", "sinl");
|
||||
break;
|
||||
case Intrinsic::cos:
|
||||
EnsureFPIntrinsicsExist(M, F, "cosf", "cos", "cosl");
|
||||
break;
|
||||
case Intrinsic::pow:
|
||||
EnsureFPIntrinsicsExist(M, F, "powf", "pow", "powl");
|
||||
break;
|
||||
case Intrinsic::log:
|
||||
EnsureFPIntrinsicsExist(M, F, "logf", "log", "logl");
|
||||
break;
|
||||
case Intrinsic::log2:
|
||||
EnsureFPIntrinsicsExist(M, F, "log2f", "log2", "log2l");
|
||||
break;
|
||||
case Intrinsic::log10:
|
||||
EnsureFPIntrinsicsExist(M, F, "log10f", "log10", "log10l");
|
||||
break;
|
||||
case Intrinsic::exp:
|
||||
EnsureFPIntrinsicsExist(M, F, "expf", "exp", "expl");
|
||||
break;
|
||||
case Intrinsic::exp2:
|
||||
EnsureFPIntrinsicsExist(M, F, "exp2f", "exp2", "exp2l");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit the code to lower bswap of V before the specified instruction IP.
|
||||
static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) {
|
||||
assert(V->getType()->isIntOrIntVectorTy() && "Can't bswap a non-integer type!");
|
||||
|
||||
@@ -270,8 +270,9 @@ bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
|
||||
/// Create an empty function with the given name.
|
||||
static Function *createDummyFunction(StringRef Name, Module &M) {
|
||||
auto &Context = M.getContext();
|
||||
Function *F = cast<Function>(M.getOrInsertFunction(
|
||||
Name, FunctionType::get(Type::getVoidTy(Context), false)));
|
||||
Function *F =
|
||||
Function::Create(FunctionType::get(Type::getVoidTy(Context), false),
|
||||
Function::ExternalLinkage, Name, M);
|
||||
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
|
||||
new UnreachableInst(Context, BB);
|
||||
return F;
|
||||
|
||||
@@ -1104,9 +1104,9 @@ MachineOutliner::createOutlinedFunction(Module &M, OutlinedFunction &OF,
|
||||
|
||||
// Create the function using an IR-level function.
|
||||
LLVMContext &C = M.getContext();
|
||||
Function *F = dyn_cast<Function>(
|
||||
M.getOrInsertFunction(NameStream.str(), Type::getVoidTy(C)));
|
||||
assert(F && "Function was null!");
|
||||
Function *F =
|
||||
Function::Create(FunctionType::get(Type::getVoidTy(C), false),
|
||||
Function::ExternalLinkage, NameStream.str(), M);
|
||||
|
||||
// NOTE: If this is linkonceodr, then we can take advantage of linker deduping
|
||||
// which gives us better results when we outline from linkonceodr functions.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user