Skip to content

Commit e428598

Browse files
mbudiu-vmwChrisDodd
mbudiu-vmw
authored andcommitted
Partial commit; WIP for issues 356, 357; use empty stf file if no file is present to validate json
1 parent cbee56a commit e428598

29 files changed

+660
-64
lines changed

backends/bmv2/jsonconverter.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ class ExpressionConverter : public Inspector {
371371
}
372372

373373
void postorder(const IR::Shr* expression) override {
374-
// special handling for shift of a lookahead -> current
374+
// special handling for shift of a lookahead
375375
auto l = get(expression->left);
376376
if (l->is<Util::JsonObject>()) {
377377
auto jo = l->to<Util::JsonObject>();
@@ -412,7 +412,7 @@ class ExpressionConverter : public Inspector {
412412

413413
void postorder(const IR::Slice* expression) override {
414414
// Special case for parser select: look for
415-
// packet.lookahead<T>()[h:l]. Convert to current(l, h - l).
415+
// packet.lookahead<T>()[h:l]. Convert to lookahead(l, h - l).
416416
// Only correct within a select() expression, but we cannot check that
417417
// since the caller invokes the converter directly with the select argument.
418418
auto m = get(expression->e0);
@@ -2494,6 +2494,20 @@ Util::IJson* JsonConverter::convertParserStatement(const IR::StatOrDecl* stat) {
24942494
}
24952495
return result;
24962496
}
2497+
} else if (minst->is<P4::BuiltInMethod>()) {
2498+
auto bi = minst->to<P4::BuiltInMethod>();
2499+
if (bi->name == IR::Type_Header::setValid || bi->name == IR::Type_Header::setInvalid) {
2500+
auto mem = new IR::Member(Util::SourceInfo(), bi->appliedTo, "$valid$");
2501+
typeMap->setType(mem, IR::Type_Void::get());
2502+
auto jexpr = conv->convert(mem, true, false);
2503+
result->emplace("op", "set");
2504+
params->append(jexpr);
2505+
2506+
auto bl = new IR::BoolLiteral(bi->name == IR::Type_Header::setValid);
2507+
auto r = conv->convert(bl, true, true, true);
2508+
params->append(r);
2509+
return result;
2510+
}
24972511
}
24982512
}
24992513
::error("%1%: not supported in parser on this target", stat);
@@ -2518,6 +2532,9 @@ void JsonConverter::convertSimpleKey(const IR::Expression* keySet,
25182532
} else if (keySet->is<IR::Constant>()) {
25192533
value = keySet->to<IR::Constant>()->value;
25202534
mask = -1;
2535+
} else if (keySet->is<IR::BoolLiteral>()) {
2536+
value = keySet->to<IR::BoolLiteral>()->value ? 1 : 0;
2537+
mask = -1;
25212538
} else {
25222539
::error("%1% must evaluate to a compile-time constant", keySet);
25232540
value = 0;

backends/bmv2/lower.cpp

+52-5
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const IR::Node* LowerExpressions::postorder(IR::Neg* expression) {
4949
auto sub = new IR::Sub(expression->srcInfo, zero, expression->expr);
5050
typeMap->setType(zero, type);
5151
typeMap->setType(sub, type);
52-
LOG1("Replaced " << expression << " with " << sub);
52+
LOG3("Replaced " << expression << " with " << sub);
5353
return sub;
5454
}
5555

@@ -61,14 +61,14 @@ const IR::Node* LowerExpressions::postorder(IR::Cast* expression) {
6161
auto zero = new IR::Constant(srcType, 0);
6262
auto cmp = new IR::Equ(expression->srcInfo, expression->expr, zero);
6363
typeMap->setType(cmp, destType);
64-
LOG1("Replaced " << expression << " with " << cmp);
64+
LOG3("Replaced " << expression << " with " << cmp);
6565
return cmp;
6666
} else if (destType->is<IR::Type_Bits>() && srcType->is<IR::Type_Boolean>()) {
6767
auto mux = new IR::Mux(expression->srcInfo, expression->expr,
6868
new IR::Constant(destType, 1),
6969
new IR::Constant(destType, 0));
7070
typeMap->setType(mux, destType);
71-
LOG1("Replaced " << expression << " with " << mux);
71+
LOG3("Replaced " << expression << " with " << mux);
7272
return mux;
7373
}
7474
// This may be a new expression
@@ -93,7 +93,7 @@ const IR::Node* LowerExpressions::postorder(IR::Slice* expression) {
9393
auto type = IR::Type_Bits::get(h - l + 1);
9494
auto result = new IR::Cast(expression->srcInfo, type, sh);
9595
typeMap->setType(result, type);
96-
LOG1("Replaced " << expression << " with " << result);
96+
LOG3("Replaced " << expression << " with " << result);
9797
return result;
9898
}
9999

@@ -121,7 +121,7 @@ const IR::Node* LowerExpressions::postorder(IR::Concat* expression) {
121121
typeMap->setType(result, resulttype);
122122
typeMap->setType(sh, resulttype);
123123
typeMap->setType(and0, resulttype);
124-
LOG1("Replaced " << expression << " with " << result);
124+
LOG3("Replaced " << expression << " with " << result);
125125
return result;
126126
}
127127

@@ -347,4 +347,51 @@ const IR::Node* FixupChecksum::preorder(IR::P4Control* control) {
347347
return control;
348348
}
349349

350+
////////////////////////////////////////////////////////////////////////////////////
351+
352+
namespace {
353+
354+
// Detect whether a Select expression is too complicated for BMv2
355+
class ComplexExpression : public Inspector {
356+
public:
357+
bool isComplex = false;
358+
ComplexExpression() { setName("ComplexExpression"); }
359+
360+
void postorder(const IR::PathExpression*) override {}
361+
void postorder(const IR::Member*) override {}
362+
void postorder(const IR::Literal*) override {}
363+
// all other expressions are complex
364+
void postorder(const IR::Expression*) override { isComplex = true; }
365+
};
366+
367+
} // namespace
368+
369+
const IR::Node*
370+
RemoveExpressionsFromSelects::postorder(IR::SelectExpression* expression) {
371+
bool changes = true;
372+
auto vec = new IR::Vector<IR::Expression>();
373+
for (auto e : *expression->select->components) {
374+
ComplexExpression ce;
375+
(void)e->apply(ce);
376+
if (ce.isComplex) {
377+
changes = true;
378+
auto type = typeMap->getType(e, true)->getP4Type();
379+
auto name = refMap->newName("tmp");
380+
auto decl = new IR::Declaration_Variable(Util::SourceInfo(), IR::ID(name),
381+
IR::Annotations::empty, type, nullptr);
382+
newDecls.push_back(decl);
383+
auto assign = new IR::AssignmentStatement(
384+
Util::SourceInfo(), new IR::PathExpression(name), e);
385+
assignments.push_back(assign);
386+
vec->push_back(new IR::PathExpression(name));
387+
} else {
388+
vec->push_back(e);
389+
}
390+
}
391+
392+
if (changes)
393+
expression->select = new IR::ListExpression(expression->select->srcInfo, vec);
394+
return expression;
395+
}
396+
350397
} // namespace BMV2

backends/bmv2/lower.h

+41-2
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,17 @@ namespace BMV2 {
2525

2626
// Convert expressions not supported on BMv2
2727
class LowerExpressions : public Transform {
28+
P4::ReferenceMap* refMap;
2829
P4::TypeMap* typeMap;
2930
// Cannot shift with a value larger than 8 bits
3031
const int maxShiftWidth = 8;
3132

3233
const IR::Expression* shift(const IR::Operation_Binary* expression) const;
3334
public:
34-
explicit LowerExpressions(P4::TypeMap* typeMap) : typeMap(typeMap)
35-
{ CHECK_NULL(typeMap); setName("LowerExpressions"); }
35+
explicit LowerExpressions(P4::ReferenceMap* refMap, P4::TypeMap* typeMap) :
36+
refMap(refMap), typeMap(typeMap)
37+
{ CHECK_NULL(refMap); CHECK_NULL(typeMap); setName("LowerExpressions"); }
38+
3639
const IR::Node* postorder(IR::Expression* expression) override;
3740
const IR::Node* postorder(IR::Shl* expression) override
3841
{ return shift(expression); }
@@ -58,6 +61,42 @@ class FixupChecksum : public Transform {
5861
const IR::Node* preorder(IR::P4Control* control) override;
5962
};
6063

64+
65+
// If a select contains an expression which
66+
// looks too complicated, it is lifted into a temporary.
67+
class RemoveExpressionsFromSelects : public Transform {
68+
P4::ReferenceMap* refMap;
69+
P4::TypeMap* typeMap;
70+
IR::IndexedVector<IR::Declaration> newDecls;
71+
IR::IndexedVector<IR::StatOrDecl> assignments;
72+
73+
public:
74+
RemoveExpressionsFromSelects(P4::ReferenceMap* refMap, P4::TypeMap* typeMap):
75+
refMap(refMap), typeMap(typeMap)
76+
{ CHECK_NULL(refMap); CHECK_NULL(typeMap); setName("RemoveExpressionsFromSelects"); }
77+
const IR::Node* postorder(IR::SelectExpression* expression) override;
78+
const IR::Node* preorder(IR::ParserState* state) override
79+
{ assignments.clear(); return state; }
80+
const IR::Node* postorder(IR::ParserState* state) override {
81+
if (!assignments.empty()) {
82+
auto comp = new IR::IndexedVector<IR::StatOrDecl>(*state->components);
83+
comp->append(assignments);
84+
state->components = comp;
85+
}
86+
return state;
87+
}
88+
const IR::Node* preorder(IR::P4Parser* parser) override
89+
{ newDecls.clear(); return parser; }
90+
const IR::Node* postorder(IR::P4Parser* parser) override {
91+
if (!newDecls.empty()) {
92+
auto locals = new IR::IndexedVector<IR::Declaration>(*parser->parserLocals);
93+
locals->append(newDecls);
94+
parser->parserLocals = locals;
95+
}
96+
return parser;
97+
}
98+
};
99+
61100
} // namespace BMV2
62101

63102
#endif /* _BACKENDS_BMV2_LOWER_H_ */

backends/bmv2/midend.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@ limitations under the License.
4444
#include "midend/removeParameters.h"
4545
#include "midend/removeReturns.h"
4646
#include "midend/simplifyKey.h"
47-
#include "midend/simplifySelect.h"
47+
#include "midend/simplifySelectCases.h"
48+
#include "midend/simplifySelectList.h"
4849
#include "midend/validateProperties.h"
4950
#include "midend/compileTimeOps.h"
5051
#include "midend/predication.h"
52+
#include "midend/expandLookahead.h"
5153

5254
namespace BMV2 {
5355

@@ -150,12 +152,14 @@ MidEnd::MidEnd(CompilerOptions& options) {
150152
new P4::NonLeftValue(&refMap, &typeMap)),
151153
new P4::ConstantFolding(&refMap, &typeMap),
152154
new P4::StrengthReduction(),
153-
new P4::SimplifySelect(&refMap, &typeMap, true), // require constant keysets
155+
new P4::SimplifySelectCases(&refMap, &typeMap, true), // require constant keysets
156+
new P4::ExpandLookahead(&refMap, &typeMap),
154157
new P4::SimplifyParsers(&refMap),
155158
new P4::StrengthReduction(),
156159
new P4::EliminateTuples(&refMap, &typeMap),
157160
new P4::CopyStructures(&refMap, &typeMap),
158161
new P4::NestedStructs(&refMap, &typeMap),
162+
new P4::SimplifySelectList(&refMap, &typeMap),
159163
new P4::Predication(&refMap),
160164
new P4::ConstantFolding(&refMap, &typeMap),
161165
new P4::LocalCopyPropagation(&refMap, &typeMap),
@@ -172,8 +176,10 @@ MidEnd::MidEnd(CompilerOptions& options) {
172176
new P4::SimplifyControlFlow(&refMap, &typeMap),
173177
new P4::RemoveLeftSlices(&refMap, &typeMap),
174178
new P4::TypeChecking(&refMap, &typeMap),
175-
new LowerExpressions(&typeMap),
179+
new LowerExpressions(&refMap, &typeMap),
176180
new P4::ConstantFolding(&refMap, &typeMap, false),
181+
new P4::TypeChecking(&refMap, &typeMap),
182+
new RemoveExpressionsFromSelects(&refMap, &typeMap),
177183
new FixupChecksum(&updateControlBlockName),
178184
new P4::SimplifyControlFlow(&refMap, &typeMap),
179185
new P4::RemoveUnusedDeclarations(&refMap),

backends/bmv2/run-bmv2-test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def process_file(options, argv):
217217
else:
218218
result = SUCCESS
219219

220-
if result == SUCCESS:
220+
if result == SUCCESS and not expected_error:
221221
result = run_model(options, tmpdir, jsonfile);
222222

223223
if options.cleanupTmp:

backends/ebpf/midend.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ limitations under the License.
2424
#include "midend/removeParameters.h"
2525
#include "midend/local_copyprop.h"
2626
#include "midend/simplifyKey.h"
27-
#include "midend/simplifySelect.h"
27+
#include "midend/simplifySelectCases.h"
28+
#include "midend/simplifySelectList.h"
2829
#include "midend/validateProperties.h"
2930
#include "midend/eliminateTuples.h"
3031
#include "midend/noMatch.h"
@@ -104,12 +105,13 @@ const IR::ToplevelBlock* MidEnd::run(EbpfOptions& options, const IR::P4Program*
104105
new P4::NonLeftValue(&refMap, &typeMap)),
105106
new P4::RemoveExits(&refMap, &typeMap),
106107
new P4::ConstantFolding(&refMap, &typeMap),
107-
new P4::SimplifySelect(&refMap, &typeMap, false), // accept non-constant keysets
108+
new P4::SimplifySelectCases(&refMap, &typeMap, false), // accept non-constant keysets
108109
new P4::HandleNoMatch(&refMap),
109110
new P4::SimplifyParsers(&refMap),
110111
new P4::StrengthReduction(),
111112
new P4::EliminateTuples(&refMap, &typeMap),
112113
new P4::LocalCopyPropagation(&refMap, &typeMap),
114+
new P4::SimplifySelectList(&refMap, &typeMap),
113115
new P4::MoveDeclarations(), // more may have been introduced
114116
new P4::SimplifyControlFlow(&refMap, &typeMap),
115117
new P4::ValidateTableProperties({"implementation"}),

backends/p4test/midend.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ limitations under the License.
2626
#include "midend/local_copyprop.h"
2727
#include "midend/simplifyKey.h"
2828
#include "midend/parserUnroll.h"
29-
#include "midend/simplifySelect.h"
29+
#include "midend/simplifySelectCases.h"
30+
#include "midend/simplifySelectList.h"
3031
#include "midend/eliminateTuples.h"
3132
#include "midend/nestedStructs.h"
3233
#include "midend/copyStructures.h"
3334
#include "midend/predication.h"
3435
#include "midend/noMatch.h"
36+
#include "midend/expandLookahead.h"
3537
#include "frontends/p4/simplifyParsers.h"
3638
#include "frontends/p4/typeMap.h"
3739
#include "frontends/p4/evaluator/evaluator.h"
@@ -115,13 +117,15 @@ MidEnd::MidEnd(CompilerOptions& options) {
115117
new P4::NonLeftValue(&refMap, &typeMap)),
116118
new P4::RemoveExits(&refMap, &typeMap),
117119
new P4::ConstantFolding(&refMap, &typeMap),
118-
new P4::SimplifySelect(&refMap, &typeMap, false), // non-constant keysets
120+
new P4::SimplifySelectCases(&refMap, &typeMap, false), // non-constant keysets
121+
new P4::ExpandLookahead(&refMap, &typeMap),
119122
new P4::HandleNoMatch(&refMap),
120123
new P4::SimplifyParsers(&refMap),
121124
new P4::StrengthReduction(),
122125
new P4::EliminateTuples(&refMap, &typeMap),
123126
new P4::CopyStructures(&refMap, &typeMap),
124127
new P4::NestedStructs(&refMap, &typeMap),
128+
new P4::SimplifySelectList(&refMap, &typeMap),
125129
new P4::Predication(&refMap),
126130
new P4::ConstantFolding(&refMap, &typeMap),
127131
new P4::LocalCopyPropagation(&refMap, &typeMap),

backends/p4test/run-p4-sample.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def process_file(options, argv):
170170
# We rely on the fact that these keys are in alphabetical order.
171171
rename = { "FrontEnd_11_SimplifyControlFlow": "first",
172172
"FrontEnd_26_FrontEndLast": "frontend",
173-
"MidEnd_33_Evaluator": "midend" }
173+
"MidEnd_35_Evaluator": "midend" }
174174

175175
if options.verbose:
176176
print("Writing temporary files into ", tmpdir)

0 commit comments

Comments
 (0)