P4C
The P4 Compiler
Loading...
Searching...
No Matches
mau/asm_output.h
1
19#ifndef BF_P4C_MAU_ASM_OUTPUT_H_
20#define BF_P4C_MAU_ASM_OUTPUT_H_
21
22#include <initializer_list>
23#include <map>
24#include <set>
25#include <sstream>
26#include <vector>
27
28#include "bf-p4c/common/asm_output.h"
29#include "bf-p4c/mau/input_xbar.h"
30#include "bf-p4c/mau/memories.h"
31#include "bf-p4c/mau/next_table.h"
32#include "bf-p4c/mau/resource.h"
33#include "bf-p4c/phv/phv_fields.h"
34#include "lib/log.h"
35#include "lib/safe_vector.h"
36
37class PhvInfo;
38class BFN_Options;
39namespace MauPower {
41}
42
43struct fmt_state {
44 const char *sep = " ";
45 int next = 0;
46 void emit(std::ostream &out, const char *name, int group, int bit, int width) {
47 if (bit < 0) return;
48 out << sep << name;
49 if (group != -1) out << '(' << group << ")";
50 out << ": ";
51 out << bit << ".." << bit + width - 1;
52 next = bit + width;
53 sep = ", ";
54 }
55 void emit(std::ostream &out, const char *name, int group,
56 const safe_vector<std::pair<int, int>> &bits) {
57 if (bits.size() == 1) {
58 emit(out, name, group, bits[0].first, bits[0].second - bits[0].first + 1);
59 } else if (bits.size() > 1) {
60 out << sep << name;
61 if (group != -1) out << '(' << group << ")";
62 out << ": [ ";
63 sep = "";
64 for (auto &p : bits) {
65 out << sep << p.first << ".." << p.second;
66 sep = ", ";
67 }
68 out << " ]";
69 }
70 }
71};
72cstring format_name(int type);
73
75 const safe_vector<int> &vec;
76 Memories::Use::type_t type;
77 bool is_mapcol;
78 friend std::ostream &operator<<(std::ostream &, const memory_vector &);
79
80 public:
81 memory_vector(const safe_vector<int> &v, Memories::Use::type_t t, bool ism)
82 : vec(v), type(t), is_mapcol(ism) {}
83};
84
85class MauAsmOutput : public MauInspector {
86 protected:
87 const PhvInfo &phv;
88 const IR::BFN::Pipe *pipe;
89 const NextTable *nxt_tbl;
90 const MauPower::FinalizeMauPredDepsPower *power_and_mpr;
91 const BFN_Options &options;
92
93 private:
94 struct TableInstance {
95 explicit TableInstance(const IR::MAU::Table *table) : tableInfo(table) {}
96
97 const IR::MAU::Table *tableInfo;
98 };
99
100 std::map<std::pair<gress_t, int>, std::vector<TableInstance>> by_stage;
102 std::pair<UniqueId, const Memories::Use *>>
103 selector_memory;
104 profile_t init_apply(const IR::Node *root) override { return MauInspector::init_apply(root); }
105 bool preorder(const IR::MAU::Table *tbl) override {
106 auto tableId = std::make_pair(tbl->gress, tbl->stage());
107 by_stage[tableId].push_back(TableInstance(tbl));
108 return true;
109 }
110 bool preorder(const IR::MAU::BackendAttached *) override {
111 // Same backend resource can be attached to a table split across
112 // multiple stages which means it must be visited for each table.
113 // In order to enable this, we need to set visitAgain on the common
114 // resource
115 visitAgain();
116 return true;
117 }
118 void postorder(const IR::MAU::Selector *as) override {
119 visitAgain();
120 auto tbl = findContext<IR::MAU::Table>();
121 if (tbl->is_placed()) {
122 auto &unattached = tbl->resources->memuse.at(tbl->unique_id()).unattached_tables;
123 auto unique_id = tbl->unique_id(as);
124 if (!unattached.count(unique_id) && tbl->resources->memuse.count(unique_id)) {
125 selector_memory[std::make_pair(tbl->stage(), as)] =
126 std::make_pair(unique_id, &tbl->resources->memuse.at(unique_id));
127 }
128 }
129 }
130 bool preorder(const IR::MAU::StatefulAlu *) override { return false; }
131 friend std::ostream &operator<<(std::ostream &, const MauAsmOutput &);
132
133 public:
134 class NextTableSet;
135
136 protected:
137 bool require_ixbar(const IR::MAU::Table *tbl, IXBar::Use::type_t) const;
138 bool require_ixbar(const IR::MAU::Table *tbl, std::initializer_list<IXBar::Use::type_t>) const;
139 void emit_ixbar(std::ostream &out, indent_t indent, const IR::MAU::Table *tbl,
140 IXBar::Use::type_t type) const;
141 void emit_ixbar(std::ostream &out, indent_t indent, const IR::MAU::Table *tbl,
142 std::initializer_list<IXBar::Use::type_t> types) const;
143 void emit_random_seed(std::ostream &out, indent_t indent, const TableMatch *fmt) const;
144 // FIXME: change API to be target-agnostic
145 void emit_hash_dist(std::ostream &out, indent_t indent,
146 const safe_vector<Tofino::IXBar::HashDistUse> *hash_dist_use,
147 bool hashmod) const;
148
149 bool emit_gateway(std::ostream &out, indent_t gw_indent, const IR::MAU::Table *tbl,
150 bool hash_action, NextTableSet next_hit, NextTableSet &gw_miss) const;
151 void emit_no_match_gateway(std::ostream &out, indent_t gw_indent,
152 const IR::MAU::Table *tbl) const;
153 void emit_table_hitmap(std::ostream &out, indent_t indent, const IR::MAU::Table *tbl,
154 NextTableSet &next_hit, NextTableSet &gw_miss, bool no_match_hit,
155 bool gw_can_miss) const;
156
157 virtual void emit_ways(std::ostream &out, indent_t indent, const IXBar::Use *use,
158 const Memories::Use *mem) const;
159
160 public:
161 virtual void emit_table_format(std::ostream &out, indent_t, const TableFormat::Use &use,
162 const TableMatch *tm, bool ternary, bool no_match) const;
163
164 protected:
165 virtual void emit_memory(std::ostream &out, indent_t, const Memories::Use &,
166 const IR::MAU::Table::Layout *l = nullptr,
167 const TableFormat::Use *f = nullptr) const = 0;
168
169 void emit_table_context_json(std::ostream &out, indent_t, const IR::MAU::Table *tbl) const;
170 void emit_ternary_match(std::ostream &out, indent_t, const TableFormat::Use &use) const;
171 void emit_atcam_match(std::ostream &out, indent_t, const IR::MAU::Table *tbl,
172 std::stringstream &context_json_entries) const;
173 void emit_table(std::ostream &out, const IR::MAU::Table *tbl, int stage, gress_t gress) const;
174 void emit_always_run_action(std::ostream &out, const IR::MAU::Table *tbl, int stage,
175 gress_t gress) const;
176 void emit_static_entries(std::ostream &, indent_t indent, const IR::MAU::Table *tbl,
177 std::stringstream &context_json_entries) const;
178 void next_table_non_action_map(const IR::MAU::Table *,
179 safe_vector<NextTableSet> &next_table_map) const;
180 void emit_table_indir(std::ostream &out, indent_t, const IR::MAU::Table *tbl,
181 const IR::MAU::TernaryIndirect *ti) const;
182 void emit_action_data_format(std::ostream &out, indent_t, const IR::MAU::Table *tbl,
183 const IR::MAU::Action *af) const;
184 void emit_single_alias(std::ostream &out, std::string &sep, const ActionData::Parameter *param,
185 le_bitrange adt_range, cstring alias,
186 safe_vector<ActionData::Argument> &full_args, cstring action_name) const;
187 void emit_action_data_alias(std::ostream &out, indent_t, const IR::MAU::Table *tbl,
188 const IR::MAU::Action *af) const;
189 void emit_action_data_bus(std::ostream &out, indent_t, const IR::MAU::Table *tbl,
190 bitvec source) const;
191 bool emit_idletime(std::ostream &out, indent_t indent, const IR::MAU::Table *tbl,
192 const IR::MAU::IdleTime *id) const;
193 void emit_indirect_res_context_json(std::ostream &, indent_t indent, const IR::MAU::Table *tbl,
194 std::stringstream &context_json_entries) const;
195 virtual bool gateway_uses_inhibit_index(const IR::MAU::Table *) const { return false; }
196 std::string indirect_address(const IR::MAU::AttachedMemory *) const;
197 std::string indirect_pfe(const IR::MAU::AttachedMemory *) const;
198 std::string stateful_counter_addr(IR::MAU::StatefulUse use) const;
199 std::string build_call(const IR::MAU::AttachedMemory *at_mem,
200 const IR::MAU::BackendAttached *ba, const IR::MAU::Table *tbl) const;
201 std::string build_sel_len_call(const IR::MAU::Selector *as) const;
202 std::string build_meter_color_call(const IR::MAU::Meter *mtr,
203 const IR::MAU::BackendAttached *ba,
204 const IR::MAU::Table *tbl) const;
205 NextTableSet next_for(const IR::MAU::Table *tbl, cstring what) const;
206
207 class EmitAction;
209 class EmitAttached;
210 class UnattachedName;
211 // class EmitHashExpression;
212
213 public:
214 MauAsmOutput(const PhvInfo &phv, const IR::BFN::Pipe *pipe, const NextTable *nxts,
215 const MauPower::FinalizeMauPredDepsPower *pmpr, const BFN_Options &options)
216 : phv(phv), pipe(pipe), nxt_tbl(nxts), power_and_mpr(pmpr), options(options) {}
217
218 static cstring find_attached_name(const IR::MAU::Table *tbl, const IR::MAU::AttachedMemory *am);
219 static ordered_set<UniqueId> find_attached_ids(const IR::MAU::Table *tbl,
220 const IR::MAU::AttachedMemory *am);
221};
222
224 public:
225 const IR::MAU::Table *table = nullptr;
226 const PhvInfo &phv;
227
228 // 'match_fields', 'proxy_hash' and 'proxy_hash_fields' here are used only by
229 // 'emit_table_format' while 'ghost_bits' and 'identity_hash' are used only by
230 // 'emit_ixbar_hash_table' (called via emit_ixbar and emit_single_ixbar), so they
231 // could be two independent data structures (or just extra arguments) -- the combo
232 // here into a single object is accidental.
233 safe_vector<Slice> match_fields;
234 safe_vector<Slice> match_fields_word;
235 safe_vector<Slice> match_fields_byte;
236 safe_vector<Slice> ghost_bits;
237
239 le_bitrange bits;
240 explicit ProxyHashSlice(le_bitrange b) : bits(b) {}
241
242 public:
243 friend std::ostream &operator<<(std::ostream &out, const ProxyHashSlice &sl) {
244 return out << "hash_group" << "(" << sl.bits.lo << ".." << sl.bits.hi << ")";
245 }
246 };
247 safe_vector<ProxyHashSlice> proxy_hash_fields;
248 bool proxy_hash = false;
249 bool identity_hash = false;
250 bool dynamic_key_masks = false;
251
252 void init_proxy_hash();
253 virtual void populate_match_fields();
254 void populate_ghost_bits();
255 void populate_slices(safe_vector<Slice> &slices,
256 const std::map<IXBar::Use::Byte, bitvec> &byte_infos);
257
258 TableMatch(const PhvInfo &phv, const IR::MAU::Table *tbl);
259 explicit TableMatch(const PhvInfo &phv) : phv(phv) {}
260 static TableMatch *create(const PhvInfo &phv, const IR::MAU::Table *tbl);
261};
262
263#endif /* BF_P4C_MAU_ASM_OUTPUT_H_ */
Definition action_format.h:53
Definition bf-p4c-options.h:28
Definition mau/asm_output.cpp:1230
Definition mau/asm_output.cpp:1781
Definition mau/asm_output.cpp:356
Definition mau/asm_output.cpp:1175
Definition mau/asm_output.h:85
std::string build_call(const IR::MAU::AttachedMemory *at_mem, const IR::MAU::BackendAttached *ba, const IR::MAU::Table *tbl) const
Definition mau/asm_output.cpp:2918
void emit_table_hitmap(std::ostream &out, indent_t indent, const IR::MAU::Table *tbl, NextTableSet &next_hit, NextTableSet &gw_miss, bool no_match_hit, bool gw_can_miss) const
Definition mau/asm_output.cpp:2554
void emit_action_data_alias(std::ostream &out, indent_t, const IR::MAU::Table *tbl, const IR::MAU::Action *af) const
Definition mau/asm_output.cpp:533
std::string indirect_address(const IR::MAU::AttachedMemory *) const
Definition mau/asm_output.cpp:2869
std::string build_sel_len_call(const IR::MAU::Selector *as) const
Definition mau/asm_output.cpp:3021
void emit_action_data_bus(std::ostream &out, indent_t, const IR::MAU::Table *tbl, bitvec source) const
Definition mau/asm_output.cpp:1032
bool emit_gateway(std::ostream &out, indent_t gw_indent, const IR::MAU::Table *tbl, bool hash_action, NextTableSet next_hit, NextTableSet &gw_miss) const
Definition mau/asm_output.cpp:1976
std::string build_meter_color_call(const IR::MAU::Meter *mtr, const IR::MAU::BackendAttached *ba, const IR::MAU::Table *tbl) const
Definition mau/asm_output.cpp:2978
void emit_no_match_gateway(std::ostream &out, indent_t gw_indent, const IR::MAU::Table *tbl) const
Definition mau/asm_output.cpp:2106
Definition mau_visitor.h:29
Definition finalize_mau_pred_deps_power.h:47
Definition next_table.h:26
Definition node.h:95
Definition visitor.h:78
Definition bitvec.h:120
Definition cstring.h:85
Definition indent.h:26
Definition ordered_map.h:32
Definition ordered_set.h:32
Definition safe_vector.h:27
Definition phv_fields.h:1095
Definition mau/asm_output.h:223
Definition mau/asm_output.h:74
Definition mau/asm_output.h:39
Definition input_xbar.h:191
Definition memories.h:81
int lo
Definition lib/bitrange.h:694
int hi
Definition lib/bitrange.h:700
Definition table_format.h:108
Definition mau/asm_output.h:238
Definition mau/asm_output.h:43