42 using StageAndAccess = PHV::StageAndAccess;
43 using ReadWritePair = std::pair<const PHV::AllocSlice *, const PHV::AllocSlice *>;
46 using AccessInfo = std::pair<ordered_set<const IR::BFN::Unit *>,
bool>;
51 static constexpr unsigned READ = PHV::FieldUse::READ;
52 static constexpr unsigned WRITE = PHV::FieldUse::WRITE;
61 void setDeparserStageValue(
int dep) { DEPARSER = dep; }
63 int getDeparserStageValue()
const {
return DEPARSER; }
65 std::optional<Entry> getDarkLiveRange(
const PHV::Field *f)
const {
66 if (livemap.count(f))
return livemap.at(f);
70 void addAccess(
const PHV::Field *f,
int stage,
unsigned access,
const IR::BFN::Unit *unit,
72 StageAndAccess key = std::make_pair(stage,
PHV::FieldUse(access));
73 bool fieldEntryPresent = livemap.count(f);
74 bool accessEntryPresent = fieldEntryPresent && livemap.at(f).count(key);
75 if (!fieldEntryPresent || !accessEntryPresent) {
78 AccessInfo val = std::make_pair(units, dark);
79 livemap[f][key] = val;
82 livemap[f][key].first.insert(unit);
83 livemap[f][key].second &= dark;
86 void clear() { livemap.clear(); }
88 bool count(
const PHV::Field *f)
const {
return livemap.count(f); }
92 const AccessInfo &at(
const PHV::Field *f,
int stage,
unsigned access)
const {
93 StageAndAccess key = std::make_pair(stage,
PHV::FieldUse(access));
94 return livemap.at(f).at(key);
97 bool hasAccess(
const PHV::Field *f, StageAndAccess sa)
const {
98 return livemap.count(f) && livemap.at(f).count(sa);
101 bool hasAccess(
const PHV::Field *f,
int stage,
unsigned access)
const {
102 return hasAccess(f, std::make_pair(stage,
PHV::FieldUse(access)));
105 std::optional<StageAndAccess> getEarliestAccess(
const PHV::Field *f)
const;
106 std::optional<StageAndAccess> getLatestAccess(
const PHV::Field *f)
const;
117 static constexpr unsigned READ = PHV::FieldUse::READ;
118 static constexpr unsigned WRITE = PHV::FieldUse::WRITE;
119 static constexpr int PARSER = -1;
120 using StageAndAccess = PHV::StageAndAccess;
122 using AccessInfo = DarkLiveRangeMap::AccessInfo;
124 using ReadWritePair = std::pair<const PHV::AllocSlice *, const PHV::AllocSlice *>;
129 StageAndAccess minStage;
130 StageAndAccess maxStage;
137 minStage = std::make_pair(acc.first, acc.second);
138 maxStage = std::make_pair(acc.first, acc.second);
140 for (
const auto *u : a.first) {
142 const auto *tbl = u->to<IR::MAU::Table>();
144 LOG_DEBUG5(
"\t D. Add unit " << tbl->name.c_str() <<
" to slice " << field);
145 field.addRef(tbl->name, acc.second);
149 void addAccess(StageAndAccess s,
const AccessInfo &a) {
151 BUG_CHECK(minStage != s,
"New access cannot be the same as the min access.");
153 BUG_CHECK(maxStage != s,
"New access cannot be the same as the max access.");
156 BUG_CHECK(maxStage.first < s.first ||
157 (maxStage.first == s.first && maxStage.second < s.second),
158 "New access must be greater than max access.");
159 maxStage.first = s.first;
160 maxStage.second = s.second;
161 for (
const auto *u : a.first) {
163 const auto *tbl = u->to<IR::MAU::Table>();
165 LOG_DEBUG5(
"\t E. Add unit " << tbl->name.c_str() <<
" to slice " << field);
166 field.addRef(tbl->name, s.second);
171 if (field != other.field)
return false;
172 if (minStage != other.minStage)
return false;
173 if (maxStage != other.maxStage)
return false;
174 if (units.size() != other.units.size())
return false;
175 for (
const auto *u : units)
176 if (!other.units.count(u))
return false;
177 for (
const auto *u : other.units)
178 if (!units.count(u))
return false;
182 bool operator!=(
const OrderedFieldInfo &other)
const {
return !(*
this == other); }
189 for (
auto unit : units) {
190 const auto *tbl = unit->to<IR::MAU::Table>();
192 for (
auto stg_val : PhvInfo::minStages(tbl)) {
196 stage = std::min(stage, stg_val);
199 dg_stage = dg.min_stage(tbl);
201 dg_stage = std::min(dg_stage, dg.min_stage(tbl));
203 LOG_DEBUG6(TAB3
"Table: " << tbl->externalName()
204 <<
", phvInfo min-stage: " << stage);
205 LOG_DEBUG6(TAB3
"Table: " << tbl->externalName() <<
", DG min-stage: " << dg_stage);
208 return std::min(stage, dg_stage);
212 using OrderedFieldSummary = std::vector<OrderedFieldInfo>;
258 bool preorder(
const IR::MAU::Table *tbl)
override;
259 bool preorder(
const IR::MAU::Action *act)
override;
260 void end_apply()
override;
265 std::optional<OrderedFieldSummary> produceFieldsInOrder(
269 const int stage)
const;
271 bool validateLiveness(
const OrderedFieldSummary &slices)
const;
274 gress_t gress)
const;
276 bool increasesDependenceCriticalPath(
const IR::MAU::Table *use,
277 const IR::MAU::Table *init)
const;
279 std::optional<PHV::ActionSet> getInitActions(
const PHV::Container &c,
281 const IR::MAU::Table *t,
284 std::optional<PHV::DarkInitMap> getInitPointsForTable(
287 PHV::DarkInitMap &initMap,
bool moveLastFieldToDark,
bool initializeCurrentField,
295 const OrderedFieldSummary &fieldsInOrder)
const;
301 const OrderedFieldSummary &fieldsInOrder)
const;
305 bool cannotInitInAction(
const PHV::Container &c,
const IR::MAU::Action *action,
308 std::optional<PHV::DarkInitEntry *> getInitForLastFieldToDark(
313 std::optional<PHV::DarkInitEntry *> getInitForCurrentFieldFromDark(
317 std::optional<PHV::DarkInitEntry *> getInitForCurrentFieldWithZero(
319 const PHV::Transaction &alloc, std::optional<PHV::DarkInitEntry *>,
bool useARA)
const;
321 bool ignoreReachCondition(
323 const ordered_set<std::pair<const IR::BFN::Unit *, const IR::BFN::Unit *>> &conflicts)
326 bool isGroupDominatorEarlierThanFirstUseOfCurrentField(
328 const IR::MAU::Table *groupDominator)
const;
332 bool onlyReadCandidates)
const;
334 std::optional<PHV::DarkInitEntry> generateInitForLastStageAlwaysInit(
336 PHV::DarkInitMap &darkInitMap)
const;
338 std::optional<PHV::DarkInitEntry> generateARAzeroInit(
const OrderedFieldInfo &field,
341 bool onlyDeparserUse,
342 bool onlyReadCandidates)
const;
345 std::optional<PHV::DarkInitMap> findInitializationNodes(
348 bool prioritizeARAinits)
const;
359 noOverlay(pragmas.pa_no_overlay()),
362 actionConstraints(actions),
364 noInitFields(pragmas.pa_no_init().getFields()),
365 notParsedFields(pragmas.pa_deparser_zero().getNotParsedFields()),
366 notDeparsedFields(pragmas.pa_deparser_zero().getNotDeparsedFields()),
367 overlay(phv.dark_mutex()),
397 std::optional<PHV::DarkInitMap> findInitializationNodes(
400 bool prioritizeARAinits)
const {
401 if (!suitableForDarkOverlay(slice)) {
402 LOG_FEATURE(
"alloc_progress", 5,
403 TAB2
"Dark overlay candidate " << slice <<
" not a good fit for container "
404 << slice.container());
410 for (
auto &sl : alloced) {
415 BUG_CHECK(c == sl.container(),
416 "Containers for dark overlay candidates are different.");
418 BUG_CHECK(c !=
PHV::Container(),
"Container candidate for dark overlay cannot be NULL.");
419 BUG_CHECK(c == slice.container(),
"Needs to be the same container");
421 return initNode.findInitializationNodes(group, c, fields, alloc, canUseARA,
425 const DarkLiveRangeMap &getLiveMap()
const {
return initNode.getLiveMap(); }
static bool overlaps(const int num_max_min_stages, const DarkLiveRangeEntry &range1, const DarkLiveRangeEntry &range2)
Definition dark_live_range.cpp:29
void info(const int kind, const char *format, const T *node, Args &&...args)
Report info messages of type kind. Requires that the node argument have source info.
Definition lib/error.h:148