【问题标题】:Data type for bool in LLVM IRLLVM IR 中 bool 的数据类型
【发布时间】:2016-07-09 21:18:35
【问题描述】:

我正在编写一个编程语言编译器来集成 DSL 和 C/C++。为此,我决定使用 LLVM 有几个原因。

有一个主程序。在这个主程序中,我加载了由 clang 编译的 bitcode 文件。可加载的位码文件代表一个简短但完整的编程语言环境,包括 REPL、解析器、链接器和 AST。

到目前为止,我的理解是布尔数据类型在 IR 中表示为 i1。我已经用 -O3 优化了我的代码,我得到了一个布尔值跟随 IR 代码(通过使用 llvm-dis 从生成的位码文件中反汇编):

%"class.tl::contrib::toy::ToyREPL" = type <{  %"class.tl::contrib::toy::InitLanguage"*, i8, [7 x i8] }>

该类是 ToyREPL,它正在使用另一个类 InitLanguage。奇怪的是,布尔值似乎由一个 i8 和一个 i8 数组呈现。我真的不明白。

我已经定义了一个 Makefile。首先我编译文件。之后我将它们链接到一个 bc 文件,然后优化并将其与其他一些库链接。

@cd $(BIN)/$(TARGET)/$(2); $(LINK) -o $(1).$(BITCODE_EXT) $(3)

@cd $(BIN)/$(TARGET)/$(2); $(OPT) -O3 $(1).$(BITCODE_EXT) -o $(1).$(OPT_NAME).$(BITCODE_EXT) $(OPTIMIZER_FLAGS) 

@$(LINK) -o $(BIN)/$(TARGET)/$(2)/$(1).$(BITCODE_EXT) $(BIN)/$(TARGET)/$(2)/$(1).$(OPT_NAME).bc $(LINK_OPTION) $(4)

编译器标志是:

-v -g -emit-llvm -I$(BOOST_INC_DIR) -std=c++11 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS

优化器标志是-std-link-opts

链接标志是-v

ToyREPL 类的相关部分在这里:

class ToyREPL {
private:

  InitLanguage *initLang;

  bool runs = false;

现在我的问题:我的假设是错误的 bool 应该被编译为 i1 的位码吗?我需要考虑什么样的编译器开关才能编译到 i1?如果您认为我的构建过程在某些方面是错误的,请告诉我。生成的位码文件是可读的,我可以将模块和类 ToyREPL 作为 StructType 检索。

【问题讨论】:

  • 用代码替换引号——在引用供人类而非计算机编写的内容时,引号通常是最好的。 ;)

标签: c++ c++11 llvm llvm-clang


【解决方案1】:

如果我理解正确,你的问题本质上是 - 为什么是 C++ 类

class ToyREPL {
  bool runs = false;
  ...
};

由 Clang 编译成 type &lt;{ i8, [7 x i8], ... }&gt;?

首先,为什么 Clang 选择 i8 而不是 i1 作为布尔字段很简单 - the smallest C++ type takes one byte of memory,除非您使用位字段,否则这也适用于结构中的字段。另见this related question about why a whole byte is used for booleans。 LLVM 本身使用i1 作为布尔值,但那是因为它大致独立于平台——在降低阶段,它们可能会再次变成整个字节。

至于[7 x i8],这是填充,用于确保这种类型的每个对象都是 64 位对齐的,并且不与任何其他对象共享其内存 - 在 64 位系统上非常合理的方法。或者,如果有以下结构字段,则可能已插入填充以确保该字段是 64 位对齐的。

如果您想了解更多信息,The Wikipedia article on alignment and padding 是一个有用的起点。

【讨论】:

  • 这似乎是显而易见的答案......但是 LLVM 方面没有例外,还是其中大部分是由指定 C++ 的方式引起的?
  • 谢谢。填充是有意义的,因为我有一台 64 位机器。但这意味着只有当我手头有位码时,我才能区分整数值和布尔值,不是吗?
  • @VermillionAzure 这一切都来自 Clang,据我所知,由于 C++ 的指定方式和性能原因。例如,另一种语言可能要求 i1 用于布尔值以节省空间 - 但随后降低阶段可能会做一些时髦的事情,以便在只有字节寻址的机器上加载和存储 i1
  • @repl 您可以通过查看如何来辨别它是如何使用的……但总的来说,我想您是对的,而且无法判断。如果它对您很重要,您可以随时打开调试信息,它应该提供有关每个字段声明类型的所有信息。
猜你喜欢
  • 1970-01-01
  • 2014-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多