【问题标题】:about LLVM IR: No function definition in LLVM ir code关于 LLVM IR:LLVM ir 代码中没有函数定义
【发布时间】:2016-07-26 21:54:01
【问题描述】:

我正在查看由 clang 转换为 cpp 文件的 llvm ir 文件。但是我发现 llvm ir 文件中有几个函数只有声明而没有定义。而且所有这些功能都不是“内置”功能,例如:

declare i32 @puts(i8* nocapture)

就像:

declare void @_ZNK5Arrow7BaseRow9getColumnINS_11IpGenPrefixEEEvtRT_(%"class.Arrow::BaseRow"*, i16 zeroext, %"class.Arrow::IpGenPrefix"* dereferenceable(24)) #0

这些函数似乎使用了一些外部定义?我是 LLVM IR 的新手。我想知道 LLVM IR 有没有办法像 cpp 库那样做,我可以存储我将在一些 LLVM IR 库中使用的函数,并通过像 include 这样的操作在 .ll 文件中使用它们?

谢谢

【问题讨论】:

  • 您确定包含定义Arrow::BaseRow::getColumn<Arrow::IpGenPrefix> 的文件吗?
  • 不,没有包含声明类型。显然,它可以通过一些插入声明的实用程序来实现。
  • @eush77 正如我所提到的,这个 llvm ir 是用 clang 从一个 cpp 文件转换而来的。 cpp 文件包括定义 getColumn 的文件。但是我想知道当我使用 MCJIT 执行 llvm ir 中的函数时,我将如何执行仅在 llvm ir 中声明而没有定义的函数。 llvm ir 中的函数是否仅在(cpp 文件)等其他文件中声明和定义?以及如何生成这种函数?

标签: llvm llvm-clang llvm-ir llvm-c++-api llvm-3.0


【解决方案1】:

这些函数似乎使用了一些外部定义?

没错。 declare 关键字indicates 一个函数声明,与函数定义相对,函数声明can only be linked externally

函数声明具有除 external 或 extern_weak 之外的任何链接类型都是非法的。

Clang 生成声明而不是定义的原因是(很可能)这些函数没有在提供给它的翻译单元中定义。

声明在链接期间被解析。要将多个 LLVM 模块链接在一起,请使用 llvm-link 工具。

例如,假设lib.cpp 定义了函数foo(),该函数在main.cpp 中使用。

$ clang++ -c -emit-llvm main.cpp lib.cpp

此命令将这些文件编译为 LLVM IR 并创建两个模块 main.bclib.bcmain.bc 仅包含 foo() 的声明,因为此函数是在单独的翻译单元中定义的。 foo()的定义在lib.bc中。

$ llvm-link main.bc lib.bc -o all.bc

此命令将main.bclib.bc 链接到一个模块中,该模块现在包含foo() 的定义。

【讨论】:

  • 就我而言,我有三个文件:main.cpplib.cppfunc.cpp:首先:func.cpp 有一个函数 foo(),它在 lib.cpp 中使用函数 foo1() ,而func.cpp被clang SECOND转换为func.llmain.cpp使用parseIRFile提取func.ll中的函数foo()并调用它。 Q:函数func.ll只有foo1()的声明,没有定义。虽然main.cpp 不包括lib.h,但func.ll 中没有定义,如何在llvm ir 中没有定义的情况下执行foo1()。如果可以,我们如何在 llvm ir 中手动生成这种函数。
  • @He 嗯,这样编译调用foo()会失败吗?您是否将lib.cpp 链接到main.cpp 以便foo1 在目标文件中存在并且在外部可见?当没有给出定义时,LLVM 应该按名称找到 foo1()。见stackoverflow.com/a/6086687/2424184
  • 感谢您的帮助。它没有失败。但是我想手动生成 llvm ir,所以我想知道是否可以在 llvm ir 中使用 cpp 函数,以及我们如何做到这一点。换句话说,我希望我的 llvm ir 可以使用 cpp 文件中定义的函数。我知道我需要在 llvm ir 中声明该函数,但是如何将此声明链接到 cpp 中的定义。
  • @He (1) 无论 LLVM IR 是如何生成的,无论是通过 Clang 还是您自己的代码,这都应该通过函数名称自动发生。它可能会由于名称修改而失败。 (2) 然后您的另一个选择是使用Module::getFunction 从模块中获取LLVM 函数,并使用ExecutionEngine::addGlobalMapping 手动将其映射到目标C++ 函数的地址。
  • 您的意思是函数名称是 llvm ir 中的名称,如 _ZNK5Arrow7BaseRow9getColumnINS_11IpGenPrefixEEEvtRT_ 或 cpp 中的函数名称 getColumn。所以基本上我只是在llvm ir中声明了外部函数,当我使用MCJIT时,它会自己解析函数吗?顺便说一句,非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-30
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多