本文整理汇总了C++中Argument::setName方法的典型用法代码示例。如果您正苦于以下问题:C++ Argument::setName方法的具体用法?C++ Argument::setName怎么用?C++ Argument::setName使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Argument
的用法示例。
在下文中一共展示了Argument::setName方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: insertIndirectCounterIncrement
void GCOVProfiler::insertIndirectCounterIncrement() {
Function *Fn =
cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
Fn->setUnnamedAddr(true);
Fn->setLinkage(GlobalValue::InternalLinkage);
Fn->addFnAttr(Attributes::NoInline);
if (NoRedZone)
Fn->addFnAttr(Attributes::NoRedZone);
Type *Int32Ty = Type::getInt32Ty(*Ctx);
Type *Int64Ty = Type::getInt64Ty(*Ctx);
Constant *NegOne = ConstantInt::get(Int32Ty, 0xffffffff);
// Create basic blocks for function.
BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn);
IRBuilder<> Builder(BB);
BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn);
BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn);
BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn);
// uint32_t pred = *predecessor;
// if (pred == 0xffffffff) return;
Argument *Arg = Fn->arg_begin();
Arg->setName("predecessor");
Value *Pred = Builder.CreateLoad(Arg, "pred");
Value *Cond = Builder.CreateICmpEQ(Pred, NegOne);
BranchInst::Create(Exit, PredNotNegOne, Cond, BB);
Builder.SetInsertPoint(PredNotNegOne);
// uint64_t *counter = counters[pred];
// if (!counter) return;
Value *ZExtPred = Builder.CreateZExt(Pred, Int64Ty);
Arg = llvm::next(Fn->arg_begin());
Arg->setName("counters");
Value *GEP = Builder.CreateGEP(Arg, ZExtPred);
Value *Counter = Builder.CreateLoad(GEP, "counter");
Cond = Builder.CreateICmpEQ(Counter,
Constant::getNullValue(Int64Ty->getPointerTo()));
Builder.CreateCondBr(Cond, Exit, CounterEnd);
// ++*counter;
Builder.SetInsertPoint(CounterEnd);
Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter),
ConstantInt::get(Int64Ty, 1));
Builder.CreateStore(Add, Counter);
Builder.CreateBr(Exit);
// Fill in the exit block.
Builder.SetInsertPoint(Exit);
Builder.CreateRetVoid();
}
示例2: assert
static Function* createAdd1(Module *M) {
// Create the add1 function entry and insert this entry into module M. The
// function will have a return type of "int" and take an argument of "int".
// The '0' terminates the list of argument types.
Function *Add1F =
cast<Function>(M->getOrInsertFunction("add1", Type::Int32Ty, Type::Int32Ty,
(Type *)0));
// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
BasicBlock *BB = BasicBlock::Create("EntryBlock", Add1F);
// Get pointers to the constant `1'.
Value *One = ConstantInt::get(Type::Int32Ty, 1);
// Get pointers to the integer argument of the add1 function...
assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
Argument *ArgX = Add1F->arg_begin(); // Get the arg
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the add instruction, inserting it into the end of BB.
Instruction *Add = BinaryOperator::CreateAdd(One, ArgX, "addresult", BB);
// Create the return instruction and add it to the basic block
ReturnInst::Create(Add, BB);
// Now, function add1 is ready.
return Add1F;
}
示例3: visit
virtual void visit(Function *type)
{
Function *funTy = control()->newFunction(0, 0);
funTy->copy(type);
funTy->setConst(type->isConst());
funTy->setVolatile(type->isVolatile());
funTy->setName(rewrite->rewriteName(type->name()));
funTy->setReturnType(rewrite->rewriteType(type->returnType()));
for (unsigned i = 0, argc = type->argumentCount(); i < argc; ++i) {
Symbol *arg = type->argumentAt(i);
Argument *newArg = control()->newArgument(0, 0);
newArg->copy(arg);
newArg->setName(rewrite->rewriteName(arg->name()));
newArg->setType(rewrite->rewriteType(arg->type()));
// the copy() call above set the scope to 'type'
// reset it to 0 before adding addMember to avoid assert
newArg->resetEnclosingScope();
funTy->addMember(newArg);
}
temps.append(funTy);
}
示例4: Argument
Argument *Engine::newArgument(Function *function, const QString &name, const Type *type)
{
Argument *a = new Argument(function);
a->setName(name);
a->setType(type);
_symbols.append(a);
return a;
}
示例5: ICmpInst
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.
Function *FibF =
cast<Function>(M->getOrInsertFunction("fib", Type::getInt32Ty(Context),
Type::getInt32Ty(Context),
(Type *)0));
// Add a basic block to the function.
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", FibF);
// Get pointers to the constants.
Value *One = ConstantInt::get(Type::getInt32Ty(Context), 1);
Value *Two = ConstantInt::get(Type::getInt32Ty(Context), 2);
// Get pointer to the integer argument of the add1 function...
Argument *ArgX = FibF->arg_begin(); // Get the arg.
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the true_block.
BasicBlock *RetBB = BasicBlock::Create(Context, "return", FibF);
// Create an exit block.
BasicBlock* RecurseBB = BasicBlock::Create(Context, "recurse", FibF);
// Create the "if (arg <= 2) goto exitbb"
Value *CondInst = new ICmpInst(*BB, ICmpInst::ICMP_SLE, ArgX, Two, "cond");
BranchInst::Create(RetBB, RecurseBB, CondInst, BB);
// Create: ret int 1
ReturnInst::Create(Context, One, RetBB);
// create fib(x-1)
Value *Sub = BinaryOperator::CreateSub(ArgX, One, "arg", RecurseBB);
CallInst *CallFibX1 = CallInst::Create(FibF, Sub, "fibx1", RecurseBB);
CallFibX1->setTailCall();
// create fib(x-2)
Sub = BinaryOperator::CreateSub(ArgX, Two, "arg", RecurseBB);
CallInst *CallFibX2 = CallInst::Create(FibF, Sub, "fibx2", RecurseBB);
CallFibX2->setTailCall();
// fib(x-1)+fib(x-2)
Value *Sum = BinaryOperator::CreateAdd(CallFibX1, CallFibX2,
"addresult", RecurseBB);
// Create the return instruction and add it to the basic block
ReturnInst::Create(Context, Sum, RecurseBB);
return FibF;
}
示例6: initArgumentList
void ActionRequest::initArgumentList() {
Node *actNode = getActionNode();
if (actNode == NULL)
return;
int nArgNodes = actNode->getNNodes();
argumentList.clear();
for (int n = 0; n < nArgNodes; n++) {
Argument *arg = new Argument();
Node *argNode = actNode->getNode(n);
arg->setName(argNode->getName());
arg->setValue(argNode->getValue());
argumentList.add(arg);
}
}
示例7: main
int main() {
InitializeNativeTarget();
LLVMContext Context;
// Create some module to put our function into it.
Module *M = new Module("test", Context);
// 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),
(Type *)0));
// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", Add1F);
// Create a basic block builder with default parameters. The builder will
// automatically append instructions to the basic block `BB'.
IRBuilder<> builder(BB);
// Get pointers to the constant `1'.
Value *One = builder.getInt32(1);
// Get pointers to the integer argument of the add1 function...
assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
Argument *ArgX = Add1F->arg_begin(); // Get the arg
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the add instruction, inserting it into the end of BB.
Value *Add = builder.CreateAdd(One, ArgX);
// Create the return instruction and add it to the basic block
builder.CreateRet(Add);
// Now, function add1 is ready.
// 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),
(Type *)0));
// Add a basic block to the FooF function.
BB = BasicBlock::Create(Context, "EntryBlock", FooF);
// Tell the basic block builder to attach itself to the new basic block
builder.SetInsertPoint(BB);
// Get pointer to the constant `10'.
Value *Ten = builder.getInt32(10);
// Pass Ten to the call to Add1F
CallInst *Add1CallRes = builder.CreateCall(Add1F, Ten);
Add1CallRes->setTailCall(true);
// Create the return instruction and add it to the basic block.
builder.CreateRet(Add1CallRes);
// Now we create the JIT.
ExecutionEngine* EE = EngineBuilder(M).create();
outs() << "We just constructed this LLVM module:\n\n" << *M;
outs() << "\n\nRunning foo: ";
outs().flush();
// Call the `foo' function with no arguments:
std::vector<GenericValue> noargs;
GenericValue gv = EE->runFunction(FooF, noargs);
// Import result of execution:
outs() << "Result: " << gv.IntVal << "\n";
EE->freeMachineCodeForFunction(FooF);
delete EE;
llvm_shutdown();
return 0;
}
示例8: main
int main() {
// Create some module to put our function into it.
Module *M = new Module("test");
// 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::Int32Ty, Type::Int32Ty,
(Type *)0));
// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
BasicBlock *BB = BasicBlock::Create("EntryBlock", Add1F);
// Get pointers to the constant `1'.
Value *One = ConstantInt::get(Type::Int32Ty, 1);
// Get pointers to the integer argument of the add1 function...
assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
Argument *ArgX = Add1F->arg_begin(); // Get the arg
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the add instruction, inserting it into the end of BB.
Instruction *Add = BinaryOperator::CreateAdd(One, ArgX, "addresult", BB);
// Create the return instruction and add it to the basic block
ReturnInst::Create(Add, BB);
// Now, function add1 is ready.
// Now we going to create function `foo', which returns an int and takes no
// arguments.
Function *FooF =
cast<Function>(M->getOrInsertFunction("foo", Type::Int32Ty, (Type *)0));
// Add a basic block to the FooF function.
BB = BasicBlock::Create("EntryBlock", FooF);
// Get pointers to the constant `10'.
Value *Ten = ConstantInt::get(Type::Int32Ty, 10);
// Pass Ten to the call call:
CallInst *Add1CallRes = CallInst::Create(Add1F, Ten, "add1", BB);
Add1CallRes->setTailCall(true);
// Create the return instruction and add it to the basic block.
ReturnInst::Create(Add1CallRes, BB);
// Now we create the JIT.
ExistingModuleProvider* MP = new ExistingModuleProvider(M);
ExecutionEngine* EE = ExecutionEngine::create(MP, false);
outs() << "We just constructed this LLVM module:\n\n" << *M;
outs() << "\n\nRunning foo: ";
outs().flush();
// Call the `foo' function with no arguments:
std::vector<GenericValue> noargs;
GenericValue gv = EE->runFunction(FooF, noargs);
// Import result of execution:
outs() << "Result: " << gv.IntVal << "\n";
return 0;
}
示例9: initialize
void SharkFunction::initialize(const char *name) {
// Create the function
_function = Function::Create(
entry_point_type(),
GlobalVariable::InternalLinkage,
name);
// Get our arguments
Function::arg_iterator ai = function()->arg_begin();
Argument *method = ai++;
method->setName("method");
Argument *osr_buf = NULL;
if (is_osr()) {
osr_buf = ai++;
osr_buf->setName("osr_buf");
}
Argument *base_pc = ai++;
base_pc->setName("base_pc");
code_buffer()->set_base_pc(base_pc);
Argument *thread = ai++;
thread->setName("thread");
set_thread(thread);
// Create the list of blocks
set_block_insertion_point(NULL);
_blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, block_count());
for (int i = 0; i < block_count(); i++) {
ciTypeFlow::Block *b = flow()->pre_order_at(i);
// Work around a bug in pre_order_at() that does not return
// the correct pre-ordering. If pre_order_at() were correct
// this line could simply be:
// _blocks[i] = new SharkTopLevelBlock(this, b);
_blocks[b->pre_order()] = new SharkTopLevelBlock(this, b);
}
// Walk the tree from the start block to determine which
// blocks are entered and which blocks require phis
SharkTopLevelBlock *start_block = block(flow()->start_block_num());
assert(start_block->start() == flow()->start_bci(), "blocks out of order");
start_block->enter();
// Initialize all entered blocks
for (int i = 0; i < block_count(); i++) {
if (block(i)->entered())
block(i)->initialize();
}
// Create and push our stack frame
set_block_insertion_point(&function()->front());
builder()->SetInsertPoint(CreateBlock());
_stack = SharkStack::CreateBuildAndPushFrame(this, method);
// Create the entry state
SharkState *entry_state;
if (is_osr()) {
entry_state = new SharkOSREntryState(start_block, method, osr_buf);
// Free the OSR buffer
builder()->CreateCall(builder()->osr_migration_end(), osr_buf);
}
else {
entry_state = new SharkNormalEntryState(start_block, method);
// Lock if necessary
if (is_synchronized()) {
SharkTopLevelBlock *locker =
new SharkTopLevelBlock(this, start_block->ciblock());
locker->add_incoming(entry_state);
set_block_insertion_point(start_block->entry_block());
locker->acquire_method_lock();
entry_state = locker->current_state();
}
}
// Transition into the method proper
start_block->add_incoming(entry_state);
builder()->CreateBr(start_block->entry_block());
// Parse the blocks
for (int i = 0; i < block_count(); i++) {
if (!block(i)->entered())
continue;
if (i + 1 < block_count())
set_block_insertion_point(block(i + 1)->entry_block());
else
set_block_insertion_point(NULL);
block(i)->emit_IR();
}
do_deferred_zero_checks();
}
示例10: initialize
void SharkNativeWrapper::initialize(const char *name) {
// Create the function
_function = Function::Create(
SharkType::entry_point_type(),
GlobalVariable::InternalLinkage,
name);
// Get our arguments
Function::arg_iterator ai = function()->arg_begin();
Argument *method = ai++;
method->setName("method");
Argument *base_pc = ai++;
base_pc->setName("base_pc");
code_buffer()->set_base_pc(base_pc);
Argument *thread = ai++;
thread->setName("thread");
set_thread(thread);
// Create and push our stack frame
builder()->SetInsertPoint(CreateBlock());
_stack = SharkStack::CreateBuildAndPushFrame(this, method);
NOT_PRODUCT(method = NULL);
// Create the oopmap. We use the one oopmap for every call site in
// the wrapper, which results in the odd mild inefficiency but is a
// damn sight easier to code.
OopMap *oopmap = new OopMap(
SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()),
SharkStack::oopmap_slot_munge(arg_size()));
oopmap->set_oop(SharkStack::slot2reg(stack()->method_slot_offset()));
// Set up the oop_tmp slot if required:
// - For static methods we use it to handlize the class argument
// for the call, and to protect the same during slow path locks
// (if synchronized).
// - For methods returning oops, we use it to protect the return
// value across safepoints or slow path unlocking.
if (is_static() || is_returning_oop()) {
_oop_tmp_slot = stack()->slot_addr(
stack()->oop_tmp_slot_offset(),
SharkType::oop_type(),
"oop_tmp_slot");
oopmap->set_oop(SharkStack::slot2reg(stack()->oop_tmp_slot_offset()));
}
// Set up the monitor slot, for synchronized methods
if (is_synchronized()) {
Unimplemented();
_lock_slot_offset = 23;
}
// Start building the argument list
std::vector<const Type*> param_types;
std::vector<Value*> param_values;
const PointerType *box_type = PointerType::getUnqual(SharkType::oop_type());
// First argument is the JNIEnv
param_types.push_back(SharkType::jniEnv_type());
param_values.push_back(
builder()->CreateAddressOfStructEntry(
thread,
JavaThread::jni_environment_offset(),
SharkType::jniEnv_type(),
"jni_environment"));
// For static methods, the second argument is the class
if (is_static()) {
builder()->CreateStore(
builder()->CreateInlineOop(
JNIHandles::make_local(
target()->method_holder()->klass_part()->java_mirror())),
oop_tmp_slot());
param_types.push_back(box_type);
param_values.push_back(oop_tmp_slot());
_receiver_slot_offset = stack()->oop_tmp_slot_offset();
}
else if (is_returning_oop()) {
// The oop_tmp slot is registered in the oopmap,
// so we need to clear it. This is one of the
// mild inefficiencies I mentioned earlier.
builder()->CreateStore(LLVMValue::null(), oop_tmp_slot());
}
// Parse the arguments
for (int i = 0; i < arg_size(); i++) {
int slot_offset = stack()->locals_slots_offset() + arg_size() - 1 - i;
int adjusted_offset = slot_offset;
BasicBlock *null, *not_null, *merge;
Value *box;
PHINode *phi;
switch (arg_type(i)) {
case T_VOID:
break;
case T_OBJECT:
case T_ARRAY:
//.........这里部分代码省略.........
示例11: AllocaInst
// Creates the helper function that will do the setjmp() call and
// function call for implementing Invoke. Creates the call to the
// helper function. Returns a Value which is zero on the normal
// execution path and non-zero if the landingpad block should be
// entered.
Value *FuncRewriter::createSetjmpWrappedCall(InvokeInst *Invoke) {
Type *I32 = Type::getInt32Ty(Func->getContext());
// Allocate space for storing the invoke's result temporarily (so
// that the helper function can return multiple values). We don't
// need to do this if the result is unused, and we can't if its type
// is void.
Instruction *ResultAlloca = NULL;
if (!Invoke->use_empty()) {
ResultAlloca = new AllocaInst(Invoke->getType(), "invoke_result_ptr");
Func->getEntryBlock().getInstList().push_front(ResultAlloca);
}
// Create type for the helper function.
SmallVector<Type *, 10> ArgTypes;
for (unsigned I = 0, E = Invoke->getNumArgOperands(); I < E; ++I)
ArgTypes.push_back(Invoke->getArgOperand(I)->getType());
ArgTypes.push_back(Invoke->getCalledValue()->getType());
ArgTypes.push_back(FrameJmpBuf->getType());
if (ResultAlloca)
ArgTypes.push_back(Invoke->getType()->getPointerTo());
FunctionType *FTy = FunctionType::get(I32, ArgTypes, false);
// Create the helper function.
Function *HelperFunc = Function::Create(
FTy, GlobalValue::InternalLinkage, Func->getName() + "_setjmp_caller");
Func->getParent()->getFunctionList().insertAfter(Func, HelperFunc);
BasicBlock *EntryBB = BasicBlock::Create(Func->getContext(), "", HelperFunc);
BasicBlock *NormalBB = BasicBlock::Create(Func->getContext(), "normal",
HelperFunc);
BasicBlock *ExceptionBB = BasicBlock::Create(Func->getContext(), "exception",
HelperFunc);
// Unpack the helper function's arguments.
Function::arg_iterator ArgIter = HelperFunc->arg_begin();
SmallVector<Value *, 10> InnerCallArgs;
for (unsigned I = 0, E = Invoke->getNumArgOperands(); I < E; ++I) {
ArgIter->setName("arg");
InnerCallArgs.push_back(ArgIter++);
}
Argument *CalleeArg = ArgIter++;
Argument *JmpBufArg = ArgIter++;
CalleeArg->setName("func_ptr");
JmpBufArg->setName("jmp_buf");
// Create setjmp() call.
Value *SetjmpArgs[] = { JmpBufArg };
CallInst *SetjmpCall = CallInst::Create(SetjmpIntrinsic, SetjmpArgs,
"invoke_sj", EntryBB);
CopyDebug(SetjmpCall, Invoke);
// Setting the "returns_twice" attribute here prevents optimization
// passes from inlining HelperFunc into its caller.
SetjmpCall->setCanReturnTwice();
// Check setjmp()'s result.
Value *IsZero = CopyDebug(new ICmpInst(*EntryBB, CmpInst::ICMP_EQ, SetjmpCall,
ConstantInt::get(I32, 0),
"invoke_sj_is_zero"), Invoke);
CopyDebug(BranchInst::Create(NormalBB, ExceptionBB, IsZero, EntryBB), Invoke);
// Handle the normal, non-exceptional code path.
CallInst *InnerCall = CallInst::Create(CalleeArg, InnerCallArgs, "",
NormalBB);
CopyDebug(InnerCall, Invoke);
InnerCall->setAttributes(Invoke->getAttributes());
InnerCall->setCallingConv(Invoke->getCallingConv());
if (ResultAlloca) {
InnerCall->setName("result");
Argument *ResultArg = ArgIter++;
ResultArg->setName("result_ptr");
CopyDebug(new StoreInst(InnerCall, ResultArg, NormalBB), Invoke);
}
ReturnInst::Create(Func->getContext(), ConstantInt::get(I32, 0), NormalBB);
// Handle the exceptional code path.
ReturnInst::Create(Func->getContext(), ConstantInt::get(I32, 1), ExceptionBB);
// Create the outer call to the helper function.
SmallVector<Value *, 10> OuterCallArgs;
for (unsigned I = 0, E = Invoke->getNumArgOperands(); I < E; ++I)
OuterCallArgs.push_back(Invoke->getArgOperand(I));
OuterCallArgs.push_back(Invoke->getCalledValue());
OuterCallArgs.push_back(FrameJmpBuf);
if (ResultAlloca)
OuterCallArgs.push_back(ResultAlloca);
CallInst *OuterCall = CallInst::Create(HelperFunc, OuterCallArgs,
"invoke_is_exc", Invoke);
CopyDebug(OuterCall, Invoke);
// Retrieve the function return value stored in the alloca. We only
// need to do this on the non-exceptional path, but we currently do
// it unconditionally because that is simpler.
if (ResultAlloca) {
Value *Result = new LoadInst(ResultAlloca, "", Invoke);
Result->takeName(Invoke);
Invoke->replaceAllUsesWith(Result);
}
return OuterCall;
//.........这里部分代码省略.........
示例12: initLLVM
void initLLVM() {
InitializeNativeTarget();
// Create some module to put our function into it.
std::unique_ptr<Module> Owner = make_unique<Module>("test", Context);
Module *M = Owner.get();
// 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), (Type*)0
));
// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", Add1F);
// Create a basic block builder with default parameters. The builder will
// automatically append instructions to the basic block `BB'.
IRBuilder<> builder(BB);
// Get pointers to the constant `1'.
Value *One = builder.getInt32(1);
// Get pointers to the integer argument of the add1 function...
assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
Argument *ArgX = Add1F->arg_begin(); // Get the arg
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the add instruction, inserting it into the end of BB.
Value *Add = builder.CreateAdd(One, ArgX);
// Create the return instruction and add it to the basic block
builder.CreateRet(Add);
// Now, function add1 is ready.
// Now we're going to create function `foo',
// which returns an int and takes no arguments.
FooF = cast<Function>(M->getOrInsertFunction(
"foo", Type::getInt32Ty(Context), (Type *)0
));
// Add a basic block to the FooF function.
BB = BasicBlock::Create(Context, "EntryBlock", FooF);
// Tell the basic block builder to attach itself to the new basic block
builder.SetInsertPoint(BB);
// Get pointer to the constant `10'.
Value *Ten = builder.getInt32(10);
// Pass Ten to the call to Add1F
CallInst *Add1CallRes = builder.CreateCall(Add1F, Ten);
Add1CallRes->setTailCall(true);
// Create the return instruction and add it to the basic block.
builder.CreateRet(Add1CallRes);
// Now we create the JIT.
EE = EngineBuilder(std::move(Owner)).create();
/*
outs() << "We just constructed this LLVM module:\n\n" << *M;
outs() << "\n\nRunning foo: ";
outs().flush();
*/
}