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

Alternate strength reduction and constant folding to eliminate constants #3706

Merged
merged 3 commits into from
Nov 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backends/bmv2/common/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const IR::Expression* LowerExpressions::shift(const IR::Operation_Binary* expres
auto rhs = expression->right;
auto rhstype = typeMap->getType(rhs, true);
if (rhstype->is<IR::Type_InfInt>()) {
auto cst = rhs->to<IR::Constant>();
auto cst = rhs->checkedTo<IR::Constant>();
big_int maxShift = Util::shift_left(1, LowerExpressions::maxShiftWidth);
if (cst->value > maxShift)
::error(ErrorType::ERR_OVERLIMIT, "%1%: shift amount limited to %2% on this target",
Expand Down
4 changes: 2 additions & 2 deletions backends/bmv2/psa_switch/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ PsaSwitchMidEnd::PsaSwitchMidEnd(CompilerOptions& options, std::ostream* outStre
new P4::MoveDeclarations(), // more may have been introduced
new P4::ConstantFolding(&refMap, &typeMap),
new P4::LocalCopyPropagation(&refMap, &typeMap, nullptr, policy),
new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap),
new PassRepeated({new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap)}),
new P4::MoveDeclarations(),
new P4::ValidateTableProperties({"psa_implementation", "psa_direct_counter",
"psa_direct_meter", "psa_idle_timeout", "size"}),
Expand Down
3 changes: 2 additions & 1 deletion backends/bmv2/psa_switch/psaSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ void PsaSwitchBackend::convert(const IR::ToplevelBlock* tlb) {
new P4::TypeChecking(refMap, typeMap),
new P4::SimplifyControlFlow(refMap, typeMap),
new LowerExpressions(typeMap),
new P4::ConstantFolding(refMap, typeMap, false),
new PassRepeated(
{new P4::ConstantFolding(refMap, typeMap), new P4::StrengthReduction(refMap, typeMap)}),
new P4::TypeChecking(refMap, typeMap),
new P4::RemoveComplexExpressions(refMap, typeMap,
new ProcessControls(&structure.pipeline_controls)),
Expand Down
4 changes: 2 additions & 2 deletions backends/bmv2/simple_switch/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ SimpleSwitchMidEnd::SimpleSwitchMidEnd(CompilerOptions& options, std::ostream* o
new P4::MoveDeclarations(), // more may have been introduced
new P4::ConstantFolding(&refMap, &typeMap),
new P4::LocalCopyPropagation(&refMap, &typeMap),
new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&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())),
Expand Down
3 changes: 2 additions & 1 deletion backends/dpdk/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ DpdkMidEnd::DpdkMidEnd(CompilerOptions& options, std::ostream* outStream) {
new P4::MoveDeclarations(), // more may have been introduced
new P4::ConstantFolding(&refMap, &typeMap),
new P4::LocalCopyPropagation(&refMap, &typeMap, nullptr, policy),
new P4::ConstantFolding(&refMap, &typeMap),
new PassRepeated({new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap)}),
new P4::MoveDeclarations(),
validateTableProperties(options.arch),
new P4::SimplifyControlFlow(&refMap, &typeMap),
Expand Down
3 changes: 2 additions & 1 deletion backends/ebpf/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ const IR::ToplevelBlock* MidEnd::run(EbpfOptions& options, const IR::P4Program*
new P4::ExpandEmit(&refMap, &typeMap),
new P4::HandleNoMatch(&refMap),
new P4::SimplifyParsers(&refMap),
new P4::StrengthReduction(&refMap, &typeMap),
new PassRepeated({new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap)}),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
Expand Down
4 changes: 3 additions & 1 deletion backends/ubpf/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ const IR::ToplevelBlock* MidEnd::run(EbpfOptions& options, const IR::P4Program*
new P4::ConstantFolding(&refMap, &typeMap),
// accept non-constant keysets
new P4::SimplifySelectCases(&refMap, &typeMap, false), new P4::HandleNoMatch(&refMap),
new P4::SimplifyParsers(&refMap), new P4::StrengthReduction(&refMap, &typeMap),
new P4::SimplifyParsers(&refMap),
new PassRepeated({new P4::ConstantFolding(&refMap, &typeMap),
new P4::StrengthReduction(&refMap, &typeMap)}),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap),
new P4::LocalCopyPropagation(&refMap, &typeMap),
Expand Down
105 changes: 105 additions & 0 deletions testdata/p4_16_samples/issue3702-bmv2.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//#include "third_party/p4lang_p4c/p4include/core.p4"
//#include "third_party/p4lang_p4c/p4include/v1model.p4"
#include "core.p4"
#include "v1model.p4"

typedef bit<48> ethernet_addr_t;
typedef bit<32> ipv4_addr_t;

// Enums
enum bit <16> EtherType {
ETYPE_IPV4 = 0x0800
};

// Header definitions
header ethernet_t {
ethernet_addr_t da; // destination address
ethernet_addr_t sa; // source address
bit<16> type; // First (mandatory) Ethertype field
}

header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<6> dscp; // The 6 most significant bits of the diff_serv field.
bit<2> ecn; // The 2 least significant bits of the diff_serv field.
bit<16> total_len;
bit<16> identification;
bit<1> reserved;
bit<1> do_not_fragment;
bit<1> more_fragments;
bit<13> frag_offset;
bit<8> ttl;
bit<8> protocol;
bit<16> header_checksum;
ipv4_addr_t src_addr;
ipv4_addr_t dst_addr;
}

header ipv4_options_t {
varbit<480> options;
}

// Set of extracted headers.
struct headers_t {
ethernet_t mac; // mac header
ipv4_options_t ip; // v4/v6 union
}

// Required metadata structure.
struct local_metadata_t {

}

// Signature is governed by the architecture (PNA)
parser v1model_parser(packet_in pkt, out headers_t hdrs,
inout local_metadata_t local_meta,
inout standard_metadata_t standard_meta) {
state start {
pkt.extract(hdrs.mac);
transition select(hdrs.mac.type) {
EtherType.ETYPE_IPV4 : parse_ipv4;
default: accept;
}
}

state parse_ipv4 {
ipv4_t ipv4 = pkt.lookahead<ipv4_t>();
bit<32> byte_len = ((bit<32>)(ipv4.ihl & 0xF)) << 2;
pkt.extract(hdrs.ip, byte_len << 3);
transition accept;
}

}

control compute_ip_checksum(inout headers_t headers,
inout local_metadata_t local_metadata) {
apply {
}
}
control verify_ip_checksum(inout headers_t headers,
inout local_metadata_t local_metadata) {
apply {
}
}

control egress(inout headers_t headers,
inout local_metadata_t local_metadata,
inout standard_metadata_t standard_metadata) {
apply {
}
}
control ingress(inout headers_t headers,
inout local_metadata_t local_metadata,
inout standard_metadata_t standard_metadata) {
apply {
}
}

control deparser(packet_out packet, in headers_t headers) {
apply {
}
}

// Main invocation
V1Switch(v1model_parser(), verify_ip_checksum(), ingress(), egress(), compute_ip_checksum(), deparser()) main;
88 changes: 88 additions & 0 deletions testdata/p4_16_samples_outputs/issue3702-bmv2-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <core.p4>
#define V1MODEL_VERSION 20180101
#include <v1model.p4>

typedef bit<48> ethernet_addr_t;
typedef bit<32> ipv4_addr_t;
enum bit<16> EtherType {
ETYPE_IPV4 = 16w0x800
}

header ethernet_t {
ethernet_addr_t da;
ethernet_addr_t sa;
bit<16> type;
}

header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<6> dscp;
bit<2> ecn;
bit<16> total_len;
bit<16> identification;
bit<1> reserved;
bit<1> do_not_fragment;
bit<1> more_fragments;
bit<13> frag_offset;
bit<8> ttl;
bit<8> protocol;
bit<16> header_checksum;
ipv4_addr_t src_addr;
ipv4_addr_t dst_addr;
}

header ipv4_options_t {
varbit<480> options;
}

struct headers_t {
ethernet_t mac;
ipv4_options_t ip;
}

struct local_metadata_t {
}

parser v1model_parser(packet_in pkt, out headers_t hdrs, inout local_metadata_t local_meta, inout standard_metadata_t standard_meta) {
state start {
pkt.extract<ethernet_t>(hdrs.mac);
transition select(hdrs.mac.type) {
EtherType.ETYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
ipv4_t ipv4 = pkt.lookahead<ipv4_t>();
bit<32> byte_len = (bit<32>)ipv4.ihl << 2;
pkt.extract<ipv4_options_t>(hdrs.ip, byte_len << 3);
transition accept;
}
}

control compute_ip_checksum(inout headers_t headers, inout local_metadata_t local_metadata) {
apply {
}
}

control verify_ip_checksum(inout headers_t headers, inout local_metadata_t local_metadata) {
apply {
}
}

control egress(inout headers_t headers, inout local_metadata_t local_metadata, inout standard_metadata_t standard_metadata) {
apply {
}
}

control ingress(inout headers_t headers, inout local_metadata_t local_metadata, inout standard_metadata_t standard_metadata) {
apply {
}
}

control deparser(packet_out packet, in headers_t headers) {
apply {
}
}

V1Switch<headers_t, local_metadata_t>(v1model_parser(), verify_ip_checksum(), ingress(), egress(), compute_ip_checksum(), deparser()) main;
90 changes: 90 additions & 0 deletions testdata/p4_16_samples_outputs/issue3702-bmv2-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <core.p4>
#define V1MODEL_VERSION 20180101
#include <v1model.p4>

typedef bit<48> ethernet_addr_t;
typedef bit<32> ipv4_addr_t;
enum bit<16> EtherType {
ETYPE_IPV4 = 16w0x800
}

header ethernet_t {
ethernet_addr_t da;
ethernet_addr_t sa;
bit<16> type;
}

header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<6> dscp;
bit<2> ecn;
bit<16> total_len;
bit<16> identification;
bit<1> reserved;
bit<1> do_not_fragment;
bit<1> more_fragments;
bit<13> frag_offset;
bit<8> ttl;
bit<8> protocol;
bit<16> header_checksum;
ipv4_addr_t src_addr;
ipv4_addr_t dst_addr;
}

header ipv4_options_t {
varbit<480> options;
}

struct headers_t {
ethernet_t mac;
ipv4_options_t ip;
}

struct local_metadata_t {
}

parser v1model_parser(packet_in pkt, out headers_t hdrs, inout local_metadata_t local_meta, inout standard_metadata_t standard_meta) {
@name("v1model_parser.ipv4") ipv4_t ipv4_0;
@name("v1model_parser.byte_len") bit<32> byte_len_0;
state start {
pkt.extract<ethernet_t>(hdrs.mac);
transition select(hdrs.mac.type) {
EtherType.ETYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
ipv4_0 = pkt.lookahead<ipv4_t>();
byte_len_0 = (bit<32>)ipv4_0.ihl << 2;
pkt.extract<ipv4_options_t>(hdrs.ip, byte_len_0 << 3);
transition accept;
}
}

control compute_ip_checksum(inout headers_t headers, inout local_metadata_t local_metadata) {
apply {
}
}

control verify_ip_checksum(inout headers_t headers, inout local_metadata_t local_metadata) {
apply {
}
}

control egress(inout headers_t headers, inout local_metadata_t local_metadata, inout standard_metadata_t standard_metadata) {
apply {
}
}

control ingress(inout headers_t headers, inout local_metadata_t local_metadata, inout standard_metadata_t standard_metadata) {
apply {
}
}

control deparser(packet_out packet, in headers_t headers) {
apply {
}
}

V1Switch<headers_t, local_metadata_t>(v1model_parser(), verify_ip_checksum(), ingress(), egress(), compute_ip_checksum(), deparser()) main;
Loading