LLVM IR 中 bool 的数据类型

Data type for bool in LLVM IR

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

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

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

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

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

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

@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

Link 标志是 -v

Class ToyREPL 的相关部分在这里:

class ToyREPL {
private:

  InitLanguage *initLang;

  bool runs = false;

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

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

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

由 Clang 编译成 type <{ i8, [7 x i8], ... }>?

所以首先,为什么 Clang 选择 i8 而不是 i1 作为布尔字段很简单 - , and unless you use bit-fields, that also applies to fields in structs. Also see 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 是一个有用的起点。