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