P4C
The P4 Compiler
Loading...
Searching...
No Matches
table_layout.h
1
19#ifndef BF_P4C_MAU_TABLE_LAYOUT_H_
20#define BF_P4C_MAU_TABLE_LAYOUT_H_
21
22#include "backends/tofino/bf-p4c/mau/action_format.h"
23#include "backends/tofino/bf-p4c/mau/attached_output.h"
24#include "backends/tofino/bf-p4c/mau/mau_visitor.h"
25#include "backends/tofino/bf-p4c/mau/payload_gateway.h"
26#include "lib/safe_vector.h"
27
28namespace StageFlag {
29enum StageFlag_t { Immediate = 1, NoImmediate = 2 };
30}
31
32using namespace P4;
33
35 public:
36 IR::MAU::Table::Layout layout;
37 IR::MAU::Table::Way way;
38 safe_vector<int> way_sizes;
39 safe_vector<int> partition_sizes;
40 safe_vector<int> dleft_hash_sizes;
41 int entries = 0;
42 int srams = 0, maprams = 0, tcams = 0;
43 int lambs = 0;
44 int local_tinds = 0;
45 int select_bus_split = -1;
46 int action_format_index = -1;
47 bool previously_widened = false;
48 bool identity = false;
49 LayoutOption() {}
50 explicit LayoutOption(const IR::MAU::Table::Layout l, int i)
51 : layout(l), action_format_index(i) {}
52 LayoutOption(const IR::MAU::Table::Layout l, const IR::MAU::Table::Way w, int i)
53 : layout(l), way(w), action_format_index(i) {}
54 LayoutOption *clone() const;
55 void clear_mems() {
56 srams = 0;
57 lambs = 0;
58 local_tinds = 0;
59 maprams = 0;
60 tcams = 0;
61 entries = 0;
62 select_bus_split = -1;
63 way_sizes.clear();
64 partition_sizes.clear();
65 dleft_hash_sizes.clear();
66 }
67
68 int logical_tables() const {
69 if (partition_sizes.size() > 0)
70 return static_cast<int>(partition_sizes.size());
71 else if (dleft_hash_sizes.size() > 0)
72 return static_cast<int>(dleft_hash_sizes.size());
73 return 1;
74 }
75 friend std::ostream &operator<<(std::ostream &, const LayoutOption &);
76 void dbprint_multiline() const {}
77};
78inline std::ostream &operator<<(std::ostream &out, const LayoutOption *lo) {
79 if (lo) return out << *lo;
80 return out << "(null LayoutOption)";
81}
82
84 PhvInfo &phv; // may need to add TempVars as part of action/table
85 SplitAttachedInfo &att_info; // rewrites for splitting
86
87 public:
88 const ReductionOrInfo &red_info; // needed by action analysis
90
91 private:
92 virtual void setup_exact_match(const IR::MAU::Table *tbl,
93 const IR::MAU::Table::Layout &layout_proto,
94 ActionData::FormatType_t format_type,
95 int action_data_bytes_in_table, int immediate_bits, int index);
96 virtual void setup_layout_option_no_match(const IR::MAU::Table *tbl,
97 const IR::MAU::Table::Layout &layout,
98 ActionData::FormatType_t format_type);
99 virtual void setup_ternary_layout(const IR::MAU::Table *tbl,
100 const IR::MAU::Table::Layout &layout_proto,
101 ActionData::FormatType_t format_type,
102 int action_data_bytes_in_table, int immediate_bits,
103 int index);
104 void compute_action_formats(const IR::MAU::Table *t, ActionData::FormatType_t type);
105 void compute_layout_options(const IR::MAU::Table *t, ActionData::FormatType_t type);
106
107 void add_hash_action_option(const IR::MAU::Table *tbl, const IR::MAU::Table::Layout &layout,
108 ActionData::FormatType_t format_type, bool &hash_action_only);
109 static void setup_indirect_ptrs(IR::MAU::Table::Layout &layout, const IR::MAU::Table *tbl,
110 ActionData::FormatType_t format_type);
111 void setup_layout_options(const IR::MAU::Table *tbl, const IR::MAU::Table::Layout &layout_proto,
112 ActionData::FormatType_t format_type);
113 void setup_ternary_layout_options(const IR::MAU::Table *tbl,
114 const IR::MAU::Table::Layout &layout_proto,
115 ActionData::FormatType_t format_type);
116 bool need_meter(const IR::MAU::Table *t, ActionData::FormatType_t format_type) const;
117
118 protected:
119 using key_t = std::pair<cstring, ActionData::FormatType_t>;
120 template <class T>
121 using cache_t = std::map<key_t, safe_vector<T>>;
122 cache_t<LayoutOption> cache_layout_options;
123 cache_t<ActionData::Format::Use> cache_action_formats;
124 int get_pack_pragma_val(const IR::MAU::Table *tbl, const IR::MAU::Table::Layout &layout_proto);
125
126 public:
127 const safe_vector<LayoutOption> &get_layout_options(const IR::MAU::Table *t,
129 BUG_CHECK(t, "null table pointer");
130 auto key = std::make_pair(t->name, type);
131 if (!cache_layout_options.count(key)) compute_layout_options(t, type);
132 return cache_layout_options.at(key);
133 }
134 const safe_vector<LayoutOption> &get_layout_options(const IR::MAU::Table *t) {
135 return get_layout_options(t, ActionData::FormatType_t::default_for_table(t));
136 }
137
138 const safe_vector<ActionData::Format::Use> &get_action_formats(const IR::MAU::Table *t,
140 BUG_CHECK(t, "null table pointer");
141 auto key = std::make_pair(t->name, type);
142 if (!cache_action_formats.count(key)) compute_action_formats(t, type);
143 return cache_action_formats.at(key);
144 }
145 const safe_vector<ActionData::Format::Use> &get_action_formats(const IR::MAU::Table *t) {
146 return get_action_formats(t, ActionData::FormatType_t::default_for_table(t));
147 }
148
149 // meter output formats are stored here, but they are essentially completely independent
150 // of the layout choices.
151 std::map<cstring /* table name */, MeterALU::Format::Use> total_meter_output_format;
152 MeterALU::Format::Use get_attached_formats(const IR::MAU::Table *t,
153 ActionData::FormatType_t format_type) const {
154 if (!t || !total_meter_output_format.count(t->name) || !need_meter(t, format_type))
155 return {};
156 return total_meter_output_format.at(t->name);
157 }
158
159 void clear() {
160 cache_layout_options.clear();
161 cache_action_formats.clear();
162 total_meter_output_format.clear();
163 fpc.clear();
164 }
165
166 static LayoutChoices *create(PhvInfo &p, const ReductionOrInfo &ri, SplitAttachedInfo &a);
168 : phv(p), att_info(a), red_info(ri), fpc(phv) {}
169 void add_payload_gw_layout(const IR::MAU::Table *tbl, const LayoutOption &base_option);
170};
171
174 bool _hash_dist_needed = false;
175 bool _rng_needed = false;
176 bool preorder(const IR::MAU::HashDist *) {
177 _hash_dist_needed = true;
178 return false;
179 }
180 bool preorder(const IR::MAU::RandomNumber *) {
181 _rng_needed = true;
182 return false;
183 }
184
185 public:
186 bool is_hash_dist_needed() { return _hash_dist_needed; }
187 bool is_rng_needed() { return _rng_needed; }
188};
189
192 using RandKey = std::pair<const IR::MAU::Table *, const IR::MAU::Action *>;
193 ordered_map<RandKey, RandExterns> rand_extern_per_action;
194 void postorder(const IR::MAU::RandomNumber *rn) override;
195
196 Visitor::profile_t init_apply(const IR::Node *node) override {
197 auto rv = MauInspector::init_apply(node);
198 rand_extern_per_action.clear();
199 return rv;
200 }
201
202 public:
204};
205
209 const SplitAttachedInfo &att_info;
210
211 Visitor::profile_t init_apply(const IR::Node *node) override {
212 auto rv = PassManager::init_apply(node);
213 occupied_buses.clear();
214 possible_addresses.clear();
215 return rv;
216 }
217
218 class FindBusUsers : public MauInspector {
220 bool preorder(const IR::MAU::IdleTime *) override;
221 bool preorder(const IR::MAU::Counter *) override;
222 // Don't want to visit AttachedOutputs/StatefulCall
223 bool preorder(const IR::MAU::Action *) override { return false; }
224
225 public:
226 explicit FindBusUsers(MeterColorMapramAddress &self) : self(self) {}
227 };
228
229 class DetermineMeterReqs : public MauInspector {
231 bool preorder(const IR::MAU::Meter *) override;
232 // Don't want to visit AttachedOutputs/StatefulCall
233 bool preorder(const IR::MAU::Action *) override { return false; }
234
235 public:
236 explicit DetermineMeterReqs(MeterColorMapramAddress &self) : self(self) {}
237 };
238
239 class SetMapramAddress : public MauModifier {
241 bool preorder(IR::MAU::Meter *) override;
242 // Don't want to visit AttachedOutputs/StatefulCall
243 bool preorder(IR::MAU::Action *) override { return false; }
244
245 public:
246 explicit SetMapramAddress(MeterColorMapramAddress &self) : self(self) {}
247 };
248
249 public:
250 explicit MeterColorMapramAddress(const SplitAttachedInfo &att_info) : att_info(att_info) {
251 addPasses(
252 {new FindBusUsers(*this), new DetermineMeterReqs(*this), new SetMapramAddress(*this)});
253 }
254};
255
257 LayoutChoices &lc;
258
259 bool preorder(const IR::MAU::ActionData *) override;
260
261 public:
262 explicit ValidateActionProfileFormat(LayoutChoices &l) : lc(l) { visitDagOnce = false; }
263};
264
266 bool preorder(const IR::MAU::Table *) override;
267
268 public:
270};
271
273 bool preorder(const IR::MAU::Table *) override {
274 visitOnce();
275 return true;
276 }
277 bool preorder(const IR::MAU::Selector *) override;
278
279 public:
280 ProhibitAtcamWideSelectors() { visitDagOnce = false; }
281};
282
284 ordered_map<cstring, std::set<cstring>> placement_priorities;
285 bool run_once = false;
286
287 profile_t init_apply(const IR::Node *root) override {
288 auto rv = MauInspector::init_apply(root);
289 placement_priorities.clear();
290 return rv;
291 }
292
293 bool preorder(const IR::MAU::Table *tbl) override;
294 void end_apply() override;
295
296 public:
298};
299
300class TableLayout : public PassManager {
301 LayoutChoices &lc;
302 SplitAttachedInfo &att_info;
303
304 profile_t init_apply(const IR::Node *root) override;
305
306 public:
308 static void check_for_ternary(IR::MAU::Table::Layout &layout, const IR::MAU::Table *tbl);
309 static void check_for_atcam(IR::MAU::Table::Layout &layout, const IR::MAU::Table *tbl,
310 cstring &partition_index, const PhvInfo &phv);
311 static void check_for_alpm(IR::MAU::Table::Layout &, const IR::MAU::Table *tbl,
312 cstring &partition_index, const PhvInfo &phv);
313};
314
319 private:
320 std::map<UniqueId, int> totalCounterRams = {};
321
322 public:
323 Visitor::profile_t init_apply(const IR::Node *root) override {
324 auto rv = PassManager::init_apply(root);
325 totalCounterRams.clear();
326 return rv;
327 }
328
330 private:
332
333 public:
334 bool preorder(const IR::MAU::Table *table) override;
335 explicit FindCounterRams(AssignCounterLRTValues &self) : self_(self) {}
336 };
337
338 class ComputeLRT : public MauModifier {
339 private:
341 void calculate_lrt_threshold_and_interval(const IR::MAU::Table *tbl,
342 IR::MAU::Counter *cntr);
343
344 public:
345 bool preorder(IR::MAU::Counter *cntr) override;
346 explicit ComputeLRT(AssignCounterLRTValues &self) : self_(self) {}
347 };
348
349 AssignCounterLRTValues() { addPasses({new FindCounterRams(*this), new ComputeLRT(*this)}); }
350};
351
352#endif /* BF_P4C_MAU_TABLE_LAYOUT_H_ */
Definition attached_info.h:32
Definition table_layout.h:338
Definition table_layout.h:329
Definition table_layout.h:318
Definition table_layout.h:283
Definition payload_gateway.h:31
Definition table_layout.h:173
Definition table_layout.h:83
Definition table_layout.h:34
Definition mau_visitor.h:29
Definition mau_visitor.h:45
Definition table_layout.h:206
Definition node.h:94
Definition ir/pass_manager.h:40
Definition visitor.h:78
Definition cstring.h:85
Definition ordered_map.h:32
Definition ordered_set.h:32
Definition safe_vector.h:27
Definition phv_fields.h:1095
Definition table_layout.h:272
Definition table_layout.h:190
Definition attached_info.h:235
Definition table_layout.h:300
static void check_for_atcam(IR::MAU::Table::Layout &layout, const IR::MAU::Table *tbl, cstring &partition_index, const PhvInfo &phv)
Definition table_layout.cpp:175
Definition table_layout.h:256
Definition table_layout.h:265
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition table_layout.h:28
Definition attached_output.h:42
Definition reduction_or.h:47