51 static const cstring ID_PING_PONG_SUFFIX;
55 static const cstring GMD_STRUCTURE_NAME;
59 static const cstring PING_PONG_FIELD_NAME;
66 const IR::Type_Header *ghost_meta_struct =
nullptr;
73 using RegisterSet = std::set<const IR::Declaration_Instance *>;
76 template <
typename Key>
79 template <
typename Key,
typename Value>
80 using TnaControlPairMap = std::map<std::pair<const IR::BFN::TnaControl *, const Key>,
Value,
83 template <
typename Value>
84 using TnaControlMap = std::map<const IR::BFN::TnaControl *, Value, TnaControlLess>;
86 using RegisterToRegisterActionMap =
87 TnaControlPairMap<const IR::Declaration_Instance *, RegisterSet>;
88 using RegisterToP4ActionMap =
89 TnaControlPairMap<const IR::Declaration_Instance *, std::set<const IR::P4Action *>>;
90 using P4ActionToRegisterMap =
91 TnaControlPairMap<const IR::P4Action *, const IR::Declaration_Instance *>;
92 using P4ActionToP4TableMap = TnaControlPairMap<const IR::P4Action *, const IR::P4Table *>;
93 using P4TableToRegisterMap =
94 TnaControlPairMap<const IR::P4Table *, const IR::Declaration_Instance *>;
95 using P4TableToP4TableMap = std::unordered_map<const IR::P4Table *, const IR::P4Table *>;
96 using ControlToRegisterMap = TnaControlMap<RegisterSet>;
100 TnaControlMap<cstring> ghost_meta_name;
102 RegisterToRegisterActionMap registerToRegisterAction;
103 RegisterToP4ActionMap registerToP4Action;
104 P4ActionToRegisterMap p4ActionToRegister;
105 P4ActionToP4TableMap p4ActionToP4Table;
106 P4TableToRegisterMap p4TableToRegister;
107 ControlToRegisterMap ppIfCoveredRegisters;
108 ControlToRegisterMap controlToRegister;
109 P4TableToP4TableMap p4TableToDuplicateTable;
114 inline IR::Path *appendPingPongSuffix(IR::Path *, std::set<cstring> &);
115 inline void duplicateNodeDeclaration(
const IR::Declaration *, IR::BFN::TnaControl *,
116 std::set<cstring> &);
120 std::set<const IR::Declaration_Instance *> allRegisters()
const;
121 bool shouldTransform();
125 bool isPingPongValid(
const IR::Declaration_Instance *reg);
130 bool isPingPongValid(
const IR::BFN::TnaControl *gress,
const IR::Declaration_Instance *reg,
131 bool calculatingCovered =
false);
136 bool calculatingCovered =
false);
156 class GetAllRegisters :
public Inspector {
159 bool preorder(
const IR::MethodCallExpression *)
override;
171 bool preorder(
const IR::ActionListElement *)
override;
182 class CheckPingPongTables :
public Inspector {
187 bool preorder(
const IR::Type_Header *)
override;
189 bool preorder(
const IR::PathExpression *)
override;
191 bool preorder(
const IR::Parameter *)
override;
200 class GeneratePingPongMechanismDeclarations :
public Transform {
203 IR::Node *preorder(IR::P4Program *);
204 IR::Node *preorder(IR::BFN::TnaControl *);
207 explicit GeneratePingPongMechanismDeclarations(
PingPongGeneration &self) : self(self) {}
213 class GeneratePingPongMechanism :
public Transform {
216 IR::Node *postorder(IR::MethodCallStatement *);
227 : refMap(refMap), typeMap(typeMap) {
228 setName(
"Automatic ping-pong generation");
230 new TypeChecking(refMap, typeMap,
true),
new GetAllRegisters(*
this),
231 new AddAllTables(*
this),
new CheckPingPongTables(*
this),
232 new PassIf([
this]() {
return shouldTransform(); },
233 {
new GeneratePingPongMechanismDeclarations(*
this),
236 new GeneratePingPongMechanism(*
this)})});