#include #include #include "triton/ir/basic_block.h" #include "triton/ir/instructions.h" #include "triton/ir/type.h" #include "triton/ir/function.h" namespace triton { namespace ir { class phi_node; basic_block::basic_block(context &ctx, const std::string &name, function *parent, basic_block* next): value(type::get_label_ty(ctx), name), ctx_(ctx), parent_(parent) { if(parent_) parent_->insert_block(this, next); } basic_block* basic_block::create(context &ctx, const std::string &name, function *parent, basic_block* next){ return new basic_block(ctx, name, parent, next); } void basic_block::replace_phi_uses_with(basic_block* before, basic_block* after) { for(ir::instruction* i: inst_list_){ auto* curr_phi = dynamic_cast(i); if(!curr_phi) break; // curr_phi->replace_uses_of_with(before, after); for (size_t idx = 0; idx < curr_phi->get_num_incoming(); ++idx) if (curr_phi->get_incoming_block(idx) == before) curr_phi->set_incoming_block(idx, after); } } void basic_block::append_instruction(ir::instruction* i){ i->set_parent(this); inst_list_.push_back(i); } basic_block* basic_block::split_before(ir::instruction* loc, const std::string& name) { basic_block* ret = basic_block::create(ctx_, name, parent_, this); ret->set_name(get_name()); set_name("after_" + name); // splice instruction list auto loc_it = std::find(inst_list_.begin(), inst_list_.end(), loc); ret->get_inst_list().splice(ret->get_inst_list().begin(), inst_list_, inst_list_.begin(), loc_it); for(ir::instruction* i: ret->get_inst_list()) i->set_parent(ret); // the predecessors of `this` becomes the predecessors of `ret` for(ir::basic_block* pred: get_predecessors()){ auto* term = dynamic_cast(pred->get_inst_list().back()); assert(term); term->replace_uses_of_with(this, ret); replace_phi_uses_with(pred, ret); } ir::branch_inst* br = branch_inst::create(this); ret->append_instruction(br); return ret; } std::vector basic_block::get_predecessors() const { std::vector ret; for(ir::user* u: users_) if(auto term = dynamic_cast(u)) ret.push_back(term->get_parent()); return ret; } std::vector basic_block::get_successors() const { std::vector ret; for(ir::instruction* i: inst_list_) for(ir::value* v: i->ops()) if(auto block = dynamic_cast(v)) ret.push_back(block); return ret; } basic_block::iterator basic_block::get_first_non_phi(){ auto it = begin(); for(; it != end(); it++) if(!dynamic_cast(*it)){ return it; } return it; } } }