Commit bd7b44fb authored by 李晓奇's avatar 李晓奇

can pass functional

parent f268905c
...@@ -42,13 +42,23 @@ class ConstFolder { ...@@ -42,13 +42,23 @@ class ConstFolder {
class Expression { class Expression {
public: public:
// TODO: you need to extend expression types according to testcases // TODO: you need to extend expression types according to testcases
enum gvn_expr_t { e_constant, e_bin, e_phi, e_cast, e_gep, e_unique }; enum gvn_expr_t {
e_constant,
e_bin,
e_phi,
e_cast,
e_gep,
e_unique,
e_global,
e_argument,
e_call
};
Expression(gvn_expr_t t) : expr_type(t) {} Expression(gvn_expr_t t) : expr_type(t) {}
virtual ~Expression() = default; virtual ~Expression() = default;
virtual std::string print() = 0; virtual std::string print() = 0;
gvn_expr_t get_expr_type() const { return expr_type; } gvn_expr_t get_expr_type() const { return expr_type; }
private: protected:
gvn_expr_t expr_type; gvn_expr_t expr_type;
}; };
...@@ -198,7 +208,6 @@ class GEPExpression : public Expression { ...@@ -198,7 +208,6 @@ class GEPExpression : public Expression {
std::vector<std::shared_ptr<Expression>> idxs_; std::vector<std::shared_ptr<Expression>> idxs_;
}; };
// 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,
...@@ -213,13 +222,88 @@ class UniqueExpression : public Expression { ...@@ -213,13 +222,88 @@ class UniqueExpression : public Expression {
return instr_ == other->instr_; return instr_ == other->instr_;
} }
UniqueExpression(Instruction *instr, size_t index) UniqueExpression(Instruction *instr, size_t index, gvn_expr_t tp = e_unique)
: Expression(e_unique), instr_(instr), index_(index) {} : Expression(tp), instr_(instr), index_(index) {}
private: protected:
Instruction *instr_; Instruction *instr_;
size_t index_; size_t index_;
}; };
// global variables
class GlobalVarExpression : public Expression {
public:
static std::shared_ptr<GlobalVarExpression> create(GlobalVariable *g) {
return std::make_shared<GlobalVarExpression>(g);
}
virtual std::string print() { return "<" + g_->get_name() + ">"; }
bool equiv(const GlobalVarExpression *other) const {
return g_ == other->g_;
}
GlobalVarExpression(GlobalVariable *g) : Expression(e_global), g_(g) {}
private:
GlobalVariable *g_;
};
// this is the arguments passed to the current function, but not the arguments
// given to a function call.
class ArgExpression : public Expression {
public:
static std::shared_ptr<ArgExpression> create(Argument *a) {
return std::make_shared<ArgExpression>(a);
}
virtual std::string print() { return "[" + a_->get_name() + "]"; }
bool equiv(const ArgExpression *other) const { return a_ == other->a_; }
ArgExpression(Argument *a) : Expression(e_argument), a_(a) {}
private:
Argument *a_;
};
// function call
class CallExpression : public UniqueExpression {
public:
static std::shared_ptr<CallExpression> create(
Instruction *instr,
size_t index,
bool pure,
std::vector<std::shared_ptr<Expression>> &args) {
return std::make_shared<CallExpression>(instr, index, pure, args);
}
virtual std::string print() {
std::string ret = "{ " + f_->get_name();
for (auto arg : args_)
ret += " " + arg->print();
return ret + " }";
}
bool equiv(const CallExpression *other) const {
// single instruction, should be same
if (instr_ == other->instr_)
return true;
if (not(pure_ and f_ == other->f_))
return false;
for (int i = 0; i < args_.size(); i++)
if (not(*args_[i] == *other->args_[i]))
return false;
return true;
}
CallExpression(Instruction *instr,
size_t index,
bool pure,
std::vector<std::shared_ptr<Expression>> &args)
: UniqueExpression(instr, index, e_call)
, pure_(pure)
, f_(static_cast<Function *>(instr->get_operand(0)))
, args_(args) {}
private:
bool pure_;
Function *f_;
std::vector<std::shared_ptr<Expression>> args_;
};
} // namespace GVNExpression } // namespace GVNExpression
/** /**
...@@ -304,7 +388,7 @@ class GVN : public Pass { ...@@ -304,7 +388,7 @@ class GVN : public Pass {
private: private:
bool dump_json_; bool dump_json_;
std::uint64_t next_value_number_ = 1; std::uint64_t next_value_number_;
Function *func_; Function *func_;
std::map<BasicBlock *, partitions> pin_, pout_; std::map<BasicBlock *, partitions> pin_, pout_;
std::unique_ptr<FuncInfo> func_info_; std::unique_ptr<FuncInfo> func_info_;
...@@ -312,30 +396,38 @@ class GVN : public Pass { ...@@ -312,30 +396,38 @@ class GVN : public Pass {
std::unique_ptr<DeadCode> dce_; std::unique_ptr<DeadCode> dce_;
// self add member // self add member
std::map<BasicBlock *, bool> _TOP; // std::uint64_t start_number_;
partitions join_helper(BasicBlock *pre1, BasicBlock *pre2);
BasicBlock *curr_bb; BasicBlock *curr_bb;
std::map<BasicBlock *, bool> _TOP;
std::map<std::pair<Instruction *, Value *>, size_t> start_idx_; std::map<std::pair<Instruction *, Value *>, size_t> start_idx_;
std::map<GlobalVariable *,
std::shared_ptr<GVNExpression::GlobalVarExpression>>
global_map_;
std::map<Argument *, std::shared_ptr<GVNExpression::Expression>> arg_map_;
// //
// self add function // self add function
// //
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);
static int pretend_copy_stmt(Instruction *inst, BasicBlock *bb); static int pretend_copy_stmt(Instruction *inst, BasicBlock *bb);
std::shared_ptr<GVNExpression::Expression> search_ve( std::shared_ptr<GVNExpression::Expression> search_ve(
Value *v, Value *v,
const partitions &part); const partitions &part);
partitions join_helper(BasicBlock *pre1, BasicBlock *pre2);
std::vector<std::shared_ptr<GVNExpression::Expression>> valueExpr_core_( std::vector<std::shared_ptr<GVNExpression::Expression>> valueExpr_core_(
Instruction *instr, Instruction *instr,
const partitions &part, const partitions &part,
const size_t count, const size_t count,
bool fold_ = true); bool fold_ = false,
int start_index_ = 0);
Constant *constFold_core(const size_t count, Constant *constFold_core(const size_t count,
const partitions &part, const partitions &part,
Instruction *instr, Instruction *instr,
const std::vector<Value *> &operands); const std::vector<Value *> &operands);
void assign_start_idx_(); void assign_start_idx_();
void dump_tmp(Function &); void dump_tmp(Function &);
void reset_number() { next_value_number_ = 1; }
}; };
bool operator==(const GVN::partitions &p1, const GVN::partitions &p2); bool operator==(const GVN::partitions &p1, const GVN::partitions &p2);
This diff is collapsed.
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