1#include <iostream>
2#include <algorithm>
3#include "triton/ir/basic_block.h"
4#include "triton/ir/instructions.h"
5#include "triton/ir/type.h"
6#include "triton/ir/function.h"
7
8namespace triton {
9namespace ir {
10
11class phi_node;
12
13
14basic_block::basic_block(context &ctx, const std::string &name, function *parent, basic_block* next):
15 value(type::get_label_ty(ctx), name), ctx_(ctx), parent_(parent) {
16 if(parent_)
17 parent_->insert_block(this, next);
18}
19
20basic_block* basic_block::create(context &ctx, const std::string &name, function *parent, basic_block* next){
21 return new basic_block(ctx, name, parent, next);
22}
23
24void basic_block::replace_phi_uses_with(basic_block* before, basic_block* after) {
25 for(ir::instruction* i: inst_list_){
26 auto* curr_phi = dynamic_cast<ir::phi_node*>(i);
27 if(!curr_phi)
28 break;
29 // curr_phi->replace_uses_of_with(before, after);
30 for (size_t idx = 0; idx < curr_phi->get_num_incoming(); ++idx)
31 if (curr_phi->get_incoming_block(idx) == before)
32 curr_phi->set_incoming_block(idx, after);
33 }
34}
35
36void basic_block::append_instruction(ir::instruction* i){
37 i->set_parent(this);
38 inst_list_.push_back(i);
39}
40
41basic_block* basic_block::split_before(ir::instruction* loc, const std::string& name) {
42 basic_block* ret = basic_block::create(ctx_, name, parent_, this);
43 ret->set_name(get_name());
44 set_name("after_" + name);
45
46 // splice instruction list
47 auto loc_it = std::find(inst_list_.begin(), inst_list_.end(), loc);
48 ret->get_inst_list().splice(ret->get_inst_list().begin(), inst_list_, inst_list_.begin(), loc_it);
49 for(ir::instruction* i: ret->get_inst_list())
50 i->set_parent(ret);
51 // the predecessors of `this` becomes the predecessors of `ret`
52 for(ir::basic_block* pred: get_predecessors()){
53 auto* term = dynamic_cast<ir::terminator_inst*>(pred->get_inst_list().back());
54 assert(term);
55 term->replace_uses_of_with(this, ret);
56 replace_phi_uses_with(pred, ret);
57 }
58 ir::branch_inst* br = branch_inst::create(this);
59 ret->append_instruction(br);
60 return ret;
61}
62
63std::vector<basic_block*> basic_block::get_predecessors() const {
64 std::vector<basic_block*> ret;
65 for(ir::user* u: users_)
66 if(auto term = dynamic_cast<ir::terminator_inst*>(u))
67 ret.push_back(term->get_parent());
68 return ret;
69}
70
71std::vector<basic_block*> basic_block::get_successors() const {
72 std::vector<basic_block*> ret;
73 for(ir::instruction* i: inst_list_)
74 for(ir::value* v: i->ops())
75 if(auto block = dynamic_cast<ir::basic_block*>(v))
76 ret.push_back(block);
77 return ret;
78}
79
80basic_block::iterator basic_block::get_first_non_phi(){
81 auto it = begin();
82 for(; it != end(); it++)
83 if(!dynamic_cast<phi_node*>(*it)){
84 return it;
85 }
86 return it;
87}
88
89}
90
91}
92