Commit 06a9b882 authored by lxq's avatar lxq

the order matters for data flow analysis!

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