如何在LLVM中声明函数并稍后定义它

How to declare a function in LLVM and define it later

本文关键字:定义 函数 声明 LLVM      更新时间:2023-10-16

我如何在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:

BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
Builder.SetInsertPoint(BB);

PS:答案是未经测试的,回答者不是LLVM专家。

PPS:对于InlineAsm函数,正如我在使用MetaGer进行搜索后认为的那样,您不能声明函数引用自万花筒。唯一的方法是在调用的地方创建InlineAsm函数。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