Commit 06a9b882 authored by lxq's avatar lxq

the order matters for data flow analysis!

parent baff6088
...@@ -129,15 +129,23 @@ class CodeGen { ...@@ -129,15 +129,23 @@ class CodeGen {
string reg2, string reg2,
int imm, int imm,
string tinstr, string tinstr,
int tid = 0,
int bits = 12, int bits = 12,
string treg = "$t0",
bool u = false) { bool u = false) {
/* this function will tranfser
* `addi.d $a0, $fp, imm` to `add.d $a0, $fp, tmp_ireg` if imm
* overfloats for `addi.d`. During the time we move `imm` to `tmp_ireg`,
* another tmp ireg will be used, they can be same, but we must specify
* it.
*/
auto treg = tmpregname(tid, false);
assert(treg != reg2 && "it's possible to write tid before reg2's use");
auto [l, h] = immRange(bits, u); auto [l, h] = immRange(bits, u);
if (l <= imm and imm <= h) if (l <= imm and imm <= h)
output.push_back(instr_ir + " " + reg1 + ", " + reg2 + ", " + output.push_back(instr_ir + " " + reg1 + ", " + reg2 + ", " +
to_string(imm)); to_string(imm));
else { else {
assert(value2reg(ConstantInt::get(imm, m), 0, treg) == treg); assert(value2reg(ConstantInt::get(imm, m), tid, treg) == treg);
output.push_back(tinstr + " " + reg1 + ", " + reg2 + ", " + treg); output.push_back(tinstr + " " + reg1 + ", " + reg2 + ", " + treg);
} }
} }
......
...@@ -450,6 +450,7 @@ class GVN : public Pass { ...@@ -450,6 +450,7 @@ class GVN : public Pass {
std::unique_ptr<FuncInfo> func_info_; std::unique_ptr<FuncInfo> func_info_;
std::unique_ptr<GVNExpression::ConstFolder> folder_; std::unique_ptr<GVNExpression::ConstFolder> folder_;
std::unique_ptr<DeadCode> dce_; std::unique_ptr<DeadCode> dce_;
std::vector<BasicBlock *> BB_DFS_Order;
// self add member // self add member
// std::uint64_t start_number_; // std::uint64_t start_number_;
...@@ -463,6 +464,7 @@ class GVN : public Pass { ...@@ -463,6 +464,7 @@ class GVN : public Pass {
// //
// self add function // self add function
// //
void get_dfs_order(Function *func);
void add_map_(); void add_map_();
std::uint64_t new_number() { return next_value_number_++; } std::uint64_t new_number() { return next_value_number_++; }
void deal_with_entry(BasicBlock *Entry); void deal_with_entry(BasicBlock *Entry);
......
...@@ -215,8 +215,7 @@ CodeGen::value2reg(Value *v, int i, string recommend) { ...@@ -215,8 +215,7 @@ CodeGen::value2reg(Value *v, int i, string recommend) {
} else if (dynamic_cast<AllocaInst *>(v)) { } else if (dynamic_cast<AllocaInst *>(v)) {
// auto alloc_instr = dynamic_cast<AllocaInst *>(v); // auto alloc_instr = dynamic_cast<AllocaInst *>(v);
// give the stack address // give the stack address
makeSureInRange( makeSureInRange("addi.d", reg_name, FP, -off.at(v), "add.d", i);
"addi.d", reg_name, FP, -off.at(v), "add.d", 12, reg_name);
/* output.push_back("addi.d " + reg_name + ", $fp, -" + /* output.push_back("addi.d " + reg_name + ", $fp, -" +
* to_string(off.at(v))); */ * to_string(off.at(v))); */
} else if (dynamic_cast<Argument *>(v)) { } else if (dynamic_cast<Argument *>(v)) {
...@@ -235,8 +234,7 @@ CodeGen::value2reg(Value *v, int i, string recommend) { ...@@ -235,8 +234,7 @@ CodeGen::value2reg(Value *v, int i, string recommend) {
FP, FP,
func_arg_off.at(cur_func).at(id), func_arg_off.at(cur_func).at(id),
instr_ir + "x" + suff, instr_ir + "x" + suff,
12, i);
reg_name);
/* output.push_back(instr_ir + suff + " " + reg_name + ", $fp, " + /* output.push_back(instr_ir + suff + " " + reg_name + ", $fp, " +
* to_string(func_arg_off.at(cur_func).at(id))); */ * to_string(func_arg_off.at(cur_func).at(id))); */
} }
...@@ -248,8 +246,7 @@ CodeGen::value2reg(Value *v, int i, string recommend) { ...@@ -248,8 +246,7 @@ CodeGen::value2reg(Value *v, int i, string recommend) {
FP, FP,
-off.at(v), -off.at(v),
instr_ir + "x" + suff, instr_ir + "x" + suff,
12, i);
reg_name);
/* output.push_back(instr_ir + suff + " " + reg_name + /* output.push_back(instr_ir + suff + " " + reg_name +
* ", $fp, -" + to_string(off.at(v))); */ * ", $fp, -" + to_string(off.at(v))); */
} }
...@@ -350,10 +347,10 @@ CodeGen::IR2assem(SiToFpInst *instr) { ...@@ -350,10 +347,10 @@ CodeGen::IR2assem(SiToFpInst *instr) {
} }
string string
CodeGen::bool2branch(Instruction *instr) { CodeGen::bool2branch(Instruction *cond) {
assert(instr->get_type() == m->get_int1_type()); assert(cond->get_type() == m->get_int1_type());
auto icmp_instr = dynamic_cast<CmpInst *>(instr); auto icmp_instr = dynamic_cast<CmpInst *>(cond);
auto fcmp_instr = dynamic_cast<FCmpInst *>(instr); auto fcmp_instr = dynamic_cast<FCmpInst *>(cond);
assert(icmp_instr or fcmp_instr); assert(icmp_instr or fcmp_instr);
string instr_ir; string instr_ir;
...@@ -365,9 +362,9 @@ CodeGen::bool2branch(Instruction *instr) { ...@@ -365,9 +362,9 @@ CodeGen::bool2branch(Instruction *instr) {
break; break;
case CmpInst::NE: { case CmpInst::NE: {
instr_ir = "bne"; instr_ir = "bne";
if (instr->get_operand(1) == CONST_0 and if (cond->get_operand(1) == CONST_0 and
dynamic_cast<Instruction *>(instr->get_operand(0)) and dynamic_cast<Instruction *>(cond->get_operand(0)) and
dynamic_cast<Instruction *>(instr->get_operand(0)) dynamic_cast<Instruction *>(cond->get_operand(0))
->is_zext()) { ->is_zext()) {
// something like: // something like:
// %op0 = icmp slt i32 1, 2 # deepest // %op0 = icmp slt i32 1, 2 # deepest
...@@ -375,7 +372,7 @@ CodeGen::bool2branch(Instruction *instr) { ...@@ -375,7 +372,7 @@ CodeGen::bool2branch(Instruction *instr) {
// %op2 = icmp ne i32 %op1, 0 // %op2 = icmp ne i32 %op1, 0
// br i1 %op2, label %label3, label %label5 // br i1 %op2, label %label3, label %label5
auto deepest = static_cast<Instruction *>( auto deepest = static_cast<Instruction *>(
static_cast<Instruction *>(instr->get_operand(0)) static_cast<Instruction *>(cond->get_operand(0))
->get_operand(0)); ->get_operand(0));
return bool2branch(deepest); return bool2branch(deepest);
} }
...@@ -395,11 +392,11 @@ CodeGen::bool2branch(Instruction *instr) { ...@@ -395,11 +392,11 @@ CodeGen::bool2branch(Instruction *instr) {
reverse = true; reverse = true;
break; break;
} }
auto reg1 = value2reg(instr->get_operand(0), 0); auto reg1 = value2reg(cond->get_operand(0), 0);
auto reg2 = value2reg(instr->get_operand(1), 1); auto reg2 = value2reg(cond->get_operand(1), 1);
return instr_ir + " " + return instr_ir + " " +
(reverse ? (reg2 + ", " + reg1) : (reg1 + ", " + reg2)) + ","; (reverse ? (reg2 + ", " + reg1) : (reg1 + ", " + reg2)) + ",";
} else { } else if (fcmp_instr) {
switch (fcmp_instr->get_cmp_op()) { switch (fcmp_instr->get_cmp_op()) {
case FCmpInst::EQ: case FCmpInst::EQ:
instr_ir = "fcmp.ceq.s $fcc0"; instr_ir = "fcmp.ceq.s $fcc0";
...@@ -422,11 +419,12 @@ CodeGen::bool2branch(Instruction *instr) { ...@@ -422,11 +419,12 @@ CodeGen::bool2branch(Instruction *instr) {
instr_ir = "fcmp.cle.s $fcc0"; instr_ir = "fcmp.cle.s $fcc0";
break; break;
} }
auto reg1 = value2reg(instr->get_operand(0), 0); auto reg1 = value2reg(cond->get_operand(0), 0);
auto reg2 = value2reg(instr->get_operand(1), 1); auto reg2 = value2reg(cond->get_operand(1), 1);
output.push_back(instr_ir + ", " + reg1 + ", " + reg2); output.push_back(instr_ir + ", " + reg1 + ", " + reg2);
return (reverse ? "bceqz $fcc0," : "bcnez $fcc0,"); return (reverse ? "bceqz $fcc0," : "bcnez $fcc0,");
} } else
assert(false);
} }
void void
...@@ -435,10 +433,20 @@ CodeGen::IR2assem(BranchInst *instr) { ...@@ -435,10 +433,20 @@ CodeGen::IR2assem(BranchInst *instr) {
auto TBB = static_cast<BasicBlock *>(instr->get_operand(1)); auto TBB = static_cast<BasicBlock *>(instr->get_operand(1));
auto FBB = static_cast<BasicBlock *>(instr->get_operand(2)); auto FBB = static_cast<BasicBlock *>(instr->get_operand(2));
// value2reg(instr->get_operand(0)); // value2reg(instr->get_operand(0));
string instr_ir = auto cond = instr->get_operand(0);
bool2branch(static_cast<Instruction *>(instr->get_operand(0))); if (dynamic_cast<ConstantInt *>(cond)) {
output.push_back(instr_ir + " " + label_in_assem(TBB)); auto const_bool = static_cast<ConstantInt *>(cond);
output.push_back("b " + label_in_assem(FBB)); assert(const_bool->get_type()->is_integer_type() and
static_cast<IntegerType *>(const_bool->get_type())
->get_num_bits() == 1);
bool cond_value = const_bool->get_value();
output.push_back("b " + label_in_assem(cond_value ? TBB : FBB));
} else {
string instr_ir =
bool2branch(static_cast<Instruction *>(instr->get_operand(0)));
output.push_back(instr_ir + " " + label_in_assem(TBB));
output.push_back("b " + label_in_assem(FBB));
}
} else { } else {
auto bb = static_cast<BasicBlock *>(instr->get_operand(0)); auto bb = static_cast<BasicBlock *>(instr->get_operand(0));
output.push_back("b " + label_in_assem(bb)); output.push_back("b " + label_in_assem(bb));
...@@ -513,16 +521,15 @@ CodeGen::pass_arguments(CallInst *instr) { ...@@ -513,16 +521,15 @@ CodeGen::pass_arguments(CallInst *instr) {
vis[i] = true; vis[i] = true;
} }
order.clear();
for (int arg_id = 1; arg_id < instr->get_num_operand(); arg_id++)
order.push_back(arg_id); // initialize
// 3. pass arguments' value // 3. pass arguments' value
assert(order.size() == func->get_num_of_args()); int passed = 0;
map<string, bool> wroten; // assert(order.size() >= func->get_num_of_args());
map<string, bool> changed;
// bool assigned[8] = {false}; // bool assigned[8] = {false};
string t0_contained; string t0_contained;
for (auto arg_id : order) { for (auto arg_id : order) {
if (arg_id > func->get_num_of_args())
continue;
auto arg_value = instr->get_operand(arg_id); auto arg_value = instr->get_operand(arg_id);
auto arg_is_float = arg_value->get_type()->is_float_type(); auto arg_is_float = arg_value->get_type()->is_float_type();
auto arg_reg_aid = regname(arg_id, arg_is_float); auto arg_reg_aid = regname(arg_id, arg_is_float);
...@@ -531,12 +538,12 @@ CodeGen::pass_arguments(CallInst *instr) { ...@@ -531,12 +538,12 @@ CodeGen::pass_arguments(CallInst *instr) {
// arg_reg_aid(only right when arg_id <= 8) // arg_reg_aid(only right when arg_id <= 8)
v_reg = value2reg(arg_value, 1); v_reg = value2reg(arg_value, 1);
if (backup[arg_id]) { // a_id still relied by some argument due to cycle if (backup[arg_id]) { // a_id still relied by some argument due to cycle
assert(not wroten[arg_reg_aid]); assert(not changed[arg_reg_aid]);
gencopy(t_reg, arg_reg_aid, arg_is_float); gencopy(t_reg, arg_reg_aid, arg_is_float);
t0_contained = arg_reg_aid; t0_contained = arg_reg_aid;
} }
// in case that the src register has been wroten // in case that the src register has been wroten
if (wroten[v_reg]) { if (changed[v_reg]) {
assert(t0_contained == v_reg); assert(t0_contained == v_reg);
v_reg = arg_value->get_type()->is_float_type() ? "$ft0" : "$t0"; v_reg = arg_value->get_type()->is_float_type() ? "$ft0" : "$t0";
} }
...@@ -555,8 +562,12 @@ CodeGen::pass_arguments(CallInst *instr) { ...@@ -555,8 +562,12 @@ CodeGen::pass_arguments(CallInst *instr) {
* $sp, " + to_string(func_arg_off.at(func).at(arg_id))); * $sp, " + to_string(func_arg_off.at(func).at(arg_id)));
*/ */
} }
wroten[arg_reg_aid] = true; if (arg_reg_aid != v_reg) {
changed[arg_reg_aid] = true;
}
passed++;
} }
assert(passed == func->get_num_of_args());
} }
void void
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <deque>
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
...@@ -386,8 +387,10 @@ GVN::detectEquivalences() { ...@@ -386,8 +387,10 @@ GVN::detectEquivalences() {
#ifdef __DEBUG__ #ifdef __DEBUG__
std::cout << ++times << "th iteration" << std::endl; std::cout << ++times << "th iteration" << std::endl;
#endif #endif
for (auto &_bb : func_->get_basic_blocks()) { /* for (auto &_bb : func_->get_basic_blocks()) {
auto bb = &_bb; * std::cout << _bb.get_name() << std::endl;
* auto bb = &_bb; */
for (auto &bb : BB_DFS_Order) {
if (bb == Entry) if (bb == Entry)
continue; continue;
// get PIN of bb from predecessor(s) // get PIN of bb from predecessor(s)
...@@ -922,6 +925,7 @@ GVN::run() { ...@@ -922,6 +925,7 @@ GVN::run() {
for (auto &f : m_->get_functions()) { for (auto &f : m_->get_functions()) {
if (f.get_basic_blocks().empty()) if (f.get_basic_blocks().empty())
continue; continue;
get_dfs_order(&f);
func_ = &f; func_ = &f;
initPerFunction(); initPerFunction();
LOG_INFO << "Processing " << f.get_name(); LOG_INFO << "Processing " << f.get_name();
...@@ -953,6 +957,26 @@ GVN::run() { ...@@ -953,6 +957,26 @@ GVN::run() {
gvn_json << "]"; gvn_json << "]";
} }
void
GVN::get_dfs_order(Function *func) {
std::map<BasicBlock *, bool> vis;
std::deque<BasicBlock *> Q;
BB_DFS_Order.clear();
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 void
GVN::dump_tmp(Function &f) { GVN::dump_tmp(Function &f) {
std::string gvn_json; std::string gvn_json;
......
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