P4C
The P4 Compiler
Loading...
Searching...
No Matches
instruction_selection.h
1
19#ifndef BF_P4C_MAU_INSTRUCTION_SELECTION_H_
20#define BF_P4C_MAU_INSTRUCTION_SELECTION_H_
21
22#include "backends/tofino/bf-p4c/bf-p4c-options.h"
23#include "backends/tofino/bf-p4c/common/utils.h"
24#include "backends/tofino/bf-p4c/ir/tofino_write_context.h"
25#include "backends/tofino/bf-p4c/mau/mau_visitor.h"
26#include "backends/tofino/bf-p4c/mau/reduction_or.h"
27#include "backends/tofino/bf-p4c/phv/phv_fields.h"
28#include "ir/ir-generated.h"
29
30using namespace P4;
31
38 bool preorder(const IR::MAU::Primitive *prim) override;
39
40 public:
42};
43
49 const IR::Expression *preorder(IR::Cast *) override;
50
51 public:
53};
54
59 const IR::Expression *preorder(IR::Primitive *) override;
60
61 public:
63};
64
70class HashGenSetup : public PassManager {
72 ordered_set<const IR::Expression *> hash_dist_injections;
73 const PhvInfo &phv;
74 const BFN_Options &options;
75
76 Visitor::profile_t init_apply(const IR::Node *node) override {
77 auto rv = PassManager::init_apply(node);
78 hash_gen_injections.clear();
79 hash_dist_injections.clear();
80 return rv;
81 }
82
86 class CreateHashGenExprs : public MauInspector, TofinoWriteContext {
87 HashGenSetup &self;
88 std::vector<const IR::Expression *> per_prim_hge;
89 bool preorder(const IR::MAU::StatefulAlu *) override { return false; }
90 bool preorder(const IR::BFN::SignExtend *) override;
91 bool preorder(const IR::Concat *) override;
92 bool preorder(const IR::Expression *) override;
93 bool preorder(const IR::Constant *) override;
94 bool preorder(const IR::MAU::Primitive *) override;
95 void postorder(const IR::MAU::Primitive *) override;
96
97 void check_for_symmetric(const IR::Declaration_Instance *decl, const IR::ListExpression *le,
99 bool isBetter(const IR::Expression *dest, const IR::Expression *a, const IR::Expression *b);
100
101 public:
102 explicit CreateHashGenExprs(HashGenSetup &s) : self(s) {}
103 };
104
108 class ScanHashDists : public MauInspector {
109 HashGenSetup &self;
110 bool preorder(const IR::MAU::StatefulAlu *) override { return false; }
111 bool preorder(const IR::Expression *) override;
112
113 public:
114 explicit ScanHashDists(HashGenSetup &s) : self(s) {}
115 };
116
120 class UpdateHashDists : public MauTransform {
121 HashGenSetup &self;
122 const IR::Expression *postorder(IR::Expression *) override;
123
124 public:
125 explicit UpdateHashDists(HashGenSetup &s) : self(s) {}
126 };
127
128 public:
129 explicit HashGenSetup(const PhvInfo &p, const BFN_Options &o) : phv(p), options(o) {
130 addPasses(
131 {new CreateHashGenExprs(*this), new ScanHashDists(*this), new UpdateHashDists(*this)});
132 }
133};
134
145 std::set<UniqueAttachedId> per_flow_enables;
146 std::map<UniqueAttachedId, IR::MAU::MeterType> meter_types;
147
149
150 const IR::MAU::Action *preorder(IR::MAU::Action *) override;
151 const IR::Node *postorder(IR::MAU::Primitive *) override;
152 const IR::MAU::Action *postorder(IR::MAU::Action *) override;
153
154 void clear_action() {
155 stateful.clear();
156 per_flow_enables.clear();
157 meter_types.clear();
158 }
159
160 public:
161 explicit Synth2PortSetup(const PhvInfo &) {}
162};
163
180 const PhvInfo &phv;
181 IR::MAU::Action *af = nullptr;
182 class SplitInstructions;
183 int synth_arg_num = 0;
184 const IR::MAU::TableSeq *ts = nullptr;
186
187 profile_t init_apply(const IR::Node *root) override;
188 const IR::MAU::HashDist *preorder(IR::MAU::HashDist *hd) override {
189 prune();
190 return hd;
191 }
192 const IR::GlobalRef *preorder(IR::GlobalRef *) override;
193 const IR::MAU::TableSeq *postorder(IR::MAU::TableSeq *) override;
194 const IR::MAU::Action *postorder(IR::MAU::Action *) override;
195 const IR::MAU::Action *preorder(IR::MAU::Action *) override;
196 const IR::MAU::SaluAction *preorder(IR::MAU::SaluAction *a) override {
197 prune();
198 return a;
199 }
200 const IR::Expression *postorder(IR::Add *) override;
201 const IR::Expression *postorder(IR::AddSat *) override;
202 const IR::Expression *postorder(IR::Sub *) override;
203 const IR::Expression *postorder(IR::SubSat *) override;
204 const IR::Expression *postorder(IR::Neg *) override;
205 const IR::Expression *postorder(IR::Shr *) override;
206 const IR::Expression *postorder(IR::Shl *) override;
207 const IR::Expression *postorder(IR::BAnd *) override;
208 const IR::Expression *postorder(IR::BOr *) override;
209 const IR::Expression *postorder(IR::BXor *) override;
210 const IR::Expression *postorder(IR::Cmpl *) override;
211 const IR::Expression *preorder(IR::BFN::SignExtend *) override;
212 const IR::Expression *preorder(IR::Concat *) override;
213 // const IR::Expression *postorder(IR::Cast *) override;
214 const IR::Expression *postorder(IR::Operation_Relation *) override;
215 const IR::Expression *postorder(IR::Mux *) override;
216 const IR::Slice *postorder(IR::Slice *) override;
217 const IR::Expression *postorder(IR::BoolLiteral *) override;
218 const IR::Node *postorder(IR::MAU::Primitive *) override;
219 const IR::MAU::Instruction *postorder(IR::MAU::Instruction *i) override { return i; }
220
221 bool checkPHV(const IR::Expression *);
222 bool checkActionBus(const IR::Expression *e);
223 bool checkSrc1(const IR::Expression *);
224 bool checkConst(const IR::Expression *ex, long &value);
225 bool equiv(const IR::Expression *a, const IR::Expression *b);
226 IR::Member *genIntrinsicMetadata(gress_t gress, cstring header, cstring field);
227
228 void limitWidth(const IR::Expression *);
229
230 public:
231 explicit DoInstructionSelection(const PhvInfo &phv) : phv(phv) {}
232};
233
241 const PhvInfo &phv;
242 const IR::TempVar *saved_tempvar = nullptr;
243 const IR::MAU::HashDist *saved_hashdist = nullptr;
244 typedef std::pair<const IR::MAU::AttachedMemory *, const IR::MAU::Table *> HashDistKey;
245 typedef std::pair<const IR::MAU::StatefulCall *, const IR::MAU::Table *> StatefulCallKey;
246 ordered_set<cstring> remove_tempvars;
247 ordered_set<cstring> copy_propagated_tempvars;
249 ordered_map<cstring, const IR::MAU::HashDist *> stateful_alu_from_hash_dists;
252 typedef IR::MAU::StatefulUse use_t;
254 action_use;
255 typedef std::pair<const IR::MAU::Synth2Port *, const IR::MAU::Table *> IndexCheck;
256 struct clear_info_t {
257 const IR::MAU::AttachedMemory *attached = 0;
258 bitvec clear_value;
259 uint32_t busy_value = 0;
260 };
263
264 ordered_set<IndexCheck> addressed_by_hash;
265 ordered_set<IndexCheck> addressed_by_index;
266
267 profile_t init_apply(const IR::Node *root) override {
268 remove_tempvars.clear();
269 copy_propagated_tempvars.clear();
270 remove_instr.clear();
271 stateful_alu_from_hash_dists.clear();
272 update_hd.clear();
273 return PassManager::init_apply(root);
274 }
275 class Scan : public MauInspector, TofinoWriteContext {
277 bool preorder(const IR::MAU::Action *) override;
278 bool preorder(const IR::MAU::Instruction *) override;
279 bool preorder(const IR::TempVar *) override;
280 bool preorder(const IR::MAU::HashDist *) override;
281 void postorder(const IR::MAU::Instruction *) override;
282 void postorder(const IR::MAU::Primitive *) override;
283 void postorder(const IR::MAU::Table *) override;
284 void setup_index_operand(const IR::Expression *index_expr,
285 const IR::MAU::Synth2Port *synth2port, const IR::MAU::Table *tbl,
286 const IR::MAU::StatefulCall *call);
287 void simpl_concat(std::vector<const IR::Expression *> &slices, const IR::Concat *concat);
288
289 public:
290 explicit Scan(StatefulAttachmentSetup &self) : self(self) {}
291 };
292 class Update : public MauTransform {
294 const IR::MAU::StatefulCall *preorder(IR::MAU::StatefulCall *) override;
295 const IR::MAU::BackendAttached *preorder(IR::MAU::BackendAttached *ba) override;
296 const IR::MAU::StatefulAlu *preorder(IR::MAU::StatefulAlu *salu) override;
297 const IR::MAU::Instruction *preorder(IR::MAU::Instruction *sp) override;
298
299 public:
300 explicit Update(StatefulAttachmentSetup &self) : self(self) {
301 dontForwardChildrenBeforePreorder = true;
302 }
303 };
304
305 const IR::MAU::HashDist *find_hash_dist(const IR::Expression *expr,
306 const IR::MAU::Primitive *prim);
307 IR::MAU::HashDist *create_hash_dist(const IR::Expression *e, const IR::MAU::Primitive *prim);
308
309 public:
310 explicit StatefulAttachmentSetup(const PhvInfo &p) : phv(p) {
311 addPasses({new Scan(*this), new Update(*this)});
312 }
313};
314
316 bool preorder(IR::MAU::StatefulCall *sc) override;
317
318 public:
320};
321
326 const PhvInfo &phv;
327 struct FieldImpact {
328 le_bitrange dest_bits;
329 const IR::Expression *read;
330
331 public:
332 FieldImpact(le_bitrange db, const IR::Expression *r) : dest_bits(db), read(r) {}
333 const IR::Expression *getSlice(bool isSalu, le_bitrange bits);
334 };
336 bool elem_copy_propagated = false;
337 IR::Vector<IR::MAU::Primitive> *split_set = nullptr;
338
339 const IR::Node *preorder(IR::Node *n) override {
340 visitOnce();
341 return n;
342 }
343 const IR::Node *preorder(IR::MAU::Instruction *i) override;
344 const IR::MAU::StatefulCall *preorder(IR::MAU::StatefulCall *sc) override {
345 prune();
346 return sc;
347 }
348 const IR::MAU::Action *preorder(IR::MAU::Action *a) override;
349 const IR::Expression *preorder(IR::Expression *a) override;
350 void update(const IR::MAU::Instruction *instr, const IR::Expression *e);
351 const IR::Expression *propagate(const IR::MAU::Instruction *instr, const IR::Expression *e);
352 const IR::MAU::Action *postorder(IR::MAU::Action *) override;
353
354 public:
355 explicit BackendCopyPropagation(const PhvInfo &p) : phv(p) { visitDagOnce = false; }
356};
357
363 public:
365
366 private:
367 const PhvInfo &phv;
368 FieldWrites writes;
369
370 bool preorder(const IR::MAU::Action *) override;
371 void postorder(const IR::MAU::Instruction *) override;
372 bool preorder(const IR::MAU::StatefulCall *) override { return false; }
373 bool preorder(const IR::MAU::BackendAttached *) override { return false; }
374
375 public:
376 explicit VerifyParallelWritesAndReads(const PhvInfo &p) : phv(p) {}
377};
378
383 const PhvInfo &phv;
384
385 public:
388 // Store field and all its phv bits in current action. Used for handling overlapping set
390 // Need to handle overlapping set if it's set to true.
392
393 private:
394 class Scan : public MauInspector, TofinoWriteContext {
396 LastInstrMap last_instr_map;
397
398 bool preorder(const IR::MAU::Action *) override;
399 bool preorder(const IR::MAU::Instruction *) override;
400 bool preorder(const IR::MAU::StatefulCall *) override { return false; }
401 bool preorder(const IR::MAU::BackendAttached *) override { return false; }
402 void postorder(const IR::MAU::Action *) override;
403
404 public:
405 explicit Scan(EliminateAllButLastWrite &self) : self(self) {}
406 };
407
408 class Update : public MauTransform, TofinoWriteContext {
410 const IR::MAU::Action *current_af = nullptr;
411 const IR::MAU::Action *preorder(IR::MAU::Action *) override;
412 const IR::Node *preorder(IR::MAU::Instruction *) override;
413 const IR::MAU::StatefulCall *preorder(IR::MAU::StatefulCall *sc) override {
414 prune();
415 return sc;
416 }
417 const IR::MAU::BackendAttached *preorder(IR::MAU::BackendAttached *ba) override {
418 prune();
419 return ba;
420 }
421
422 public:
423 explicit Update(EliminateAllButLastWrite &self) : self(self) {}
424 };
425
426 public:
427 explicit EliminateAllButLastWrite(const PhvInfo &p) : phv(p) {
428 addPasses({new Scan(*this), new Update(*this)});
429 }
430};
431
501 const PhvInfo &phv;
502
503 public:
504 std::map<const PHV::Field *, int> comp_adj_field_width_map;
505 std::map<const cstring, int> comp_adj_name_width_map;
506 std::map<const IR::MAU::Action *, std::set<const PHV::Field *>> comp_adj_fields_per_action_map;
507
508 private:
509 class Scan : public MauInspector {
511 std::map<const PHV::Field *, bitvec> comp_or_set_zero_writes;
513 std::set<const PHV::Field *> other_targets;
514
515 bool preorder(const IR::MAU::Action *) override;
516 bool preorder(const IR::MAU::Instruction *) override;
517 bool preorder(const IR::MAU::StatefulCall *) override { return false; }
518 bool preorder(const IR::MAU::BackendAttached *) override { return false; }
519 void postorder(const IR::MAU::Action *) override;
520
521 public:
522 explicit Scan(ArithCompareAdjustment &self) : self(self) {}
523 };
524
525 class Update : public Transform {
526 private:
528 const IR::MAU::Action *current_af = nullptr;
529 std::set<const PHV::Field *> comp_adj_fields;
530
531 const IR::MAU::Action *preorder(IR::MAU::Action *) override;
532 const IR::MAU::Instruction *preorder(IR::MAU::Instruction *) override;
533 const IR::Metadata *preorder(IR::Metadata *) override;
534 const IR::ConcreteHeaderRef *preorder(IR::ConcreteHeaderRef *) override;
535 const IR::Node *preorder(IR::Member *) override;
536 const IR::Type_StructLike *adjust_type_struct(const IR::Type_StructLike *, cstring name);
537 const IR::MAU::StatefulCall *preorder(IR::MAU::StatefulCall *sc) override {
538 prune();
539 return sc;
540 }
541 const IR::MAU::BackendAttached *preorder(IR::MAU::BackendAttached *ba) override {
542 prune();
543 return ba;
544 }
545 const IR::MAU::Action *postorder(IR::MAU::Action *) override;
546
547 public:
548 explicit Update(ArithCompareAdjustment &self) : self(self) {}
549 };
550
551 bool is_compare(cstring name) {
552 return name == "gtequ" || name == "gteqs" || name == "ltu" || name == "lts" ||
553 name == "lequ" || name == "leqs" || name == "gtu" || name == "gts" || name == "eq" ||
554 name == "neq" || name == "eq64" || name == "neq64";
555 }
556
557 public:
558 explicit ArithCompareAdjustment(const PhvInfo &p) : phv(p) {
559 addPasses({new Scan(*this), new Update(*this)});
560 }
561};
562
568class MeterSetup : public PassManager {
569 // Tracks the inputs per lpf
571 // Tracks the pre-color per meter
573 // Marks an action for setting a meter type
576 const PhvInfo &phv;
577
578 class Scan : public MauInspector {
579 MeterSetup &self;
580 void find_input(const IR::MAU::Primitive *);
581 void find_pre_color(const IR::MAU::Primitive *);
582 const IR::Expression *convert_cast_to_slice(const IR::Expression *);
583 profile_t init_apply(const IR::Node *root) override;
584 bool preorder(const IR::MAU::Instruction *) override;
585 bool preorder(const IR::MAU::Primitive *) override;
586
587 public:
588 explicit Scan(MeterSetup &self) : self(self) {}
589 };
590
591 class Update : public MauModifier {
592 MeterSetup &self;
593 void update_input(IR::MAU::Meter *);
594 void update_pre_color(IR::MAU::Meter *);
595 bool preorder(IR::MAU::Meter *) override;
596 bool preorder(IR::MAU::Action *) override;
597
598 public:
599 explicit Update(MeterSetup &self) : self(self) {}
600 };
601
602 public:
603 explicit MeterSetup(const PhvInfo &p) : phv(p) {
604 addPasses({new Scan(*this), new Update(*this)});
605 }
606};
607
609 struct AttachedActionCoord {
610 bool all_per_flow_enabled = true;
611 bool all_same_meter_type = true;
612 bool meter_type_set = false;
613 IR::MAU::MeterType meter_type = IR::MAU::MeterType::UNUSED;
614 const IR::MAU::AttachedMemory *am = nullptr;
615 };
616
617 using AttachedInfo = std::map<UniqueAttachedId, AttachedActionCoord>;
618 // coordinate the Attached Info across all inspectors
620 // Just to run the modifier on BackendAttached Objects
622
623 class InitializeAttachedInfo : public MauInspector {
625 bool preorder(const IR::MAU::BackendAttached *) override;
626
627 public:
628 explicit InitializeAttachedInfo(SetupAttachedAddressing &self) : self(self) {}
629 };
630
631 class ScanTables : public MauInspector {
633 bool preorder(const IR::MAU::Table *) override;
634
635 public:
636 explicit ScanTables(SetupAttachedAddressing &self) : self(self) {}
637 };
638
639 class VerifyAttached : public MauInspector {
641 bool preorder(const IR::MAU::BackendAttached *) override;
642
643 public:
644 explicit VerifyAttached(SetupAttachedAddressing &self) : self(self) {}
645 };
646
647 class UpdateAttached : public MauModifier {
649 void simple_attached(IR::MAU::BackendAttached *);
650 bool preorder(IR::MAU::BackendAttached *) override;
651
652 public:
653 explicit UpdateAttached(SetupAttachedAddressing &self) : self(self) {}
654 };
655
656 public:
658 addPasses({new InitializeAttachedInfo(*this), new ScanTables(*this),
659 new VerifyAttached(*this), new UpdateAttached(*this)});
660 }
661};
662
664 const IR::Node *preorder(IR::Slice *) override;
665
666 public:
668};
669
672
673 Visitor::profile_t init_apply(const IR::Node *node) override {
674 auto rv = PassManager::init_apply(node);
675 hash_dist_instrs.clear();
676 return rv;
677 }
678
679 class Scan : public MauInspector {
681 bool contains_hash_dist = false;
682
683 bool preorder(const IR::MAU::BackendAttached *) override { return false; }
684 bool preorder(const IR::MAU::StatefulCall *) override { return false; }
685 bool preorder(const IR::MAU::Instruction *) override;
686 bool preorder(const IR::MAU::HashDist *) override;
687 void postorder(const IR::MAU::Instruction *) override;
688
689 public:
690 explicit Scan(GuaranteeHashDistSize &s) : self(s) {}
691 };
692
693 class Update : public MauTransform {
695
696 const IR::Node *postorder(IR::MAU::Instruction *) override;
697
698 public:
699 explicit Update(GuaranteeHashDistSize &s) : self(s) {}
700 };
701
702 public:
703 GuaranteeHashDistSize() { addPasses({new Scan(*this), new Update(*this)}); }
704};
705
707 public:
709 const IR::Node *postorder(IR::Mux *prim) override;
710};
711
713 public:
715};
716
717#endif /* BF_P4C_MAU_INSTRUCTION_SELECTION_H_ */
Definition instruction_selection.h:500
Definition bf-p4c-options.h:28
Definition instruction_selection.h:325
Definition instruction_selection.h:58
Definition instruction_selection.cpp:621
Definition instruction_selection.h:179
Definition instruction_selection.h:382
Definition instruction_selection.h:670
Definition instruction_selection.h:70
Definition instruction_selection.h:712
InstructionSelection(const BFN_Options &, PhvInfo &, const ReductionOrInfo &)
Definition instruction_selection.cpp:3246
Definition mau_visitor.h:29
Definition mau_visitor.h:45
Definition mau_visitor.h:55
Definition instruction_selection.h:568
Definition instruction_selection.h:315
Definition node.h:94
Definition vector.h:59
Definition ltbitmatrix.h:25
Definition ir/pass_manager.h:40
Definition visitor.h:424
Definition visitor.h:78
Definition bitvec.h:120
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 instruction_selection.h:663
Definition instruction_selection.h:608
Definition instruction_selection.h:706
Definition instruction_selection.h:240
Definition instruction_selection.h:143
Definition instruction_selection.h:48
Definition tofino_write_context.h:24
Definition instruction_selection.h:37
Definition instruction_selection.h:362
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition hash_function.h:28
Definition reduction_or.h:47