Skip to content

Commit 1840fae

Browse files
committed
Framework for copy-on-write visitors (WIP)
- COWptr/COWref objects that support cloning on demand to allow writes - Lots of autogenerated code for IR classes to make things work transparently - specialization for vectors/maps etc - rename IR::MAU::Primitive -> IR::MAU::MauPrimitive to avoid name ambiguity with IR::Primitive Signed-off-by: Chris Dodd <cdodd@nvidia.com>
1 parent 4536e01 commit 1840fae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2048
-421
lines changed

backends/tofino/bf-p4c/common/check_for_unimplemented_features.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121
#include "lib/error_reporter.h"
2222

2323
std::optional<const IR::Operation_Binary *> CheckOperations::getSrcBinop(
24-
const IR::MAU::Primitive *prim) const {
24+
const IR::MAU::MauPrimitive *prim) const {
2525
prim = prim->apply(RemoveCasts());
2626
if (prim->name != "modify_field") return std::nullopt;
2727
if (prim->operands.size() < 2) return std::nullopt;
2828
if (auto *binop = prim->operands[1]->to<IR::Operation_Binary>()) return binop;
2929
return std::nullopt;
3030
}
3131

32-
bool CheckOperations::isModBitMask(const IR::MAU::Primitive *prim) const {
32+
bool CheckOperations::isModBitMask(const IR::MAU::MauPrimitive *prim) const {
3333
auto *binop = getSrcBinop(prim).value_or(nullptr);
3434
if (!binop || binop->getStringOp() != "|") return false;
3535
auto leftBinop = binop->left->to<IR::Operation_Binary>();
@@ -38,7 +38,7 @@ bool CheckOperations::isModBitMask(const IR::MAU::Primitive *prim) const {
3838
return leftBinop->getStringOp() == "&" && rightBinop->getStringOp() == "&";
3939
}
4040

41-
bool CheckOperations::preorder(const IR::MAU::Primitive *prim) {
41+
bool CheckOperations::preorder(const IR::MAU::MauPrimitive *prim) {
4242
if (isModBitMask(prim))
4343
error("The following operation is not yet supported: %1%", prim->srcInfo);
4444
return true;

backends/tofino/bf-p4c/common/check_for_unimplemented_features.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,17 @@ class CheckOperations : public Inspector {
4141

4242
/// @returns BOP in modify_field(x, BOP), if BOP is a binary operation
4343
/// expression.
44-
std::optional<const IR::Operation_Binary *> getSrcBinop(const IR::MAU::Primitive *p) const;
44+
std::optional<const IR::Operation_Binary *> getSrcBinop(const IR::MAU::MauPrimitive *p) const;
4545

4646
/// @returns true if @p is a P4_16 encoding of a P4_14 funnel shift
4747
/// operation, eg. modify_field(x, (y ++ z) >> n).
48-
bool isFunnelShift(const IR::MAU::Primitive *p) const;
48+
bool isFunnelShift(const IR::MAU::MauPrimitive *p) const;
4949

5050
/// @returns true if @p is a P4_16 encoding of a P4_14 bitmasked modify_field
5151
/// operation, eg. modify_field(x, val, 0xAA).
52-
bool isModBitMask(const IR::MAU::Primitive *p) const;
52+
bool isModBitMask(const IR::MAU::MauPrimitive *p) const;
5353

54-
bool preorder(const IR::MAU::Primitive *) override;
54+
bool preorder(const IR::MAU::MauPrimitive *) override;
5555
};
5656

5757
class CheckForUnimplementedFeatures : public PassManager {

backends/tofino/bf-p4c/common/extract_maupipe.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,10 @@ class ConvertMethodCalls : public MauTransform {
242242
return prim;
243243
}
244244

245-
const IR::MAU::Primitive *postorder(IR::MAU::Primitive *prim) {
245+
const IR::MAU::MauPrimitive *postorder(IR::MAU::MauPrimitive *prim) {
246246
if (prim->name == "method_call_init") {
247247
BUG_CHECK(prim->operands.size() == 1, "method call initialization failed");
248-
if (auto *p = prim->operands.at(0)->to<IR::MAU::Primitive>())
248+
if (auto *p = prim->operands.at(0)->to<IR::MAU::MauPrimitive>())
249249
return p;
250250
else if (prim->operands.at(0)->is<IR::Member>())
251251
// comes from a bare "isValid" call -- is a noop
@@ -379,7 +379,8 @@ class ActionBodySetup : public Inspector {
379379
if (!af->exitAction) {
380380
cstring pname = "modify_field"_cs;
381381
if (assign->left->type->is<IR::Type_Header>()) pname = "copy_header"_cs;
382-
auto prim = new IR::MAU::Primitive(assign->srcInfo, pname, assign->left, assign->right);
382+
auto prim =
383+
new IR::MAU::MauPrimitive(assign->srcInfo, pname, assign->left, assign->right);
383384
prim->in_hash = InHashAnnot();
384385
af->action.push_back(prim);
385386
}
@@ -388,7 +389,7 @@ class ActionBodySetup : public Inspector {
388389
bool preorder(const IR::MethodCallStatement *mc) override {
389390
if (!af->exitAction) {
390391
auto mc_init =
391-
new IR::MAU::Primitive(mc->srcInfo, "method_call_init"_cs, mc->methodCall);
392+
new IR::MAU::MauPrimitive(mc->srcInfo, "method_call_init"_cs, mc->methodCall);
392393
af->action.push_back(mc_init);
393394
}
394395
return false;
@@ -1293,7 +1294,7 @@ void AttachTables::InitializeStatefulAlus ::updateAttachedSalu(const IR::Declara
12931294
}
12941295
if (ext->type->toString().startsWith("LearnAction")) salu->learn_action = true;
12951296

1296-
auto prim = findContext<IR::MAU::Primitive>();
1297+
auto prim = findContext<IR::MAU::MauPrimitive>();
12971298
LOG6(" - " << (prim ? prim->name.c_str() : "<no primitive>"));
12981299
if (prim && prim->name.endsWith(".address")) {
12991300
salu->chain_vpn = true;
@@ -1340,7 +1341,7 @@ void AttachTables::InitializeStatefulAlus::postorder(const IR::GlobalRef *gref)
13401341
* Gathers information about register params and checks
13411342
* that they are used in a single stateful ALU.
13421343
*/
1343-
bool AttachTables::InitializeRegisterParams::preorder(const IR::MAU::Primitive *prim) {
1344+
bool AttachTables::InitializeRegisterParams::preorder(const IR::MAU::MauPrimitive *prim) {
13441345
if (prim->name != "RegisterParam.read") return true;
13451346
const IR::Declaration_Instance *reg_param_decl = nullptr;
13461347
if (auto *gr = prim->operands.at(0)->to<IR::GlobalRef>())

backends/tofino/bf-p4c/common/extract_maupipe.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class AttachTables : public PassManager {
126126
ordered_map<const IR::Declaration_Instance *,
127127
IR::MAU::StatefulAlu *>
128128
param_salus; // RegisterParam -> StatefulAlu
129-
bool preorder(const IR::MAU::Primitive *prim) override;
129+
bool preorder(const IR::MAU::MauPrimitive *prim) override;
130130
void end_apply() override;
131131

132132
public:

backends/tofino/bf-p4c/common/field_defuse.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,13 @@ bool FieldDefUse::preorder(const IR::MAU::Action *act) {
384384
return false;
385385
}
386386

387-
bool FieldDefUse::preorder(const IR::MAU::Primitive *prim) {
387+
bool FieldDefUse::preorder(const IR::MAU::MauPrimitive *prim) {
388388
// TODO: consider h.f1 = h.f1 + 1; When we visit it,
389389
// we should first visit the source on the RHS, as how hardware does.
390390
// The h.f1 on RHS is an use of previous def, and the one on LHS is a
391391
// write that clears the previous defs from this point.
392392
// TODO: The long-term fix for this is to change the order of visiting when
393-
// visiting IR::MAU::Primitive to the evaluation order defined in spec,
393+
// visiting IR::MAU::MauPrimitive to the evaluation order defined in spec,
394394
// to make control flow visit correct.
395395
LOG6("FieldDefUse preorder Primitive : " << prim << IndentCtl::indent);
396396
if (prim->operands.size() > 0) {

backends/tofino/bf-p4c/common/field_defuse.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class FieldDefUse : public BFN::ControlFlowVisitor, public Inspector, TofinoWrit
155155
bool preorder(const IR::BFN::LoweredParser *p) override;
156156
bool preorder(const IR::MAU::Table *t) override;
157157
void postorder(const IR::MAU::Table *t) override;
158-
bool preorder(const IR::MAU::Primitive *prim) override;
158+
bool preorder(const IR::MAU::MauPrimitive *prim) override;
159159
bool preorder(const IR::MAU::Action *p) override;
160160
bool preorder(const IR::MAU::StatefulAlu *prim) override;
161161
bool preorder(const IR::Expression *e) override;

backends/tofino/bf-p4c/common/header_stack.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void CollectHeaderStackInfo::postorder(IR::HeaderStack *hs) {
5151
i.inThread[INGRESS] = false;
5252
}
5353

54-
void CollectHeaderStackInfo::postorder(IR::MAU::Primitive *prim) {
54+
void CollectHeaderStackInfo::postorder(IR::MAU::MauPrimitive *prim) {
5555
if (prim->name == "push_front" || prim->name == "pop_front") {
5656
LOG3("CollectHeaderStackInfo: visiting " << prim);
5757
BUG_CHECK(prim->operands.size() == 2, "wrong number of operands to %s", prim);
@@ -147,8 +147,8 @@ IR::Node *RemovePushInitialization::preorder(IR::MAU::Action *act) {
147147
// then cleared when an initialization is found.
148148
ordered_map<cstring, bitvec> pushed_inits;
149149

150-
ordered_map<cstring, const IR::MAU::Primitive *> push_prims;
151-
IR::Vector<IR::MAU::Primitive> to_keep;
150+
ordered_map<cstring, const IR::MAU::MauPrimitive *> push_prims;
151+
IR::Vector<IR::MAU::MauPrimitive> to_keep;
152152

153153
for (auto *prim : act->action) {
154154
to_keep.push_back(prim);

backends/tofino/bf-p4c/common/header_stack.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct CollectHeaderStackInfo : public Modifier {
3939
private:
4040
Visitor::profile_t init_apply(const IR::Node *root) override;
4141
void postorder(IR::HeaderStack *stack) override;
42-
void postorder(IR::MAU::Primitive *primitive) override;
42+
void postorder(IR::MAU::MauPrimitive *primitive) override;
4343
void postorder(IR::BFN::Pipe *pipe) override;
4444

4545
BFN::HeaderStackInfo *stacks;

backends/tofino/bf-p4c/ir/gateway_control_flow.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class GatewayControlFlow : public virtual ControlFlowVisitor {
5656

5757
public:
5858
virtual void pre_visit_table_next(const IR::MAU::Table *tbl, cstring tags) = 0;
59+
void pre_visit_table_next(IR::COWptr<IR::MAU::Table> tbl, cstring tags) {
60+
pre_visit_table_next(tbl.get(), tags);
61+
}
5962
};
6063

6164
} // end namespace BFN

backends/tofino/bf-p4c/ir/mau.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ namespace MAU {
3737
// function templates to be in the same compilation unit.
3838
void Table::visit_children(Visitor &v, const char *n) { visit_children(this, v, n); }
3939
void Table::visit_children(Visitor &v, const char *n) const { visit_children(this, v, n); }
40+
void Table::COWref::visit_children(Visitor &v, const char *n) { Table::visit_children(this, v, n); }
4041

4142
/**
4243
* The potential control flow(s) through an IR::MAU::Table object are quite complex, which
@@ -167,7 +168,7 @@ void Table::visit_gateway_inhibited(THIS *self, Visitor &v, const char *,
167168
std::set<cstring> gw_tags_seen;
168169
bool fallen_through = false;
169170
for (auto &gw : self->gateway_rows) {
170-
auto tag = gw.second;
171+
cstring tag = gw.second;
171172
if (!tag || gw_tags_seen.count(tag)) continue;
172173

173174
gw_tags_seen.emplace(tag);

0 commit comments

Comments
 (0)