Skip to content

Commit

Permalink
Module::getOrInsertFunction is using C-style vararg instead of variad…
Browse files Browse the repository at this point in the history
…ic templates.

From a user prospective, it forces the use of an annoying nullptr to mark the end of the vararg, and there's not type checking on the arguments.
The variadic template is an obvious solution to both issues.

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

llvm-svn: 299949
  • Loading branch information
serge-sans-paille-qb committed Apr 11, 2017
1 parent de3b9a2 commit 59a2d7b
Show file tree
Hide file tree
Showing 30 changed files with 171 additions and 200 deletions.
8 changes: 4 additions & 4 deletions llvm/examples/BrainF/BrainF.cpp
Expand Up @@ -74,18 +74,18 @@ void BrainF::header(LLVMContext& C) {

//declare i32 @getchar()
getchar_func = cast<Function>(module->
getOrInsertFunction("getchar", IntegerType::getInt32Ty(C), NULL));
getOrInsertFunction("getchar", IntegerType::getInt32Ty(C)));

//declare i32 @putchar(i32)
putchar_func = cast<Function>(module->
getOrInsertFunction("putchar", IntegerType::getInt32Ty(C),
IntegerType::getInt32Ty(C), NULL));
IntegerType::getInt32Ty(C)));

//Function header

//define void @brainf()
brainf_func = cast<Function>(module->
getOrInsertFunction("brainf", Type::getVoidTy(C), NULL));
getOrInsertFunction("brainf", Type::getVoidTy(C)));

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

Expand Down Expand Up @@ -156,7 +156,7 @@ void BrainF::header(LLVMContext& C) {
//declare i32 @puts(i8 *)
Function *puts_func = cast<Function>(module->
getOrInsertFunction("puts", IntegerType::getInt32Ty(C),
PointerType::getUnqual(IntegerType::getInt8Ty(C)), NULL));
PointerType::getUnqual(IntegerType::getInt8Ty(C))));

//brainf.aberror:
aberrorbb = BasicBlock::Create(C, label, brainf_func);
Expand Down
2 changes: 1 addition & 1 deletion llvm/examples/BrainF/BrainFDriver.cpp
Expand Up @@ -77,7 +77,7 @@ void addMainFunction(Module *mod) {
getOrInsertFunction("main", IntegerType::getInt32Ty(mod->getContext()),
IntegerType::getInt32Ty(mod->getContext()),
PointerType::getUnqual(PointerType::getUnqual(
IntegerType::getInt8Ty(mod->getContext()))), NULL));
IntegerType::getInt8Ty(mod->getContext())))));
{
Function::arg_iterator args = main_func->arg_begin();
Value *arg_0 = &*args++;
Expand Down
3 changes: 1 addition & 2 deletions llvm/examples/Fibonacci/fibonacci.cpp
Expand Up @@ -54,8 +54,7 @@ static Function *CreateFibFunction(Module *M, LLVMContext &Context) {
// to return an int and take an int parameter.
Function *FibF =
cast<Function>(M->getOrInsertFunction("fib", Type::getInt32Ty(Context),
Type::getInt32Ty(Context),
nullptr));
Type::getInt32Ty(Context)));

// Add a basic block to the function.
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", FibF);
Expand Down
7 changes: 2 additions & 5 deletions llvm/examples/HowToUseJIT/HowToUseJIT.cpp
Expand Up @@ -69,11 +69,9 @@ int main() {

// Create the add1 function entry and insert this entry into module M. The
// function will have a return type of "int" and take an argument of "int".
// The '0' terminates the list of argument types.
Function *Add1F =
cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context),
Type::getInt32Ty(Context),
nullptr));
Type::getInt32Ty(Context)));

// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
Expand Down Expand Up @@ -102,8 +100,7 @@ int main() {
// Now we're going to create function `foo', which returns an int and takes no
// arguments.
Function *FooF =
cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context),
nullptr));
cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context)));

// Add a basic block to the FooF function.
BB = BasicBlock::Create(Context, "EntryBlock", FooF);
Expand Down
6 changes: 2 additions & 4 deletions llvm/examples/ParallelJIT/ParallelJIT.cpp
Expand Up @@ -54,8 +54,7 @@ static Function* createAdd1(Module *M) {
Function *Add1F =
cast<Function>(M->getOrInsertFunction("add1",
Type::getInt32Ty(M->getContext()),
Type::getInt32Ty(M->getContext()),
nullptr));
Type::getInt32Ty(M->getContext())));

// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
Expand Down Expand Up @@ -85,8 +84,7 @@ static Function *CreateFibFunction(Module *M) {
Function *FibF =
cast<Function>(M->getOrInsertFunction("fib",
Type::getInt32Ty(M->getContext()),
Type::getInt32Ty(M->getContext()),
nullptr));
Type::getInt32Ty(M->getContext())));

// Add a basic block to the function.
BasicBlock *BB = BasicBlock::Create(M->getContext(), "EntryBlock", FibF);
Expand Down
18 changes: 14 additions & 4 deletions llvm/include/llvm/IR/Module.h
Expand Up @@ -321,12 +321,22 @@ class Module {
/// or a ConstantExpr BitCast of that type if the named function has a
/// different type. This version of the method takes a null terminated list of
/// function arguments, which makes it easier for clients to use.
Constant *getOrInsertFunction(StringRef Name, AttributeList AttributeList,
Type *RetTy, ...) LLVM_END_WITH_NULL;
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),
AttributeList);
}

/// Same as above, but without the attributes.
Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ...)
LLVM_END_WITH_NULL;
template<typename... ArgsTy>
Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ArgsTy... Args) {
return getOrInsertFunction(Name, AttributeList{}, RetTy, Args...);
}

/// Look up the specified function in the module symbol table. If it does not
/// exist, return null.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/CountingFunctionInserter.cpp
Expand Up @@ -41,7 +41,7 @@ namespace {
Type *VoidTy = Type::getVoidTy(F.getContext());
Constant *CountingFn =
F.getParent()->getOrInsertFunction(CountingFunctionName,
VoidTy, nullptr);
VoidTy);
CallInst::Create(CountingFn, "", &*F.begin()->getFirstInsertionPt());
return true;
}
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/IntrinsicLowering.cpp
Expand Up @@ -115,21 +115,21 @@ void IntrinsicLowering::AddPrototypes(Module &M) {
Type::getInt8PtrTy(Context),
Type::getInt8PtrTy(Context),
Type::getInt8PtrTy(Context),
DL.getIntPtrType(Context), nullptr);
DL.getIntPtrType(Context));
break;
case Intrinsic::memmove:
M.getOrInsertFunction("memmove",
Type::getInt8PtrTy(Context),
Type::getInt8PtrTy(Context),
Type::getInt8PtrTy(Context),
DL.getIntPtrType(Context), nullptr);
DL.getIntPtrType(Context));
break;
case Intrinsic::memset:
M.getOrInsertFunction("memset",
Type::getInt8PtrTy(Context),
Type::getInt8PtrTy(Context),
Type::getInt32Ty(M.getContext()),
DL.getIntPtrType(Context), nullptr);
DL.getIntPtrType(Context));
break;
case Intrinsic::sqrt:
EnsureFPIntrinsicsExist(M, F, "sqrtf", "sqrt", "sqrtl");
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineOutliner.cpp
Expand Up @@ -1098,7 +1098,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
// Create the function using an IR-level function.
LLVMContext &C = M.getContext();
Function *F = dyn_cast<Function>(
M.getOrInsertFunction(NameStream.str(), Type::getVoidTy(C), nullptr));
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
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/SafeStack.cpp
Expand Up @@ -451,7 +451,7 @@ void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, ReturnInst &RI,
IRBuilder<> IRBFail(CheckTerm);
// FIXME: respect -fsanitize-trap / -ftrap-function here?
Constant *StackChkFail = F.getParent()->getOrInsertFunction(
"__stack_chk_fail", IRB.getVoidTy(), nullptr);
"__stack_chk_fail", IRB.getVoidTy());
IRBFail.CreateCall(StackChkFail, {});
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/SjLjEHPrepare.cpp
Expand Up @@ -482,10 +482,10 @@ bool SjLjEHPrepare::runOnFunction(Function &F) {
Module &M = *F.getParent();
RegisterFn = M.getOrInsertFunction(
"_Unwind_SjLj_Register", Type::getVoidTy(M.getContext()),
PointerType::getUnqual(FunctionContextTy), nullptr);
PointerType::getUnqual(FunctionContextTy));
UnregisterFn = M.getOrInsertFunction(
"_Unwind_SjLj_Unregister", Type::getVoidTy(M.getContext()),
PointerType::getUnqual(FunctionContextTy), nullptr);
PointerType::getUnqual(FunctionContextTy));
FrameAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::frameaddress);
StackAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave);
StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore);
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/StackProtector.cpp
Expand Up @@ -484,13 +484,13 @@ BasicBlock *StackProtector::CreateFailBB() {
Constant *StackChkFail =
M->getOrInsertFunction("__stack_smash_handler",
Type::getVoidTy(Context),
Type::getInt8PtrTy(Context), nullptr);
Type::getInt8PtrTy(Context));

B.CreateCall(StackChkFail, B.CreateGlobalStringPtr(F->getName(), "SSH"));
} else {
Constant *StackChkFail =
M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context),
nullptr);
M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));

B.CreateCall(StackChkFail, {});
}
B.CreateUnreachable();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/TargetLoweringBase.cpp
Expand Up @@ -1818,7 +1818,7 @@ Value *TargetLoweringBase::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
Type *StackPtrTy = Type::getInt8PtrTy(M->getContext());
Value *Fn = M->getOrInsertFunction("__safestack_pointer_address",
StackPtrTy->getPointerTo(0), nullptr);
StackPtrTy->getPointerTo(0));
return IRB.CreateCall(Fn);
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/IR/Instructions.cpp
Expand Up @@ -466,7 +466,7 @@ static Instruction *createMalloc(Instruction *InsertBefore,
Value *MallocFunc = MallocF;
if (!MallocFunc)
// prototype malloc as "void *malloc(size_t)"
MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, nullptr);
MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy);
PointerType *AllocPtrType = PointerType::getUnqual(AllocTy);
CallInst *MCall = nullptr;
Instruction *Result = nullptr;
Expand Down Expand Up @@ -560,7 +560,7 @@ static Instruction *createFree(Value *Source,
Type *VoidTy = Type::getVoidTy(M->getContext());
Type *IntPtrTy = Type::getInt8PtrTy(M->getContext());
// prototype free as "void free(void*)"
Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, nullptr);
Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy);
CallInst *Result = nullptr;
Value *PtrCast = Source;
if (InsertBefore) {
Expand Down
41 changes: 0 additions & 41 deletions llvm/lib/IR/Module.cpp
Expand Up @@ -147,47 +147,6 @@ Constant *Module::getOrInsertFunction(StringRef Name,
return getOrInsertFunction(Name, Ty, AttributeList());
}

// getOrInsertFunction - 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 version of the method takes a null terminated list of function
// arguments, which makes it easier for clients to use.
//
Constant *Module::getOrInsertFunction(StringRef Name,
AttributeList AttributeList, Type *RetTy,
...) {
va_list Args;
va_start(Args, RetTy);

// Build the list of argument types...
std::vector<Type*> ArgTys;
while (Type *ArgTy = va_arg(Args, Type*))
ArgTys.push_back(ArgTy);

va_end(Args);

// Build the function type and chain to the other getOrInsertFunction...
return getOrInsertFunction(Name,
FunctionType::get(RetTy, ArgTys, false),
AttributeList);
}

Constant *Module::getOrInsertFunction(StringRef Name,
Type *RetTy, ...) {
va_list Args;
va_start(Args, RetTy);

// Build the list of argument types...
std::vector<Type*> ArgTys;
while (Type *ArgTy = va_arg(Args, Type*))
ArgTys.push_back(ArgTy);

va_end(Args);

// Build the function type and chain to the other getOrInsertFunction...
return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false),
AttributeList());
}

// getFunction - Look up the specified function in the module symbol table.
// If it does not exist, return null.
//
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
Expand Up @@ -2146,8 +2146,7 @@ bool HexagonLoopIdiomRecognize::processCopyingStore(Loop *CurLoop,
Type *VoidTy = Type::getVoidTy(Ctx);
Module *M = Func->getParent();
Constant *CF = M->getOrInsertFunction(HexagonVolatileMemcpyName, VoidTy,
Int32PtrTy, Int32PtrTy, Int32Ty,
nullptr);
Int32PtrTy, Int32PtrTy, Int32Ty);
Function *Fn = cast<Function>(CF);
Fn->setLinkage(Function::ExternalLinkage);

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Mips/Mips16HardFloat.cpp
Expand Up @@ -420,7 +420,7 @@ static bool fixupFPReturnAndCall(Function &F, Module *M,
Attribute::ReadNone);
A = A.addAttribute(C, AttributeList::FunctionIndex,
Attribute::NoInline);
Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, nullptr));
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();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -2101,7 +2101,7 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const {
auto *SecurityCheckCookie = cast<Function>(
M.getOrInsertFunction("__security_check_cookie",
Type::getVoidTy(M.getContext()),
Type::getInt8PtrTy(M.getContext()), nullptr));
Type::getInt8PtrTy(M.getContext())));
SecurityCheckCookie->setCallingConv(CallingConv::X86_FastCall);
SecurityCheckCookie->addAttribute(1, Attribute::AttrKind::InReg);
return;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/IPO/CrossDSOCFI.cpp
Expand Up @@ -98,7 +98,7 @@ void CrossDSOCFI::buildCFICheck(Module &M) {
LLVMContext &Ctx = M.getContext();
Constant *C = M.getOrInsertFunction(
"__cfi_check", Type::getVoidTy(Ctx), Type::getInt64Ty(Ctx),
Type::getInt8PtrTy(Ctx), Type::getInt8PtrTy(Ctx), nullptr);
Type::getInt8PtrTy(Ctx), Type::getInt8PtrTy(Ctx));
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.
Expand All @@ -120,7 +120,7 @@ void CrossDSOCFI::buildCFICheck(Module &M) {
IRBuilder<> IRBFail(TrapBB);
Constant *CFICheckFailFn = M.getOrInsertFunction(
"__cfi_check_fail", Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx),
Type::getInt8PtrTy(Ctx), nullptr);
Type::getInt8PtrTy(Ctx));
IRBFail.CreateCall(CFICheckFailFn, {&CFICheckFailData, &Addr});
IRBFail.CreateBr(ExitBB);

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
Expand Up @@ -1221,7 +1221,7 @@ void DevirtModule::importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo) {
// The type of the function in the declaration is irrelevant because every
// call site will cast it to the correct type.
auto *SingleImpl = M.getOrInsertFunction(
Res.SingleImplName, Type::getVoidTy(M.getContext()), nullptr);
Res.SingleImplName, Type::getVoidTy(M.getContext()));

// This is the import phase so we should not be exporting anything.
bool IsExported = false;
Expand Down

0 comments on commit 59a2d7b

Please sign in to comment.