121 lines
5.4 KiB
Markdown
121 lines
5.4 KiB
Markdown
这个 `IR.cpp` 文件实现了 `IR.h` 中定义的中间表示(IR)数据结构的功能。它包含了类型系统、值、指令、基本块、函数和模块的具体实现,以及一些辅助函数用于打印 IR 的内容。以下是对文件中主要内容的整理和解释:
|
||
|
||
---
|
||
|
||
### **1. 辅助函数**
|
||
#### **1.1 `interleave` 函数**
|
||
- **作用**:用于在输出流中插入分隔符(如逗号)来打印容器中的元素。
|
||
- **示例**:
|
||
```cpp
|
||
interleave(os, container, ", ");
|
||
```
|
||
|
||
#### **1.2 打印函数**
|
||
- **`printVarName`**:打印变量名,全局变量以 `@` 开头,局部变量以 `%` 开头。
|
||
- **`printBlockName`**:打印基本块名,以 `^` 开头。
|
||
- **`printFunctionName`**:打印函数名,以 `@` 开头。
|
||
- **`printOperand`**:打印操作数,如果是常量则直接打印值,否则打印变量名。
|
||
|
||
---
|
||
|
||
### **2. 类型系统**
|
||
#### **2.1 `Type` 类的实现**
|
||
- **静态方法**:
|
||
- `getIntType()`、`getFloatType()`、`getVoidType()`、`getLabelType()`:返回对应类型的单例对象。
|
||
- `getPointerType(Type *baseType)`:返回指向 `baseType` 的指针类型。
|
||
- `getFunctionType(Type *returnType, const vector<Type *> ¶mTypes)`:返回函数类型。
|
||
- **`getSize()`**:返回类型的大小(如 `int` 和 `float` 为 4 字节,指针为 8 字节)。
|
||
- **`print()`**:打印类型的表示。
|
||
|
||
#### **2.2 `PointerType` 类的实现**
|
||
- **静态方法**:
|
||
- `get(Type *baseType)`:返回指向 `baseType` 的指针类型,使用 `std::map` 缓存已创建的指针类型。
|
||
- **`getBaseType()`**:返回指针指向的基础类型。
|
||
|
||
#### **2.3 `FunctionType` 类的实现**
|
||
- **静态方法**:
|
||
- `get(Type *returnType, const vector<Type *> ¶mTypes)`:返回函数类型,使用 `std::set` 缓存已创建的函数类型。
|
||
- **`getReturnType()`** 和 `getParamTypes()`:分别返回函数的返回类型和参数类型列表。
|
||
|
||
---
|
||
|
||
### **3. 值(Value)**
|
||
#### **3.1 `Value` 类的实现**
|
||
- **`replaceAllUsesWith(Value *value)`**:将该值的所有用途替换为另一个值。
|
||
- **`isConstant()`**:判断值是否为常量(包括常量值、全局值和函数)。
|
||
|
||
#### **3.2 `ConstantValue` 类的实现**
|
||
- **静态方法**:
|
||
- `get(int value)` 和 `get(float value)`:返回整数或浮点数常量,使用 `std::map` 缓存已创建的常量。
|
||
- **`getInt()` 和 `getFloat()`**:返回常量的值。
|
||
- **`print()`**:打印常量的值。
|
||
|
||
#### **3.3 `Argument` 类的实现**
|
||
- **构造函数**:初始化参数的类型、所属基本块和索引。
|
||
- **`print()`**:打印参数的表示。
|
||
|
||
---
|
||
|
||
### **4. 基本块(BasicBlock)**
|
||
#### **4.1 `BasicBlock` 类的实现**
|
||
- **构造函数**:初始化基本块的名称和所属函数。
|
||
- **`print()`**:打印基本块的表示,包括参数和指令。
|
||
|
||
---
|
||
|
||
### **5. 指令(Instruction)**
|
||
#### **5.1 `Instruction` 类的实现**
|
||
- **构造函数**:初始化指令的类型、所属基本块和名称。
|
||
- **`print()`**:由具体指令类实现。
|
||
|
||
#### **5.2 具体指令类的实现**
|
||
- **`CallInst`**:表示函数调用指令。
|
||
- **`print()`**:打印函数调用的表示。
|
||
- **`UnaryInst`**:表示一元操作指令(如取反、类型转换)。
|
||
- **`print()`**:打印一元操作的表示。
|
||
- **`BinaryInst`**:表示二元操作指令(如加法、减法)。
|
||
- **`print()`**:打印二元操作的表示。
|
||
- **`ReturnInst`**:表示返回指令。
|
||
- **`print()`**:打印返回指令的表示。
|
||
- **`UncondBrInst`**:表示无条件跳转指令。
|
||
- **`print()`**:打印无条件跳转的表示。
|
||
- **`CondBrInst`**:表示条件跳转指令。
|
||
- **`print()`**:打印条件跳转的表示。
|
||
- **`AllocaInst`**:表示栈内存分配指令。
|
||
- **`print()`**:打印内存分配的表示。
|
||
- **`LoadInst`**:表示从内存加载值的指令。
|
||
- **`print()`**:打印加载指令的表示。
|
||
- **`StoreInst`**:表示将值存储到内存的指令。
|
||
- **`print()`**:打印存储指令的表示。
|
||
|
||
---
|
||
|
||
### **6. 函数(Function)**
|
||
#### **6.1 `Function` 类的实现**
|
||
- **构造函数**:初始化函数的名称、返回类型和参数类型。
|
||
- **`print()`**:打印函数的表示,包括基本块和指令。
|
||
|
||
---
|
||
|
||
### **7. 模块(Module)**
|
||
#### **7.1 `Module` 类的实现**
|
||
- **`print()`**:打印模块的表示,包括所有函数和全局变量。
|
||
|
||
---
|
||
|
||
### **8. 用户(User)**
|
||
#### **8.1 `User` 类的实现**
|
||
- **`setOperand(int index, Value *value)`**:设置指定索引的操作数。
|
||
- **`replaceOperand(int index, Value *value)`**:替换指定索引的操作数,并更新用途列表。
|
||
|
||
---
|
||
|
||
### **9. 总结**
|
||
- **类型系统**:实现了 `Type`、`PointerType` 和 `FunctionType`,用于表示 IR 中的类型。
|
||
- **值**:实现了 `Value`、`ConstantValue` 和 `Argument`,用于表示 IR 中的值和参数。
|
||
- **基本块**:实现了 `BasicBlock`,用于组织指令。
|
||
- **指令**:实现了多种具体指令类(如 `CallInst`、`BinaryInst` 等),用于表示 IR 中的操作。
|
||
- **函数和模块**:实现了 `Function` 和 `Module`,用于组织 IR 的结构。
|
||
- **打印功能**:通过 `print()` 方法,可以将 IR 的内容输出为可读的文本格式。
|
||
|
||
这个文件是编译器中间表示的核心实现,能够将抽象语法树(AST)转换为中间代码,并支持后续的优化和目标代码生成。 |