Skip to content

实验四代码优化

aySun edited this page Apr 20, 2023 · 3 revisions

SYsU-lang:sysu-optimizer实验指导

在实验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。

其实可以参考样例代码中是如何编写Pass的

API介绍

BasicBlock相关

BasicBlock相关的API具体可以看"llvm/IR/BasicBlock.h"

  • getTerminator():获得基本块的终止指令

Instruction相关

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中的全局变量