4 #include "utils/DotPrinter.h"
5 #include "utils/Generator.h"
12 class BasicBlock
final :
public Value {
17 struct iterator_pimpl {
26 bool equal(
const iterator_pimpl& other)
const {
27 return afterEnd == other.afterEnd && beforeBegin == other.beforeBegin &&
37 friend class BasicBlock;
38 iterator_impl(
Instruction* inst, T bb,
bool afterEnd,
bool beforeBegin)
39 : pimpl_{afterEnd, beforeBegin, inst}, bb_{bb} {}
42 iterator_impl() : pimpl_{
true,
false,
nullptr} {}
44 assert(!pimpl_.beforeBegin && !pimpl_.afterEnd);
48 assert(!pimpl_.beforeBegin && !pimpl_.afterEnd);
51 iterator_impl& operator++() {
55 iterator_impl& operator--() {
59 bool operator==(
const iterator_impl& other)
const {
60 return pimpl_.equal(other.pimpl_);
62 bool operator!=(
const iterator_impl& other)
const {
63 return !(*
this == other);
65 T getBB()
const {
return bb_; }
67 bool isBeforeFirst()
const {
return pimpl_.beforeBegin; }
69 bool isAfterLast()
const {
return pimpl_.afterEnd; }
73 iterator_pimpl pimpl_;
91 using iterator = iterator_impl<BasicBlock*>;
94 using const_iterator = iterator_impl<
const BasicBlock*>;
97 BasicBlock(
Context& ctx, Function* parent);
100 static BasicBlock* Create(
Context& ctx, Function* parent) {
102 ctx.alloc().allocate_bytes(
sizeof(BasicBlock),
alignof(BasicBlock));
103 return new(buf) BasicBlock{ctx, parent};
106 auto* parent()
const {
return parent_; }
108 auto begin() {
return iterator{first_,
this, first_ ==
nullptr,
false}; }
110 auto end() {
return iterator{last_,
this,
true,
false}; }
113 return const_iterator{first_,
this, first_ ==
nullptr,
false};
116 auto end()
const {
return const_iterator{last_,
this,
true,
false}; }
122 std::ostream& print(std::ostream& os)
const override;
124 auto* terminator()
const {
return last_; }
128 void eraseFromParent();
132 utils::
Generator<BasicBlock*> successors()
const;
134 utils::
Generator<BasicBlock*> predecessors()
const;