P4C
The P4 Compiler
Loading...
Searching...
No Matches
simpleSwitch.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef BACKENDS_BMV2_SIMPLE_SWITCH_SIMPLESWITCH_H_
9#define BACKENDS_BMV2_SIMPLE_SWITCH_SIMPLESWITCH_H_
10
11#include <algorithm>
12#include <cstring>
13
14#include "backends/bmv2/common/action.h"
15#include "backends/bmv2/common/backend.h"
16#include "backends/bmv2/common/control.h"
17#include "backends/bmv2/common/deparser.h"
18#include "backends/bmv2/common/extern.h"
19#include "backends/bmv2/common/globals.h"
20#include "backends/bmv2/common/header.h"
21#include "backends/bmv2/common/options.h"
22#include "backends/bmv2/common/parser.h"
23#include "backends/bmv2/common/sharedActionSelectorCheck.h"
24#include "backends/common/programStructure.h"
25#include "frontends/common/constantFolding.h"
26#include "frontends/p4-14/fromv1.0/v1model.h"
27#include "frontends/p4/evaluator/evaluator.h"
28#include "frontends/p4/simplify.h"
29#include "frontends/p4/unusedDeclarations.h"
30#include "midend/convertEnums.h"
31
32namespace P4::BMV2 {
33
34class V1ProgramStructure : public P4::ProgramStructure {
35 public:
36 std::set<cstring> pipeline_controls;
37 std::set<cstring> non_pipeline_controls;
38
39 const IR::P4Parser *parser = nullptr;
40 const IR::P4Control *ingress = nullptr;
41 const IR::P4Control *egress = nullptr;
42 const IR::P4Control *compute_checksum = nullptr;
43 const IR::P4Control *verify_checksum = nullptr;
44 const IR::P4Control *deparser = nullptr;
45
46 V1ProgramStructure() {}
47 BlockConverted blockKind(const IR::Node *node) const {
48 if (node == parser)
49 return BlockConverted::Parser;
50 else if (node == ingress)
51 return BlockConverted::Ingress;
52 else if (node == egress)
53 return BlockConverted::Egress;
54 else if (node == compute_checksum)
55 return BlockConverted::ChecksumCompute;
56 else if (node == verify_checksum)
57 return BlockConverted::ChecksumVerify;
58 else if (node == deparser)
59 return BlockConverted::Deparser;
60 return BlockConverted::None;
61 }
62};
63
64class SimpleSwitchExpressionConverter : public ExpressionConverter {
65 V1ProgramStructure *structure;
66
67 public:
68 SimpleSwitchExpressionConverter(P4::ReferenceMap *refMap, P4::TypeMap *typeMap,
69 V1ProgramStructure *structure, cstring scalarsName)
70 : ExpressionConverter(refMap, typeMap, structure, scalarsName), structure(structure) {}
71
72 void modelError(const char *format, const IR::Node *node) {
73 ::P4::errorWithSuffix(ErrorType::ERR_MODEL, format,
74 "\nAre you using an up-to-date v1model.p4?", node);
75 }
76
77 bool isStandardMetadataParameter(const IR::Parameter *param) {
78 auto params = structure->parser->getApplyParameters();
79 if (params->size() != 4) {
80 modelError("%1%: Expected 4 parameter for parser", structure->parser);
81 return false;
82 }
83 if (params->parameters.at(3) == param) return true;
84
85 params = structure->ingress->getApplyParameters();
86 if (params->size() != 3) {
87 modelError("%1%: Expected 3 parameter for ingress", structure->ingress);
88 return false;
89 }
90 if (params->parameters.at(2) == param) return true;
91
92 params = structure->egress->getApplyParameters();
93 if (params->size() != 3) {
94 modelError("%1%: Expected 3 parameter for egress", structure->egress);
95 return false;
96 }
97 if (params->parameters.at(2) == param) return true;
98
99 return false;
100 }
101
102 Util::IJson *convertParam(const IR::Parameter *param, cstring fieldName) override {
103 if (isStandardMetadataParameter(param)) {
104 auto result = new Util::JsonObject();
105 if (fieldName != "") {
106 result->emplace("type", "field");
107 auto e = BMV2::mkArrayField(result, "value"_cs);
108 e->append("standard_metadata");
109 e->append(fieldName);
110 } else {
111 result->emplace("type", "header");
112 result->emplace("value", "standard_metadata");
113 }
114 return result;
115 }
116 return nullptr;
117 }
118};
119
120class ParseV1Architecture : public Inspector {
121 V1ProgramStructure *structure;
122 P4V1::V1Model &v1model;
123
124 public:
125 explicit ParseV1Architecture(V1ProgramStructure *structure)
126 : structure(structure), v1model(P4V1::V1Model::instance) {}
127 void modelError(const char *format, const IR::Node *node);
128 bool preorder(const IR::PackageBlock *block) override;
129};
130
131class SimpleSwitchBackend : public Backend {
132 BMV2Options &options;
133 P4V1::V1Model &v1model;
134 V1ProgramStructure *structure = nullptr;
135 ExpressionConverter *conv = nullptr;
136
137 protected:
138 void createRecirculateFieldsList(ConversionContext *ctxt, const IR::ToplevelBlock *tlb,
139 cstring scalarName);
140 cstring createCalculation(cstring algo, const IR::Expression *fields,
141 Util::JsonArray *calculations, bool usePayload, const IR::Node *node);
142
143 public:
144 void modelError(const char *format, const IR::Node *place) const;
145 void convertChecksum(const IR::BlockStatement *body, Util::JsonArray *checksums,
146 Util::JsonArray *calculations, bool verify);
147 void createActions(ConversionContext *ctxt, V1ProgramStructure *structure);
148
149 void convert(const IR::ToplevelBlock *tlb) override;
150 SimpleSwitchBackend(BMV2Options &options, P4::ReferenceMap *refMap, P4::TypeMap *typeMap,
151 P4::ConvertEnums::EnumMapping *enumMap)
152 : Backend(options, refMap, typeMap, enumMap),
153 options(options),
154 v1model(P4V1::V1Model::instance) {}
155};
156
157EXTERN_CONVERTER_W_FUNCTION(clone)
158EXTERN_CONVERTER_W_FUNCTION(clone_preserving_field_list)
159EXTERN_CONVERTER_W_FUNCTION_AND_MODEL(hash, P4V1::V1Model, v1model)
160EXTERN_CONVERTER_W_FUNCTION(digest)
161EXTERN_CONVERTER_W_FUNCTION(resubmit_preserving_field_list)
162EXTERN_CONVERTER_W_FUNCTION(recirculate_preserving_field_list)
163EXTERN_CONVERTER_W_FUNCTION(mark_to_drop)
164EXTERN_CONVERTER_W_FUNCTION(log_msg)
165EXTERN_CONVERTER_W_FUNCTION_AND_MODEL(random, P4V1::V1Model, v1model)
166EXTERN_CONVERTER_W_FUNCTION_AND_MODEL(truncate, P4V1::V1Model, v1model)
167EXTERN_CONVERTER_W_OBJECT_AND_INSTANCE_AND_MODEL(register, P4V1::V1Model, v1model)
168EXTERN_CONVERTER_W_OBJECT_AND_INSTANCE_AND_MODEL(counter, P4V1::V1Model, v1model)
169EXTERN_CONVERTER_W_OBJECT_AND_INSTANCE_AND_MODEL(meter, P4V1::V1Model, v1model)
170EXTERN_CONVERTER_W_OBJECT_AND_INSTANCE(direct_counter)
171EXTERN_CONVERTER_W_OBJECT_AND_INSTANCE_AND_MODEL(direct_meter, P4V1::V1Model, v1model)
172EXTERN_CONVERTER_W_INSTANCE_AND_MODEL(action_profile, P4V1::V1Model, v1model)
173EXTERN_CONVERTER_W_INSTANCE_AND_MODEL(action_selector, P4V1::V1Model, v1model)
174
175} // namespace P4::BMV2
176
177#endif /* BACKENDS_BMV2_SIMPLE_SWITCH_SIMPLESWITCH_H_ */
Definition backends/bmv2/common/options.h:18
Definition expression.h:42
void convert(const IR::ToplevelBlock *tlb) override
Definition simpleSwitch.cpp:1070
Util::IJson * convertParam(const IR::Parameter *param, cstring fieldName) override
Definition simpleSwitch.h:102
Definition simpleSwitch.h:34
Definition node.h:53
Definition frontends/p4-14/fromv1.0/v1model.h:253
Definition backends/common/programStructure.h:23
Class used to encode maps from paths to declarations.
Definition referenceMap.h:67
Definition typeMap.h:32
Definition lib/json.h:41
Definition lib/json.h:128
Definition lib/json.h:177
Definition cstring.h:85
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition action.cpp:9
void errorWithSuffix(const int kind, const char *format, const char *suffix, const T *node, Args &&...args)
This is similar to the above method, but also has a suffix.
Definition lib/error.h:76
Definition bmv2/common/helpers.h:288