51class TablePlacement :
public PassManager {
73 const IR::MAU::Table *table;
88 static int placement_round;
90 bool can_split(
const IR::MAU::Table *,
const IR::MAU::AttachedMemory *);
92 std::map<const IR::MAU::Table *, struct TableInfo> tblInfo;
93 std::vector<struct TableInfo *> tblByUid;
94 std::map<cstring, struct TableInfo *> tblByName;
95 std::map<const IR::MAU::TableSeq *, struct TableSeqInfo> seqInfo;
96 std::map<const IR::MAU::AttachedMemory *, ordered_set<const IR::MAU::Table *>> attached_to;
97 std::set<const IR::MAU::Table *> not_eligible;
98 int uid(
const IR::MAU::Table *t) {
return tblInfo.at(t).uid; }
99 int uid(
cstring t) {
return tblByName.at(t)->uid; }
100 int uid(
const IR::MAU::TableSeq *t) {
101 if (seqInfo.count(t) == 0)
return -1;
102 return seqInfo.at(t).uid;
104 const IR::MAU::Table *getTblByName(cstring t) {
105 if (
auto *ti = get(tblByName, t)) {
108 LOG5(
"No tbl info found for table : " << t);
113 TablePlacement(
const BFN_Options &, DependencyGraph &,
const TablesMutuallyExclusive &,
114 PhvInfo &, LayoutChoices &,
const SharedIndirectAttachedAnalysis &,
115 SplitAttachedInfo &, TableSummary &, MauBacktracker &);
118 bool limit_tmp_creation;
119 explicit FinalRerunTablePlacementTrigger(
bool l)
122 DECLARE_TYPEINFO(FinalRerunTablePlacementTrigger);
126 GatewayMergeChoices gateway_merge_choices(
const IR::MAU::Table *table);
138 DOWNWARD_DOM_FRONTIER,
146 bool backtrack(trigger &)
override;
154 attached_entries_t attached_entries;
156 std::map<cstring, std::map<cstring, RejectReason>> rejected_placements;
157 void reject_placement(
const Placed *of, choice_t reason,
const Placed *better);
160 std::array<bool, 3> table_in_gress = {{
false,
false,
false}};
161 cstring error_message;
162 bool ignoreContainerConflicts =
false;
163 bool limit_tmp_creation =
false;
164 std::array<const IR::MAU::Table *, 2> starter_pistol = {{
nullptr,
nullptr}};
165 bool alloc_done =
false;
167 profile_t init_apply(
const IR::Node *root)
override;
168 void end_apply()
override { placement_round++; };
170 bool try_pick_layout(
const gress_t &gress, std::vector<Placed *> tables_to_allocate,
171 std::vector<Placed *> tables_placed);
172 bool try_alloc_adb(
const gress_t &gress, std::vector<Placed *> tables_to_allocate,
173 std::vector<Placed *> tables_placed);
174 bool try_alloc_imem(
const gress_t &gress, std::vector<Placed *> tables_to_allocate,
175 std::vector<Placed *> tables_placed);
177 bool try_alloc_ixbar(
Placed *next, std::vector<Placed *> allocated_layout);
178 bool try_alloc_format(
Placed *next,
bool gw_linked);
179 bool try_alloc_mem(
Placed *next, std::vector<Placed *> whole_stage);
180 void setup_detached_gateway(IR::MAU::Table *tbl,
const Placed *placed);
181 void filter_layout_options(
Placed *pl);
182 bool disable_split_layout(
const IR::MAU::Table *tbl);
184 bool shrink_attached_tbl(
Placed *next,
bool first_time,
bool &done_shrink);
185 bool shrink_estimate(
Placed *next,
int &srams_left,
int &tcams_left,
int min_entries);
186 bool shrink_preferred_lo(
Placed *next);
187 TableSummary::PlacementResult try_alloc_all(
Placed *next, std::vector<Placed *> whole_stage,
188 const char *what,
bool no_memory =
false);
189 bool initial_stage_and_entries(TablePlacement::Placed *rv,
int &furthest_stage);
190 Placed *try_place_table(
Placed *rv,
const StageUseEstimate ¤t,
191 const TableSummary::PlacedTable *pt =
nullptr);
192 safe_vector<Placed *> try_place_table(
const IR::MAU::Table *t,
const Placed *done,
193 const StageUseEstimate ¤t, GatewayMergeChoices &gmc,
194 const TableSummary::PlacedTable *pt =
nullptr);
196 friend std::ostream &operator<<(std::ostream &out, choice_t choice);
199 const StageUseEstimate ¤t);
201 std::multimap<cstring, const Placed *> table_placed;
202 std::multimap<cstring, const Placed *>::const_iterator find_placed(cstring name)
const;
203 void find_dependency_stages(
204 const IR::MAU::Table *tbl,
205 std::map<
int, ordered_map<const Placed *, DependencyGraph::dependencies_t>> &)
const;
207 template <
class... Args>
208 void error(Args... args) {
210 auto msg = ctxt.errorReporter().format_message(args...);
211 LOG5(
" defer error: " << msg);
212 summary.addPlacementError(msg);
214 int errorCount()
const {
return P4::errorCount() + summary.placementErrorCount(); }
240 std::map<cstring, save_placement_t> saved_placements;
241 int backtrack_count = 0;
242 int MaxBacktracksPerPipe = 32;
243 bool resource_mode =
false;
244 std::map<cstring, std::set<int>> bt_attempts;
247 std::optional<BacktrackPlacement *> find_previous_placement(
const Placed *best,
int offset,
248 bool local_bt,
int process_stage);
249 std::optional<BacktrackPlacement *> find_backtrack_point(
const Placed *,
int,
bool);
250 bool is_better(
const Placed *,
const Placed *, TablePlacement::choice_t &);
251 int get_control_anti_split_adj_score(
const Placed *)
const;
256 bool preorder(
const IR::BFN::Pipe *)
override;
260 bool are_metadata_deps_satisfied(
const Placed *placed,
const IR::MAU::Table *t)
const;
261 Placed *try_backfill_table(
const Placed *done,
const IR::MAU::Table *tbl,
cstring before);
262 bool can_place_with_partly_placed(
const IR::MAU::Table *tbl,
264 const Placed *placed);
265 bool gateway_thread_can_start(
const IR::MAU::Table *,
const Placed *placed);
266 IR::MAU::Table *create_starter_table(gress_t gress);
268 template <
class... Args>
269 void error(Args... args) {
272 int errorCount()
const {
return self.errorCount(); }
273 std::pair<bool, const Placed *> alt_table_placement(
const IR::BFN::Pipe *pipe);
274 const Placed *default_table_placement(
const IR::BFN::Pipe *pipe);
287 IR::Node *preorder(IR::MAU::TableSeq *)
override;
288 IR::Node *postorder(IR::MAU::TableSeq *)
override;
289 IR::Node *preorder(IR::MAU::Table *)
override;
290 IR::Node *postorder(IR::MAU::Table *)
override;
291 IR::Node *preorder(IR::MAU::BackendAttached *)
override;
292 IR::Node *preorder(IR::BFN::Pipe *pipe)
override;
293 IR::Node *postorder(IR::BFN::Pipe *pipe)
override;
295 IR::MAU::Table::Layout &gw_layout);
297 int stage_table = -1, IR::MAU::Table **last =
nullptr);
300 int stage_table = -1);
301 void table_set_resources(IR::MAU::Table *tbl,
const TableResourceAlloc *res,
const int entries);
302 template <
class... Args>
303 void error(Args... args) {
306 int errorCount()
const {
return self.errorCount(); }
311class MergeAlwaysRunActions :
public PassManager {
314 using TableFieldSlices = std::map<IR::MAU::Table *, PHV::FieldSlice>;
316 struct AlwaysRunKey {
320 bool operator<(
const AlwaysRunKey &ark)
const {
321 if (stage != ark.stage)
return stage < ark.stage;
322 return gress < ark.gress;
325 AlwaysRunKey(
int s, gress_t g) : stage(s), gress(g) {}
328 std::map<AlwaysRunKey, ordered_set<const IR::MAU::Table *>> ar_tables_per_stage;
329 std::map<AlwaysRunKey, const IR::MAU::Table *> merge_per_stage;
330 std::map<AlwaysRunKey, std::set<int>> merged_ar_minStages;
336 typedef std::map<const IR::MAU::Table *, int> premerge_table_stg_t;
340 bool mergedARAwitNewStage;
343 auto rv = PassManager::init_apply(node);
344 ar_tables_per_stage.clear();
345 merge_per_stage.clear();
346 merged_ar_minStages.clear();
347 written_fldSlice.clear();
348 read_fldSlice.clear();
349 premergeLRstart.clear();
350 premergeLRend.clear();
351 mergedARAwitNewStage =
false;
354 LOG7(
"MIN STAGE DEPARSER stage: " << self.phv.getDeparserStage());
355 LOG7(PhvInfo::reportMinStages());
356 LOG7(
"DG DEPARSER stage: " << (self.deps.max_min_stage + 1));
363 MergeAlwaysRunActions &self;
364 bool preorder(
const IR::MAU::Table *)
override;
365 bool preorder(
const IR::MAU::Primitive *)
override;
366 void end_apply()
override;
369 explicit Scan(MergeAlwaysRunActions &s) : self(s) {}
373 MergeAlwaysRunActions &self;
374 const IR::MAU::Table *preorder(IR::MAU::Table *)
override;
375 void end_apply()
override;
378 explicit Update(MergeAlwaysRunActions &s) : self(s) {}
387 MergeAlwaysRunActions &self;
391 std::map<PHV::AllocSlice *, std::pair<bool, bool>> sliceLRmodifies;
393 bool preorder(
const IR::MAU::Table *)
override;
394 bool preorder(
const IR::Expression *)
override;
395 void end_apply()
override;
398 explicit UpdateAffectedTableMinStage(MergeAlwaysRunActions &s) : self(s) {}
401 const IR::MAU::Table *ar_replacement(
int st, gress_t gress) {
402 AlwaysRunKey ark(st, gress);
403 if (ar_tables_per_stage.count(ark) == 0)
404 BUG(
"MergeAlwaysRunActions cannot find stage of an always run table");
405 auto set = ar_tables_per_stage.at(ark);
406 return *(set.begin());
409 template <
class... Args>
410 void error(Args... args) {
413 int errorCount()
const {
return self.errorCount(); }
417 addPasses({
new Scan(*
this),
new Update(*
this),
new FindDependencyGraph(self.phv, self.deps),
418 new UpdateAffectedTableMinStage(*
this)});
static BaseCompileContext & get()
Definition compile_context.cpp:61
Definition tofino_write_context.h:24