-
Notifications
You must be signed in to change notification settings - Fork 445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create explicit count calls for direct counters in P4_14->16 translation #421
Conversation
We don't have a clear spec for direct counters in the P4-14 spec. I exepceted that they always count, i.e., you don't need to invoke the count method explicitly in each action. Also, it is not clear at all whether such counters are also meant to count misses (e.g., default_action execution). The standard model (under construction) should specify the counter behavior clearly. Depending on the specification of the behavior of the counters, this code may need to be only inserted in the back-end, and not as P4-16 code. In fact, if the counter extern does not have a count method, then this code should not exist in the IR. Conversely, if the count method exists, we have to answer other important questions about it semantics, e.g., what happens if you call it multiple times in an action, or if you increment multiple counters in the same action. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the point of this code.
It inserts operations which do not exist in the source and do not exist in the target code.
} else if (em->originalExternType->name == v1model.directCounter.name) { | ||
if (em->method->name == v1model.directCounter.count.name) { | ||
BUG_CHECK(mc->arguments->size() == 0, "Expected 0 argument for %1%", mc); | ||
// Do not generate any code for this operation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this. If you generate no code for the count, then what is the point of having it?
@@ -626,7 +626,8 @@ void ProgramStructure::createDeparser() { | |||
|
|||
const IR::P4Table* | |||
ProgramStructure::convertTable(const IR::V1Table* table, cstring newName, | |||
IR::IndexedVector<IR::Declaration>* stateful) { | |||
IR::IndexedVector<IR::Declaration>* stateful, | |||
std::map<cstring, cstring> &mapNames) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would give a more suggestive name to the mapNames argument, perhaps "actionRenameMap".
@@ -1338,7 +1341,8 @@ const IR::Statement* ProgramStructure::convertPrimitive(const IR::Primitive* pri | |||
|
|||
const IR::P4Action* | |||
ProgramStructure::convertAction(const IR::ActionFunction* action, cstring newName, | |||
const IR::Meter* meterToAccess) { | |||
const IR::Meter* meterToAccess, | |||
cstring counterToAccess) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there always a single counter to access?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe P4_14 only supports a single direct meter and a single direct counter on a table (though it is not really specified). This code only supports one direct meter and one direct counter per table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could not see the error message checking for this in the diff. Maybe it's somewhere else...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a problem with the existing code for both direct_counter and direct_meter that should be addressed.
// Save the original action name in an annotation. | ||
if (counterToAccess != nullptr) { | ||
ExpressionConverter conv(this); | ||
// add a writeback to the meter field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this comment wrong?
auto mc = new IR::MethodCallExpression(Util::SourceInfo(), method, | ||
emptyTypeArguments, args); | ||
auto stat = new IR::MethodCallStatement(mc->srcInfo, mc); | ||
body->push_back(stat); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is a return in the body this statement will be unreachable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was copied from the direct_meter code which is similarly incorrect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P4_14 does not support return in action bodies, so this problem cannot occur.
@@ -1565,8 +1599,15 @@ ProgramStructure::convertControl(const IR::V1Control* control, cstring newName) | |||
::error("Cannot locate table %1%", c.first->table.name); | |||
return nullptr; | |||
} | |||
if (std::find(usedTables.begin(), usedTables.end(), tbl) != usedTables.end()) | |||
directCounters.emplace(c.first->table.name, c.first->name); | |||
if (std::find(usedTables.begin(), usedTables.end(), tbl) != usedTables.end()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if a counter is used in multiple tables?
What if its count method is invoked multiple times?
That is the point of this change -- to make the behavior of the direct counters explicit. This is mostly for backends OTHER than bmv2-ss, as bmv2-ss has implicit direct counters (so we end up inserting the count calls, then just removing them again when we create the json). |
The problem with this change is that you are allowing people to insert explicit calls to count, and then you ignore them. If you plan to change bmv2 this makes sense, but otherwise for the v1model this is pointless. |
If this is for the purpose of other back-ends this transformation should be done in the back-end, and not in the front-end. |
To be clear, I actually like this approach of explicitly indicating counter operations better, it's just that this does not seem to be implemented correctly on the only target implementing v1model that comes with the public compiler: bmv2. So people will write code explicitly invoking count (or NOT invoking count), but bmv2 will do the wrong thing in these cases. So it would be nice if BMv2 would be changed to follow this model. |
The plan is to switch from using simple_switch and v1model.p4 to using bmv2-psa and psa.p4 (portable switch arch, which is the planned p4_16 standard architecture). There will be a bunch more changes for that; this is just one small piece that seems relatively self-contained. |
By definition P4-14 can only be executed on v1model.p4... |
P4_14 can be executed on any architecture that can support it. v1model.p4 is just a stop-gap until we can have the 'proper' P4_16 stdarch -- once that is available, we want to get rid of v1model.p4 and make P4_14->16 translation target the p4_16 standard architecture. |
This may be impossible, or it may restrict severely what can be in the standard architecture. |
9b9175f
to
498c040
Compare
6b0521b
to
baef6e4
Compare
This is a small piece of Pierce's code, just the part that creates explicit 'count' calls for direct counter externs.