Skip to content

Commit

Permalink
Basic support for @p4runtime_translation and `@p4runtime_translatio…
Browse files Browse the repository at this point in the history
…n_mappings`.
  • Loading branch information
fruffy-g committed Feb 1, 2024
1 parent 0483c2b commit f901822
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 62 deletions.
10 changes: 8 additions & 2 deletions backends/bmv2/common/annotations.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ class ParseAnnotations : public P4::ParseAnnotations {
public:
ParseAnnotations()
: P4::ParseAnnotations("BMV2", false,
{PARSE_EMPTY("metadata"), PARSE_EXPRESSION_LIST("field_list"),
PARSE("alias", StringLiteral), PARSE("priority", Constant)}) {}
{
PARSE_EMPTY("metadata"),
PARSE_EXPRESSION_LIST("field_list"),
PARSE("alias", StringLiteral),
PARSE("priority", Constant),
PARSE_EXPRESSION_LIST("p4runtime_translation_mappings"),
PARSE_P4RUNTIME_TRANSLATION("p4runtime_translation"),
}) {}
};

} // namespace BMV2
Expand Down
48 changes: 25 additions & 23 deletions backends/p4tools/modules/testgen/targets/bmv2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,31 @@ if(ENABLE_TESTING)
endif()

# Source files for p4testgen.
set(TESTGEN_SOURCES
${TESTGEN_SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/common.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/protobuf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/protobuf_ir.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/metadata.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/ptf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/stf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/bmv2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cmd_stepper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/concolic.cpp
${CMAKE_CURRENT_SOURCE_DIR}/constants.cpp
${CMAKE_CURRENT_SOURCE_DIR}/contrib/bmv2_hash/calculations.cpp
${CMAKE_CURRENT_SOURCE_DIR}/expr_stepper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/map_direct_externs.cpp
${CMAKE_CURRENT_SOURCE_DIR}/p4_asserts_parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/p4_refers_to_parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/program_info.cpp
${CMAKE_CURRENT_SOURCE_DIR}/table_stepper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/target.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_spec.cpp
PARENT_SCOPE
set(
TESTGEN_SOURCES
${TESTGEN_SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/common.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/protobuf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/protobuf_ir.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/metadata.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/ptf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend/stf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/bmv2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cmd_stepper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/concolic.cpp
${CMAKE_CURRENT_SOURCE_DIR}/constants.cpp
${CMAKE_CURRENT_SOURCE_DIR}/contrib/bmv2_hash/calculations.cpp
${CMAKE_CURRENT_SOURCE_DIR}/expr_stepper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/map_direct_externs.cpp
${CMAKE_CURRENT_SOURCE_DIR}/p4_asserts_parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/p4_refers_to_parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/p4runtime_translation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/program_info.cpp
${CMAKE_CURRENT_SOURCE_DIR}/table_stepper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/target.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_backend.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_spec.cpp
PARENT_SCOPE
)

set(TESTGEN_GTEST_SOURCES
Expand Down
11 changes: 11 additions & 0 deletions backends/p4tools/modules/testgen/targets/bmv2/bmv2.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
#include "backends/p4tools/modules/testgen/targets/bmv2/bmv2.h"

#include <optional>
#include <string>
#include <utility>

#include "backends/bmv2/common/annotations.h"
#include "backends/p4tools/common/compiler/compiler_target.h"
#include "backends/p4tools/common/compiler/midend.h"
#include "frontends/common/options.h"
#include "frontends/common/resolveReferences/referenceMap.h"
#include "frontends/p4/typeChecking/typeChecker.h"
#include "frontends/p4/typeMap.h"
#include "lib/cstring.h"
#include "lib/error.h"
#include "midend/coverage.h"

#include "backends/p4tools/modules/testgen/core/compiler_target.h"
#include "backends/p4tools/modules/testgen/options.h"
#include "backends/p4tools/modules/testgen/targets/bmv2/map_direct_externs.h"
#include "backends/p4tools/modules/testgen/targets/bmv2/p4_asserts_parser.h"
#include "backends/p4tools/modules/testgen/targets/bmv2/p4_refers_to_parser.h"
#include "backends/p4tools/modules/testgen/targets/bmv2/p4runtime_translation.h"

namespace P4Tools::P4Testgen::Bmv2 {

Expand Down Expand Up @@ -106,9 +113,13 @@ CompilerResultOrError Bmv2V1ModelCompilerTarget::runCompilerImpl(

MidEnd Bmv2V1ModelCompilerTarget::mkMidEnd(const CompilerOptions &options) const {
MidEnd midEnd(options);
auto *refMap = midEnd.getRefMap();
auto *typeMap = midEnd.getTypeMap();
midEnd.addPasses({
// Parse BMv2-specific annotations.
new BMV2::ParseAnnotations(),
new P4::TypeChecking(refMap, typeMap, true),
new PropagateP4RuntimeTranslation(*typeMap),
});
midEnd.addDefaultPasses();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "backends/p4tools/modules/testgen/targets/bmv2/p4runtime_translation.h"

std::vector<const IR::Annotation *>
P4Tools::P4Testgen::Bmv2::PropagateP4RuntimeTranslation::lookupP4RuntimeAnnotations(
const P4::TypeMap &typeMap, const IR::Type *type) {
std::vector<const IR::Annotation *> p4RuntimeAnnotations;
const auto *typeName = type->to<IR::Type_Name>();
if (typeName != nullptr) {
type = typeMap.getType(typeName);
if (type == nullptr) {
::error("Type %1% not found in the type map.", typeName);
return p4RuntimeAnnotations;
}
type = type->getP4Type();
}
const auto *annotatedType = type->to<IR::IAnnotated>();
if (annotatedType == nullptr) {
return p4RuntimeAnnotations;
}
const auto *p4runtimeAnnotation = annotatedType->getAnnotation("p4runtime_translation");
if (p4runtimeAnnotation != nullptr) {
BUG_CHECK(!p4runtimeAnnotation->needsParsing,
"The @p4runtime_translation annotation should have been parsed already.");
p4RuntimeAnnotations.push_back(p4runtimeAnnotation);
}
const auto *p4runtimeTranslationMappings =
annotatedType->getAnnotation("p4runtime_translation_mappings");
if (p4runtimeTranslationMappings != nullptr) {
BUG_CHECK(
!p4runtimeTranslationMappings->needsParsing,
"The @p4runtime_translation_mappings annotation should have been parsed already.");
p4RuntimeAnnotations.push_back(p4runtimeTranslationMappings);
}
return p4RuntimeAnnotations;
}

const IR::Parameter *P4Tools::P4Testgen::Bmv2::PropagateP4RuntimeTranslation::preorder(
IR::Parameter *parameter) {
auto p4RuntimeAnnotations = lookupP4RuntimeAnnotations(_typeMap, parameter->type);
if (p4RuntimeAnnotations.empty()) {
return parameter;
}
auto *annotationsVector = parameter->annotations->clone();
for (const auto *p4runtimeAnnotation : p4RuntimeAnnotations) {
annotationsVector->annotations.push_back(p4runtimeAnnotation);
}
parameter->annotations = annotationsVector;
return parameter;
}

const IR::KeyElement *P4Tools::P4Testgen::Bmv2::PropagateP4RuntimeTranslation::preorder(
IR::KeyElement *keyElement) {
auto p4RuntimeAnnotations = lookupP4RuntimeAnnotations(_typeMap, keyElement->expression->type);
if (p4RuntimeAnnotations.empty()) {
return keyElement;
}
auto *annotationsVector = keyElement->annotations->clone();
for (const auto *p4runtimeAnnotation : p4RuntimeAnnotations) {
annotationsVector->annotations.push_back(p4runtimeAnnotation);
}
keyElement->annotations = annotationsVector;
return keyElement;
}

P4Tools::P4Testgen::Bmv2::PropagateP4RuntimeTranslation::PropagateP4RuntimeTranslation(
const P4::TypeMap &typeMap)
: _typeMap(typeMap) {
setName("PropagateP4RuntimeTranslation");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef BACKENDS_P4TOOLS_MODULES_TESTGEN_TARGETS_BMV2_P4RUNTIME_TRANSLATION_H_
#define BACKENDS_P4TOOLS_MODULES_TESTGEN_TARGETS_BMV2_P4RUNTIME_TRANSLATION_H_
#include <functional>

#include "frontends/p4/typeMap.h"
#include "ir/ir.h"
#include "ir/visitor.h"

namespace P4Tools::P4Testgen::Bmv2 {

/// Propagates P4Runtime annotations attached to type definitions to the nodes which use these type
/// definitions. For now, this is restricted to key elements and action parameters.
class PropagateP4RuntimeTranslation : public Transform {
/// We use the typemap to look up the original declaration for type reference.
/// These declarations may have an annotation.
std::reference_wrapper<const P4::TypeMap> _typeMap;

/// Look up annotations relevant to P4Runtime. They may influence the control plane interfaces.
static std::vector<const IR::Annotation *> lookupP4RuntimeAnnotations(
const P4::TypeMap &typeMap, const IR::Type *type);

const IR::Parameter *preorder(IR::Parameter *parameter) override;
const IR::KeyElement *preorder(IR::KeyElement *keyElement) override;

public:
explicit PropagateP4RuntimeTranslation(const P4::TypeMap &typeMap);
};

} // namespace P4Tools::P4Testgen::Bmv2

#endif /* BACKENDS_P4TOOLS_MODULES_TESTGEN_TARGETS_BMV2_P4RUNTIME_TRANSLATION_H_ */
Loading

0 comments on commit f901822

Please sign in to comment.