Skip to content
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

Enable loopsunrolling by default [recreated] #3142

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
  •  
  •  
  •  
113 changes: 57 additions & 56 deletions backends/bmv2/simple_switch/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,62 +72,63 @@ SimpleSwitchMidEnd::SimpleSwitchMidEnd(CompilerOptions &options, std::ostream *o
if (BMV2::SimpleSwitchContext::get().options().loadIRFromJson == false) {
auto *convertEnums =
new P4::ConvertEnums(&refMap, &typeMap, new EnumOn32Bits("v1model.p4"));
addPasses(
{options.ndebug ? new P4::RemoveAssertAssume(&refMap, &typeMap) : nullptr,
new P4::CheckTableSize(),
new P4::RemoveMiss(&refMap, &typeMap),
new P4::EliminateNewtype(&refMap, &typeMap),
new P4::EliminateInvalidHeaders(&refMap, &typeMap),
new P4::EliminateSerEnums(&refMap, &typeMap),
convertEnums,
[this, convertEnums]() { enumMap = convertEnums->getEnumMapping(); },
new P4::OrderArguments(&refMap, &typeMap),
new P4::TypeChecking(&refMap, &typeMap),
new P4::SimplifyKey(
&refMap, &typeMap,
new P4::OrPolicy(new P4::IsValid(&refMap, &typeMap), new P4::IsMask())),
new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap),
new P4::SimplifySelectCases(&refMap, &typeMap, true), // require constant keysets
new P4::ExpandLookahead(&refMap, &typeMap),
new P4::ExpandEmit(&refMap, &typeMap),
new P4::SimplifyParsers(&refMap),
new P4::StrengthReduction(&refMap, &typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap),
new P4::NestedStructs(&refMap, &typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
new P4::RemoveSelectBooleans(&refMap, &typeMap),
new P4::FlattenHeaders(&refMap, &typeMap),
new P4::FlattenInterfaceStructs(&refMap, &typeMap),
new P4::ReplaceSelectRange(&refMap, &typeMap),
new P4::Predication(&refMap),
new P4::MoveDeclarations(), // more may have been introduced
new P4::ConstantFolding(&refMap, &typeMap),
new P4::LocalCopyPropagation(&refMap, &typeMap),
new PassRepeated({new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap)}),
new P4::SimplifyKey(
&refMap, &typeMap,
new P4::OrPolicy(new P4::IsValid(&refMap, &typeMap), new P4::IsMask())),
new P4::MoveDeclarations(),
new P4::ValidateTableProperties(
{"implementation", "size", "counters", "meters", "support_timeout"}),
new P4::SimplifyControlFlow(&refMap, &typeMap),
new P4::EliminateTypedef(&refMap, &typeMap),
new P4::CompileTimeOperations(),
new P4::TableHit(&refMap, &typeMap),
new P4::EliminateSwitch(&refMap, &typeMap),
new P4::RemoveLeftSlices(&refMap, &typeMap),
// p4c-bm removed unused action parameters. To produce a compatible
// control plane API, we remove them as well for P4-14 programs.
{isv1 ? new P4::RemoveUnusedActionParameters(&refMap) : nullptr},
new P4::TypeChecking(&refMap, &typeMap),
{options.loopsUnrolling ? new P4::ParsersUnroll(true, &refMap, &typeMap) : nullptr},
evaluator,
[this, evaluator]() { toplevel = evaluator->getToplevelBlock(); },
new P4::MidEndLast()});
addPasses({options.ndebug ? new P4::RemoveAssertAssume(&refMap, &typeMap) : nullptr,
new P4::CheckTableSize(),
new P4::RemoveMiss(&refMap, &typeMap),
new P4::EliminateNewtype(&refMap, &typeMap),
new P4::EliminateInvalidHeaders(&refMap, &typeMap),
new P4::EliminateSerEnums(&refMap, &typeMap),
convertEnums,
[this, convertEnums]() { enumMap = convertEnums->getEnumMapping(); },
new P4::OrderArguments(&refMap, &typeMap),
new P4::TypeChecking(&refMap, &typeMap),
new P4::SimplifyKey(
&refMap, &typeMap,
new P4::OrPolicy(new P4::IsValid(&refMap, &typeMap), new P4::IsMask())),
new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap),
// require constant keysets
new P4::SimplifySelectCases(&refMap, &typeMap, true),
new P4::ExpandLookahead(&refMap, &typeMap),
new P4::ExpandEmit(&refMap, &typeMap),
new P4::SimplifyParsers(&refMap),
new P4::StrengthReduction(&refMap, &typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap),
new P4::NestedStructs(&refMap, &typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
new P4::RemoveSelectBooleans(&refMap, &typeMap),
new P4::FlattenHeaders(&refMap, &typeMap),
new P4::FlattenInterfaceStructs(&refMap, &typeMap),
new P4::ReplaceSelectRange(&refMap, &typeMap),
new P4::Predication(&refMap),
new P4::MoveDeclarations(), // more may have been introduced
new P4::ConstantFolding(&refMap, &typeMap),
new P4::LocalCopyPropagation(&refMap, &typeMap),
new PassRepeated({new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap)}),
new P4::SimplifyKey(
&refMap, &typeMap,
new P4::OrPolicy(new P4::IsValid(&refMap, &typeMap), new P4::IsMask())),
new P4::MoveDeclarations(),
new P4::ValidateTableProperties(
{"implementation", "size", "counters", "meters", "support_timeout"}),
new P4::SimplifyControlFlow(&refMap, &typeMap),
new P4::EliminateTypedef(&refMap, &typeMap),
new P4::CompileTimeOperations(),
new P4::TableHit(&refMap, &typeMap),
new P4::EliminateSwitch(&refMap, &typeMap),
new P4::RemoveLeftSlices(&refMap, &typeMap),
// p4c-bm removed unused action parameters. To produce a compatible
// control plane API, we remove them as well for P4-14 programs.
{(isv1 ? new P4::RemoveUnusedActionParameters(&refMap) : nullptr)},
new P4::TypeChecking(&refMap, &typeMap),
// Try to unroll all parser loops.
new P4::ParsersUnroll(true, &refMap, &typeMap),
evaluator,
[this, evaluator]() { toplevel = evaluator->getToplevelBlock(); },
new P4::MidEndLast()});
if (options.listMidendPasses) {
listPasses(*outStream, "\n");
*outStream << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion backends/p4test/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ MidEnd::MidEnd(CompilerOptions &options, std::ostream *outStream) {
new P4::HSIndexSimplifier(&refMap, &typeMap),
new P4::SynthesizeActions(&refMap, &typeMap, new SkipControls(v1controls)),
new P4::MoveActionsToTables(&refMap, &typeMap),
options.loopsUnrolling ? new P4::ParsersUnroll(true, &refMap, &typeMap) : nullptr,
new P4::ParsersUnroll(true, &refMap, &typeMap),
evaluator,
[this, evaluator]() { toplevel = evaluator->getToplevelBlock(); },
new P4::MidEndLast()});
Expand Down
13 changes: 0 additions & 13 deletions backends/p4tools/modules/testgen/targets/bmv2/test/BMV2Xfail.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
p4tools_add_xfail_reason(
"testgen-p4c-bmv2"
"simple_switch died with return code -6"
# Assertion 'Default switch case should not be reachable' failed,
# file '../../include/bm/bm_sim/actions.h' line '369'.
issue1607-bmv2.p4
bmv2_copy_headers.p4

# terminate called after throwing an instance of 'std::out_of_range'
# h.array[h.h.a].index
# It turns out that h.h.a matters more than the size of the array
Expand Down Expand Up @@ -237,14 +232,6 @@ p4tools_add_xfail_reason(
####################################################################################################
# These tests require additional input parameters to compile properly.

p4tools_add_xfail_reason(
"testgen-p4c-bmv2"
"uninitialized: next field read"
# error: parsedHdr.hstack.next uninitialized: next field read
# next not implemented in p4c/backends/bmv2/common/expression.cpp line 367
next-def-use.p4
)

p4tools_add_xfail_reason(
"testgen-p4c-bmv2"
"headers: the type should be a struct of headers, stacks, or unions"
Expand Down
17 changes: 16 additions & 1 deletion midend/parserUnroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ class ParserStateRewriter : public Transform {
ParserStateRewriter rewriter(parserStructure, state, valueMap, refMap, typeMap, afterExec,
visitedStates);
auto basetype = getTypeArray(expression->left);
if (!basetype->is<IR::Type_Stack>()) return expression;
if (!basetype->is<IR::Type_Stack>() || expression->right->is<IR::Constant>()) {
return expression;
}
IR::ArrayIndex *newExpression = expression->clone();
ExpressionEvaluator ev(refMap, typeMap, valueMap);
auto *value = ev.evaluate(expression->right, false);
Expand Down Expand Up @@ -691,6 +693,19 @@ class ParserSymbolicInterpreter {
return false;
}

/// Find previous state with the same and ad checks indexes.
bool hasTheSameIdexes(ParserStateInfo *state) {
const ParserStateInfo *crt = state;
while (true) {
crt = crt->predecessor;
if (crt == nullptr) return false;
if (crt->state == state->state) {
return equStackVariableMap(crt->statesIndexes, state->statesIndexes);
}
}
return false;
}

/// Gets new name for a state
IR::ID getNewName(ParserStateInfo *state) {
if (state->currentIndex == 0) {
Expand Down
41 changes: 38 additions & 3 deletions testdata/p4_14_samples_outputs/06-SimpleVlanStack-midend.p4
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ struct headers {
}

parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
state stateOutOfBound {
verify(false, error.StackOutOfBounds);
transition reject;
}
@name(".parse_ethernet") state parse_ethernet {
packet.extract<ethernet_t>(hdr.ethernet);
transition select(hdr.ethernet.ethertype) {
Expand All @@ -34,12 +38,43 @@ parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout
}
}
@name(".parse_vlan_tag") state parse_vlan_tag {
packet.extract<vlan_tag_t>(hdr.vlan_tag.next);
transition select(hdr.vlan_tag.last.ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag;
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w0]);
transition select(hdr.vlan_tag[32w0].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag1;
default: accept;
}
}
state parse_vlan_tag1 {
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w1]);
transition select(hdr.vlan_tag[32w1].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag2;
default: accept;
}
}
state parse_vlan_tag2 {
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w2]);
transition select(hdr.vlan_tag[32w2].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag3;
default: accept;
}
}
state parse_vlan_tag3 {
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w3]);
transition select(hdr.vlan_tag[32w3].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag4;
default: accept;
}
}
state parse_vlan_tag4 {
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w4]);
transition select(hdr.vlan_tag[32w4].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag5;
default: accept;
}
}
state parse_vlan_tag5 {
transition stateOutOfBound;
}
@name(".start") state start {
transition parse_ethernet;
}
Expand Down
21 changes: 18 additions & 3 deletions testdata/p4_14_samples_outputs/07-SimpleVlanStackIP-midend.p4
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ struct headers {
}

parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
state stateOutOfBound {
verify(false, error.StackOutOfBounds);
transition reject;
}
@name(".parse_ethernet") state parse_ethernet {
packet.extract<ethernet_t>(hdr.ethernet);
transition select(hdr.ethernet.ethertype) {
Expand All @@ -56,13 +60,24 @@ parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout
transition accept;
}
@name(".parse_vlan_tag") state parse_vlan_tag {
packet.extract<vlan_tag_t>(hdr.vlan_tag.next);
transition select(hdr.vlan_tag.last.ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag;
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w0]);
transition select(hdr.vlan_tag[32w0].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag1;
16w0x800: parse_ipv4;
default: accept;
}
}
state parse_vlan_tag1 {
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w1]);
transition select(hdr.vlan_tag[32w1].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag2;
16w0x800: parse_ipv4;
default: accept;
}
}
state parse_vlan_tag2 {
transition stateOutOfBound;
}
@name(".start") state start {
transition parse_ethernet;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ struct headers {
}

parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
state stateOutOfBound {
verify(false, error.StackOutOfBounds);
transition reject;
}
@name(".parse_ethernet") state parse_ethernet {
packet.extract<ethernet_t>(hdr.ethernet);
transition select(hdr.ethernet.ethertype) {
Expand All @@ -58,13 +62,24 @@ parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout
transition accept;
}
@name(".parse_vlan_tag") state parse_vlan_tag {
packet.extract<vlan_tag_t>(hdr.vlan_tag.next);
transition select(hdr.vlan_tag.last.ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag;
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w0]);
transition select(hdr.vlan_tag[32w0].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag1;
16w0x800: parse_ipv4;
default: accept;
}
}
state parse_vlan_tag1 {
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w1]);
transition select(hdr.vlan_tag[32w1].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag2;
16w0x800: parse_ipv4;
default: accept;
}
}
state parse_vlan_tag2 {
transition stateOutOfBound;
}
@name(".start") state start {
transition parse_ethernet;
}
Expand Down
21 changes: 18 additions & 3 deletions testdata/p4_14_samples_outputs/09-IPv4OptionsUnparsed-midend.p4
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ struct headers {
parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
@name("ParserImpl.tmp_hdr") ipv4_t_1 tmp_hdr_0;
bit<160> tmp;
state stateOutOfBound {
verify(false, error.StackOutOfBounds);
transition reject;
}
@name(".parse_ethernet") state parse_ethernet {
packet.extract<ethernet_t>(hdr.ethernet);
transition select(hdr.ethernet.ethertype) {
Expand Down Expand Up @@ -94,13 +98,24 @@ parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout
transition accept;
}
@name(".parse_vlan_tag") state parse_vlan_tag {
packet.extract<vlan_tag_t>(hdr.vlan_tag.next);
transition select(hdr.vlan_tag.last.ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag;
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w0]);
transition select(hdr.vlan_tag[32w0].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag1;
16w0x800: parse_ipv4;
default: accept;
}
}
state parse_vlan_tag1 {
packet.extract<vlan_tag_t>(hdr.vlan_tag[32w1]);
transition select(hdr.vlan_tag[32w1].ethertype) {
16w0x8100 &&& 16w0xefff: parse_vlan_tag2;
16w0x800: parse_ipv4;
default: accept;
}
}
state parse_vlan_tag2 {
transition stateOutOfBound;
}
@name(".start") state start {
tmp_hdr_0.setInvalid();
transition parse_ethernet;
Expand Down
Loading