From baff60888861ce0f8bd310ada30d1a415e2a395a Mon Sep 17 00:00:00 2001 From: lxq <877250099@qq.com> Date: Wed, 8 Feb 2023 09:49:35 +0800 Subject: [PATCH] Use DFS order for block traverse, pass --- include/codegen/liverange.hpp | 5 +++ src/codegen/codegen.cpp | 2 +- src/codegen/liverange.cpp | 60 +++++++++++++++++++++++++++++------ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/include/codegen/liverange.hpp b/include/codegen/liverange.hpp index 46b379a..768049d 100644 --- a/include/codegen/liverange.hpp +++ b/include/codegen/liverange.hpp @@ -1,12 +1,14 @@ #ifndef LIVERANGE_HPP #define LIVERANGE_HPP +#include "Function.h" #include "Module.h" #include "Value.h" #include #include #include +#include using std::map; using std::pair; @@ -18,6 +20,7 @@ using std::vector; #define UNINITIAL -1 #define __LRA_PRINT__ +#define __USE_DFS_ORDER__ namespace LRA { @@ -70,6 +73,7 @@ class LiveRangeAnalyzer { Module *m; // Function *func; int ir_cnt; + vector BB_DFS_Order; map IN, OUT; map instr_id; map, int> cpstmt_id; @@ -77,6 +81,7 @@ class LiveRangeAnalyzer { LVITS liveIntervals; map intervalmap; + void get_dfs_order(Function*); void make_id(Function *); void make_interval(Function *); diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 7f827fb..e7111e2 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -405,7 +405,7 @@ CodeGen::bool2branch(Instruction *instr) { instr_ir = "fcmp.ceq.s $fcc0"; break; case FCmpInst::NE: - instr_ir = "fcmp.cun.s $fcc0"; + instr_ir = "fcmp.cne.s $fcc0"; break; case FCmpInst::GT: instr_ir = "fcmp.cle.s $fcc0"; diff --git a/src/codegen/liverange.cpp b/src/codegen/liverange.cpp index 1ba7f11..015af88 100644 --- a/src/codegen/liverange.cpp +++ b/src/codegen/liverange.cpp @@ -1,7 +1,10 @@ #include "liverange.hpp" +#include "BasicBlock.h" #include "Function.h" +#include + using std::cout; using std::endl; using namespace LRA; @@ -15,6 +18,7 @@ LiveRangeAnalyzer::clear() { cpstmt_id.clear(); intervalmap.clear(); liveIntervals.clear(); + BB_DFS_Order.clear(); } LiveSet @@ -38,13 +42,18 @@ LiveRangeAnalyzer::make_id(Function *func) { // instruction numbering // this is also the structure of the IR logically: // ignore phi, add copy-statement - for (auto &bb : func->get_basic_blocks()) { - for (auto &instr : bb.get_instructions()) { +#ifdef __USE_DFS_ORDER__ + for (auto bb : BB_DFS_Order) { +#else + for (auto &bb_ : func->get_basic_blocks()) { + auto bb = &bb_; +#endif + for (auto &instr : bb->get_instructions()) { if (instr.is_phi()) continue; if (instr.is_br() or instr.is_ret()) { // insert copy-stmt in front of the jump ir - auto it = phi_map.find(&bb); + auto it = phi_map.find(bb); if (it != phi_map.end()) { for (auto pr : it->second) { cpstmt_id[pr] = ++ir_cnt; @@ -56,25 +65,51 @@ LiveRangeAnalyzer::make_id(Function *func) { } } +void +LiveRangeAnalyzer::get_dfs_order(Function *func) { + map vis; + std::deque Q; + + Q.push_back(func->get_entry_block()); + + while (not Q.empty()) { + auto bb = Q.front(); + Q.pop_front(); + if (vis[bb]) + continue; + vis[bb] = true; + BB_DFS_Order.push_back(bb); + for (auto succ : bb->get_succ_basic_blocks()) + Q.push_front(succ); + } +} + void LiveRangeAnalyzer::run(Function *func) { clear(); + get_dfs_order(func); make_id(func); bool cont = true; while (cont) { cont = false; // reverse traverse BasicBlocks +#ifdef __USE_DFS_ORDER__ + for (auto rit_bb = BB_DFS_Order.rbegin(); rit_bb != BB_DFS_Order.rend(); + ++rit_bb) { + auto bb = *rit_bb; +#else for (auto rit_bb = func->get_basic_blocks().rbegin(); rit_bb != func->get_basic_blocks().rend(); ++rit_bb) { auto bb = &(*rit_bb); +#endif LiveSet bef_in, out; bool last_ir = true; // reverse traverse instructions - for (auto rit_ir = rit_bb->get_instructions().rbegin(); - rit_ir != rit_bb->get_instructions().rend(); + for (auto rit_ir = bb->get_instructions().rbegin(); + rit_ir != bb->get_instructions().rend(); ++rit_ir) { auto instr = &(*rit_ir); if (instr->is_phi()) { @@ -133,7 +168,7 @@ LiveRangeAnalyzer::run(Function *func) { make_interval(func); #ifdef __LRA_PRINT__ - print(func, false, true); + print(func, true, true); #endif } @@ -205,14 +240,19 @@ LiveRangeAnalyzer::print(Function *func, cout << "\tin-set: " + print_liveSet(IN.at(0)) << "\n"; cout << "\tout-set: " + print_liveSet(OUT.at(0)) << "\n"; } - for (auto &bb : func->get_basic_blocks()) { - for (auto &instr : bb.get_instructions()) { +#ifdef __USE_DFS_ORDER__ + for (auto bb : BB_DFS_Order) { +#else + for (auto &bb_ : func->get_basic_blocks()) { + auto bb = &bb_; +#endif + for (auto &instr : bb->get_instructions()) { if (instr.is_phi()) // ignore phi continue; // insert copy-stmt if ((instr.is_br() or instr.is_ret()) and - phi_map.find(&bb) != phi_map.end()) { - for (auto pr : phi_map.find(&bb)->second) { + phi_map.find(bb) != phi_map.end()) { + for (auto pr : phi_map.find(bb)->second) { auto [lv, rv] = pr; auto idx = cpstmt_id.at(pr); cout << cpstmt_id.at(pr) << ". " << lv->get_name() << " = " -- GitLab