Commit 08898ecb authored by 李晓奇's avatar 李晓奇

now shuold pass loop3!

parent b1f2b21d
...@@ -69,6 +69,8 @@ class ConstantExpression : public Expression { ...@@ -69,6 +69,8 @@ class ConstantExpression : public Expression {
} }
ConstantExpression(Constant *c) : Expression(e_constant), c_(c) {} ConstantExpression(Constant *c) : Expression(e_constant), c_(c) {}
Constant *get_val() { return c_; }
private: private:
Constant *c_; Constant *c_;
}; };
...@@ -199,20 +201,24 @@ class GEPExpression : public Expression { ...@@ -199,20 +201,24 @@ class GEPExpression : public Expression {
// unique expression: not equal to any one else // unique expression: not equal to any one else
class UniqueExpression : public Expression { class UniqueExpression : public Expression {
public: public:
static std::shared_ptr<UniqueExpression> create(Instruction *instr) { static std::shared_ptr<UniqueExpression> create(Instruction *instr,
return std::make_shared<UniqueExpression>(instr); size_t index) {
return std::make_shared<UniqueExpression>(instr, index);
} }
virtual std::string print() { return "(UNIQUE " + instr_->print() + ")"; } // virtual std::string print() { return "(UNIQUE " + instr_->print() + ")";
// }
virtual std::string print() { return "v" + std::to_string(index_); }
bool equiv(const UniqueExpression *other) const { bool equiv(const UniqueExpression *other) const {
return instr_ == other->instr_; return instr_ == other->instr_;
} }
UniqueExpression(Instruction *instr) UniqueExpression(Instruction *instr, size_t index)
: Expression(e_unique), instr_(instr) {} : Expression(e_unique), instr_(instr), index_(index) {}
private: private:
Instruction *instr_; Instruction *instr_;
size_t index_;
}; };
} // namespace GVNExpression } // namespace GVNExpression
...@@ -276,7 +282,8 @@ class GVN : public Pass { ...@@ -276,7 +282,8 @@ class GVN : public Pass {
partitions transferFunction(BasicBlock *bb); partitions transferFunction(BasicBlock *bb);
std::shared_ptr<GVNExpression::PhiExpression> valuePhiFunc( std::shared_ptr<GVNExpression::PhiExpression> valuePhiFunc(
std::shared_ptr<GVNExpression::Expression>, std::shared_ptr<GVNExpression::Expression>,
BasicBlock *bb); BasicBlock *bb,
Instruction *instr);
std::shared_ptr<GVNExpression::Expression> valueExpr( std::shared_ptr<GVNExpression::Expression> valueExpr(
Instruction *instr, Instruction *instr,
const partitions &part); const partitions &part);
...@@ -308,6 +315,7 @@ class GVN : public Pass { ...@@ -308,6 +315,7 @@ class GVN : public Pass {
std::map<BasicBlock *, bool> _TOP; std::map<BasicBlock *, bool> _TOP;
partitions join_helper(BasicBlock *pre1, BasicBlock *pre2); partitions join_helper(BasicBlock *pre1, BasicBlock *pre2);
BasicBlock *curr_bb; BasicBlock *curr_bb;
std::map<std::pair<Instruction *, Value *>, size_t> start_idx_;
// //
// self add function // self add function
// //
...@@ -317,11 +325,17 @@ class GVN : public Pass { ...@@ -317,11 +325,17 @@ class GVN : public Pass {
Value *v, Value *v,
const partitions &part); const partitions &part);
std::vector<std::shared_ptr<GVNExpression::Expression>> core_( std::vector<std::shared_ptr<GVNExpression::Expression>> valueExpr_core_(
Instruction *instr, Instruction *instr,
const partitions &part, const partitions &part,
size_t count, const size_t count,
bool fold_ = true); bool fold_ = true);
Constant *constFold_core(const size_t count,
const partitions &part,
Instruction *instr,
const std::vector<Value *> &operands);
void assign_start_idx_();
void dump_tmp(Function &);
}; };
bool operator==(const GVN::partitions &p1, const GVN::partitions &p2); bool operator==(const GVN::partitions &p1, const GVN::partitions &p2);
...@@ -199,6 +199,8 @@ dump_bb2partition(const std::map<BasicBlock *, GVN::partitions> &map) { ...@@ -199,6 +199,8 @@ dump_bb2partition(const std::map<BasicBlock *, GVN::partitions> &map) {
static void static void
print_partitions(const GVN::partitions &p) { print_partitions(const GVN::partitions &p) {
if (p.empty()) { if (p.empty()) {
// to del
// std::cout << "empty partitions\n";
LOG_DEBUG << "empty partitions\n"; LOG_DEBUG << "empty partitions\n";
return; return;
} }
...@@ -206,13 +208,14 @@ print_partitions(const GVN::partitions &p) { ...@@ -206,13 +208,14 @@ print_partitions(const GVN::partitions &p) {
for (auto &cc : p) for (auto &cc : p)
log += print_congruence_class(*cc); log += print_congruence_class(*cc);
LOG_DEBUG << log; // please don't use std::cout LOG_DEBUG << log; // please don't use std::cout
// to del
// std::cout << log;
} }
} // namespace utils } // namespace utils
GVN::partitions GVN::partitions
GVN::join_helper(BasicBlock *pre1, BasicBlock *pre2) { GVN::join_helper(BasicBlock *pre1, BasicBlock *pre2) {
assert(not _TOP[pre1] or not _TOP[pre2] && "should flow here, not jump"); assert(not _TOP[pre1] or not _TOP[pre2] && "should flow here, not jump");
if (_TOP[pre1]) if (_TOP[pre1])
return pout_[pre2]; return pout_[pre2];
else if (_TOP[pre2]) else if (_TOP[pre2])
...@@ -260,25 +263,70 @@ GVN::intersect(shared_ptr<CongruenceClass> ci, shared_ptr<CongruenceClass> cj) { ...@@ -260,25 +263,70 @@ GVN::intersect(shared_ptr<CongruenceClass> ci, shared_ptr<CongruenceClass> cj) {
if (c->members_.size()) // not empty if (c->members_.size()) // not empty
{ {
if (c->index_ == 0) { if (c->index_ == 0) {
c->index_ = new_number(); // it must be a phi instruction
// and be separated to 2 copy statement
// we should use the copy-stmt int the previous block
auto instr = static_cast<Instruction *>(*c->members_.begin());
auto instr_phi = dynamic_cast<PhiInst *>(instr);
int exact_idx;
// trick here: use the exact value number
if (instr_phi) {
auto exact_pre_bb =
*(instr_phi->get_parent()->get_pre_basic_blocks().begin());
auto e = instr_phi->get_operand(
pretend_copy_stmt(instr_phi, exact_pre_bb));
exact_idx = start_idx_.at(std::make_pair(instr_phi, e));
} else {
exact_idx = start_idx_.at(std::make_pair(instr, nullptr));
}
c->index_ = exact_idx;
c->value_expr_ = c->value_phi_ = c->value_expr_ = c->value_phi_ =
PhiExpression::create(ci->value_expr_, cj->value_expr_); PhiExpression::create(ci->value_expr_, cj->value_expr_);
} }
// ??
c->leader_ = *c->members_.begin(); c->leader_ = *c->members_.begin();
} }
return c; return c;
} }
// assign start index for each instruction, including copy statement
// ther logic here:
// - use the same traver order as main run
// - assign an incremental number for each instruction
void
GVN::assign_start_idx_() {
int res;
for (auto &bb : func_->get_basic_blocks()) {
for (auto &instr : bb.get_instructions()) {
if (not instr.is_phi() and not instr.is_void())
start_idx_[std::make_pair(&instr, nullptr)] = new_number();
}
// and the phi instruction in all the successors
for (auto succ : bb.get_succ_basic_blocks()) {
for (auto &instr : succ->get_instructions()) {
if (instr.is_phi()) {
if ((res = pretend_copy_stmt(&instr, &bb)) == -1)
continue;
start_idx_[std::make_pair(&instr, instr.get_operand(res))] =
new_number();
}
}
}
}
next_value_number_ = 1;
}
void void
GVN::detectEquivalences() { GVN::detectEquivalences() {
int times = 0;
bool changed; bool changed;
std::cout << "all the instruction address:" << std::endl; std::cout << "all the instruction address:" << std::endl;
for (auto &bb : func_->get_basic_blocks()) { for (auto &bb : func_->get_basic_blocks()) {
for (auto &instr : bb.get_instructions()) for (auto &instr : bb.get_instructions())
std::cout << &instr << "\t" << instr.print() << std::endl; std::cout << &instr << "\t" << instr.print() << std::endl;
} }
assign_start_idx_();
// initialize pout with top // initialize pout with top
for (auto &bb : func_->get_basic_blocks()) { for (auto &bb : func_->get_basic_blocks()) {
_TOP[&bb] = true; _TOP[&bb] = true;
...@@ -293,6 +341,7 @@ GVN::detectEquivalences() { ...@@ -293,6 +341,7 @@ GVN::detectEquivalences() {
// iterate until converge // iterate until converge
do { do {
changed = false; changed = false;
std::cout << ++times << "th iteration" << std::endl;
for (auto &_bb : func_->get_basic_blocks()) { for (auto &_bb : func_->get_basic_blocks()) {
auto bb = &_bb; auto bb = &_bb;
if (bb == Entry) if (bb == Entry)
...@@ -306,12 +355,12 @@ GVN::detectEquivalences() { ...@@ -306,12 +355,12 @@ GVN::detectEquivalences() {
case 2: { case 2: {
auto pre_1 = *pre_bbs_.begin(); auto pre_1 = *pre_bbs_.begin();
auto pre_2 = *(++pre_bbs_.begin()); auto pre_2 = *(++pre_bbs_.begin());
pin_[bb] = join_helper(pre_1, pre_2); pin_[bb] = clone(join_helper(pre_1, pre_2));
break; break;
} }
case 1: { case 1: {
auto pre = *(pre_bbs_.begin()); auto pre = *(pre_bbs_.begin());
pin_[bb] = pout_[pre]; pin_[bb] = clone(pout_[pre]);
break; break;
} }
default: default:
...@@ -324,9 +373,15 @@ GVN::detectEquivalences() { ...@@ -324,9 +373,15 @@ GVN::detectEquivalences() {
// check changes in pout // check changes in pout
changed |= not(part == pout_[bb]); changed |= not(part == pout_[bb]);
pout_[bb] = part; pout_[bb] = clone(part);
_TOP[bb] = false; _TOP[bb] = false;
/* std::cout << "//-------\n"
* << "//after transferFunction(basic-block="
* << bb->get_name() << "), all pout:" << std::endl; */
// dump_tmp(*func_);
} }
// reset value number
} while (changed); } while (changed);
} }
...@@ -343,11 +398,51 @@ GVN::search_ve(Value *v, const GVN::partitions &part) { ...@@ -343,11 +398,51 @@ GVN::search_ve(Value *v, const GVN::partitions &part) {
return nullptr; return nullptr;
} }
// try constant fold for `count` operands
// the related instr is `instr`
Constant *
GVN::constFold_core(const size_t count,
const partitions &part,
Instruction *instr,
const std::vector<Value *> &operands) {
assert(count == 1 or count == 2);
Constant *res = nullptr;
// the first operand
auto op0_const_value = dynamic_cast<Constant *>(operands[0]);
auto op0_search_ = search_ve(operands[0], part);
auto op0_const_expr =
op0_search_ ? dynamic_cast<ConstantExpression *>(op0_search_.get())
: nullptr;
if ((op0_const_value or op0_const_expr)) {
auto op0_const =
op0_const_value ? op0_const_value : op0_const_expr->get_val();
// by now: the type cast instruction can do constant fold
if (count == 1)
res = folder_->compute(instr, op0_const);
if (count == 2) {
// the second operand
auto op1_const_value = dynamic_cast<Constant *>(operands[1]);
auto op1_search_ = search_ve(operands[1], part);
auto op1_const_expr =
op1_search_
? dynamic_cast<ConstantExpression *>(op1_search_.get())
: nullptr;
if (op1_const_value or op1_const_expr) {
auto op1_const = op1_const_value ? op1_const_value
: op1_const_expr->get_val();
res = folder_->compute(instr, op0_const, op1_const);
}
}
}
return res;
}
// for each op, try to find the // for each op, try to find the
std::vector<shared_ptr<Expression>> std::vector<shared_ptr<Expression>>
GVN::core_(Instruction *instr, GVN::valueExpr_core_(Instruction *instr,
const partitions &part, const partitions &part,
size_t count, const size_t count,
bool fold_) { bool fold_) {
assert(not(fold_ and count > 2)); assert(not(fold_ and count > 2));
...@@ -357,23 +452,13 @@ GVN::core_(Instruction *instr, ...@@ -357,23 +452,13 @@ GVN::core_(Instruction *instr,
std::vector<shared_ptr<Expression>> ret; std::vector<shared_ptr<Expression>> ret;
// if able to fold, then fold // if able to fold, then fold
fold_ &= bool(dynamic_cast<Constant *>(operands[0]));
if (count == 2)
fold_ &= bool(dynamic_cast<Constant *>(operands[1]));
if (fold_) { if (fold_) {
Constant *res; Constant *res = nullptr;
if (count == 1) { if ((res = constFold_core(count, part, instr, operands))) {
res =
folder_->compute(instr, dynamic_cast<Constant *>(operands[0]));
} else {
// count == 2
res = folder_->compute(instr,
dynamic_cast<Constant *>(operands[0]),
dynamic_cast<Constant *>(operands[1]));
}
ret.push_back(ConstantExpression::create(res)); ret.push_back(ConstantExpression::create(res));
return ret; return ret;
} }
}
// normal case: // normal case:
// - try to find expression that already exists // - try to find expression that already exists
...@@ -405,7 +490,7 @@ GVN::valueExpr(Instruction *instr, const partitions &part) { ...@@ -405,7 +490,7 @@ GVN::valueExpr(Instruction *instr, const partitions &part) {
return tmp; return tmp;
if (instr->isBinary() or instr->is_cmp() or instr->is_fcmp()) { if (instr->isBinary() or instr->is_cmp() or instr->is_fcmp()) {
res = core_(instr, part, 2); res = valueExpr_core_(instr, part, 2);
if (res.size() == 1) // constant fold if (res.size() == 1) // constant fold
return res[0]; return res[0];
else else
...@@ -414,7 +499,7 @@ GVN::valueExpr(Instruction *instr, const partitions &part) { ...@@ -414,7 +499,7 @@ GVN::valueExpr(Instruction *instr, const partitions &part) {
} else if (instr->is_phi()) { } else if (instr->is_phi()) {
err = "phi"; err = "phi";
} else if (instr->is_fp2si() or instr->is_si2fp() or instr->is_zext()) { } else if (instr->is_fp2si() or instr->is_si2fp() or instr->is_zext()) {
res = core_(instr, part, 1); res = valueExpr_core_(instr, part, 1);
if (res[0]->get_expr_type() == Expression::e_constant) if (res[0]->get_expr_type() == Expression::e_constant)
return res[0]; return res[0];
Type *dest_type; Type *dest_type;
...@@ -439,12 +524,16 @@ GVN::valueExpr(Instruction *instr, const partitions &part) { ...@@ -439,12 +524,16 @@ GVN::valueExpr(Instruction *instr, const partitions &part) {
instr->get_instr_type(), res[0], dest_type); instr->get_instr_type(), res[0], dest_type);
} }
} else if (instr->is_gep()) { } else if (instr->is_gep()) {
res = core_(instr, part, instr->get_operands().size(), false); res = valueExpr_core_(instr, part, instr->get_operands().size(), false);
auto ptr = res[0]; auto ptr = res[0];
res.erase(res.begin()); res.erase(res.begin());
return GEPExpression::create(ptr, res); return GEPExpression::create(ptr, res);
} else if (instr->is_load() or instr->is_alloca() or instr->is_call()) { } else if (instr->is_load() or instr->is_alloca() or instr->is_call()) {
return UniqueExpression::create(instr); auto ret = search_ve(instr, part);
if (ret)
return ret;
else
return UniqueExpression::create(instr, next_value_number_);
} }
std::cerr << "Undefined case: " << err << std::endl; std::cerr << "Undefined case: " << err << std::endl;
...@@ -459,8 +548,10 @@ GVN::valueExpr(Instruction *instr, const partitions &part) { ...@@ -459,8 +548,10 @@ GVN::valueExpr(Instruction *instr, const partitions &part) {
// //
/// \param bb basic block in which the transfer function is called /// \param bb basic block in which the transfer function is called
GVN::partitions GVN::partitions
GVN::transferFunction(Instruction *x, Value *e, partitions pin) { GVN::transferFunction(Instruction *instr, Value *e, partitions pin) {
partitions pout = pin; next_value_number_ = start_idx_[std::make_pair(instr, e)];
partitions pout = clone(pin);
// TODO: deal with copy-stmt case // TODO: deal with copy-stmt case
// ?? deal with copy statement // ?? deal with copy statement
auto e_instr = dynamic_cast<Instruction *>(e); auto e_instr = dynamic_cast<Instruction *>(e);
...@@ -469,10 +560,13 @@ GVN::transferFunction(Instruction *x, Value *e, partitions pin) { ...@@ -469,10 +560,13 @@ GVN::transferFunction(Instruction *x, Value *e, partitions pin) {
"A value must be from an instruction or constant"); "A value must be from an instruction or constant");
// erase the old record for x // erase the old record for x
std::set<Value *>::iterator it; std::set<Value *>::iterator it;
for (auto c : pin) for (auto c : pout)
if ((it = std::find(c->members_.begin(), c->members_.end(), x)) != if ((it = std::find(c->members_.begin(), c->members_.end(), instr)) !=
c->members_.end()) { c->members_.end()) {
c->members_.erase(it); c->members_.erase(it);
if (c->members_.empty())
pout.erase(c);
break;
} }
// TODO: get different ValueExpr by Instruction::OpID, modify pout // TODO: get different ValueExpr by Instruction::OpID, modify pout
...@@ -483,25 +577,29 @@ GVN::transferFunction(Instruction *x, Value *e, partitions pin) { ...@@ -483,25 +577,29 @@ GVN::transferFunction(Instruction *x, Value *e, partitions pin) {
if (e_const) if (e_const)
ve = ConstantExpression::create(e_const); ve = ConstantExpression::create(e_const);
else else
ve = valueExpr(e_instr, pin); ve = valueExpr(e_instr, pout);
} else } else
ve = valueExpr(x, pin); ve = valueExpr(instr, pout);
auto vpf = valuePhiFunc(ve, curr_bb); auto vpf = valuePhiFunc(ve, curr_bb, instr);
// TODO: set leader // TODO: set leader
for (auto c : pout) { for (auto c : pout) {
if (ve == c->value_expr_ or if (ve == c->value_expr_ or
(vpf and c->value_phi_ and *vpf == *c->value_phi_)) { (vpf and c->value_phi_ and *vpf == *c->value_phi_)) {
c->value_expr_ = ve; // c->value_expr_ = ve;
c->members_.insert(x); c->members_.insert(instr);
return pout; return pout;
} }
} }
auto c = createCongruenceClass(new_number()); auto c = createCongruenceClass(new_number());
c->members_.insert(x); c->members_.insert(instr);
c->leader_ = x;
c->value_expr_ = ve; c->value_expr_ = ve;
c->value_phi_ = vpf; c->value_phi_ = vpf;
if (c->value_expr_->get_expr_type() == Expression::e_constant)
c->leader_ =
static_cast<ConstantExpression *>(c->value_expr_.get())->get_val();
else
c->leader_ = instr;
pout.insert(c); pout.insert(c);
return pout; return pout;
} }
...@@ -520,8 +618,6 @@ GVN::transferFunction(BasicBlock *bb) { ...@@ -520,8 +618,6 @@ GVN::transferFunction(BasicBlock *bb) {
* utils::print_partitions(pin_[bb]); * utils::print_partitions(pin_[bb]);
* LOG_INFO << "pout before:\n"; * LOG_INFO << "pout before:\n";
* utils::print_partitions(pout_[bb]); */ * utils::print_partitions(pout_[bb]); */
std::cout << "for basic block " << bb->get_name() << ", pin:" << std::endl;
utils::print_partitions(pin_[bb]);
// iterate through all instructions in the block // iterate through all instructions in the block
for (auto &instr : bb->get_instructions()) { for (auto &instr : bb->get_instructions()) {
...@@ -539,39 +635,88 @@ GVN::transferFunction(BasicBlock *bb) { ...@@ -539,39 +635,88 @@ GVN::transferFunction(BasicBlock *bb) {
} }
} }
} }
/* LOG_INFO << "pout after:\n"; std::cout << "-------\n"
* utils::print_partitions(part); << "for basic block " << bb->get_name() << ", pout:" << std::endl;
* std::cout << std::endl; */ utils::print_partitions(part);
return part; return part;
} }
// NOTE: only instruction op matter
shared_ptr<PhiExpression> shared_ptr<PhiExpression>
GVN::valuePhiFunc(shared_ptr<Expression> ve, BasicBlock *bb) { GVN::valuePhiFunc(shared_ptr<Expression> ve,
BasicBlock *bb,
Instruction *instr) {
// TODO // TODO
// get 2 predecessors
auto pre_bbs_ = bb->get_pre_basic_blocks();
if (pre_bbs_.size() == 1)
return nullptr;
auto pre_1 = *pre_bbs_.begin();
auto pre_2 = *(++pre_bbs_.begin());
// check expression form
if (ve->get_expr_type() != Expression::e_bin) if (ve->get_expr_type() != Expression::e_bin)
return nullptr; return nullptr;
auto ve_bin = static_cast<BinaryExpression *>(ve.get()); auto ve_bin = static_cast<BinaryExpression *>(ve.get());
if (ve_bin->lhs_->get_expr_type() != Expression::e_phi or if (ve_bin->lhs_->get_expr_type() != Expression::e_phi and
ve_bin->rhs_->get_expr_type() != Expression::e_phi) ve_bin->rhs_->get_expr_type() != Expression::e_phi)
return nullptr; return nullptr;
shared_ptr<Expression> vi{}, vj{};
shared_ptr<BinaryExpression> vl_merge{}, vr_merge{};
shared_ptr<Expression> vl_merge_E{}, vr_merge_E{};
// get 2 phi expressions // get 2 phi expressions
auto lhs = static_cast<PhiExpression *>(ve_bin->lhs_.get()); auto lhs_phi = dynamic_cast<PhiExpression *>(ve_bin->lhs_.get());
auto rhs = static_cast<PhiExpression *>(ve_bin->rhs_.get()); auto rhs_phi = dynamic_cast<PhiExpression *>(ve_bin->rhs_.get());
// get 2 predecessors
auto pre_bbs_ = bb->get_pre_basic_blocks();
auto pre_1 = *pre_bbs_.begin();
auto pre_2 = *(++pre_bbs_.begin());
// set vl_merge and vr_merge
if (ve_bin->lhs_->get_expr_type() == Expression::e_phi and
ve_bin->rhs_->get_expr_type() == Expression::e_phi) {
// try to get the merged value expression // try to get the merged value expression
auto vl_merge = BinaryExpression::create(ve_bin->op_, lhs->lhs_, rhs->lhs_); vl_merge =
auto vr_merge = BinaryExpression::create(ve_bin->op_, lhs->rhs_, rhs->rhs_); BinaryExpression::create(ve_bin->op_, lhs_phi->lhs_, rhs_phi->lhs_);
auto vi = getVN(pout_[pre_1], vl_merge); vr_merge =
auto vj = getVN(pout_[pre_2], vr_merge); BinaryExpression::create(ve_bin->op_, lhs_phi->rhs_, rhs_phi->rhs_);
} else if (ve_bin->lhs_->get_expr_type() == Expression::e_phi) {
vl_merge =
BinaryExpression::create(ve_bin->op_, lhs_phi->lhs_, ve_bin->rhs_);
vr_merge =
BinaryExpression::create(ve_bin->op_, lhs_phi->rhs_, ve_bin->rhs_);
} else {
vl_merge =
BinaryExpression::create(ve_bin->op_, ve_bin->lhs_, rhs_phi->lhs_);
vr_merge =
BinaryExpression::create(ve_bin->op_, ve_bin->lhs_, rhs_phi->rhs_);
}
// constant fold
if (vl_merge->lhs_->get_expr_type() == Expression::e_constant and
vl_merge->rhs_->get_expr_type() == Expression::e_constant) {
auto vl_merge_l =
dynamic_cast<ConstantExpression *>(vl_merge->lhs_.get());
auto vl_merge_r =
dynamic_cast<ConstantExpression *>(vl_merge->rhs_.get());
vl_merge_E = ConstantExpression::create(folder_->compute(
instr, vl_merge_l->get_val(), vl_merge_r->get_val()));
} else
vl_merge_E = vl_merge;
if (vr_merge->lhs_->get_expr_type() == Expression::e_constant and
vr_merge->rhs_->get_expr_type() == Expression::e_constant) {
auto vr_merge_l =
dynamic_cast<ConstantExpression *>(vr_merge->lhs_.get());
auto vr_merge_r =
dynamic_cast<ConstantExpression *>(vr_merge->rhs_.get());
vr_merge_E = ConstantExpression::create(folder_->compute(
instr, vr_merge_l->get_val(), vr_merge_r->get_val()));
} else
vr_merge_E = vr_merge;
vi = getVN(pout_[pre_1], vl_merge_E);
vj = getVN(pout_[pre_2], vr_merge_E);
if (vi == nullptr) if (vi == nullptr)
vi = valuePhiFunc(vl_merge, pre_1); vi = valuePhiFunc(vl_merge_E, pre_1, instr);
if (vj == nullptr) if (vj == nullptr)
vj = valuePhiFunc(vr_merge, pre_2); vj = valuePhiFunc(vr_merge_E, pre_2, instr);
if (vi and vj) if (vi and vj)
return PhiExpression::create(vi, vj); return PhiExpression::create(vi, vj);
...@@ -688,6 +833,19 @@ GVN::run() { ...@@ -688,6 +833,19 @@ GVN::run() {
gvn_json << "]"; gvn_json << "]";
} }
void
GVN::dump_tmp(Function &f) {
std::string gvn_json;
if (dump_json_) {
gvn_json += "{\n\"function\": ";
gvn_json += "\"" + f.get_name() + "\", ";
gvn_json += "\n\"pout\": " + utils::dump_bb2partition(pout_);
gvn_json += "},";
}
gvn_json += "]";
std::cout << gvn_json << std::endl;
}
template <typename T> template <typename T>
static bool static bool
equiv_as(const Expression &lhs, const Expression &rhs) { equiv_as(const Expression &lhs, const Expression &rhs) {
...@@ -729,6 +887,7 @@ GVN::partitions ...@@ -729,6 +887,7 @@ GVN::partitions
GVN::clone(const partitions &p) { GVN::clone(const partitions &p) {
partitions data; partitions data;
for (auto &cc : p) { for (auto &cc : p) {
assert(not cc->members_.empty());
data.insert(std::make_shared<CongruenceClass>(*cc)); data.insert(std::make_shared<CongruenceClass>(*cc));
} }
return data; return data;
......
rm -rf *.ll rm -rf *.ll
rm -rf gvn.json rm -rf gvn.json
rm -rf `ls | grep -v "\."` rm -rf `ls | grep -v "\."`
rm -rf tmp*
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