Abstract
不是鲸书。
arvcc
想尝试设计一套针对优化和程序分析的框架。 通常做程序分析有两条路子,一条是针对程序分析的专用分析器,单独作为一套框架使用;另一条是作为编译器的优化趟来实现, 想到哪里写到哪里。
针对常规的编译流程Source——IR——CodeGen,我目前还是倾向于Clang的设计,先打算研究其架构并简化出来一套适合的东西。其次要继续读static analysis方向的论文,复现其算法和原理。
我准备在arvcc仓库里面实现新设计的编译框架,最近的工作主要是将Clang里面的架构简化出来然后加以利用。
Option
llvm中所有的工具都会使用到选项options:
1 | '-emit-llvm', '-S' and'test.cpp' are all options |
所以option是一个根类,各个工具也有自己的选项子类比如Driver下面可以有自己的DriverOption。这些XXXOption都是各个工具*.td/*.def文件自定义,然后通过TableGen自动生成的。
arvcc聚焦了很少的功能,所以我打算将各自Option直接集成到不同工具目录下,比如Driver的话,就直接定义在DriverOption.h中,其中DriverOption类继承自Option类。
Driver
工业级编译器需要考虑很多兼容性功能和用户接口,从而有了Driver的概念。还有很多性能上的trade-off从而用很多LLVM自定义的数据结构。故其具体实现上也及其复杂繁琐。
Clang本质是一个Driver,而-cc1才是编译器前端。在命令行中敲下clang a.cpp之后,编译器默认会自带很多编译选项-###,其中就有-cc1来进入编译器前端。
Type
Clang通过定义各个DriverOptions的类型来映射整个编译流程,甚至精确到了选择指定的工具,编译步骤和输出格式。
开发环境
记录自己机器上和开发有关的些许细节。
brew
brew是用的最多的,我机器上存在多个版本的软件比如python/llvm/node...,PATH里都是以brew版本为准(因为时间原因,可能brew自己构建其他软件的依赖也选择了不同的版本,可以使用brew search xxx来查看)。下面列出项目相关:
llvm+clang:构建于brew info llvm,目前-v = 13.0.1$CC/CXX用于cmake的默认编译器-LDFLAGS/CPPFLAGS用于cmake编译器编译选项
NeoVim:构建于brew info NeoVim,目前版本-v = 0.6.1,依赖检查: checkhealthVoltron:构建依赖brew info python 3.10ccls:构建依赖brew info llvm
lsp
今年正式从Vim+YCM转到了NeoVim+LSP。language server protocol降低了由M家IDE厂商分别为N门语言做插件的复杂度。由language server(针对语言)和language client(针对IDE/Editor)两部分构成。我的配置是server:ccls+client:coc.vim.
目前仅仅使用其completion和go to def/ref功能。
ccls
-DCMAKE_PREFIX_PATH选项很重要,这是因为它将clang/llvm的头文件include paths和库resourceDir硬编码到ccls中以便索引。
include paths: clang -v -fsyntax-only -x c++ /dev/null
resourceDir: clang -print-resource-dir
ccls使用.ccls/ compile_command.json来索引文件:
1 | % cmake -H. -BDebug -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=YES |
coc.vim
想要加其他语言的插件:CocConfig。
有些硬编码的字符可以直接使用grep来过滤文本文件内容,fzf/find来查找指定目录下的文件。
1 | grep -r "ccc_print_phases" llvm-src/clang/ # 目录查找 |
lldb
我用voltron做调试器前端,功能很全就是需要在自启动窗口。。有点麻烦
1 | $ voltron view register |