-
Notifications
You must be signed in to change notification settings - Fork 39
实验四代码优化
在实验sysu-generator中你已经成功生成了LLVM IR,但是得到的LLVM IR还有很大的优化空间,在sysu-optimizer中,你将需要对上一个实验生成的IR进行优化。举个例子。
对于源代码
int main(){
int a = 1;
return a;
}
使用clang -cc1 -O0 -S -emit-llvm
生成的IR如下
define i32 @main() {
entry:
%retval = alloca i32, align 4
%a = alloca i32, align 4
store i32 0, i32* %retval, align 4
store i32 1, i32* %a, align 4
%0 = load i32, i32* %a, align 4
ret i32 %0
}
使用clang -cc1 -O3 -S -emit-llvm
生成的IR如下
define i32 @main() {
entry:
ret i32 1
}
显然后者生成的IR在性能上更优。
建议阅读https://buaa-se-compiling.github.io/miniSysY-tutorial/pre/design_hints.html 了解LLVM IR是如何存储在内存的。
简单来说,整个IR文件是一个Module,Module里面是由多个Function和GlobalVariable构成的;一个Function又是由多个BasicBlock组成;BasicBlock里面包含一系列的Instruction。想对Module,Function等概念有更多了解的,可以阅读https://www.llvm.org/docs/ProgrammersManual.html#the-core-llvm-class-hierarchy-reference 。
要了解操作BasicBlock,Instruction等的方法可以阅读https://www.llvm.org/docs/ProgrammersManual.html#helpful-hints-for-common-operations 。
由于要编写Pass,然后利用Pass对IR进行优化,需要先学习Pass Manager,可以阅读下面的文章学习如何写Pass。
- https://llvm.org/docs/WritingAnLLVMNewPMPass.html
- https://llvm.org/docs/NewPassManager.html
- https://llvm.org/devmtg/2019-10/slides/Warzynski-WritingAnLLVMPass.pdf
- https://medium.com/@mshockwave/writing-llvm-pass-in-2018-part-i-531c700e85eb
- https://github.com/banach-space/llvm-tutor
其实可以参考样例代码中是如何编写Pass的
BasicBlock相关的API具体可以看"llvm/IR/BasicBlock.h"。
-
getTerminator()
:获得基本块的终止指令
Instruction相关的API具体可以看"llvm/IR/Instruction.h"。
-
eraseFromParent()
:将指令从基本块中删除 -
getOperand()
:获取指令的操作数 -
llvm::BinaryOperator::CreateAShr()
:创建新的指令 -
ReplaceInstWithInst(oldInst,NewInst)
:用新指令替换旧指令 -
ReplaceInstWithValue()
:用值替换指令
llvm::Module M;
for(auto gv_iter = M.global_begin();gv_iter!=M.global_end();gv_iter++){
...
}//遍历Module中的全局变量