1 //===-- evm/bblock.h - a single basic block --*- C++ -*-===//
3 // A basic block contains a list of instructions.
5 //===----------------------------------------------------------------------===//
7 #ifndef _JITCS_INT_BBLOCK_IMPL_H_
8 #define _JITCS_INT_BBLOCK_IMPL_H_
10 #include "jitcs_adt_range.h"
11 #include "jitcs_adt_slice.h"
12 #include "jitcs_int_adt_tmpvector.h"
13 #include "jitcs_base.h"
14 #include "jitcs_bblock.h"
15 #include "jitcs_instruction.h"
22 class BasicBlockImpl
: public BasicBlock
{
24 // TODO: use structures that use TempAllocator
25 typedef TmpVector
<BasicBlockImpl
*, 2> BasicBlockList
;
26 typedef TmpVector
<Instruction
*, 8> InstructionList
;
28 typedef BasicBlockList::iterator bb_iterator
;
29 typedef BasicBlockList::const_iterator const_bb_iterator
;
30 typedef InstructionList::iterator ins_iterator
;
31 typedef InstructionList::const_iterator const_ins_iterator
;
32 typedef Range
<bb_iterator
> bb_range
;
33 typedef Range
<ins_iterator
> ins_range
;
34 typedef ConstRange
<const_bb_iterator
> const_bb_range
;
35 typedef ConstRange
<const_ins_iterator
> const_ins_range
;
38 static Ref
<BasicBlockImpl
> From(Ref
<BasicBlock
> s
) {
39 return reinterpret_cast<BasicBlockImpl
*>(s
._ptr
);
41 static Ref
<const BasicBlockImpl
> From(Ref
<const BasicBlock
> s
) {
42 return reinterpret_cast<const BasicBlockImpl
*>(s
._ptr
);
44 /*[[override]] virtual */ BasicBlockImpl
& impl() { return *this; }
45 /*[[override]] virtual */ const BasicBlockImpl
& impl() const { return *this; }
48 BasicBlockImpl(FunctionImpl
& f
, BBId id
);
49 ~BasicBlockImpl() = default;
50 BasicBlockImpl(const BasicBlockImpl
&) = delete;
51 void operator=(const BasicBlockImpl
&) = delete;
54 /*[[override]] virtual */ BBId
id() const { return _bbId
; }
55 RefOrNull
<BasicBlockImpl
> getFallThruFrom() const { return _bbFallThruFrom
; }
56 RefOrNull
<BasicBlockImpl
> getFallThruTo() const { return _bbFallThruTo
; }
58 size_t instr_size() const { return _listOfIns
.size(); }
59 Slice
<Instruction
*> insns() { return _listOfIns
; }
60 Slice
<const Instruction
*> cinsns() const {
61 return Slice
<const Instruction
*>
62 (const_cast<const Instruction
**>(_listOfIns
.ptr()),
66 bb_iterator
pred_begin() { return _predecessors
.begin(); }
67 bb_iterator
pred_end() { return _predecessors
.end(); }
68 const_bb_iterator
pred_begin() const { return pred_cbegin(); }
69 const_bb_iterator
pred_end() const { return pred_cend(); }
70 const_bb_iterator
pred_cbegin() const { return _predecessors
.begin(); }
71 const_bb_iterator
pred_cend() const { return _predecessors
.end(); }
73 bb_iterator
succ_begin() { return _successors
.begin(); }
74 bb_iterator
succ_end() { return _successors
.end(); }
75 const_bb_iterator
succ_begin() const { return succ_cbegin(); }
76 const_bb_iterator
succ_end() const { return succ_cend(); }
77 const_bb_iterator
succ_cbegin() const { return _successors
.begin(); }
78 const_bb_iterator
succ_cend() const { return _successors
.end(); }
80 ins_iterator
instr_begin() { return _listOfIns
.begin(); }
81 ins_iterator
instr_end() { return _listOfIns
.end(); }
82 const_ins_iterator
instr_begin() const { return instr_cbegin(); }
83 const_ins_iterator
instr_end() const { return instr_cend(); }
84 const_ins_iterator
instr_cbegin() const { return _listOfIns
.begin(); }
85 const_ins_iterator
instr_cend() const { return _listOfIns
.end(); }
87 bb_range
pred_range() { return bb_range(pred_begin(), pred_end()); }
88 const_bb_range
pred_range() const { return pred_crange(); }
89 const_bb_range
pred_crange() const { return const_bb_range(pred_cbegin(), pred_cend()); }
91 bb_range
succ_range() { return bb_range(succ_begin(), succ_end()); }
92 const_bb_range
succ_range() const { return succ_crange(); }
93 const_bb_range
succ_crange() const { return const_bb_range(succ_cbegin(), succ_cend()); }
95 ins_range
instr_range() { return ins_range(instr_begin(), instr_end()); }
96 const_ins_range
instr_range() const { return instr_crange(); }
97 const_ins_range
instr_crange() const { return const_ins_range(instr_cbegin(), instr_cend()); }
99 // std::vector<BBlock*> const* getPredecessors() const { return &_predecessors; }
100 // std::vector<BBlock*> const* getSuccessors() const { return &_successors; }
101 // std::vector<InsRef> const* getInstructions() const { return &_listOfIns; }
104 // methods for use when constructing basic blocks
105 // append: add a block of instructions to the basic block. the stream is broken down
106 // into individual instructions here. also, it must be ascertained, that the data pointed to by
107 // p is alive until the compilation of the function is complete. if in doubt, use append_copy
109 // append_copy: same as append, but copies data to the storage of a TempAllocator first.
110 /*[[override]] virtual */ size_t append(Slice
<iptr
>);
111 /*[[override]] virtual */ size_t append_copy(Slice
<const iptr
>);
113 // methods for fixing up the control flow graph
114 static void BuildEdge(Ref
<BasicBlockImpl
> fromBB
,
115 Ref
<BasicBlockImpl
> toBB
, bool isFallthru
);
116 static void SetFallthru(Ref
<BasicBlockImpl
> fromBB
,
117 Ref
<BasicBlockImpl
> toBB
);
119 void dump(MachineDumper
&) const;
123 TempAllocator
& _alloc
;
124 InstructionList _listOfIns
;
125 BasicBlockList _successors
, _predecessors
;
127 RefOrNull
<BasicBlockImpl
> _bbFallThruFrom
, _bbFallThruTo
;
130 //inline bool evm::NextData::isRegDead(BBlock* bb, ResId res) const {
131 // return isRegDead() || (isRegDeadOrLiveOut() && !bb->getLiveOut().test(res.id));
135 } // End jitcs namespace
138 // _JITCS_INT_BBLOCK_IMPL_H_