P4C
The P4 Compiler
Loading...
Searching...
No Matches
live_range_split.h
1
19#ifndef BACKENDS_TOFINO_BF_P4C_PHV_LIVE_RANGE_SPLIT_H_
20#define BACKENDS_TOFINO_BF_P4C_PHV_LIVE_RANGE_SPLIT_H_
21
22#include <set>
23#include <vector>
24
25#include "phv/analysis/dark_live_range.h"
26#include "phv/fieldslice_live_range.h"
27#include "phv/phv_fields.h"
28
29namespace PHV {
30
31class AllocUtils;
32
36 int minStage;
37 int maxStage;
41 std::vector<bitvec> vec;
42 unsigned containerWidth;
43
45 unsigned vecIdx(PHV::StageAndAccess sa) const {
46 BUG_CHECK(sa.first >= minStage && sa.first <= maxStage,
47 "vecIdx (%1%) out of stage range [%2%, %3%]", sa.first, minStage, maxStage);
48 int stage = sa.first - minStage;
49 int offset = sa.second.isWrite() ? 1 : 0;
50 int val = stage * 2 + offset;
51 BUG_CHECK(val >= 0, "Invalid StageAndAccess stage %1%", val);
52 return static_cast<unsigned>(val);
53 }
54
66 std::vector<le_bitrange> availBitsAt(unsigned i, unsigned minLength);
67
68 friend std::ostream &operator<<(std::ostream &, const ContainerOccupancy &);
69
70 public:
71 ContainerOccupancy() : containerWidth(0) {}
72
73 ContainerOccupancy(int minStage, int maxStage, unsigned containerWidth)
74 : minStage(minStage),
75 maxStage(maxStage),
76 vec((maxStage - minStage + 1) * 2),
77 containerWidth(containerWidth) {
78 BUG_CHECK(minStage >= -1, "ContainerOccupancy minStage (%1%) must be >= -1");
79 BUG_CHECK(maxStage >= minStage, "Invalid ContainerOccupancy stage range (%1% > %2%)",
80 minStage, maxStage);
81 }
82
84 void setRange(StageAndAccess begin, StageAndAccess end, le_bitrange range);
85
89 std::vector<le_bitrange> availBitsAt(PHV::StageAndAccess sa, unsigned minLength = 0) {
90 return availBitsAt(vecIdx(sa), minLength);
91 }
92
93 bool isRangeAvailable(StageAndAccess begin, StageAndAccess end, le_bitrange range);
94};
95
99struct FreeSlice {
100 Container container;
101 le_bitrange range;
102 LiveRange lr;
103
104 bool operator==(const FreeSlice &c) const {
105 return container == c.container && range == c.range && lr.start == c.lr.start &&
106 lr.end == c.lr.end;
107 }
108 bool operator!=(const FreeSlice &c) const { return !(*this == c); }
109 bool operator<(const FreeSlice &c) const {
110 if (container != c.container) return container < c.container;
111 if (range != c.range) return range < c.range;
112 if (lr.start != c.lr.start) return lr.start < c.lr.start;
113 if (lr.end != c.lr.end) return lr.end < c.lr.end;
114 return false;
115 }
116
119 bool isFullyAvailableAt(int stage) const {
120 if (lr.start.first > stage || (lr.start.first == stage && !lr.start.second.isRead())) {
121 return false;
122 }
123 if (lr.end.first < stage || (lr.end.first == stage && !lr.end.second.isWrite())) {
124 return false;
125 }
126 return true;
127 }
128
129 friend std::ostream &operator<<(std::ostream &, const FreeSlice &);
130};
131
135 public:
139 using ContainerSequences = std::set<ContainerSequence>;
140
141 private:
142 static const FieldUse READ;
143 static const FieldUse WRITE;
144
145 const Allocation &alloc;
146 const PhvInfo &phvInfo;
147 const AllocUtils &utils;
148 const DependencyGraph &deps;
149 const std::list<ContainerGroup *> containerGroups;
150 const DarkLiveRangeMap &liveRangeMap;
151 const NonMochaDarkFields &nonMochaDark;
152
153 std::map<Container, ContainerGroup *> groupForContainer;
154 std::map<const Field *, std::set<StageAndAccess>> nonMochaStagesForField;
155 std::map<const Field *, std::set<StageAndAccess>> nonDarkStagesForField;
156
157 std::set<StageAndAccess> getMochaIncompatibleStagesForField(const Field *field) const;
158 std::set<StageAndAccess> getDarkIncompatibleStagesForField(const Field *field) const;
159
160 public:
161 explicit LiveRangeSplit(const Allocation &alloc, const PhvInfo &phv, const AllocUtils &utils,
162 const DependencyGraph &deps,
163 const std::list<ContainerGroup *> &containerGroups,
164 const DarkLiveRangeMap &liveRangeMap,
165 const NonMochaDarkFields &nonMochaDark);
166
168 std::set<FreeSlice> buildContainerOccupancy(StageAndAccess begin, StageAndAccess end,
169 const FieldSlice &fs) const;
170
172 ContainerSequences buildContainerSeqs(const std::set<FreeSlice> &avail, StageAndAccess begin,
173 StageAndAccess end) const;
174
178 ContainerSequences findLiveRangeSplits(StageAndAccess begin, StageAndAccess end,
179 const FieldSlice &fs) const;
180 ContainerSequences findLiveRangeSplits(const LiveRangeInfo &lri, const FieldSlice &fs) const;
181
182 static void report(const ContainerSequences &splits);
183};
184
198 std::function<const ConcreteAllocation *()> getAllocFn;
199 const std::list<const PHV::SuperCluster *> &unallocated;
200 PhvInfo &phv;
201 const PHV::AllocUtils &utils;
202 const DependencyGraph &deps;
203 const DarkLiveRangeMap &liveRangeMap;
204 const NonMochaDarkFields &nonMochaDark;
205
206 const IR::Node *apply_visitor(const IR::Node *root, const char *name = 0) override;
207
208 public:
209 LiveRangeSplitOrFail(std::function<const ConcreteAllocation *()> getAllocFn,
210 const std::list<const PHV::SuperCluster *> &unallocated, PhvInfo &phv,
211 const PHV::AllocUtils &utils, const DependencyGraph &deps,
212 const DarkLiveRangeMap &liveRangeMap,
213 const NonMochaDarkFields &nonMochaDark)
214 : getAllocFn(getAllocFn),
215 unallocated(unallocated),
216 phv(phv),
217 utils(utils),
218 deps(deps),
219 liveRangeMap(liveRangeMap),
220 nonMochaDark(nonMochaDark) {}
221};
222
223} // namespace PHV
224
225#endif /* BACKENDS_TOFINO_BF_P4C_PHV_LIVE_RANGE_SPLIT_H_ */
Definition dark_live_range.h:40
Definition non_mocha_dark_fields.h:29
Definition node.h:95
Definition visitor.h:75
Definition ordered_set.h:32
Definition phv/utils/utils.h:117
Definition phv/utils/utils.h:506
Definition phv.h:176
Definition live_range_split.h:35
void setRange(StageAndAccess begin, StageAndAccess end, le_bitrange range)
Set bits in range for stage span [begin, end].
Definition live_range_split.cpp:64
std::vector< le_bitrange > availBitsAt(PHV::StageAndAccess sa, unsigned minLength=0)
Definition live_range_split.h:89
Definition phv_fields.h:154
Definition phv_fields.h:898
Definition phv.h:248
Definition fieldslice_live_range.h:35
Definition live_range_split.h:134
ContainerSequences buildContainerSeqs(const std::set< FreeSlice > &avail, StageAndAccess begin, StageAndAccess end) const
Builds a list of all possible allocations.
Definition live_range_split.cpp:460
std::set< FreeSlice > buildContainerOccupancy(StageAndAccess begin, StageAndAccess end, const FieldSlice &fs) const
For each stage, find container (slices) that are available at each one.
Definition live_range_split.cpp:213
ContainerSequences findLiveRangeSplits(StageAndAccess begin, StageAndAccess end, const FieldSlice &fs) const
Definition live_range_split.cpp:567
Definition live_range_split.h:197
Definition phv_fields.h:1095
The namespace encapsulating PHV-related stuff.
Definition gateway.h:32
Definition table_dependency_graph.h:52
Definition allocate_phv.h:55
Definition live_range_split.h:99
bool isFullyAvailableAt(int stage) const
Definition live_range_split.h:119
Definition phv.h:309