rep*_*epl 5 c++ llvm llvm-clang c++11
我正在编写一个编程语言编译器来集成 DSL 和 C/C++。为此,我出于几个原因决定使用 LLVM。
有一个主程序。在这个主程序中,我加载了由 clang 编译的位码文件。可加载的位码文件代表一个简短但完整的编程语言环境,包含 REPL、解析器、链接器和 AST。
到目前为止,我的理解是布尔数据类型在 IR 中表示为 i1。我已经使用 -O3 优化了我的代码,并得到了以下 IR 代码的布尔值(通过使用 llvm-dis 从生成的位码文件中反汇编):
%"class.tl::contrib::toy::ToyREPL" = type <{ %"class.tl::contrib::toy::InitLanguage"*, i8, [7 x i8] }>
Run Code Online (Sandbox Code Playgroud)
该类是 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)
Run Code Online (Sandbox Code Playgroud)
编译器标志是:
-v -g -emit-llvm -I$(BOOST_INC_DIR) -std=c++11 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
Run Code Online (Sandbox Code Playgroud)
优化器标志是-std-link-opts
链接标志是-v.
ToyREPL 类的相关部分在这里:
class ToyREPL {
private:
InitLanguage *initLang;
bool runs = false;
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:我的假设是否错误 bool 应该被编译为 i1?我需要考虑什么样的编译器开关才能编译到 i1?如果您认为我的构建过程在某种程度上是错误的,请告诉我。生成的位码文件是可读的,我可以检索模块和 ToyREPL 类作为 StructType。
如果我理解正确的话,你的问题本质上是 - 为什么 C++ 类
class ToyREPL {
bool runs = false;
...
};
Run Code Online (Sandbox Code Playgroud)
由 Clang 编译成type <{ i8, [7 x i8], ... }>?
首先,为什么 Clang 选择i8布尔i1字段很简单 -最小的 C++ 类型占用一个字节的内存,除非您使用位字段,否则这也适用于结构中的字段。另请参阅有关为什么将整个字节用于 booleans 的相关问题。LLVM 本身用于i1布尔值,但这是因为它大致与平台无关 - 在降低阶段,这些值可能会再次变成整个字节。
至于[7 x i8],这是填充,旨在确保这种类型的每个对象都是 64 位对齐的,并且不与任何其他对象共享其内存 - 在 64 位系统上这是非常合理的方法。或者,如果存在以下结构字段,则可能已插入填充以确保该字段是 64 位对齐的。
如果您想了解更多信息,有关对齐和填充的维基百科文章是一个有用的起点。
| 归档时间: |
|
| 查看次数: |
6575 次 |
| 最近记录: |