Joos1W Compiler Framework
All Classes Functions Typedefs Pages
BasicBlock.cc
1 #include "tir/BasicBlock.h"
2 
3 #include <sstream>
4 
5 #include "tir/Constant.h"
6 #include "tir/Context.h"
7 #include "tir/Instructions.h"
8 #include "utils/DotPrinter.h"
9 
10 namespace tir {
11 
12 BasicBlock::BasicBlock(Context& ctx, Function* parent)
13  : Value{ctx, Type::getLabelTy(ctx)},
14  first_{nullptr},
15  last_{nullptr},
16  parent_{parent} {
17  parent->addBlock(this);
18  setName("bb");
19 }
20 
21 void BasicBlock::iterator_pimpl::next() {
22  // 1. The next instruction after beforeBegin is instr itself
23  if(beforeBegin) {
24  beforeBegin = false;
25  return;
26  }
27  // 2. Fetch the next instruction
28  auto* next = inst->next();
29  // 3. If it does not exist, we've entered afterEnd
30  if(next) {
31  inst = next;
32  } else {
33  afterEnd = true;
34  }
35 }
36 
37 void BasicBlock::iterator_pimpl::prev() {
38  // 1. The previous instruction before afterEnd is instr itself
39  if(afterEnd) {
40  afterEnd = false;
41  return;
42  }
43  // 2. Fetch the previous instruction
44  auto* prev = inst->prev();
45  // 3. If it does not exist, we've entered beforeBegin
46  if(prev) {
47  inst = prev;
48  } else {
49  beforeBegin = true;
50  }
51 }
52 
53 void BasicBlock::appendAfterEnd(Instruction* instr) {
54  if(last_) {
55  instr->insertAfter(last_);
56  last_ = instr;
57  } else {
58  first_ = last_ = instr;
59  }
60  instr->parent_ = this;
61 }
62 
63 void BasicBlock::insertBeforeBegin(Instruction* instr) {
64  if(first_) {
65  instr->insertBefore(first_);
66  first_ = instr;
67  } else {
68  first_ = last_ = instr;
69  }
70  instr->parent_ = this;
71 }
72 
73 std::ostream& BasicBlock::print(std::ostream& os) const {
74  printName(os) << ":";
75  for(auto inst : *this) {
76  os << "\n ";
77  inst->print(os);
78  }
79  return os;
80 }
81 
82 void BasicBlock::erase(Instruction* instr) {
83  assert(instr->parent_ == this && "Instruction does not belong to this BB");
85 }
86 
87 void BasicBlock::eraseFromParent() {
88  if(parent_ == nullptr) return;
89  parent_->removeBlock(this);
90 }
91 
92 int BasicBlock::printDotNode(utils::DotPrinter& dp) const {
93  auto id = dp.id();
94  dp.startTLabel(id, {}, "1");
95  std::ostringstream os;
96  print(os) << "\n";
97  dp.printTableSingleRow(os.str(), {}, true);
98  if(auto term = dyn_cast_or_null<BranchInst>(terminator())) {
99  if(term->getSuccessor(0) != term->getSuccessor(1))
100  dp.printTableDoubleRow("T", "F", {"port", "T"}, {"port", "F"});
101  }
102  dp.endTLabel();
103  return id;
104 }
105 
106 utils::Generator<BasicBlock*> BasicBlock::successors() const {
107  assert(terminator() && "Basic block has no terminator");
108  auto term = dyn_cast<BranchInst>(terminator());
109  if(term) {
110  co_yield term->getSuccessor(0);
111  if(term->getSuccessor(0) != term->getSuccessor(1)) {
112  co_yield term->getSuccessor(1);
113  }
114  }
115 }
116 
117 utils::Generator<BasicBlock*> BasicBlock::predecessors() const {
118  std::unordered_set<BasicBlock*> visited;
119  for(auto user : users()) {
120  if(auto term = dyn_cast<BranchInst>(user)) {
121  visited.insert(term->parent());
122  }
123  }
124  for(auto pred : visited) {
125  co_yield pred;
126  }
127 }
128 
129 } // namespace tir