Compare commits

..

14 Commits

Author SHA1 Message Date
Lixuanwang
b2b88ee511 [backend-beta] saving for simpler implementation for register allocation 2025-06-24 05:02:11 +08:00
Lixuanwang
395e6e4003 [backend] fixed many bugs 2025-06-24 03:23:45 +08:00
Lixuanwang
20cc08708a [backend] introduced debug option 2025-06-24 02:56:17 +08:00
Lixuanwang
942cb32976 [backend] fixed bugs 2025-06-24 00:42:14 +08:00
Lixuanwang
ac7569d890 Merge branch 'IROptPre' into backend 2025-06-24 00:40:36 +08:00
Lixuanwang
11cd32e6df [backend] fixed some bugs 2025-06-24 00:35:38 +08:00
Lixuanwang
617244fae7 [backend] switch to simpler implementation for inst selection 2025-06-24 00:30:33 +08:00
Lixuanwang
3c3f48ee87 [backend] fixed 1 segmentation fault 2025-06-23 22:38:29 +08:00
Lixuanwang
ab3eb253f9 [backend] debugging segmentation fault caused by branch instr 2025-06-23 17:02:29 +08:00
Lixuanwang
7d37bd7528 [backend] introduced DAG, GraphAlloc 2025-06-23 15:38:01 +08:00
Lixuanwang
af00612376 [backend] supported if 2025-06-23 06:16:19 +08:00
ladev789
10e1476ba1 [backend] test01 passed 2025-06-22 20:05:34 +08:00
ladev789
b94e87637a Merge remote-tracking branch 'origin/IRPrinter' into backend 2025-06-22 20:00:29 +08:00
ladev789
88a561177d [backend] incorrect asm output 2025-06-22 20:00:03 +08:00
11 changed files with 1032 additions and 1142 deletions

View File

@@ -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,6 +665,42 @@ 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 移动指令
* *

View File

@@ -1,30 +1,10 @@
#include "RISCv32Backend.h" #include "RISCv32Backend.h"
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <stack>
namespace sysy { 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::string RISCv32CodeGen::code_gen() {
std::stringstream ss; std::stringstream ss;
ss << ".text\n"; ss << ".text\n";
@@ -34,16 +14,22 @@ std::string RISCv32CodeGen::code_gen() {
std::string RISCv32CodeGen::module_gen() { std::string RISCv32CodeGen::module_gen() {
std::stringstream ss; std::stringstream ss;
// 生成全局变量(数据段) for (auto& global : module->getGlobals()) {
for (const auto& global : module->getGlobals()) { ss << ".global " << global->getName() << "\n";
ss << ".data\n"; ss << ".section .data\n";
ss << ".globl " << global->getName() << "\n"; ss << ".align 2\n";
ss << global->getName() << ":\n"; ss << global->getName() << ":\n";
ss << " .word 0\n"; // 假设初始化为0 for (auto value : global->getInitValues().getValues()) {
auto const_val = dynamic_cast<ConstantValue*>(value);
if (const_val->isInt()) {
ss << ".word " << const_val->getInt() << "\n";
} else {
ss << ".float " << const_val->getFloat() << "\n";
}
}
} }
// 生成函数(文本段) ss << ".section .text\n";
ss << ".text\n"; for (auto& func : module->getFunctions()) {
for (const auto& func : module->getFunctions()) {
ss << function_gen(func.second.get()); ss << function_gen(func.second.get());
} }
return ss.str(); return ss.str();
@@ -51,107 +37,582 @@ std::string RISCv32CodeGen::module_gen() {
std::string RISCv32CodeGen::function_gen(Function* func) { std::string RISCv32CodeGen::function_gen(Function* func) {
std::stringstream ss; std::stringstream ss;
// 函数标签 ss << ".global " << func->getName() << "\n";
ss << ".globl " << func->getName() << "\n"; ss << ".type " << func->getName() << ", @function\n";
ss << func->getName() << ":\n"; ss << func->getName() << ":\n";
// 序言:保存 ra分配堆栈
bool is_leaf = true; // 简化假设 // Perform register allocation
ss << " addi sp, sp, -16\n"; auto live_sets = liveness_analysis(func);
ss << " sw ra, 12(sp)\n"; auto interference_graph = build_interference_graph(live_sets);
// 寄存器分配 auto alloc = color_graph(func, interference_graph);
auto alloc = register_allocation(func);
// 生成基本块代码 // Prologue: Adjust stack and save callee-saved registers
for (const auto& bb : func->getBasicBlocks()) { if (alloc.stack_size > 0) {
ss << basicBlock_gen(bb.get(), alloc); ss << " addi sp, sp, -" << alloc.stack_size << "\n";
ss << " sw ra, " << (alloc.stack_size - 4) << "(sp)\n";
}
for (auto preg : callee_saved) {
if (std::find_if(alloc.vreg_to_preg.begin(), alloc.vreg_to_preg.end(),
[preg](const auto& pair) { return pair.second == preg; }) != alloc.vreg_to_preg.end()) {
ss << " sw " << get_preg_str(preg) << ", " << (alloc.stack_size - 8) << "(sp)\n";
}
}
int block_idx = 0;
for (auto& bb : func->getBasicBlocks()) {
ss << basicBlock_gen(bb.get(), alloc, block_idx++);
}
// Epilogue: Restore callee-saved registers and stack
for (auto preg : callee_saved) {
if (std::find_if(alloc.vreg_to_preg.begin(), alloc.vreg_to_preg.end(),
[preg](const auto& pair) { return pair.second == preg; }) != alloc.vreg_to_preg.end()) {
ss << " lw " << get_preg_str(preg) << ", " << (alloc.stack_size - 8) << "(sp)\n";
}
}
if (alloc.stack_size > 0) {
ss << " lw ra, " << (alloc.stack_size - 4) << "(sp)\n";
ss << " addi sp, sp, " << alloc.stack_size << "\n";
} }
// 结尾:恢复 ra释放堆栈
ss << " lw ra, 12(sp)\n";
ss << " addi sp, sp, 16\n";
ss << " ret\n"; ss << " ret\n";
return ss.str(); return ss.str();
} }
std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc) { std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc, int block_idx) {
std::stringstream ss; std::stringstream ss;
ss << bb->getName() << ":\n"; ss << ".L" << block_idx << ":\n";
for (const auto& inst : bb->getInstructions()) { auto dag_nodes = build_dag(bb);
auto riscv_insts = instruction_gen(inst.get()); for (auto& node : dag_nodes) {
for (const auto& riscv_inst : riscv_insts) { select_instructions(node.get(), alloc);
ss << " " << riscv_inst.opcode; }
for (size_t i = 0; i < riscv_inst.operands.size(); ++i) { std::set<DAGNode*> emitted_nodes;
if (i > 0) ss << ", "; for (auto& node : dag_nodes) {
if (riscv_inst.operands[i].kind == Operand::Kind::Reg) { emit_instructions(node.get(), ss, alloc, emitted_nodes);
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(); return ss.str();
} }
std::vector<RISCv32CodeGen::RISCv32Inst> RISCv32CodeGen::instruction_gen(Instruction* inst) { std::vector<std::unique_ptr<RISCv32CodeGen::DAGNode>> RISCv32CodeGen::build_dag(BasicBlock* bb) {
std::vector<RISCv32Inst> insts; std::vector<std::unique_ptr<DAGNode>> nodes;
if (auto bin = dynamic_cast<BinaryInst*>(inst)) { std::map<Value*, DAGNode*> value_to_node;
std::string opcode; int vreg_counter = 0;
if (bin->getKind() == BinaryInst::kAdd) opcode = "add";
else if (bin->getKind() == BinaryInst::kSub) opcode = "sub"; for (auto& inst : bb->getInstructions()) {
else if (bin->getKind() == BinaryInst::kMul) opcode = "mul"; if (auto alloca = dynamic_cast<AllocaInst*>(inst.get())) {
else return insts; // 其他操作未实现 auto node = std::make_unique<DAGNode>(DAGNode::ALLOCA_ADDR);
insts.emplace_back(opcode, std::vector<Operand>{ node->value = alloca;
{Operand::Kind::Reg, bin}, node->result_vreg = "%" + inst->getName(); // Use IR name (%a(0), %b(0))
{Operand::Kind::Reg, bin->getLhs()}, value_to_node[alloca] = node.get();
{Operand::Kind::Reg, bin->getRhs()} nodes.push_back(std::move(node));
}); } else if (auto load = dynamic_cast<LoadInst*>(inst.get())) {
} else if (auto load = dynamic_cast<LoadInst*>(inst)) { auto node = std::make_unique<DAGNode>(DAGNode::LOAD);
insts.emplace_back("lw", std::vector<Operand>{ node->value = load;
{Operand::Kind::Reg, load}, node->result_vreg = "%" + inst->getName(); // Use IR name (%0, %1)
{Operand::Kind::Label, load->getPointer()->getName()} auto pointer = load->getPointer();
}); if (value_to_node.count(pointer)) {
} else if (auto store = dynamic_cast<StoreInst*>(inst)) { node->operands.push_back(value_to_node[pointer]);
insts.emplace_back("sw", std::vector<Operand>{ value_to_node[pointer]->users.push_back(node.get());
{Operand::Kind::Reg, store->getValue()}, }
{Operand::Kind::Label, store->getPointer()->getName()} value_to_node[load] = node.get();
}); nodes.push_back(std::move(node));
} else if (auto store = dynamic_cast<StoreInst*>(inst.get())) {
auto node = std::make_unique<DAGNode>(DAGNode::STORE);
node->value = store;
auto value_operand = store->getValue();
auto pointer = store->getPointer();
if (value_to_node.count(value_operand)) {
node->operands.push_back(value_to_node[value_operand]);
value_to_node[value_operand]->users.push_back(node.get());
} else if (auto const_val = dynamic_cast<ConstantValue*>(value_operand)) {
auto const_node = std::make_unique<DAGNode>(DAGNode::CONSTANT);
const_node->value = const_val;
const_node->result_vreg = "%" + std::to_string(vreg_counter++); // Use simple %N for constants
value_to_node[value_operand] = const_node.get();
node->operands.push_back(const_node.get());
const_node->users.push_back(node.get());
nodes.push_back(std::move(const_node));
}
if (value_to_node.count(pointer)) {
node->operands.push_back(value_to_node[pointer]);
value_to_node[pointer]->users.push_back(node.get());
}
nodes.push_back(std::move(node));
} else if (auto binary = dynamic_cast<BinaryInst*>(inst.get())) {
auto node = std::make_unique<DAGNode>(DAGNode::BINARY);
node->value = binary;
node->result_vreg = "%" + inst->getName(); // Use IR name (%2)
for (auto operand : binary->getOperands()) {
auto op_value = operand->getValue();
if (value_to_node.count(op_value)) {
node->operands.push_back(value_to_node[op_value]);
value_to_node[op_value]->users.push_back(node.get());
} else if (auto const_val = dynamic_cast<ConstantValue*>(op_value)) {
auto const_node = std::make_unique<DAGNode>(DAGNode::CONSTANT);
const_node->value = const_val;
const_node->result_vreg = "%" + std::to_string(vreg_counter++);
value_to_node[op_value] = const_node.get();
node->operands.push_back(const_node.get());
const_node->users.push_back(node.get());
nodes.push_back(std::move(const_node));
}
}
value_to_node[binary] = node.get();
nodes.push_back(std::move(node));
} else if (auto ret = dynamic_cast<ReturnInst*>(inst.get())) {
auto node = std::make_unique<DAGNode>(DAGNode::RETURN);
node->value = ret;
if (ret->hasReturnValue()) {
auto value_operand = ret->getReturnValue();
if (value_to_node.count(value_operand)) {
node->operands.push_back(value_to_node[value_operand]);
value_to_node[value_operand]->users.push_back(node.get());
} else if (auto const_val = dynamic_cast<ConstantValue*>(value_operand)) {
auto const_node = std::make_unique<DAGNode>(DAGNode::CONSTANT);
const_node->value = const_val;
const_node->result_vreg = "%" + std::to_string(vreg_counter++);
value_to_node[value_operand] = const_node.get();
node->operands.push_back(const_node.get());
const_node->users.push_back(node.get());
nodes.push_back(std::move(const_node));
}
}
nodes.push_back(std::move(node));
} else if (auto cond_br = dynamic_cast<CondBrInst*>(inst.get())) {
auto node = std::make_unique<DAGNode>(DAGNode::BRANCH);
node->value = cond_br;
auto condition = cond_br->getCondition();
if (value_to_node.count(condition)) {
node->operands.push_back(value_to_node[condition]);
value_to_node[condition]->users.push_back(node.get());
} else if (auto const_val = dynamic_cast<ConstantValue*>(condition)) {
auto const_node = std::make_unique<DAGNode>(DAGNode::CONSTANT);
const_node->value = const_val;
const_node->result_vreg = "%" + std::to_string(vreg_counter++);
value_to_node[condition] = const_node.get();
node->operands.push_back(const_node.get());
const_node->users.push_back(node.get());
nodes.push_back(std::move(const_node));
}
nodes.push_back(std::move(node));
} else if (auto uncond_br = dynamic_cast<UncondBrInst*>(inst.get())) {
auto node = std::make_unique<DAGNode>(DAGNode::BRANCH);
node->value = uncond_br;
nodes.push_back(std::move(node));
}
} }
return insts; return nodes;
} }
void RISCv32CodeGen::eliminate_phi(Function* func) { void RISCv32CodeGen::select_instructions(DAGNode* node, const RegAllocResult& alloc) {
// TODO: 实现 phi 指令消除 if (node->inst.empty()) {
switch (node->kind) {
case DAGNode::CONSTANT: {
auto const_val = dynamic_cast<ConstantValue*>(node->value);
if (const_val->isInt()) {
node->inst = "li " + node->result_vreg + ", " + std::to_string(const_val->getInt());
} else {
node->inst = "# float constant not implemented";
}
break;
}
case DAGNode::LOAD: {
auto load = dynamic_cast<LoadInst*>(node->value);
auto pointer = load->getPointer();
if (auto alloca = dynamic_cast<AllocaInst*>(pointer)) {
if (alloc.stack_map.count(alloca)) {
node->inst = "lw " + node->result_vreg + ", " + std::to_string(alloc.stack_map.at(alloca)) + "(sp)";
}
} else if (auto global = dynamic_cast<GlobalValue*>(pointer)) {
node->inst = "lw " + node->result_vreg + ", " + global->getName() + "(gp)";
}
break;
}
case DAGNode::STORE: {
auto store = dynamic_cast<StoreInst*>(node->value);
auto pointer = store->getPointer();
auto value_vreg = node->operands[0]->result_vreg;
if (auto alloca = dynamic_cast<AllocaInst*>(pointer)) {
if (alloc.stack_map.count(alloca)) {
node->inst = "sw " + value_vreg + ", " + std::to_string(alloc.stack_map.at(alloca)) + "(sp)";
}
} else if (auto global = dynamic_cast<GlobalValue*>(pointer)) {
node->inst = "sw " + value_vreg + ", " + global->getName() + "(gp)";
}
break;
}
case DAGNode::BINARY: {
auto binary = dynamic_cast<BinaryInst*>(node->value);
auto lhs_vreg = node->operands[0]->result_vreg;
auto rhs_vreg = node->operands[1]->result_vreg;
std::string op;
switch (binary->getKind()) {
case Instruction::kAdd: op = "add"; break;
case Instruction::kSub: op = "sub"; break;
case Instruction::kMul: op = "mul"; break;
case Instruction::kDiv: op = "div"; break;
case Instruction::kICmpEQ: op = "seq"; break;
case Instruction::kICmpNE: op = "sne"; break;
case Instruction::kICmpLT: op = "slt"; break;
case Instruction::kICmpGT: op = "sgt"; break;
case Instruction::kICmpLE: op = "sle"; break;
case Instruction::kICmpGE: op = "sge"; break;
default: op = "# unknown"; break;
}
node->inst = op + " " + node->result_vreg + ", " + lhs_vreg + ", " + rhs_vreg;
break;
}
case DAGNode::RETURN: {
auto ret = dynamic_cast<ReturnInst*>(node->value);
if (ret->hasReturnValue()) {
auto value_vreg = node->operands[0]->result_vreg;
node->inst = "mv a0, " + value_vreg;
} else {
node->inst = "ret";
}
break;
}
case DAGNode::BRANCH: {
if (auto cond_br = dynamic_cast<CondBrInst*>(node->value)) {
auto condition_vreg = node->operands[0]->result_vreg;
auto then_block = cond_br->getThenBlock();
auto else_block = cond_br->getElseBlock();
int then_idx = 0, else_idx = 0;
int idx = 0;
for (auto& bb : cond_br->getFunction()->getBasicBlocks()) {
if (bb.get() == then_block) then_idx = idx;
if (bb.get() == else_block) else_idx = idx;
idx++;
}
node->inst = "bne " + condition_vreg + ", zero, .L" + std::to_string(then_idx) + "\n j .L" + std::to_string(else_idx);
} else if (auto uncond_br = dynamic_cast<UncondBrInst*>(node->value)) {
auto target_block = uncond_br->getBlock();
int target_idx = 0;
int idx = 0;
for (auto& bb : uncond_br->getFunction()->getBasicBlocks()) {
if (bb.get() == target_block) target_idx = idx;
idx++;
}
node->inst = "j .L" + std::to_string(target_idx);
}
break;
}
default:
node->inst = "# unimplemented";
break;
}
}
} }
std::map<Instruction*, std::set<Value*>> RISCv32CodeGen::liveness_analysis(Function* func) { void RISCv32CodeGen::emit_instructions(DAGNode* node, std::stringstream& ss, const RegAllocResult& alloc, std::set<DAGNode*>& emitted_nodes) {
std::map<Instruction*, std::set<Value*>> live_sets; if (emitted_nodes.count(node)) return;
// TODO: 实现活跃性分析 for (auto operand : node->operands) {
return live_sets; emit_instructions(operand, ss, alloc, emitted_nodes);
}
if (!node->inst.empty() && node->inst != "# unimplemented" && node->inst.find("# alloca") == std::string::npos) {
std::string inst = node->inst;
std::vector<std::pair<std::string, std::string>> replacements;
// Collect replacements for result and operand virtual registers
if (node->result_vreg != "" && node->kind != DAGNode::ALLOCA_ADDR) {
if (alloc.vreg_to_preg.count(node->result_vreg)) {
replacements.emplace_back(node->result_vreg, get_preg_str(alloc.vreg_to_preg.at(node->result_vreg)));
} else if (alloc.spill_map.count(node->result_vreg)) {
auto temp_reg = PhysicalReg::T0;
replacements.emplace_back(node->result_vreg, get_preg_str(temp_reg));
inst = inst.substr(0, inst.find('\n')); // Handle multi-line instructions
ss << " " << inst << "\n";
ss << " sw " << get_preg_str(temp_reg) << ", " << alloc.spill_map.at(node->result_vreg) << "(sp)\n";
emitted_nodes.insert(node);
return;
} else {
ss << "# Error: Virtual register " << node->result_vreg << " not allocated (kind: " << node->getNodeKindString() << ")\n";
}
}
for (auto operand : node->operands) {
if (operand->result_vreg != "" && operand->kind != DAGNode::ALLOCA_ADDR) {
if (alloc.vreg_to_preg.count(operand->result_vreg)) {
replacements.emplace_back(operand->result_vreg, get_preg_str(alloc.vreg_to_preg.at(operand->result_vreg)));
} else if (alloc.spill_map.count(operand->result_vreg)) {
auto temp_reg = PhysicalReg::T1;
ss << " lw " << get_preg_str(temp_reg) << ", " << alloc.spill_map.at(operand->result_vreg) << "(sp)\n";
replacements.emplace_back(operand->result_vreg, get_preg_str(temp_reg));
} else {
ss << "# Error: Operand virtual register " << operand->result_vreg << " not allocated (kind: " << operand->getNodeKindString() << ")\n";
}
}
}
// Perform all replacements only if vreg exists in inst
for (const auto& [vreg, preg] : replacements) {
size_t pos = inst.find(vreg);
while (pos != std::string::npos) {
inst.replace(pos, vreg.length(), preg);
pos = inst.find(vreg, pos + preg.length());
}
}
// Emit the instruction
if (node->kind == DAGNode::BRANCH || inst.find('\n') != std::string::npos) {
ss << inst << "\n";
} else if (inst != "ret") {
ss << " " << inst << "\n";
}
}
emitted_nodes.insert(node);
} }
std::map<Value*, std::set<Value*>> RISCv32CodeGen::build_interference_graph( std::map<Instruction*, std::set<std::string>> RISCv32CodeGen::liveness_analysis(Function* func) {
const std::map<Instruction*, std::set<Value*>>& live_sets) { std::map<Instruction*, std::set<std::string>> live_in, live_out;
std::map<Value*, std::set<Value*>> graph; bool changed;
// TODO: 实现干扰图构建
return graph; // Build DAG for all basic blocks
std::map<BasicBlock*, std::vector<std::unique_ptr<DAGNode>>> bb_dags;
for (auto& bb : func->getBasicBlocks()) {
bb_dags[bb.get()] = build_dag(bb.get());
}
// Initialize live_in and live_out
for (auto& bb : func->getBasicBlocks()) {
for (auto& inst : bb->getInstructions()) {
live_in[inst.get()];
live_out[inst.get()];
}
}
do {
changed = false;
for (auto& bb : func->getBasicBlocks()) {
// Reverse iterate for backward analysis
for (auto it = bb->getInstructions().rbegin(); it != bb->getInstructions().rend(); ++it) {
auto inst = it->get();
std::set<std::string> new_live_in, new_live_out;
// live_out = union of live_in of successors
for (auto succ : bb->getSuccessors()) {
if (!succ->getInstructions().empty()) {
auto succ_inst = succ->getInstructions().front().get();
new_live_out.insert(live_in[succ_inst].begin(), live_in[succ_inst].end());
}
}
// Collect def and use
std::set<std::string> def, use;
// IR instruction def
if (inst->getName() != "" && !dynamic_cast<AllocaInst*>(inst)) {
def.insert("%" + inst->getName());
}
// IR instruction use
for (auto operand : inst->getOperands()) {
auto value = operand->getValue();
if (auto op_inst = dynamic_cast<Instruction*>(value)) {
if (op_inst->getName() != "" && !dynamic_cast<AllocaInst*>(op_inst)) {
use.insert("%" + op_inst->getName());
}
}
}
// DAG node def and use
for (auto& node : bb_dags[bb.get()]) {
if (node->value == inst && node->kind != DAGNode::ALLOCA_ADDR) {
if (node->result_vreg != "") {
def.insert(node->result_vreg);
}
for (auto operand : node->operands) {
if (operand->result_vreg != "" && operand->kind != DAGNode::ALLOCA_ADDR) {
use.insert(operand->result_vreg);
}
}
}
// Constants
if (node->kind == DAGNode::CONSTANT) {
for (auto user : node->users) {
if (user->value == inst) {
use.insert(node->result_vreg);
}
}
}
}
// live_in = use U (live_out - def)
std::set<std::string> live_out_minus_def;
std::set_difference(new_live_out.begin(), new_live_out.end(),
def.begin(), def.end(),
std::inserter(live_out_minus_def, live_out_minus_def.begin()));
new_live_in.insert(use.begin(), use.end());
new_live_in.insert(live_out_minus_def.begin(), live_out_minus_def.end());
// Debug
std::cerr << "Instruction: " << (inst->getName() != "" ? "%" + inst->getName() : "none") << "\n";
std::cerr << " def: "; for (const auto& d : def) std::cerr << d << " "; std::cerr << "\n";
std::cerr << " use: "; for (const auto& u : use) std::cerr << u << " "; std::cerr << "\n";
std::cerr << " live_in: "; for (const auto& v : new_live_in) std::cerr << v << " "; std::cerr << "\n";
std::cerr << " live_out: "; for (const auto& v : new_live_out) std::cerr << v << " "; std::cerr << "\n";
if (live_in[inst] != new_live_in || live_out[inst] != new_live_out) {
live_in[inst] = new_live_in;
live_out[inst] = new_live_out;
changed = true;
}
}
}
} while (changed);
// Debug live_out
for (const auto& [inst, live_vars] : live_out) {
std::cerr << "Instruction: " << (inst->getName() != "" ? "%" + inst->getName() : "none") << " live_out: ";
for (const auto& var : live_vars) {
std::cerr << var << " ";
}
std::cerr << "\n";
}
return live_out;
} }
RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) { std::map<std::string, std::set<std::string>> RISCv32CodeGen::build_interference_graph(
RegAllocResult result; const std::map<Instruction*, std::set<std::string>>& live_sets) {
// TODO: 实现寄存器分配 std::map<std::string, std::set<std::string>> interference_graph;
return result; for (const auto& [inst, live_vars] : live_sets) {
std::string def_var = inst->getName() != "" && !dynamic_cast<AllocaInst*>(inst) ? "%" + inst->getName() : "";
if (def_var != "") {
interference_graph[def_var]; // Initialize
for (const auto& live_var : live_vars) {
if (live_var != def_var && live_var.find("%a(") != 0 && live_var.find("%b(") != 0) {
interference_graph[def_var].insert(live_var);
interference_graph[live_var].insert(def_var);
}
}
}
// Initialize all live variables
for (const auto& live_var : live_vars) {
if (live_var.find("%a(") != 0 && live_var.find("%b(") != 0) {
interference_graph[live_var];
}
}
// Live variables interfere with each other
for (auto it1 = live_vars.begin(); it1 != live_vars.end(); ++it1) {
if (it1->find("%a(") == 0 || it1->find("%b(") == 0) continue;
for (auto it2 = std::next(it1); it2 != live_vars.end(); ++it2) {
if (it2->find("%a(") == 0 || it2->find("%b(") == 0) continue;
interference_graph[*it1].insert(*it2);
interference_graph[*it2].insert(*it1);
}
}
}
// Debug
for (const auto& [vreg, neighbors] : interference_graph) {
std::cerr << "Vreg " << vreg << " interferes with: ";
for (const auto& neighbor : neighbors) {
std::cerr << neighbor << " ";
}
std::cerr << "\n";
}
return interference_graph;
}
RISCv32CodeGen::RegAllocResult RISCv32CodeGen::color_graph(Function* func, const std::map<std::string, std::set<std::string>>& interference_graph) {
RegAllocResult alloc;
std::map<std::string, std::set<std::string>> ig = interference_graph;
std::stack<std::string> stack;
std::set<std::string> spilled;
// Available physical registers
std::vector<PhysicalReg> available_regs = {
PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3, PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6,
PhysicalReg::S0, PhysicalReg::S1, PhysicalReg::S2, PhysicalReg::S3, PhysicalReg::S4, PhysicalReg::S5,
PhysicalReg::S6, PhysicalReg::S7, PhysicalReg::S8, PhysicalReg::S9, PhysicalReg::S10, PhysicalReg::S11
};
// Simplify: Push nodes with degree < number of registers
while (!ig.empty()) {
bool simplified = false;
for (auto it = ig.begin(); it != ig.end();) {
if (it->second.size() < available_regs.size()) {
stack.push(it->first);
for (auto& [vreg, neighbors] : ig) {
neighbors.erase(it->first);
}
it = ig.erase(it);
simplified = true;
} else {
++it;
}
}
if (!simplified) {
// Spill the node with the highest degree
auto max_it = ig.begin();
for (auto it = ig.begin(); it != ig.end(); ++it) {
if (it->second.size() > max_it->second.size()) {
max_it = it;
}
}
spilled.insert(max_it->first);
for (auto& [vreg, neighbors] : ig) {
neighbors.erase(max_it->first);
}
ig.erase(max_it);
}
}
// Assign colors (physical registers)
while (!stack.empty()) {
auto vreg = stack.top();
stack.pop();
std::set<PhysicalReg> used_colors;
if (interference_graph.count(vreg)) {
for (const auto& neighbor : interference_graph.at(vreg)) {
if (alloc.vreg_to_preg.count(neighbor)) {
used_colors.insert(alloc.vreg_to_preg.at(neighbor));
}
}
}
bool assigned = false;
for (auto preg : available_regs) {
if (!used_colors.count(preg)) {
alloc.vreg_to_preg[vreg] = preg;
assigned = true;
break;
}
}
if (!assigned) {
spilled.insert(vreg);
}
}
// Allocate stack space for AllocaInst and spilled virtual registers
int stack_offset = 0;
for (auto& bb : func->getBasicBlocks()) {
for (auto& inst : bb->getInstructions()) {
if (auto alloca = dynamic_cast<AllocaInst*>(inst.get())) {
alloc.stack_map[alloca] = stack_offset;
stack_offset += 4; // 4 bytes per variable
}
}
}
for (const auto& vreg : spilled) {
alloc.spill_map[vreg] = stack_offset;
stack_offset += 4;
}
alloc.stack_size = stack_offset + 8; // Extra space for ra and callee-saved
// Debug output to verify register allocation
for (const auto& [vreg, preg] : alloc.vreg_to_preg) {
std::cerr << "Vreg " << vreg << " assigned to " << get_preg_str(preg) << "\n";
}
for (const auto& vreg : spilled) {
std::cerr << "Vreg " << vreg << " spilled to stack offset " << alloc.spill_map.at(vreg) << "\n";
}
return alloc;
}
RISCv32CodeGen::PhysicalReg RISCv32CodeGen::get_preg_or_temp(const std::string& vreg, const RegAllocResult& alloc) const {
if (alloc.vreg_to_preg.count(vreg)) {
return alloc.vreg_to_preg.at(vreg);
}
return PhysicalReg::T0; // Fallback for spilled registers, handled in emit_instructions
} }
} // namespace sysy } // namespace sysy

View File

@@ -6,60 +6,96 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <set> #include <set>
#include <memory>
#include <iostream>
#include <functional>
#include <stack>
namespace sysy { namespace sysy {
class RISCv32CodeGen { class RISCv32CodeGen {
public: public:
explicit RISCv32CodeGen(Module* mod) : module(mod) {} enum class PhysicalReg {
std::string code_gen(); // 生成模块的汇编代码 ZERO, RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, T3, T4, T5, T6
};
struct DAGNode {
enum NodeKind { CONSTANT, LOAD, STORE, BINARY, CALL, RETURN, BRANCH, ALLOCA_ADDR };
NodeKind kind;
Value* value = nullptr;
std::string inst;
std::string result_vreg;
std::vector<DAGNode*> operands;
std::vector<DAGNode*> users;
DAGNode(NodeKind k) : kind(k) {}
std::string getNodeKindString() const {
switch (kind) {
case CONSTANT: return "CONSTANT";
case LOAD: return "LOAD";
case STORE: return "STORE";
case BINARY: return "BINARY";
case CALL: return "CALL";
case RETURN: return "RETURN";
case BRANCH: return "BRANCH";
case ALLOCA_ADDR: return "ALLOCA_ADDR";
default: return "UNKNOWN";
}
}
};
struct RegAllocResult {
std::map<std::string, PhysicalReg> vreg_to_preg; // 虚拟寄存器到物理寄存器的映射
std::map<Value*, int> stack_map; // AllocaInst到栈偏移的映射
std::map<std::string, int> spill_map; // 溢出的虚拟寄存器到栈偏移的映射
int stack_size = 0; // 总栈帧大小
};
RISCv32CodeGen(Module* mod) : module(mod) {}
std::string code_gen();
std::string module_gen();
std::string function_gen(Function* func);
std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc, int block_idx);
std::vector<std::unique_ptr<DAGNode>> build_dag(BasicBlock* bb);
void select_instructions(DAGNode* node, const RegAllocResult& alloc);
void emit_instructions(DAGNode* node, std::stringstream& ss, const RegAllocResult& alloc, std::set<DAGNode*>& emitted_nodes);
std::map<Instruction*, std::set<std::string>> liveness_analysis(Function* func);
std::map<std::string, std::set<std::string>> build_interference_graph(
const std::map<Instruction*, std::set<std::string>>& live_sets);
RegAllocResult color_graph(Function* func, const std::map<std::string, std::set<std::string>>& interference_graph);
private: private:
Module* module; Module* module;
std::map<PhysicalReg, std::string> preg_to_str = {
// 物理寄存器 {PhysicalReg::ZERO, "zero"}, {PhysicalReg::RA, "ra"}, {PhysicalReg::SP, "sp"},
enum class PhysicalReg { {PhysicalReg::GP, "gp"}, {PhysicalReg::TP, "tp"}, {PhysicalReg::T0, "t0"},
T0, T1, T2, T3, T4, T5, T6, // x5-x7, x28-x31 {PhysicalReg::T1, "t1"}, {PhysicalReg::T2, "t2"}, {PhysicalReg::S0, "s0"},
A0, A1, A2, A3, A4, A5, A6, A7 // x10-x17 {PhysicalReg::S1, "s1"}, {PhysicalReg::A0, "a0"}, {PhysicalReg::A1, "a1"},
}; {PhysicalReg::A2, "a2"}, {PhysicalReg::A3, "a3"}, {PhysicalReg::A4, "a4"},
static const std::vector<PhysicalReg> allocable_regs; {PhysicalReg::A5, "a5"}, {PhysicalReg::A6, "a6"}, {PhysicalReg::A7, "a7"},
{PhysicalReg::S2, "s2"}, {PhysicalReg::S3, "s3"}, {PhysicalReg::S4, "s4"},
// 操作数 {PhysicalReg::S5, "s5"}, {PhysicalReg::S6, "s6"}, {PhysicalReg::S7, "s7"},
struct Operand { {PhysicalReg::S8, "s8"}, {PhysicalReg::S9, "s9"}, {PhysicalReg::S10, "s10"},
enum class Kind { Reg, Imm, Label }; {PhysicalReg::S11, "s11"}, {PhysicalReg::T3, "t3"}, {PhysicalReg::T4, "t4"},
Kind kind; {PhysicalReg::T5, "t5"}, {PhysicalReg::T6, "t6"}
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 指令 std::vector<PhysicalReg> caller_saved = {
struct RISCv32Inst { PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3, PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6,
std::string opcode; PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3, PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7
std::vector<Operand> operands;
RISCv32Inst(const std::string& op, const std::vector<Operand>& ops)
: opcode(op), operands(ops) {}
}; };
// 寄存器分配结果 std::vector<PhysicalReg> callee_saved = {
struct RegAllocResult { PhysicalReg::S0, PhysicalReg::S1, PhysicalReg::S2, PhysicalReg::S3, PhysicalReg::S4, PhysicalReg::S5,
std::map<Value*, PhysicalReg> reg_map; // 虚拟寄存器到物理寄存器的映射 PhysicalReg::S6, PhysicalReg::S7, PhysicalReg::S8, PhysicalReg::S9, PhysicalReg::S10, PhysicalReg::S11
std::map<Value*, int> stack_map; // 虚拟寄存器到堆栈槽的映射
int stack_size; // 堆栈帧大小
}; };
// 后端方法 std::string get_preg_str(PhysicalReg preg) const {
std::string module_gen(); return preg_to_str.at(preg);
std::string function_gen(Function* func); }
std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc);
std::vector<RISCv32Inst> instruction_gen(Instruction* inst); PhysicalReg get_preg_or_temp(const std::string& vreg, const RegAllocResult& alloc) const;
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 } // namespace sysy

View File

@@ -1,520 +0,0 @@
#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的所有前驱结点
// 迭代计算支配结点,直到不再变化
// 这里使用迭代法,直到支配结点不再变化
// TODOLengauer-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

View File

@@ -128,15 +128,12 @@ void SysYPrinter::printFunction(Function *function) {
std::cout << " @" << function->getName() << "("; std::cout << " @" << function->getName() << "(";
auto entryBlock = function->getEntryBlock(); auto entryBlock = function->getEntryBlock();
const auto &args_types = function->getParamTypes();
auto &args = entryBlock->getArguments(); auto &args = entryBlock->getArguments();
int i = 0; for (size_t i = 0; i < args.size(); i++) {
for (const auto &args_type : args_types) {
if (i > 0) std::cout << ", "; if (i > 0) std::cout << ", ";
printType(args_type); printType(args[i]->getType());
std::cout << " %" << args[i]->getName(); std::cout << " %" << args[i]->getName();
i++;
} }
std::cout << ") {" << std::endl; std::cout << ") {" << std::endl;

View File

@@ -317,6 +317,7 @@ class ConstantValue : public Value {
class Instruction; class Instruction;
class Function; class Function;
class Loop;
class BasicBlock; class BasicBlock;
/*! /*!
@@ -326,73 +327,104 @@ 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 *>;
using block_list = std::vector<BasicBlock *>; using block_list = std::vector<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; ///< 后继列表
bool reachable = false; BasicBlock *idom = nullptr; ///< 直接支配结点即支配树前驱唯一默认nullptr
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:
unsigned getNumInstructions() const { return instructions.size(); } public:
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; } ///< 获取前驱列表
iterator begin() { return instructions.begin(); } block_list& getSuccessors() { return successors; } ///< 获取后继列表
iterator end() { return instructions.end(); } block_set& getDominants() { return dominants; }
iterator terminator() { return std::prev(end()); } BasicBlock* getIdom() { return idom; }
void insertArgument(AllocaInst *inst) { arguments.push_back(inst); } block_list& getSdoms() { return sdoms; }
block_set& getDFs() { return dominant_frontiers; }
iterator begin() { return instructions.begin(); } ///< 返回指向指令列表开头的迭代器
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);
@@ -401,7 +433,7 @@ public:
} 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()) {
@@ -409,7 +441,7 @@ public:
} 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) {
@@ -417,16 +449,41 @@ public:
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 removeInst(iterator pos) { instructions.erase(pos); } void setLoop(Loop *loop2set) { loopbelong = loop2set; } ///< 设置所属循环
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block); Loop* getLoop() { return loopbelong; } ///< 获得所属循环
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
@@ -1141,11 +1198,109 @@ 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 definitionclass //! Function definition
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));
@@ -1153,6 +1308,9 @@ 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,
@@ -1164,47 +1322,167 @@ 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; ///< 函数调用的函数集合
public:
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:
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; } void clearAttribute() { attribute = PlaceHolder; } ///< 清楚所有函数属性只保留PlaceHolder
Type* getReturnType() const { return getType()->as<FunctionType>()->getReturnType(); } Loop* getLoopOfBasicBlock(BasicBlock *bb) {
auto getParamTypes() const { return getType()->as<FunctionType>()->getParamTypes(); } return basicblock2Loop.count(bb) != 0 ? basicblock2Loop[bb] : nullptr;
auto getBasicBlocks() { return make_range(blocks); } } ///< 获得块所在循环
unsigned getLoopDepthByBlock(BasicBlock *basicblock2Check) {
if (getLoopOfBasicBlock(basicblock2Check) != nullptr) {
auto loop = getLoopOfBasicBlock(basicblock2Check);
return loop->getLoopDepth();
}
return static_cast<unsigned>(0);
} ///< 通过块,获得其所在循环深度
void addBBToLoop(BasicBlock *bb, Loop *LoopToadd) { basicblock2Loop[bb] = LoopToadd; } ///< 添加块与循环的映射
std::unordered_map<BasicBlock *, Loop *>& getBBToLoopRef() {
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 {

View File

@@ -1,403 +0,0 @@
#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

View File

@@ -10,6 +10,7 @@ using namespace antlr4;
#include "SysYIRGenerator.h" #include "SysYIRGenerator.h"
#include "SysYIRPrinter.h" #include "SysYIRPrinter.h"
#include "SysYIROptPre.h" #include "SysYIROptPre.h"
#include "RISCv32Backend.h"
// #include "LLVMIRGenerator.h" // #include "LLVMIRGenerator.h"
using namespace sysy; using namespace sysy;
@@ -73,18 +74,26 @@ int main(int argc, char **argv) {
// visit AST to generate IR // visit AST to generate IR
SysYIRGenerator generator;
generator.visitCompUnit(moduleAST);
if (argStopAfter == "ir") { if (argStopAfter == "ir") {
SysYIRGenerator generator;
generator.visitCompUnit(moduleAST);
auto moduleIR = generator.get(); auto moduleIR = generator.get();
SysYPrinter printer(moduleIR); SysYPrinter printer(moduleIR);
printer.printIR(); printer.printIR();
auto builder = generator.getBuilder(); auto builder = generator.getBuilder();
SysYOptPre optPre(moduleIR, builder); SysYOptPre optPre(moduleIR, builder);
optPre.SysYOptimizateAfterIR(); optPre.SysYOptimizateAfterIR();
printer.printIR();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
// generate assembly
auto module = generator.get();
sysy::RISCv32CodeGen codegen(module);
string asmCode = codegen.code_gen();
if (argStopAfter == "asm") {
cout << asmCode << endl;
return EXIT_SUCCESS;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@@ -1,12 +1,8 @@
//test add //test add
int main(){ int main(){
int a, b; int a, b;
float d;
a = 10; a = 10;
b = 2; b = 2;
int c = a; return a + b;
d = 1.1 ;
return a + b + c;
} }

View File

@@ -5,10 +5,10 @@ int main() {
const int b = 2; const int b = 2;
int c; int c;
if (a == b) if (a != b)
c = a + b; c = b - a + 20; // 21 <- this
else else
c = a * b; c = a * b + b + b + 10; // 16
return c; return c;
} }

View File

@@ -7,7 +7,7 @@ int mul(int x, int y) {
int main(){ int main(){
int a, b; int a, b;
a = 10; a = 10;
b = 0; b = 3;
a = mul(a, b); a = mul(a, b); //60
return a + b; return a + b; //66
} }