diff --git a/backends/bmv2/Makefile.am b/backends/bmv2/Makefile.am index 25a084228ee..b0ecd0e5c1a 100644 --- a/backends/bmv2/Makefile.am +++ b/backends/bmv2/Makefile.am @@ -23,6 +23,8 @@ p4c_bm2_ss_SOURCES = \ backends/bmv2/bmv2.cpp \ backends/bmv2/analyzer.h \ backends/bmv2/analyzer.cpp \ + backends/bmv2/copyStructures.h \ + backends/bmv2/copyStructures.cpp \ backends/bmv2/jsonconverter.h \ backends/bmv2/jsonconverter.cpp \ backends/bmv2/inlining.h \ @@ -30,7 +32,9 @@ p4c_bm2_ss_SOURCES = \ backends/bmv2/midend.h \ backends/bmv2/midend.cpp \ backends/bmv2/lower.h \ - backends/bmv2/lower.cpp + backends/bmv2/lower.cpp \ + backends/bmv2/validateProperties.h \ + backends/bmv2/validateProperties.cpp cpplint_FILES += $(p4c_bm2_ss_SOURCES) @@ -49,8 +53,7 @@ bmv2tests.mk: $(GENTESTS) $(srcdir)/%reldir%/Makefile.am \ $(srcdir)/testdata/p4_16_samples $(srcdir)/testdata/p4_14_samples @$(GENTESTS) $(srcdir) bmv2 $(srcdir)/backends/bmv2/run-bmv2-test.py $^ >$@ -# First 3 exhibit P4_14 features still unimplemented -# Last two are back-end bugs +# These exhibit P4_14 features still unimplemented XFAIL_TESTS += \ bmv2/testdata/p4_14_samples/09-IPv4OptionsUnparsed.p4.test \ bmv2/testdata/p4_14_samples/TLV_parsing.p4.test \ diff --git a/backends/bmv2/copyStructures.cpp b/backends/bmv2/copyStructures.cpp new file mode 100644 index 00000000000..8ea5e3640e4 --- /dev/null +++ b/backends/bmv2/copyStructures.cpp @@ -0,0 +1,52 @@ +/* +Copyright 2016 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "copyStructures.h" + +namespace BMV2 { + +const IR::Node* DoCopyStructures::postorder(IR::AssignmentStatement* statement) { + auto ltype = typeMap->getType(statement->left, true); + if (!ltype->is()) + return statement; + + auto retval = new IR::Vector(); + auto strct = ltype->to(); + if (statement->right->is()) { + auto list = statement->right->to(); + unsigned index = 0; + for (auto f : *strct->fields) { + auto right = list->components->at(index); + auto left = new IR::Member(Util::SourceInfo(), statement->left, f->name); + retval->push_back(new IR::AssignmentStatement(statement->srcInfo, left, right)); + index++; + } + } else { + if (ltype->is()) + // Leave headers as they are -- copy_header will also copy the valid bit + return statement; + + for (auto f : *strct->fields) { + auto right = new IR::Member(Util::SourceInfo(), statement->right, f->name); + auto left = new IR::Member(Util::SourceInfo(), statement->left, f->name); + retval->push_back(new IR::AssignmentStatement(statement->srcInfo, left, right)); + } + } + + return retval; +} + +} // namespace BMV2 diff --git a/backends/bmv2/copyStructures.h b/backends/bmv2/copyStructures.h new file mode 100644 index 00000000000..a7b569a0f49 --- /dev/null +++ b/backends/bmv2/copyStructures.h @@ -0,0 +1,46 @@ +/* +Copyright 2016 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _BACKENDS_BMV2_COPYSTRUCTURES_H_ +#define _BACKENDS_BMV2_COPYSTRUCTURES_H_ + +#include "ir/ir.h" +#include "frontends/p4/typeChecking/typeChecker.h" + +namespace BMV2 { + +// Convert assignments between structures to assignments between fields +class DoCopyStructures : public Transform { + P4::TypeMap* typeMap; + public: + explicit DoCopyStructures(P4::TypeMap* typeMap) : typeMap(typeMap) + { CHECK_NULL(typeMap); setName("DoCopyStructures"); } + const IR::Node* postorder(IR::AssignmentStatement* statement) override; +}; + +class CopyStructures : public PassRepeated { + public: + CopyStructures(P4::ReferenceMap* refMap, P4::TypeMap* typeMap) : + PassManager({}) { + CHECK_NULL(refMap); CHECK_NULL(typeMap); setName("CopyStructures"); + passes.emplace_back(new P4::TypeChecking(refMap, typeMap)); + passes.emplace_back(new DoCopyStructures(typeMap)); + } +}; + +} // namespace BMV2 + +#endif /* _BACKENDS_BMV2_COPYSTRUCTURES_H__ */ diff --git a/backends/bmv2/jsonconverter.cpp b/backends/bmv2/jsonconverter.cpp index 9bbb8d93d8c..da6c9d4739e 100644 --- a/backends/bmv2/jsonconverter.cpp +++ b/backends/bmv2/jsonconverter.cpp @@ -367,7 +367,7 @@ class ExpressionConverter : public Inspector { if (param == converter->stdMetadataParameter) { result->emplace("type", "field"); auto e = mkArrayField(result, "value"); - e->append("standard_metadata"); + e->append(converter->jsonMetadataParameterName); e->append(expression->member); } else { if (type->is()) { @@ -404,11 +404,29 @@ class ExpressionConverter : public Inspector { CHECK_NULL(l); result->emplace("type", "field"); auto e = mkArrayField(result, "value"); - if (l->is()) - e->append(l->to()->get("value")); - else + if (l->is()) { + auto lv = l->to()->get("value"); + if (lv->is()) { + // nested struct reference [ ["m", "f"], "x" ] => [ "m", "f.x" ] + auto array = lv->to(); + BUG_CHECK(array->size() == 2, "expected 2 elements"); + auto first = array->at(0); + auto second = array->at(1); + BUG_CHECK(second->is(), "expected a value"); + e->append(first); + cstring nestedField = second->to()->getString(); + nestedField += "." + expression->member.name; + e->append(nestedField); + } else if (lv->is()) { + e->append(lv); + e->append(expression->member.name); + } else { + BUG("%1%: Unexpected json", lv); + } + } else { e->append(l); - e->append(expression->member.name); + e->append(expression->member.name); + } } } map.emplace(expression, result); @@ -531,9 +549,10 @@ class ExpressionConverter : public Inspector { auto decl = converter->refMap->getDeclaration(expression->path, true); if (auto param = decl->to()) { if (param == converter->stdMetadataParameter) { + // This is a flat struct auto result = new Util::JsonObject(); result->emplace("type", "header"); - result->emplace("value", "standard_metadata"); + result->emplace("value", converter->jsonMetadataParameterName); map.emplace(expression, result); return; } diff --git a/backends/bmv2/jsonconverter.h b/backends/bmv2/jsonconverter.h index 19278efbc4b..c2dfa9bc679 100644 --- a/backends/bmv2/jsonconverter.h +++ b/backends/bmv2/jsonconverter.h @@ -1,5 +1,5 @@ /* -Copyright 2013-present Barefoot Networks, Inc. +Copyright 2013-present Barefoot Networks, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -69,6 +69,7 @@ class JsonConverter final { const IR::Parameter* headerParameter; const IR::Parameter* userMetadataParameter; const IR::Parameter* stdMetadataParameter; + cstring jsonMetadataParameterName = "standard_metadata"; private: Util::JsonArray *headerTypes; diff --git a/backends/bmv2/midend.cpp b/backends/bmv2/midend.cpp index b93cfc7d202..f1c9041bcba 100644 --- a/backends/bmv2/midend.cpp +++ b/backends/bmv2/midend.cpp @@ -15,8 +15,10 @@ limitations under the License. */ #include "midend.h" +#include "validateProperties.h" #include "lower.h" #include "inlining.h" +#include "copyStructures.h" #include "midend/actionsInlining.h" #include "midend/removeReturns.h" #include "midend/moveConstructors.h" @@ -117,7 +119,7 @@ void MidEnd::setup_for_P4_16(CompilerOptions&) { new P4::SimplifyControlFlow(&refMap, &typeMap), new P4::SynthesizeActions(&refMap, &typeMap), new P4::MoveActionsToTables(&refMap, &typeMap), - }); + }); } @@ -134,11 +136,14 @@ MidEnd::MidEnd(CompilerOptions& options) { // BMv2-specific passes auto evaluator = new P4::EvaluatorPass(&refMap, &typeMap); addPasses({ + // TODO: replace Tuple types with structs new P4::SimplifyControlFlow(&refMap, &typeMap), new P4::TypeChecking(&refMap, &typeMap), new P4::RemoveLeftSlices(&typeMap), new P4::TypeChecking(&refMap, &typeMap), new LowerExpressions(&typeMap), + new CopyStructures(&refMap, &typeMap), + new ValidateTableProperties(), new P4::ConstantFolding(&refMap, &typeMap), evaluator, new VisitFunctor([this, evaluator]() { toplevel = evaluator->getToplevelBlock(); }) diff --git a/backends/bmv2/validateProperties.cpp b/backends/bmv2/validateProperties.cpp new file mode 100644 index 00000000000..7e7014b737c --- /dev/null +++ b/backends/bmv2/validateProperties.cpp @@ -0,0 +1,19 @@ +#include "validateProperties.h" + +namespace BMV2 { + +void ValidateTableProperties::postorder(const IR::TableProperty* property) { + static cstring knownProperties[] = { + "actions", + "default_action", + "key", + "implementation", + "size" + }; + for (size_t i=0; i < ELEMENTS(knownProperties); i++) + if (property->name.name == knownProperties[i]) + return; + ::warning("Unknown table property: %1%", property); +} + +} // namespace BMV2 diff --git a/backends/bmv2/validateProperties.h b/backends/bmv2/validateProperties.h new file mode 100644 index 00000000000..bd8ff5d9308 --- /dev/null +++ b/backends/bmv2/validateProperties.h @@ -0,0 +1,35 @@ +/* +Copyright 2016 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _BACKENDS_BMV2_VALIDATEPROPERTIES_H_ +#define _BACKENDS_BMV2_VALIDATEPROPERTIES_H_ + +#include "ir/ir.h" +#include "frontends/p4/typeMap.h" + +namespace BMV2 { + +// Checks to see if there are any unknown properties. +class ValidateTableProperties : public Inspector { + public: + ValidateTableProperties() + { setName("ValidateTableProperties"); } + void postorder(const IR::TableProperty* property) override; +}; + +} // namespace BMV2 + +#endif /* _BACKENDS_BMV2_VALIDATEPROPERTIES_H_ */ diff --git a/frontends/common/resolveReferences/resolveReferences.cpp b/frontends/common/resolveReferences/resolveReferences.cpp index fd9958e0f3b..9ec1bb47430 100644 --- a/frontends/common/resolveReferences/resolveReferences.cpp +++ b/frontends/common/resolveReferences/resolveReferences.cpp @@ -69,7 +69,7 @@ ResolutionContext::resolve(IR::ID name, P4::ResolutionType type, bool previousOn auto vector = decls->toVector(); if (!vector->empty()) { - LOG2("Resolved in " << current->getNode()); + LOG2("Resolved in " << dbp(current->getNode())); return vector; } else { continue; @@ -105,7 +105,7 @@ ResolutionContext::resolve(IR::ID name, P4::ResolutionType type, bool previousOn continue; } - LOG2("Resolved in " << current->getNode()); + LOG2("Resolved in " << dbp(current->getNode())); auto result = new std::vector(); result->push_back(decl); return result; diff --git a/frontends/p4/fromv1.0/v1model.h b/frontends/p4/fromv1.0/v1model.h index 6dba9238289..665bdae3a99 100644 --- a/frontends/p4/fromv1.0/v1model.h +++ b/frontends/p4/fromv1.0/v1model.h @@ -35,7 +35,7 @@ struct Parser_Model : public ::Model::Elem { packetParam("packet", P4::P4CoreLibrary::instance.packetIn, 0), headersParam("hdr", headersType, 1), metadataParam("meta", userMetaType, 2), - standardMetadataParam("stdMeta", standardMetadataType, 3) + standardMetadataParam("standard_metadata", standardMetadataType, 3) {} ::Model::Param_Model packetParam; ::Model::Param_Model headersParam; diff --git a/frontends/p4/sideEffects.cpp b/frontends/p4/sideEffects.cpp index 26a5549c4c6..6b9e97de213 100644 --- a/frontends/p4/sideEffects.cpp +++ b/frontends/p4/sideEffects.cpp @@ -125,6 +125,28 @@ class DismantleExpression : public Transform { typeMap->setType(result->final, type); if (leftValue) typeMap->setLeftValue(result->final); + + if (TableApplySolver::isHit(expression, refMap, typeMap)) { + auto ctx = getContext(); + // f(t.apply().hit) => + // bool tmp; + // if (t.apply().hit) + // tmp = true; + // else + // tmp = false; + // f(tmp) + BUG_CHECK(type->is(), "%1%: not boolean", type); + if (ctx != nullptr && ctx->node->is()) { + auto tmp = result->createTemporary(type); + auto path = new IR::PathExpression(IR::ID(tmp)); + auto tstat = new IR::AssignmentStatement(Util::SourceInfo(), path->clone(), new IR::BoolLiteral(true)); + auto fstat = new IR::AssignmentStatement(Util::SourceInfo(), path->clone(), new IR::BoolLiteral(false)); + auto ifStatement = new IR::IfStatement(Util::SourceInfo(), result->final, tstat, fstat); + result->statements->push_back(ifStatement); + result->final = path->clone(); + typeMap->setType(result->final, type); + } + } prune(); return result->final; } @@ -245,20 +267,9 @@ class DismantleExpression : public Transform { const IR::Node* preorder(IR::LAnd* expression) override { return shortCircuit(expression); } const IR::Node* preorder(IR::LOr* expression) override { return shortCircuit(expression); } - const IR::Node* postorder(IR::Member* expression) override { - LOG1("Visiting " << dbp(expression)); - auto orig = getOriginal(); - result->final = expression; - if (typeMap->isLeftValue(orig)) - typeMap->setLeftValue(result->final); - if (typeMap->isCompileTimeConstant(orig)) - typeMap->setCompileTimeConstant(orig); - return result->final; - } - const IR::Node* preorder(IR::MethodCallExpression* mce) override { BUG_CHECK(!leftValue, "%1%: method on left hand side?", mce); - LOG1("Visiting " << mce); + LOG1("Visiting " << dbp(mce)); auto orig = getOriginal(); auto type = typeMap->getType(orig, true); if (!SideEffects::check(orig, refMap, typeMap)) { diff --git a/frontends/p4/tableApply.h b/frontends/p4/tableApply.h index b4905d328f8..8855268dbdf 100644 --- a/frontends/p4/tableApply.h +++ b/frontends/p4/tableApply.h @@ -27,7 +27,10 @@ limitations under the License. namespace P4 { -// These +// These are used to figure out whether an expression has the form: +// table.apply().hit +// or +// table.apply().action_run class TableApplySolver { public: static const IR::P4Table* isHit(const IR::Expression* expression, diff --git a/midend/actionSynthesis.cpp b/midend/actionSynthesis.cpp index 22a5972d835..c117c37642b 100644 --- a/midend/actionSynthesis.cpp +++ b/midend/actionSynthesis.cpp @@ -44,8 +44,8 @@ const IR::Node* DoMoveActionsToTables::postorder(IR::MethodCallStatement* statem // Action invocation BUG_CHECK(ac->expr->method->is(), "%1%: Expected a PathExpression", ac->expr->method); - auto actionPath = new IR::PathExpression(ac->action->name); - auto call = new IR::MethodCallExpression(Util::SourceInfo(), actionPath, + auto actionPath = new IR::PathExpression(IR::ID(mc->srcInfo, ac->action->name)); + auto call = new IR::MethodCallExpression(mc->srcInfo, actionPath, new IR::Vector(), directionArgs); auto actinst = new IR::ActionListElement(statement->srcInfo, IR::Annotations::empty, call); auto actions = new IR::IndexedVector(); diff --git a/p4include/v1model.p4 b/p4include/v1model.p4 index 43463797150..6a0d71c4cd3 100644 --- a/p4include/v1model.p4 +++ b/p4include/v1model.p4 @@ -112,7 +112,11 @@ extern void recirculate(in T data); extern void clone(in CloneType type, in bit<32> session); extern void clone3(in CloneType type, in bit<32> session, in T data); -// Architecture +// The name 'standard_metadata' is reserved + +// Architecture. +// M should be a struct of structs +// H should be a struct of headers or stacks parser Parser(packet_in b, out H parsedHdr, diff --git a/testdata/p4_16_samples/action-synth.p4 b/testdata/p4_16_samples/action-synth.p4 new file mode 100644 index 00000000000..085c9d2db6a --- /dev/null +++ b/testdata/p4_16_samples/action-synth.p4 @@ -0,0 +1,59 @@ +/* +Copyright 2016 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +struct H { }; +struct M { }; + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { transition accept; } +} + +control Aux(inout M meta) { + action a() {} + apply { + a(); + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + Aux() aux; + apply { + aux.apply(meta); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { } +} + + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), + ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples/hit-expr.p4 b/testdata/p4_16_samples/hit-expr.p4 new file mode 100644 index 00000000000..bde1d44cde2 --- /dev/null +++ b/testdata/p4_16_samples/hit-expr.p4 @@ -0,0 +1,56 @@ +/* +Copyright 2016 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +struct H { }; +struct M { }; + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { transition accept; } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + table t { + key = {} + actions = { NoAction; } + default_action = NoAction(); + } + apply { + if (!t.apply().hit) {} // issue #137 + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { } +} + + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), + ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples/junk-prop-bmv2.p4 b/testdata/p4_16_samples/junk-prop-bmv2.p4 new file mode 100644 index 00000000000..aff0c8469b9 --- /dev/null +++ b/testdata/p4_16_samples/junk-prop-bmv2.p4 @@ -0,0 +1,57 @@ +/* +Copyright 2016 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +struct H { }; +struct M { }; + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { transition accept; } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + table t { + key = {} + actions = { NoAction; } + default_action = NoAction(); + junk = 1; // issue #138 + } + apply { + t.apply(); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { } +} + + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), + ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples/x-bmv2.p4 b/testdata/p4_16_samples/x-bmv2.p4 new file mode 100644 index 00000000000..631ac3bd1af --- /dev/null +++ b/testdata/p4_16_samples/x-bmv2.p4 @@ -0,0 +1,59 @@ +/* +Copyright 2916 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include +typedef standard_metadata_t std_meta_t; + +struct S { bit<32> x; } +header T { bit<32> y; } +struct H { T s; } +struct M { S s; } + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { } +} + +parser ParserI(packet_in b, out H parsedHdr, inout M meta, inout std_meta_t std_meta) { + state start { transition accept; } +} + +control ctrl(inout M meta) { + apply { } +} + +control IngressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + + ctrl() do_ctrl; + + apply { + do_ctrl.apply(meta); + } +} + +control EgressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + apply { } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { } +} +control DeparserI(packet_out b, in H hdr) { + apply { } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), + DeparserI()) main; diff --git a/testdata/p4_16_samples/x-bmv2.stf b/testdata/p4_16_samples/x-bmv2.stf new file mode 100644 index 00000000000..e69de29bb2d diff --git a/testdata/p4_16_samples_outputs/action-synth-first.p4 b/testdata/p4_16_samples_outputs/action-synth-first.p4 new file mode 100644 index 00000000000..bbd33427706 --- /dev/null +++ b/testdata/p4_16_samples_outputs/action-synth-first.p4 @@ -0,0 +1,51 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control Aux(inout M meta) { + action a() { + } + apply { + a(); + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + Aux() aux; + apply { + aux.apply(meta); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/action-synth-frontend.p4 b/testdata/p4_16_samples_outputs/action-synth-frontend.p4 new file mode 100644 index 00000000000..ffe12f0d8f2 --- /dev/null +++ b/testdata/p4_16_samples_outputs/action-synth-frontend.p4 @@ -0,0 +1,51 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control Aux(inout M meta) { + @name("a") action a_0() { + } + apply { + a_0(); + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + @name("aux") Aux() aux_0; + apply { + aux_0.apply(meta); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/action-synth-midend.p4 b/testdata/p4_16_samples_outputs/action-synth-midend.p4 new file mode 100644 index 00000000000..962d010adf6 --- /dev/null +++ b/testdata/p4_16_samples_outputs/action-synth-midend.p4 @@ -0,0 +1,71 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + M meta_1; + @name("aux.a") action aux_a() { + } + action act() { + meta_1 = meta; + } + action act_0() { + meta = meta_1; + } + table tbl_act() { + actions = { + act(); + } + const default_action = act(); + } + table tbl_aux_a() { + actions = { + aux_a(); + } + const default_action = aux_a(); + } + table tbl_act_0() { + actions = { + act_0(); + } + const default_action = act_0(); + } + apply { + tbl_act.apply(); + tbl_aux_a.apply(); + tbl_act_0.apply(); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/action-synth.p4 b/testdata/p4_16_samples_outputs/action-synth.p4 new file mode 100644 index 00000000000..1582ac11b81 --- /dev/null +++ b/testdata/p4_16_samples_outputs/action-synth.p4 @@ -0,0 +1,51 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control Aux(inout M meta) { + action a() { + } + apply { + a(); + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + Aux() aux; + apply { + aux.apply(meta); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/action-synth.p4-stderr b/testdata/p4_16_samples_outputs/action-synth.p4-stderr new file mode 100644 index 00000000000..e69de29bb2d diff --git a/testdata/p4_16_samples_outputs/hit-expr-first.p4 b/testdata/p4_16_samples_outputs/hit-expr-first.p4 new file mode 100644 index 00000000000..0f7aa266387 --- /dev/null +++ b/testdata/p4_16_samples_outputs/hit-expr-first.p4 @@ -0,0 +1,51 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + table t() { + key = { + } + actions = { + NoAction(); + } + default_action = NoAction(); + } + apply { + if (!t.apply().hit) + ; + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/hit-expr-frontend.p4 b/testdata/p4_16_samples_outputs/hit-expr-frontend.p4 new file mode 100644 index 00000000000..7f7f5122629 --- /dev/null +++ b/testdata/p4_16_samples_outputs/hit-expr-frontend.p4 @@ -0,0 +1,53 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + @name("t") table t_0() { + key = { + } + actions = { + NoAction(); + } + default_action = NoAction(); + } + apply { + if (t_0.apply().hit) + ; + else + ; + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/hit-expr-midend.p4 b/testdata/p4_16_samples_outputs/hit-expr-midend.p4 new file mode 100644 index 00000000000..3300023554b --- /dev/null +++ b/testdata/p4_16_samples_outputs/hit-expr-midend.p4 @@ -0,0 +1,55 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + @name("NoAction_1") action NoAction() { + } + @name("t") table t() { + key = { + } + actions = { + NoAction(); + } + default_action = NoAction(); + } + apply { + if (t.apply().hit) + ; + else + ; + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/hit-expr.p4 b/testdata/p4_16_samples_outputs/hit-expr.p4 new file mode 100644 index 00000000000..1cb7d9f772e --- /dev/null +++ b/testdata/p4_16_samples_outputs/hit-expr.p4 @@ -0,0 +1,51 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + table t() { + key = { + } + actions = { + NoAction; + } + default_action = NoAction(); + } + apply { + if (!t.apply().hit) { + } + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/hit-expr.p4-stderr b/testdata/p4_16_samples_outputs/hit-expr.p4-stderr new file mode 100644 index 00000000000..e69de29bb2d diff --git a/testdata/p4_16_samples_outputs/junk-prop-bmv2-first.p4 b/testdata/p4_16_samples_outputs/junk-prop-bmv2-first.p4 new file mode 100644 index 00000000000..7907d0a8382 --- /dev/null +++ b/testdata/p4_16_samples_outputs/junk-prop-bmv2-first.p4 @@ -0,0 +1,51 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + table t() { + key = { + } + actions = { + NoAction(); + } + default_action = NoAction(); + junk = 1; + } + apply { + t.apply(); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/junk-prop-bmv2-frontend.p4 b/testdata/p4_16_samples_outputs/junk-prop-bmv2-frontend.p4 new file mode 100644 index 00000000000..bac9d89f6e2 --- /dev/null +++ b/testdata/p4_16_samples_outputs/junk-prop-bmv2-frontend.p4 @@ -0,0 +1,51 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + @name("t") table t_0() { + key = { + } + actions = { + NoAction(); + } + default_action = NoAction(); + junk = 1; + } + apply { + t_0.apply(); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/junk-prop-bmv2-midend.p4 b/testdata/p4_16_samples_outputs/junk-prop-bmv2-midend.p4 new file mode 100644 index 00000000000..518874185bb --- /dev/null +++ b/testdata/p4_16_samples_outputs/junk-prop-bmv2-midend.p4 @@ -0,0 +1,53 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + @name("NoAction_1") action NoAction() { + } + @name("t") table t() { + key = { + } + actions = { + NoAction(); + } + default_action = NoAction(); + junk = 1; + } + apply { + t.apply(); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/junk-prop-bmv2.p4 b/testdata/p4_16_samples_outputs/junk-prop-bmv2.p4 new file mode 100644 index 00000000000..594925e674f --- /dev/null +++ b/testdata/p4_16_samples_outputs/junk-prop-bmv2.p4 @@ -0,0 +1,51 @@ +#include +#include + +struct H { +} + +struct M { +} + +parser ParserI(packet_in pk, out H hdr, inout M meta, inout standard_metadata_t smeta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + table t() { + key = { + } + actions = { + NoAction; + } + default_action = NoAction(); + junk = 1; + } + apply { + t.apply(); + } +} + +control EgressI(inout H hdr, inout M meta, inout standard_metadata_t smeta) { + apply { + } +} + +control DeparserI(packet_out pk, in H hdr) { + apply { + } +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/junk-prop-bmv2.p4-stderr b/testdata/p4_16_samples_outputs/junk-prop-bmv2.p4-stderr new file mode 100644 index 00000000000..e69de29bb2d diff --git a/testdata/p4_16_samples_outputs/simplify-frontend.p4 b/testdata/p4_16_samples_outputs/simplify-frontend.p4 index 81ae0b4d3f5..bbcfe1b61c5 100644 --- a/testdata/p4_16_samples_outputs/simplify-frontend.p4 +++ b/testdata/p4_16_samples_outputs/simplify-frontend.p4 @@ -2,6 +2,8 @@ control c(out bool x) { bool tmp; + bool tmp_0; + bool tmp_1; @name("t1") table t1_0() { key = { x: exact; @@ -22,11 +24,20 @@ control c(out bool x) { } apply { x = true; - if (!t1_0.apply().hit) - tmp = false; + if (t1_0.apply().hit) + tmp = true; else - tmp = t2_0.apply().hit; - if (tmp) + tmp = false; + if (!tmp) + tmp_0 = false; + else { + if (t2_0.apply().hit) + tmp_1 = true; + else + tmp_1 = false; + tmp_0 = tmp_1; + } + if (tmp_0) x = false; } } diff --git a/testdata/p4_16_samples_outputs/simplify-midend.p4 b/testdata/p4_16_samples_outputs/simplify-midend.p4 index 795681cd0db..2d50ec3135d 100644 --- a/testdata/p4_16_samples_outputs/simplify-midend.p4 +++ b/testdata/p4_16_samples_outputs/simplify-midend.p4 @@ -1,7 +1,9 @@ #include control c(out bool x) { - bool tmp_0; + bool tmp_2; + bool tmp_3; + bool tmp_4; @name("NoAction_1") action NoAction() { } @name("NoAction_2") action NoAction_0() { @@ -25,15 +27,27 @@ control c(out bool x) { default_action = NoAction_0(); } action act() { - tmp_0 = false; + tmp_2 = true; } action act_0() { - tmp_0 = t2.apply().hit; + tmp_2 = false; } action act_1() { x = true; } action act_2() { + tmp_3 = false; + } + action act_3() { + tmp_4 = true; + } + action act_4() { + tmp_4 = false; + } + action act_5() { + tmp_3 = tmp_4; + } + action act_6() { x = false; } table tbl_act() { @@ -60,14 +74,47 @@ control c(out bool x) { } const default_action = act_2(); } + table tbl_act_3() { + actions = { + act_3(); + } + const default_action = act_3(); + } + table tbl_act_4() { + actions = { + act_4(); + } + const default_action = act_4(); + } + table tbl_act_5() { + actions = { + act_5(); + } + const default_action = act_5(); + } + table tbl_act_6() { + actions = { + act_6(); + } + const default_action = act_6(); + } apply { tbl_act.apply(); - if (!t1.apply().hit) + if (t1.apply().hit) tbl_act_0.apply(); else tbl_act_1.apply(); - if (tmp_0) + if (!tmp_2) tbl_act_2.apply(); + else { + if (t2.apply().hit) + tbl_act_3.apply(); + else + tbl_act_4.apply(); + tbl_act_5.apply(); + } + if (tmp_3) + tbl_act_6.apply(); } } diff --git a/testdata/p4_16_samples_outputs/x-bmv2-first.p4 b/testdata/p4_16_samples_outputs/x-bmv2-first.p4 new file mode 100644 index 00000000000..a96dbd96032 --- /dev/null +++ b/testdata/p4_16_samples_outputs/x-bmv2-first.p4 @@ -0,0 +1,59 @@ +#include +#include + +typedef standard_metadata_t std_meta_t; +struct S { + bit<32> x; +} + +header T { + bit<32> y; +} + +struct H { + T s; +} + +struct M { + S s; +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +parser ParserI(packet_in b, out H parsedHdr, inout M meta, inout std_meta_t std_meta) { + state start { + transition accept; + } +} + +control ctrl(inout M meta) { + apply { + } +} + +control IngressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + ctrl() do_ctrl; + apply { + do_ctrl.apply(meta); + } +} + +control EgressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +control DeparserI(packet_out b, in H hdr) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/x-bmv2-frontend.p4 b/testdata/p4_16_samples_outputs/x-bmv2-frontend.p4 new file mode 100644 index 00000000000..adedd733a84 --- /dev/null +++ b/testdata/p4_16_samples_outputs/x-bmv2-frontend.p4 @@ -0,0 +1,59 @@ +#include +#include + +typedef standard_metadata_t std_meta_t; +struct S { + bit<32> x; +} + +header T { + bit<32> y; +} + +struct H { + T s; +} + +struct M { + S s; +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +parser ParserI(packet_in b, out H parsedHdr, inout M meta, inout std_meta_t std_meta) { + state start { + transition accept; + } +} + +control ctrl(inout M meta) { + apply { + } +} + +control IngressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + @name("do_ctrl") ctrl() do_ctrl_0; + apply { + do_ctrl_0.apply(meta); + } +} + +control EgressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +control DeparserI(packet_out b, in H hdr) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/x-bmv2-midend.p4 b/testdata/p4_16_samples_outputs/x-bmv2-midend.p4 new file mode 100644 index 00000000000..c101d906856 --- /dev/null +++ b/testdata/p4_16_samples_outputs/x-bmv2-midend.p4 @@ -0,0 +1,64 @@ +#include +#include + +typedef standard_metadata_t std_meta_t; +struct S { + bit<32> x; +} + +header T { + bit<32> y; +} + +struct H { + T s; +} + +struct M { + S s; +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +parser ParserI(packet_in b, out H parsedHdr, inout M meta, inout std_meta_t std_meta) { + state start { + transition accept; + } +} + +control IngressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + M meta_1; + action act() { + meta_1 = meta; + meta = meta_1; + } + table tbl_act() { + actions = { + act(); + } + const default_action = act(); + } + apply { + tbl_act.apply(); + } +} + +control EgressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +control DeparserI(packet_out b, in H hdr) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/x-bmv2.p4 b/testdata/p4_16_samples_outputs/x-bmv2.p4 new file mode 100644 index 00000000000..b22bf2b0fc0 --- /dev/null +++ b/testdata/p4_16_samples_outputs/x-bmv2.p4 @@ -0,0 +1,59 @@ +#include +#include + +typedef standard_metadata_t std_meta_t; +struct S { + bit<32> x; +} + +header T { + bit<32> y; +} + +struct H { + T s; +} + +struct M { + S s; +} + +control VerifyChecksumI(in H hdr, inout M meta) { + apply { + } +} + +parser ParserI(packet_in b, out H parsedHdr, inout M meta, inout std_meta_t std_meta) { + state start { + transition accept; + } +} + +control ctrl(inout M meta) { + apply { + } +} + +control IngressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + ctrl() do_ctrl; + apply { + do_ctrl.apply(meta); + } +} + +control EgressI(inout H hdr, inout M meta, inout std_meta_t std_meta) { + apply { + } +} + +control ComputeChecksumI(inout H hdr, inout M meta) { + apply { + } +} + +control DeparserI(packet_out b, in H hdr) { + apply { + } +} + +V1Switch(ParserI(), VerifyChecksumI(), IngressI(), EgressI(), ComputeChecksumI(), DeparserI()) main; diff --git a/testdata/p4_16_samples_outputs/x-bmv2.p4-stderr b/testdata/p4_16_samples_outputs/x-bmv2.p4-stderr new file mode 100644 index 00000000000..e69de29bb2d