Commit baff6088 authored by lxq's avatar lxq

Use DFS order for block traverse, pass

parent 805d36ad
#ifndef LIVERANGE_HPP
#define LIVERANGE_HPP
#include "Function.h"
#include "Module.h"
#include "Value.h"
#include <iostream>
#include <map>
#include <set>
#include <vector>
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<BasicBlock*> BB_DFS_Order;
map<int, LiveSet> IN, OUT;
map<Value *, int> instr_id;
map<pair<Value *, Value *>, int> cpstmt_id;
......@@ -77,6 +81,7 @@ class LiveRangeAnalyzer {
LVITS liveIntervals;
map<Value *, Interval> intervalmap;
void get_dfs_order(Function*);
void make_id(Function *);
void make_interval(Function *);
......
......@@ -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";
......
#include "liverange.hpp"
#include "BasicBlock.h"
#include "Function.h"
#include <deque>
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<BasicBlock *, bool> vis;
std::deque<BasicBlock *> 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() << " = "
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment