Skip to content

Commit

Permalink
fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Gemini321 committed Apr 7, 2024
1 parent 02683d6 commit d0e8ef4
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs/task4_doc/apidoc.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
## 常用API

待补充
54 changes: 45 additions & 9 deletions docs/task4_doc/optimizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

### 数据流优化

数据流优化通过分析程序中数据的传递和使用方式改进程序性能,主要涉及LLVM IR的use-def链的使用。
数据流优化通过分析程序中数据的传递和使用方式改进程序性能,主要涉及LLVM IR的use-def链的使用。use-def链描述LLVM IR中变量定义与使用的关系,若变量`x``y`的计算中被使用,则存在一条use从`y`指向`x`,更复杂的情况以此类推。use-def链能够表示变量之间的依赖关系,在数据流分析中起着至关重要的作用。

#### 常量传播&常量传播

代表测例:`bitset-*.sysu.c``fft-*.sysu.c``if-combine*.sysu.c`

难度:*
难度:★☆☆☆☆

常量传播(Constant Propagation)与常量折叠(Constant Folding)是最常见的常量优化方式,其原理为在编译阶段尽可能减少常量的计算与存储。两者的区别为:

Expand All @@ -35,21 +35,25 @@ int c = 3;

代表测例:

难度:***
难度:★★★☆☆

死代码消除(Dead Code Elimination,DCE)是一种将对全局变量、输出和返回结果无影响(无副作用)的指令删除的优化。对于一个程序而言,满足以上条件的指令我们认为它在进行一些无意义的计算,其计算结果对于外界来说是不可感知的,因此即使删除也不会对程序的结果产生影响。下面是一个简单的例子:

```C++
// 优化前
int main() {
int sum = 0;
int j = 0;
for(int i = 0; i < 10; i ++) sum += i;
...
print(j);
return 0;
}

// 优化后
int main() {
int j = 0;
print(j);
return 0;
}
```
Expand All @@ -62,7 +66,7 @@ int main() {

代表测例:`hoist-*.sysu.c`

难度:**
难度:&#9733;&#9733;&#9734;&#9734;&#9734;

公共子表达式消除(Common Subexpression Elimination,CSE)是一个非常经典的优化算法,如果一个表达式E在计算得到后没有变化,且同时作为多条指令的操作数被使用,那么E能够被称为公共子表达式:

Expand All @@ -74,7 +78,7 @@ int e = a + b + c;
// CSE优化后
int tmp = a + b;
int d = tmp - c;
int e = a + b;
int e = tmp + c;
```

CSE的优化原理是比较简单的,本质上就是复用之前已经计算得到的结果,避免重复计算。根据CSE的原理可以引出两个问题:
Expand All @@ -93,7 +97,7 @@ CSE可以通过简单的搜索实现:对于每一条可能为公共子表达

代表测例:`instruction-combining-*.sysu.c`

难度:***
难度:&#9733;&#9733;&#9733;&#9734;&#9734;

指令合并(Instruction Combining)是一种将多条指令合并成一条指令的优化方式。下面是一个简单的例子:

Expand All @@ -120,19 +124,37 @@ int c = a + 2;

#### 循环展开

代表测例:`bitset*.sysu.c``crypto-*.sysu.c``instruction-combining-*.sysu.c``integer-divide-optimization-*.sysu.c`

难度:待补充

仅介绍循环次数为常数、可完全展开的循环展开

#### 控制流简化

代表测例:所有performance测例

难度:待补充

待补充

### 指令级优化

指令级优化主要包括指令调度、指令选择等内容,将单条或多条指令转化为运行效率更高的指令。

#### mem2reg

代表测例:所有performance测例

难度:待补充

待补充

#### 强度削弱

代表测例:`bitset*.sysu.c``crypto-*.sysu,c`

难度:*
难度:&#9733;&#9734;&#9734;&#9734;&#9734;

强度削弱(Strength Reduction)将一条高计算复杂度的指令,转化为一条或多条低复杂度的指令。强度削弱是一个很简单但非常有效的优化方式,因为这样的优化机会广泛存在于我们编写的程序之中。在算法比赛中我们常常在编程时使用到这些技巧,但编译器使得我们无需为了性能小心翼翼地编程而获得高性能的程序。下面是一些直观的例子:

Expand All @@ -150,7 +172,7 @@ int a = x << 3, b = x & 0b11, c = (x << 1) + x;

代表测例:

难度:*
难度:&#9733;&#9734;&#9734;&#9734;&#9734;

代数恒等式(Algebraic Identities)通过数学规则消除无意义的数学运算,提前将结果算出。例如:

Expand All @@ -168,6 +190,12 @@ int e = x * 0, f = x % 1;

#### 函数内联

代表测例:所有performance测例

难度:&#9733;&#9733;&#9733;&#9733;&#9734;

待补充

### 访存优化

访存优化通过分析程序的访存模式,消除非必要的访存指令,并提升访存行为的局部性。
Expand All @@ -176,7 +204,7 @@ int e = x * 0, f = x % 1;

代表测例:`dead-code-elimination-*.sysu.c`

难度:**
难度:&#9733;&#9733;&#9734;&#9734;&#9734;

死存储消除(Dead Storage Elimination,DSE)与DCE相同,都是将无意义的代码识别并删除,两者本质上是同一种优化算法。不同的是前者主要针对变量初始化、访存指令的消除,而后者主要针对计算指令的消除。对于一个定义了但并未对输出、返回值和全局变量产生影响的变量,其定义、访存指令可以全部删除。

Expand All @@ -202,8 +230,16 @@ int main() {

#### 自动向量化

代表测例:`mm*.sysu.c`

难度:&#9733;&#9733;&#9733;&#9733;&#9733;

包括向量化内存访问与向量化计算。

#### 自动并行

代表测例:`mm*.sysu.c`

难度:&#9733;&#9733;&#9733;&#9733;&#9733;

自动识别可以并行执行的代码块,并将部分代码由串行执行优化为并行执行,充分利用CPU的计算资源。
8 changes: 4 additions & 4 deletions docs/task4_doc/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

## 任务描述

本次实验的实验内容是实现一个LLVM IR优化器,对中间代码生成的结果进行优化。实验的输入与输出均为LLVM IR,要求同学们在保证代码正确性的基础上面向给定测试样例进行代码优化。每个优化由一个优化pass实现,不同pass之间相互独立。在本次实验没有标准答案,同学们可以自由发挥,借助任何可能的优化方法提升程序的运行效率,并通过测评系统测评。
本次实验的实验内容是实现一个LLVM IR优化器,对中间代码生成的结果进行优化。实验的输入与输出均为LLVM IR,要求同学们在保证代码正确性的基础上面向给定测试样例进行代码优化。在LLVM中,中端优化函数以优化pass的形式存在,其作用是对输入的LLVM IR进行分析与变换,并输出变换后的LLVM IR。每个优化由一个或多个优化pass实现,不同优化的pass之间相互独立。在本次实验没有标准答案,同学们可以自由发挥,借助任何可能的优化方法提升程序的运行效率,并通过测评系统测评。

## 评分标准

实验的评分主要分为两个部分:正确性与程序运行性能。对于一个编译器而言,保证正确性是必然要求。中间代码优化实验的比较对象为`clang O2`,对于每个实验测例,我们将比较优化后的程序的输出与返回值:若两者相同,则进入性能测试;若两者不相同,则实验得分为0。
实验的评分主要分为两个部分:正确性与程序运行性能。对于一个编译器而言,保证正确性是必然要求。中间代码优化实验的比较对象为`clang O2`,对于每个实验测例,我们将比较优化后的程序运行的输出与返回值:若两者相同,则进入性能测试;若两者不相同,则实验得分为0。

通过正确性验证后,我们将`clang O2`优化后的程序运行时间与优化器优化后的程序运行时间求比值,再将性能测例中每个测例的分数取平均即为本次实验的总得分。若某测例在优化器优化后运行性能超过`clang O2`,则该测例记为满分。
通过正确性验证后,我们将`clang O2`优化后的程序运行时间与优化器优化后的程序运行时间求比值,再将性能测例中每个测例的分数取平均值,结果即为本次实验的总得分。若某测例在优化器优化后运行性能超过`clang O2`,则该测例记为满分。

本次实验不允许出现以下行为,若出现以下行为将视为作弊与抄袭:

Expand All @@ -21,5 +21,5 @@

* 在理解LLVM优化源代码的基础上将其简化移植
* 使用LLVM提供的**分析pass**获取优化所需的信息(优化pass和分析pass的区别是前者执行后会修改LLVM IR,而后者仅返回信息不改变IR)
* 鼓励同学们添加实验测例中未涉及到的优化并提供相应测例(可在实验报告中说明,我们将在分析优化效果与难度后酌情加分
* 鼓励同学们添加实验测例中未涉及到的优化并提供相应测例(可在实验报告中说明,我们将在分析优化效果与优化实现难度后酌情加分

0 comments on commit d0e8ef4

Please sign in to comment.