How can I declare a function in LLVM (with a specific signature) and create a call to it, e.g.
llvm::Value* return = m_builder.CreateCall( function, arguments );
but then define the body of the function later (which must be an InlineAsm function) ?
I'm later accessing the functions in a module in the following way
for (llvm::Module::iterator it = mod->begin(), end = mod->end(); it != end; ++it)
{
if( needsImplementation(it) ) {
llvm::InlineAsm* inlineCall = ...
it.body = inlineCall // This doesn't exist, pseudocode for what I need
}
}
Since the signature is the same this should be possible I believe.
A function declaration tells the compiler about a function name and how to call the function. The actual body of the function can be defined separately. int max(int, int); Function declaration is required when you define a function in one source file and you call that function in another file.
You can use Function::getArgumentList() method to get a list of function's arguments.
• nsw – no signed wrap for add, sub, mul, shl. • nuw – no unsigned wrap for add, sub, mul, shl.
All LLVM passes are subclasses of the Pass class, which implement functionality by overriding virtual methods inherited from Pass .
From the "Kaleidoscope: Code generation to LLVM IR" manual: http://llvm.org/docs/tutorial/LangImpl3.html
3.4. Function Code Generation
Code generation for prototypes and functions must handle a number of details, which make their code less beautiful than expression code generation, but allows us to illustrate some important points. First, lets talk about code generation for prototypes: they are used both for function bodies and external function declarations. The code starts with:
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector<Type*> Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
Later, when you want to add IR to the function you should get its declaration from the module: TheModule->getFunction(Name);
and add a BasicBlock:
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
Builder.SetInsertPoint(BB);
PS: answer is untested and answerer is not expert in LLVM.
PPS: For InlineAsm function, as I think after doing searches with MetaGer, you can't declare function as cited from Kaleidoscope. The only way is to have InlineAsm
function created at the place of call. Example of such usage is here: CyanogenMod/android/art/compiler/llvm/runtime_support_builder_x86.cc#44
44 Value* RuntimeSupportBuilderX86::EmitGetCurrentThread() {
45 Function* ori_func = GetRuntimeSupportFunction(runtime_support::GetCurrentThread);
// ^^^^^ this is used only to know right Type of Function.
46 std::string inline_asm(StringPrintf("mov %%fs:%d, $0", Thread::SelfOffset().Int32Value())); // <<< define the body of InlineAsm
47 InlineAsm* func = InlineAsm::get(ori_func->getFunctionType(), inline_asm, "=r", false); // << Create InlineAsm function
48 CallInst* thread = irb_.CreateCall(func); // << Call it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With