Как я могу объявить функцию в LLVM (с определенной подписью) и создать вызов к ней, например,
llvm::Value* return = m_builder.CreateCall( function, arguments );
но затем определите тело функции позже (которая должна быть функцией InlineAsm)?
Позже я получаю доступ к функциям в модуле следующим образом
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
}
}
Поскольку подпись одна и та же, это должно быть возможно, я считаю.
Из руководства «Калейдоскоп: генерация кода в LLVM IR»: http://llvm.org/docs/tutorial/LangImpl3.html
3.4. Генерация кода функции
Генерация кода для прототипов и функций должна обрабатывать ряд деталей, которые делают их код менее красивым, чем генерация кода выражения, но позволяют нам проиллюстрировать некоторые важные моменты. Во-первых, давайте поговорим о генерации кода для прототипов: они используются как для тел функций, так и для объявлений внешних функций. Код начинается с:
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);
Позже, когда вы захотите добавить IR в функцию, вы должны получить ее объявление из модуля: TheModule->getFunction(Name);
и добавьте базовый блок:
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
Builder.SetInsertPoint(BB);
PS: ответ не проверен, а ответчик не является экспертом в LLVM.
PPS: для функции InlineAsm, как я думаю после делать поиски с MetaGer, Вы не можете объявить функцию, как указано в калейдоскопе. Единственный способ это иметь InlineAsm
Функция создана на месте вызова. Пример такого использования здесь: CyanogenMod / Android / искусство / составитель / 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
Других решений пока нет …