1 //===-- evm/bblock.h - a single basic block --*- C++ -*-===//
3 // A basic block contains a list of instructions.
5 //===----------------------------------------------------------------------===//
7 #ifndef _JITCS_INT_DFGANALYSIS_H_
8 #define _JITCS_INT_DFGANALYSIS_H_
10 #include "jitcs_base.h"
11 #include "jitcs_ids.h"
12 #include "jitcs_adt_ref.h"
13 #include "jitcs_adt_slice.h"
14 #include "jitcs_int_adt_bitmap.h"
15 #include "jitcs_int_virtualregister.h"
16 #include "jitcs_int_function_impl.h"
31 enum { E_UseDefBits
= 2, E_UseDefMask
= (1 << E_UseDefBits
) - 1,
32 E_UseDefShift
= 0, E_Use
= 1, E_Def
= 2, E_UseDef
= E_Use
| E_Def
,
33 //E_SizeBits = 3, E_SizeMask = (1 << E_SizeBits) - 1,
34 //E_SizeShift = E_UseDefShift + E_UseDefBits,
35 //E_ResClassBits = 3, E_ResClassMask = (1 << E_ResClassBits) - 1,
36 //E_ResClassShift = E_SizeShift + E_SizeBits,
37 //E_ResClassShift = E_UseDefShift + E_UseDefBits,
38 E_ResShift
= E_UseDefShift
+ E_UseDefBits
};
44 ResId
getResId() { return static_cast<ResId
>(resInfo
>> E_ResShift
); }
45 //ResClassId getResClassId() {
46 // return static_cast<ResClassId>
47 // ((resInfo >> E_ResClassShift) & E_ResClassMask);
49 //u32 getResLogSize() { return ((resInfo >> E_SizeShift) & E_SizeMask); }
50 u32
getNext(BitSlice liveOut
) {
51 return nextUse
== ~1 ? (~0 ^ liveOut
.test(getResId())) : nextUse
;
53 u32
getUseDef() { return ((resInfo
>> E_UseDefShift
) & E_UseDefMask
); }
54 bool isUse() { return (resInfo
& E_Use
) != 0; }
55 bool isDef() { return (resInfo
& E_Def
) != 0; }
56 bool isUseOnly() { return (resInfo
& E_UseDefMask
) == E_Use
; }
57 bool isDefOnly() { return (resInfo
& E_UseDefMask
) == E_Def
; }
58 bool isUseDef() { return (resInfo
& E_UseDefMask
) == E_UseDef
; }
60 struct InstructionData
{
64 // for each resource class, the range of relevant resources can be
65 // extracted as ptr[RCL == 0 ? 0 : resClassEnd[RCL-1] .. resClassEnd[RCL]]
66 // - each range of resources starts with fixed register resources
67 // - the non-fixed register resources are ordered by increasing number of
68 // bits in the mask field
69 // - the bit of fixed resources is removed from non-fixed resources
70 // with overlapping life-range (concerning the instruction)
78 Slice
<InstructionData
> instructions
;
79 Slice
<NextData
> useRangeData
;
80 BitSlice useRangeIsValid
;
89 void init(FunctionImpl
& f
, AMode m
, Slice
<u32
> touchedFixed
);
90 void dump(IDumper
& o
) const;
92 bool isUsed(Ref
<BasicBlock
> bb
, Ref
<const VirtualRegister
> v
) const;
93 bool isDefined(Ref
<BasicBlock
> bb
, Ref
<const VirtualRegister
> v
) const;
94 bool isLiveIn(Ref
<BasicBlock
> bb
, Ref
<const VirtualRegister
> v
) const;
95 bool isLiveOut(Ref
<BasicBlock
> bb
, Ref
<const VirtualRegister
> v
) const;
97 bool isUsed(Ref
<BasicBlockImpl
> bb
, Ref
<const VirtualRegister
> v
) const;
98 bool isDefined(Ref
<BasicBlockImpl
> bb
, Ref
<const VirtualRegister
> v
) const;
99 bool isLiveIn(Ref
<BasicBlockImpl
> bb
, Ref
<const VirtualRegister
> v
) const;
100 bool isLiveOut(Ref
<BasicBlockImpl
> bb
, Ref
<const VirtualRegister
> v
) const;
102 void extractUseDef(Ref
<BasicBlockImpl
> bb
, size_t ins
,
103 BitSlice used
, BitSlice defined
) const;
108 Slice
<BlockData
> _blocks
;
111 struct GatherResourceList
{
119 Entry touchedResources
[NUM
];
120 u32 numFixed
, numNonFixed
;
122 ClassWise byClass
[8];
124 // --------------------
128 // --------------------
129 void addNonFixedDef(Ref
<const VirtualRegister
> r
, u32 mask
) {
130 _addNonFixed(r
->resclass
, _combine(r
), mask
, DFGAnalysis::ResourceData::E_Def
);
132 void addNonFixedUseDef(Ref
<const VirtualRegister
> r
, u32 mask
) {
133 _addNonFixed(r
->resclass
, _combine(r
), mask
, DFGAnalysis::ResourceData::E_UseDef
);
135 void addNonFixedUse(Ref
<const VirtualRegister
> r
, u32 mask
) {
136 _addNonFixed(r
->resclass
, _combine(r
), mask
, DFGAnalysis::ResourceData::E_Use
);
138 // --------------------
139 void addFixedDef(Ref
<const VirtualRegister
> r
, u32 mask
) {
140 _addFixed(r
->resclass
, _combine(r
), mask
, DFGAnalysis::ResourceData::E_Def
);
142 void addFixedUseDef(Ref
<const VirtualRegister
> r
, u32 mask
) {
143 _addFixed(r
->resclass
, _combine(r
), mask
, DFGAnalysis::ResourceData::E_UseDef
);
145 void addFixedUse(Ref
<const VirtualRegister
> r
, u32 mask
) {
146 _addFixed(r
->resclass
, _combine(r
), mask
, DFGAnalysis::ResourceData::E_Use
);
148 // --------------------
149 void addFixedDef(ResId res
, ResClassId rescl
, u32 mask
) {
150 _addFixed(rescl
, _combine(res
), mask
, DFGAnalysis::ResourceData::E_Def
);
152 void addFixedUseDef(ResId res
, ResClassId rescl
, u32 mask
) {
153 _addFixed(rescl
, _combine(res
), mask
, DFGAnalysis::ResourceData::E_UseDef
);
155 void addFixedUse(ResId res
, ResClassId rescl
, u32 mask
) {
156 _addFixed(rescl
, _combine(res
), mask
, DFGAnalysis::ResourceData::E_Use
);
160 u32
_combine(ResId res
) const {
161 return (res
<< DFGAnalysis::ResourceData::E_ResShift
);
163 u32
_combine(Ref
<const VirtualRegister
> r
) const {
164 return _combine(r
->res
);
166 void _addNonFixed(ResClassId
, u32 id
, u32 mask
, u32 usedef
);
167 void _addFixed(ResClassId
, u32 id
, u32 mask
, u32 usedef
);
170 class SetupBlockResourceInfo
{
172 SetupBlockResourceInfo(FunctionImpl
& f
);
173 SetupBlockResourceInfo() = delete;
174 SetupBlockResourceInfo(const SetupBlockResourceInfo
&) = delete;
175 SetupBlockResourceInfo
& operator =(const SetupBlockResourceInfo
&) = delete;
177 void init(Slice
<DFGAnalysis::InstructionData
> ins
,
178 BitSlice def
, BitSlice use
,
179 BitSlice nextValid
, Slice
<DFGAnalysis::NextData
> next
,
180 Slice
<u32
> touchedFixed
);
181 void push_front(GatherResourceList
&);
183 RefOrNull
<const VirtualRegister
> getFrameRegister(size_t fr
) {
184 return _f
.getFrameRegisterInfo(fr
).reg
;
188 Slice
<DFGAnalysis::InstructionData
> _ins
;
189 BitSlice _def
, _use
, _nextValid
;
190 Slice
<u32
> _touchedFixed
;
191 Slice
<DFGAnalysis::NextData
> _next
;
194 TempAllocator
&_alloc
;
195 Slice
<DFGAnalysis::ResourceData
> _remaining
;
199 } // end of namespace jitcs
202 // _JITCS_INT_DFGANALYSIS_H_