From 0eae00a0375421964a6c05c9dfadc738e139ba09 Mon Sep 17 00:00:00 2001 From: tinysnail Date: Sat, 20 Nov 2021 14:03:23 +0800 Subject: [PATCH] doc update --- doc/SysYFIR.md | 129 +++++++++++++++----------------- doc/figs/核心类概念图.png | Bin 0 -> 30475 bytes 2 files changed, 62 insertions(+), 67 deletions(-) create mode 100755 doc/figs/核心类概念图.png diff --git a/doc/SysYFIR.md b/doc/SysYFIR.md index 9d63f6b..df93b1e 100644 --- a/doc/SysYFIR.md +++ b/doc/SysYFIR.md @@ -32,7 +32,7 @@ - [Constant](#constant) - [Function](#function) - [GlobalVariable](#globalvariable) - - [IRBuilder](#irbuilder) + - [IRStmtBuilder](#irstmtbuilder) - [Instruction](#instruction-1) - [Module](#module) - [Type](#type) @@ -43,10 +43,10 @@ ## IR ### IR Features -- 采用 3 地址的方式 +- 采用类型化三地址代码的方式 - 区别于 X86 汇编的目标和源寄存器共用的模式: ADD EAX, EBX - %2 = add i32 %0, %1 -- SSA 形式 + 无限寄存器 +- 静态单赋值 (SSA) 形式 + 无限寄存器 - 每个变量都只被赋值一次 - 容易确定操作间的依赖关系,便于优化分析 - 强类型系统 @@ -61,8 +61,8 @@ - `functiontype`函数类型,包括函数返回值类型与参数类型(下述文档未提及) ### IR Format -以下面的`easy.c`与`easy.ll`为例进行说明。 -通过命令`clang -S -emit-llvm easy.c`可以得到对应的`easy.ll`如下(助教增加了额外的注释)。`.ll`文件中注释以`;`开头。 +下面以`easy.c`与`easy.ll`为例进行说明。 +通过命令`clang -S -emit-llvm easy.c`可以得到对应的`easy.ll`如下(其中增加了额外的注释)。`.ll`文件中注释以`;`开头。 - `easy.c`: ``` c @@ -125,7 +125,7 @@ !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!"clang version 10.0.1 "} ``` -其中,每个program由1个或多个module组成,module之间由LLVM Linker合并。 +每个program由1个或多个module组成,每个module对应1个程序文件,module之间由LLVM Linker进行链接形成1个可执行文件或者库。 每个module组成如下: - Target Information: ``` c @@ -136,9 +136,9 @@ - Others:尾部其他信息 每个函数的组成如下: -- 头部:函数返回值类型,函数名,函数参数 +- 头部:函数返回值类型、函数名、函数参数 - 一个或多个基本块: - - 每个基本块又有Label和Instruction组成。 + - 每个基本块由Label和Instruction组成。 ``` c 8: ; preds = %7, %0 %9 = load i32, i32* %2, align 4 @@ -150,7 +150,7 @@ `%9 = load i32, i32* %2, align 4`中的`%9`是目的操作数,`load`是指令助记符,`i32`是`int32`的类型,`i32*`是指向`int32`的地址类型,`%2`是源操作数,`align 4`表示对齐。 ### Instruction #### Terminator Instructions -**注**:ret与br都是Terminator Instructions也就是终止指令,在llvm基本块的定义里,基本块是单进单出的,因此只能有一条终止指令(ret或br)。当一个基本块有两条终止指令,clang 在做解析会认为第一个终结指令是此基本块的结束,并会开启一个新的匿名的基本块(并占用了下一个编号)。 +**注**:ret与br都是Terminator Instructions也就是终止指令,在llvm基本块的定义里,基本块是单进单出的,因此只能有一条终止指令(ret或br)。当一个基本块有两条终止指令,clang 在做解析时会认为第一个终结指令是此基本块的结束,并会开启一个新的匿名的基本块(并占用了下一个编号)。 ##### Ret - 格式 - `ret ` @@ -201,7 +201,7 @@ - 例子: - `%ptr = alloca i32` - `%ptr = alloca [10 x i32]` -- 概念: `alloca`指令在当前执行函数的堆栈帧上分配内存,当该函数返回其调用者时将自动释放该内存。 始终在地址空间中为数据布局中指示的分配资源分配对象 +- 概念: `alloca`指令在当前执行函数的栈帧上分配内存,当该函数返回其调用者时将自动释放该内存。 始终在地址空间中为数据布局中指示的分配资源分配对象 ##### Load - 格式:` = load , * ` @@ -259,7 +259,7 @@ ### 核心类概念图 -to make +![](figs/核心类概念图.png) ### BasicBlock - 继承:从[value](#value)继承 @@ -275,31 +275,31 @@ to make - API: ```c++ - static BasicBlock *create(Module *m, const std::string &name , Function *parent ) // 创建并返回BB块,参数分别是BB块所属的Module,name是其名字默认为空,BB块所属的Function - Function *get_parent(); + static BasicBlock *create(Module *m, const std::string &name , Function *parent ) // 返回BB块所属的函数 - Module *get_module(); + Function *get_parent(); // 返回BB块所属的Module + Module *get_module(); + // 返回BB块的终止指令(ret|br),若BB块最后一条指令不是终止指令返回null Instruction *get_terminator(); - // 返回BB块的终止指令(ret|br)若BB块最后一条指令不是终止指令返回null - void add_instruction(Instruction *instr); // 将instr指令添加到此BB块指令链表结尾,调用IRBuilder里来创建函数会自动调用此方法 - void add_instr_begin(Instruction *instr); + void add_instruction(Instruction *instr); // 将instr指令添加到此BB块指令链表开头 + void add_instr_begin(Instruction *instr); + // 将instr指令从BB块指令链表中移除,同时调用api维护好instr的操作数的use链表 void delete_instr(Instruction *instr); - // 将instr指令从BB块指令链表中移除,同时调用api维护好instr的操作数的use链表。 + // BB块中指令数为空返回true bool empty(); - // BB块中为空返回true - int get_num_of_instr(); // 返回BB块中指令的数目 - std::list &get_instructions(); + int get_num_of_instr(); //返回BB块的指令链表 - void erase_from_parent(); + std::list &get_instructions(); // 将此BB块从所属函数的bb链表中移除 + void erase_from_parent(); /****************api about cfg****************/ - std::list &get_pre_basic_blocks() // 返回前驱快集合 + std::list &get_pre_basic_blocks() // 返回前驱块集合 std::list &get_succ_basic_blocks() // 返回后继块集合 void add_pre_basic_block(BasicBlock *bb) // 添加前驱块 void add_succ_basic_block(BasicBlock *bb) // 添加后继块 @@ -314,14 +314,14 @@ to make - 继承:从[User](#user)继承 - 含义:常数,各种类型常量的基类 - 子类: - - ConstantInt: + - ConstantInt - 含义:int类型的常数 - - 成员: + - 成员 - val_:常数值 - - API: + - API ```cpp int get_value() // 返回该常数类型中存的常数值 @@ -330,25 +330,25 @@ to make static ConstantInt *get(bool val, Module *m) // 以val值来创建bool常数类 ``` - - ConstantFP: + - ConstantFP - 含义:float类型的常数 - - 成员: + - 成员 - val_:常数值 - - API: + - API ```cpp static ConstantFP *get(float val, Module *m) // 以val值创建并返回浮点数常量类 float get_value() // 返回该常数类型中存的常数值 ``` - - ConstantZero: + - ConstantZero - 含义:用于全局变量初始化的常量0值。 - - API: + - API ```cpp static ConstantZero *get(Type *ty, Module *m);// 创建并返回ConstantZero常量类 @@ -357,7 +357,7 @@ to make - ConstantArray - 含义:数组类型的常数 - - 成员: + - 成员 - const_array_:数组常量值 - API:cminus语法不需要数组常量的支持(本次实验不需要用到),在此不过多解释。感兴趣可以自行查看源代码。 @@ -366,16 +366,16 @@ to make - 含义:函数,该类描述 LLVM 的一个简单过程,维护基本块表,格式化参数表 -- 成员: +- 成员 - basic_blocks_:基本块列表 - arguments_:形参列表 - parent_:函数属于的module -- API: +- API ```cpp static Function *create(FunctionType *ty, const std::string &name, Module *parent); - // 创建并返回Function,参数依次是待创建函数类型ty,函数名字name(不可为空),函数所属的Module + // 创建并返回Function,参数依次是待创建函数类型ty、函数名字name(不可为空)、函数所属的Module FunctionType *get_function_type() const; // 返回此函数类的函数类型 Type *get_return_type() const; @@ -404,11 +404,11 @@ to make -- 相关类: - - Argument: +- 相关类 + - Argument - 含义:参数 - - 成员: + - 成员 - arg_no_:参数序号 - parent_:参数属于哪个函数 @@ -425,40 +425,40 @@ to make - is_const:是否为常量 - init_val_:初始值 - API:由于cminusf语义要求所有的全局变量都默认初始化为0,故`GlobalVariable`中成员和API再构造CminusFBuilder用不到 -### IRBuilder +### IRStmtBuilder - 含义:生成IR的辅助类,该类提供了独立的接口创建各种 IR 指令,并将它们插入基本块中, 该辅助类不做任何类型检查。 -- API: +- API ```cpp BasicBlock *get_insert_block()// 返回正在插入指令的BB void set_insert_point(BasicBlock *bb)// 设置当前需要插入指令的bb - Instruction *create_[instr_type]()// 创建instr_type(具体名字参考IRBuilder.h代码)的指令并对应插入到正在插入的BB块,这种类型的指令看函数名字和参数名字和IR文档是一一对应的。 + XXXInst *create_[instr_type]()// 创建instr_type(具体名字参考IRStmtBuilder.h代码)的指令并对应插入到正在插入的BB块,这种类型的指令看函数名字和参数名字和IR文档是一一对应的。 ``` ### Instruction - 继承:从[User](#user)继承 - 含义:指令,该类是所有 LLVM 指令的基类,主要维护指令的操作码(指令类别),指令所属的基本块,指令的操作数个数信息 -- 成员: +- 成员 - parent_:指令所属的BasicBlock - op_id_:指令的类型id - num_ops_指令的操作数个数 -- 子类: +- 子类 - BinaryInst:双目运算指令包括add、sub、mul、div - 其他子类和前述文档中提到的指令一一对应,不在此赘述。 -- API:所有指令的创建都要通过IRBuilder进行,不需要关注Instruction类的实现细节,(**注**:不通过IRBuilder来创建指令,而直接调用指令子类的创建方法未经助教完善的测试) +- API:所有指令的创建都要通过 IRStmtBuilder 进行,不需要关注Instruction类的实现细节,(**注**:不通过 IRStmtBuilder 来创建指令,而直接调用指令子类的创建方法未经助教完善的测试) ### Module - 含义:一个编译单元,在此源语言的意义下是一个文件 -- 成员: +- 成员 - function_list_:函数链表,记录了这个编译单元的所有函数 - global_list_:全局变量链表 - instr_id2string_:通过指令类型id得到其打印的string - module_name_, source_file_name:未使用 - 从module中能取到的基本类型 -- API: +- API ```cpp Type *get_void_type(); @@ -479,19 +479,19 @@ to make ### Type - 含义:IR的类型,该类是所有类型的超类 -- 成员: +- 成员 - tid_:枚举类型,表示type的类型(包含VoidType、LabelType、FloatType、Int1、Int32、ArrayType、PointerType) -- 子类: +- 子类 - IntegerType - 含义:int 类型 - - 成员: + - 成员 - num_bits:长度(i1或者i32) - - API: + - API ```cpp unsigned get_num_bits();// 返回int的位数 @@ -502,11 +502,11 @@ to make - FunctionType - 含义:函数类型 - - 成员: + - 成员 - result_:返回值类型 - args_:参数类型列表 - - API: + - API ```cpp static FunctionType *get(Type *result, std::vector params); @@ -525,11 +525,11 @@ to make - ArrayType - 含义:数组类型 - - 成员: + - 成员 - contained_:数组成员的类型 - num_elements_:数组维数 - - API: + - API ```cpp static ArrayType *get(Type *contained, unsigned num_elements) @@ -542,11 +542,11 @@ to make - PointerType - 含义:指针类型 - - 成员: + - 成员 - contained_:指针指向的类型 - - API: + - API ```cpp Type *get_element_type() const { return contained_; } @@ -557,7 +557,7 @@ to make // 对于pointertype而言返回指针指向的类型,其他则返回nullptr ``` -- API: +- API ```cpp bool is_void_type()// 判断是否是void类型其他类型有类似API请查看Type.h @@ -572,11 +572,11 @@ to make - 含义:使用者,提供一个操作数表,表中每个操作数都直接指向一个 Value, 提供了 use-def 信息,它本身是 Value 的子类, Value 类会维护一个该数据使用者的列表,提供def-use信息。简单来说操作数表表示我用了谁,该数据使用者列表表示谁用了我。这两个表在后续的**优化实验**会比较重要请务必理解。 -- 成员: +- 成员 - operands_:参数列表,表示这个使用者所用到的参数 - num_ops_:表示该使用者使用的参数的个数 -- API: +- API ```cpp Value *get_operand(unsigned i) const; @@ -593,18 +593,15 @@ to make // 移除操作数链表中索引为index1-index2的操作数,例如想删除第0个操作数:remove_operands(0,0) ``` - - - ### Value - 含义:最基础的类,代表一个操作数,代表一个可能用于指令操作数的带类型数据 -- 成员: +- 成员 - use_list_:记录了所有使用该操作数的指令的列表 - name_:名字 - type_:类型,一个type类,表示操作数的类型 -- API: +- API ```cpp Type *get_type() const //返回这个操作数的类型 @@ -617,8 +614,6 @@ to make // 将val从this的use_list_中移除 ``` - - ### 总结 -助教在接口文档里筛选了可能会需要用到的接口,如果对API有问题的请移步issue讨论,本次`SysYF IR`接口由助教自行设计实现,并做了大量测试,如有对助教的实现方法有异议或者建议的也请移步issue讨论,**请不要直接修改助教的代码,若因修改助教代码造成后续实验仓库合并的冲突请自行解决**。 \ No newline at end of file +在本文档里提供了为SysYF语言程序生成LLVM IR可能需要用到的SysYF IR应用编程接口,如果对这些API有问题的请移步issue讨论,本次`SysYF IR`应用编程接口由助教自行设计实现,并做了大量测试,如有对助教的实现方法有异议或者建议的也请移步issue讨论,**请不要直接修改助教的代码,若因修改助教代码造成后续实验仓库合并的冲突请自行解决**。 diff --git a/doc/figs/核心类概念图.png b/doc/figs/核心类概念图.png new file mode 100755 index 0000000000000000000000000000000000000000..be5dec78f890ed76b8a27a6a6efe6ebd26783105 GIT binary patch literal 30475 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 literal 0 HcmV?d00001