Compare commits
16 Commits
array_add
...
AnalysisPa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac7644f450 | ||
|
|
3dbb394bc2 | ||
|
|
d50f76a770 | ||
|
|
73dd8eba22 | ||
|
|
10b43fc90d | ||
|
|
3d233ff199 | ||
|
|
568e9af626 | ||
|
|
63fc92dcbd | ||
|
|
29f75e60a5 | ||
|
|
9d8930f5df | ||
|
|
3da2f3ec80 | ||
|
|
496e2abfb6 | ||
|
|
4711fb603b | ||
|
|
dda8bbe444 | ||
|
|
25a8c72a9b | ||
|
|
232ed6d023 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -50,3 +50,5 @@ GTAGS
|
|||||||
__init__.py
|
__init__.py
|
||||||
|
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
|
.DS_*
|
||||||
17
TODO.md
17
TODO.md
@@ -3,20 +3,27 @@
|
|||||||
### 1. **前端必须模块**
|
### 1. **前端必须模块**
|
||||||
- **词法/语法分析**(已完成):
|
- **词法/语法分析**(已完成):
|
||||||
- `SysYLexer`/`SysYParser`:ANTLR生成的解析器
|
- `SysYLexer`/`SysYParser`:ANTLR生成的解析器
|
||||||
- **IR生成核心**:
|
- **IR生成核心**:(已完成)
|
||||||
- `SysYIRGenerator`:将AST转换为中间表示(IR)
|
- `SysYIRGenerator`:将AST转换为中间表示(IR)
|
||||||
- `IRBuilder`:构建指令和基本块的工具类(你们正在实现的部分)
|
- `IRBuilder`:构建指令和基本块的工具类(你们正在实现的部分)
|
||||||
|
- **IR打印器**:(基本完成)
|
||||||
|
- `SysYIRPrinter`: 打印llvm ir格式的指令,优化遍后查看优化效果,la指令,subarray数组翻译范式需要改进
|
||||||
|
|
||||||
### 2. **中端必要优化(最小集合)**
|
### 2. **中端必要优化(最小集合)**
|
||||||
|
- **CFG优化**:(待测试)
|
||||||
|
- `SysYIROptPre`:CFG优化顺便解决IR生成的缺陷(void自动添加ret指令,合并嵌套if/while语句生成的多个exit(后续可以实现回填机制))
|
||||||
|
|
||||||
常量传播
|
常量传播
|
||||||
| 优化阶段 | 关键作用 | 是否必须 |
|
| 优化阶段 | 关键作用 | 是否必须 |
|
||||||
|-------------------|----------------------------------|----------|
|
|-------------------|----------------------------------|----------|
|
||||||
| `Mem2Reg` | 消除冗余内存访问,转换为SSA形式 | ✅ 核心 |
|
| `Mem2Reg` | 消除冗余内存访问,转换为SSA形式 | ✅ 核心 |(必须)
|
||||||
| `DCE` (死代码消除) | 移除无用指令 | ✅ 必要 |
|
| `DCE` (死代码消除) | 移除无用指令 | ✅ 必要 |(必须)
|
||||||
| `DFE` (死函数消除) | 移除未使用的函数 | ✅ 必要 |
|
| `DFE` (死函数消除) | 移除未使用的函数 | ✅ 必要 |(必须)
|
||||||
| `FuncAnalysis` | 函数调用关系分析 | ✅ 基础 |
|
|
||||||
| `Global2Local` | 全局变量降级为局部变量 | ✅ 重要 |
|
| `Global2Local` | 全局变量降级为局部变量 | ✅ 重要 |
|
||||||
|
|
||||||
|
还需要做 Reg2Mem
|
||||||
|
|
||||||
|
|
||||||
### 3. **后端核心流程(必须实现)**
|
### 3. **后端核心流程(必须实现)**
|
||||||
```mermaid
|
```mermaid
|
||||||
graph LR
|
graph LR
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ add_executable(sysyc
|
|||||||
IR.cpp
|
IR.cpp
|
||||||
SysYIRGenerator.cpp
|
SysYIRGenerator.cpp
|
||||||
# Backend.cpp
|
# Backend.cpp
|
||||||
# LLVMIRGenerator.cpp
|
SysYIRPrinter.cpp
|
||||||
# LLVMIRGenerator_1.cpp
|
SysYIROptPre.cpp
|
||||||
|
RISCv32Backend.cpp
|
||||||
)
|
)
|
||||||
target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
target_compile_options(sysyc PRIVATE -frtti)
|
target_compile_options(sysyc PRIVATE -frtti)
|
||||||
|
|||||||
40
src/IR.cpp
40
src/IR.cpp
@@ -598,11 +598,11 @@ auto SymbolTable::addVariable(const std::string &name, User *variable) -> User *
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
auto iter = variableIndex.find(name);
|
auto iter = variableIndex.find(name);
|
||||||
if (iter != variableIndex.end()) {
|
if (iter != variableIndex.end()) {
|
||||||
ss << name << "(" << iter->second << ")";
|
ss << name << iter->second ;
|
||||||
iter->second += 1;
|
iter->second += 1;
|
||||||
} else {
|
} else {
|
||||||
variableIndex.emplace(name, 1);
|
variableIndex.emplace(name, 1);
|
||||||
ss << name << "(" << 0 << ")";
|
ss << name << 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
variable->setName(ss.str());
|
variable->setName(ss.str());
|
||||||
@@ -665,42 +665,6 @@ void SymbolTable::leaveScope() { curNode = curNode->pNode; }
|
|||||||
*/
|
*/
|
||||||
auto SymbolTable::isInGlobalScope() const -> bool { return curNode->pNode == nullptr; }
|
auto SymbolTable::isInGlobalScope() const -> bool { return curNode->pNode == nullptr; }
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 判断是否为循环不变量
|
|
||||||
* @param value: 要判断的value
|
|
||||||
* @return true: 是不变量
|
|
||||||
* @return false: 不是
|
|
||||||
*/
|
|
||||||
auto Loop::isSimpleLoopInvariant(Value *value) -> bool {
|
|
||||||
// auto constValue = dynamic_cast<ConstantValue *>(value);
|
|
||||||
// if (constValue != nullptr) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
if (auto instr = dynamic_cast<Instruction *>(value)) {
|
|
||||||
if (instr->isLoad()) {
|
|
||||||
auto loadinst = dynamic_cast<LoadInst *>(instr);
|
|
||||||
|
|
||||||
auto loadvalue = dynamic_cast<AllocaInst *>(loadinst->getOperand(0));
|
|
||||||
if (loadvalue != nullptr) {
|
|
||||||
if (loadvalue->getParent() != nullptr) {
|
|
||||||
auto basicblock = loadvalue->getParent();
|
|
||||||
return !this->isLoopContainsBasicBlock(basicblock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto globalvalue = dynamic_cast<GlobalValue *>(loadinst->getOperand(0));
|
|
||||||
if (globalvalue != nullptr) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
auto basicblock = instr->getParent();
|
|
||||||
|
|
||||||
return !this->isLoopContainsBasicBlock(basicblock);
|
|
||||||
}
|
|
||||||
auto basicblock = instr->getParent();
|
|
||||||
return !this->isLoopContainsBasicBlock(basicblock);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 移动指令
|
* @brief 移动指令
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ std::any LLVMIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) {
|
|||||||
|
|
||||||
if (varDef->ASSIGN()) {
|
if (varDef->ASSIGN()) {
|
||||||
value = std::any_cast<std::string>(varDef->initVal()->accept(this));
|
value = std::any_cast<std::string>(varDef->initVal()->accept(this));
|
||||||
if (irTmpTable.find(value) != irTmpTable.end() && sysy::isa<sysy::ConstantValue>(irTmpTable[value])) {
|
if (irTmpTable.find(value) != irTmpTable.end() && isa<sysy::ConstantValue>(irTmpTable[value])) {
|
||||||
initValue = irTmpTable[value];
|
initValue = irTmpTable[value];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ std::any LLVMIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
|
value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
|
||||||
if (sysy::isa<sysy::ConstantValue>(irTmpTable[value])) {
|
if (isa<sysy::ConstantValue>(irTmpTable[value])) {
|
||||||
initValue = irTmpTable[value];
|
initValue = irTmpTable[value];
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -310,7 +310,7 @@ std::any LLVMIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx) {
|
|||||||
} else {
|
} else {
|
||||||
irStream << " ret " << currentReturnType << " 0\n";
|
irStream << " ret " << currentReturnType << " 0\n";
|
||||||
sysy::IRBuilder builder(currentIRBlock);
|
sysy::IRBuilder builder(currentIRBlock);
|
||||||
builder.createReturnInst(sysy::ConstantValue::get(getIRType("int"),0));
|
builder.createReturnInst(sysy::ConstantValue::get(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
irStream << "}\n";
|
irStream << "}\n";
|
||||||
@@ -524,10 +524,10 @@ std::any LLVMIRGenerator::visitNumber(SysYParser::NumberContext* ctx) {
|
|||||||
sysy::Value* irValue = nullptr;
|
sysy::Value* irValue = nullptr;
|
||||||
if (ctx->ILITERAL()) {
|
if (ctx->ILITERAL()) {
|
||||||
value = ctx->ILITERAL()->getText();
|
value = ctx->ILITERAL()->getText();
|
||||||
irValue = sysy::ConstantValue::get(getIRType("int"), std::stoi(value));
|
irValue = sysy::ConstantValue::get(std::stoi(value));
|
||||||
} else if (ctx->FLITERAL()) {
|
} else if (ctx->FLITERAL()) {
|
||||||
value = ctx->FLITERAL()->getText();
|
value = ctx->FLITERAL()->getText();
|
||||||
irValue = sysy::ConstantValue::get(getIRType("float"), std::stof(value));
|
irValue = sysy::ConstantValue::get(std::stof(value));
|
||||||
} else {
|
} else {
|
||||||
value = "";
|
value = "";
|
||||||
}
|
}
|
||||||
|
|||||||
0
src/Mem2Reg.cpp
Normal file
0
src/Mem2Reg.cpp
Normal file
157
src/RISCv32Backend.cpp
Normal file
157
src/RISCv32Backend.cpp
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#include "RISCv32Backend.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
const std::vector<RISCv32CodeGen::PhysicalReg> RISCv32CodeGen::allocable_regs = {
|
||||||
|
PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3,
|
||||||
|
PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6,
|
||||||
|
PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3,
|
||||||
|
PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string RISCv32CodeGen::reg_to_string(PhysicalReg reg) {
|
||||||
|
switch (reg) {
|
||||||
|
case PhysicalReg::T0: return "t0"; case PhysicalReg::T1: return "t1";
|
||||||
|
case PhysicalReg::T2: return "t2"; case PhysicalReg::T3: return "t3";
|
||||||
|
case PhysicalReg::T4: return "t4"; case PhysicalReg::T5: return "t5";
|
||||||
|
case PhysicalReg::T6: return "t6"; case PhysicalReg::A0: return "a0";
|
||||||
|
case PhysicalReg::A1: return "a1"; case PhysicalReg::A2: return "a2";
|
||||||
|
case PhysicalReg::A3: return "a3"; case PhysicalReg::A4: return "a4";
|
||||||
|
case PhysicalReg::A5: return "a5"; case PhysicalReg::A6: return "a6";
|
||||||
|
case PhysicalReg::A7: return "a7";
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RISCv32CodeGen::code_gen() {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << ".text\n";
|
||||||
|
ss << module_gen();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RISCv32CodeGen::module_gen() {
|
||||||
|
std::stringstream ss;
|
||||||
|
// 生成全局变量(数据段)
|
||||||
|
for (const auto& global : module->getGlobals()) {
|
||||||
|
ss << ".data\n";
|
||||||
|
ss << ".globl " << global->getName() << "\n";
|
||||||
|
ss << global->getName() << ":\n";
|
||||||
|
ss << " .word 0\n"; // 假设初始化为0
|
||||||
|
}
|
||||||
|
// 生成函数(文本段)
|
||||||
|
ss << ".text\n";
|
||||||
|
for (const auto& func : module->getFunctions()) {
|
||||||
|
ss << function_gen(func.second.get());
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RISCv32CodeGen::function_gen(Function* func) {
|
||||||
|
std::stringstream ss;
|
||||||
|
// 函数标签
|
||||||
|
ss << ".globl " << func->getName() << "\n";
|
||||||
|
ss << func->getName() << ":\n";
|
||||||
|
// 序言:保存 ra,分配堆栈
|
||||||
|
bool is_leaf = true; // 简化假设
|
||||||
|
ss << " addi sp, sp, -16\n";
|
||||||
|
ss << " sw ra, 12(sp)\n";
|
||||||
|
// 寄存器分配
|
||||||
|
auto alloc = register_allocation(func);
|
||||||
|
// 生成基本块代码
|
||||||
|
for (const auto& bb : func->getBasicBlocks()) {
|
||||||
|
ss << basicBlock_gen(bb.get(), alloc);
|
||||||
|
}
|
||||||
|
// 结尾:恢复 ra,释放堆栈
|
||||||
|
ss << " lw ra, 12(sp)\n";
|
||||||
|
ss << " addi sp, sp, 16\n";
|
||||||
|
ss << " ret\n";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << bb->getName() << ":\n";
|
||||||
|
for (const auto& inst : bb->getInstructions()) {
|
||||||
|
auto riscv_insts = instruction_gen(inst.get());
|
||||||
|
for (const auto& riscv_inst : riscv_insts) {
|
||||||
|
ss << " " << riscv_inst.opcode;
|
||||||
|
for (size_t i = 0; i < riscv_inst.operands.size(); ++i) {
|
||||||
|
if (i > 0) ss << ", ";
|
||||||
|
if (riscv_inst.operands[i].kind == Operand::Kind::Reg) {
|
||||||
|
auto it = alloc.reg_map.find(riscv_inst.operands[i].value);
|
||||||
|
if (it != alloc.reg_map.end()) {
|
||||||
|
ss << reg_to_string(it->second);
|
||||||
|
} else {
|
||||||
|
auto stack_it = alloc.stack_map.find(riscv_inst.operands[i].value);
|
||||||
|
if (stack_it != alloc.stack_map.end()) {
|
||||||
|
ss << stack_it->second << "(sp)";
|
||||||
|
} else {
|
||||||
|
ss << "%" << riscv_inst.operands[i].value->getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (riscv_inst.operands[i].kind == Operand::Kind::Imm) {
|
||||||
|
ss << riscv_inst.operands[i].label;
|
||||||
|
} else {
|
||||||
|
ss << riscv_inst.operands[i].label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RISCv32CodeGen::RISCv32Inst> RISCv32CodeGen::instruction_gen(Instruction* inst) {
|
||||||
|
std::vector<RISCv32Inst> insts;
|
||||||
|
if (auto bin = dynamic_cast<BinaryInst*>(inst)) {
|
||||||
|
std::string opcode;
|
||||||
|
if (bin->getKind() == BinaryInst::kAdd) opcode = "add";
|
||||||
|
else if (bin->getKind() == BinaryInst::kSub) opcode = "sub";
|
||||||
|
else if (bin->getKind() == BinaryInst::kMul) opcode = "mul";
|
||||||
|
else return insts; // 其他操作未实现
|
||||||
|
insts.emplace_back(opcode, std::vector<Operand>{
|
||||||
|
{Operand::Kind::Reg, bin},
|
||||||
|
{Operand::Kind::Reg, bin->getLhs()},
|
||||||
|
{Operand::Kind::Reg, bin->getRhs()}
|
||||||
|
});
|
||||||
|
} else if (auto load = dynamic_cast<LoadInst*>(inst)) {
|
||||||
|
insts.emplace_back("lw", std::vector<Operand>{
|
||||||
|
{Operand::Kind::Reg, load},
|
||||||
|
{Operand::Kind::Label, load->getPointer()->getName()}
|
||||||
|
});
|
||||||
|
} else if (auto store = dynamic_cast<StoreInst*>(inst)) {
|
||||||
|
insts.emplace_back("sw", std::vector<Operand>{
|
||||||
|
{Operand::Kind::Reg, store->getValue()},
|
||||||
|
{Operand::Kind::Label, store->getPointer()->getName()}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return insts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RISCv32CodeGen::eliminate_phi(Function* func) {
|
||||||
|
// TODO: 实现 phi 指令消除
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<Instruction*, std::set<Value*>> RISCv32CodeGen::liveness_analysis(Function* func) {
|
||||||
|
std::map<Instruction*, std::set<Value*>> live_sets;
|
||||||
|
// TODO: 实现活跃性分析
|
||||||
|
return live_sets;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<Value*, std::set<Value*>> RISCv32CodeGen::build_interference_graph(
|
||||||
|
const std::map<Instruction*, std::set<Value*>>& live_sets) {
|
||||||
|
std::map<Value*, std::set<Value*>> graph;
|
||||||
|
// TODO: 实现干扰图构建
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) {
|
||||||
|
RegAllocResult result;
|
||||||
|
// TODO: 实现寄存器分配
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
67
src/RISCv32Backend.h
Normal file
67
src/RISCv32Backend.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#ifndef RISCV32_BACKEND_H
|
||||||
|
#define RISCV32_BACKEND_H
|
||||||
|
|
||||||
|
#include "IR.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
class RISCv32CodeGen {
|
||||||
|
public:
|
||||||
|
explicit RISCv32CodeGen(Module* mod) : module(mod) {}
|
||||||
|
std::string code_gen(); // 生成模块的汇编代码
|
||||||
|
|
||||||
|
private:
|
||||||
|
Module* module;
|
||||||
|
|
||||||
|
// 物理寄存器
|
||||||
|
enum class PhysicalReg {
|
||||||
|
T0, T1, T2, T3, T4, T5, T6, // x5-x7, x28-x31
|
||||||
|
A0, A1, A2, A3, A4, A5, A6, A7 // x10-x17
|
||||||
|
};
|
||||||
|
static const std::vector<PhysicalReg> allocable_regs;
|
||||||
|
|
||||||
|
// 操作数
|
||||||
|
struct Operand {
|
||||||
|
enum class Kind { Reg, Imm, Label };
|
||||||
|
Kind kind;
|
||||||
|
Value* value; // 用于寄存器
|
||||||
|
std::string label; // 用于标签或立即数
|
||||||
|
Operand(Kind k, Value* v) : kind(k), value(v), label("") {}
|
||||||
|
Operand(Kind k, const std::string& l) : kind(k), value(nullptr), label(l) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// RISC-V 指令
|
||||||
|
struct RISCv32Inst {
|
||||||
|
std::string opcode;
|
||||||
|
std::vector<Operand> operands;
|
||||||
|
RISCv32Inst(const std::string& op, const std::vector<Operand>& ops)
|
||||||
|
: opcode(op), operands(ops) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 寄存器分配结果
|
||||||
|
struct RegAllocResult {
|
||||||
|
std::map<Value*, PhysicalReg> reg_map; // 虚拟寄存器到物理寄存器的映射
|
||||||
|
std::map<Value*, int> stack_map; // 虚拟寄存器到堆栈槽的映射
|
||||||
|
int stack_size; // 堆栈帧大小
|
||||||
|
};
|
||||||
|
|
||||||
|
// 后端方法
|
||||||
|
std::string module_gen();
|
||||||
|
std::string function_gen(Function* func);
|
||||||
|
std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc);
|
||||||
|
std::vector<RISCv32Inst> instruction_gen(Instruction* inst);
|
||||||
|
RegAllocResult register_allocation(Function* func);
|
||||||
|
void eliminate_phi(Function* func);
|
||||||
|
std::map<Instruction*, std::set<Value*>> liveness_analysis(Function* func);
|
||||||
|
std::map<Value*, std::set<Value*>> build_interference_graph(
|
||||||
|
const std::map<Instruction*, std::set<Value*>>& live_sets);
|
||||||
|
std::string reg_to_string(PhysicalReg reg);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
|
|
||||||
|
#endif // RISCV32_BACKEND_H
|
||||||
@@ -0,0 +1,520 @@
|
|||||||
|
#include "SysYIRAnalyser.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
|
||||||
|
void ControlFlowAnalysis::init() {
|
||||||
|
// 初始化分析器
|
||||||
|
auto &functions = pModule->getFunctions();
|
||||||
|
for (const auto &function : functions) {
|
||||||
|
auto func = function.second.get();
|
||||||
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
|
for (auto &basicBlock : basicBlocks) {
|
||||||
|
blockAnalysisInfo[basicBlock.get()] = new BlockAnalysisInfo();
|
||||||
|
blockAnalysisInfo[basicBlock.get()]->clear();
|
||||||
|
}
|
||||||
|
functionAnalysisInfo[func] = new FunctionAnalysisInfo();
|
||||||
|
functionAnalysisInfo[func]->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControlFlowAnalysis::runControlFlowAnalysis() {
|
||||||
|
// 运行控制流分析
|
||||||
|
clear(); // 清空之前的分析结果
|
||||||
|
init(); // 初始化分析器
|
||||||
|
computeDomNode();
|
||||||
|
computeDomTree();
|
||||||
|
computeDomFrontierAllBlk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControlFlowAnalysis::intersectOP4Dom(std::unordered_set<BasicBlock *> &dom, const std::unordered_set<BasicBlock *> &other) {
|
||||||
|
// 计算交集
|
||||||
|
for (auto it = dom.begin(); it != dom.end();) {
|
||||||
|
if (other.find(*it) == other.end()) {
|
||||||
|
// 如果other中没有这个基本块,则从dom中删除
|
||||||
|
it = dom.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ControlFlowAnalysis::findCommonDominator(BasicBlock *a, BasicBlock *b) -> BasicBlock * {
|
||||||
|
// 查找两个基本块的共同支配结点
|
||||||
|
while (a != b) {
|
||||||
|
BlockAnalysisInfo* infoA = blockAnalysisInfo[a];
|
||||||
|
BlockAnalysisInfo* infoB = blockAnalysisInfo[b];
|
||||||
|
// 如果深度不同,则向上移动到直接支配结点
|
||||||
|
// TODO:空间换时间倍增优化,优先级较低
|
||||||
|
while (infoA->getDomDepth() > infoB->getDomDepth()) a = const_cast<BasicBlock*>(infoA->getIdom());
|
||||||
|
while (infoB->getDomDepth() > infoA->getDomDepth()) b = const_cast<BasicBlock*>(infoB->getIdom());
|
||||||
|
if (a == b) break;
|
||||||
|
a = const_cast<BasicBlock*>(infoA->getIdom());
|
||||||
|
b = const_cast<BasicBlock*>(infoB->getIdom());
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControlFlowAnalysis::computeDomNode(){
|
||||||
|
auto &functions = pModule->getFunctions();
|
||||||
|
// 分析每个函数内的基本块
|
||||||
|
for (const auto &function : functions) {
|
||||||
|
auto func = function.second.get();
|
||||||
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
|
std::unordered_set<BasicBlock *> domSetTmp;
|
||||||
|
// 一开始把domSetTmp置为所有block
|
||||||
|
auto entry_block = func->getEntryBlock();
|
||||||
|
entry_block->setName("Entry");
|
||||||
|
blockAnalysisInfo[entry_block]->addDominants(entry_block);
|
||||||
|
for (auto &basicBlock : basicBlocks) {
|
||||||
|
domSetTmp.emplace(basicBlock.get());
|
||||||
|
}
|
||||||
|
// 初始化
|
||||||
|
for (auto &basicBlock : basicBlocks) {
|
||||||
|
if (basicBlock.get() != entry_block) {
|
||||||
|
blockAnalysisInfo[basicBlock.get()]->setDominants(domSetTmp);
|
||||||
|
// 先把所有block的必经结点都设为N
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支配节点计算公式
|
||||||
|
//DOM[B]={B}∪ {⋂P∈pred(B) DOM[P]}
|
||||||
|
// 其中pred(B)是B的所有前驱结点
|
||||||
|
// 迭代计算支配结点,直到不再变化
|
||||||
|
// 这里使用迭代法,直到支配结点不再变化
|
||||||
|
// TODO:Lengauer-Tarjan 算法可以更高效地计算支配结点
|
||||||
|
// 或者按照CFG拓扑序遍历效率更高
|
||||||
|
bool changed = true;
|
||||||
|
while (changed) {
|
||||||
|
changed = false;
|
||||||
|
// 循环非start结点
|
||||||
|
for (auto &basicBlock : basicBlocks) {
|
||||||
|
if (basicBlock.get() != entry_block) {
|
||||||
|
auto olddom =
|
||||||
|
blockAnalysisInfo[basicBlock.get()]->getDominants();
|
||||||
|
|
||||||
|
std::unordered_set<BasicBlock *> dom =
|
||||||
|
blockAnalysisInfo[basicBlock->getPredecessors().front()]->getDominants();
|
||||||
|
|
||||||
|
// 对于每个基本块,计算其支配结点
|
||||||
|
// 取其前驱结点的支配结点的交集和自己
|
||||||
|
for (auto pred : basicBlock->getPredecessors()) {
|
||||||
|
intersectOP4Dom(dom, blockAnalysisInfo[pred]->getDominants());
|
||||||
|
}
|
||||||
|
dom.emplace(basicBlock.get());
|
||||||
|
blockAnalysisInfo[basicBlock.get()]->setDominants(dom);
|
||||||
|
|
||||||
|
if (dom != olddom) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControlFlowAnalysis::computeDomTree() {
|
||||||
|
// 构造支配树
|
||||||
|
auto &functions = pModule->getFunctions();
|
||||||
|
for (const auto &function : functions) {
|
||||||
|
auto func = function.second.get();
|
||||||
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
|
auto entry_block = func->getEntryBlock();
|
||||||
|
|
||||||
|
blockAnalysisInfo[entry_block]->setIdom(entry_block);
|
||||||
|
blockAnalysisInfo[entry_block]->setDomDepth(0); // 入口块深度为0
|
||||||
|
|
||||||
|
bool changed = true;
|
||||||
|
while (changed) {
|
||||||
|
changed = false;
|
||||||
|
|
||||||
|
for (auto &basicBlock : basicBlocks) {
|
||||||
|
if (basicBlock.get() == entry_block) continue;
|
||||||
|
|
||||||
|
BasicBlock *new_idom = nullptr;
|
||||||
|
for (auto pred : basicBlock->getPredecessors()) {
|
||||||
|
// 跳过未处理的前驱
|
||||||
|
if (blockAnalysisInfo[pred]->getIdom() == nullptr) continue;
|
||||||
|
new_idom = (new_idom == nullptr) ? pred : findCommonDominator(new_idom, pred);
|
||||||
|
// if (new_idom == nullptr)
|
||||||
|
// new_idom = pred;
|
||||||
|
// else
|
||||||
|
// new_idom = findCommonDominator(new_idom, pred);
|
||||||
|
}
|
||||||
|
// 更新直接支配节点
|
||||||
|
if (new_idom && new_idom != blockAnalysisInfo[basicBlock.get()]->getIdom()) {
|
||||||
|
// 移除旧的支配关系
|
||||||
|
if (blockAnalysisInfo[basicBlock.get()]->getIdom()) {
|
||||||
|
blockAnalysisInfo[const_cast<BasicBlock*>(blockAnalysisInfo[basicBlock.get()]->getIdom())]->removeSdoms(basicBlock.get());
|
||||||
|
}
|
||||||
|
// 设置新的支配关系
|
||||||
|
blockAnalysisInfo[basicBlock.get()]->setIdom(new_idom);
|
||||||
|
blockAnalysisInfo[new_idom]->addSdoms(basicBlock.get());
|
||||||
|
// 更新深度 = 直接支配节点深度 + 1
|
||||||
|
blockAnalysisInfo[basicBlock.get()]->setDomDepth(
|
||||||
|
blockAnalysisInfo[new_idom]->getDomDepth() + 1);
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for (auto &basicBlock : basicBlocks) {
|
||||||
|
// if (basicBlock.get() != func->getEntryBlock()) {
|
||||||
|
// auto dominats =
|
||||||
|
// blockAnalysisInfo[basicBlock.get()]->getDominants();
|
||||||
|
// bool found = false;
|
||||||
|
// // 从前驱结点开始寻找直接支配结点
|
||||||
|
// std::queue<BasicBlock *> q;
|
||||||
|
// for (auto pred : basicBlock->getPredecessors()) {
|
||||||
|
// q.push(pred);
|
||||||
|
// }
|
||||||
|
// // BFS遍历前驱结点,直到找到直接支配结点
|
||||||
|
// while (!found && !q.empty()) {
|
||||||
|
// auto curr = q.front();
|
||||||
|
// q.pop();
|
||||||
|
// if (curr == basicBlock.get())
|
||||||
|
// continue;
|
||||||
|
// if (dominats.count(curr) != 0U) {
|
||||||
|
// blockAnalysisInfo[basicBlock.get()]->setIdom(curr);
|
||||||
|
// blockAnalysisInfo[curr]->addSdoms(basicBlock.get());
|
||||||
|
// found = true;
|
||||||
|
// } else {
|
||||||
|
// for (auto pred : curr->getPredecessors()) {
|
||||||
|
// q.push(pred);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::unordered_set<BasicBlock *> ControlFlowAnalysis::computeDomFrontier(BasicBlock *block) {
|
||||||
|
// std::unordered_set<BasicBlock *> ret_list;
|
||||||
|
// // 计算 localDF
|
||||||
|
// for (auto local_successor : block->getSuccessors()) {
|
||||||
|
// if (local_successor->getIdom() != block) {
|
||||||
|
// ret_list.emplace(local_successor);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // 计算 upDF
|
||||||
|
// for (auto up_successor : block->getSdoms()) {
|
||||||
|
// auto childrenDF = computeDF(up_successor);
|
||||||
|
// for (auto w : childrenDF) {
|
||||||
|
// if (block != w->getIdom() || block == w) {
|
||||||
|
// ret_list.emplace(w);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return ret_list;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void ControlFlowAnalysis::computeDomFrontierAllBlk() {
|
||||||
|
auto &functions = pModule->getFunctions();
|
||||||
|
for (const auto &function : functions) {
|
||||||
|
auto func = function.second.get();
|
||||||
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
|
|
||||||
|
// 按支配树深度排序(从深到浅)
|
||||||
|
std::vector<BasicBlock *> orderedBlocks;
|
||||||
|
for (auto &bb : basicBlocks) {
|
||||||
|
orderedBlocks.push_back(bb.get());
|
||||||
|
}
|
||||||
|
std::sort(orderedBlocks.begin(), orderedBlocks.end(),
|
||||||
|
[this](BasicBlock *a, BasicBlock *b) {
|
||||||
|
return blockAnalysisInfo[a]->getDomDepth() > blockAnalysisInfo[b]->getDomDepth();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算支配边界
|
||||||
|
for (auto block : orderedBlocks) {
|
||||||
|
std::unordered_set<BasicBlock *> df;
|
||||||
|
|
||||||
|
// Local DF: 直接后继中不被当前块支配的
|
||||||
|
for (auto succ : block->getSuccessors()) {
|
||||||
|
// 当前块不支配该后继(即不是其直接支配节点)
|
||||||
|
if (blockAnalysisInfo[succ]->getIdom() != block) {
|
||||||
|
df.insert(succ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Up DF: 从支配子树中继承
|
||||||
|
for (auto child : blockAnalysisInfo[block]->getSdoms()) {
|
||||||
|
for (auto w : blockAnalysisInfo[child]->getDomFrontiers()) {
|
||||||
|
// 如果w不被当前块支配
|
||||||
|
if (block != blockAnalysisInfo[w]->getIdom()) {
|
||||||
|
df.insert(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockAnalysisInfo[block]->setDomFrontiers(df);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================
|
||||||
|
// dataflow analysis utils
|
||||||
|
// ==========================
|
||||||
|
|
||||||
|
// 先引用学长的代码
|
||||||
|
// TODO: Worklist 增加逆后序遍历机制
|
||||||
|
void DataFlowAnalysisUtils::forwardAnalyze(Module *pModule){
|
||||||
|
std::map<DataFlowAnalysis *, bool> workAnalysis;
|
||||||
|
for (auto &dataflow : forwardAnalysisList) {
|
||||||
|
dataflow->init(pModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &function : pModule->getFunctions()) {
|
||||||
|
for (auto &dataflow : forwardAnalysisList) {
|
||||||
|
workAnalysis.emplace(dataflow, false);
|
||||||
|
}
|
||||||
|
while (!workAnalysis.empty()) {
|
||||||
|
for (const auto &block : function.second->getBasicBlocks()) {
|
||||||
|
for (auto &elem : workAnalysis) {
|
||||||
|
if (elem.first->analyze(pModule, block.get())) {
|
||||||
|
elem.second = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::map<DataFlowAnalysis *, bool> tmp;
|
||||||
|
std::remove_copy_if(workAnalysis.begin(), workAnalysis.end(), std::inserter(tmp, tmp.end()),
|
||||||
|
[](const std::pair<DataFlowAnalysis *, bool> &elem) -> bool { return !elem.second; });
|
||||||
|
workAnalysis.swap(tmp);
|
||||||
|
|
||||||
|
for (auto &elem : workAnalysis) {
|
||||||
|
elem.second = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFlowAnalysisUtils::backwardAnalyze(Module *pModule) {
|
||||||
|
std::map<DataFlowAnalysis *, bool> workAnalysis;
|
||||||
|
for (auto &dataflow : backwardAnalysisList) {
|
||||||
|
dataflow->init(pModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &function : pModule->getFunctions()) {
|
||||||
|
for (auto &dataflow : backwardAnalysisList) {
|
||||||
|
workAnalysis.emplace(dataflow, false);
|
||||||
|
}
|
||||||
|
while (!workAnalysis.empty()) {
|
||||||
|
for (const auto &block : function.second->getBasicBlocks()) {
|
||||||
|
for (auto &elem : workAnalysis) {
|
||||||
|
if (elem.first->analyze(pModule, block.get())) {
|
||||||
|
elem.second = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::map<DataFlowAnalysis *, bool> tmp;
|
||||||
|
std::remove_copy_if(workAnalysis.begin(), workAnalysis.end(), std::inserter(tmp, tmp.end()),
|
||||||
|
[](const std::pair<DataFlowAnalysis *, bool> &elem) -> bool { return !elem.second; });
|
||||||
|
workAnalysis.swap(tmp);
|
||||||
|
|
||||||
|
for (auto &elem : workAnalysis) {
|
||||||
|
elem.second = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::set<User *> ActiveVarAnalysis::getUsedSet(Instruction *inst) {
|
||||||
|
using Kind = Instruction::Kind;
|
||||||
|
std::vector<User *> operands;
|
||||||
|
for (const auto &operand : inst->getOperands()) {
|
||||||
|
operands.emplace_back(dynamic_cast<User *>(operand->getValue()));
|
||||||
|
}
|
||||||
|
std::set<User *> result;
|
||||||
|
switch (inst->getKind()) {
|
||||||
|
// phi op
|
||||||
|
case Kind::kPhi:
|
||||||
|
case Kind::kCall:
|
||||||
|
result.insert(std::next(operands.begin()), operands.end());
|
||||||
|
break;
|
||||||
|
case Kind::kCondBr:
|
||||||
|
result.insert(operands[0]);
|
||||||
|
break;
|
||||||
|
case Kind::kBr:
|
||||||
|
case Kind::kAlloca:
|
||||||
|
break;
|
||||||
|
// mem op
|
||||||
|
case Kind::kStore:
|
||||||
|
// StoreInst 的第一个操作数是被存储的值,第二个操作数是存储的变量
|
||||||
|
// 后续的是可能的数组维度
|
||||||
|
result.insert(operands[0]);
|
||||||
|
result.insert(operands.begin() + 2, operands.end());
|
||||||
|
break;
|
||||||
|
case Kind::kLoad:
|
||||||
|
case Kind::kLa: {
|
||||||
|
auto variable = dynamic_cast<AllocaInst *>(operands[0]);
|
||||||
|
auto global = dynamic_cast<GlobalValue *>(operands[0]);
|
||||||
|
auto constArray = dynamic_cast<ConstantVariable *>(operands[0]);
|
||||||
|
if ((variable != nullptr && variable->getNumDims() == 0) || (global != nullptr && global->getNumDims() == 0) ||
|
||||||
|
(constArray != nullptr && constArray->getNumDims() == 0)) {
|
||||||
|
result.insert(operands[0]);
|
||||||
|
}
|
||||||
|
result.insert(std::next(operands.begin()), operands.end());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Kind::kGetSubArray: {
|
||||||
|
for (unsigned i = 2; i < operands.size(); i++) {
|
||||||
|
// 数组的维度信息
|
||||||
|
result.insert(operands[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Kind::kMemset: {
|
||||||
|
result.insert(std::next(operands.begin()), operands.end());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Kind::kInvalid:
|
||||||
|
// Binary
|
||||||
|
case Kind::kAdd:
|
||||||
|
case Kind::kSub:
|
||||||
|
case Kind::kMul:
|
||||||
|
case Kind::kDiv:
|
||||||
|
case Kind::kRem:
|
||||||
|
case Kind::kICmpEQ:
|
||||||
|
case Kind::kICmpNE:
|
||||||
|
case Kind::kICmpLT:
|
||||||
|
case Kind::kICmpLE:
|
||||||
|
case Kind::kICmpGT:
|
||||||
|
case Kind::kICmpGE:
|
||||||
|
case Kind::kFAdd:
|
||||||
|
case Kind::kFSub:
|
||||||
|
case Kind::kFMul:
|
||||||
|
case Kind::kFDiv:
|
||||||
|
case Kind::kFCmpEQ:
|
||||||
|
case Kind::kFCmpNE:
|
||||||
|
case Kind::kFCmpLT:
|
||||||
|
case Kind::kFCmpLE:
|
||||||
|
case Kind::kFCmpGT:
|
||||||
|
case Kind::kFCmpGE:
|
||||||
|
case Kind::kAnd:
|
||||||
|
case Kind::kOr:
|
||||||
|
// Unary
|
||||||
|
case Kind::kNeg:
|
||||||
|
case Kind::kNot:
|
||||||
|
case Kind::kFNot:
|
||||||
|
case Kind::kFNeg:
|
||||||
|
case Kind::kFtoI:
|
||||||
|
case Kind::kItoF:
|
||||||
|
// terminator
|
||||||
|
case Kind::kReturn:
|
||||||
|
result.insert(operands.begin(), operands.end());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.erase(nullptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
User * ActiveVarAnalysis::getDefine(Instruction *inst) {
|
||||||
|
User *result = nullptr;
|
||||||
|
if (inst->isStore()) {
|
||||||
|
StoreInst* store = dynamic_cast<StoreInst *>(inst);
|
||||||
|
auto operand = store->getPointer();
|
||||||
|
AllocaInst* variable = dynamic_cast<AllocaInst *>(operand);
|
||||||
|
GlobalValue* global = dynamic_cast<GlobalValue *>(operand);
|
||||||
|
if ((variable != nullptr && variable->getNumDims() != 0) || (global != nullptr && global->getNumDims() != 0)) {
|
||||||
|
// 如果是数组变量或者全局变量,则不返回定义
|
||||||
|
// TODO:兼容数组变量
|
||||||
|
result = nullptr;
|
||||||
|
} else {
|
||||||
|
result = dynamic_cast<User *>(operand);
|
||||||
|
}
|
||||||
|
} else if (inst->isPhi()) {
|
||||||
|
result = dynamic_cast<User *>(inst->getOperand(0));
|
||||||
|
} else if (inst->isBinary() || inst->isUnary() || inst->isCall() ||
|
||||||
|
inst->isLoad() || inst->isLa()) {
|
||||||
|
result = dynamic_cast<User *>(inst);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActiveVarAnalysis::init(Module *pModule) {
|
||||||
|
for (const auto &function : pModule->getFunctions()) {
|
||||||
|
for (const auto &block : function.second->getBasicBlocks()) {
|
||||||
|
activeTable.emplace(block.get(), std::vector<std::set<User *>>{});
|
||||||
|
for (unsigned i = 0; i < block->getNumInstructions() + 1; i++)
|
||||||
|
activeTable.at(block.get()).emplace_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 活跃变量分析公式 每个块内的分析动作供分析器调用
|
||||||
|
bool ActiveVarAnalysis::analyze(Module *pModule, BasicBlock *block) {
|
||||||
|
bool changed = false; // 标记数据流结果是否有变化
|
||||||
|
std::set<User *> activeSet{}; // 当前计算的活跃变量集合
|
||||||
|
|
||||||
|
// 步骤1: 计算基本块出口的活跃变量集 (OUT[B])
|
||||||
|
// 公式: OUT[B] = ∪_{S ∈ succ(B)} IN[S]
|
||||||
|
for (const auto &succ : block->getSuccessors()) {
|
||||||
|
// 获取后继块入口的活跃变量集 (IN[S])
|
||||||
|
auto succActiveSet = activeTable.at(succ).front();
|
||||||
|
// 合并所有后继块的入口活跃变量
|
||||||
|
activeSet.insert(succActiveSet.begin(), succActiveSet.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤2: 处理基本块出口处的活跃变量集
|
||||||
|
const auto &instructions = block->getInstructions();
|
||||||
|
const auto numInstructions = instructions.size();
|
||||||
|
|
||||||
|
// 获取旧的出口活跃变量集 (block出口对应索引numInstructions)
|
||||||
|
const auto &oldEndActiveSet = activeTable.at(block)[numInstructions];
|
||||||
|
|
||||||
|
// 检查出口活跃变量集是否有变化
|
||||||
|
if (!std::equal(activeSet.begin(), activeSet.end(),
|
||||||
|
oldEndActiveSet.begin(), oldEndActiveSet.end()))
|
||||||
|
{
|
||||||
|
changed = true; // 标记变化
|
||||||
|
activeTable.at(block)[numInstructions] = activeSet; // 更新出口活跃变量集
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤3: 逆序遍历基本块中的指令
|
||||||
|
// 从最后一条指令开始向前计算每个程序点的活跃变量
|
||||||
|
auto instructionIter = instructions.end();
|
||||||
|
instructionIter--; // 指向最后一条指令
|
||||||
|
|
||||||
|
// 从出口向入口遍历 (索引从numInstructions递减到1)
|
||||||
|
for (unsigned i = numInstructions; i > 0; i--) {
|
||||||
|
auto inst = instructionIter->get(); // 当前指令
|
||||||
|
|
||||||
|
auto used = getUsedSet(inst);
|
||||||
|
User *defined = getDefine(inst);
|
||||||
|
|
||||||
|
// 步骤3.3: 计算指令入口的活跃变量 (IN[i])
|
||||||
|
// 公式: IN[i] = use_i ∪ (OUT[i] - def_i)
|
||||||
|
activeSet.erase(defined); // 移除被定义的变量 (OUT[i] - def_i)
|
||||||
|
activeSet.insert(used.begin(), used.end()); // 添加使用的变量
|
||||||
|
|
||||||
|
// 获取旧的入口活跃变量集 (位置i-1对应当前指令的入口)
|
||||||
|
const auto &oldActiveSet = activeTable.at(block)[i - 1];
|
||||||
|
|
||||||
|
// 检查活跃变量集是否有变化
|
||||||
|
if (!std::equal(activeSet.begin(), activeSet.end(),
|
||||||
|
oldActiveSet.begin(), oldActiveSet.end()))
|
||||||
|
{
|
||||||
|
changed = true; // 标记变化
|
||||||
|
activeTable.at(block)[i - 1] = activeSet; // 更新入口活跃变量集
|
||||||
|
}
|
||||||
|
|
||||||
|
instructionIter--; // 移动到前一条指令
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed; // 返回数据流结果是否变化
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto ActiveVarAnalysis::getActiveTable() const -> const std::map<BasicBlock *, std::vector<std::set<User *>>> & {
|
||||||
|
return activeTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
|
|
||||||
|
|||||||
@@ -73,10 +73,12 @@ std::any SysYIRGenerator::visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ValueCounter values = {};
|
||||||
|
if (varDef->initVal() != nullptr) {
|
||||||
ArrayValueTree* root = std::any_cast<ArrayValueTree *>(varDef->initVal()->accept(this));
|
ArrayValueTree* root = std::any_cast<ArrayValueTree *>(varDef->initVal()->accept(this));
|
||||||
ValueCounter values;
|
|
||||||
Utils::tree2Array(type, root, dims, dims.size(), values, &builder);
|
Utils::tree2Array(type, root, dims, dims.size(), values, &builder);
|
||||||
delete root;
|
delete root;
|
||||||
|
}
|
||||||
// 创建全局变量,并更新符号表
|
// 创建全局变量,并更新符号表
|
||||||
module->createGlobalValue(name, Type::getPointerType(type), dims, values);
|
module->createGlobalValue(name, Type::getPointerType(type), dims, values);
|
||||||
}
|
}
|
||||||
@@ -456,7 +458,7 @@ std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext *ctx) {
|
|||||||
returnValue = std::any_cast<Value *>(visitExp(ctx->exp()));
|
returnValue = std::any_cast<Value *>(visitExp(ctx->exp()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* funcType = builder.getBasicBlock()->getParent()->getType();
|
Type* funcType = builder.getBasicBlock()->getParent()->getReturnType();
|
||||||
if (funcType!= returnValue->getType() && returnValue != nullptr) {
|
if (funcType!= returnValue->getType() && returnValue != nullptr) {
|
||||||
ConstantValue * constValue = dynamic_cast<ConstantValue *>(returnValue);
|
ConstantValue * constValue = dynamic_cast<ConstantValue *>(returnValue);
|
||||||
if (constValue != nullptr) {
|
if (constValue != nullptr) {
|
||||||
|
|||||||
489
src/SysYIROptPre.cpp
Normal file
489
src/SysYIROptPre.cpp
Normal file
@@ -0,0 +1,489 @@
|
|||||||
|
/**
|
||||||
|
* @file: Sysyoptimization.cpp
|
||||||
|
* @brief CFG优化
|
||||||
|
* @Author : Ixeux email:you@domain.com
|
||||||
|
* @Version : 1.0
|
||||||
|
* @Creat Date : 2024-08-10
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "SysYIROptPre.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include "IR.h"
|
||||||
|
#include "IRBuilder.h"
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use删除operand,以免扰乱后续分析
|
||||||
|
* instr: 要删除的指令
|
||||||
|
*/
|
||||||
|
void SysYOptPre::usedelete(Instruction *instr) {
|
||||||
|
for (auto &use : instr->getOperands()) {
|
||||||
|
Value* val = use->getValue();
|
||||||
|
// std::cout << delete << val->getName() << std::endl;
|
||||||
|
val->removeUse(use);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 删除br后的无用指令
|
||||||
|
void SysYOptPre::SysYDelInstAfterBr() {
|
||||||
|
auto &functions = pModule->getFunctions();
|
||||||
|
for (auto &function : functions) {
|
||||||
|
auto basicBlocks = function.second->getBasicBlocks();
|
||||||
|
for (auto &basicBlock : basicBlocks) {
|
||||||
|
bool Branch = false;
|
||||||
|
auto &instructions = basicBlock->getInstructions();
|
||||||
|
auto Branchiter = instructions.end();
|
||||||
|
for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
|
||||||
|
if (Branch)
|
||||||
|
usedelete(iter->get());
|
||||||
|
else if ((*iter)->isTerminator()){
|
||||||
|
Branch = true;
|
||||||
|
Branchiter = iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Branchiter != instructions.end()) ++Branchiter;
|
||||||
|
while (Branchiter != instructions.end())
|
||||||
|
Branchiter = instructions.erase(Branchiter);
|
||||||
|
|
||||||
|
if (Branch) { // 更新前驱后继关系
|
||||||
|
auto thelastinstinst = basicBlock->getInstructions().end();
|
||||||
|
--thelastinstinst;
|
||||||
|
auto &Successors = basicBlock->getSuccessors();
|
||||||
|
for (auto iterSucc = Successors.begin(); iterSucc != Successors.end();) {
|
||||||
|
(*iterSucc)->removePredecessor(basicBlock.get());
|
||||||
|
basicBlock->removeSuccessor(*iterSucc);
|
||||||
|
}
|
||||||
|
if (thelastinstinst->get()->isUnconditional()) {
|
||||||
|
BasicBlock* branchBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(0));
|
||||||
|
basicBlock->addSuccessor(branchBlock);
|
||||||
|
branchBlock->addPredecessor(basicBlock.get());
|
||||||
|
} else if (thelastinstinst->get()->isConditional()) {
|
||||||
|
BasicBlock* thenBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(1));
|
||||||
|
BasicBlock* elseBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(2));
|
||||||
|
basicBlock->addSuccessor(thenBlock);
|
||||||
|
basicBlock->addSuccessor(elseBlock);
|
||||||
|
thenBlock->addPredecessor(basicBlock.get());
|
||||||
|
elseBlock->addPredecessor(basicBlock.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SysYOptPre::SysYBlockMerge() {
|
||||||
|
auto &functions = pModule->getFunctions(); //std::map<std::string, std::unique_ptr<Function>>
|
||||||
|
for (auto &function : functions) {
|
||||||
|
// auto basicBlocks = function.second->getBasicBlocks();
|
||||||
|
auto &func = function.second;
|
||||||
|
for (auto blockiter = func->getBasicBlocks().begin();
|
||||||
|
blockiter != func->getBasicBlocks().end();) {
|
||||||
|
if (blockiter->get()->getNumSuccessors() == 1) {
|
||||||
|
// 如果当前块只有一个后继块
|
||||||
|
// 且后继块只有一个前驱块
|
||||||
|
// 则将当前块和后继块合并
|
||||||
|
if (((blockiter->get())->getSuccessors()[0])->getNumPredecessors() == 1) {
|
||||||
|
// std::cout << "merge block: " << blockiter->get()->getName() << std::endl;
|
||||||
|
BasicBlock* block = blockiter->get();
|
||||||
|
BasicBlock* nextBlock = blockiter->get()->getSuccessors()[0];
|
||||||
|
auto nextarguments = nextBlock->getArguments();
|
||||||
|
// 删除br指令
|
||||||
|
if (block->getNumInstructions() != 0) {
|
||||||
|
auto thelastinstinst = block->end();
|
||||||
|
(--thelastinstinst);
|
||||||
|
if (thelastinstinst->get()->isUnconditional()) {
|
||||||
|
usedelete(thelastinstinst->get());
|
||||||
|
block->getInstructions().erase(thelastinstinst);
|
||||||
|
} else if (thelastinstinst->get()->isConditional()) {
|
||||||
|
// 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式
|
||||||
|
if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) {
|
||||||
|
usedelete(thelastinstinst->get());
|
||||||
|
block->getInstructions().erase(thelastinstinst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 将后继块的指令移动到当前块
|
||||||
|
// 并将后继块的父指针改为当前块
|
||||||
|
for (auto institer = nextBlock->begin(); institer != nextBlock->end();) {
|
||||||
|
institer->get()->setParent(block);
|
||||||
|
block->getInstructions().emplace_back(institer->release());
|
||||||
|
institer = nextBlock->getInstructions().erase(institer);
|
||||||
|
}
|
||||||
|
// 合并参数
|
||||||
|
// TODO:是否需要去重?
|
||||||
|
for (auto &argm : nextarguments) {
|
||||||
|
argm->setParent(block);
|
||||||
|
block->insertArgument(argm);
|
||||||
|
}
|
||||||
|
// 更新前驱后继关系,类似树节点操作
|
||||||
|
block->removeSuccessor(nextBlock);
|
||||||
|
nextBlock->removePredecessor(block);
|
||||||
|
std::list<BasicBlock *> succshoulddel;
|
||||||
|
for (auto &succ : nextBlock->getSuccessors()) {
|
||||||
|
block->addSuccessor(succ);
|
||||||
|
succ->replacePredecessor(nextBlock, block);
|
||||||
|
succshoulddel.push_back(succ);
|
||||||
|
}
|
||||||
|
for (auto del : succshoulddel) {
|
||||||
|
nextBlock->removeSuccessor(del);
|
||||||
|
}
|
||||||
|
|
||||||
|
func->removeBasicBlock(nextBlock);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
blockiter++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
blockiter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除无前驱块,兼容SSA后的处理
|
||||||
|
void SysYOptPre::SysYDelNoPreBLock() {
|
||||||
|
|
||||||
|
auto &functions = pModule->getFunctions(); // std::map<std::string, std::unique_ptr<sysy::Function>>
|
||||||
|
for (auto &function : functions) {
|
||||||
|
auto &func = function.second;
|
||||||
|
|
||||||
|
for (auto &block : func->getBasicBlocks()) {
|
||||||
|
block->setreachableFalse();
|
||||||
|
}
|
||||||
|
// 对函数基本块做一个拓扑排序,排查不可达基本块
|
||||||
|
auto entryBlock = func->getEntryBlock();
|
||||||
|
entryBlock->setreachableTrue();
|
||||||
|
std::queue<BasicBlock *> blockqueue;
|
||||||
|
blockqueue.push(entryBlock);
|
||||||
|
while (!blockqueue.empty()) {
|
||||||
|
auto block = blockqueue.front();
|
||||||
|
blockqueue.pop();
|
||||||
|
for (auto &succ : block->getSuccessors()) {
|
||||||
|
if (!succ->getreachable()) {
|
||||||
|
succ->setreachableTrue();
|
||||||
|
blockqueue.push(succ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除不可达基本块指令
|
||||||
|
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) {
|
||||||
|
|
||||||
|
if (!blockIter->get()->getreachable())
|
||||||
|
for (auto &iterInst : blockIter->get()->getInstructions())
|
||||||
|
usedelete(iterInst.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) {
|
||||||
|
if (!blockIter->get()->getreachable()) {
|
||||||
|
for (auto succblock : blockIter->get()->getSuccessors()) {
|
||||||
|
int indexphi = 1;
|
||||||
|
for (auto pred : succblock->getPredecessors()) {
|
||||||
|
if (pred == blockIter->get()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
indexphi++;
|
||||||
|
}
|
||||||
|
for (auto &phiinst : succblock->getInstructions()) {
|
||||||
|
if (phiinst->getKind() != Instruction::kPhi) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
phiinst->removeOperand(indexphi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除不可达基本块,注意迭代器不可达问题
|
||||||
|
func->removeBasicBlock((blockIter++)->get());
|
||||||
|
} else {
|
||||||
|
blockIter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysYOptPre::SysYDelEmptyBlock() {
|
||||||
|
auto &functions = pModule->getFunctions();
|
||||||
|
for (auto &function : functions) {
|
||||||
|
// 收集不可达基本块
|
||||||
|
// 这里的不可达基本块是指没有实际指令的基本块
|
||||||
|
// 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时,也会被视作不可达
|
||||||
|
auto basicBlocks = function.second->getBasicBlocks();
|
||||||
|
std::map<sysy::BasicBlock *, BasicBlock *> EmptyBlocks;
|
||||||
|
// 空块儿和后继的基本块的映射
|
||||||
|
for (auto &basicBlock : basicBlocks) {
|
||||||
|
if (basicBlock->getNumInstructions() == 0) {
|
||||||
|
if (basicBlock->getNumSuccessors() == 1) {
|
||||||
|
EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// 如果只有phi指令和一个uncondbr。(phi)*(uncondbr)?
|
||||||
|
// 判断除了最后一个指令之外是不是只有phi指令
|
||||||
|
bool onlyPhi = true;
|
||||||
|
for (auto &inst : basicBlock->getInstructions()) {
|
||||||
|
if (!inst->isPhi() && !inst->isUnconditional()) {
|
||||||
|
onlyPhi = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(onlyPhi)
|
||||||
|
EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// 更新基本块信息,增加必要指令
|
||||||
|
for (auto &basicBlock : basicBlocks) {
|
||||||
|
// 把空块转换成只有跳转指令的不可达块
|
||||||
|
if (distance(basicBlock->begin(), basicBlock->end()) == 0) {
|
||||||
|
if (basicBlock->getNumSuccessors() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (basicBlock->getNumSuccessors() > 1) {
|
||||||
|
assert("");
|
||||||
|
}
|
||||||
|
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
||||||
|
pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto thelastinst = basicBlock->getInstructions().end();
|
||||||
|
--thelastinst;
|
||||||
|
|
||||||
|
// 根据br指令传递的后继块信息,跳过空块链
|
||||||
|
if (thelastinst->get()->isUnconditional()) {
|
||||||
|
BasicBlock* OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||||||
|
BasicBlock *thelastBlockOld = nullptr;
|
||||||
|
// 如果空块链表为多个块
|
||||||
|
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
|
||||||
|
EmptyBlocks.end()) {
|
||||||
|
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||||||
|
thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]);
|
||||||
|
}
|
||||||
|
|
||||||
|
basicBlock->removeSuccessor(OldBrBlock);
|
||||||
|
OldBrBlock->removePredecessor(basicBlock.get());
|
||||||
|
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
|
||||||
|
|
||||||
|
if (thelastBlockOld != nullptr) {
|
||||||
|
int indexphi = 0;
|
||||||
|
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
|
||||||
|
if (pred == thelastBlockOld) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
indexphi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新phi指令的操作数
|
||||||
|
// 移除thelastBlockOld对应的phi操作数
|
||||||
|
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
|
||||||
|
if (InstInNew->isPhi()) {
|
||||||
|
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (thelastinst->get()->getKind() == Instruction::kCondBr) {
|
||||||
|
auto OldThenBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
|
auto OldElseBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
|
||||||
|
|
||||||
|
BasicBlock *thelastBlockOld = nullptr;
|
||||||
|
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))) !=
|
||||||
|
EmptyBlocks.end()) {
|
||||||
|
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
|
thelastinst->get()->replaceOperand(
|
||||||
|
1, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))]);
|
||||||
|
}
|
||||||
|
basicBlock->removeSuccessor(OldThenBlock);
|
||||||
|
OldThenBlock->removePredecessor(basicBlock.get());
|
||||||
|
// 处理 then 和 else 分支合并的情况
|
||||||
|
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
||||||
|
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
|
usedelete(thelastinst->get());
|
||||||
|
thelastinst = basicBlock->getInstructions().erase(thelastinst);
|
||||||
|
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
||||||
|
pBuilder->createUncondBrInst(thebrBlock, {});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)));
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get());
|
||||||
|
// auto indexInNew = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors().
|
||||||
|
|
||||||
|
if (thelastBlockOld != nullptr) {
|
||||||
|
int indexphi = 0;
|
||||||
|
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getPredecessors()) {
|
||||||
|
if (pred == thelastBlockOld) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
indexphi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getInstructions()) {
|
||||||
|
if (InstInNew->isPhi()) {
|
||||||
|
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thelastBlockOld = nullptr;
|
||||||
|
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) !=
|
||||||
|
EmptyBlocks.end()) {
|
||||||
|
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
|
||||||
|
thelastinst->get()->replaceOperand(
|
||||||
|
2, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))]);
|
||||||
|
}
|
||||||
|
basicBlock->removeSuccessor(OldElseBlock);
|
||||||
|
OldElseBlock->removePredecessor(basicBlock.get());
|
||||||
|
// 处理 then 和 else 分支合并的情况
|
||||||
|
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
||||||
|
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
|
usedelete(thelastinst->get());
|
||||||
|
thelastinst = basicBlock->getInstructions().erase(thelastinst);
|
||||||
|
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
||||||
|
pBuilder->createUncondBrInst(thebrBlock, {});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)));
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get());
|
||||||
|
|
||||||
|
if (thelastBlockOld != nullptr) {
|
||||||
|
int indexphi = 0;
|
||||||
|
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getPredecessors()) {
|
||||||
|
if (pred == thelastBlockOld) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
indexphi++;
|
||||||
|
}
|
||||||
|
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getInstructions()) {
|
||||||
|
if (InstInNew->isPhi()) {
|
||||||
|
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (basicBlock->getNumSuccessors() == 1) {
|
||||||
|
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
||||||
|
pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
|
||||||
|
auto thelastinst = basicBlock->getInstructions().end();
|
||||||
|
(--thelastinst);
|
||||||
|
auto OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||||||
|
sysy::BasicBlock *thelastBlockOld = nullptr;
|
||||||
|
while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
|
||||||
|
EmptyBlocks.end()) {
|
||||||
|
thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
|
||||||
|
|
||||||
|
thelastinst->get()->replaceOperand(
|
||||||
|
0, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))]);
|
||||||
|
}
|
||||||
|
|
||||||
|
basicBlock->removeSuccessor(OldBrBlock);
|
||||||
|
OldBrBlock->removePredecessor(basicBlock.get());
|
||||||
|
basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
|
||||||
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
|
||||||
|
if (thelastBlockOld != nullptr) {
|
||||||
|
int indexphi = 0;
|
||||||
|
for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
|
||||||
|
if (pred == thelastBlockOld) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
indexphi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
|
||||||
|
if (InstInNew->isPhi()) {
|
||||||
|
dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto iter = function.second->getBasicBlocks().begin(); iter != function.second->getBasicBlocks().end();) {
|
||||||
|
|
||||||
|
if (EmptyBlocks.find(iter->get()) != EmptyBlocks.end()) {
|
||||||
|
// EntryBlock跳过
|
||||||
|
if (iter->get() == function.second->getEntryBlock()) {
|
||||||
|
++iter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &iterInst : iter->get()->getInstructions())
|
||||||
|
usedelete(iterInst.get());
|
||||||
|
// 删除不可达基本块的phi指令的操作数
|
||||||
|
for (auto &succ : iter->get()->getSuccessors()) {
|
||||||
|
int index = 0;
|
||||||
|
for (auto &pred : succ->getPredecessors()) {
|
||||||
|
if (pred == iter->get()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &instinsucc : succ->getInstructions()) {
|
||||||
|
if (instinsucc->isPhi()) {
|
||||||
|
dynamic_cast<PhiInst *>(instinsucc.get())->removeOperand(index);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function.second->removeBasicBlock((iter++)->get());
|
||||||
|
} else {
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题)
|
||||||
|
void SysYOptPre::SysYAddReturn() {
|
||||||
|
auto &functions = pModule->getFunctions();
|
||||||
|
for (auto &function : functions) {
|
||||||
|
auto &func = function.second;
|
||||||
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
|
for (auto &block : basicBlocks) {
|
||||||
|
if (block->getNumSuccessors() == 0) {
|
||||||
|
// 如果基本块没有后继块,则添加一个返回指令
|
||||||
|
if (block->getNumInstructions() == 0) {
|
||||||
|
pBuilder->setPosition(block.get(), block->end());
|
||||||
|
pBuilder->createReturnInst({});
|
||||||
|
}
|
||||||
|
auto thelastinst = block->getInstructions().end();
|
||||||
|
--thelastinst;
|
||||||
|
if (thelastinst->get()->getKind() != Instruction::kReturn) {
|
||||||
|
pBuilder->setPosition(block.get(), block->end());
|
||||||
|
// TODO: 如果int float函数缺少返回值是否需要报错
|
||||||
|
if (func->getReturnType()->isInt()) {
|
||||||
|
pBuilder->createReturnInst(ConstantValue::get(0));
|
||||||
|
} else if (func->getReturnType()->isFloat()) {
|
||||||
|
pBuilder->createReturnInst(ConstantValue::get(0.0F));
|
||||||
|
} else {
|
||||||
|
pBuilder->createReturnInst({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
482
src/SysYIRPrinter.cpp
Normal file
482
src/SysYIRPrinter.cpp
Normal file
@@ -0,0 +1,482 @@
|
|||||||
|
#include "SysYIRPrinter.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include "IR.h"
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
void SysYPrinter::printIR() {
|
||||||
|
|
||||||
|
const auto &functions = pModule->getFunctions();
|
||||||
|
|
||||||
|
//TODO: Print target datalayout and triple (minimal required by LLVM)
|
||||||
|
|
||||||
|
printGlobalVariable();
|
||||||
|
|
||||||
|
for (const auto &iter : functions) {
|
||||||
|
if (iter.second->getName() == "main") {
|
||||||
|
printFunction(iter.second.get());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &iter : functions) {
|
||||||
|
if (iter.second->getName() != "main") {
|
||||||
|
printFunction(iter.second.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SysYPrinter::getTypeString(Type *type) {
|
||||||
|
if (type->isVoid()) {
|
||||||
|
return "void";
|
||||||
|
} else if (type->isInt()) {
|
||||||
|
return "i32";
|
||||||
|
} else if (type->isFloat()) {
|
||||||
|
return "float";
|
||||||
|
|
||||||
|
} else if (auto ptrType = dynamic_cast<PointerType*>(type)) {
|
||||||
|
return getTypeString(ptrType->getBaseType()) + "*";
|
||||||
|
} else if (auto ptrType = dynamic_cast<FunctionType*>(type)) {
|
||||||
|
return getTypeString(ptrType->getReturnType());
|
||||||
|
}
|
||||||
|
assert(false && "Unsupported type");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SysYPrinter::getValueName(Value *value) {
|
||||||
|
if (auto global = dynamic_cast<GlobalValue*>(value)) {
|
||||||
|
return "@" + global->getName();
|
||||||
|
} else if (auto inst = dynamic_cast<Instruction*>(value)) {
|
||||||
|
return "%" + inst->getName();
|
||||||
|
} else if (auto constVal = dynamic_cast<ConstantValue*>(value)) {
|
||||||
|
if (constVal->isFloat()) {
|
||||||
|
return std::to_string(constVal->getFloat());
|
||||||
|
}
|
||||||
|
return std::to_string(constVal->getInt());
|
||||||
|
} else if (auto constVar = dynamic_cast<ConstantVariable*>(value)) {
|
||||||
|
return constVar->getName();
|
||||||
|
}
|
||||||
|
assert(false && "Unknown value type");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysYPrinter::printType(Type *type) {
|
||||||
|
std::cout << getTypeString(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysYPrinter::printValue(Value *value) {
|
||||||
|
std::cout << getValueName(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysYPrinter::printGlobalVariable() {
|
||||||
|
auto &globals = pModule->getGlobals();
|
||||||
|
|
||||||
|
for (const auto &global : globals) {
|
||||||
|
std::cout << "@" << global->getName() << " = global ";
|
||||||
|
|
||||||
|
auto baseType = dynamic_cast<PointerType *>(global->getType())->getBaseType();
|
||||||
|
printType(baseType);
|
||||||
|
|
||||||
|
if (global->getNumDims() > 0) {
|
||||||
|
// Array type
|
||||||
|
std::cout << " [";
|
||||||
|
for (unsigned i = 0; i < global->getNumDims(); i++) {
|
||||||
|
if (i > 0) std::cout << " x ";
|
||||||
|
std::cout << getValueName(global->getDim(i));
|
||||||
|
}
|
||||||
|
std::cout << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << " ";
|
||||||
|
|
||||||
|
if (global->getNumDims() > 0) {
|
||||||
|
// Array initializer
|
||||||
|
std::cout << "[";
|
||||||
|
auto values = global->getInitValues();
|
||||||
|
auto counterValues = values.getValues();
|
||||||
|
auto counterNumbers = values.getNumbers();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < counterNumbers.size(); i++) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
if (baseType->isFloat()) {
|
||||||
|
std::cout << "float " << dynamic_cast<ConstantValue*>(counterValues[i])->getFloat();
|
||||||
|
} else {
|
||||||
|
std::cout << "i32 " << dynamic_cast<ConstantValue*>(counterValues[i])->getInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "]";
|
||||||
|
} else {
|
||||||
|
// Scalar initializer
|
||||||
|
if (baseType->isFloat()) {
|
||||||
|
std::cout << "float " << dynamic_cast<ConstantValue*>(global->getByIndex(0))->getFloat();
|
||||||
|
} else {
|
||||||
|
std::cout << "i32 " << dynamic_cast<ConstantValue*>(global->getByIndex(0))->getInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ", align 4" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysYPrinter::printFunction(Function *function) {
|
||||||
|
// Function signature
|
||||||
|
std::cout << "define ";
|
||||||
|
printType(function->getReturnType());
|
||||||
|
std::cout << " @" << function->getName() << "(";
|
||||||
|
|
||||||
|
auto entryBlock = function->getEntryBlock();
|
||||||
|
const auto &args_types = function->getParamTypes();
|
||||||
|
auto &args = entryBlock->getArguments();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (const auto &args_type : args_types) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
printType(args_type);
|
||||||
|
std::cout << " %" << args[i]->getName();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ") {" << std::endl;
|
||||||
|
|
||||||
|
// Function body
|
||||||
|
for (const auto &blockIter : function->getBasicBlocks()) {
|
||||||
|
// Basic block label
|
||||||
|
BasicBlock* blockPtr = blockIter.get();
|
||||||
|
if (blockPtr == function->getEntryBlock()) {
|
||||||
|
std::cout << "entry:" << std::endl;
|
||||||
|
} else if (!blockPtr->getName().empty()) {
|
||||||
|
std::cout << blockPtr->getName() << ":" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instructions
|
||||||
|
for (const auto &instIter : blockIter->getInstructions()) {
|
||||||
|
auto inst = instIter.get();
|
||||||
|
std::cout << " ";
|
||||||
|
printInst(inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "}" << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysYPrinter::printInst(Instruction *pInst) {
|
||||||
|
using Kind = Instruction::Kind;
|
||||||
|
|
||||||
|
switch (pInst->getKind()) {
|
||||||
|
case Kind::kAdd:
|
||||||
|
case Kind::kSub:
|
||||||
|
case Kind::kMul:
|
||||||
|
case Kind::kDiv:
|
||||||
|
case Kind::kRem:
|
||||||
|
case Kind::kFAdd:
|
||||||
|
case Kind::kFSub:
|
||||||
|
case Kind::kFMul:
|
||||||
|
case Kind::kFDiv:
|
||||||
|
case Kind::kICmpEQ:
|
||||||
|
case Kind::kICmpNE:
|
||||||
|
case Kind::kICmpLT:
|
||||||
|
case Kind::kICmpGT:
|
||||||
|
case Kind::kICmpLE:
|
||||||
|
case Kind::kICmpGE:
|
||||||
|
case Kind::kFCmpEQ:
|
||||||
|
case Kind::kFCmpNE:
|
||||||
|
case Kind::kFCmpLT:
|
||||||
|
case Kind::kFCmpGT:
|
||||||
|
case Kind::kFCmpLE:
|
||||||
|
case Kind::kFCmpGE:
|
||||||
|
case Kind::kAnd:
|
||||||
|
case Kind::kOr: {
|
||||||
|
auto binInst = dynamic_cast<BinaryInst *>(pInst);
|
||||||
|
|
||||||
|
// Print result variable if exists
|
||||||
|
if (!binInst->getName().empty()) {
|
||||||
|
std::cout << "%" << binInst->getName() << " = ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operation name
|
||||||
|
switch (pInst->getKind()) {
|
||||||
|
case Kind::kAdd: std::cout << "add"; break;
|
||||||
|
case Kind::kSub: std::cout << "sub"; break;
|
||||||
|
case Kind::kMul: std::cout << "mul"; break;
|
||||||
|
case Kind::kDiv: std::cout << "sdiv"; break;
|
||||||
|
case Kind::kRem: std::cout << "srem"; break;
|
||||||
|
case Kind::kFAdd: std::cout << "fadd"; break;
|
||||||
|
case Kind::kFSub: std::cout << "fsub"; break;
|
||||||
|
case Kind::kFMul: std::cout << "fmul"; break;
|
||||||
|
case Kind::kFDiv: std::cout << "fdiv"; break;
|
||||||
|
case Kind::kICmpEQ: std::cout << "icmp eq"; break;
|
||||||
|
case Kind::kICmpNE: std::cout << "icmp ne"; break;
|
||||||
|
case Kind::kICmpLT: std::cout << "icmp slt"; break;
|
||||||
|
case Kind::kICmpGT: std::cout << "icmp sgt"; break;
|
||||||
|
case Kind::kICmpLE: std::cout << "icmp sle"; break;
|
||||||
|
case Kind::kICmpGE: std::cout << "icmp sge"; break;
|
||||||
|
case Kind::kFCmpEQ: std::cout << "fcmp oeq"; break;
|
||||||
|
case Kind::kFCmpNE: std::cout << "fcmp one"; break;
|
||||||
|
case Kind::kFCmpLT: std::cout << "fcmp olt"; break;
|
||||||
|
case Kind::kFCmpGT: std::cout << "fcmp ogt"; break;
|
||||||
|
case Kind::kFCmpLE: std::cout << "fcmp ole"; break;
|
||||||
|
case Kind::kFCmpGE: std::cout << "fcmp oge"; break;
|
||||||
|
case Kind::kAnd: std::cout << "and"; break;
|
||||||
|
case Kind::kOr: std::cout << "or"; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Types and operands
|
||||||
|
std::cout << " ";
|
||||||
|
printType(binInst->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(binInst->getLhs());
|
||||||
|
std::cout << ", ";
|
||||||
|
printValue(binInst->getRhs());
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kNeg:
|
||||||
|
case Kind::kNot:
|
||||||
|
case Kind::kFNeg:
|
||||||
|
case Kind::kFNot:
|
||||||
|
case Kind::kFtoI:
|
||||||
|
case Kind::kBitFtoI:
|
||||||
|
case Kind::kItoF:
|
||||||
|
case Kind::kBitItoF: {
|
||||||
|
auto unyInst = dynamic_cast<UnaryInst *>(pInst);
|
||||||
|
|
||||||
|
if (!unyInst->getName().empty()) {
|
||||||
|
std::cout << "%" << unyInst->getName() << " = ";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pInst->getKind()) {
|
||||||
|
case Kind::kNeg: std::cout << "sub "; break;
|
||||||
|
case Kind::kNot: std::cout << "xor "; break;
|
||||||
|
case Kind::kFNeg: std::cout << "fneg "; break;
|
||||||
|
case Kind::kFNot: std::cout << "fneg "; break; // FNot not standard, map to fneg
|
||||||
|
case Kind::kFtoI: std::cout << "fptosi "; break;
|
||||||
|
case Kind::kBitFtoI: std::cout << "bitcast "; break;
|
||||||
|
case Kind::kItoF: std::cout << "sitofp "; break;
|
||||||
|
case Kind::kBitItoF: std::cout << "bitcast "; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printType(unyInst->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
|
||||||
|
// Special handling for negation
|
||||||
|
if (pInst->getKind() == Kind::kNeg || pInst->getKind() == Kind::kNot) {
|
||||||
|
std::cout << "i32 0, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
printValue(pInst->getOperand(0));
|
||||||
|
|
||||||
|
// For bitcast, need to specify destination type
|
||||||
|
if (pInst->getKind() == Kind::kBitFtoI || pInst->getKind() == Kind::kBitItoF) {
|
||||||
|
std::cout << " to ";
|
||||||
|
printType(unyInst->getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kCall: {
|
||||||
|
auto callInst = dynamic_cast<CallInst *>(pInst);
|
||||||
|
auto function = callInst->getCallee();
|
||||||
|
|
||||||
|
if (!callInst->getName().empty()) {
|
||||||
|
std::cout << "%" << callInst->getName() << " = ";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "call ";
|
||||||
|
printType(callInst->getType());
|
||||||
|
std::cout << " @" << function->getName() << "(";
|
||||||
|
|
||||||
|
auto params = callInst->getArguments();
|
||||||
|
bool first = true;
|
||||||
|
for (auto ¶m : params) {
|
||||||
|
if (!first) std::cout << ", ";
|
||||||
|
first = false;
|
||||||
|
printType(param->getValue()->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(param->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ")" << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kCondBr: {
|
||||||
|
auto condBrInst = dynamic_cast<CondBrInst *>(pInst);
|
||||||
|
std::cout << "br i1 ";
|
||||||
|
printValue(condBrInst->getCondition());
|
||||||
|
std::cout << ", label %" << condBrInst->getThenBlock()->getName();
|
||||||
|
std::cout << ", label %" << condBrInst->getElseBlock()->getName();
|
||||||
|
std::cout << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kBr: {
|
||||||
|
auto brInst = dynamic_cast<UncondBrInst *>(pInst);
|
||||||
|
std::cout << "br label %" << brInst->getBlock()->getName();
|
||||||
|
std::cout << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kReturn: {
|
||||||
|
auto retInst = dynamic_cast<ReturnInst *>(pInst);
|
||||||
|
std::cout << "ret ";
|
||||||
|
if (retInst->getNumOperands() != 0) {
|
||||||
|
printType(retInst->getOperand(0)->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(retInst->getOperand(0));
|
||||||
|
} else {
|
||||||
|
std::cout << "void";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kAlloca: {
|
||||||
|
auto allocaInst = dynamic_cast<AllocaInst *>(pInst);
|
||||||
|
std::cout << "%" << allocaInst->getName() << " = alloca ";
|
||||||
|
|
||||||
|
auto baseType = dynamic_cast<PointerType *>(allocaInst->getType())->getBaseType();
|
||||||
|
printType(baseType);
|
||||||
|
|
||||||
|
if (allocaInst->getNumDims() > 0) {
|
||||||
|
std::cout << ", ";
|
||||||
|
for (size_t i = 0; i < allocaInst->getNumDims(); i++) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
printType(Type::getIntType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(allocaInst->getDim(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ", align 4" << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kLoad: {
|
||||||
|
auto loadInst = dynamic_cast<LoadInst *>(pInst);
|
||||||
|
std::cout << "%" << loadInst->getName() << " = load ";
|
||||||
|
printType(loadInst->getType());
|
||||||
|
std::cout << ", ";
|
||||||
|
printType(loadInst->getPointer()->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(loadInst->getPointer());
|
||||||
|
|
||||||
|
if (loadInst->getNumIndices() > 0) {
|
||||||
|
std::cout << ", ";
|
||||||
|
for (size_t i = 0; i < loadInst->getNumIndices(); i++) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
printType(Type::getIntType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(loadInst->getIndex(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ", align 4" << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kLa: {
|
||||||
|
auto laInst = dynamic_cast<LaInst *>(pInst);
|
||||||
|
std::cout << "%" << laInst->getName() << " = getelementptr inbounds ";
|
||||||
|
|
||||||
|
auto ptrType = dynamic_cast<PointerType*>(laInst->getPointer()->getType());
|
||||||
|
printType(ptrType->getBaseType());
|
||||||
|
std::cout << ", ";
|
||||||
|
printType(laInst->getPointer()->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(laInst->getPointer());
|
||||||
|
std::cout << ", ";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < laInst->getNumIndices(); i++) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
printType(Type::getIntType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(laInst->getIndex(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kStore: {
|
||||||
|
auto storeInst = dynamic_cast<StoreInst *>(pInst);
|
||||||
|
std::cout << "store ";
|
||||||
|
printType(storeInst->getValue()->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(storeInst->getValue());
|
||||||
|
std::cout << ", ";
|
||||||
|
printType(storeInst->getPointer()->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(storeInst->getPointer());
|
||||||
|
|
||||||
|
if (storeInst->getNumIndices() > 0) {
|
||||||
|
std::cout << ", ";
|
||||||
|
for (size_t i = 0; i < storeInst->getNumIndices(); i++) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
printType(Type::getIntType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(storeInst->getIndex(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ", align 4" << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kMemset: {
|
||||||
|
auto memsetInst = dynamic_cast<MemsetInst *>(pInst);
|
||||||
|
std::cout << "call void @llvm.memset.p0.";
|
||||||
|
printType(memsetInst->getPointer()->getType());
|
||||||
|
std::cout << "(";
|
||||||
|
printType(memsetInst->getPointer()->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(memsetInst->getPointer());
|
||||||
|
std::cout << ", i8 ";
|
||||||
|
printValue(memsetInst->getValue());
|
||||||
|
std::cout << ", i32 ";
|
||||||
|
printValue(memsetInst->getSize());
|
||||||
|
std::cout << ", i1 false)" << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kPhi: {
|
||||||
|
auto phiInst = dynamic_cast<PhiInst *>(pInst);
|
||||||
|
std::cout << "%" << phiInst->getName() << " = phi ";
|
||||||
|
printType(phiInst->getType());
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < phiInst->getNumOperands(); i += 2) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
std::cout << "[ ";
|
||||||
|
printValue(phiInst->getOperand(i));
|
||||||
|
std::cout << ", %" << dynamic_cast<BasicBlock*>(phiInst->getOperand(i+1))->getName() << " ]";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Kind::kGetSubArray: {
|
||||||
|
auto getSubArrayInst = dynamic_cast<GetSubArrayInst *>(pInst);
|
||||||
|
std::cout << "%" << getSubArrayInst->getName() << " = getelementptr inbounds ";
|
||||||
|
|
||||||
|
auto ptrType = dynamic_cast<PointerType*>(getSubArrayInst->getFatherArray()->getType());
|
||||||
|
printType(ptrType->getBaseType());
|
||||||
|
std::cout << ", ";
|
||||||
|
printType(getSubArrayInst->getFatherArray()->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(getSubArrayInst->getFatherArray());
|
||||||
|
std::cout << ", ";
|
||||||
|
bool firstIndex = true;
|
||||||
|
for (auto &index : getSubArrayInst->getIndices()) {
|
||||||
|
if (!firstIndex) std::cout << ", ";
|
||||||
|
firstIndex = false;
|
||||||
|
printType(Type::getIntType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(index->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false && "Unsupported instruction kind");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
356
src/include/IR.h
356
src/include/IR.h
@@ -317,7 +317,6 @@ class ConstantValue : public Value {
|
|||||||
|
|
||||||
class Instruction;
|
class Instruction;
|
||||||
class Function;
|
class Function;
|
||||||
class Loop;
|
|
||||||
class BasicBlock;
|
class BasicBlock;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -327,11 +326,11 @@ class BasicBlock;
|
|||||||
* a terminator (branch or return). Besides, `BasicBlock` stores its arguments
|
* a terminator (branch or return). Besides, `BasicBlock` stores its arguments
|
||||||
* and records its predecessor and successor `BasicBlock`s.
|
* and records its predecessor and successor `BasicBlock`s.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class BasicBlock : public Value {
|
class BasicBlock : public Value {
|
||||||
friend class Function;
|
friend class Function;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using inst_list = std::list<std::unique_ptr<Instruction>>;
|
using inst_list = std::list<std::unique_ptr<Instruction>>;
|
||||||
using iterator = inst_list::iterator;
|
using iterator = inst_list::iterator;
|
||||||
using arg_list = std::vector<AllocaInst *>;
|
using arg_list = std::vector<AllocaInst *>;
|
||||||
@@ -339,92 +338,61 @@ class BasicBlock;
|
|||||||
using block_set = std::unordered_set<BasicBlock *>;
|
using block_set = std::unordered_set<BasicBlock *>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Function *parent; ///< 从属的函数
|
Function *parent; ///< 从属的函数
|
||||||
inst_list instructions; ///< 拥有的指令序列
|
inst_list instructions; ///< 拥有的指令序列
|
||||||
arg_list arguments; ///< 分配空间后的形式参数列表
|
arg_list arguments; ///< 分配空间后的形式参数列表
|
||||||
block_list successors; ///< 前驱列表
|
block_list successors; ///< 前驱列表
|
||||||
block_list predecessors; ///< 后继列表
|
block_list predecessors; ///< 后继列表
|
||||||
BasicBlock *idom = nullptr; ///< 直接支配结点,即支配树前驱,唯一,默认nullptr
|
bool reachable = false;
|
||||||
block_list sdoms; ///< 支配树后继,可以有多个
|
|
||||||
block_set dominants; ///< 必经结点集合
|
|
||||||
block_set dominant_frontiers; ///< 支配边界
|
|
||||||
bool reachable = false; ///< 用于表示该节点是否可达,默认不可达
|
|
||||||
Loop *loopbelong = nullptr; ///< 用来表示该块属于哪个循环,唯一,默认nullptr
|
|
||||||
int loopdepth = 0; /// < 用来表示其归属循环的深度,默认0
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BasicBlock(Function *parent, const std::string &name = "")
|
explicit BasicBlock(Function *parent, const std::string &name = "")
|
||||||
: Value(Type::getLabelType(), name), parent(parent) {}
|
: Value(Type::getLabelType(), name), parent(parent) {}
|
||||||
|
|
||||||
~BasicBlock() override {
|
~BasicBlock() override {
|
||||||
for (auto pre : predecessors) {
|
for (auto pre : predecessors) {
|
||||||
pre->removeSuccessor(this);
|
pre->removeSuccessor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto suc : successors) {
|
for (auto suc : successors) {
|
||||||
suc->removePredecessor(this);
|
suc->removePredecessor(this);
|
||||||
}
|
}
|
||||||
} ///< 基本块的析构函数,同时删除其前驱后继关系
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned getNumInstructions() const { return instructions.size(); } ///< 获取指令数量
|
|
||||||
unsigned getNumArguments() const { return arguments.size(); } ///< 获取形式参数数量
|
unsigned getNumInstructions() const { return instructions.size(); }
|
||||||
unsigned getNumPredecessors() const { return predecessors.size(); } ///< 获取前驱数量
|
unsigned getNumArguments() const { return arguments.size(); }
|
||||||
unsigned getNumSuccessors() const { return successors.size(); } ///< 获取后继数量
|
unsigned getNumPredecessors() const { return predecessors.size(); }
|
||||||
Function* getParent() const { return parent; } ///< 获取父函数
|
unsigned getNumSuccessors() const { return successors.size(); }
|
||||||
void setParent(Function *func) { parent = func; } ///< 设置父函数
|
Function* getParent() const { return parent; }
|
||||||
inst_list& getInstructions() { return instructions; } ///< 获取指令列表
|
void setParent(Function *func) { parent = func; }
|
||||||
arg_list& getArguments() { return arguments; } ///< 获取分配空间后的形式参数列表
|
inst_list& getInstructions() { return instructions; }
|
||||||
const block_list& getPredecessors() const { return predecessors; } ///< 获取前驱列表
|
arg_list& getArguments() { return arguments; }
|
||||||
block_list& getSuccessors() { return successors; } ///< 获取后继列表
|
const block_list& getPredecessors() const { return predecessors; }
|
||||||
block_set& getDominants() { return dominants; }
|
block_list& getSuccessors() { return successors; }
|
||||||
BasicBlock* getIdom() { return idom; }
|
iterator begin() { return instructions.begin(); }
|
||||||
block_list& getSdoms() { return sdoms; }
|
iterator end() { return instructions.end(); }
|
||||||
block_set& getDFs() { return dominant_frontiers; }
|
iterator terminator() { return std::prev(end()); }
|
||||||
iterator begin() { return instructions.begin(); } ///< 返回指向指令列表开头的迭代器
|
void insertArgument(AllocaInst *inst) { arguments.push_back(inst); }
|
||||||
iterator end() { return instructions.end(); } ///< 返回指向指令列表末尾的迭代器
|
|
||||||
iterator terminator() { return std::prev(end()); } ///< 基本块最后的IR
|
|
||||||
void insertArgument(AllocaInst *inst) { arguments.push_back(inst); } ///< 插入分配空间后的形式参数
|
|
||||||
void addPredecessor(BasicBlock *block) {
|
void addPredecessor(BasicBlock *block) {
|
||||||
if (std::find(predecessors.begin(), predecessors.end(), block) == predecessors.end()) {
|
if (std::find(predecessors.begin(), predecessors.end(), block) == predecessors.end()) {
|
||||||
predecessors.push_back(block);
|
predecessors.push_back(block);
|
||||||
}
|
}
|
||||||
} ///< 添加前驱
|
}
|
||||||
void addSuccessor(BasicBlock *block) {
|
void addSuccessor(BasicBlock *block) {
|
||||||
if (std::find(successors.begin(), successors.end(), block) == successors.end()) {
|
if (std::find(successors.begin(), successors.end(), block) == successors.end()) {
|
||||||
successors.push_back(block);
|
successors.push_back(block);
|
||||||
}
|
}
|
||||||
} ///< 添加后继
|
}
|
||||||
void addPredecessor(const block_list &blocks) {
|
void addPredecessor(const block_list &blocks) {
|
||||||
for (auto block : blocks) {
|
for (auto block : blocks) {
|
||||||
addPredecessor(block);
|
addPredecessor(block);
|
||||||
}
|
}
|
||||||
} ///< 添加多个前驱
|
}
|
||||||
void addSuccessor(const block_list &blocks) {
|
void addSuccessor(const block_list &blocks) {
|
||||||
for (auto block : blocks) {
|
for (auto block : blocks) {
|
||||||
addSuccessor(block);
|
addSuccessor(block);
|
||||||
}
|
}
|
||||||
} ///< 添加多个后继
|
|
||||||
void setIdom(BasicBlock *block) { idom = block; }
|
|
||||||
void addSdoms(BasicBlock *block) { sdoms.push_back(block); }
|
|
||||||
void clearSdoms() { sdoms.clear(); }
|
|
||||||
// 重载1,参数为 BasicBlock*
|
|
||||||
void addDominants(BasicBlock *block) { dominants.emplace(block); }
|
|
||||||
// 重载2,参数为 block_set
|
|
||||||
void addDominants(const block_set &blocks) { dominants.insert(blocks.begin(), blocks.end()); }
|
|
||||||
void setDominants(BasicBlock *block) {
|
|
||||||
dominants.clear();
|
|
||||||
addDominants(block);
|
|
||||||
}
|
|
||||||
void setDominants(const block_set &doms) {
|
|
||||||
dominants.clear();
|
|
||||||
addDominants(doms);
|
|
||||||
}
|
|
||||||
void setDFs(const block_set &df) {
|
|
||||||
dominant_frontiers.clear();
|
|
||||||
for (auto elem : df) {
|
|
||||||
dominant_frontiers.emplace(elem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void removePredecessor(BasicBlock *block) {
|
void removePredecessor(BasicBlock *block) {
|
||||||
auto iter = std::find(predecessors.begin(), predecessors.end(), block);
|
auto iter = std::find(predecessors.begin(), predecessors.end(), block);
|
||||||
@@ -433,7 +401,7 @@ class BasicBlock;
|
|||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
} ///< 删除前驱
|
}
|
||||||
void removeSuccessor(BasicBlock *block) {
|
void removeSuccessor(BasicBlock *block) {
|
||||||
auto iter = std::find(successors.begin(), successors.end(), block);
|
auto iter = std::find(successors.begin(), successors.end(), block);
|
||||||
if (iter != successors.end()) {
|
if (iter != successors.end()) {
|
||||||
@@ -441,7 +409,7 @@ class BasicBlock;
|
|||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
} ///< 删除后继
|
}
|
||||||
void replacePredecessor(BasicBlock *oldBlock, BasicBlock *newBlock) {
|
void replacePredecessor(BasicBlock *oldBlock, BasicBlock *newBlock) {
|
||||||
for (auto &predecessor : predecessors) {
|
for (auto &predecessor : predecessors) {
|
||||||
if (predecessor == oldBlock) {
|
if (predecessor == oldBlock) {
|
||||||
@@ -449,41 +417,16 @@ class BasicBlock;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ///< 替换前驱
|
|
||||||
// 获取支配树中该块的所有子节点,包括子节点的子节点等,迭代实现
|
|
||||||
block_list getChildren() {
|
|
||||||
std::queue<BasicBlock *> q;
|
|
||||||
block_list children;
|
|
||||||
for (auto sdom : sdoms) {
|
|
||||||
q.push(sdom);
|
|
||||||
children.push_back(sdom);
|
|
||||||
}
|
}
|
||||||
while (!q.empty()) {
|
|
||||||
auto block = q.front();
|
|
||||||
q.pop();
|
|
||||||
for (auto sdom : block->sdoms) {
|
|
||||||
q.push(sdom);
|
|
||||||
children.push_back(sdom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setreachableTrue() { reachable = true; } ///< 设置可达
|
void setreachableTrue() { reachable = true; } ///< 设置可达
|
||||||
void setreachableFalse() { reachable = false; } ///< 设置不可达
|
void setreachableFalse() { reachable = false; } ///< 设置不可达
|
||||||
bool getreachable() { return reachable; } ///< 返回可达状态
|
bool getreachable() { return reachable; } ///< 返回可达状态
|
||||||
|
|
||||||
static void conectBlocks(BasicBlock *prev, BasicBlock *next) {
|
static void conectBlocks(BasicBlock *prev, BasicBlock *next) {
|
||||||
prev->addSuccessor(next);
|
prev->addSuccessor(next);
|
||||||
next->addPredecessor(prev);
|
next->addPredecessor(prev);
|
||||||
} ///< 连接两个块,即设置两个基本块的前驱后继关系
|
}
|
||||||
void setLoop(Loop *loop2set) { loopbelong = loop2set; } ///< 设置所属循环
|
void removeInst(iterator pos) { instructions.erase(pos); }
|
||||||
Loop* getLoop() { return loopbelong; } ///< 获得所属循环
|
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block);
|
||||||
void setLoopDepth(int loopdepth2set) { loopdepth = loopdepth2set; } ///< 设置循环深度
|
|
||||||
int getLoopDepth() { return loopdepth; } ///< 获得其在循环的深度
|
|
||||||
void removeInst(iterator pos) { instructions.erase(pos); } ///< 删除指令
|
|
||||||
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block); ///< 移动指令
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! User is the abstract base type of `Value` types which use other `Value` as
|
//! User is the abstract base type of `Value` types which use other `Value` as
|
||||||
@@ -1198,109 +1141,11 @@ public:
|
|||||||
|
|
||||||
class GlobalValue;
|
class GlobalValue;
|
||||||
|
|
||||||
// 循环类
|
|
||||||
class Loop {
|
|
||||||
public:
|
|
||||||
using block_list = std::vector<BasicBlock *>;
|
|
||||||
using block_set = std::unordered_set<BasicBlock *>;
|
|
||||||
using Loop_list = std::vector<Loop *>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Function *parent; // 所属函数
|
|
||||||
block_list blocksInLoop; // 循环内的基本块
|
|
||||||
BasicBlock *preheaderBlock = nullptr; // 前驱块
|
|
||||||
BasicBlock *headerBlock = nullptr; // 循环头
|
|
||||||
block_list latchBlock; // 回边块
|
|
||||||
block_set exitingBlocks; // 退出块
|
|
||||||
block_set exitBlocks; // 退出目标块
|
|
||||||
Loop *parentloop = nullptr; // 父循环
|
|
||||||
Loop_list subLoops; // 子循环
|
|
||||||
size_t loopID; // 循环ID
|
|
||||||
unsigned loopDepth; // 循环深度
|
|
||||||
|
|
||||||
Instruction *indCondVar = nullptr; // 循环条件变量
|
|
||||||
Instruction::Kind IcmpKind; // 比较类型
|
|
||||||
Value *indEnd = nullptr; // 循环结束值
|
|
||||||
AllocaInst *IndPhi = nullptr; // 循环变量
|
|
||||||
|
|
||||||
ConstantValue *indBegin = nullptr; // 循环起始值
|
|
||||||
ConstantValue *indStep = nullptr; // 循环步长
|
|
||||||
|
|
||||||
std::set<GlobalValue *> GlobalValuechange; // 循环内改变的全局变量
|
|
||||||
|
|
||||||
int StepType = 0; // 循环步长类型
|
|
||||||
bool parallelable = false; // 是否可并行
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Loop(BasicBlock *header, const std::string &name = "")
|
|
||||||
: headerBlock(header) {
|
|
||||||
blocksInLoop.push_back(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setloopID() {
|
|
||||||
static unsigned loopCount = 0;
|
|
||||||
loopCount = loopCount + 1;
|
|
||||||
loopID = loopCount;
|
|
||||||
}
|
|
||||||
ConstantValue* getindBegin() { return indBegin; } ///< 获得循环开始值
|
|
||||||
ConstantValue* getindStep() { return indStep; } ///< 获得循环步长
|
|
||||||
void setindBegin(ConstantValue *indBegin2set) { indBegin = indBegin2set; } ///< 设置循环开始值
|
|
||||||
void setindStep(ConstantValue *indStep2set) { indStep = indStep2set; } ///< 设置循环步长
|
|
||||||
void setStepType(int StepType2Set) { StepType = StepType2Set; } ///< 设置循环变量规则
|
|
||||||
int getStepType() { return StepType; } ///< 获得循环变量规则
|
|
||||||
size_t getLoopID() { return loopID; }
|
|
||||||
|
|
||||||
BasicBlock* getHeader() const { return headerBlock; }
|
|
||||||
BasicBlock* getPreheaderBlock() const { return preheaderBlock; }
|
|
||||||
block_list& getLatchBlocks() { return latchBlock; }
|
|
||||||
block_set& getExitingBlocks() { return exitingBlocks; }
|
|
||||||
block_set& getExitBlocks() { return exitBlocks; }
|
|
||||||
Loop* getParentLoop() const { return parentloop; }
|
|
||||||
void setParentLoop(Loop *parent) { parentloop = parent; }
|
|
||||||
void addBasicBlock(BasicBlock *bb) { blocksInLoop.push_back(bb); }
|
|
||||||
void addSubLoop(Loop *loop) { subLoops.push_back(loop); }
|
|
||||||
void setLoopDepth(unsigned depth) { loopDepth = depth; }
|
|
||||||
block_list& getBasicBlocks() { return blocksInLoop; }
|
|
||||||
Loop_list& getSubLoops() { return subLoops; }
|
|
||||||
unsigned getLoopDepth() const { return loopDepth; }
|
|
||||||
|
|
||||||
bool isLoopContainsBasicBlock(BasicBlock *bb) const {
|
|
||||||
return std::find(blocksInLoop.begin(), blocksInLoop.end(), bb) != blocksInLoop.end();
|
|
||||||
} ///< 判断输入块是否在该循环内
|
|
||||||
|
|
||||||
void addExitingBlock(BasicBlock *bb) { exitingBlocks.insert(bb); }
|
|
||||||
void addExitBlock(BasicBlock *bb) { exitBlocks.insert(bb); }
|
|
||||||
void addLatchBlock(BasicBlock *bb) { latchBlock.push_back(bb); }
|
|
||||||
void setPreheaderBlock(BasicBlock *bb) { preheaderBlock = bb; }
|
|
||||||
|
|
||||||
void setIndexCondInstr(Instruction *instr) { indCondVar = instr; }
|
|
||||||
void setIcmpKind(Instruction::Kind kind) { IcmpKind = kind; }
|
|
||||||
Instruction::Kind getIcmpKind() const { return IcmpKind; }
|
|
||||||
|
|
||||||
bool isSimpleLoopInvariant(Value *value) ; ///< 判断是否为简单循环不变量,若其在loop中,则不是。
|
|
||||||
|
|
||||||
void setIndEnd(Value *value) { indEnd = value; }
|
|
||||||
void setIndPhi(AllocaInst *phi) { IndPhi = phi; }
|
|
||||||
Value* getIndEnd() const { return indEnd; }
|
|
||||||
AllocaInst* getIndPhi() const { return IndPhi; }
|
|
||||||
Instruction* getIndCondVar() const { return indCondVar; }
|
|
||||||
|
|
||||||
void addGlobalValuechange(GlobalValue *globalvaluechange2add) {
|
|
||||||
GlobalValuechange.insert(globalvaluechange2add);
|
|
||||||
} ///<添加在循环中改变的全局变量
|
|
||||||
std::set<GlobalValue *>& getGlobalValuechange() {
|
|
||||||
return GlobalValuechange;
|
|
||||||
} ///<获得在循环中改变的所有全局变量
|
|
||||||
|
|
||||||
void setParallelable(bool flag) { parallelable = flag; }
|
|
||||||
bool isParallelable() const { return parallelable; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Module;
|
class Module;
|
||||||
//! Function definition
|
//! Function definitionclass
|
||||||
class Function : public Value {
|
class Function : public Value {
|
||||||
friend class Module;
|
friend class Module;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Function(Module *parent, Type *type, const std::string &name) : Value(type, name), parent(parent) {
|
Function(Module *parent, Type *type, const std::string &name) : Value(type, name), parent(parent) {
|
||||||
blocks.emplace_back(new BasicBlock(this));
|
blocks.emplace_back(new BasicBlock(this));
|
||||||
@@ -1308,9 +1153,6 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using block_list = std::list<std::unique_ptr<BasicBlock>>;
|
using block_list = std::list<std::unique_ptr<BasicBlock>>;
|
||||||
using Loop_list = std::list<std::unique_ptr<Loop>>;
|
|
||||||
|
|
||||||
// 函数优化属性标识符
|
|
||||||
enum FunctionAttribute : uint64_t {
|
enum FunctionAttribute : uint64_t {
|
||||||
PlaceHolder = 0x0UL,
|
PlaceHolder = 0x0UL,
|
||||||
Pure = 0x1UL << 0,
|
Pure = 0x1UL << 0,
|
||||||
@@ -1322,167 +1164,47 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
Module *parent; ///< 函数的父模块
|
Module *parent; ///< 函数的父模块
|
||||||
block_list blocks; ///< 函数包含的基本块列表
|
block_list blocks; ///< 函数包含的基本块列表
|
||||||
Loop_list loops; ///< 函数包含的循环列表
|
|
||||||
Loop_list topLoops; ///< 函数所包含的顶层循环;
|
|
||||||
std::list<std::unique_ptr<AllocaInst>> indirectAllocas; ///< 函数中mem2reg引入的间接分配的内存
|
|
||||||
|
|
||||||
FunctionAttribute attribute = PlaceHolder; ///< 函数属性
|
FunctionAttribute attribute = PlaceHolder; ///< 函数属性
|
||||||
std::set<Function *> callees; ///< 函数调用的函数集合
|
std::set<Function *> callees; ///< 函数调用的函数集合
|
||||||
|
|
||||||
std::unordered_map<BasicBlock *, Loop *> basicblock2Loop;
|
|
||||||
std::unordered_map<Value *, BasicBlock *> value2AllocBlocks; ///< value -- alloc block mapping
|
|
||||||
std::unordered_map<Value *, std::unordered_map<BasicBlock *, int>>
|
|
||||||
value2DefBlocks; //< value -- define blocks mapping
|
|
||||||
std::unordered_map<Value *, std::unordered_map<BasicBlock *, int>> value2UseBlocks; //< value -- use blocks mapping
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static unsigned getcloneIndex() {
|
static unsigned getcloneIndex() {
|
||||||
static unsigned cloneIndex = 0;
|
static unsigned cloneIndex = 0;
|
||||||
cloneIndex += 1;
|
cloneIndex += 1;
|
||||||
return cloneIndex - 1;
|
return cloneIndex - 1;
|
||||||
}
|
}
|
||||||
Function* clone(const std::string &suffix = "_" + std::to_string(getcloneIndex()) + "@") const; ///< 复制函数
|
Function* clone(const std::string &suffix = "_" + std::to_string(getcloneIndex()) + "@") const;
|
||||||
const std::set<Function *>& getCallees() { return callees; }
|
const std::set<Function *>& getCallees() { return callees; }
|
||||||
void addCallee(Function *callee) { callees.insert(callee); }
|
void addCallee(Function *callee) { callees.insert(callee); }
|
||||||
void removeCallee(Function *callee) { callees.erase(callee); }
|
void removeCallee(Function *callee) { callees.erase(callee); }
|
||||||
void clearCallees() { callees.clear(); }
|
void clearCallees() { callees.clear(); }
|
||||||
std::set<Function *> getCalleesWithNoExternalAndSelf();
|
std::set<Function *> getCalleesWithNoExternalAndSelf();
|
||||||
FunctionAttribute getAttribute() const { return attribute; } ///< 获取函数属性
|
FunctionAttribute getAttribute() const { return attribute; }
|
||||||
void setAttribute(FunctionAttribute attr) {
|
void setAttribute(FunctionAttribute attr) {
|
||||||
attribute = static_cast<FunctionAttribute>(attribute | attr);
|
attribute = static_cast<FunctionAttribute>(attribute | attr);
|
||||||
} ///< 设置函数属性
|
|
||||||
void clearAttribute() { attribute = PlaceHolder; } ///< 清楚所有函数属性,只保留PlaceHolder
|
|
||||||
Loop* getLoopOfBasicBlock(BasicBlock *bb) {
|
|
||||||
return basicblock2Loop.count(bb) != 0 ? basicblock2Loop[bb] : nullptr;
|
|
||||||
} ///< 获得块所在循环
|
|
||||||
unsigned getLoopDepthByBlock(BasicBlock *basicblock2Check) {
|
|
||||||
if (getLoopOfBasicBlock(basicblock2Check) != nullptr) {
|
|
||||||
auto loop = getLoopOfBasicBlock(basicblock2Check);
|
|
||||||
return loop->getLoopDepth();
|
|
||||||
}
|
}
|
||||||
return static_cast<unsigned>(0);
|
void clearAttribute() { attribute = PlaceHolder; }
|
||||||
} ///< 通过块,获得其所在循环深度
|
Type* getReturnType() const { return getType()->as<FunctionType>()->getReturnType(); }
|
||||||
void addBBToLoop(BasicBlock *bb, Loop *LoopToadd) { basicblock2Loop[bb] = LoopToadd; } ///< 添加块与循环的映射
|
auto getParamTypes() const { return getType()->as<FunctionType>()->getParamTypes(); }
|
||||||
std::unordered_map<BasicBlock *, Loop *>& getBBToLoopRef() {
|
auto getBasicBlocks() { return make_range(blocks); }
|
||||||
return basicblock2Loop;
|
|
||||||
} ///< 获得块-循环映射表
|
|
||||||
// auto getNewLoopPtr(BasicBlock *header) -> Loop * { return new Loop(header); }
|
|
||||||
Type* getReturnType() const { return getType()->as<FunctionType>()->getReturnType(); } ///< 获取返回值类型
|
|
||||||
auto getParamTypes() const { return getType()->as<FunctionType>()->getParamTypes(); } ///< 获取形式参数类型列表
|
|
||||||
auto getBasicBlocks() { return make_range(blocks); } ///< 获取基本块列表
|
|
||||||
block_list& getBasicBlocks_NoRange() { return blocks; }
|
block_list& getBasicBlocks_NoRange() { return blocks; }
|
||||||
BasicBlock* getEntryBlock() { return blocks.front().get(); } ///< 获取入口块
|
BasicBlock* getEntryBlock() { return blocks.front().get(); }
|
||||||
void removeBasicBlock(BasicBlock *blockToRemove) {
|
void removeBasicBlock(BasicBlock *blockToRemove) {
|
||||||
auto is_same_ptr = [blockToRemove](const std::unique_ptr<BasicBlock> &ptr) { return ptr.get() == blockToRemove; };
|
auto is_same_ptr = [blockToRemove](const std::unique_ptr<BasicBlock> &ptr) { return ptr.get() == blockToRemove; };
|
||||||
blocks.remove_if(is_same_ptr);
|
blocks.remove_if(is_same_ptr);
|
||||||
// blocks.erase(std::remove_if(blocks.begin(), blocks.end(), is_same_ptr), blocks.end());
|
}
|
||||||
} ///< 将该块从function的blocks中删除
|
|
||||||
// auto getBasicBlocks_NoRange() -> block_list & { return blocks; }
|
|
||||||
BasicBlock* addBasicBlock(const std::string &name = "") {
|
BasicBlock* addBasicBlock(const std::string &name = "") {
|
||||||
blocks.emplace_back(new BasicBlock(this, name));
|
blocks.emplace_back(new BasicBlock(this, name));
|
||||||
return blocks.back().get();
|
return blocks.back().get();
|
||||||
} ///< 添加新的基本块
|
}
|
||||||
BasicBlock* addBasicBlock(BasicBlock *block) {
|
BasicBlock* addBasicBlock(BasicBlock *block) {
|
||||||
blocks.emplace_back(block);
|
blocks.emplace_back(block);
|
||||||
return block;
|
return block;
|
||||||
} ///< 添加基本块到blocks中
|
}
|
||||||
BasicBlock* addBasicBlockFront(BasicBlock *block) {
|
BasicBlock* addBasicBlockFront(BasicBlock *block) {
|
||||||
blocks.emplace_front(block);
|
blocks.emplace_front(block);
|
||||||
return block;
|
return block;
|
||||||
} // 从前端插入新的基本块
|
|
||||||
/** value -- alloc blocks mapping */
|
|
||||||
void addValue2AllocBlocks(Value *value, BasicBlock *block) {
|
|
||||||
value2AllocBlocks[value] = block;
|
|
||||||
} ///< 添加value -- alloc block mapping
|
|
||||||
BasicBlock* getAllocBlockByValue(Value *value) {
|
|
||||||
if (value2AllocBlocks.count(value) > 0) {
|
|
||||||
return value2AllocBlocks[value];
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
};
|
||||||
} ///< 通过value获取alloc block
|
|
||||||
std::unordered_map<Value *, BasicBlock *>& getValue2AllocBlocks() {
|
|
||||||
return value2AllocBlocks;
|
|
||||||
} ///< 获取所有value -- alloc block mappings
|
|
||||||
void removeValue2AllocBlock(Value *value) {
|
|
||||||
value2AllocBlocks.erase(value);
|
|
||||||
} ///< 删除value -- alloc block mapping
|
|
||||||
/** value -- define blocks mapping */
|
|
||||||
void addValue2DefBlocks(Value *value, BasicBlock *block) {
|
|
||||||
++value2DefBlocks[value][block];
|
|
||||||
} ///< 添加value -- define block mapping
|
|
||||||
// keep in mind that the return is not a reference.
|
|
||||||
std::unordered_set<BasicBlock *> getDefBlocksByValue(Value *value) {
|
|
||||||
std::unordered_set<BasicBlock *> blocks;
|
|
||||||
if (value2DefBlocks.count(value) > 0) {
|
|
||||||
for (const auto &pair : value2DefBlocks[value]) {
|
|
||||||
blocks.insert(pair.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return blocks;
|
|
||||||
} ///< 通过value获取define blocks
|
|
||||||
std::unordered_map<Value *, std::unordered_map<BasicBlock *, int>>& getValue2DefBlocks() {
|
|
||||||
return value2DefBlocks;
|
|
||||||
} ///< 获取所有value -- define blocks mappings
|
|
||||||
bool removeValue2DefBlock(Value *value, BasicBlock *block) {
|
|
||||||
bool changed = false;
|
|
||||||
if (--value2DefBlocks[value][block] == 0) {
|
|
||||||
value2DefBlocks[value].erase(block);
|
|
||||||
if (value2DefBlocks[value].empty()) {
|
|
||||||
value2DefBlocks.erase(value);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
} ///< 删除value -- define block mapping
|
|
||||||
std::unordered_set<Value *> getValuesOfDefBlock() {
|
|
||||||
std::unordered_set<Value *> values;
|
|
||||||
for (const auto &pair : value2DefBlocks) {
|
|
||||||
values.insert(pair.first);
|
|
||||||
}
|
|
||||||
return values;
|
|
||||||
} ///< 获取所有定义过的value
|
|
||||||
/** value -- use blocks mapping */
|
|
||||||
void addValue2UseBlocks(Value *value, BasicBlock *block) {
|
|
||||||
++value2UseBlocks[value][block];
|
|
||||||
} ///< 添加value -- use block mapping
|
|
||||||
// keep in mind that the return is not a reference.
|
|
||||||
std::unordered_set<BasicBlock *> getUseBlocksByValue(Value *value) {
|
|
||||||
std::unordered_set<BasicBlock *> blocks;
|
|
||||||
if (value2UseBlocks.count(value) > 0) {
|
|
||||||
for (const auto &pair : value2UseBlocks[value]) {
|
|
||||||
blocks.insert(pair.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return blocks;
|
|
||||||
} ///< 通过value获取use blocks
|
|
||||||
std::unordered_map<Value *, std::unordered_map<BasicBlock *, int>>& getValue2UseBlocks() {
|
|
||||||
return value2UseBlocks;
|
|
||||||
} ///< 获取所有value -- use blocks mappings
|
|
||||||
bool removeValue2UseBlock(Value *value, BasicBlock *block) {
|
|
||||||
bool changed = false;
|
|
||||||
if (--value2UseBlocks[value][block] == 0) {
|
|
||||||
value2UseBlocks[value].erase(block);
|
|
||||||
if (value2UseBlocks[value].empty()) {
|
|
||||||
value2UseBlocks.erase(value);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
} ///< 删除value -- use block mapping
|
|
||||||
void addIndirectAlloca(AllocaInst *alloca) { indirectAllocas.emplace_back(alloca); } ///< 添加间接分配
|
|
||||||
std::list<std::unique_ptr<AllocaInst>>& getIndirectAllocas() {
|
|
||||||
return indirectAllocas;
|
|
||||||
} ///< 获取间接分配列表
|
|
||||||
|
|
||||||
/** loop -- begin */
|
|
||||||
|
|
||||||
void addLoop(Loop *loop) { loops.emplace_back(loop); } ///< 添加循环(非顶层)
|
|
||||||
void addTopLoop(Loop *loop) { topLoops.emplace_back(loop); } ///< 添加顶层循环
|
|
||||||
Loop_list& getLoops() { return loops; } ///< 获得循环(非顶层)
|
|
||||||
Loop_list& getTopLoops() { return topLoops; } ///< 获得顶层循环
|
|
||||||
/** loop -- end */
|
|
||||||
|
|
||||||
}; // class Function
|
|
||||||
|
|
||||||
//! Global value declared at file scope
|
//! Global value declared at file scope
|
||||||
class GlobalValue : public User, public LVal {
|
class GlobalValue : public User, public LVal {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class IRBuilder {
|
|||||||
std::string newName;
|
std::string newName;
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "%" << tmpIndex;
|
ss << tmpIndex;
|
||||||
newName = ss.str();
|
newName = ss.str();
|
||||||
tmpIndex++;
|
tmpIndex++;
|
||||||
} else {
|
} else {
|
||||||
@@ -136,7 +136,7 @@ class IRBuilder {
|
|||||||
std::string newName;
|
std::string newName;
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "%" << tmpIndex;
|
ss << tmpIndex;
|
||||||
newName = ss.str();
|
newName = ss.str();
|
||||||
tmpIndex++;
|
tmpIndex++;
|
||||||
} else {
|
} else {
|
||||||
@@ -221,7 +221,7 @@ class IRBuilder {
|
|||||||
std::string newName;
|
std::string newName;
|
||||||
if (name.empty() && callee->getReturnType() != Type::getVoidType()) {
|
if (name.empty() && callee->getReturnType() != Type::getVoidType()) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "%" << tmpIndex;
|
ss << tmpIndex;
|
||||||
newName = ss.str();
|
newName = ss.str();
|
||||||
tmpIndex++;
|
tmpIndex++;
|
||||||
} else {
|
} else {
|
||||||
@@ -268,7 +268,7 @@ class IRBuilder {
|
|||||||
std::string newName;
|
std::string newName;
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "%" << tmpIndex;
|
ss << tmpIndex;
|
||||||
newName = ss.str();
|
newName = ss.str();
|
||||||
tmpIndex++;
|
tmpIndex++;
|
||||||
} else {
|
} else {
|
||||||
@@ -284,7 +284,7 @@ class IRBuilder {
|
|||||||
std::string newName;
|
std::string newName;
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "%" << tmpIndex;
|
ss << tmpIndex;
|
||||||
newName = ss.str();
|
newName = ss.str();
|
||||||
tmpIndex++;
|
tmpIndex++;
|
||||||
} else {
|
} else {
|
||||||
@@ -315,7 +315,7 @@ class IRBuilder {
|
|||||||
|
|
||||||
auto fatherArrayValue = dynamic_cast<Value *>(fatherArray);
|
auto fatherArrayValue = dynamic_cast<Value *>(fatherArray);
|
||||||
auto childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block, childArrayName);
|
auto childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block, childArrayName);
|
||||||
auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block, name);
|
auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block, childArrayName);
|
||||||
assert(inst);
|
assert(inst);
|
||||||
block->getInstructions().emplace(position, inst);
|
block->getInstructions().emplace(position, inst);
|
||||||
return inst;
|
return inst;
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "SysYBaseVisitor.h"
|
|
||||||
#include "SysYParser.h"
|
|
||||||
#include "IR.h" // 引入 SysY IR 头文件
|
|
||||||
#include "IRBuilder.h"
|
|
||||||
#include <sstream>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <stack>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class LLVMIRGenerator : public SysYBaseVisitor {
|
|
||||||
public:
|
|
||||||
// 生成 IR(文本和数据结构)
|
|
||||||
std::string generateIR(SysYParser::CompUnitContext* unit);
|
|
||||||
|
|
||||||
// 获取文本格式的 LLVM IR
|
|
||||||
std::string getIR() const { return irStream.str(); }
|
|
||||||
|
|
||||||
// 获取 SysY IR 数据结构
|
|
||||||
sysy::Module* getModule() const { return module.get(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// 文本输出相关
|
|
||||||
std::stringstream irStream;
|
|
||||||
int tempCounter = 0; // 临时变量计数器
|
|
||||||
std::string currentVarType; // 当前变量类型(文本 IR 用)
|
|
||||||
|
|
||||||
// 符号表:映射变量名到 {分配地址/寄存器, 类型}(文本 IR)
|
|
||||||
std::map<std::string, std::pair<std::string, std::string>> symbolTable;
|
|
||||||
// 临时变量表:映射临时变量名到类型(文本 IR)
|
|
||||||
std::map<std::string, std::string> tmpTable;
|
|
||||||
std::vector<std::string> globalVars; // 全局变量列表(文本 IR)
|
|
||||||
|
|
||||||
// SysY IR 数据结构
|
|
||||||
std::unique_ptr<sysy::Module> module; // SysY IR 模块
|
|
||||||
// 符号表:映射变量名到 SysY IR 的 Value 指针
|
|
||||||
std::map<std::string, sysy::Value*> irSymbolTable;
|
|
||||||
// 临时变量表:映射临时变量名到 SysY IR 的 Value 指针
|
|
||||||
std::map<std::string, sysy::Value*> irTmpTable;
|
|
||||||
|
|
||||||
// 当前上下文
|
|
||||||
std::string currentFunction; // 当前函数名(文本 IR)
|
|
||||||
std::string currentReturnType; // 当前函数返回类型(文本 IR)
|
|
||||||
sysy::Function* currentIRFunction = nullptr; // 当前 SysY IR 函数
|
|
||||||
sysy::BasicBlock* currentIRBlock = nullptr; // 当前 SysY IR 基本块
|
|
||||||
|
|
||||||
// 循环控制
|
|
||||||
std::vector<std::string> breakStack; // break 标签栈(文本 IR)
|
|
||||||
std::vector<std::string> continueStack; // continue 标签栈(文本 IR)
|
|
||||||
bool hasReturn = false; // 是否有返回语句(文本 IR)
|
|
||||||
|
|
||||||
struct LoopLabels {
|
|
||||||
std::string breakLabel; // break 跳转目标标签(文本 IR)
|
|
||||||
std::string continueLabel; // continue 跳转目标标签(文本 IR)
|
|
||||||
sysy::BasicBlock* irBreakBlock = nullptr; // break 跳转目标块(SysY IR)
|
|
||||||
sysy::BasicBlock* irContinueBlock = nullptr; // continue 跳转目标块(SysY IR)
|
|
||||||
};
|
|
||||||
std::stack<LoopLabels> loopStack; // 管理循环的 break 和 continue 标签
|
|
||||||
|
|
||||||
bool inFunction = false; // 标记是否在函数内部
|
|
||||||
|
|
||||||
// 辅助函数(文本 IR)
|
|
||||||
std::string getNextTemp(); // 获取下一个临时变量名
|
|
||||||
std::string getLLVMType(const std::string& type); // 转换 SysY 类型到 LLVM 类型
|
|
||||||
|
|
||||||
// 辅助函数(SysY IR)
|
|
||||||
sysy::Type* getIRType(const std::string& type); // 转换 SysY 类型到 SysY IR 类型
|
|
||||||
std::string getIRTempName(); // 获取 SysY IR 临时变量名
|
|
||||||
void setIRPosition(sysy::BasicBlock* block); // 设置当前 IR 插入点
|
|
||||||
|
|
||||||
// 访问方法
|
|
||||||
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
|
|
||||||
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
|
|
||||||
std::any visitVarDecl(SysYParser::VarDeclContext* ctx) override;
|
|
||||||
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
|
|
||||||
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
|
|
||||||
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
|
|
||||||
std::any visitLValue(SysYParser::LValueContext* ctx) override;
|
|
||||||
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
|
|
||||||
std::any visitPrimExp(SysYParser::PrimExpContext* ctx) override;
|
|
||||||
std::any visitParenExp(SysYParser::ParenExpContext* ctx) override;
|
|
||||||
std::any visitNumber(SysYParser::NumberContext* ctx) override;
|
|
||||||
std::any visitString(SysYParser::StringContext* ctx) override;
|
|
||||||
std::any visitCall(SysYParser::CallContext* ctx) override;
|
|
||||||
std::any visitUnExp(SysYParser::UnExpContext* ctx) override;
|
|
||||||
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
|
|
||||||
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
|
|
||||||
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
|
|
||||||
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
|
|
||||||
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
|
|
||||||
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
|
|
||||||
std::any visitAssignStmt(SysYParser::AssignStmtContext* ctx) override;
|
|
||||||
std::any visitIfStmt(SysYParser::IfStmtContext* ctx) override;
|
|
||||||
std::any visitWhileStmt(SysYParser::WhileStmtContext* ctx) override;
|
|
||||||
std::any visitBreakStmt(SysYParser::BreakStmtContext* ctx) override;
|
|
||||||
std::any visitContinueStmt(SysYParser::ContinueStmtContext* ctx) override;
|
|
||||||
std::any visitReturnStmt(SysYParser::ReturnStmtContext* ctx) override;
|
|
||||||
};
|
|
||||||
0
src/include/Mem2Reg.h
Normal file
0
src/include/Mem2Reg.h
Normal file
@@ -0,0 +1,403 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IR.h"
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
// 前向声明
|
||||||
|
|
||||||
|
class Loop;
|
||||||
|
// 基本块分析信息类
|
||||||
|
class BlockAnalysisInfo {
|
||||||
|
|
||||||
|
public:
|
||||||
|
using block_list = std::vector<BasicBlock*>;
|
||||||
|
using block_set = std::unordered_set<BasicBlock*>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// 支配树相关
|
||||||
|
int domdepth = 0; ///< 支配节点所在深度
|
||||||
|
BasicBlock* idom = nullptr; ///< 直接支配结点
|
||||||
|
block_list sdoms; ///< 支配树后继
|
||||||
|
block_set dominants; ///< 必经结点集合
|
||||||
|
block_set dominant_frontiers; ///< 支配边界
|
||||||
|
|
||||||
|
// 后续添加循环分析相关
|
||||||
|
// Loop* loopbelong = nullptr; ///< 所属循环
|
||||||
|
// int loopdepth = 0; ///< 循环深度
|
||||||
|
|
||||||
|
public:
|
||||||
|
// getterface
|
||||||
|
const int getDomDepth() const { return domdepth; }
|
||||||
|
const BasicBlock* getIdom() const { return idom; }
|
||||||
|
const block_list& getSdoms() const { return sdoms; }
|
||||||
|
const block_set& getDominants() const { return dominants; }
|
||||||
|
const block_set& getDomFrontiers() const { return dominant_frontiers; }
|
||||||
|
|
||||||
|
// 支配树操作
|
||||||
|
void setDomDepth(int depth) { domdepth = depth; }
|
||||||
|
void setIdom(BasicBlock* block) { idom = block; }
|
||||||
|
void addSdoms(BasicBlock* block) { sdoms.push_back(block); }
|
||||||
|
void clearSdoms() { sdoms.clear(); }
|
||||||
|
void removeSdoms(BasicBlock* block) {
|
||||||
|
sdoms.erase(std::remove(sdoms.begin(), sdoms.end(), block), sdoms.end());
|
||||||
|
}
|
||||||
|
void addDominants(BasicBlock* block) { dominants.emplace(block); }
|
||||||
|
void addDominants(const block_set& blocks) { dominants.insert(blocks.begin(), blocks.end()); }
|
||||||
|
void setDominants(BasicBlock* block) {
|
||||||
|
dominants.clear();
|
||||||
|
addDominants(block);
|
||||||
|
}
|
||||||
|
void setDominants(const block_set& doms) {
|
||||||
|
dominants = doms;
|
||||||
|
}
|
||||||
|
void setDomFrontiers(const block_set& df) {
|
||||||
|
dominant_frontiers = df;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO:循环分析操作方法
|
||||||
|
|
||||||
|
// 清空所有分析信息
|
||||||
|
void clear() {
|
||||||
|
domdepth = -1;
|
||||||
|
idom = nullptr;
|
||||||
|
sdoms.clear();
|
||||||
|
dominants.clear();
|
||||||
|
dominant_frontiers.clear();
|
||||||
|
// loopbelong = nullptr;
|
||||||
|
// loopdepth = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 函数分析信息类
|
||||||
|
class FunctionAnalysisInfo {
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 函数属性
|
||||||
|
enum FunctionAttribute : uint64_t {
|
||||||
|
PlaceHolder = 0x0UL,
|
||||||
|
Pure = 0x1UL << 0,
|
||||||
|
SelfRecursive = 0x1UL << 1,
|
||||||
|
SideEffect = 0x1UL << 2,
|
||||||
|
NoPureCauseMemRead = 0x1UL << 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// 数据结构
|
||||||
|
using Loop_list = std::list<std::unique_ptr<Loop>>;
|
||||||
|
using block_loop_map = std::unordered_map<BasicBlock*, Loop*>;
|
||||||
|
using value_block_map = std::unordered_map<Value*, BasicBlock*>;
|
||||||
|
using value_block_count_map = std::unordered_map<Value*, std::unordered_map<BasicBlock*, int>>;
|
||||||
|
|
||||||
|
// 分析数据
|
||||||
|
FunctionAttribute attribute = PlaceHolder; ///< 函数属性
|
||||||
|
std::set<Function*> callees; ///< 函数调用集合
|
||||||
|
Loop_list loops; ///< 所有循环
|
||||||
|
Loop_list topLoops; ///< 顶层循环
|
||||||
|
block_loop_map basicblock2Loop; ///< 基本块到循环映射
|
||||||
|
std::list<std::unique_ptr<AllocaInst>> indirectAllocas; ///< 间接分配内存
|
||||||
|
|
||||||
|
// 值定义/使用信息
|
||||||
|
value_block_map value2AllocBlocks; ///< 值分配位置映射
|
||||||
|
value_block_count_map value2DefBlocks; ///< 值定义位置映射
|
||||||
|
value_block_count_map value2UseBlocks; ///< 值使用位置映射
|
||||||
|
|
||||||
|
// 函数属性操作
|
||||||
|
FunctionAttribute getAttribute() const { return attribute; }
|
||||||
|
void setAttribute(FunctionAttribute attr) { attribute = static_cast<FunctionAttribute>(attribute | attr); }
|
||||||
|
void clearAttribute() { attribute = PlaceHolder; }
|
||||||
|
|
||||||
|
// 调用关系操作
|
||||||
|
void addCallee(Function* callee) { callees.insert(callee); }
|
||||||
|
void removeCallee(Function* callee) { callees.erase(callee); }
|
||||||
|
void clearCallees() { callees.clear(); }
|
||||||
|
|
||||||
|
// 循环分析操作
|
||||||
|
Loop* getLoopOfBasicBlock(BasicBlock* bb) {
|
||||||
|
auto it = basicblock2Loop.find(bb);
|
||||||
|
return it != basicblock2Loop.end() ? it->second : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addBBToLoop(BasicBlock* bb, Loop* loop) { basicblock2Loop[bb] = loop; }
|
||||||
|
|
||||||
|
unsigned getLoopDepthByBlock(BasicBlock* bb) {
|
||||||
|
Loop* loop = getLoopOfBasicBlock(bb);
|
||||||
|
return loop ? loop->getLoopDepth() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 值-块映射操作
|
||||||
|
void addValue2AllocBlocks(Value* value, BasicBlock* block) { value2AllocBlocks[value] = block; }
|
||||||
|
|
||||||
|
BasicBlock* getAllocBlockByValue(Value* value) {
|
||||||
|
auto it = value2AllocBlocks.find(value);
|
||||||
|
return it != value2AllocBlocks.end() ? it->second : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 值定义/使用操作
|
||||||
|
void addValue2DefBlocks(Value* value, BasicBlock* block) { ++value2DefBlocks[value][block]; }
|
||||||
|
void addValue2UseBlocks(Value* value, BasicBlock* block) { ++value2UseBlocks[value][block]; }
|
||||||
|
|
||||||
|
// 间接分配操作
|
||||||
|
void addIndirectAlloca(AllocaInst* alloca) { indirectAllocas.emplace_back(alloca); }
|
||||||
|
|
||||||
|
// 清空所有分析信息
|
||||||
|
void clear() {
|
||||||
|
attribute = PlaceHolder;
|
||||||
|
callees.clear();
|
||||||
|
loops.clear();
|
||||||
|
topLoops.clear();
|
||||||
|
basicblock2Loop.clear();
|
||||||
|
indirectAllocas.clear();
|
||||||
|
value2AllocBlocks.clear();
|
||||||
|
value2DefBlocks.clear();
|
||||||
|
value2UseBlocks.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 循环类 - 未实现优化
|
||||||
|
class Loop {
|
||||||
|
public:
|
||||||
|
using block_list = std::vector<BasicBlock *>;
|
||||||
|
using block_set = std::unordered_set<BasicBlock *>;
|
||||||
|
using Loop_list = std::vector<Loop *>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Function *parent; // 所属函数
|
||||||
|
block_list blocksInLoop; // 循环内的基本块
|
||||||
|
BasicBlock *preheaderBlock = nullptr; // 前驱块
|
||||||
|
BasicBlock *headerBlock = nullptr; // 循环头
|
||||||
|
block_list latchBlock; // 回边块
|
||||||
|
block_set exitingBlocks; // 退出块
|
||||||
|
block_set exitBlocks; // 退出目标块
|
||||||
|
Loop *parentloop = nullptr; // 父循环
|
||||||
|
Loop_list subLoops; // 子循环
|
||||||
|
size_t loopID; // 循环ID
|
||||||
|
unsigned loopDepth; // 循环深度
|
||||||
|
|
||||||
|
Instruction *indCondVar = nullptr; // 循环条件变量
|
||||||
|
Instruction::Kind IcmpKind; // 比较类型
|
||||||
|
Value *indEnd = nullptr; // 循环结束值
|
||||||
|
AllocaInst *IndPhi = nullptr; // 循环变量
|
||||||
|
|
||||||
|
ConstantValue *indBegin = nullptr; // 循环起始值
|
||||||
|
ConstantValue *indStep = nullptr; // 循环步长
|
||||||
|
|
||||||
|
std::set<GlobalValue *> GlobalValuechange; // 循环内改变的全局变量
|
||||||
|
|
||||||
|
int StepType = 0; // 循环步长类型
|
||||||
|
bool parallelable = false; // 是否可并行
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Loop(BasicBlock *header, const std::string &name = "")
|
||||||
|
: headerBlock(header) {
|
||||||
|
blocksInLoop.push_back(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setloopID() {
|
||||||
|
static unsigned loopCount = 0;
|
||||||
|
loopCount = loopCount + 1;
|
||||||
|
loopID = loopCount;
|
||||||
|
}
|
||||||
|
ConstantValue* getindBegin() { return indBegin; }
|
||||||
|
ConstantValue* getindStep() { return indStep; }
|
||||||
|
void setindBegin(ConstantValue *indBegin2set) { indBegin = indBegin2set; }
|
||||||
|
void setindStep(ConstantValue *indStep2set) { indStep = indStep2set; }
|
||||||
|
void setStepType(int StepType2Set) { StepType = StepType2Set; }
|
||||||
|
int getStepType() { return StepType; }
|
||||||
|
size_t getLoopID() { return loopID; }
|
||||||
|
|
||||||
|
BasicBlock* getHeader() const { return headerBlock; }
|
||||||
|
BasicBlock* getPreheaderBlock() const { return preheaderBlock; }
|
||||||
|
block_list& getLatchBlocks() { return latchBlock; }
|
||||||
|
block_set& getExitingBlocks() { return exitingBlocks; }
|
||||||
|
block_set& getExitBlocks() { return exitBlocks; }
|
||||||
|
Loop* getParentLoop() const { return parentloop; }
|
||||||
|
void setParentLoop(Loop *parent) { parentloop = parent; }
|
||||||
|
void addBasicBlock(BasicBlock *bb) { blocksInLoop.push_back(bb); }
|
||||||
|
void addSubLoop(Loop *loop) { subLoops.push_back(loop); }
|
||||||
|
void setLoopDepth(unsigned depth) { loopDepth = depth; }
|
||||||
|
block_list& getBasicBlocks() { return blocksInLoop; }
|
||||||
|
Loop_list& getSubLoops() { return subLoops; }
|
||||||
|
unsigned getLoopDepth() const { return loopDepth; }
|
||||||
|
|
||||||
|
bool isLoopContainsBasicBlock(BasicBlock *bb) const {
|
||||||
|
return std::find(blocksInLoop.begin(), blocksInLoop.end(), bb) != blocksInLoop.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addExitingBlock(BasicBlock *bb) { exitingBlocks.insert(bb); }
|
||||||
|
void addExitBlock(BasicBlock *bb) { exitBlocks.insert(bb); }
|
||||||
|
void addLatchBlock(BasicBlock *bb) { latchBlock.push_back(bb); }
|
||||||
|
void setPreheaderBlock(BasicBlock *bb) { preheaderBlock = bb; }
|
||||||
|
|
||||||
|
void setIndexCondInstr(Instruction *instr) { indCondVar = instr; }
|
||||||
|
void setIcmpKind(Instruction::Kind kind) { IcmpKind = kind; }
|
||||||
|
Instruction::Kind getIcmpKind() const { return IcmpKind; }
|
||||||
|
|
||||||
|
bool isSimpleLoopInvariant(Value *value) ;
|
||||||
|
|
||||||
|
void setIndEnd(Value *value) { indEnd = value; }
|
||||||
|
void setIndPhi(AllocaInst *phi) { IndPhi = phi; }
|
||||||
|
Value* getIndEnd() const { return indEnd; }
|
||||||
|
AllocaInst* getIndPhi() const { return IndPhi; }
|
||||||
|
Instruction* getIndCondVar() const { return indCondVar; }
|
||||||
|
|
||||||
|
void addGlobalValuechange(GlobalValue *globalvaluechange2add) {
|
||||||
|
GlobalValuechange.insert(globalvaluechange2add);
|
||||||
|
}
|
||||||
|
std::set<GlobalValue *>& getGlobalValuechange() {
|
||||||
|
return GlobalValuechange;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setParallelable(bool flag) { parallelable = flag; }
|
||||||
|
bool isParallelable() const { return parallelable; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 控制流分析类
|
||||||
|
class ControlFlowAnalysis {
|
||||||
|
private:
|
||||||
|
Module *pModule; ///< 模块
|
||||||
|
std::unordered_map<BasicBlock*, BlockAnalysisInfo*> blockAnalysisInfo; // 基本块分析信息
|
||||||
|
std::unordered_map<Function*, FunctionAnalysisInfo*> functionAnalysisInfo; // 函数分析信息
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ControlFlowAnalysis(Module *pMoudle) : pModule(pMoudle) {}
|
||||||
|
|
||||||
|
void init(); // 初始化分析器
|
||||||
|
void computeDomNode(); // 计算必经结点
|
||||||
|
void computeDomTree(); // 构造支配树
|
||||||
|
// std::unordered_set<BasicBlock *> computeDomFrontier(BasicBlock *block) ; // 计算单个块的支配边界(弃用)
|
||||||
|
void computeDomFrontierAllBlk(); // 计算所有块的支配边界
|
||||||
|
void runControlFlowAnalysis(); // 运行控制流分析(主要是支配树和支配边界)
|
||||||
|
void clear(){
|
||||||
|
for (auto &pair : blockAnalysisInfo) {
|
||||||
|
delete pair.second; // 清理基本块分析信息
|
||||||
|
}
|
||||||
|
blockAnalysisInfo.clear();
|
||||||
|
|
||||||
|
for (auto &pair : functionAnalysisInfo) {
|
||||||
|
delete pair.second; // 清理函数分析信息
|
||||||
|
}
|
||||||
|
functionAnalysisInfo.clear();
|
||||||
|
} // 清空分析结果
|
||||||
|
~ControlFlowAnalysis() {
|
||||||
|
clear(); // 析构时清理所有分析信息
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void intersectOP4Dom(std::unordered_set<BasicBlock *> &dom, const std::unordered_set<BasicBlock *> &other); // 交集运算,
|
||||||
|
BasicBlock* findCommonDominator(BasicBlock *a, BasicBlock *b); // 查找两个基本块的共同支配结点
|
||||||
|
};
|
||||||
|
|
||||||
|
// 数据流分析类
|
||||||
|
// 该类为抽象类,具体的数据流分析器需要继承此类
|
||||||
|
// 因为每个数据流分析器的分析动作都不一样,所以需要继承并实现analyze方法
|
||||||
|
class DataFlowAnalysis {
|
||||||
|
public:
|
||||||
|
virtual ~DataFlowAnalysis() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void init(Module *pModule) {} ///< 分析器初始化
|
||||||
|
virtual auto analyze(Module *pModule, BasicBlock *block) -> bool { return true; } ///< 分析动作,若完成则返回true;
|
||||||
|
virtual void clear() {} ///< 清空
|
||||||
|
};
|
||||||
|
|
||||||
|
// 数据流分析工具类
|
||||||
|
// 该类用于管理多个数据流分析器,提供统一的前向与后向分析接口
|
||||||
|
class DataFlowAnalysisUtils {
|
||||||
|
private:
|
||||||
|
std::vector<DataFlowAnalysis *> forwardAnalysisList; ///< 前向分析器列表
|
||||||
|
std::vector<DataFlowAnalysis *> backwardAnalysisList; ///< 后向分析器列表
|
||||||
|
|
||||||
|
public:
|
||||||
|
DataFlowAnalysisUtils() = default;
|
||||||
|
|
||||||
|
// 统一构造
|
||||||
|
DataFlowAnalysisUtils(
|
||||||
|
std::vector<DataFlowAnalysis *> forwardList = {},
|
||||||
|
std::vector<DataFlowAnalysis *> backwardList = {})
|
||||||
|
: forwardAnalysisList(std::move(forwardList)),
|
||||||
|
backwardAnalysisList(std::move(backwardList)) {}
|
||||||
|
|
||||||
|
// 统一添加接口
|
||||||
|
void addAnalyzers(
|
||||||
|
std::vector<DataFlowAnalysis *> forwardList,
|
||||||
|
std::vector<DataFlowAnalysis *> backwardList = {})
|
||||||
|
{
|
||||||
|
forwardAnalysisList.insert(
|
||||||
|
forwardAnalysisList.end(),
|
||||||
|
forwardList.begin(),
|
||||||
|
forwardList.end());
|
||||||
|
|
||||||
|
backwardAnalysisList.insert(
|
||||||
|
backwardAnalysisList.end(),
|
||||||
|
backwardList.begin(),
|
||||||
|
backwardList.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单独添加接口
|
||||||
|
void addForwardAnalyzer(DataFlowAnalysis *analyzer) {
|
||||||
|
forwardAnalysisList.push_back(analyzer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addBackwardAnalyzer(DataFlowAnalysis *analyzer) {
|
||||||
|
backwardAnalysisList.push_back(analyzer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置分析器列表
|
||||||
|
void setAnalyzers(
|
||||||
|
std::vector<DataFlowAnalysis *> forwardList,
|
||||||
|
std::vector<DataFlowAnalysis *> backwardList)
|
||||||
|
{
|
||||||
|
forwardAnalysisList = std::move(forwardList);
|
||||||
|
backwardAnalysisList = std::move(backwardList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空列表
|
||||||
|
void clear() {
|
||||||
|
forwardAnalysisList.clear();
|
||||||
|
backwardAnalysisList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 访问器
|
||||||
|
const auto& getForwardAnalyzers() const { return forwardAnalysisList; }
|
||||||
|
const auto& getBackwardAnalyzers() const { return backwardAnalysisList; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
void forwardAnalyze(Module *pModule); ///< 执行前向分析
|
||||||
|
void backwardAnalyze(Module *pModule); ///< 执行后向分析
|
||||||
|
};
|
||||||
|
|
||||||
|
// 活跃变量分析类
|
||||||
|
// 提供def - use分析
|
||||||
|
// 未兼容数组变量但是考虑了维度的use信息
|
||||||
|
class ActiveVarAnalysis : public DataFlowAnalysis {
|
||||||
|
private:
|
||||||
|
std::map<BasicBlock *, std::vector<std::set<User *>>> activeTable; ///< 活跃信息表,存储每个基本块内的的活跃变量信息
|
||||||
|
|
||||||
|
public:
|
||||||
|
ActiveVarAnalysis() = default;
|
||||||
|
~ActiveVarAnalysis() override = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::set<User*> getUsedSet(Instruction *inst);
|
||||||
|
static User* getDefine(Instruction *inst);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void init(Module *pModule) override;
|
||||||
|
bool analyze(Module *pModule, BasicBlock *block) override;
|
||||||
|
// 外部活跃信息表访问器
|
||||||
|
const std::map<BasicBlock *, std::vector<std::set<User *>>> &getActiveTable() const;
|
||||||
|
void clear() override {
|
||||||
|
activeTable.clear(); // 清空活跃信息表
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 分析管理器
|
||||||
|
class AnalysisManager {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
37
src/include/SysYIROptPre.h
Normal file
37
src/include/SysYIROptPre.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IR.h"
|
||||||
|
#include "IRBuilder.h"
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
// 优化前对SysY IR的预处理,也可以视作部分CFG优化
|
||||||
|
// 主要包括删除无用指令、合并基本块、删除空块等
|
||||||
|
// 这些操作可以在SysY IR生成时就完成,但为了简化IR生成过程,
|
||||||
|
// 这里将其放在SysY IR生成后进行预处理
|
||||||
|
// 同时兼容phi节点的处理,可以再mem2reg后再次调用优化
|
||||||
|
class SysYOptPre {
|
||||||
|
private:
|
||||||
|
Module *pModule;
|
||||||
|
IRBuilder *pBuilder;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SysYOptPre(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
|
||||||
|
|
||||||
|
void SysYOptimizateAfterIR(){
|
||||||
|
SysYDelInstAfterBr();
|
||||||
|
SysYBlockMerge();
|
||||||
|
SysYDelNoPreBLock();
|
||||||
|
SysYDelEmptyBlock();
|
||||||
|
SysYAddReturn();
|
||||||
|
}
|
||||||
|
void SysYDelInstAfterBr(); // 删除br后面的指令
|
||||||
|
void SysYDelEmptyBlock(); // 空块删除
|
||||||
|
void SysYDelNoPreBLock(); // 删除无前驱块
|
||||||
|
void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块,
|
||||||
|
// 也可以修改IR生成实现回填机制
|
||||||
|
void SysYAddReturn(); // 添加return指令(主要针对Void函数)
|
||||||
|
void usedelete(Instruction *instr); // use删除
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
29
src/include/SysYIRPrinter.h
Normal file
29
src/include/SysYIRPrinter.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "IR.h"
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
class SysYPrinter {
|
||||||
|
private:
|
||||||
|
Module *pModule;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SysYPrinter(Module *pModule) : pModule(pModule) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void printIR();
|
||||||
|
void printGlobalVariable();
|
||||||
|
void printFunction(Function *function);
|
||||||
|
void printInst(Instruction *pInst);
|
||||||
|
void printType(Type *type);
|
||||||
|
void printValue(Value *value);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::string getOperandName(Value *operand);
|
||||||
|
std::string getTypeString(Type *type);
|
||||||
|
std::string getValueName(Value *value);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
@@ -8,6 +8,8 @@ using namespace std;
|
|||||||
using namespace antlr4;
|
using namespace antlr4;
|
||||||
// #include "Backend.h"
|
// #include "Backend.h"
|
||||||
#include "SysYIRGenerator.h"
|
#include "SysYIRGenerator.h"
|
||||||
|
#include "SysYIRPrinter.h"
|
||||||
|
#include "SysYIROptPre.h"
|
||||||
// #include "LLVMIRGenerator.h"
|
// #include "LLVMIRGenerator.h"
|
||||||
using namespace sysy;
|
using namespace sysy;
|
||||||
|
|
||||||
@@ -76,22 +78,13 @@ int main(int argc, char **argv) {
|
|||||||
SysYIRGenerator generator;
|
SysYIRGenerator generator;
|
||||||
generator.visitCompUnit(moduleAST);
|
generator.visitCompUnit(moduleAST);
|
||||||
auto moduleIR = generator.get();
|
auto moduleIR = generator.get();
|
||||||
// moduleIR->print(cout);
|
SysYPrinter printer(moduleIR);
|
||||||
|
printer.printIR();
|
||||||
|
auto builder = generator.getBuilder();
|
||||||
|
SysYOptPre optPre(moduleIR, builder);
|
||||||
|
optPre.SysYOptimizateAfterIR();
|
||||||
|
printer.printIR();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
// else if (argStopAfter == "llvmir") {
|
|
||||||
// LLVMIRGenerator llvmirGenerator;
|
|
||||||
// llvmirGenerator.generateIR(moduleAST); // 使用公共接口生成 IR
|
|
||||||
// cout << llvmirGenerator.getIR();
|
|
||||||
// return EXIT_SUCCESS;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // generate assembly
|
|
||||||
// CodeGen codegen(moduleIR);
|
|
||||||
// string asmCode = codegen.code_gen();
|
|
||||||
// cout << asmCode << endl;
|
|
||||||
// if (argStopAfter == "asm")
|
|
||||||
// return EXIT_SUCCESS;
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user