Skip to content

Commit 973cc13

Browse files
author
mbudiu-vmw
committed
Fix for issues #138 and #141
1 parent 6665263 commit 973cc13

Some content is hidden

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

45 files changed

+802
-85
lines changed

backends/bmv2/Makefile.am

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ p4c_bm2_ss_SOURCES = \
3232
backends/bmv2/midend.h \
3333
backends/bmv2/midend.cpp \
3434
backends/bmv2/lower.h \
35-
backends/bmv2/lower.cpp
35+
backends/bmv2/lower.cpp \
36+
backends/bmv2/eliminateVerify.h \
37+
backends/bmv2/eliminateVerify.cpp
3638

3739
cpplint_FILES += $(p4c_bm2_ss_SOURCES)
3840

backends/bmv2/eliminateVerify.cpp

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include "eliminateVerify.h"
2+
#include "frontends/p4/methodInstance.h"
3+
4+
namespace BMV2 {
5+
6+
// Convert verify(b, e)
7+
// into
8+
// transition select(b) {
9+
// false : reject;
10+
// true : continuation;
11+
// }
12+
// The error is just ignored - BMv2 does not expose it
13+
const IR::Node* EliminateVerify::postorder(IR::ParserState* state) {
14+
// This code is very similar to RemoveParserControlFlow
15+
LOG1("Visiting " << dbp(state));
16+
// Set of newly created states
17+
auto states = new IR::IndexedVector<IR::ParserState>();
18+
IR::ParserState* currentState = state;
19+
// components of the currentState
20+
auto currentComponents = new IR::IndexedVector<IR::StatOrDecl>();
21+
auto origComponents = state->components;
22+
auto origSelect = state->selectExpression;
23+
24+
cstring joinName; // non-empty if we split the state
25+
for (auto c : *origComponents) {
26+
if (c->is<IR::MethodCallStatement>()) {
27+
auto mcs = c->to<IR::MethodCallStatement>();
28+
auto mi = P4::MethodInstance::resolve(mcs, refMap, typeMap);
29+
auto ef = mi->to<P4::ExternFunction>();
30+
if (ef != nullptr &&
31+
ef->method->name.name == IR::ParserState::verify) {
32+
LOG1("Converting " << dbp(c) << " into states");
33+
34+
states->push_back(currentState);
35+
BUG_CHECK(mcs->methodCall->arguments->size() == 2, "%1%: Expected 2 arguments", mcs);
36+
auto cond = mcs->methodCall->arguments->at(0);
37+
cstring joinName = refMap->newName(state->name.name + "_join");
38+
39+
auto vec = new IR::Vector<IR::Expression>();
40+
vec->push_back(cond);
41+
auto trueCase = new IR::SelectCase(
42+
Util::SourceInfo(), new IR::BoolLiteral(true),
43+
new IR::PathExpression(IR::ID(joinName)));
44+
auto falseCase = new IR::SelectCase(
45+
Util::SourceInfo(), new IR::BoolLiteral(false),
46+
new IR::PathExpression(IR::ID(IR::ParserState::reject)));
47+
auto cases = new IR::Vector<IR::SelectCase>();
48+
cases->push_back(trueCase);
49+
cases->push_back(falseCase);
50+
currentState->selectExpression = new IR::SelectExpression(
51+
Util::SourceInfo(), new IR::ListExpression(vec), std::move(*cases));
52+
53+
currentState->components = currentComponents;
54+
currentComponents = new IR::IndexedVector<IR::StatOrDecl>();
55+
currentState = new IR::ParserState(
56+
Util::SourceInfo(), joinName, IR::Annotations::empty,
57+
currentComponents, origSelect); // may be overriten
58+
}
59+
} else {
60+
currentComponents->push_back(c);
61+
}
62+
}
63+
64+
if (states->empty())
65+
return state;
66+
states->push_back(currentState);
67+
return states;
68+
}
69+
70+
} // namespace BMV2

backends/bmv2/eliminateVerify.h

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
Copyright 2016 VMware, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#ifndef _BACKENDS_BMV2_ELIMINATEVERIFY_H_
18+
#define _BACKENDS_BMV2_ELIMINATEVERIFY_H_
19+
20+
#include "ir/ir.h"
21+
#include "frontends/p4/typeChecking/typeChecker.h"
22+
23+
namespace BMV2 {
24+
25+
// convert verify into select
26+
class EliminateVerify : public Transform {
27+
P4::ReferenceMap* refMap;
28+
P4::TypeMap* typeMap;
29+
public:
30+
const IR::Node* postorder(IR::ParserState* state) override;
31+
EliminateVerify(P4::ReferenceMap* refMap, P4::TypeMap* typeMap) : refMap(refMap), typeMap(typeMap)
32+
{ CHECK_NULL(refMap); CHECK_NULL(typeMap); setName("EliminateVerify"); }
33+
};
34+
35+
} // namespace BMV2
36+
37+
#endif /* _BACKENDS_BMV2_ELIMINATEVERIFY_H_ */

backends/bmv2/jsonconverter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2097,7 +2097,7 @@ Util::IJson* JsonConverter::toJson(const IR::P4Parser* parser) {
20972097
auto result = new Util::JsonObject();
20982098
result->emplace("name", "parser"); // at least in simple_router this name is hardwired
20992099
result->emplace("id", nextId("parser"));
2100-
result->emplace("init_state", IR::ParserState::start.name);
2100+
result->emplace("init_state", IR::ParserState::start);
21012101
auto states = mkArrayField(result, "parse_states");
21022102

21032103
for (auto state : *parser->states) {

backends/bmv2/midend.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818
#include "lower.h"
1919
#include "inlining.h"
2020
#include "copyStructures.h"
21+
#include "eliminateVerify.h"
2122
#include "midend/actionsInlining.h"
2223
#include "midend/validateProperties.h"
2324
#include "midend/removeReturns.h"
@@ -29,7 +30,6 @@ limitations under the License.
2930
#include "midend/removeLeftSlices.h"
3031
#include "midend/convertEnums.h"
3132
#include "midend/simplifyKey.h"
32-
#include "midend/parserControlFlow.h"
3333
#include "midend/simplifySelect.h"
3434
#include "frontends/p4/uniqueNames.h"
3535
#include "frontends/p4/simplifyParsers.h"
@@ -85,7 +85,6 @@ void MidEnd::setup_for_P4_16(CompilerOptions&) {
8585
// we may come through this path even if the program is actually a P4 v1.0 program
8686
auto evaluator = new P4::EvaluatorPass(&refMap, &typeMap);
8787
addPasses({
88-
new P4::RemoveParserControlFlow(&refMap, &typeMap),
8988
new P4::ConvertEnums(&refMap, &typeMap,
9089
new EnumOn32Bits()),
9190
new P4::RemoveReturns(&refMap),
@@ -137,13 +136,15 @@ MidEnd::MidEnd(CompilerOptions& options) {
137136
auto evaluator = new P4::EvaluatorPass(&refMap, &typeMap);
138137
addPasses({
139138
// TODO: replace Tuple types with structs
139+
new EliminateVerify(&refMap, &typeMap),
140140
new P4::SimplifyControlFlow(&refMap, &typeMap),
141141
new P4::TypeChecking(&refMap, &typeMap),
142142
new P4::RemoveLeftSlices(&typeMap),
143143
new P4::TypeChecking(&refMap, &typeMap),
144144
new LowerExpressions(&typeMap),
145145
new CopyStructures(&refMap, &typeMap),
146-
new P4::ValidateTableProperties({ "implementation", "size" }),
146+
new P4::ValidateTableProperties({ "implementation", "size", "counters",
147+
"meters", "size", "supportTimeout" }),
147148
new P4::ConstantFolding(&refMap, &typeMap),
148149
evaluator,
149150
new VisitFunctor([this, evaluator]() { toplevel = evaluator->getToplevelBlock(); })

backends/ebpf/ebpfObject.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void EBPFProgram::emit(CodeBuilder *builder) {
8383
createLocalVariables(builder);
8484
builder->newline();
8585
builder->emitIndent();
86-
builder->appendFormat("goto %s;", IR::ParserState::start.name.c_str());
86+
builder->appendFormat("goto %s;", IR::ParserState::start.c_str());
8787
builder->newline();
8888

8989
parser->emit(builder);

backends/ebpf/ebpfParser.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ bool StateTranslationVisitor::preorder(const IR::ParserState* parserState) {
6363
if (parserState->selectExpression == nullptr) {
6464
builder->emitIndent();
6565
builder->append("goto ");
66-
builder->append(IR::ParserState::reject.name);
66+
builder->append(IR::ParserState::reject);
6767
builder->endOfStatement(true);
6868
} else if (parserState->selectExpression->is<IR::SelectExpression>()) {
6969
visit(parserState->selectExpression);
@@ -95,7 +95,7 @@ bool StateTranslationVisitor::preorder(const IR::SelectExpression* expression) {
9595

9696
if (!hasDefault) {
9797
builder->emitIndent();
98-
builder->appendFormat("default: goto %s;", IR::ParserState::reject.name.c_str());
98+
builder->appendFormat("default: goto %s;", IR::ParserState::reject.c_str());
9999
builder->newline();
100100
}
101101

@@ -137,7 +137,7 @@ StateTranslationVisitor::compileExtractField(
137137
builder->newline();
138138

139139
builder->emitIndent();
140-
builder->appendFormat("goto %s;", IR::ParserState::reject.name.c_str());
140+
builder->appendFormat("goto %s;", IR::ParserState::reject.c_str());
141141
builder->newline();
142142
builder->blockEnd(true);
143143

@@ -330,7 +330,7 @@ void EBPFParser::emit(CodeBuilder *builder) {
330330

331331
// Create a synthetic reject state
332332
builder->emitIndent();
333-
builder->appendFormat("%s: { return 1; }", IR::ParserState::reject.name.c_str());
333+
builder->appendFormat("%s: { return 1; }", IR::ParserState::reject.c_str());
334334
builder->newline();
335335
builder->newline();
336336
}

backends/p4test/midend.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ limitations under the License.
2626
#include "midend/simplifyKey.h"
2727
#include "midend/parserUnroll.h"
2828
#include "midend/simplifySelect.h"
29-
#include "midend/parserControlFlow.h"
3029
#include "frontends/p4/simplifyParsers.h"
3130
#include "frontends/p4/typeMap.h"
3231
#include "frontends/p4/evaluator/evaluator.h"
@@ -54,7 +53,6 @@ MidEnd::MidEnd(CompilerOptions& options) {
5453
// TODO: lower errors to integers
5554
// TODO: handle bit-slices as out arguments
5655
addPasses({
57-
new P4::RemoveParserControlFlow(&refMap, &typeMap),
5856
new P4::RemoveReturns(&refMap),
5957
new P4::MoveConstructors(&refMap),
6058
new P4::RemoveAllUnusedDeclarations(&refMap),

backends/p4test/run-p4-sample.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ def process_file(options, argv):
185185

186186
# We rely on the fact that these keys are in alphabetical order.
187187
rename = { "FrontEnd_11_SimplifyControlFlow": "first",
188-
"FrontEnd_23_SpecializeAll": "frontend",
189-
"MidEnd_27_Evaluator": "midend" }
188+
"FrontEnd_24_RemoveParserControlFlow": "frontend",
189+
"MidEnd_26_Evaluator": "midend" }
190190

191191
if options.verbose:
192192
print("Writing temporary files into ", tmpdir)

frontends/Makefile.am

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ p4_frontend_SOURCES = \
4444
frontends/p4/evaluator/evaluator.cpp \
4545
frontends/p4/evaluator/substituteParameters.h \
4646
frontends/p4/evaluator/substituteParameters.cpp \
47+
frontends/p4/parserControlFlow.cpp \
48+
frontends/p4/parserControlFlow.h \
4749
frontends/p4/cloner.h \
4850
frontends/p4/reservedWords.h \
4951
frontends/p4/reservedWords.cpp \

frontends/p4/coreLibrary.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ enum class StandardExceptions {
2828
EmptyStack,
2929
FullStack,
3030
OverwritingHeader,
31-
HeaderTooShort
31+
HeaderTooShort,
32+
ParserTimeout,
3233
};
3334
} // namespace P4
3435

@@ -55,6 +56,9 @@ inline std::ostream& operator<<(std::ostream &out, P4::StandardExceptions e) {
5556
case P4::StandardExceptions::HeaderTooShort:
5657
out << "HeaderTooShort";
5758
break;
59+
case P4::StandardExceptions::ParserTimeout:
60+
out << "ParserTimeout";
61+
break;
5862
default:
5963
BUG("Unhandled case");
6064
}
@@ -91,8 +95,8 @@ class P4Exception_Model : public ::Model::Elem {
9195
}
9296
};
9397

94-
// Model of P4 standard library
95-
// To be kept in sync with corelib.p4
98+
// Model of P4 core library
99+
// To be kept in sync with core.p4
96100
class P4CoreLibrary : public ::Model::Model {
97101
protected:
98102
P4CoreLibrary() :

frontends/p4/def_use.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ bool ComputeWriteSet::preorder(const IR::EmptyStatement*) {
725725
}
726726

727727
bool ComputeWriteSet::preorder(const IR::AssignmentStatement* statement) {
728-
LOG1("Visiting " << dbp(statement));
728+
LOG1("Visiting " << dbp(statement) << " " << statement);
729729
lhs = true;
730730
visit(statement->left);
731731
lhs = false;
@@ -739,6 +739,7 @@ bool ComputeWriteSet::preorder(const IR::AssignmentStatement* statement) {
739739
}
740740

741741
bool ComputeWriteSet::preorder(const IR::SwitchStatement* statement) {
742+
LOG1("Visiting " << dbp(statement));
742743
visit(statement->expression);
743744
auto locs = get(statement->expression);
744745
auto defs = currentDefinitions->writes(getProgramPoint(), locs);

frontends/p4/def_use.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,10 @@ class Definitions {
288288
{ CHECK_NULL(loc); CHECK_NULL(point); definitions[loc] = point; }
289289
void set(const StorageLocation* loc, const ProgramPoints* point);
290290
void set(const LocationSet* loc, const ProgramPoints* point);
291-
const ProgramPoints* get(const BaseLocation* location) const
292-
{ auto r = ::get(definitions, location); CHECK_NULL(r); return r; }
291+
const ProgramPoints* get(const BaseLocation* location) const {
292+
auto r = ::get(definitions, location);
293+
BUG_CHECK(r != nullptr, "%1%: no definitions", location);
294+
return r; }
293295
const ProgramPoints* get(const LocationSet* locations) const;
294296
bool operator==(const Definitions& other) const;
295297
void dbprint(std::ostream& out) const {

frontends/p4/fromv1.0/programStructure.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ void ProgramStructure::createDeparser() {
512512
}
513513
}
514514

515-
cstring start = IR::ParserState::start.name;
515+
cstring start = IR::ParserState::start;
516516
const IR::Expression* startHeader;
517517
// find starting point
518518
if (extracts.count(start) != 0) {

frontends/p4/frontend.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ limitations under the License.
4343
#include "simplifyDefUse.h"
4444
#include "simplifyParsers.h"
4545
#include "specialize.h"
46+
#include "parserControlFlow.h"
4647

4748
namespace P4 {
4849

@@ -110,6 +111,7 @@ FrontEnd::run(const CompilerOptions &options, const IR::P4Program* program) {
110111
new SimplifyDefUse(&refMap, &typeMap),
111112
new SimplifyControlFlow(&refMap, &typeMap),
112113
new SpecializeAll(&refMap, &typeMap),
114+
new RemoveParserControlFlow(&refMap, &typeMap),
113115
};
114116

115117
passes.setName("FrontEnd");

midend/parserControlFlow.cpp frontends/p4/parserControlFlow.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const IR::Node* DoRemoveParserControlFlow::postorder(IR::ParserState* state) {
8686
trueComponents->push_back(ifstat->ifTrue);
8787
auto trueState = new IR::ParserState(
8888
Util::SourceInfo(), trueName, IR::Annotations::empty, trueComponents,
89-
new IR::PathExpression(IR::ID(joinName)));
89+
new IR::PathExpression(IR::ID(joinName, nullptr)));
9090
states->push_back(trueState);
9191

9292
// s_false
@@ -97,7 +97,7 @@ const IR::Node* DoRemoveParserControlFlow::postorder(IR::ParserState* state) {
9797
falseComponents->push_back(ifstat->ifFalse);
9898
auto falseState = new IR::ParserState(
9999
Util::SourceInfo(), falseName, IR::Annotations::empty, falseComponents,
100-
new IR::PathExpression(IR::ID(joinName)));
100+
new IR::PathExpression(IR::ID(joinName, nullptr)));
101101
states->push_back(falseState);
102102
}
103103

@@ -106,10 +106,10 @@ const IR::Node* DoRemoveParserControlFlow::postorder(IR::ParserState* state) {
106106
vec->push_back(ifstat->condition);
107107
auto trueCase = new IR::SelectCase(
108108
Util::SourceInfo(), new IR::BoolLiteral(true),
109-
new IR::PathExpression(IR::ID(trueName)));
109+
new IR::PathExpression(IR::ID(trueName, nullptr)));
110110
auto falseCase = new IR::SelectCase(
111111
Util::SourceInfo(), new IR::BoolLiteral(false),
112-
new IR::PathExpression(IR::ID(falseName)));
112+
new IR::PathExpression(IR::ID(falseName, nullptr)));
113113
auto cases = new IR::Vector<IR::SelectCase>();
114114
cases->push_back(trueCase);
115115
cases->push_back(falseCase);
File renamed without changes.

0 commit comments

Comments
 (0)