[ast] laying down the ground work for on-the-fly phi-node simplification

This commit is contained in:
Philippe Tillet
2019-01-06 15:16:02 -05:00
parent 6bfceae4a6
commit 179890c7ad
8 changed files with 60 additions and 14 deletions

View File

@@ -23,7 +23,7 @@ void test(fp32 *A, fp32 *B, fp32 *C, int32 i){\
int32 j = 1;\ int32 j = 1;\
int32 k;\ int32 k;\
i = i + j;\ i = i + j;\
for(k = 0; k < 10; k = k+1){\ for(k = 0; k < 10; k = k+5){\
int32 u = 1;\ int32 u = 1;\
u = u + i;\ u = u + i;\
if(k == 0)\ if(k == 0)\

View File

@@ -187,7 +187,9 @@ void lowering(ir::module &src, Module &dst){
for(unsigned i = 0; i < phi->get_num_incoming(); i++){ for(unsigned i = 0; i < phi->get_num_incoming(); i++){
ir::value *inc_val = phi->get_incoming_value(i); ir::value *inc_val = phi->get_incoming_value(i);
ir::basic_block *inc_block = phi->get_incoming_block(i); ir::basic_block *inc_block = phi->get_incoming_block(i);
dst_phi->addIncoming(vmap[inc_val], bmap[inc_block]); Value *llvm_inc_val = llvm_value(inc_val, dst_ctx, vmap, bmap);
BasicBlock *llvm_block = bmap[inc_block];
dst_phi->addIncoming(llvm_inc_val, llvm_block);
} }
} }
} }

View File

@@ -30,6 +30,7 @@ public:
private: private:
phi_node *make_phi(type *ty, unsigned num_values, basic_block *block); phi_node *make_phi(type *ty, unsigned num_values, basic_block *block);
value *try_remove_trivial_phis(ir::phi_node *&phi);
value *add_phi_operands(const std::string& name, phi_node *&phi); value *add_phi_operands(const std::string& name, phi_node *&phi);
value *get_value_recursive(const std::string& name, basic_block *block); value *get_value_recursive(const std::string& name, basic_block *block);
void push_function(function *fn) { functions_.push_back(fn); } void push_function(function *fn) { functions_.push_back(fn); }

View File

@@ -10,6 +10,7 @@ namespace ir{
class type; class type;
class use; class use;
class user;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// value class // value class
@@ -21,7 +22,9 @@ public:
value(type *ty, const std::string &name = ""); value(type *ty, const std::string &name = "");
virtual ~value(){ } virtual ~value(){ }
// uses // uses
void add_use(use *arg); void add_use(use arg);
const std::vector<use> &get_uses() { return uses_; }
virtual void replace_all_uses_with(value *target);
// name // name
void set_name(const std::string &name); void set_name(const std::string &name);
const std::string &get_name() const { return name_; } const std::string &get_name() const { return name_; }
@@ -30,6 +33,9 @@ public:
private: private:
type *ty_; type *ty_;
std::string name_; std::string name_;
protected:
std::vector<use> uses_;
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -78,6 +84,9 @@ public:
value *get_operand(unsigned i); value *get_operand(unsigned i);
unsigned get_num_operands() const ; unsigned get_num_operands() const ;
// Utils
void replace_all_uses_with(value *target);
private: private:
std::vector<use> ops_; std::vector<use> ops_;
}; };

View File

@@ -105,7 +105,6 @@ ir::value* function_definition::codegen(ir::module *mod) const{
mod->seal_block(entry); mod->seal_block(entry);
mod->get_builder().set_insert_point(entry); mod->get_builder().set_insert_point(entry);
body_->codegen(mod); body_->codegen(mod);
std::cout << mod->get_builder().get_insert_block()->get_name() << std::endl;
mod->get_builder().create_ret_void(); mod->get_builder().create_ret_void();
return nullptr; return nullptr;
} }

View File

@@ -26,7 +26,9 @@ instruction::instruction(type *ty, unsigned num_ops, const std::string &name, in
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
phi_node::phi_node(type *ty, unsigned num_reserved, std::string const &name, instruction *next) phi_node::phi_node(type *ty, unsigned num_reserved, std::string const &name, instruction *next)
: instruction(ty, num_reserved, name, next), blocks_(num_reserved){ } : instruction(ty, 0, name, next) {
blocks_.reserve(num_reserved);
}
// Set incoming value // Set incoming value
void phi_node::set_incoming_value(unsigned i, value *v){ void phi_node::set_incoming_value(unsigned i, value *v){
@@ -44,11 +46,8 @@ void phi_node::set_incoming_block(unsigned i, basic_block *block){
// Add incoming // Add incoming
void phi_node::add_incoming(value *v, basic_block *block){ void phi_node::add_incoming(value *v, basic_block *block){
if(get_num_operands()==num_reserved_){ resize_ops(get_num_operands() + 1);
num_reserved_++; blocks_.resize(get_num_operands() + 1);
resize_ops(num_reserved_);
blocks_.resize(num_reserved_);
}
set_incoming_value(get_num_operands() - 1, v); set_incoming_value(get_num_operands() - 1, v);
set_incoming_block(get_num_operands() - 1, block); set_incoming_block(get_num_operands() - 1, block);
} }

View File

@@ -39,13 +39,34 @@ ir::phi_node* module::make_phi(ir::type *ty, unsigned num_values, ir::basic_bloc
return res; return res;
} }
ir::value *module::try_remove_trivial_phis(ir::phi_node *&phi){
ir::value *same = nullptr;
for(ir::value *op: phi->ops()){
// unique value or self-reference
if(op == same || op == phi)
continue;
// the phi-node merges at least two values; non-trivial
if(same)
return phi;
same = op;
}
assert(same && "the phi-node is unreachable or in the start block");
std::vector<ir::use> uses = phi->get_uses();
phi->replace_all_uses_with(same);
for(ir::use &u: uses)
if(auto *uphi = dynamic_cast<ir::phi_node*>(u.get()))
if(uphi != phi)
try_remove_trivial_phis(uphi);
return same;
}
ir::value *module::add_phi_operands(const std::string& name, ir::phi_node *&phi){ ir::value *module::add_phi_operands(const std::string& name, ir::phi_node *&phi){
ir::basic_block *block = phi->get_parent(); ir::basic_block *block = phi->get_parent();
for(ir::basic_block *pred: block->get_predecessors()){ for(ir::basic_block *pred: block->get_predecessors()){
ir::value *value = get_value(name, pred); ir::value *value = get_value(name, pred);
phi->add_incoming(value, pred); phi->add_incoming(value, pred);
} }
return phi; return try_remove_trivial_phis(phi);
} }
ir::value *module::get_value_recursive(const std::string& name, ir::basic_block *block) { ir::value *module::get_value_recursive(const std::string& name, ir::basic_block *block) {

View File

@@ -14,17 +14,26 @@ value::value(type *ty, const std::string &name): ty_(ty){
set_name(name); set_name(name);
} }
void value::add_use(use arg) {
uses_.push_back(arg);
}
// TODO: automatic naming scheme + update symbol table // TODO: automatic naming scheme + update symbol table
void value::set_name(const std::string &name){ void value::set_name(const std::string &name){
name_ = name; name_ = name;
} }
void value::replace_all_uses_with(value *target){
throw std::runtime_error("not implemented");
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// use class // use class
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void use::set(value *val){ void use::set(value *val){
val_ = val; val_ = val;
val_->add_use(*this);
} }
value *use::operator=(value *rhs){ value *use::operator=(value *rhs){
@@ -54,5 +63,11 @@ unsigned user::get_num_operands() const{
return ops_.size(); return ops_.size();
} }
void user::replace_all_uses_with(value *target) {
for(use &u: uses_){
u.set(target);
}
}
} }
} }