forked from OSchip/llvm-project
Revert "[opaque pointer types] Add a FunctionCallee wrapper type, and use it."
This reverts commit f47d6b38c7
(r352791).
Seems to run into compilation failures with GCC (but not clang, where
I tested it). Reverting while I investigate.
llvm-svn: 352800
This commit is contained in:
parent
c62214da3d
commit
fadf25068e
|
@ -3056,7 +3056,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
|
|||
bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Kind);
|
||||
|
||||
llvm::CallInst *CheckCall;
|
||||
llvm::FunctionCallee SlowPathFn;
|
||||
llvm::Constant *SlowPathFn;
|
||||
if (WithDiag) {
|
||||
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
|
||||
auto *InfoPtr =
|
||||
|
@ -3078,8 +3078,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
|
|||
CheckCall = Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
|
||||
}
|
||||
|
||||
CGM.setDSOLocal(
|
||||
cast<llvm::GlobalValue>(SlowPathFn.getCallee()->stripPointerCasts()));
|
||||
CGM.setDSOLocal(cast<llvm::GlobalValue>(SlowPathFn->stripPointerCasts()));
|
||||
CheckCall->setDoesNotThrow();
|
||||
|
||||
EmitBlock(Cont);
|
||||
|
|
|
@ -3491,17 +3491,11 @@ Important Public Members of the ``Module`` class
|
|||
Look up the specified function in the ``Module`` SymbolTable_. If it does not
|
||||
exist, return ``null``.
|
||||
|
||||
* ``FunctionCallee getOrInsertFunction(const std::string &Name,
|
||||
const FunctionType *T)``
|
||||
* ``Function *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. 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.
|
||||
Look up the specified function in the ``Module`` SymbolTable_. If it does not
|
||||
exist, add an external declaration for the function and return it.
|
||||
|
||||
* ``std::string getTypeName(const Type *Ty)``
|
||||
|
||||
|
|
|
@ -72,17 +72,19 @@ void BrainF::header(LLVMContext& C) {
|
|||
Tys);
|
||||
|
||||
//declare i32 @getchar()
|
||||
getchar_func =
|
||||
module->getOrInsertFunction("getchar", IntegerType::getInt32Ty(C));
|
||||
getchar_func = cast<Function>(module->
|
||||
getOrInsertFunction("getchar", IntegerType::getInt32Ty(C)));
|
||||
|
||||
//declare i32 @putchar(i32)
|
||||
putchar_func = module->getOrInsertFunction(
|
||||
"putchar", IntegerType::getInt32Ty(C), IntegerType::getInt32Ty(C));
|
||||
putchar_func = cast<Function>(module->
|
||||
getOrInsertFunction("putchar", IntegerType::getInt32Ty(C),
|
||||
IntegerType::getInt32Ty(C)));
|
||||
|
||||
//Function header
|
||||
|
||||
//define void @brainf()
|
||||
brainf_func = module->getOrInsertFunction("brainf", Type::getVoidTy(C));
|
||||
brainf_func = cast<Function>(module->
|
||||
getOrInsertFunction("brainf", Type::getVoidTy(C)));
|
||||
|
||||
builder = new IRBuilder<>(BasicBlock::Create(C, label, brainf_func));
|
||||
|
||||
|
@ -151,9 +153,9 @@ void BrainF::header(LLVMContext& C) {
|
|||
"aberrormsg");
|
||||
|
||||
//declare i32 @puts(i8 *)
|
||||
FunctionCallee puts_func = module->getOrInsertFunction(
|
||||
"puts", IntegerType::getInt32Ty(C),
|
||||
PointerType::getUnqual(IntegerType::getInt8Ty(C)));
|
||||
Function *puts_func = cast<Function>(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;
|
||||
FunctionCallee brainf_func;
|
||||
FunctionCallee getchar_func;
|
||||
FunctionCallee putchar_func;
|
||||
Function *brainf_func;
|
||||
Function *getchar_func;
|
||||
Function *putchar_func;
|
||||
Value *ptr_arr;
|
||||
Value *ptr_arrmax;
|
||||
BasicBlock *endbb;
|
||||
|
|
|
@ -72,13 +72,11 @@ 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)
|
||||
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 *main_func = cast<Function>(mod->
|
||||
getOrInsertFunction("main", IntegerType::getInt32Ty(mod->getContext()),
|
||||
IntegerType::getInt32Ty(mod->getContext()),
|
||||
PointerType::getUnqual(PointerType::getUnqual(
|
||||
IntegerType::getInt8Ty(mod->getContext())))));
|
||||
{
|
||||
Function::arg_iterator args = main_func->arg_begin();
|
||||
Value *arg_0 = &*args++;
|
||||
|
|
|
@ -51,10 +51,9 @@ 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 =
|
||||
Function::Create(FibFTy, Function::ExternalLinkage, "fib", M);
|
||||
cast<Function>(M->getOrInsertFunction("fib", Type::getInt32Ty(Context),
|
||||
Type::getInt32Ty(Context)));
|
||||
|
||||
// Add a basic block to the function.
|
||||
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", FibF);
|
||||
|
|
|
@ -69,9 +69,8 @@ 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 =
|
||||
Function::Create(FunctionType::get(Type::getInt32Ty(Context),
|
||||
{Type::getInt32Ty(Context)}, false),
|
||||
Function::ExternalLinkage, "add1", M);
|
||||
cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context),
|
||||
Type::getInt32Ty(Context)));
|
||||
|
||||
// Add a basic block to the function. As before, it automatically inserts
|
||||
// because of the last argument.
|
||||
|
@ -100,8 +99,7 @@ int main() {
|
|||
// Now we're going to create function `foo', which returns an int and takes no
|
||||
// arguments.
|
||||
Function *FooF =
|
||||
Function::Create(FunctionType::get(Type::getInt32Ty(Context), {}, false),
|
||||
Function::ExternalLinkage, "foo", M);
|
||||
cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context)));
|
||||
|
||||
// Add a basic block to the FooF function.
|
||||
BB = BasicBlock::Create(Context, "EntryBlock", FooF);
|
||||
|
|
|
@ -49,10 +49,11 @@ 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 =
|
||||
Function::Create(FunctionType::get(Type::getInt32Ty(Context),
|
||||
{Type::getInt32Ty(Context)}, false),
|
||||
Function::ExternalLinkage, "add1", M);
|
||||
cast<Function>(M->getOrInsertFunction("add1",
|
||||
Type::getInt32Ty(M->getContext()),
|
||||
Type::getInt32Ty(M->getContext())));
|
||||
|
||||
// Add a basic block to the function. As before, it automatically inserts
|
||||
// because of the last argument.
|
||||
|
@ -79,10 +80,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.
|
||||
FunctionType *FibFTy = FunctionType::get(Type::getInt32Ty(Context),
|
||||
{Type::getInt32Ty(Context)}, false);
|
||||
Function *FibF =
|
||||
Function::Create(FibFTy, Function::ExternalLinkage, "fib", M);
|
||||
Function *FibF =
|
||||
cast<Function>(M->getOrInsertFunction("fib",
|
||||
Type::getInt32Ty(M->getContext()),
|
||||
Type::getInt32Ty(M->getContext())));
|
||||
|
||||
// Add a basic block to the function.
|
||||
BasicBlock *BB = BasicBlock::Create(M->getContext(), "EntryBlock", FibF);
|
||||
|
|
|
@ -30,6 +30,10 @@ 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,39 +157,6 @@ 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 = std::enable_if<(&T::getFunctionType != nullptr), void>>
|
||||
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(FunctionCallee Callee, BasicBlock *NormalDest,
|
||||
InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest,
|
||||
BasicBlock *UnwindDest, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> OpBundles,
|
||||
const Twine &Name = "") {
|
||||
return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(),
|
||||
NormalDest, UnwindDest, Args, OpBundles, Name);
|
||||
return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest,
|
||||
UnwindDest, Args, OpBundles, Name);
|
||||
}
|
||||
|
||||
InvokeInst *CreateInvoke(FunctionCallee Callee, BasicBlock *NormalDest,
|
||||
InvokeInst *CreateInvoke(Function *Callee, BasicBlock *NormalDest,
|
||||
BasicBlock *UnwindDest,
|
||||
ArrayRef<Value *> Args = None,
|
||||
const Twine &Name = "") {
|
||||
return CreateInvoke(Callee.getFunctionType(), Callee.getCallee(),
|
||||
NormalDest, UnwindDest, Args, Name);
|
||||
return CreateInvoke(Callee->getFunctionType(), Callee, NormalDest,
|
||||
UnwindDest, Args, Name);
|
||||
}
|
||||
|
||||
// Deprecated [opaque pointer types]
|
||||
|
@ -1988,17 +1988,16 @@ public:
|
|||
return Insert(CI, Name);
|
||||
}
|
||||
|
||||
CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args = None,
|
||||
CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args = None,
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
|
||||
return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args, Name,
|
||||
FPMathTag);
|
||||
return CreateCall(Callee->getFunctionType(), Callee, Args, Name, FPMathTag);
|
||||
}
|
||||
|
||||
CallInst *CreateCall(FunctionCallee Callee, ArrayRef<Value *> Args,
|
||||
CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> OpBundles,
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
|
||||
return CreateCall(Callee.getFunctionType(), Callee.getCallee(), Args,
|
||||
OpBundles, Name, FPMathTag);
|
||||
return CreateCall(Callee->getFunctionType(), Callee, Args, OpBundles, Name,
|
||||
FPMathTag);
|
||||
}
|
||||
|
||||
// Deprecated [opaque pointer types]
|
||||
|
|
|
@ -1232,11 +1232,6 @@ 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,44 +1543,25 @@ public:
|
|||
CallInst(Ty, Func, Args, Bundles, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
static CallInst *Create(FunctionCallee Func, const Twine &NameStr = "",
|
||||
static CallInst *Create(Function *Func, const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), NameStr,
|
||||
InsertBefore);
|
||||
return Create(Func->getFunctionType(), Func, NameStr, InsertBefore);
|
||||
}
|
||||
|
||||
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> Bundles = None,
|
||||
static CallInst *Create(Function *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles,
|
||||
NameStr, InsertBefore);
|
||||
return Create(Func->getFunctionType(), Func, Args, NameStr, InsertBefore);
|
||||
}
|
||||
|
||||
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,
|
||||
static CallInst *Create(Function *Func, const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), NameStr,
|
||||
InsertAtEnd);
|
||||
return Create(Func->getFunctionType(), Func, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
|
||||
static CallInst *Create(Function *Func, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, BasicBlock *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);
|
||||
return Create(Func->getFunctionType(), Func, Args, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
// Deprecated [opaque pointer types]
|
||||
|
@ -3723,36 +3704,36 @@ public:
|
|||
NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
|
||||
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
|
||||
IfException, Args, None, NameStr, InsertBefore);
|
||||
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
|
||||
None, NameStr, InsertBefore);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
|
||||
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> Bundles = None,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = nullptr) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
|
||||
IfException, Args, Bundles, NameStr, InsertBefore);
|
||||
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
|
||||
Bundles, NameStr, InsertBefore);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
|
||||
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
|
||||
IfException, Args, NameStr, InsertAtEnd);
|
||||
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
|
||||
NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
|
||||
static InvokeInst *Create(Function *Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> Bundles,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd) {
|
||||
return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
|
||||
IfException, Args, Bundles, NameStr, InsertAtEnd);
|
||||
return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args,
|
||||
Bundles, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
// Deprecated [opaque pointer types]
|
||||
|
|
|
@ -332,18 +332,16 @@ 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. Otherwise, if the existing function has the correct prototype, return
|
||||
/// 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
|
||||
/// the existing function.
|
||||
/// 3. Finally, the function exists but has the wrong prototype: return the
|
||||
/// 4. Finally, the function exists but has the wrong prototype: return the
|
||||
/// function with a constantexpr cast to the right prototype.
|
||||
///
|
||||
/// 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,
|
||||
AttributeList AttributeList);
|
||||
|
||||
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T);
|
||||
Constant *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
|
||||
|
@ -351,10 +349,11 @@ 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>
|
||||
FunctionCallee getOrInsertFunction(StringRef Name,
|
||||
AttributeList AttributeList, Type *RetTy,
|
||||
ArgsTy... Args) {
|
||||
template<typename... ArgsTy>
|
||||
Constant *getOrInsertFunction(StringRef Name,
|
||||
AttributeList AttributeList,
|
||||
Type *RetTy, ArgsTy... Args)
|
||||
{
|
||||
SmallVector<Type*, sizeof...(ArgsTy)> ArgTys{Args...};
|
||||
return getOrInsertFunction(Name,
|
||||
FunctionType::get(RetTy, ArgTys, false),
|
||||
|
@ -362,17 +361,15 @@ public:
|
|||
}
|
||||
|
||||
/// Same as above, but without the attributes.
|
||||
template <typename... ArgsTy>
|
||||
FunctionCallee getOrInsertFunction(StringRef Name, Type *RetTy,
|
||||
ArgsTy... Args) {
|
||||
template<typename... ArgsTy>
|
||||
Constant *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>
|
||||
FunctionCallee
|
||||
getOrInsertFunction(StringRef Name, AttributeList AttributeList,
|
||||
FunctionType *Invalid, ArgsTy... Args) = delete;
|
||||
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.
|
||||
|
|
|
@ -21,7 +21,6 @@ namespace llvm {
|
|||
template <typename T> class ArrayRef;
|
||||
class Module;
|
||||
class Function;
|
||||
class FunctionCallee;
|
||||
class GlobalValue;
|
||||
class GlobalVariable;
|
||||
class Constant;
|
||||
|
@ -40,14 +39,20 @@ void appendToGlobalCtors(Module &M, Function *F, int Priority,
|
|||
void appendToGlobalDtors(Module &M, Function *F, int Priority,
|
||||
Constant *Data = nullptr);
|
||||
|
||||
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes);
|
||||
// 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);
|
||||
|
||||
/// 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 *, FunctionCallee> createSanitizerCtorAndInitFunctions(
|
||||
std::pair<Function *, Function *> createSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
StringRef VersionCheckName = StringRef());
|
||||
|
@ -59,10 +64,10 @@ std::pair<Function *, FunctionCallee> createSanitizerCtorAndInitFunctions(
|
|||
///
|
||||
/// \return Returns pair of pointers to constructor, and init functions
|
||||
/// respectively.
|
||||
std::pair<Function *, FunctionCallee> getOrCreateSanitizerCtorAndInitFunctions(
|
||||
std::pair<Function *, Function *> getOrCreateSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback,
|
||||
function_ref<void(Function *, Function *)> 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);
|
||||
FunctionCallee LibcallFn =
|
||||
Constant *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.
|
||||
FunctionCallee RewindFunction = nullptr;
|
||||
Constant *RewindFunction = nullptr;
|
||||
|
||||
DominatorTree *DT = nullptr;
|
||||
const TargetLowering *TLI = nullptr;
|
||||
|
|
|
@ -23,6 +23,39 @@
|
|||
#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
|
||||
|
@ -38,8 +71,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());
|
||||
FunctionCallee FCache =
|
||||
M->getOrInsertFunction(NewFn, FunctionType::get(RetTy, ParamTys, false));
|
||||
Constant* FCache = M->getOrInsertFunction(NewFn,
|
||||
FunctionType::get(RetTy, ParamTys, false));
|
||||
|
||||
IRBuilder<> Builder(CI->getParent(), CI->getIterator());
|
||||
SmallVector<Value *, 8> Args(ArgBegin, ArgEnd);
|
||||
|
@ -58,6 +91,75 @@ 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,9 +270,8 @@ 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 =
|
||||
Function::Create(FunctionType::get(Type::getVoidTy(Context), false),
|
||||
Function::ExternalLinkage, Name, M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction(
|
||||
Name, FunctionType::get(Type::getVoidTy(Context), false)));
|
||||
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 =
|
||||
Function::Create(FunctionType::get(Type::getVoidTy(C), false),
|
||||
Function::ExternalLinkage, NameStream.str(), M);
|
||||
Function *F = dyn_cast<Function>(
|
||||
M.getOrInsertFunction(NameStream.str(), Type::getVoidTy(C)));
|
||||
assert(F && "Function was null!");
|
||||
|
||||
// NOTE: If this is linkonceodr, then we can take advantage of linker deduping
|
||||
// which gives us better results when we outline from linkonceodr functions.
|
||||
|
|
|
@ -64,9 +64,9 @@ static bool lowerObjCCall(Function &F, const char *NewFn,
|
|||
// If we haven't already looked up this function, check to see if the
|
||||
// program already contains a function with this name.
|
||||
Module *M = F.getParent();
|
||||
FunctionCallee FCache = M->getOrInsertFunction(NewFn, F.getFunctionType());
|
||||
Constant* FCache = M->getOrInsertFunction(NewFn, F.getFunctionType());
|
||||
|
||||
if (Function *Fn = dyn_cast<Function>(FCache.getCallee())) {
|
||||
if (Function* Fn = dyn_cast<Function>(FCache)) {
|
||||
Fn->setLinkage(F.getLinkage());
|
||||
if (setNonLazyBind && !Fn->isWeakForLinker()) {
|
||||
// If we have Native ARC, set nonlazybind attribute for these APIs for
|
||||
|
|
|
@ -474,8 +474,8 @@ void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, ReturnInst &RI,
|
|||
/* Unreachable */ true, Weights);
|
||||
IRBuilder<> IRBFail(CheckTerm);
|
||||
// FIXME: respect -fsanitize-trap / -ftrap-function here?
|
||||
FunctionCallee StackChkFail =
|
||||
F.getParent()->getOrInsertFunction("__stack_chk_fail", IRB.getVoidTy());
|
||||
Constant *StackChkFail = F.getParent()->getOrInsertFunction(
|
||||
"__stack_chk_fail", IRB.getVoidTy());
|
||||
IRBFail.CreateCall(StackChkFail, {});
|
||||
}
|
||||
|
||||
|
@ -782,7 +782,7 @@ bool SafeStack::run() {
|
|||
if (DISubprogram *SP = F.getSubprogram())
|
||||
IRB.SetCurrentDebugLocation(DebugLoc::get(SP->getScopeLine(), 0, SP));
|
||||
if (SafeStackUsePointerAddress) {
|
||||
FunctionCallee Fn = F.getParent()->getOrInsertFunction(
|
||||
Value *Fn = F.getParent()->getOrInsertFunction(
|
||||
"__safestack_pointer_address", StackPtrTy->getPointerTo(0));
|
||||
UnsafeStackPtr = IRB.CreateCall(Fn);
|
||||
} else {
|
||||
|
|
|
@ -39,15 +39,15 @@ class SjLjEHPrepare : public FunctionPass {
|
|||
Type *doubleUnderDataTy;
|
||||
Type *doubleUnderJBufTy;
|
||||
Type *FunctionContextTy;
|
||||
FunctionCallee RegisterFn;
|
||||
FunctionCallee UnregisterFn;
|
||||
Function *BuiltinSetupDispatchFn;
|
||||
Function *FrameAddrFn;
|
||||
Function *StackAddrFn;
|
||||
Function *StackRestoreFn;
|
||||
Function *LSDAAddrFn;
|
||||
Function *CallSiteFn;
|
||||
Function *FuncCtxFn;
|
||||
Constant *RegisterFn;
|
||||
Constant *UnregisterFn;
|
||||
Constant *BuiltinSetupDispatchFn;
|
||||
Constant *FrameAddrFn;
|
||||
Constant *StackAddrFn;
|
||||
Constant *StackRestoreFn;
|
||||
Constant *LSDAAddrFn;
|
||||
Constant *CallSiteFn;
|
||||
Constant *FuncCtxFn;
|
||||
AllocaInst *FuncCtx;
|
||||
|
||||
public:
|
||||
|
|
|
@ -499,13 +499,14 @@ BasicBlock *StackProtector::CreateFailBB() {
|
|||
IRBuilder<> B(FailBB);
|
||||
B.SetCurrentDebugLocation(DebugLoc::get(0, 0, F->getSubprogram()));
|
||||
if (Trip.isOSOpenBSD()) {
|
||||
FunctionCallee StackChkFail = M->getOrInsertFunction(
|
||||
"__stack_smash_handler", Type::getVoidTy(Context),
|
||||
Type::getInt8PtrTy(Context));
|
||||
Constant *StackChkFail =
|
||||
M->getOrInsertFunction("__stack_smash_handler",
|
||||
Type::getVoidTy(Context),
|
||||
Type::getInt8PtrTy(Context));
|
||||
|
||||
B.CreateCall(StackChkFail, B.CreateGlobalStringPtr(F->getName(), "SSH"));
|
||||
} else {
|
||||
FunctionCallee StackChkFail =
|
||||
Constant *StackChkFail =
|
||||
M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
|
||||
|
||||
B.CreateCall(StackChkFail, {});
|
||||
|
|
|
@ -1587,8 +1587,8 @@ Value *TargetLoweringBase::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
|||
// thread's unsafe stack pointer.
|
||||
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
|
||||
Type *StackPtrTy = Type::getInt8PtrTy(M->getContext());
|
||||
FunctionCallee Fn = M->getOrInsertFunction("__safestack_pointer_address",
|
||||
StackPtrTy->getPointerTo(0));
|
||||
Value *Fn = M->getOrInsertFunction("__safestack_pointer_address",
|
||||
StackPtrTy->getPointerTo(0));
|
||||
return IRB.CreateCall(Fn);
|
||||
}
|
||||
|
||||
|
|
|
@ -111,8 +111,7 @@ class WasmEHPrepare : public FunctionPass {
|
|||
Function *GetExnF = nullptr; // wasm.get.exception() intrinsic
|
||||
Function *ExtractExnF = nullptr; // wasm.extract.exception() intrinsic
|
||||
Function *GetSelectorF = nullptr; // wasm.get.ehselector() intrinsic
|
||||
FunctionCallee CallPersonalityF =
|
||||
nullptr; // _Unwind_CallPersonality() wrapper
|
||||
Function *CallPersonalityF = nullptr; // _Unwind_CallPersonality() wrapper
|
||||
|
||||
bool prepareEHPads(Function &F);
|
||||
bool prepareThrows(Function &F);
|
||||
|
@ -253,10 +252,9 @@ bool WasmEHPrepare::prepareEHPads(Function &F) {
|
|||
Intrinsic::getDeclaration(&M, Intrinsic::wasm_extract_exception);
|
||||
|
||||
// _Unwind_CallPersonality() wrapper function, which calls the personality
|
||||
CallPersonalityF = M.getOrInsertFunction(
|
||||
"_Unwind_CallPersonality", IRB.getInt32Ty(), IRB.getInt8PtrTy());
|
||||
if (Function *F = dyn_cast<Function>(CallPersonalityF.getCallee()))
|
||||
F->setDoesNotThrow();
|
||||
CallPersonalityF = cast<Function>(M.getOrInsertFunction(
|
||||
"_Unwind_CallPersonality", IRB.getInt32Ty(), IRB.getInt8PtrTy()));
|
||||
CallPersonalityF->setDoesNotThrow();
|
||||
|
||||
unsigned Index = 0;
|
||||
for (auto *BB : CatchPads) {
|
||||
|
|
|
@ -1018,10 +1018,9 @@ bool Intrinsic::isLeaf(ID id) {
|
|||
Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
|
||||
// There can never be multiple globals with the same name of different types,
|
||||
// because intrinsics must be a specific type.
|
||||
return cast<Function>(
|
||||
M->getOrInsertFunction(getName(id, Tys),
|
||||
getType(M->getContext(), id, Tys))
|
||||
.getCallee());
|
||||
return
|
||||
cast<Function>(M->getOrInsertFunction(getName(id, Tys),
|
||||
getType(M->getContext(), id, Tys)));
|
||||
}
|
||||
|
||||
// This defines the "Intrinsic::getIntrinsicForGCCBuiltin()" method.
|
||||
|
|
|
@ -517,7 +517,7 @@ static Instruction *createMalloc(Instruction *InsertBefore,
|
|||
BasicBlock *BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd;
|
||||
Module *M = BB->getParent()->getParent();
|
||||
Type *BPTy = Type::getInt8PtrTy(BB->getContext());
|
||||
FunctionCallee MallocFunc = MallocF;
|
||||
Value *MallocFunc = MallocF;
|
||||
if (!MallocFunc)
|
||||
// prototype malloc as "void *malloc(size_t)"
|
||||
MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy);
|
||||
|
@ -541,7 +541,7 @@ static Instruction *createMalloc(Instruction *InsertBefore,
|
|||
}
|
||||
}
|
||||
MCall->setTailCall();
|
||||
if (Function *F = dyn_cast<Function>(MallocFunc.getCallee())) {
|
||||
if (Function *F = dyn_cast<Function>(MallocFunc)) {
|
||||
MCall->setCallingConv(F->getCallingConv());
|
||||
if (!F->returnDoesNotAlias())
|
||||
F->setReturnDoesNotAlias();
|
||||
|
@ -614,7 +614,7 @@ static Instruction *createFree(Value *Source,
|
|||
Type *VoidTy = Type::getVoidTy(M->getContext());
|
||||
Type *IntPtrTy = Type::getInt8PtrTy(M->getContext());
|
||||
// prototype free as "void free(void*)"
|
||||
FunctionCallee FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy);
|
||||
Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy);
|
||||
CallInst *Result = nullptr;
|
||||
Value *PtrCast = Source;
|
||||
if (InsertBefore) {
|
||||
|
@ -627,7 +627,7 @@ static Instruction *createFree(Value *Source,
|
|||
Result = CallInst::Create(FreeFunc, PtrCast, Bundles, "");
|
||||
}
|
||||
Result->setTailCall();
|
||||
if (Function *F = dyn_cast<Function>(FreeFunc.getCallee()))
|
||||
if (Function *F = dyn_cast<Function>(FreeFunc))
|
||||
Result->setCallingConv(F->getCallingConv());
|
||||
|
||||
return Result;
|
||||
|
|
|
@ -140,8 +140,8 @@ void Module::getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const {
|
|||
// it. This is nice because it allows most passes to get away with not handling
|
||||
// the symbol table directly for this common task.
|
||||
//
|
||||
FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty,
|
||||
AttributeList AttributeList) {
|
||||
Constant *Module::getOrInsertFunction(StringRef Name, FunctionType *Ty,
|
||||
AttributeList AttributeList) {
|
||||
// See if we have a definition for the specified function already.
|
||||
GlobalValue *F = getNamedValue(Name);
|
||||
if (!F) {
|
||||
|
@ -151,20 +151,21 @@ FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty,
|
|||
if (!New->isIntrinsic()) // Intrinsics get attrs set on construction
|
||||
New->setAttributes(AttributeList);
|
||||
FunctionList.push_back(New);
|
||||
return {Ty, New}; // Return the new prototype.
|
||||
return New; // Return the new prototype.
|
||||
}
|
||||
|
||||
// If the function exists but has the wrong type, return a bitcast to the
|
||||
// right type.
|
||||
auto *PTy = PointerType::get(Ty, F->getAddressSpace());
|
||||
if (F->getType() != PTy)
|
||||
return {Ty, ConstantExpr::getBitCast(F, PTy)};
|
||||
return ConstantExpr::getBitCast(F, PTy);
|
||||
|
||||
// Otherwise, we just found the existing function or a prototype.
|
||||
return {Ty, F};
|
||||
return F;
|
||||
}
|
||||
|
||||
FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty) {
|
||||
Constant *Module::getOrInsertFunction(StringRef Name,
|
||||
FunctionType *Ty) {
|
||||
return getOrInsertFunction(Name, Ty, AttributeList());
|
||||
}
|
||||
|
||||
|
|
|
@ -11748,13 +11748,12 @@ void AArch64TargetLowering::insertSSPDeclarations(Module &M) const {
|
|||
Type::getInt8PtrTy(M.getContext()));
|
||||
|
||||
// MSVC CRT has a function to validate security cookie.
|
||||
FunctionCallee SecurityCheckCookie = M.getOrInsertFunction(
|
||||
"__security_check_cookie", Type::getVoidTy(M.getContext()),
|
||||
Type::getInt8PtrTy(M.getContext()));
|
||||
if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee())) {
|
||||
F->setCallingConv(CallingConv::Win64);
|
||||
F->addAttribute(1, Attribute::AttrKind::InReg);
|
||||
}
|
||||
auto *SecurityCheckCookie = cast<Function>(
|
||||
M.getOrInsertFunction("__security_check_cookie",
|
||||
Type::getVoidTy(M.getContext()),
|
||||
Type::getInt8PtrTy(M.getContext())));
|
||||
SecurityCheckCookie->setCallingConv(CallingConv::Win64);
|
||||
SecurityCheckCookie->addAttribute(1, Attribute::AttrKind::InReg);
|
||||
return;
|
||||
}
|
||||
TargetLowering::insertSSPDeclarations(M);
|
||||
|
|
|
@ -72,7 +72,7 @@ private:
|
|||
|
||||
// Return a pointer (pointer expr) to the function if function defintion with
|
||||
// "FuncName" exists. It may create a new function prototype in pre-link mode.
|
||||
FunctionCallee getFunction(Module *M, const FuncInfo &fInfo);
|
||||
Constant *getFunction(Module *M, const FuncInfo& fInfo);
|
||||
|
||||
// Replace a normal function with its native version.
|
||||
bool replaceWithNative(CallInst *CI, const FuncInfo &FInfo);
|
||||
|
@ -139,7 +139,7 @@ private:
|
|||
// Insert an Alloc instruction.
|
||||
AllocaInst* insertAlloca(CallInst * UI, IRBuilder<> &B, const char *prefix);
|
||||
// Get a scalar native builtin signle argument FP function
|
||||
FunctionCallee getNativeFunction(Module *M, const FuncInfo &FInfo);
|
||||
Constant* getNativeFunction(Module* M, const FuncInfo &FInfo);
|
||||
|
||||
protected:
|
||||
CallInst *CI;
|
||||
|
@ -216,19 +216,19 @@ INITIALIZE_PASS(AMDGPUUseNativeCalls, "amdgpu-usenative",
|
|||
false, false)
|
||||
|
||||
template <typename IRB>
|
||||
static CallInst *CreateCallEx(IRB &B, FunctionCallee Callee, Value *Arg,
|
||||
static CallInst *CreateCallEx(IRB &B, Value *Callee, Value *Arg,
|
||||
const Twine &Name = "") {
|
||||
CallInst *R = B.CreateCall(Callee, Arg, Name);
|
||||
if (Function *F = dyn_cast<Function>(Callee.getCallee()))
|
||||
if (Function* F = dyn_cast<Function>(Callee))
|
||||
R->setCallingConv(F->getCallingConv());
|
||||
return R;
|
||||
}
|
||||
|
||||
template <typename IRB>
|
||||
static CallInst *CreateCallEx2(IRB &B, FunctionCallee Callee, Value *Arg1,
|
||||
Value *Arg2, const Twine &Name = "") {
|
||||
static CallInst *CreateCallEx2(IRB &B, Value *Callee, Value *Arg1, Value *Arg2,
|
||||
const Twine &Name = "") {
|
||||
CallInst *R = B.CreateCall(Callee, {Arg1, Arg2}, Name);
|
||||
if (Function *F = dyn_cast<Function>(Callee.getCallee()))
|
||||
if (Function* F = dyn_cast<Function>(Callee))
|
||||
R->setCallingConv(F->getCallingConv());
|
||||
return R;
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ static inline AMDGPULibFunc::EType getArgType(const AMDGPULibFunc& FInfo) {
|
|||
return (AMDGPULibFunc::EType)FInfo.getLeads()[0].ArgType;
|
||||
}
|
||||
|
||||
FunctionCallee AMDGPULibCalls::getFunction(Module *M, const FuncInfo &fInfo) {
|
||||
Constant *AMDGPULibCalls::getFunction(Module *M, const FuncInfo& fInfo) {
|
||||
// If we are doing PreLinkOpt, the function is external. So it is safe to
|
||||
// use getOrInsertFunction() at this stage.
|
||||
|
||||
|
@ -518,11 +518,11 @@ bool AMDGPULibCalls::sincosUseNative(CallInst *aCI, const FuncInfo &FInfo) {
|
|||
|
||||
nf.setPrefix(AMDGPULibFunc::NATIVE);
|
||||
nf.setId(AMDGPULibFunc::EI_SIN);
|
||||
FunctionCallee sinExpr = getFunction(M, nf);
|
||||
Constant *sinExpr = getFunction(M, nf);
|
||||
|
||||
nf.setPrefix(AMDGPULibFunc::NATIVE);
|
||||
nf.setId(AMDGPULibFunc::EI_COS);
|
||||
FunctionCallee cosExpr = getFunction(M, nf);
|
||||
Constant *cosExpr = getFunction(M, nf);
|
||||
if (sinExpr && cosExpr) {
|
||||
Value *sinval = CallInst::Create(sinExpr, opr0, "splitsin", aCI);
|
||||
Value *cosval = CallInst::Create(cosExpr, opr0, "splitcos", aCI);
|
||||
|
@ -554,7 +554,7 @@ bool AMDGPULibCalls::useNative(CallInst *aCI) {
|
|||
return sincosUseNative(aCI, FInfo);
|
||||
|
||||
FInfo.setPrefix(AMDGPULibFunc::NATIVE);
|
||||
FunctionCallee F = getFunction(aCI->getModule(), FInfo);
|
||||
Constant *F = getFunction(aCI->getModule(), FInfo);
|
||||
if (!F)
|
||||
return false;
|
||||
|
||||
|
@ -612,7 +612,7 @@ bool AMDGPULibCalls::fold_read_write_pipe(CallInst *CI, IRBuilder<> &B,
|
|||
auto *FTy = FunctionType::get(Callee->getReturnType(),
|
||||
ArrayRef<Type *>(ArgTys), false);
|
||||
AMDGPULibFunc NewLibFunc(Name, FTy);
|
||||
FunctionCallee F = AMDGPULibFunc::getOrInsertFunction(M, NewLibFunc);
|
||||
auto *F = AMDGPULibFunc::getOrInsertFunction(M, NewLibFunc);
|
||||
if (!F)
|
||||
return false;
|
||||
|
||||
|
@ -794,7 +794,7 @@ bool AMDGPULibCalls::replaceWithNative(CallInst *CI, const FuncInfo &FInfo) {
|
|||
|
||||
AMDGPULibFunc nf = FInfo;
|
||||
nf.setPrefix(AMDGPULibFunc::NATIVE);
|
||||
if (FunctionCallee FPExpr = getFunction(M, nf)) {
|
||||
if (Constant *FPExpr = getFunction(M, nf)) {
|
||||
LLVM_DEBUG(dbgs() << "AMDIC: " << *CI << " ---> ");
|
||||
|
||||
CI->setCalledFunction(FPExpr);
|
||||
|
@ -933,10 +933,9 @@ bool AMDGPULibCalls::fold_pow(CallInst *CI, IRBuilder<> &B,
|
|||
if (CF && (CF->isExactlyValue(0.5) || CF->isExactlyValue(-0.5))) {
|
||||
// pow[r](x, [-]0.5) = sqrt(x)
|
||||
bool issqrt = CF->isExactlyValue(0.5);
|
||||
if (FunctionCallee FPExpr =
|
||||
getFunction(M, AMDGPULibFunc(issqrt ? AMDGPULibFunc::EI_SQRT
|
||||
: AMDGPULibFunc::EI_RSQRT,
|
||||
FInfo))) {
|
||||
if (Constant *FPExpr = getFunction(M,
|
||||
AMDGPULibFunc(issqrt ? AMDGPULibFunc::EI_SQRT
|
||||
: AMDGPULibFunc::EI_RSQRT, FInfo))) {
|
||||
LLVM_DEBUG(errs() << "AMDIC: " << *CI << " ---> "
|
||||
<< FInfo.getName().c_str() << "(" << *opr0 << ")\n");
|
||||
Value *nval = CreateCallEx(B,FPExpr, opr0, issqrt ? "__pow2sqrt"
|
||||
|
@ -1003,8 +1002,8 @@ bool AMDGPULibCalls::fold_pow(CallInst *CI, IRBuilder<> &B,
|
|||
|
||||
// powr ---> exp2(y * log2(x))
|
||||
// pown/pow ---> powr(fabs(x), y) | (x & ((int)y << 31))
|
||||
FunctionCallee ExpExpr =
|
||||
getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_EXP2, FInfo));
|
||||
Constant *ExpExpr = getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_EXP2,
|
||||
FInfo));
|
||||
if (!ExpExpr)
|
||||
return false;
|
||||
|
||||
|
@ -1090,8 +1089,8 @@ bool AMDGPULibCalls::fold_pow(CallInst *CI, IRBuilder<> &B,
|
|||
|
||||
Value *nval;
|
||||
if (needabs) {
|
||||
FunctionCallee AbsExpr =
|
||||
getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_FABS, FInfo));
|
||||
Constant *AbsExpr = getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_FABS,
|
||||
FInfo));
|
||||
if (!AbsExpr)
|
||||
return false;
|
||||
nval = CreateCallEx(B, AbsExpr, opr0, "__fabs");
|
||||
|
@ -1099,8 +1098,8 @@ bool AMDGPULibCalls::fold_pow(CallInst *CI, IRBuilder<> &B,
|
|||
nval = cnval ? cnval : opr0;
|
||||
}
|
||||
if (needlog) {
|
||||
FunctionCallee LogExpr =
|
||||
getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_LOG2, FInfo));
|
||||
Constant *LogExpr = getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_LOG2,
|
||||
FInfo));
|
||||
if (!LogExpr)
|
||||
return false;
|
||||
nval = CreateCallEx(B,LogExpr, nval, "__log2");
|
||||
|
@ -1159,8 +1158,8 @@ bool AMDGPULibCalls::fold_rootn(CallInst *CI, IRBuilder<> &B,
|
|||
std::vector<const Type*> ParamsTys;
|
||||
ParamsTys.push_back(opr0->getType());
|
||||
Module *M = CI->getModule();
|
||||
if (FunctionCallee FPExpr =
|
||||
getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_SQRT, FInfo))) {
|
||||
if (Constant *FPExpr = getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_SQRT,
|
||||
FInfo))) {
|
||||
LLVM_DEBUG(errs() << "AMDIC: " << *CI << " ---> sqrt(" << *opr0 << ")\n");
|
||||
Value *nval = CreateCallEx(B,FPExpr, opr0, "__rootn2sqrt");
|
||||
replaceCall(nval);
|
||||
|
@ -1168,8 +1167,8 @@ bool AMDGPULibCalls::fold_rootn(CallInst *CI, IRBuilder<> &B,
|
|||
}
|
||||
} else if (ci_opr1 == 3) { // rootn(x, 3) = cbrt(x)
|
||||
Module *M = CI->getModule();
|
||||
if (FunctionCallee FPExpr =
|
||||
getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_CBRT, FInfo))) {
|
||||
if (Constant *FPExpr = getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_CBRT,
|
||||
FInfo))) {
|
||||
LLVM_DEBUG(errs() << "AMDIC: " << *CI << " ---> cbrt(" << *opr0 << ")\n");
|
||||
Value *nval = CreateCallEx(B,FPExpr, opr0, "__rootn2cbrt");
|
||||
replaceCall(nval);
|
||||
|
@ -1186,8 +1185,8 @@ bool AMDGPULibCalls::fold_rootn(CallInst *CI, IRBuilder<> &B,
|
|||
std::vector<const Type*> ParamsTys;
|
||||
ParamsTys.push_back(opr0->getType());
|
||||
Module *M = CI->getModule();
|
||||
if (FunctionCallee FPExpr =
|
||||
getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_RSQRT, FInfo))) {
|
||||
if (Constant *FPExpr = getFunction(M, AMDGPULibFunc(AMDGPULibFunc::EI_RSQRT,
|
||||
FInfo))) {
|
||||
LLVM_DEBUG(errs() << "AMDIC: " << *CI << " ---> rsqrt(" << *opr0
|
||||
<< ")\n");
|
||||
Value *nval = CreateCallEx(B,FPExpr, opr0, "__rootn2rsqrt");
|
||||
|
@ -1243,8 +1242,7 @@ bool AMDGPULibCalls::fold_fma_mad(CallInst *CI, IRBuilder<> &B,
|
|||
}
|
||||
|
||||
// Get a scalar native builtin signle argument FP function
|
||||
FunctionCallee AMDGPULibCalls::getNativeFunction(Module *M,
|
||||
const FuncInfo &FInfo) {
|
||||
Constant* AMDGPULibCalls::getNativeFunction(Module* M, const FuncInfo& FInfo) {
|
||||
if (getArgType(FInfo) == AMDGPULibFunc::F64 || !HasNative(FInfo.getId()))
|
||||
return nullptr;
|
||||
FuncInfo nf = FInfo;
|
||||
|
@ -1257,8 +1255,8 @@ bool AMDGPULibCalls::fold_sqrt(CallInst *CI, IRBuilder<> &B,
|
|||
const FuncInfo &FInfo) {
|
||||
if (getArgType(FInfo) == AMDGPULibFunc::F32 && (getVecSize(FInfo) == 1) &&
|
||||
(FInfo.getPrefix() != AMDGPULibFunc::NATIVE)) {
|
||||
if (FunctionCallee FPExpr = getNativeFunction(
|
||||
CI->getModule(), AMDGPULibFunc(AMDGPULibFunc::EI_SQRT, FInfo))) {
|
||||
if (Constant *FPExpr = getNativeFunction(
|
||||
CI->getModule(), AMDGPULibFunc(AMDGPULibFunc::EI_SQRT, FInfo))) {
|
||||
Value *opr0 = CI->getArgOperand(0);
|
||||
LLVM_DEBUG(errs() << "AMDIC: " << *CI << " ---> "
|
||||
<< "sqrt(" << *opr0 << ")\n");
|
||||
|
@ -1335,7 +1333,7 @@ bool AMDGPULibCalls::fold_sincos(CallInst *CI, IRBuilder<> &B,
|
|||
// function.
|
||||
AMDGPULibFunc nf(AMDGPULibFunc::EI_SINCOS, fInfo);
|
||||
nf.getLeads()[0].PtrKind = AMDGPULibFunc::getEPtrKindFromAddrSpace(AMDGPUAS::FLAT_ADDRESS);
|
||||
FunctionCallee Fsincos = getFunction(M, nf);
|
||||
Function *Fsincos = dyn_cast_or_null<Function>(getFunction(M, nf));
|
||||
if (!Fsincos) return false;
|
||||
|
||||
BasicBlock::iterator ItOld = B.GetInsertPoint();
|
||||
|
@ -1343,7 +1341,7 @@ bool AMDGPULibCalls::fold_sincos(CallInst *CI, IRBuilder<> &B,
|
|||
B.SetInsertPoint(UI);
|
||||
|
||||
Value *P = Alloc;
|
||||
Type *PTy = Fsincos.getFunctionType()->getParamType(1);
|
||||
Type *PTy = Fsincos->getFunctionType()->getParamType(1);
|
||||
// The allocaInst allocates the memory in private address space. This need
|
||||
// to be bitcasted to point to the address space of cos pointer type.
|
||||
// In OpenCL 2.0 this is generic, while in 1.2 that is private.
|
||||
|
|
|
@ -960,8 +960,8 @@ Function *AMDGPULibFunc::getFunction(Module *M, const AMDGPULibFunc &fInfo) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
FunctionCallee AMDGPULibFunc::getOrInsertFunction(Module *M,
|
||||
const AMDGPULibFunc &fInfo) {
|
||||
Function *AMDGPULibFunc::getOrInsertFunction(Module *M,
|
||||
const AMDGPULibFunc &fInfo) {
|
||||
std::string const FuncName = fInfo.mangle();
|
||||
Function *F = dyn_cast_or_null<Function>(
|
||||
M->getValueSymbolTable().lookup(FuncName));
|
||||
|
@ -987,7 +987,7 @@ FunctionCallee AMDGPULibFunc::getOrInsertFunction(Module *M,
|
|||
}
|
||||
}
|
||||
|
||||
FunctionCallee C;
|
||||
Constant *C = nullptr;
|
||||
if (hasPtr) {
|
||||
// Do not set extra attributes for functions with pointer arguments.
|
||||
C = M->getOrInsertFunction(FuncName, FuncTy);
|
||||
|
@ -1001,7 +1001,7 @@ FunctionCallee AMDGPULibFunc::getOrInsertFunction(Module *M,
|
|||
C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
|
||||
}
|
||||
|
||||
return C;
|
||||
return cast<Function>(C);
|
||||
}
|
||||
|
||||
bool UnmangledFuncInfo::lookup(StringRef Name, ID &Id) {
|
||||
|
|
|
@ -393,8 +393,8 @@ public:
|
|||
}
|
||||
static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
|
||||
|
||||
static FunctionCallee getOrInsertFunction(llvm::Module *M,
|
||||
const AMDGPULibFunc &fInfo);
|
||||
static Function *getOrInsertFunction(llvm::Module *M,
|
||||
const AMDGPULibFunc &fInfo);
|
||||
static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
|
||||
|
||||
private:
|
||||
|
|
|
@ -2253,8 +2253,10 @@ CleanupAndExit:
|
|||
Type *Int32PtrTy = Type::getInt32PtrTy(Ctx);
|
||||
Type *VoidTy = Type::getVoidTy(Ctx);
|
||||
Module *M = Func->getParent();
|
||||
FunctionCallee Fn = M->getOrInsertFunction(
|
||||
HexagonVolatileMemcpyName, VoidTy, Int32PtrTy, Int32PtrTy, Int32Ty);
|
||||
Constant *CF = M->getOrInsertFunction(HexagonVolatileMemcpyName, VoidTy,
|
||||
Int32PtrTy, Int32PtrTy, Int32Ty);
|
||||
Function *Fn = cast<Function>(CF);
|
||||
Fn->setLinkage(Function::ExternalLinkage);
|
||||
|
||||
const SCEV *OneS = SE->getConstant(Int32Ty, 1);
|
||||
const SCEV *BECount32 = SE->getTruncateOrZeroExtend(BECount, Int32Ty);
|
||||
|
|
|
@ -414,7 +414,7 @@ static bool fixupFPReturnAndCall(Function &F, Module *M,
|
|||
Attribute::ReadNone);
|
||||
A = A.addAttribute(C, AttributeList::FunctionIndex,
|
||||
Attribute::NoInline);
|
||||
FunctionCallee F = (M->getOrInsertFunction(Name, A, MyVoid, T));
|
||||
Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T));
|
||||
CallInst::Create(F, Params, "", &I);
|
||||
} else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
|
||||
FunctionType *FT = CI->getFunctionType();
|
||||
|
|
|
@ -109,11 +109,10 @@ bool LowerGlobalDtors::runOnModule(Module &M) {
|
|||
FunctionType::get(Type::getVoidTy(C), AtExitFuncArgs,
|
||||
/*isVarArg=*/false);
|
||||
|
||||
FunctionCallee AtExit = M.getOrInsertFunction(
|
||||
"__cxa_atexit",
|
||||
FunctionType::get(Type::getInt32Ty(C),
|
||||
{PointerType::get(AtExitFuncTy, 0), VoidStar, VoidStar},
|
||||
/*isVarArg=*/false));
|
||||
Type *AtExitArgs[] = {PointerType::get(AtExitFuncTy, 0), VoidStar, VoidStar};
|
||||
FunctionType *AtExitTy = FunctionType::get(Type::getInt32Ty(C), AtExitArgs,
|
||||
/*isVarArg=*/false);
|
||||
Constant *AtExit = M.getOrInsertFunction("__cxa_atexit", AtExitTy);
|
||||
|
||||
// Declare __dso_local.
|
||||
Constant *DsoHandle = M.getNamedValue("__dso_handle");
|
||||
|
|
|
@ -2279,13 +2279,12 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const {
|
|||
Type::getInt8PtrTy(M.getContext()));
|
||||
|
||||
// MSVC CRT has a function to validate security cookie.
|
||||
FunctionCallee SecurityCheckCookie = M.getOrInsertFunction(
|
||||
"__security_check_cookie", Type::getVoidTy(M.getContext()),
|
||||
Type::getInt8PtrTy(M.getContext()));
|
||||
if (Function *F = dyn_cast<Function>(SecurityCheckCookie.getCallee())) {
|
||||
F->setCallingConv(CallingConv::X86_FastCall);
|
||||
F->addAttribute(1, Attribute::AttrKind::InReg);
|
||||
}
|
||||
auto *SecurityCheckCookie = cast<Function>(
|
||||
M.getOrInsertFunction("__security_check_cookie",
|
||||
Type::getVoidTy(M.getContext()),
|
||||
Type::getInt8PtrTy(M.getContext())));
|
||||
SecurityCheckCookie->setCallingConv(CallingConv::X86_FastCall);
|
||||
SecurityCheckCookie->addAttribute(1, Attribute::AttrKind::InReg);
|
||||
return;
|
||||
}
|
||||
// glibc, bionic, and Fuchsia have a special slot for the stack guard.
|
||||
|
|
|
@ -86,15 +86,15 @@ private:
|
|||
StructType *EHLinkRegistrationTy = nullptr;
|
||||
StructType *CXXEHRegistrationTy = nullptr;
|
||||
StructType *SEHRegistrationTy = nullptr;
|
||||
FunctionCallee SetJmp3 = nullptr;
|
||||
FunctionCallee CxxLongjmpUnwind = nullptr;
|
||||
Constant *SetJmp3 = nullptr;
|
||||
Constant *CxxLongjmpUnwind = nullptr;
|
||||
|
||||
// Per-function state
|
||||
EHPersonality Personality = EHPersonality::Unknown;
|
||||
Function *PersonalityFn = nullptr;
|
||||
bool UseStackGuard = false;
|
||||
int ParentBaseState;
|
||||
FunctionCallee SehLongjmpUnwind = nullptr;
|
||||
Constant *SehLongjmpUnwind = nullptr;
|
||||
Constant *Cookie = nullptr;
|
||||
|
||||
/// The stack allocation containing all EH data, including the link in the
|
||||
|
@ -303,7 +303,7 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
|
|||
CxxLongjmpUnwind = TheModule->getOrInsertFunction(
|
||||
"__CxxLongjmpUnwind",
|
||||
FunctionType::get(VoidTy, Int8PtrType, /*isVarArg=*/false));
|
||||
cast<Function>(CxxLongjmpUnwind.getCallee()->stripPointerCasts())
|
||||
cast<Function>(CxxLongjmpUnwind->stripPointerCasts())
|
||||
->setCallingConv(CallingConv::X86_StdCall);
|
||||
} else if (Personality == EHPersonality::MSVC_X86SEH) {
|
||||
// If _except_handler4 is in use, some additional guard checks and prologue
|
||||
|
@ -356,7 +356,7 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
|
|||
UseStackGuard ? "_seh_longjmp_unwind4" : "_seh_longjmp_unwind",
|
||||
FunctionType::get(Type::getVoidTy(TheModule->getContext()), Int8PtrType,
|
||||
/*isVarArg=*/false));
|
||||
cast<Function>(SehLongjmpUnwind.getCallee()->stripPointerCasts())
|
||||
cast<Function>(SehLongjmpUnwind->stripPointerCasts())
|
||||
->setCallingConv(CallingConv::X86_StdCall);
|
||||
} else {
|
||||
llvm_unreachable("unexpected personality function");
|
||||
|
@ -471,11 +471,11 @@ void WinEHStatePass::rewriteSetJmpCallSite(IRBuilder<> &Builder, Function &F,
|
|||
|
||||
SmallVector<Value *, 3> OptionalArgs;
|
||||
if (Personality == EHPersonality::MSVC_CXX) {
|
||||
OptionalArgs.push_back(CxxLongjmpUnwind.getCallee());
|
||||
OptionalArgs.push_back(CxxLongjmpUnwind);
|
||||
OptionalArgs.push_back(State);
|
||||
OptionalArgs.push_back(emitEHLSDA(Builder, &F));
|
||||
} else if (Personality == EHPersonality::MSVC_X86SEH) {
|
||||
OptionalArgs.push_back(SehLongjmpUnwind.getCallee());
|
||||
OptionalArgs.push_back(SehLongjmpUnwind);
|
||||
OptionalArgs.push_back(State);
|
||||
if (UseStackGuard)
|
||||
OptionalArgs.push_back(Cookie);
|
||||
|
@ -766,7 +766,7 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
|
|||
if (!CS)
|
||||
continue;
|
||||
if (CS.getCalledValue()->stripPointerCasts() !=
|
||||
SetJmp3.getCallee()->stripPointerCasts())
|
||||
SetJmp3->stripPointerCasts())
|
||||
continue;
|
||||
|
||||
SetJmp3CallSites.push_back(CS);
|
||||
|
|
|
@ -105,10 +105,10 @@ void CrossDSOCFI::buildCFICheck(Module &M) {
|
|||
}
|
||||
|
||||
LLVMContext &Ctx = M.getContext();
|
||||
FunctionCallee C = M.getOrInsertFunction(
|
||||
Constant *C = M.getOrInsertFunction(
|
||||
"__cfi_check", Type::getVoidTy(Ctx), Type::getInt64Ty(Ctx),
|
||||
Type::getInt8PtrTy(Ctx), Type::getInt8PtrTy(Ctx));
|
||||
Function *F = dyn_cast<Function>(C.getCallee());
|
||||
Function *F = dyn_cast<Function>(C);
|
||||
// Take over the existing function. The frontend emits a weak stub so that the
|
||||
// linker knows about the symbol; this pass replaces the function body.
|
||||
F->deleteBody();
|
||||
|
@ -132,9 +132,9 @@ void CrossDSOCFI::buildCFICheck(Module &M) {
|
|||
|
||||
BasicBlock *TrapBB = BasicBlock::Create(Ctx, "fail", F);
|
||||
IRBuilder<> IRBFail(TrapBB);
|
||||
FunctionCallee CFICheckFailFn =
|
||||
M.getOrInsertFunction("__cfi_check_fail", Type::getVoidTy(Ctx),
|
||||
Type::getInt8PtrTy(Ctx), Type::getInt8PtrTy(Ctx));
|
||||
Constant *CFICheckFailFn = M.getOrInsertFunction(
|
||||
"__cfi_check_fail", Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx),
|
||||
Type::getInt8PtrTy(Ctx));
|
||||
IRBFail.CreateCall(CFICheckFailFn, {&CFICheckFailData, &Addr});
|
||||
IRBFail.CreateBr(ExitBB);
|
||||
|
||||
|
|
|
@ -1494,10 +1494,8 @@ void DevirtModule::importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo) {
|
|||
if (Res.TheKind == WholeProgramDevirtResolution::SingleImpl) {
|
||||
// The type of the function in the declaration is irrelevant because every
|
||||
// call site will cast it to the correct type.
|
||||
Constant *SingleImpl =
|
||||
cast<Constant>(M.getOrInsertFunction(Res.SingleImplName,
|
||||
Type::getVoidTy(M.getContext()))
|
||||
.getCallee());
|
||||
auto *SingleImpl = M.getOrInsertFunction(
|
||||
Res.SingleImplName, Type::getVoidTy(M.getContext()));
|
||||
|
||||
// This is the import phase so we should not be exporting anything.
|
||||
bool IsExported = false;
|
||||
|
@ -1539,12 +1537,8 @@ void DevirtModule::importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo) {
|
|||
}
|
||||
|
||||
if (Res.TheKind == WholeProgramDevirtResolution::BranchFunnel) {
|
||||
// The type of the function is irrelevant, because it's bitcast at calls
|
||||
// anyhow.
|
||||
Constant *JT = cast<Constant>(
|
||||
M.getOrInsertFunction(getGlobalName(Slot, {}, "branch_funnel"),
|
||||
Type::getVoidTy(M.getContext()))
|
||||
.getCallee());
|
||||
auto *JT = M.getOrInsertFunction(getGlobalName(Slot, {}, "branch_funnel"),
|
||||
Type::getVoidTy(M.getContext()));
|
||||
bool IsExported = false;
|
||||
applyICallBranchFunnel(SlotInfo, JT, IsExported);
|
||||
assert(!IsExported);
|
||||
|
|
|
@ -715,19 +715,19 @@ private:
|
|||
Type *IntptrTy;
|
||||
ShadowMapping Mapping;
|
||||
DominatorTree *DT;
|
||||
FunctionCallee AsanHandleNoReturnFunc;
|
||||
FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
|
||||
Function *AsanHandleNoReturnFunc;
|
||||
Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
|
||||
Constant *AsanShadowGlobal;
|
||||
|
||||
// These arrays is indexed by AccessIsWrite, Experiment and log2(AccessSize).
|
||||
FunctionCallee AsanErrorCallback[2][2][kNumberOfAccessSizes];
|
||||
FunctionCallee AsanMemoryAccessCallback[2][2][kNumberOfAccessSizes];
|
||||
Function *AsanErrorCallback[2][2][kNumberOfAccessSizes];
|
||||
Function *AsanMemoryAccessCallback[2][2][kNumberOfAccessSizes];
|
||||
|
||||
// These arrays is indexed by AccessIsWrite and Experiment.
|
||||
FunctionCallee AsanErrorCallbackSized[2][2];
|
||||
FunctionCallee AsanMemoryAccessCallbackSized[2][2];
|
||||
Function *AsanErrorCallbackSized[2][2];
|
||||
Function *AsanMemoryAccessCallbackSized[2][2];
|
||||
|
||||
FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
|
||||
Function *AsanMemmove, *AsanMemcpy, *AsanMemset;
|
||||
InlineAsm *EmptyAsm;
|
||||
Value *LocalDynamicShadow = nullptr;
|
||||
GlobalsMetadata GlobalsMD;
|
||||
|
@ -809,14 +809,14 @@ private:
|
|||
LLVMContext *C;
|
||||
Triple TargetTriple;
|
||||
ShadowMapping Mapping;
|
||||
FunctionCallee AsanPoisonGlobals;
|
||||
FunctionCallee AsanUnpoisonGlobals;
|
||||
FunctionCallee AsanRegisterGlobals;
|
||||
FunctionCallee AsanUnregisterGlobals;
|
||||
FunctionCallee AsanRegisterImageGlobals;
|
||||
FunctionCallee AsanUnregisterImageGlobals;
|
||||
FunctionCallee AsanRegisterElfGlobals;
|
||||
FunctionCallee AsanUnregisterElfGlobals;
|
||||
Function *AsanPoisonGlobals;
|
||||
Function *AsanUnpoisonGlobals;
|
||||
Function *AsanRegisterGlobals;
|
||||
Function *AsanUnregisterGlobals;
|
||||
Function *AsanRegisterImageGlobals;
|
||||
Function *AsanUnregisterImageGlobals;
|
||||
Function *AsanRegisterElfGlobals;
|
||||
Function *AsanUnregisterElfGlobals;
|
||||
|
||||
Function *AsanCtorFunction = nullptr;
|
||||
Function *AsanDtorFunction = nullptr;
|
||||
|
@ -845,11 +845,11 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
|
|||
SmallVector<Instruction *, 8> RetVec;
|
||||
unsigned StackAlignment;
|
||||
|
||||
FunctionCallee AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1],
|
||||
AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1];
|
||||
FunctionCallee AsanSetShadowFunc[0x100] = {};
|
||||
FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
|
||||
FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
|
||||
Function *AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1],
|
||||
*AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1];
|
||||
Function *AsanSetShadowFunc[0x100] = {};
|
||||
Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc;
|
||||
Function *AsanAllocaPoisonFunc, *AsanAllocasUnpoisonFunc;
|
||||
|
||||
// Stores a place and arguments of poisoning/unpoisoning call for alloca.
|
||||
struct AllocaPoisonCall {
|
||||
|
@ -1333,7 +1333,7 @@ bool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) {
|
|||
void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
|
||||
Instruction *I) {
|
||||
IRBuilder<> IRB(I);
|
||||
FunctionCallee F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
|
||||
Function *F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
|
||||
Value *Param[2] = {I->getOperand(0), I->getOperand(1)};
|
||||
for (Value *&i : Param) {
|
||||
if (i->getType()->isPointerTy())
|
||||
|
@ -1795,30 +1795,43 @@ void AddressSanitizerModule::initializeCallbacks(Module &M) {
|
|||
IRBuilder<> IRB(*C);
|
||||
|
||||
// Declare our poisoning and unpoisoning functions.
|
||||
AsanPoisonGlobals =
|
||||
M.getOrInsertFunction(kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy);
|
||||
AsanUnpoisonGlobals =
|
||||
M.getOrInsertFunction(kAsanUnpoisonGlobalsName, IRB.getVoidTy());
|
||||
AsanPoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy));
|
||||
AsanPoisonGlobals->setLinkage(Function::ExternalLinkage);
|
||||
AsanUnpoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanUnpoisonGlobalsName, IRB.getVoidTy()));
|
||||
AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage);
|
||||
|
||||
// Declare functions that register/unregister globals.
|
||||
AsanRegisterGlobals = M.getOrInsertFunction(
|
||||
kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
AsanUnregisterGlobals = M.getOrInsertFunction(
|
||||
kAsanUnregisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
AsanRegisterGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy));
|
||||
AsanRegisterGlobals->setLinkage(Function::ExternalLinkage);
|
||||
AsanUnregisterGlobals = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanUnregisterGlobalsName, IRB.getVoidTy(),
|
||||
IntptrTy, IntptrTy));
|
||||
AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage);
|
||||
|
||||
// Declare the functions that find globals in a shared object and then invoke
|
||||
// the (un)register function on them.
|
||||
AsanRegisterImageGlobals = M.getOrInsertFunction(
|
||||
kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy);
|
||||
AsanUnregisterImageGlobals = M.getOrInsertFunction(
|
||||
kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy);
|
||||
AsanRegisterImageGlobals =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy));
|
||||
AsanRegisterImageGlobals->setLinkage(Function::ExternalLinkage);
|
||||
|
||||
AsanRegisterElfGlobals =
|
||||
AsanUnregisterImageGlobals =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy));
|
||||
AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage);
|
||||
|
||||
AsanRegisterElfGlobals = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanRegisterElfGlobalsName, IRB.getVoidTy(),
|
||||
IntptrTy, IntptrTy, IntptrTy);
|
||||
AsanUnregisterElfGlobals =
|
||||
IntptrTy, IntptrTy, IntptrTy));
|
||||
AsanRegisterElfGlobals->setLinkage(Function::ExternalLinkage);
|
||||
|
||||
AsanUnregisterElfGlobals = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanUnregisterElfGlobalsName, IRB.getVoidTy(),
|
||||
IntptrTy, IntptrTy, IntptrTy);
|
||||
IntptrTy, IntptrTy, IntptrTy));
|
||||
AsanUnregisterElfGlobals->setLinkage(Function::ExternalLinkage);
|
||||
}
|
||||
|
||||
// Put the metadata and the instrumented global in the same group. This ensures
|
||||
|
@ -2332,49 +2345,51 @@ void AddressSanitizer::initializeCallbacks(Module &M) {
|
|||
Args2.push_back(ExpType);
|
||||
Args1.push_back(ExpType);
|
||||
}
|
||||
AsanErrorCallbackSized[AccessIsWrite][Exp] = M.getOrInsertFunction(
|
||||
kAsanReportErrorTemplate + ExpStr + TypeStr + "_n" + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), Args2, false));
|
||||
AsanErrorCallbackSized[AccessIsWrite][Exp] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanReportErrorTemplate + ExpStr + TypeStr + "_n" + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), Args2, false)));
|
||||
|
||||
AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] = M.getOrInsertFunction(
|
||||
ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N" + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), Args2, false));
|
||||
AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N" + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), Args2, false)));
|
||||
|
||||
for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
|
||||
AccessSizeIndex++) {
|
||||
const std::string Suffix = TypeStr + itostr(1ULL << AccessSizeIndex);
|
||||
AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
|
||||
M.getOrInsertFunction(
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanReportErrorTemplate + ExpStr + Suffix + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), Args1, false));
|
||||
FunctionType::get(IRB.getVoidTy(), Args1, false)));
|
||||
|
||||
AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
|
||||
M.getOrInsertFunction(
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
ClMemoryAccessCallbackPrefix + ExpStr + Suffix + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), Args1, false));
|
||||
FunctionType::get(IRB.getVoidTy(), Args1, false)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string MemIntrinCallbackPrefix =
|
||||
CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix;
|
||||
AsanMemmove = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memmove",
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy);
|
||||
AsanMemcpy = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memcpy",
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy);
|
||||
AsanMemset = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memset",
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt32Ty(), IntptrTy);
|
||||
AsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
MemIntrinCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy));
|
||||
AsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
MemIntrinCallbackPrefix + "memcpy", IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy));
|
||||
AsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
MemIntrinCallbackPrefix + "memset", IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy));
|
||||
|
||||
AsanHandleNoReturnFunc =
|
||||
M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy());
|
||||
AsanHandleNoReturnFunc = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy()));
|
||||
|
||||
AsanPtrCmpFunction =
|
||||
M.getOrInsertFunction(kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
AsanPtrSubFunction =
|
||||
M.getOrInsertFunction(kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
AsanPtrCmpFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy));
|
||||
AsanPtrSubFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy));
|
||||
// We insert an empty inline asm after __asan_report* to avoid callback merge.
|
||||
EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
|
||||
StringRef(""), StringRef(""),
|
||||
|
@ -2412,7 +2427,7 @@ bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
|
|||
// We cannot just ignore these methods, because they may call other
|
||||
// instrumented functions.
|
||||
if (F.getName().find(" load]") != std::string::npos) {
|
||||
FunctionCallee AsanInitFunction =
|
||||
Function *AsanInitFunction =
|
||||
declareSanitizerInitFunction(*F.getParent(), kAsanInitName, {});
|
||||
IRBuilder<> IRB(&F.front(), F.front().begin());
|
||||
IRB.CreateCall(AsanInitFunction, {});
|
||||
|
@ -2627,17 +2642,20 @@ void FunctionStackPoisoner::initializeCallbacks(Module &M) {
|
|||
IRBuilder<> IRB(*C);
|
||||
for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) {
|
||||
std::string Suffix = itostr(i);
|
||||
AsanStackMallocFunc[i] = M.getOrInsertFunction(
|
||||
kAsanStackMallocNameTemplate + Suffix, IntptrTy, IntptrTy);
|
||||
AsanStackFreeFunc[i] =
|
||||
AsanStackMallocFunc[i] = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanStackMallocNameTemplate + Suffix, IntptrTy,
|
||||
IntptrTy));
|
||||
AsanStackFreeFunc[i] = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix,
|
||||
IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
IRB.getVoidTy(), IntptrTy, IntptrTy));
|
||||
}
|
||||
if (ASan.UseAfterScope) {
|
||||
AsanPoisonStackMemoryFunc = M.getOrInsertFunction(
|
||||
kAsanPoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
AsanUnpoisonStackMemoryFunc = M.getOrInsertFunction(
|
||||
kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
AsanPoisonStackMemoryFunc = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanPoisonStackMemoryName, IRB.getVoidTy(),
|
||||
IntptrTy, IntptrTy));
|
||||
AsanUnpoisonStackMemoryFunc = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(kAsanUnpoisonStackMemoryName, IRB.getVoidTy(),
|
||||
IntptrTy, IntptrTy));
|
||||
}
|
||||
|
||||
for (size_t Val : {0x00, 0xf1, 0xf2, 0xf3, 0xf5, 0xf8}) {
|
||||
|
@ -2645,13 +2663,15 @@ void FunctionStackPoisoner::initializeCallbacks(Module &M) {
|
|||
Name << kAsanSetShadowPrefix;
|
||||
Name << std::setw(2) << std::setfill('0') << std::hex << Val;
|
||||
AsanSetShadowFunc[Val] =
|
||||
M.getOrInsertFunction(Name.str(), IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
Name.str(), IRB.getVoidTy(), IntptrTy, IntptrTy));
|
||||
}
|
||||
|
||||
AsanAllocaPoisonFunc = M.getOrInsertFunction(
|
||||
kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
AsanAllocasUnpoisonFunc = M.getOrInsertFunction(
|
||||
kAsanAllocasUnpoison, IRB.getVoidTy(), IntptrTy, IntptrTy);
|
||||
AsanAllocaPoisonFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy));
|
||||
AsanAllocasUnpoisonFunc =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
kAsanAllocasUnpoison, IRB.getVoidTy(), IntptrTy, IntptrTy));
|
||||
}
|
||||
|
||||
void FunctionStackPoisoner::copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
|
||||
|
|
|
@ -341,13 +341,13 @@ class DataFlowSanitizer : public ModulePass {
|
|||
FunctionType *DFSanSetLabelFnTy;
|
||||
FunctionType *DFSanNonzeroLabelFnTy;
|
||||
FunctionType *DFSanVarargWrapperFnTy;
|
||||
FunctionCallee DFSanUnionFn;
|
||||
FunctionCallee DFSanCheckedUnionFn;
|
||||
FunctionCallee DFSanUnionLoadFn;
|
||||
FunctionCallee DFSanUnimplementedFn;
|
||||
FunctionCallee DFSanSetLabelFn;
|
||||
FunctionCallee DFSanNonzeroLabelFn;
|
||||
FunctionCallee DFSanVarargWrapperFn;
|
||||
Constant *DFSanUnionFn;
|
||||
Constant *DFSanCheckedUnionFn;
|
||||
Constant *DFSanUnionLoadFn;
|
||||
Constant *DFSanUnimplementedFn;
|
||||
Constant *DFSanSetLabelFn;
|
||||
Constant *DFSanNonzeroLabelFn;
|
||||
Constant *DFSanVarargWrapperFn;
|
||||
MDNode *ColdCallWeights;
|
||||
DFSanABIList ABIList;
|
||||
DenseMap<Value *, Function *> UnwrappedFnMap;
|
||||
|
@ -677,8 +677,8 @@ DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName,
|
|||
Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT,
|
||||
StringRef FName) {
|
||||
FunctionType *FTT = getTrampolineFunctionType(FT);
|
||||
FunctionCallee C = Mod->getOrInsertFunction(FName, FTT);
|
||||
Function *F = dyn_cast<Function>(C.getCallee());
|
||||
Constant *C = Mod->getOrInsertFunction(FName, FTT);
|
||||
Function *F = dyn_cast<Function>(C);
|
||||
if (F && F->isDeclaration()) {
|
||||
F->setLinkage(GlobalValue::LinkOnceODRLinkage);
|
||||
BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
|
||||
|
@ -703,7 +703,7 @@ Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT,
|
|||
&*std::prev(F->arg_end()), RI);
|
||||
}
|
||||
|
||||
return cast<Constant>(C.getCallee());
|
||||
return C;
|
||||
}
|
||||
|
||||
bool DataFlowSanitizer::runOnModule(Module &M) {
|
||||
|
@ -725,51 +725,35 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
|
|||
ExternalShadowMask =
|
||||
Mod->getOrInsertGlobal(kDFSanExternShadowPtrMask, IntptrTy);
|
||||
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::NoUnwind);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::ReadNone);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex,
|
||||
Attribute::ZExt);
|
||||
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
|
||||
AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
|
||||
DFSanUnionFn =
|
||||
Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy, AL);
|
||||
DFSanUnionFn = Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy);
|
||||
if (Function *F = dyn_cast<Function>(DFSanUnionFn)) {
|
||||
F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
|
||||
F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone);
|
||||
F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
|
||||
F->addParamAttr(0, Attribute::ZExt);
|
||||
F->addParamAttr(1, Attribute::ZExt);
|
||||
}
|
||||
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::NoUnwind);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::ReadNone);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex,
|
||||
Attribute::ZExt);
|
||||
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
|
||||
AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
|
||||
DFSanCheckedUnionFn =
|
||||
Mod->getOrInsertFunction("dfsan_union", DFSanUnionFnTy, AL);
|
||||
DFSanCheckedUnionFn = Mod->getOrInsertFunction("dfsan_union", DFSanUnionFnTy);
|
||||
if (Function *F = dyn_cast<Function>(DFSanCheckedUnionFn)) {
|
||||
F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
|
||||
F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone);
|
||||
F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
|
||||
F->addParamAttr(0, Attribute::ZExt);
|
||||
F->addParamAttr(1, Attribute::ZExt);
|
||||
}
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::NoUnwind);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::ReadOnly);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex,
|
||||
Attribute::ZExt);
|
||||
DFSanUnionLoadFn =
|
||||
Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy, AL);
|
||||
DFSanUnionLoadFn =
|
||||
Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy);
|
||||
if (Function *F = dyn_cast<Function>(DFSanUnionLoadFn)) {
|
||||
F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
|
||||
F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly);
|
||||
F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
|
||||
}
|
||||
DFSanUnimplementedFn =
|
||||
Mod->getOrInsertFunction("__dfsan_unimplemented", DFSanUnimplementedFnTy);
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
|
||||
DFSanSetLabelFn =
|
||||
Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy, AL);
|
||||
DFSanSetLabelFn =
|
||||
Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy);
|
||||
if (Function *F = dyn_cast<Function>(DFSanSetLabelFn)) {
|
||||
F->addParamAttr(0, Attribute::ZExt);
|
||||
}
|
||||
DFSanNonzeroLabelFn =
|
||||
Mod->getOrInsertFunction("__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
|
||||
|
@ -780,13 +764,13 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
|
|||
SmallPtrSet<Function *, 2> FnsWithNativeABI;
|
||||
for (Function &i : M) {
|
||||
if (!i.isIntrinsic() &&
|
||||
&i != DFSanUnionFn.getCallee()->stripPointerCasts() &&
|
||||
&i != DFSanCheckedUnionFn.getCallee()->stripPointerCasts() &&
|
||||
&i != DFSanUnionLoadFn.getCallee()->stripPointerCasts() &&
|
||||
&i != DFSanUnimplementedFn.getCallee()->stripPointerCasts() &&
|
||||
&i != DFSanSetLabelFn.getCallee()->stripPointerCasts() &&
|
||||
&i != DFSanNonzeroLabelFn.getCallee()->stripPointerCasts() &&
|
||||
&i != DFSanVarargWrapperFn.getCallee()->stripPointerCasts())
|
||||
&i != DFSanUnionFn &&
|
||||
&i != DFSanCheckedUnionFn &&
|
||||
&i != DFSanUnionLoadFn &&
|
||||
&i != DFSanUnimplementedFn &&
|
||||
&i != DFSanSetLabelFn &&
|
||||
&i != DFSanNonzeroLabelFn &&
|
||||
&i != DFSanVarargWrapperFn)
|
||||
FnsToInstrument.push_back(&i);
|
||||
}
|
||||
|
||||
|
@ -1528,7 +1512,7 @@ void DFSanVisitor::visitCallSite(CallSite CS) {
|
|||
|
||||
// Calls to this function are synthesized in wrappers, and we shouldn't
|
||||
// instrument them.
|
||||
if (F == DFSF.DFS.DFSanVarargWrapperFn.getCallee()->stripPointerCasts())
|
||||
if (F == DFSF.DFS.DFSanVarargWrapperFn)
|
||||
return;
|
||||
|
||||
IRBuilder<> IRB(CS.getInstruction());
|
||||
|
@ -1561,9 +1545,9 @@ void DFSanVisitor::visitCallSite(CallSite CS) {
|
|||
TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT);
|
||||
std::string CustomFName = "__dfsw_";
|
||||
CustomFName += F->getName();
|
||||
FunctionCallee CustomF = DFSF.DFS.Mod->getOrInsertFunction(
|
||||
Constant *CustomF = DFSF.DFS.Mod->getOrInsertFunction(
|
||||
CustomFName, CustomFn.TransformedType);
|
||||
if (Function *CustomFn = dyn_cast<Function>(CustomF.getCallee())) {
|
||||
if (Function *CustomFn = dyn_cast<Function>(CustomF)) {
|
||||
CustomFn->copyAttributesFrom(F);
|
||||
|
||||
// Custom functions returning non-void will write to the return label.
|
||||
|
|
|
@ -202,13 +202,13 @@ private:
|
|||
// Our slowpath involves callouts to the runtime library.
|
||||
// Access sizes are powers of two: 1, 2, 4, 8, 16.
|
||||
static const size_t NumberOfAccessSizes = 5;
|
||||
FunctionCallee EsanAlignedLoad[NumberOfAccessSizes];
|
||||
FunctionCallee EsanAlignedStore[NumberOfAccessSizes];
|
||||
FunctionCallee EsanUnalignedLoad[NumberOfAccessSizes];
|
||||
FunctionCallee EsanUnalignedStore[NumberOfAccessSizes];
|
||||
Function *EsanAlignedLoad[NumberOfAccessSizes];
|
||||
Function *EsanAlignedStore[NumberOfAccessSizes];
|
||||
Function *EsanUnalignedLoad[NumberOfAccessSizes];
|
||||
Function *EsanUnalignedStore[NumberOfAccessSizes];
|
||||
// For irregular sizes of any alignment:
|
||||
FunctionCallee EsanUnalignedLoadN, EsanUnalignedStoreN;
|
||||
FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
|
||||
Function *EsanUnalignedLoadN, *EsanUnalignedStoreN;
|
||||
Function *MemmoveFn, *MemcpyFn, *MemsetFn;
|
||||
Function *EsanCtorFunction;
|
||||
Function *EsanDtorFunction;
|
||||
// Remember the counter variable for each struct type to avoid
|
||||
|
@ -249,31 +249,37 @@ void EfficiencySanitizer::initializeCallbacks(Module &M) {
|
|||
// We'll inline the most common (i.e., aligned and frequent sizes)
|
||||
// load + store instrumentation: these callouts are for the slowpath.
|
||||
SmallString<32> AlignedLoadName("__esan_aligned_load" + ByteSizeStr);
|
||||
EsanAlignedLoad[Idx] = M.getOrInsertFunction(
|
||||
AlignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy());
|
||||
EsanAlignedLoad[Idx] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
AlignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
SmallString<32> AlignedStoreName("__esan_aligned_store" + ByteSizeStr);
|
||||
EsanAlignedStore[Idx] = M.getOrInsertFunction(
|
||||
AlignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy());
|
||||
EsanAlignedStore[Idx] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
AlignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
SmallString<32> UnalignedLoadName("__esan_unaligned_load" + ByteSizeStr);
|
||||
EsanUnalignedLoad[Idx] = M.getOrInsertFunction(
|
||||
UnalignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy());
|
||||
EsanUnalignedLoad[Idx] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
UnalignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
SmallString<32> UnalignedStoreName("__esan_unaligned_store" + ByteSizeStr);
|
||||
EsanUnalignedStore[Idx] = M.getOrInsertFunction(
|
||||
UnalignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy());
|
||||
EsanUnalignedStore[Idx] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
UnalignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
}
|
||||
EsanUnalignedLoadN = M.getOrInsertFunction(
|
||||
"__esan_unaligned_loadN", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy);
|
||||
EsanUnalignedStoreN = M.getOrInsertFunction(
|
||||
"__esan_unaligned_storeN", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy);
|
||||
MemmoveFn =
|
||||
EsanUnalignedLoadN = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("__esan_unaligned_loadN", IRB.getVoidTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy));
|
||||
EsanUnalignedStoreN = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("__esan_unaligned_storeN", IRB.getVoidTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy));
|
||||
MemmoveFn = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy);
|
||||
MemcpyFn =
|
||||
IRB.getInt8PtrTy(), IntptrTy));
|
||||
MemcpyFn = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy);
|
||||
MemsetFn =
|
||||
IRB.getInt8PtrTy(), IntptrTy));
|
||||
MemsetFn = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt32Ty(), IntptrTy);
|
||||
IRB.getInt32Ty(), IntptrTy));
|
||||
}
|
||||
|
||||
bool EfficiencySanitizer::shouldIgnoreStructType(StructType *StructTy) {
|
||||
|
@ -504,8 +510,10 @@ void EfficiencySanitizer::createDestructor(Module &M, Constant *ToolInfoArg) {
|
|||
EsanModuleDtorName, &M);
|
||||
ReturnInst::Create(*Ctx, BasicBlock::Create(*Ctx, "", EsanDtorFunction));
|
||||
IRBuilder<> IRB_Dtor(EsanDtorFunction->getEntryBlock().getTerminator());
|
||||
FunctionCallee EsanExit =
|
||||
M.getOrInsertFunction(EsanExitName, IRB_Dtor.getVoidTy(), Int8PtrTy);
|
||||
Function *EsanExit = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(EsanExitName, IRB_Dtor.getVoidTy(),
|
||||
Int8PtrTy));
|
||||
EsanExit->setLinkage(Function::ExternalLinkage);
|
||||
IRB_Dtor.CreateCall(EsanExit, {ToolInfoArg});
|
||||
appendToGlobalDtors(M, EsanDtorFunction, EsanCtorAndDtorPriority);
|
||||
}
|
||||
|
@ -661,7 +669,7 @@ bool EfficiencySanitizer::instrumentLoadOrStore(Instruction *I,
|
|||
|
||||
Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType();
|
||||
const uint32_t TypeSizeBytes = DL.getTypeStoreSizeInBits(OrigTy) / 8;
|
||||
FunctionCallee OnAccessFunc = nullptr;
|
||||
Value *OnAccessFunc = nullptr;
|
||||
|
||||
// Convert 0 to the default alignment.
|
||||
if (Alignment == 0)
|
||||
|
|
|
@ -102,11 +102,11 @@ private:
|
|||
std::vector<Regex> &Regexes);
|
||||
|
||||
// Get pointers to the functions in the runtime library.
|
||||
FunctionCallee getStartFileFunc();
|
||||
FunctionCallee getEmitFunctionFunc();
|
||||
FunctionCallee getEmitArcsFunc();
|
||||
FunctionCallee getSummaryInfoFunc();
|
||||
FunctionCallee getEndFileFunc();
|
||||
Constant *getStartFileFunc();
|
||||
Constant *getEmitFunctionFunc();
|
||||
Constant *getEmitArcsFunc();
|
||||
Constant *getSummaryInfoFunc();
|
||||
Constant *getEndFileFunc();
|
||||
|
||||
// Add the function to write out all our counters to the global destructor
|
||||
// list.
|
||||
|
@ -647,7 +647,7 @@ void GCOVProfiler::AddFlushBeforeForkAndExec() {
|
|||
for (auto I : ForkAndExecs) {
|
||||
IRBuilder<> Builder(I);
|
||||
FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
|
||||
FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
|
||||
Constant *GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
|
||||
Builder.CreateCall(GCOVFlush);
|
||||
I->getParent()->splitBasicBlock(I);
|
||||
}
|
||||
|
@ -863,7 +863,7 @@ bool GCOVProfiler::emitProfileArcs() {
|
|||
|
||||
// Initialize the environment and register the local writeout and flush
|
||||
// functions.
|
||||
FunctionCallee GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
|
||||
Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
|
||||
Builder.CreateCall(GCOVInit, {WriteoutF, FlushF});
|
||||
Builder.CreateRetVoid();
|
||||
|
||||
|
@ -873,21 +873,22 @@ bool GCOVProfiler::emitProfileArcs() {
|
|||
return Result;
|
||||
}
|
||||
|
||||
FunctionCallee GCOVProfiler::getStartFileFunc() {
|
||||
Constant *GCOVProfiler::getStartFileFunc() {
|
||||
Type *Args[] = {
|
||||
Type::getInt8PtrTy(*Ctx), // const char *orig_filename
|
||||
Type::getInt8PtrTy(*Ctx), // const char version[4]
|
||||
Type::getInt32Ty(*Ctx), // uint32_t checksum
|
||||
};
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
|
||||
AttributeList AL;
|
||||
if (auto AK = TLI->getExtAttrForI32Param(false))
|
||||
AL = AL.addParamAttribute(*Ctx, 2, AK);
|
||||
FunctionCallee Res = M->getOrInsertFunction("llvm_gcda_start_file", FTy, AL);
|
||||
auto *Res = M->getOrInsertFunction("llvm_gcda_start_file", FTy);
|
||||
if (Function *FunRes = dyn_cast<Function>(Res))
|
||||
if (auto AK = TLI->getExtAttrForI32Param(false))
|
||||
FunRes->addParamAttr(2, AK);
|
||||
return Res;
|
||||
|
||||
}
|
||||
|
||||
FunctionCallee GCOVProfiler::getEmitFunctionFunc() {
|
||||
Constant *GCOVProfiler::getEmitFunctionFunc() {
|
||||
Type *Args[] = {
|
||||
Type::getInt32Ty(*Ctx), // uint32_t ident
|
||||
Type::getInt8PtrTy(*Ctx), // const char *function_name
|
||||
|
@ -896,34 +897,36 @@ FunctionCallee GCOVProfiler::getEmitFunctionFunc() {
|
|||
Type::getInt32Ty(*Ctx), // uint32_t cfg_checksum
|
||||
};
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
|
||||
AttributeList AL;
|
||||
if (auto AK = TLI->getExtAttrForI32Param(false)) {
|
||||
AL = AL.addParamAttribute(*Ctx, 0, AK);
|
||||
AL = AL.addParamAttribute(*Ctx, 2, AK);
|
||||
AL = AL.addParamAttribute(*Ctx, 3, AK);
|
||||
AL = AL.addParamAttribute(*Ctx, 4, AK);
|
||||
}
|
||||
return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
|
||||
auto *Res = M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
|
||||
if (Function *FunRes = dyn_cast<Function>(Res))
|
||||
if (auto AK = TLI->getExtAttrForI32Param(false)) {
|
||||
FunRes->addParamAttr(0, AK);
|
||||
FunRes->addParamAttr(2, AK);
|
||||
FunRes->addParamAttr(3, AK);
|
||||
FunRes->addParamAttr(4, AK);
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
FunctionCallee GCOVProfiler::getEmitArcsFunc() {
|
||||
Constant *GCOVProfiler::getEmitArcsFunc() {
|
||||
Type *Args[] = {
|
||||
Type::getInt32Ty(*Ctx), // uint32_t num_counters
|
||||
Type::getInt64PtrTy(*Ctx), // uint64_t *counters
|
||||
};
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
|
||||
AttributeList AL;
|
||||
if (auto AK = TLI->getExtAttrForI32Param(false))
|
||||
AL = AL.addParamAttribute(*Ctx, 0, AK);
|
||||
return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy, AL);
|
||||
auto *Res = M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
|
||||
if (Function *FunRes = dyn_cast<Function>(Res))
|
||||
if (auto AK = TLI->getExtAttrForI32Param(false))
|
||||
FunRes->addParamAttr(0, AK);
|
||||
return Res;
|
||||
}
|
||||
|
||||
FunctionCallee GCOVProfiler::getSummaryInfoFunc() {
|
||||
Constant *GCOVProfiler::getSummaryInfoFunc() {
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||
return M->getOrInsertFunction("llvm_gcda_summary_info", FTy);
|
||||
}
|
||||
|
||||
FunctionCallee GCOVProfiler::getEndFileFunc() {
|
||||
Constant *GCOVProfiler::getEndFileFunc() {
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||
return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
|
||||
}
|
||||
|
@ -943,11 +946,11 @@ Function *GCOVProfiler::insertCounterWriteout(
|
|||
BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
|
||||
IRBuilder<> Builder(BB);
|
||||
|
||||
FunctionCallee StartFile = getStartFileFunc();
|
||||
FunctionCallee EmitFunction = getEmitFunctionFunc();
|
||||
FunctionCallee EmitArcs = getEmitArcsFunc();
|
||||
FunctionCallee SummaryInfo = getSummaryInfoFunc();
|
||||
FunctionCallee EndFile = getEndFileFunc();
|
||||
Constant *StartFile = getStartFileFunc();
|
||||
Constant *EmitFunction = getEmitFunctionFunc();
|
||||
Constant *EmitArcs = getEmitArcsFunc();
|
||||
Constant *SummaryInfo = getSummaryInfoFunc();
|
||||
Constant *EndFile = getEndFileFunc();
|
||||
|
||||
NamedMDNode *CUNodes = M->getNamedMetadata("llvm.dbg.cu");
|
||||
if (!CUNodes) {
|
||||
|
|
|
@ -221,7 +221,7 @@ private:
|
|||
LLVMContext *C;
|
||||
std::string CurModuleUniqueId;
|
||||
Triple TargetTriple;
|
||||
FunctionCallee HWAsanMemmove, HWAsanMemcpy, HWAsanMemset;
|
||||
Function *HWAsanMemmove, *HWAsanMemcpy, *HWAsanMemset;
|
||||
|
||||
// Frame description is a way to pass names/sizes of local variables
|
||||
// to the run-time w/o adding extra executable code in every function.
|
||||
|
@ -270,12 +270,12 @@ private:
|
|||
|
||||
Function *HwasanCtorFunction;
|
||||
|
||||
FunctionCallee HwasanMemoryAccessCallback[2][kNumberOfAccessSizes];
|
||||
FunctionCallee HwasanMemoryAccessCallbackSized[2];
|
||||
Function *HwasanMemoryAccessCallback[2][kNumberOfAccessSizes];
|
||||
Function *HwasanMemoryAccessCallbackSized[2];
|
||||
|
||||
FunctionCallee HwasanTagMemoryFunc;
|
||||
FunctionCallee HwasanGenerateTagFunc;
|
||||
FunctionCallee HwasanThreadEnterFunc;
|
||||
Function *HwasanTagMemoryFunc;
|
||||
Function *HwasanGenerateTagFunc;
|
||||
Function *HwasanThreadEnterFunc;
|
||||
|
||||
Constant *ShadowGlobal;
|
||||
|
||||
|
@ -369,42 +369,43 @@ void HWAddressSanitizer::initializeCallbacks(Module &M) {
|
|||
const std::string TypeStr = AccessIsWrite ? "store" : "load";
|
||||
const std::string EndingStr = Recover ? "_noabort" : "";
|
||||
|
||||
HwasanMemoryAccessCallbackSized[AccessIsWrite] = M.getOrInsertFunction(
|
||||
ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false));
|
||||
HwasanMemoryAccessCallbackSized[AccessIsWrite] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false)));
|
||||
|
||||
for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
|
||||
AccessSizeIndex++) {
|
||||
HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
|
||||
M.getOrInsertFunction(
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
ClMemoryAccessCallbackPrefix + TypeStr +
|
||||
itostr(1ULL << AccessSizeIndex) + EndingStr,
|
||||
FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false));
|
||||
FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false)));
|
||||
}
|
||||
}
|
||||
|
||||
HwasanTagMemoryFunc = M.getOrInsertFunction(
|
||||
"__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy);
|
||||
HwasanGenerateTagFunc =
|
||||
M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty);
|
||||
HwasanTagMemoryFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
"__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy));
|
||||
HwasanGenerateTagFunc = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty));
|
||||
|
||||
ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow",
|
||||
ArrayType::get(IRB.getInt8Ty(), 0));
|
||||
|
||||
const std::string MemIntrinCallbackPrefix =
|
||||
CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix;
|
||||
HWAsanMemmove = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memmove",
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy);
|
||||
HWAsanMemcpy = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memcpy",
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy);
|
||||
HWAsanMemset = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memset",
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt32Ty(), IntptrTy);
|
||||
HWAsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
MemIntrinCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy));
|
||||
HWAsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
MemIntrinCallbackPrefix + "memcpy", IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy));
|
||||
HWAsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
MemIntrinCallbackPrefix + "memset", IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy));
|
||||
|
||||
HwasanThreadEnterFunc =
|
||||
M.getOrInsertFunction("__hwasan_thread_enter", IRB.getVoidTy());
|
||||
HwasanThreadEnterFunc = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("__hwasan_thread_enter", IRB.getVoidTy()));
|
||||
}
|
||||
|
||||
Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) {
|
||||
|
|
|
@ -508,16 +508,13 @@ bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static FunctionCallee
|
||||
getOrInsertValueProfilingCall(Module &M, const TargetLibraryInfo &TLI,
|
||||
bool IsRange = false) {
|
||||
static Constant *getOrInsertValueProfilingCall(Module &M,
|
||||
const TargetLibraryInfo &TLI,
|
||||
bool IsRange = false) {
|
||||
LLVMContext &Ctx = M.getContext();
|
||||
auto *ReturnTy = Type::getVoidTy(M.getContext());
|
||||
|
||||
AttributeList AL;
|
||||
if (auto AK = TLI.getExtAttrForI32Param(false))
|
||||
AL = AL.addParamAttribute(M.getContext(), 2, AK);
|
||||
|
||||
Constant *Res;
|
||||
if (!IsRange) {
|
||||
Type *ParamTypes[] = {
|
||||
#define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType
|
||||
|
@ -525,8 +522,8 @@ getOrInsertValueProfilingCall(Module &M, const TargetLibraryInfo &TLI,
|
|||
};
|
||||
auto *ValueProfilingCallTy =
|
||||
FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
|
||||
return M.getOrInsertFunction(getInstrProfValueProfFuncName(),
|
||||
ValueProfilingCallTy, AL);
|
||||
Res = M.getOrInsertFunction(getInstrProfValueProfFuncName(),
|
||||
ValueProfilingCallTy);
|
||||
} else {
|
||||
Type *RangeParamTypes[] = {
|
||||
#define VALUE_RANGE_PROF 1
|
||||
|
@ -536,9 +533,15 @@ getOrInsertValueProfilingCall(Module &M, const TargetLibraryInfo &TLI,
|
|||
};
|
||||
auto *ValueRangeProfilingCallTy =
|
||||
FunctionType::get(ReturnTy, makeArrayRef(RangeParamTypes), false);
|
||||
return M.getOrInsertFunction(getInstrProfValueRangeProfFuncName(),
|
||||
ValueRangeProfilingCallTy, AL);
|
||||
Res = M.getOrInsertFunction(getInstrProfValueRangeProfFuncName(),
|
||||
ValueRangeProfilingCallTy);
|
||||
}
|
||||
|
||||
if (Function *FunRes = dyn_cast<Function>(Res)) {
|
||||
if (auto AK = TLI.getExtAttrForI32Param(false))
|
||||
FunRes->addParamAttr(2, AK);
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) {
|
||||
|
|
|
@ -536,41 +536,41 @@ private:
|
|||
bool CallbacksInitialized = false;
|
||||
|
||||
/// The run-time callback to print a warning.
|
||||
FunctionCallee WarningFn;
|
||||
Value *WarningFn;
|
||||
|
||||
// These arrays are indexed by log2(AccessSize).
|
||||
FunctionCallee MaybeWarningFn[kNumberOfAccessSizes];
|
||||
FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes];
|
||||
Value *MaybeWarningFn[kNumberOfAccessSizes];
|
||||
Value *MaybeStoreOriginFn[kNumberOfAccessSizes];
|
||||
|
||||
/// Run-time helper that generates a new origin value for a stack
|
||||
/// allocation.
|
||||
FunctionCallee MsanSetAllocaOrigin4Fn;
|
||||
Value *MsanSetAllocaOrigin4Fn;
|
||||
|
||||
/// Run-time helper that poisons stack on function entry.
|
||||
FunctionCallee MsanPoisonStackFn;
|
||||
Value *MsanPoisonStackFn;
|
||||
|
||||
/// Run-time helper that records a store (or any event) of an
|
||||
/// uninitialized value and returns an updated origin id encoding this info.
|
||||
FunctionCallee MsanChainOriginFn;
|
||||
Value *MsanChainOriginFn;
|
||||
|
||||
/// MSan runtime replacements for memmove, memcpy and memset.
|
||||
FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
|
||||
Value *MemmoveFn, *MemcpyFn, *MemsetFn;
|
||||
|
||||
/// KMSAN callback for task-local function argument shadow.
|
||||
FunctionCallee MsanGetContextStateFn;
|
||||
Value *MsanGetContextStateFn;
|
||||
|
||||
/// Functions for poisoning/unpoisoning local variables
|
||||
FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
|
||||
Value *MsanPoisonAllocaFn, *MsanUnpoisonAllocaFn;
|
||||
|
||||
/// Each of the MsanMetadataPtrXxx functions returns a pair of shadow/origin
|
||||
/// pointers.
|
||||
FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
|
||||
FunctionCallee MsanMetadataPtrForLoad_1_8[4];
|
||||
FunctionCallee MsanMetadataPtrForStore_1_8[4];
|
||||
FunctionCallee MsanInstrumentAsmStoreFn;
|
||||
Value *MsanMetadataPtrForLoadN, *MsanMetadataPtrForStoreN;
|
||||
Value *MsanMetadataPtrForLoad_1_8[4];
|
||||
Value *MsanMetadataPtrForStore_1_8[4];
|
||||
Value *MsanInstrumentAsmStoreFn;
|
||||
|
||||
/// Helper to choose between different MsanMetadataPtrXxx().
|
||||
FunctionCallee getKmsanShadowOriginAccessFn(bool isStore, int size);
|
||||
Value *getKmsanShadowOriginAccessFn(bool isStore, int size);
|
||||
|
||||
/// Memory map parameters used in application-to-shadow calculation.
|
||||
const MemoryMapParams *MapParams;
|
||||
|
@ -823,9 +823,8 @@ void MemorySanitizer::initializeCallbacks(Module &M) {
|
|||
CallbacksInitialized = true;
|
||||
}
|
||||
|
||||
FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore,
|
||||
int size) {
|
||||
FunctionCallee *Fns =
|
||||
Value *MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore, int size) {
|
||||
Value **Fns =
|
||||
isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
|
||||
switch (size) {
|
||||
case 1:
|
||||
|
@ -925,7 +924,7 @@ void MemorySanitizer::initializeModule(Module &M) {
|
|||
/*InitArgs=*/{},
|
||||
// This callback is invoked when the functions are created the first
|
||||
// time. Hook them into the global ctors list in that case:
|
||||
[&](Function *Ctor, FunctionCallee) {
|
||||
[&](Function *Ctor, Function *) {
|
||||
if (!ClWithComdat) {
|
||||
appendToGlobalCtors(M, Ctor, 0);
|
||||
return;
|
||||
|
@ -1124,7 +1123,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
|||
DL.getTypeSizeInBits(ConvertedShadow->getType());
|
||||
unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
|
||||
if (AsCall && SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
|
||||
FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
|
||||
Value *Fn = MS.MaybeStoreOriginFn[SizeIndex];
|
||||
Value *ConvertedShadow2 = IRB.CreateZExt(
|
||||
ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
|
||||
IRB.CreateCall(Fn, {ConvertedShadow2,
|
||||
|
@ -1206,7 +1205,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
|||
unsigned TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
|
||||
unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
|
||||
if (AsCall && SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
|
||||
FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
|
||||
Value *Fn = MS.MaybeWarningFn[SizeIndex];
|
||||
Value *ConvertedShadow2 =
|
||||
IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
|
||||
IRB.CreateCall(Fn, {ConvertedShadow2, MS.TrackOrigins && Origin
|
||||
|
@ -1413,7 +1412,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
|||
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||
int Size = DL.getTypeStoreSize(ShadowTy);
|
||||
|
||||
FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size);
|
||||
Value *Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size);
|
||||
Value *AddrCast =
|
||||
IRB.CreatePointerCast(Addr, PointerType::get(IRB.getInt8Ty(), 0));
|
||||
if (Getter) {
|
||||
|
|
|
@ -222,13 +222,13 @@ private:
|
|||
std::string getSectionName(const std::string &Section) const;
|
||||
std::string getSectionStart(const std::string &Section) const;
|
||||
std::string getSectionEnd(const std::string &Section) const;
|
||||
FunctionCallee SanCovTracePCIndir;
|
||||
FunctionCallee SanCovTracePC, SanCovTracePCGuard;
|
||||
FunctionCallee SanCovTraceCmpFunction[4];
|
||||
FunctionCallee SanCovTraceConstCmpFunction[4];
|
||||
FunctionCallee SanCovTraceDivFunction[2];
|
||||
FunctionCallee SanCovTraceGepFunction;
|
||||
FunctionCallee SanCovTraceSwitchFunction;
|
||||
Function *SanCovTracePCIndir;
|
||||
Function *SanCovTracePC, *SanCovTracePCGuard;
|
||||
Function *SanCovTraceCmpFunction[4];
|
||||
Function *SanCovTraceConstCmpFunction[4];
|
||||
Function *SanCovTraceDivFunction[2];
|
||||
Function *SanCovTraceGepFunction;
|
||||
Function *SanCovTraceSwitchFunction;
|
||||
GlobalVariable *SanCovLowestStack;
|
||||
InlineAsm *EmptyAsm;
|
||||
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
|
||||
|
@ -328,52 +328,46 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
|||
Int16Ty = IRB.getInt16Ty();
|
||||
Int8Ty = IRB.getInt8Ty();
|
||||
|
||||
SanCovTracePCIndir =
|
||||
M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
|
||||
// Make sure smaller parameters are zero-extended to i64 as required by the
|
||||
// x86_64 ABI.
|
||||
AttributeList SanCovTraceCmpZeroExtAL;
|
||||
if (TargetTriple.getArch() == Triple::x86_64) {
|
||||
SanCovTraceCmpZeroExtAL =
|
||||
SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt);
|
||||
SanCovTraceCmpZeroExtAL =
|
||||
SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt);
|
||||
}
|
||||
|
||||
SanCovTracePCIndir = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy));
|
||||
SanCovTraceCmpFunction[0] =
|
||||
M.getOrInsertFunction(SanCovTraceCmp1, SanCovTraceCmpZeroExtAL, VoidTy,
|
||||
IRB.getInt8Ty(), IRB.getInt8Ty());
|
||||
SanCovTraceCmpFunction[1] =
|
||||
M.getOrInsertFunction(SanCovTraceCmp2, SanCovTraceCmpZeroExtAL, VoidTy,
|
||||
IRB.getInt16Ty(), IRB.getInt16Ty());
|
||||
SanCovTraceCmpFunction[2] =
|
||||
M.getOrInsertFunction(SanCovTraceCmp4, SanCovTraceCmpZeroExtAL, VoidTy,
|
||||
IRB.getInt32Ty(), IRB.getInt32Ty());
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceCmp1, VoidTy, IRB.getInt8Ty(), IRB.getInt8Ty()));
|
||||
SanCovTraceCmpFunction[1] = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(SanCovTraceCmp2, VoidTy, IRB.getInt16Ty(),
|
||||
IRB.getInt16Ty()));
|
||||
SanCovTraceCmpFunction[2] = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(SanCovTraceCmp4, VoidTy, IRB.getInt32Ty(),
|
||||
IRB.getInt32Ty()));
|
||||
SanCovTraceCmpFunction[3] =
|
||||
M.getOrInsertFunction(SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty);
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty));
|
||||
|
||||
SanCovTraceConstCmpFunction[0] = M.getOrInsertFunction(
|
||||
SanCovTraceConstCmp1, SanCovTraceCmpZeroExtAL, VoidTy, Int8Ty, Int8Ty);
|
||||
SanCovTraceConstCmpFunction[1] = M.getOrInsertFunction(
|
||||
SanCovTraceConstCmp2, SanCovTraceCmpZeroExtAL, VoidTy, Int16Ty, Int16Ty);
|
||||
SanCovTraceConstCmpFunction[2] = M.getOrInsertFunction(
|
||||
SanCovTraceConstCmp4, SanCovTraceCmpZeroExtAL, VoidTy, Int32Ty, Int32Ty);
|
||||
SanCovTraceConstCmpFunction[0] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceConstCmp1, VoidTy, Int8Ty, Int8Ty));
|
||||
SanCovTraceConstCmpFunction[1] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceConstCmp2, VoidTy, Int16Ty, Int16Ty));
|
||||
SanCovTraceConstCmpFunction[2] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceConstCmp4, VoidTy, Int32Ty, Int32Ty));
|
||||
SanCovTraceConstCmpFunction[3] =
|
||||
M.getOrInsertFunction(SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty);
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty));
|
||||
|
||||
{
|
||||
AttributeList AL;
|
||||
if (TargetTriple.getArch() == Triple::x86_64)
|
||||
AL = AL.addParamAttribute(*C, 0, Attribute::ZExt);
|
||||
SanCovTraceDivFunction[0] =
|
||||
M.getOrInsertFunction(SanCovTraceDiv4, AL, VoidTy, IRB.getInt32Ty());
|
||||
}
|
||||
SanCovTraceDivFunction[0] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceDiv4, VoidTy, IRB.getInt32Ty()));
|
||||
SanCovTraceDivFunction[1] =
|
||||
M.getOrInsertFunction(SanCovTraceDiv8, VoidTy, Int64Ty);
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceDiv8, VoidTy, Int64Ty));
|
||||
SanCovTraceGepFunction =
|
||||
M.getOrInsertFunction(SanCovTraceGep, VoidTy, IntptrTy);
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceGep, VoidTy, IntptrTy));
|
||||
SanCovTraceSwitchFunction =
|
||||
M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy);
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy));
|
||||
|
||||
Constant *SanCovLowestStackConstant =
|
||||
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
|
||||
|
@ -383,14 +377,28 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
|||
if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
|
||||
SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy));
|
||||
|
||||
// Make sure smaller parameters are zero-extended to i64 as required by the
|
||||
// x86_64 ABI.
|
||||
if (TargetTriple.getArch() == Triple::x86_64) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
SanCovTraceCmpFunction[i]->addParamAttr(0, Attribute::ZExt);
|
||||
SanCovTraceCmpFunction[i]->addParamAttr(1, Attribute::ZExt);
|
||||
SanCovTraceConstCmpFunction[i]->addParamAttr(0, Attribute::ZExt);
|
||||
SanCovTraceConstCmpFunction[i]->addParamAttr(1, Attribute::ZExt);
|
||||
}
|
||||
SanCovTraceDivFunction[0]->addParamAttr(0, Attribute::ZExt);
|
||||
}
|
||||
|
||||
|
||||
// We insert an empty inline asm after cov callbacks to avoid callback merge.
|
||||
EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
|
||||
StringRef(""), StringRef(""),
|
||||
/*hasSideEffects=*/true);
|
||||
|
||||
SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
|
||||
SanCovTracePCGuard =
|
||||
M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy);
|
||||
SanCovTracePC = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(SanCovTracePCName, VoidTy));
|
||||
SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
SanCovTracePCGuardName, VoidTy, Int32PtrTy));
|
||||
|
||||
for (auto &F : M)
|
||||
runOnFunction(F);
|
||||
|
@ -405,7 +413,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
|||
SanCovCountersSectionName);
|
||||
if (Ctor && Options.PCTable) {
|
||||
auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy);
|
||||
FunctionCallee InitFunction = declareSanitizerInitFunction(
|
||||
Function *InitFunction = declareSanitizerInitFunction(
|
||||
M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy});
|
||||
IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
|
||||
IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
|
||||
|
|
|
@ -110,26 +110,25 @@ private:
|
|||
Type *IntptrTy;
|
||||
IntegerType *OrdTy;
|
||||
// Callbacks to run-time library are computed in doInitialization.
|
||||
FunctionCallee TsanFuncEntry;
|
||||
FunctionCallee TsanFuncExit;
|
||||
FunctionCallee TsanIgnoreBegin;
|
||||
FunctionCallee TsanIgnoreEnd;
|
||||
Function *TsanFuncEntry;
|
||||
Function *TsanFuncExit;
|
||||
Function *TsanIgnoreBegin;
|
||||
Function *TsanIgnoreEnd;
|
||||
// Accesses sizes are powers of two: 1, 2, 4, 8, 16.
|
||||
static const size_t kNumberOfAccessSizes = 5;
|
||||
FunctionCallee TsanRead[kNumberOfAccessSizes];
|
||||
FunctionCallee TsanWrite[kNumberOfAccessSizes];
|
||||
FunctionCallee TsanUnalignedRead[kNumberOfAccessSizes];
|
||||
FunctionCallee TsanUnalignedWrite[kNumberOfAccessSizes];
|
||||
FunctionCallee TsanAtomicLoad[kNumberOfAccessSizes];
|
||||
FunctionCallee TsanAtomicStore[kNumberOfAccessSizes];
|
||||
FunctionCallee TsanAtomicRMW[AtomicRMWInst::LAST_BINOP + 1]
|
||||
[kNumberOfAccessSizes];
|
||||
FunctionCallee TsanAtomicCAS[kNumberOfAccessSizes];
|
||||
FunctionCallee TsanAtomicThreadFence;
|
||||
FunctionCallee TsanAtomicSignalFence;
|
||||
FunctionCallee TsanVptrUpdate;
|
||||
FunctionCallee TsanVptrLoad;
|
||||
FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
|
||||
Function *TsanRead[kNumberOfAccessSizes];
|
||||
Function *TsanWrite[kNumberOfAccessSizes];
|
||||
Function *TsanUnalignedRead[kNumberOfAccessSizes];
|
||||
Function *TsanUnalignedWrite[kNumberOfAccessSizes];
|
||||
Function *TsanAtomicLoad[kNumberOfAccessSizes];
|
||||
Function *TsanAtomicStore[kNumberOfAccessSizes];
|
||||
Function *TsanAtomicRMW[AtomicRMWInst::LAST_BINOP + 1][kNumberOfAccessSizes];
|
||||
Function *TsanAtomicCAS[kNumberOfAccessSizes];
|
||||
Function *TsanAtomicThreadFence;
|
||||
Function *TsanAtomicSignalFence;
|
||||
Function *TsanVptrUpdate;
|
||||
Function *TsanVptrLoad;
|
||||
Function *MemmoveFn, *MemcpyFn, *MemsetFn;
|
||||
Function *TsanCtorFunction;
|
||||
};
|
||||
|
||||
|
@ -189,14 +188,14 @@ void ThreadSanitizer::initializeCallbacks(Module &M) {
|
|||
Attr = Attr.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::NoUnwind);
|
||||
// Initialize the callbacks.
|
||||
TsanFuncEntry = M.getOrInsertFunction("__tsan_func_entry", Attr,
|
||||
IRB.getVoidTy(), IRB.getInt8PtrTy());
|
||||
TsanFuncExit =
|
||||
M.getOrInsertFunction("__tsan_func_exit", Attr, IRB.getVoidTy());
|
||||
TsanIgnoreBegin = M.getOrInsertFunction("__tsan_ignore_thread_begin", Attr,
|
||||
IRB.getVoidTy());
|
||||
TsanIgnoreEnd =
|
||||
M.getOrInsertFunction("__tsan_ignore_thread_end", Attr, IRB.getVoidTy());
|
||||
TsanFuncEntry = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
"__tsan_func_entry", Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
TsanFuncExit = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("__tsan_func_exit", Attr, IRB.getVoidTy()));
|
||||
TsanIgnoreBegin = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
"__tsan_ignore_thread_begin", Attr, IRB.getVoidTy()));
|
||||
TsanIgnoreEnd = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
"__tsan_ignore_thread_end", Attr, IRB.getVoidTy()));
|
||||
OrdTy = IRB.getInt32Ty();
|
||||
for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
|
||||
const unsigned ByteSize = 1U << i;
|
||||
|
@ -204,30 +203,32 @@ void ThreadSanitizer::initializeCallbacks(Module &M) {
|
|||
std::string ByteSizeStr = utostr(ByteSize);
|
||||
std::string BitSizeStr = utostr(BitSize);
|
||||
SmallString<32> ReadName("__tsan_read" + ByteSizeStr);
|
||||
TsanRead[i] = M.getOrInsertFunction(ReadName, Attr, IRB.getVoidTy(),
|
||||
IRB.getInt8PtrTy());
|
||||
TsanRead[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
ReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
|
||||
SmallString<32> WriteName("__tsan_write" + ByteSizeStr);
|
||||
TsanWrite[i] = M.getOrInsertFunction(WriteName, Attr, IRB.getVoidTy(),
|
||||
IRB.getInt8PtrTy());
|
||||
TsanWrite[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
WriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
|
||||
SmallString<64> UnalignedReadName("__tsan_unaligned_read" + ByteSizeStr);
|
||||
TsanUnalignedRead[i] = M.getOrInsertFunction(
|
||||
UnalignedReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
|
||||
TsanUnalignedRead[i] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
UnalignedReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
|
||||
SmallString<64> UnalignedWriteName("__tsan_unaligned_write" + ByteSizeStr);
|
||||
TsanUnalignedWrite[i] = M.getOrInsertFunction(
|
||||
UnalignedWriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy());
|
||||
TsanUnalignedWrite[i] =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
UnalignedWriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
|
||||
Type *Ty = Type::getIntNTy(M.getContext(), BitSize);
|
||||
Type *PtrTy = Ty->getPointerTo();
|
||||
SmallString<32> AtomicLoadName("__tsan_atomic" + BitSizeStr + "_load");
|
||||
TsanAtomicLoad[i] =
|
||||
M.getOrInsertFunction(AtomicLoadName, Attr, Ty, PtrTy, OrdTy);
|
||||
TsanAtomicLoad[i] = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(AtomicLoadName, Attr, Ty, PtrTy, OrdTy));
|
||||
|
||||
SmallString<32> AtomicStoreName("__tsan_atomic" + BitSizeStr + "_store");
|
||||
TsanAtomicStore[i] = M.getOrInsertFunction(
|
||||
AtomicStoreName, Attr, IRB.getVoidTy(), PtrTy, Ty, OrdTy);
|
||||
TsanAtomicStore[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
AtomicStoreName, Attr, IRB.getVoidTy(), PtrTy, Ty, OrdTy));
|
||||
|
||||
for (int op = AtomicRMWInst::FIRST_BINOP;
|
||||
op <= AtomicRMWInst::LAST_BINOP; ++op) {
|
||||
|
@ -250,34 +251,34 @@ void ThreadSanitizer::initializeCallbacks(Module &M) {
|
|||
else
|
||||
continue;
|
||||
SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart);
|
||||
TsanAtomicRMW[op][i] =
|
||||
M.getOrInsertFunction(RMWName, Attr, Ty, PtrTy, Ty, OrdTy);
|
||||
TsanAtomicRMW[op][i] = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction(RMWName, Attr, Ty, PtrTy, Ty, OrdTy));
|
||||
}
|
||||
|
||||
SmallString<32> AtomicCASName("__tsan_atomic" + BitSizeStr +
|
||||
"_compare_exchange_val");
|
||||
TsanAtomicCAS[i] = M.getOrInsertFunction(AtomicCASName, Attr, Ty, PtrTy, Ty,
|
||||
Ty, OrdTy, OrdTy);
|
||||
TsanAtomicCAS[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
AtomicCASName, Attr, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy));
|
||||
}
|
||||
TsanVptrUpdate =
|
||||
TsanVptrUpdate = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("__tsan_vptr_update", Attr, IRB.getVoidTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy());
|
||||
TsanVptrLoad = M.getOrInsertFunction("__tsan_vptr_read", Attr,
|
||||
IRB.getVoidTy(), IRB.getInt8PtrTy());
|
||||
TsanAtomicThreadFence = M.getOrInsertFunction("__tsan_atomic_thread_fence",
|
||||
Attr, IRB.getVoidTy(), OrdTy);
|
||||
TsanAtomicSignalFence = M.getOrInsertFunction("__tsan_atomic_signal_fence",
|
||||
Attr, IRB.getVoidTy(), OrdTy);
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy()));
|
||||
TsanVptrLoad = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
"__tsan_vptr_read", Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()));
|
||||
TsanAtomicThreadFence = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
"__tsan_atomic_thread_fence", Attr, IRB.getVoidTy(), OrdTy));
|
||||
TsanAtomicSignalFence = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
"__tsan_atomic_signal_fence", Attr, IRB.getVoidTy(), OrdTy));
|
||||
|
||||
MemmoveFn =
|
||||
M.getOrInsertFunction("memmove", Attr, IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy);
|
||||
MemcpyFn =
|
||||
M.getOrInsertFunction("memcpy", Attr, IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy);
|
||||
MemsetFn =
|
||||
M.getOrInsertFunction("memset", Attr, IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy);
|
||||
MemmoveFn = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("memmove", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy));
|
||||
MemcpyFn = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("memcpy", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt8PtrTy(), IntptrTy));
|
||||
MemsetFn = checkSanitizerInterfaceFunction(
|
||||
M.getOrInsertFunction("memset", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IRB.getInt32Ty(), IntptrTy));
|
||||
}
|
||||
|
||||
ThreadSanitizer::ThreadSanitizer(Module &M) {
|
||||
|
@ -289,9 +290,7 @@ ThreadSanitizer::ThreadSanitizer(Module &M) {
|
|||
/*InitArgs=*/{},
|
||||
// This callback is invoked when the functions are created the first
|
||||
// time. Hook them into the global ctors list in that case:
|
||||
[&](Function *Ctor, FunctionCallee) {
|
||||
appendToGlobalCtors(M, Ctor, 0);
|
||||
});
|
||||
[&](Function *Ctor, Function *) { appendToGlobalCtors(M, Ctor, 0); });
|
||||
}
|
||||
|
||||
static bool isVtableAccess(Instruction *I) {
|
||||
|
@ -559,7 +558,7 @@ bool ThreadSanitizer::instrumentLoadOrStore(Instruction *I,
|
|||
: cast<LoadInst>(I)->getAlignment();
|
||||
Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType();
|
||||
const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
|
||||
FunctionCallee OnAccessFunc = nullptr;
|
||||
Value *OnAccessFunc = nullptr;
|
||||
if (Alignment == 0 || Alignment >= 8 || (Alignment % (TypeSize / 8)) == 0)
|
||||
OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx];
|
||||
else
|
||||
|
@ -659,7 +658,7 @@ bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) {
|
|||
int Idx = getMemoryAccessFuncIndex(Addr, DL);
|
||||
if (Idx < 0)
|
||||
return false;
|
||||
FunctionCallee F = TsanAtomicRMW[RMWI->getOperation()][Idx];
|
||||
Function *F = TsanAtomicRMW[RMWI->getOperation()][Idx];
|
||||
if (!F)
|
||||
return false;
|
||||
const unsigned ByteSize = 1U << Idx;
|
||||
|
@ -706,9 +705,8 @@ bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) {
|
|||
I->eraseFromParent();
|
||||
} else if (FenceInst *FI = dyn_cast<FenceInst>(I)) {
|
||||
Value *Args[] = {createOrdering(&IRB, FI->getOrdering())};
|
||||
FunctionCallee F = FI->getSyncScopeID() == SyncScope::SingleThread
|
||||
? TsanAtomicSignalFence
|
||||
: TsanAtomicThreadFence;
|
||||
Function *F = FI->getSyncScopeID() == SyncScope::SingleThread ?
|
||||
TsanAtomicSignalFence : TsanAtomicThreadFence;
|
||||
CallInst *C = CallInst::Create(F, Args);
|
||||
ReplaceInstWithInst(I, C);
|
||||
}
|
||||
|
|
|
@ -930,8 +930,9 @@ bool LoopIdiomRecognize::processLoopStridedStore(
|
|||
|
||||
Module *M = TheStore->getModule();
|
||||
StringRef FuncName = "memset_pattern16";
|
||||
FunctionCallee MSP = M->getOrInsertFunction(FuncName, Builder.getVoidTy(),
|
||||
Int8PtrTy, Int8PtrTy, IntPtr);
|
||||
Value *MSP =
|
||||
M->getOrInsertFunction(FuncName, Builder.getVoidTy(),
|
||||
Int8PtrTy, Int8PtrTy, IntPtr);
|
||||
inferLibFuncAttributes(M, FuncName, *TLI);
|
||||
|
||||
// Otherwise we should form a memset_pattern16. PatternValue is known to be
|
||||
|
|
|
@ -1480,9 +1480,8 @@ makeStatepointExplicitImpl(const CallSite CS, /* to replace */
|
|||
// calls to @llvm.experimental.deoptimize with different argument types in
|
||||
// the same module. This is fine -- we assume the frontend knew what it
|
||||
// was doing when generating this kind of IR.
|
||||
CallTarget = F->getParent()
|
||||
->getOrInsertFunction("__llvm_deoptimize", FTy)
|
||||
.getCallee();
|
||||
CallTarget =
|
||||
F->getParent()->getOrInsertFunction("__llvm_deoptimize", FTy);
|
||||
|
||||
IsDeoptimize = true;
|
||||
}
|
||||
|
@ -1901,8 +1900,8 @@ static void insertUseHolderAfter(CallSite &CS, const ArrayRef<Value *> Values,
|
|||
|
||||
Module *M = CS.getInstruction()->getModule();
|
||||
// Use a dummy vararg function to actually hold the values live
|
||||
FunctionCallee Func = M->getOrInsertFunction(
|
||||
"__tmp_use", FunctionType::get(Type::getVoidTy(M->getContext()), true));
|
||||
Function *Func = cast<Function>(M->getOrInsertFunction(
|
||||
"__tmp_use", FunctionType::get(Type::getVoidTy(M->getContext()), true)));
|
||||
if (CS.isCall()) {
|
||||
// For call safepoints insert dummy calls right after safepoint
|
||||
Holders.push_back(CallInst::Create(Func, Values, "",
|
||||
|
|
|
@ -797,12 +797,11 @@ Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
|
|||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef StrlenName = TLI->getName(LibFunc_strlen);
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
FunctionCallee StrLen = M->getOrInsertFunction(
|
||||
StrlenName, DL.getIntPtrType(Context), B.getInt8PtrTy());
|
||||
Constant *StrLen = M->getOrInsertFunction(StrlenName, DL.getIntPtrType(Context),
|
||||
B.getInt8PtrTy());
|
||||
inferLibFuncAttributes(M, StrlenName, *TLI);
|
||||
CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), StrlenName);
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(StrLen.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
|
@ -817,13 +816,12 @@ Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
|
|||
StringRef StrChrName = TLI->getName(LibFunc_strchr);
|
||||
Type *I8Ptr = B.getInt8PtrTy();
|
||||
Type *I32Ty = B.getInt32Ty();
|
||||
FunctionCallee StrChr =
|
||||
Constant *StrChr =
|
||||
M->getOrInsertFunction(StrChrName, I8Ptr, I8Ptr, I32Ty);
|
||||
inferLibFuncAttributes(M, StrChrName, *TLI);
|
||||
CallInst *CI = B.CreateCall(
|
||||
StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, StrChrName);
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(StrChr.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -836,15 +834,14 @@ Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
|
|||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef StrNCmpName = TLI->getName(LibFunc_strncmp);
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
FunctionCallee StrNCmp =
|
||||
M->getOrInsertFunction(StrNCmpName, B.getInt32Ty(), B.getInt8PtrTy(),
|
||||
B.getInt8PtrTy(), DL.getIntPtrType(Context));
|
||||
Value *StrNCmp = M->getOrInsertFunction(StrNCmpName, B.getInt32Ty(),
|
||||
B.getInt8PtrTy(), B.getInt8PtrTy(),
|
||||
DL.getIntPtrType(Context));
|
||||
inferLibFuncAttributes(M, StrNCmpName, *TLI);
|
||||
CallInst *CI = B.CreateCall(
|
||||
StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, StrNCmpName);
|
||||
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(StrNCmp.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
|
@ -857,12 +854,11 @@ Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
Type *I8Ptr = B.getInt8PtrTy();
|
||||
FunctionCallee StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
|
||||
Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
|
||||
inferLibFuncAttributes(M, Name, *TLI);
|
||||
CallInst *CI =
|
||||
B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(StrCpy.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -874,13 +870,12 @@ Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
Type *I8Ptr = B.getInt8PtrTy();
|
||||
FunctionCallee StrNCpy =
|
||||
M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr, Len->getType());
|
||||
Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
|
||||
Len->getType());
|
||||
inferLibFuncAttributes(M, Name, *TLI);
|
||||
CallInst *CI = B.CreateCall(
|
||||
StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, Name);
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(StrNCpy.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -896,15 +891,14 @@ Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
|
|||
AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::NoUnwind);
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
FunctionCallee MemCpy = M->getOrInsertFunction(
|
||||
Value *MemCpy = M->getOrInsertFunction(
|
||||
"__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
|
||||
B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
|
||||
DL.getIntPtrType(Context));
|
||||
Dst = castToCStr(Dst, B);
|
||||
Src = castToCStr(Src, B);
|
||||
CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -917,14 +911,13 @@ Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
|
|||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef MemChrName = TLI->getName(LibFunc_memchr);
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
FunctionCallee MemChr =
|
||||
M->getOrInsertFunction(MemChrName, B.getInt8PtrTy(), B.getInt8PtrTy(),
|
||||
B.getInt32Ty(), DL.getIntPtrType(Context));
|
||||
Value *MemChr = M->getOrInsertFunction(MemChrName, B.getInt8PtrTy(),
|
||||
B.getInt8PtrTy(), B.getInt32Ty(),
|
||||
DL.getIntPtrType(Context));
|
||||
inferLibFuncAttributes(M, MemChrName, *TLI);
|
||||
CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, MemChrName);
|
||||
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(MemChr.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
|
@ -938,15 +931,14 @@ Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
|
|||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef MemCmpName = TLI->getName(LibFunc_memcmp);
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
FunctionCallee MemCmp =
|
||||
M->getOrInsertFunction(MemCmpName, B.getInt32Ty(), B.getInt8PtrTy(),
|
||||
B.getInt8PtrTy(), DL.getIntPtrType(Context));
|
||||
Value *MemCmp = M->getOrInsertFunction(MemCmpName, B.getInt32Ty(),
|
||||
B.getInt8PtrTy(), B.getInt8PtrTy(),
|
||||
DL.getIntPtrType(Context));
|
||||
inferLibFuncAttributes(M, MemCmpName, *TLI);
|
||||
CallInst *CI = B.CreateCall(
|
||||
MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, MemCmpName);
|
||||
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(MemCmp.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
|
@ -973,8 +965,8 @@ static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
|
|||
assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
|
||||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
FunctionCallee Callee =
|
||||
M->getOrInsertFunction(Name, Op->getType(), Op->getType());
|
||||
Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
|
||||
Op->getType());
|
||||
CallInst *CI = B.CreateCall(Callee, Op, Name);
|
||||
|
||||
// The incoming attribute set may have come from a speculatable intrinsic, but
|
||||
|
@ -983,8 +975,7 @@ static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
|
|||
CI->setAttributes(Attrs.removeAttribute(B.getContext(),
|
||||
AttributeList::FunctionIndex,
|
||||
Attribute::Speculatable));
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
|
@ -1017,12 +1008,11 @@ Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
|
|||
appendTypeSuffix(Op1, Name, NameBuffer);
|
||||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
FunctionCallee Callee = M->getOrInsertFunction(
|
||||
Name, Op1->getType(), Op1->getType(), Op2->getType());
|
||||
Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
|
||||
Op2->getType());
|
||||
CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
|
||||
CI->setAttributes(Attrs);
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
|
@ -1035,8 +1025,7 @@ Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef PutCharName = TLI->getName(LibFunc_putchar);
|
||||
FunctionCallee PutChar =
|
||||
M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
|
||||
Value *PutChar = M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
|
||||
inferLibFuncAttributes(M, PutCharName, *TLI);
|
||||
CallInst *CI = B.CreateCall(PutChar,
|
||||
B.CreateIntCast(Char,
|
||||
|
@ -1045,8 +1034,7 @@ Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
|
|||
"chari"),
|
||||
PutCharName);
|
||||
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1058,12 +1046,11 @@ Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef PutsName = TLI->getName(LibFunc_puts);
|
||||
FunctionCallee PutS =
|
||||
Value *PutS =
|
||||
M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
|
||||
inferLibFuncAttributes(M, PutsName, *TLI);
|
||||
CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1075,16 +1062,15 @@ Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef FPutcName = TLI->getName(LibFunc_fputc);
|
||||
FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(),
|
||||
B.getInt32Ty(), File->getType());
|
||||
Constant *F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(), B.getInt32Ty(),
|
||||
File->getType());
|
||||
if (File->getType()->isPointerTy())
|
||||
inferLibFuncAttributes(M, FPutcName, *TLI);
|
||||
Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
|
||||
"chari");
|
||||
CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1096,15 +1082,14 @@ Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
|
||||
FunctionCallee F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
|
||||
B.getInt32Ty(), File->getType());
|
||||
Constant *F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
|
||||
B.getInt32Ty(), File->getType());
|
||||
if (File->getType()->isPointerTy())
|
||||
inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
|
||||
Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
|
||||
CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1116,14 +1101,13 @@ Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef FPutsName = TLI->getName(LibFunc_fputs);
|
||||
FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
|
||||
B.getInt8PtrTy(), File->getType());
|
||||
Constant *F = M->getOrInsertFunction(
|
||||
FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType());
|
||||
if (File->getType()->isPointerTy())
|
||||
inferLibFuncAttributes(M, FPutsName, *TLI);
|
||||
CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1135,14 +1119,13 @@ Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
|
||||
FunctionCallee F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
|
||||
B.getInt8PtrTy(), File->getType());
|
||||
Constant *F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
|
||||
B.getInt8PtrTy(), File->getType());
|
||||
if (File->getType()->isPointerTy())
|
||||
inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
|
||||
CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1155,7 +1138,7 @@ Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
|
|||
Module *M = B.GetInsertBlock()->getModule();
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
StringRef FWriteName = TLI->getName(LibFunc_fwrite);
|
||||
FunctionCallee F = M->getOrInsertFunction(
|
||||
Constant *F = M->getOrInsertFunction(
|
||||
FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
|
||||
DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
|
||||
|
||||
|
@ -1165,8 +1148,7 @@ Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
|
|||
B.CreateCall(F, {castToCStr(Ptr, B), Size,
|
||||
ConstantInt::get(DL.getIntPtrType(Context), 1), File});
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1179,13 +1161,12 @@ Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
|
|||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef MallocName = TLI->getName(LibFunc_malloc);
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
FunctionCallee Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
|
||||
DL.getIntPtrType(Context));
|
||||
Value *Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
|
||||
DL.getIntPtrType(Context));
|
||||
inferLibFuncAttributes(M, MallocName, *TLI);
|
||||
CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
|
||||
|
||||
if (const Function *F =
|
||||
dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))
|
||||
if (const Function *F = dyn_cast<Function>(Malloc->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
|
@ -1200,13 +1181,12 @@ Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
|
|||
StringRef CallocName = TLI.getName(LibFunc_calloc);
|
||||
const DataLayout &DL = M->getDataLayout();
|
||||
IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
|
||||
FunctionCallee Calloc = M->getOrInsertFunction(
|
||||
CallocName, Attrs, B.getInt8PtrTy(), PtrType, PtrType);
|
||||
Value *Calloc = M->getOrInsertFunction(CallocName, Attrs, B.getInt8PtrTy(),
|
||||
PtrType, PtrType);
|
||||
inferLibFuncAttributes(M, CallocName, TLI);
|
||||
CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
|
||||
|
||||
if (const auto *F =
|
||||
dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))
|
||||
if (const auto *F = dyn_cast<Function>(Calloc->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
||||
return CI;
|
||||
|
@ -1221,7 +1201,7 @@ Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
|
|||
Module *M = B.GetInsertBlock()->getModule();
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
|
||||
FunctionCallee F = M->getOrInsertFunction(
|
||||
Constant *F = M->getOrInsertFunction(
|
||||
FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
|
||||
DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
|
||||
|
||||
|
@ -1229,8 +1209,7 @@ Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
|
|||
inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
|
||||
CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1242,14 +1221,13 @@ Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
|
||||
FunctionCallee F = M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(),
|
||||
File->getType());
|
||||
Constant *F =
|
||||
M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(), File->getType());
|
||||
if (File->getType()->isPointerTy())
|
||||
inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
|
||||
CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1261,15 +1239,14 @@ Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
|
|||
|
||||
Module *M = B.GetInsertBlock()->getModule();
|
||||
StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
|
||||
FunctionCallee F =
|
||||
Constant *F =
|
||||
M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
|
||||
B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
|
||||
inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
|
||||
CallInst *CI =
|
||||
B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
@ -1283,7 +1260,7 @@ Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
|
|||
Module *M = B.GetInsertBlock()->getModule();
|
||||
LLVMContext &Context = B.GetInsertBlock()->getContext();
|
||||
StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
|
||||
FunctionCallee F = M->getOrInsertFunction(
|
||||
Constant *F = M->getOrInsertFunction(
|
||||
FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
|
||||
DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
|
||||
|
||||
|
@ -1291,8 +1268,7 @@ Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
|
|||
inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
|
||||
CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
|
||||
|
||||
if (const Function *Fn =
|
||||
dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
|
||||
if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
|
||||
CI->setCallingConv(Fn->getCallingConv());
|
||||
return CI;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ static void insertCall(Function &CurFn, StringRef Func,
|
|||
Func == "__mcount" ||
|
||||
Func == "_mcount" ||
|
||||
Func == "__cyg_profile_func_enter_bare") {
|
||||
FunctionCallee Fn = M.getOrInsertFunction(Func, Type::getVoidTy(C));
|
||||
Constant *Fn = M.getOrInsertFunction(Func, Type::getVoidTy(C));
|
||||
CallInst *Call = CallInst::Create(Fn, "", InsertionPt);
|
||||
Call->setDebugLoc(DL);
|
||||
return;
|
||||
|
@ -39,7 +39,7 @@ static void insertCall(Function &CurFn, StringRef Func,
|
|||
if (Func == "__cyg_profile_func_enter" || Func == "__cyg_profile_func_exit") {
|
||||
Type *ArgTypes[] = {Type::getInt8PtrTy(C), Type::getInt8PtrTy(C)};
|
||||
|
||||
FunctionCallee Fn = M.getOrInsertFunction(
|
||||
Constant *Fn = M.getOrInsertFunction(
|
||||
Func, FunctionType::get(Type::getVoidTy(C), ArgTypes, false));
|
||||
|
||||
Instruction *RetAddr = CallInst::Create(
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "llvm/IR/Module.h"
|
||||
using namespace llvm;
|
||||
|
||||
static FunctionCallee getDefaultPersonalityFn(Module *M) {
|
||||
static Constant *getDefaultPersonalityFn(Module *M) {
|
||||
LLVMContext &C = M->getContext();
|
||||
Triple T(M->getTargetTriple());
|
||||
EHPersonality Pers = getDefaultEHPersonality(T);
|
||||
|
@ -68,8 +68,8 @@ IRBuilder<> *EscapeEnumerator::Next() {
|
|||
BasicBlock *CleanupBB = BasicBlock::Create(C, CleanupBBName, &F);
|
||||
Type *ExnTy = StructType::get(Type::getInt8PtrTy(C), Type::getInt32Ty(C));
|
||||
if (!F.hasPersonalityFn()) {
|
||||
FunctionCallee PersFn = getDefaultPersonalityFn(F.getParent());
|
||||
F.setPersonalityFn(cast<Constant>(PersFn.getCallee()));
|
||||
Constant *PersFn = getDefaultPersonalityFn(F.getParent());
|
||||
F.setPersonalityFn(PersFn);
|
||||
}
|
||||
|
||||
if (isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) {
|
||||
|
|
|
@ -126,24 +126,36 @@ void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) {
|
|||
appendToUsedList(M, "llvm.compiler.used", Values);
|
||||
}
|
||||
|
||||
FunctionCallee
|
||||
llvm::declareSanitizerInitFunction(Module &M, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes) {
|
||||
assert(!InitName.empty() && "Expected init function name");
|
||||
return M.getOrInsertFunction(
|
||||
InitName,
|
||||
FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false),
|
||||
AttributeList());
|
||||
Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) {
|
||||
if (isa<Function>(FuncOrBitcast))
|
||||
return cast<Function>(FuncOrBitcast);
|
||||
FuncOrBitcast->print(errs());
|
||||
errs() << '\n';
|
||||
std::string Err;
|
||||
raw_string_ostream Stream(Err);
|
||||
Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast;
|
||||
report_fatal_error(Err);
|
||||
}
|
||||
|
||||
std::pair<Function *, FunctionCallee> llvm::createSanitizerCtorAndInitFunctions(
|
||||
Function *llvm::declareSanitizerInitFunction(Module &M, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes) {
|
||||
assert(!InitName.empty() && "Expected init function name");
|
||||
Function *F = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
InitName,
|
||||
FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false),
|
||||
AttributeList()));
|
||||
F->setLinkage(Function::ExternalLinkage);
|
||||
return F;
|
||||
}
|
||||
|
||||
std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
StringRef VersionCheckName) {
|
||||
assert(!InitName.empty() && "Expected init function name");
|
||||
assert(InitArgs.size() == InitArgTypes.size() &&
|
||||
"Sanitizer's init function expects different number of arguments");
|
||||
FunctionCallee InitFunction =
|
||||
Function *InitFunction =
|
||||
declareSanitizerInitFunction(M, InitName, InitArgTypes);
|
||||
Function *Ctor = Function::Create(
|
||||
FunctionType::get(Type::getVoidTy(M.getContext()), false),
|
||||
|
@ -152,19 +164,20 @@ std::pair<Function *, FunctionCallee> llvm::createSanitizerCtorAndInitFunctions(
|
|||
IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB));
|
||||
IRB.CreateCall(InitFunction, InitArgs);
|
||||
if (!VersionCheckName.empty()) {
|
||||
FunctionCallee VersionCheckFunction = M.getOrInsertFunction(
|
||||
VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false),
|
||||
AttributeList());
|
||||
Function *VersionCheckFunction =
|
||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false),
|
||||
AttributeList()));
|
||||
IRB.CreateCall(VersionCheckFunction, {});
|
||||
}
|
||||
return std::make_pair(Ctor, InitFunction);
|
||||
}
|
||||
|
||||
std::pair<Function *, FunctionCallee>
|
||||
std::pair<Function *, Function *>
|
||||
llvm::getOrCreateSanitizerCtorAndInitFunctions(
|
||||
Module &M, StringRef CtorName, StringRef InitName,
|
||||
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
|
||||
function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback,
|
||||
function_ref<void(Function *, Function *)> FunctionsCreatedCallback,
|
||||
StringRef VersionCheckName) {
|
||||
assert(!CtorName.empty() && "Expected ctor function name");
|
||||
|
||||
|
@ -175,8 +188,7 @@ llvm::getOrCreateSanitizerCtorAndInitFunctions(
|
|||
Ctor->getReturnType() == Type::getVoidTy(M.getContext()))
|
||||
return {Ctor, declareSanitizerInitFunction(M, InitName, InitArgTypes)};
|
||||
|
||||
Function *Ctor;
|
||||
FunctionCallee InitFunction;
|
||||
Function *Ctor, *InitFunction;
|
||||
std::tie(Ctor, InitFunction) = llvm::createSanitizerCtorAndInitFunctions(
|
||||
M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName);
|
||||
FunctionsCreatedCallback(Ctor, InitFunction);
|
||||
|
@ -195,10 +207,9 @@ Function *llvm::getOrCreateInitFunction(Module &M, StringRef Name) {
|
|||
}
|
||||
return F;
|
||||
}
|
||||
Function *F =
|
||||
cast<Function>(M.getOrInsertFunction(Name, AttributeList(),
|
||||
Type::getVoidTy(M.getContext()))
|
||||
.getCallee());
|
||||
Function *F = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
||||
Name, AttributeList(), Type::getVoidTy(M.getContext())));
|
||||
F->setLinkage(Function::ExternalLinkage);
|
||||
|
||||
appendToGlobalCtors(M, F, 0);
|
||||
|
||||
|
|
|
@ -488,10 +488,8 @@ void PredicateInfo::buildPredicateInfo() {
|
|||
// tricky (FIXME).
|
||||
static Function *getCopyDeclaration(Module *M, Type *Ty) {
|
||||
std::string Name = "llvm.ssa.copy." + utostr((uintptr_t) Ty);
|
||||
return cast<Function>(
|
||||
M->getOrInsertFunction(Name,
|
||||
getType(M->getContext(), Intrinsic::ssa_copy, Ty))
|
||||
.getCallee());
|
||||
return cast<Function>(M->getOrInsertFunction(
|
||||
Name, getType(M->getContext(), Intrinsic::ssa_copy, Ty)));
|
||||
}
|
||||
|
||||
// Given the renaming stack, make all the operands currently on the stack real
|
||||
|
|
|
@ -56,8 +56,8 @@ void SanitizerStatReport::create(IRBuilder<> &B, SanitizerStatKind SK) {
|
|||
|
||||
FunctionType *StatReportTy =
|
||||
FunctionType::get(B.getVoidTy(), Int8PtrTy, false);
|
||||
FunctionCallee StatReport =
|
||||
M->getOrInsertFunction("__sanitizer_stat_report", StatReportTy);
|
||||
Constant *StatReport = M->getOrInsertFunction(
|
||||
"__sanitizer_stat_report", StatReportTy);
|
||||
|
||||
auto InitAddr = ConstantExpr::getGetElementPtr(
|
||||
EmptyModuleStatsTy, ModuleStatsGV,
|
||||
|
@ -97,8 +97,8 @@ void SanitizerStatReport::finish() {
|
|||
IRBuilder<> B(BB);
|
||||
|
||||
FunctionType *StatInitTy = FunctionType::get(VoidTy, Int8PtrTy, false);
|
||||
FunctionCallee StatInit =
|
||||
M->getOrInsertFunction("__sanitizer_stat_init", StatInitTy);
|
||||
Constant *StatInit = M->getOrInsertFunction(
|
||||
"__sanitizer_stat_init", StatInitTy);
|
||||
|
||||
B.CreateCall(StatInit, ConstantExpr::getBitCast(NewModuleStatsGV, Int8PtrTy));
|
||||
B.CreateRetVoid();
|
||||
|
|
|
@ -1503,8 +1503,9 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilder<> &B) {
|
|||
One = ConstantExpr::getFPExtend(One, Op->getType());
|
||||
|
||||
Module *M = CI->getModule();
|
||||
FunctionCallee NewCallee = M->getOrInsertFunction(
|
||||
TLI->getName(LdExp), Op->getType(), Op->getType(), B.getInt32Ty());
|
||||
Value *NewCallee =
|
||||
M->getOrInsertFunction(TLI->getName(LdExp), Op->getType(),
|
||||
Op->getType(), B.getInt32Ty());
|
||||
CallInst *CI = B.CreateCall(NewCallee, {One, LdExpArg});
|
||||
if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
@ -1726,8 +1727,8 @@ static void insertSinCosCall(IRBuilder<> &B, Function *OrigCallee, Value *Arg,
|
|||
}
|
||||
|
||||
Module *M = OrigCallee->getParent();
|
||||
FunctionCallee Callee =
|
||||
M->getOrInsertFunction(Name, OrigCallee->getAttributes(), ResTy, ArgTy);
|
||||
Value *Callee = M->getOrInsertFunction(Name, OrigCallee->getAttributes(),
|
||||
ResTy, ArgTy);
|
||||
|
||||
if (Instruction *ArgInst = dyn_cast<Instruction>(Arg)) {
|
||||
// If the argument is an instruction, it must dominate all uses so put our
|
||||
|
@ -2024,7 +2025,7 @@ Value *LibCallSimplifier::optimizePrintF(CallInst *CI, IRBuilder<> &B) {
|
|||
// arguments.
|
||||
if (TLI->has(LibFunc_iprintf) && !callHasFloatingPointArgument(CI)) {
|
||||
Module *M = B.GetInsertBlock()->getParent()->getParent();
|
||||
FunctionCallee IPrintFFn =
|
||||
Constant *IPrintFFn =
|
||||
M->getOrInsertFunction("iprintf", FT, Callee->getAttributes());
|
||||
CallInst *New = cast<CallInst>(CI->clone());
|
||||
New->setCalledFunction(IPrintFFn);
|
||||
|
@ -2103,7 +2104,7 @@ Value *LibCallSimplifier::optimizeSPrintF(CallInst *CI, IRBuilder<> &B) {
|
|||
// point arguments.
|
||||
if (TLI->has(LibFunc_siprintf) && !callHasFloatingPointArgument(CI)) {
|
||||
Module *M = B.GetInsertBlock()->getParent()->getParent();
|
||||
FunctionCallee SIPrintFFn =
|
||||
Constant *SIPrintFFn =
|
||||
M->getOrInsertFunction("siprintf", FT, Callee->getAttributes());
|
||||
CallInst *New = cast<CallInst>(CI->clone());
|
||||
New->setCalledFunction(SIPrintFFn);
|
||||
|
@ -2260,7 +2261,7 @@ Value *LibCallSimplifier::optimizeFPrintF(CallInst *CI, IRBuilder<> &B) {
|
|||
// floating point arguments.
|
||||
if (TLI->has(LibFunc_fiprintf) && !callHasFloatingPointArgument(CI)) {
|
||||
Module *M = B.GetInsertBlock()->getParent()->getParent();
|
||||
FunctionCallee FIPrintFFn =
|
||||
Constant *FIPrintFFn =
|
||||
M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes());
|
||||
CallInst *New = cast<CallInst>(CI->clone());
|
||||
New->setCalledFunction(FIPrintFFn);
|
||||
|
|
|
@ -826,14 +826,13 @@ CleanupAndPrepareModules(BugDriver &BD, std::unique_ptr<Module> Test,
|
|||
|
||||
// Add the resolver to the Safe module.
|
||||
// Prototype: void *getPointerToNamedFunction(const char* Name)
|
||||
FunctionCallee resolverFunc = Safe->getOrInsertFunction(
|
||||
Constant *resolverFunc = Safe->getOrInsertFunction(
|
||||
"getPointerToNamedFunction", Type::getInt8PtrTy(Safe->getContext()),
|
||||
Type::getInt8PtrTy(Safe->getContext()));
|
||||
|
||||
// Use the function we just added to get addresses of functions we need.
|
||||
for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
|
||||
if (F->isDeclaration() && !F->use_empty() &&
|
||||
&*F != resolverFunc.getCallee() &&
|
||||
if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc &&
|
||||
!F->isIntrinsic() /* ignore intrinsics */) {
|
||||
Function *TestFn = Test->getFunction(F->getName());
|
||||
|
||||
|
|
|
@ -595,8 +595,8 @@ int main(int argc, char **argv, char * const *envp) {
|
|||
if (!RemoteMCJIT) {
|
||||
// If the program doesn't explicitly call exit, we will need the Exit
|
||||
// function later on to make an explicit call, so get the function now.
|
||||
FunctionCallee Exit = Mod->getOrInsertFunction(
|
||||
"exit", Type::getVoidTy(Context), Type::getInt32Ty(Context));
|
||||
Constant *Exit = Mod->getOrInsertFunction("exit", Type::getVoidTy(Context),
|
||||
Type::getInt32Ty(Context));
|
||||
|
||||
// Run static constructors.
|
||||
if (!ForceInterpreter) {
|
||||
|
@ -620,21 +620,19 @@ int main(int argc, char **argv, char * const *envp) {
|
|||
|
||||
// If the program didn't call exit explicitly, we should call it now.
|
||||
// This ensures that any atexit handlers get called correctly.
|
||||
if (Function *ExitF =
|
||||
dyn_cast<Function>(Exit.getCallee()->stripPointerCasts())) {
|
||||
if (ExitF->getFunctionType() == Exit.getFunctionType()) {
|
||||
std::vector<GenericValue> Args;
|
||||
GenericValue ResultGV;
|
||||
ResultGV.IntVal = APInt(32, Result);
|
||||
Args.push_back(ResultGV);
|
||||
EE->runFunction(ExitF, Args);
|
||||
WithColor::error(errs(), argv[0])
|
||||
<< "exit(" << Result << ") returned!\n";
|
||||
abort();
|
||||
}
|
||||
if (Function *ExitF = dyn_cast<Function>(Exit)) {
|
||||
std::vector<GenericValue> Args;
|
||||
GenericValue ResultGV;
|
||||
ResultGV.IntVal = APInt(32, Result);
|
||||
Args.push_back(ResultGV);
|
||||
EE->runFunction(ExitF, Args);
|
||||
WithColor::error(errs(), argv[0]) << "exit(" << Result << ") returned!\n";
|
||||
abort();
|
||||
} else {
|
||||
WithColor::error(errs(), argv[0])
|
||||
<< "exit defined with wrong prototype!\n";
|
||||
abort();
|
||||
}
|
||||
WithColor::error(errs(), argv[0]) << "exit defined with wrong prototype!\n";
|
||||
abort();
|
||||
} else {
|
||||
// else == "if (RemoteMCJIT)"
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ TEST_F(AliasAnalysisTest, getModRefInfo) {
|
|||
// Setup function.
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(C), std::vector<Type *>(), false);
|
||||
auto *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
auto *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
auto *BB = BasicBlock::Create(C, "entry", F);
|
||||
auto IntType = Type::getInt32Ty(C);
|
||||
auto PtrType = Type::getInt32PtrTy(C);
|
||||
|
|
|
@ -78,7 +78,7 @@ TEST_F(DivergenceAnalysisTest, DAInitialState) {
|
|||
IntegerType *IntTy = IntegerType::getInt32Ty(Context);
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), {IntTy}, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
|
||||
ReturnInst::Create(Context, nullptr, BB);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ TEST(OrderedInstructionsTest, DominanceTest) {
|
|||
IRBuilder<> B(Ctx);
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Ctx), {B.getInt8PtrTy()}, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
|
||||
// Create the function as follow and check for dominance relation.
|
||||
//
|
||||
|
|
|
@ -26,8 +26,7 @@ TEST(PhiValuesTest, SimplePhi) {
|
|||
Type *I32PtrTy = Type::getInt32PtrTy(C);
|
||||
|
||||
// Create a function with phis that do not have other phis as incoming values
|
||||
Function *F = Function::Create(FunctionType::get(VoidTy, false),
|
||||
Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FunctionType::get(VoidTy, false)));
|
||||
|
||||
BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
|
||||
BasicBlock *If = BasicBlock::Create(C, "if", F);
|
||||
|
@ -93,8 +92,7 @@ TEST(PhiValuesTest, DependentPhi) {
|
|||
Type *I32PtrTy = Type::getInt32PtrTy(C);
|
||||
|
||||
// Create a function with a phi that has another phi as an incoming value
|
||||
Function *F = Function::Create(FunctionType::get(VoidTy, false),
|
||||
Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FunctionType::get(VoidTy, false)));
|
||||
|
||||
BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
|
||||
BasicBlock *If1 = BasicBlock::Create(C, "if1", F);
|
||||
|
|
|
@ -63,7 +63,7 @@ protected:
|
|||
TEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) {
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
|
||||
std::vector<Type *>(), false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
|
||||
ReturnInst::Create(Context, nullptr, BB);
|
||||
|
||||
|
@ -112,7 +112,7 @@ TEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) {
|
|||
TEST_F(ScalarEvolutionsTest, SimplifiedPHI) {
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
|
||||
std::vector<Type *>(), false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
|
||||
BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
|
||||
BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
|
||||
|
@ -146,7 +146,7 @@ TEST_F(ScalarEvolutionsTest, ExpandPtrTypeSCEV) {
|
|||
auto *I32PtrTy = Type::getInt32PtrTy(Context);
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
|
||||
BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
|
||||
BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
|
||||
|
@ -329,7 +329,7 @@ TEST_F(ScalarEvolutionsTest, CommutativeExprOperandOrder) {
|
|||
TEST_F(ScalarEvolutionsTest, CompareSCEVComplexity) {
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
|
||||
BasicBlock *LoopBB = BasicBlock::Create(Context, "bb1", F);
|
||||
BranchInst::Create(LoopBB, EntryBB);
|
||||
|
@ -399,7 +399,7 @@ TEST_F(ScalarEvolutionsTest, CompareValueComplexity) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), {IntPtrTy, IntPtrTy}, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
|
||||
|
||||
Value *X = &*F->arg_begin();
|
||||
|
@ -435,7 +435,7 @@ TEST_F(ScalarEvolutionsTest, SCEVAddExpr) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), ArgTys, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
|
||||
Argument *A1 = &*F->arg_begin();
|
||||
Argument *A2 = &*(std::next(F->arg_begin()));
|
||||
|
@ -669,7 +669,7 @@ TEST_F(ScalarEvolutionsTest, SCEVZeroExtendExpr) {
|
|||
// ret void
|
||||
// }
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), {}, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
|
||||
|
||||
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
|
||||
BasicBlock *CondBB = BasicBlock::Create(Context, "for.cond", F);
|
||||
|
@ -748,7 +748,7 @@ TEST_F(ScalarEvolutionsTest, SCEVZeroExtendExprNonIntegral) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
|
||||
Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
|
||||
|
||||
Argument *Arg = &*F->arg_begin();
|
||||
|
||||
|
@ -821,7 +821,7 @@ TEST_F(ScalarEvolutionsTest, SCEVExitLimitForgetLoop) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
|
||||
Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
|
||||
|
||||
BasicBlock *Top = BasicBlock::Create(Context, "top", F);
|
||||
BasicBlock *LPh = BasicBlock::Create(Context, "L.ph", F);
|
||||
|
@ -919,7 +919,7 @@ TEST_F(ScalarEvolutionsTest, SCEVExitLimitForgetValue) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
|
||||
Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
|
||||
|
||||
Argument *Arg = &*F->arg_begin();
|
||||
|
||||
|
@ -979,8 +979,7 @@ TEST_F(ScalarEvolutionsTest, SCEVAddRecFromPHIwithLargeConstants) {
|
|||
// ix.
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
|
||||
Function *F =
|
||||
Function::Create(FTy, Function::ExternalLinkage, "addrecphitest", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("addrecphitest", FTy));
|
||||
|
||||
/*
|
||||
Create IR:
|
||||
|
@ -1036,8 +1035,7 @@ TEST_F(ScalarEvolutionsTest, SCEVAddRecFromPHIwithLargeConstantAccum) {
|
|||
SmallVector<Type *, 1> Types;
|
||||
Types.push_back(Int32Ty);
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
|
||||
Function *F =
|
||||
Function::Create(FTy, Function::ExternalLinkage, "addrecphitest", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("addrecphitest", FTy));
|
||||
|
||||
/*
|
||||
Create IR:
|
||||
|
@ -1091,7 +1089,7 @@ TEST_F(ScalarEvolutionsTest, SCEVFoldSumOfTruncs) {
|
|||
SmallVector<Type *, 1> Types;
|
||||
Types.push_back(ArgTy);
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
|
||||
ReturnInst::Create(Context, nullptr, BB);
|
||||
|
||||
|
@ -1147,7 +1145,7 @@ TEST_F(ScalarEvolutionsTest, SCEVExpanderIsSafeToExpandAt) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
|
||||
Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
|
||||
|
||||
BasicBlock *Top = BasicBlock::Create(Context, "top", F);
|
||||
BasicBlock *LPh = BasicBlock::Create(Context, "L.ph", F);
|
||||
|
@ -1208,7 +1206,7 @@ TEST_F(ScalarEvolutionsTest, SCEVExpanderNUW) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
|
||||
Argument *Arg = &*F->arg_begin();
|
||||
ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
|
||||
|
||||
|
@ -1260,7 +1258,7 @@ TEST_F(ScalarEvolutionsTest, SCEVExpanderNSW) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
|
||||
Argument *Arg = &*F->arg_begin();
|
||||
ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
|
||||
|
||||
|
@ -1310,7 +1308,7 @@ TEST_F(ScalarEvolutionsTest, SCEVCacheNUW) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
|
||||
Argument *Arg = &*F->arg_begin();
|
||||
ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
|
||||
|
||||
|
@ -1361,7 +1359,7 @@ TEST_F(ScalarEvolutionsTest, SCEVCacheNSW) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
|
||||
Argument *Arg = &*F->arg_begin();
|
||||
ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
|
||||
|
||||
|
@ -1411,7 +1409,7 @@ TEST_F(ScalarEvolutionsTest, SCEVComputeExpressionSize) {
|
|||
|
||||
FunctionType *FTy =
|
||||
FunctionType::get(Type::getVoidTy(Context), { T_int64, T_int64 }, false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
|
||||
Argument *A = &*F->arg_begin();
|
||||
Argument *B = &*std::next(F->arg_begin());
|
||||
ConstantInt *C = ConstantInt::get(Context, APInt(64, 1));
|
||||
|
|
|
@ -33,7 +33,7 @@ protected:
|
|||
static StoreInst *getFunctionWithSingleStore(Module *M, StringRef Name) {
|
||||
auto &C = M->getContext();
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), {});
|
||||
auto *F = Function::Create(FTy, Function::ExternalLinkage, Name, M);
|
||||
auto *F = cast<Function>(M->getOrInsertFunction(Name, FTy));
|
||||
auto *BB = BasicBlock::Create(C, "entry", F);
|
||||
auto *IntType = Type::getInt32Ty(C);
|
||||
auto *PtrType = Type::getInt32PtrTy(C);
|
||||
|
|
|
@ -67,7 +67,7 @@ TEST_F(TargetLibraryInfoTest, InvalidProto) {
|
|||
for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) {
|
||||
LibFunc LF = (LibFunc)FI;
|
||||
auto *F = cast<Function>(
|
||||
M->getOrInsertFunction(TLI.getName(LF), InvalidFTy).getCallee());
|
||||
M->getOrInsertFunction(TLI.getName(LF), InvalidFTy));
|
||||
EXPECT_FALSE(isLibFunc(F, LF));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ CFGHolder::CFGHolder(StringRef ModuleName, StringRef FunctionName)
|
|||
: Context(llvm::make_unique<LLVMContext>()),
|
||||
M(llvm::make_unique<Module>(ModuleName, *Context)) {
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Context), {}, false);
|
||||
F = Function::Create(FTy, Function::ExternalLinkage, FunctionName, M.get());
|
||||
F = cast<Function>(M->getOrInsertFunction(FunctionName, FTy));
|
||||
}
|
||||
CFGHolder::~CFGHolder() = default;
|
||||
|
||||
|
|
|
@ -117,9 +117,8 @@ protected:
|
|||
32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, "");
|
||||
}
|
||||
Function *getFunction(StringRef Name) {
|
||||
return Function::Create(
|
||||
FunctionType::get(Type::getVoidTy(Context), None, false),
|
||||
Function::ExternalLinkage, Name, M);
|
||||
return cast<Function>(M.getOrInsertFunction(
|
||||
Name, FunctionType::get(Type::getVoidTy(Context), None, false)));
|
||||
}
|
||||
};
|
||||
typedef MetadataTest MDStringTest;
|
||||
|
|
|
@ -26,7 +26,7 @@ TEST(VerifierTest, Branch_i1) {
|
|||
LLVMContext C;
|
||||
Module M("M", C);
|
||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
|
||||
BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
|
||||
BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
|
||||
ReturnInst::Create(C, Exit);
|
||||
|
@ -49,7 +49,7 @@ TEST(VerifierTest, InvalidRetAttribute) {
|
|||
LLVMContext C;
|
||||
Module M("M", C);
|
||||
FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
|
||||
Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
|
||||
Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
|
||||
AttributeList AS = F->getAttributes();
|
||||
F->setAttributes(
|
||||
AS.addAttribute(C, AttributeList::ReturnIndex, Attribute::UWTable));
|
||||
|
@ -67,9 +67,9 @@ TEST(VerifierTest, CrossModuleRef) {
|
|||
Module M2("M2", C);
|
||||
Module M3("M3", C);
|
||||
FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
|
||||
Function *F1 = Function::Create(FTy, Function::ExternalLinkage, "foo1", M1);
|
||||
Function *F2 = Function::Create(FTy, Function::ExternalLinkage, "foo2", M2);
|
||||
Function *F3 = Function::Create(FTy, Function::ExternalLinkage, "foo3", M3);
|
||||
Function *F1 = cast<Function>(M1.getOrInsertFunction("foo1", FTy));
|
||||
Function *F2 = cast<Function>(M2.getOrInsertFunction("foo2", FTy));
|
||||
Function *F3 = cast<Function>(M3.getOrInsertFunction("foo3", FTy));
|
||||
|
||||
BasicBlock *Entry1 = BasicBlock::Create(C, "entry", F1);
|
||||
BasicBlock *Entry3 = BasicBlock::Create(C, "entry", F3);
|
||||
|
@ -173,8 +173,8 @@ TEST(VerifierTest, DetectInvalidDebugInfo) {
|
|||
new GlobalVariable(M, Type::getInt8Ty(C), false,
|
||||
GlobalValue::ExternalLinkage, nullptr, "g");
|
||||
|
||||
auto *F = Function::Create(FunctionType::get(Type::getVoidTy(C), false),
|
||||
Function::ExternalLinkage, "f", M);
|
||||
auto *F = cast<Function>(M.getOrInsertFunction(
|
||||
"f", FunctionType::get(Type::getVoidTy(C), false)));
|
||||
IRBuilder<> Builder(BasicBlock::Create(C, "", F));
|
||||
Builder.CreateUnreachable();
|
||||
F->setSubprogram(DIB.createFunction(
|
||||
|
|
Loading…
Reference in New Issue