Skip to content

Commit

Permalink
Fix generation of P4Info for v1model registers
Browse files Browse the repository at this point in the history
Use declaration instance type instead of evaluated block instance
type. The evaluated block instance type gives us a
Type_SpecializedCanonical node which doesn't use Type_Name and therefore
violates pre-condition for typeSpecConverter.
  • Loading branch information
antoninbas committed May 1, 2018
1 parent 9724fe8 commit d50facb
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
13 changes: 7 additions & 6 deletions control-plane/p4RuntimeSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ struct Register {
const TypeMap* typeMap,
p4::P4TypeInfo* p4RtTypeInfo) {
CHECK_NULL(instance);
auto declaration = instance->node->to<IR::IDeclaration>();
auto declaration = instance->node->to<IR::Declaration_Instance>();

auto size = instance->getParameterValue("size")->to<IR::Constant>();
if (!size->is<IR::Constant>()) {
Expand All @@ -210,13 +210,14 @@ struct Register {
}

// retrieve type parameter for the register instance and convert it to p4::P4DataTypeSpec
BUG_CHECK(instance->instanceType->is<IR::Type_SpecializedCanonical>(),
"%1%: expected Type_SpecializedCanonical", instance->instanceType);
auto instanceType = instance->instanceType->to<IR::Type_SpecializedCanonical>();
BUG_CHECK(instanceType->arguments->size() == 1,
BUG_CHECK(declaration->type->is<IR::Type_Specialized>(),
"%1%: expected Type_Specialized", declaration->type);
auto type = declaration->type->to<IR::Type_Specialized>();
BUG_CHECK(type->arguments->size() == 1,
"%1%: expected one type argument", instance);
auto typeArg = instanceType->arguments->at(0);
auto typeArg = type->arguments->at(0);
auto typeSpec = TypeSpecConverter::convert(typeMap, refMap, typeArg, p4RtTypeInfo);
CHECK_NULL(typeSpec);

return Register{declaration->controlPlaneName(),
declaration->to<IR::IAnnotated>(),
Expand Down
4 changes: 4 additions & 0 deletions control-plane/typeSpecConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ bool TypeSpecConverter::preorder(const IR::Type_Tuple* type) {
for (auto cType : type->components) {
visit(cType);
auto cTypeSpec = map.at(cType);
CHECK_NULL(cTypeSpec);
auto member = tupleTypeSpec->add_members();
member->CopyFrom(*cTypeSpec);
}
Expand Down Expand Up @@ -146,6 +147,7 @@ bool TypeSpecConverter::preorder(const IR::Type_Struct* type) {
auto fType = f->type;
visit(fType);
auto fTypeSpec = map.at(fType);
CHECK_NULL(fTypeSpec);
auto member = structTypeSpec->add_members();
member->set_name(f->controlPlaneName());
member->mutable_type_spec()->CopyFrom(*fTypeSpec);
Expand All @@ -167,6 +169,7 @@ bool TypeSpecConverter::preorder(const IR::Type_Header* type) {
auto fType = f->type;
visit(fType);
auto fTypeSpec = map.at(fType);
CHECK_NULL(fTypeSpec);
BUG_CHECK(fTypeSpec->has_bitstring(),
"Only bistring fields expected in header type declaration %1%", type);
auto member = headerTypeSpec->add_members();
Expand All @@ -190,6 +193,7 @@ bool TypeSpecConverter::preorder(const IR::Type_HeaderUnion* type) {
auto fType = f->type;
visit(fType);
auto fTypeSpec = map.at(fType);
CHECK_NULL(fTypeSpec);
BUG_CHECK(fTypeSpec->has_header(),
"Only header fields expected in header union declaration %1%", type);
auto member = headerUnionTypeSpec->add_members();
Expand Down
38 changes: 26 additions & 12 deletions test/gtest/p4runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,25 +859,39 @@ TEST_F(P4Runtime, Register) {
control ingress(inout Headers h, inout Metadata m,
inout standard_metadata_t sm) {
@my_anno("This is an annotation!")
register<tuple<bit<16>, bit<8> > >(128) my_register;
apply { my_register.write(32w10, {16w1, 8w2}); } }
register<tuple<bit<16>, bit<8> > >(128) my_register_1;
register<Header>(128) my_register_2;
apply {
my_register_1.write(32w10, {16w1, 8w2});
my_register_2.write(32w10, h.h); } }
V1Switch(parse(), verifyChecksum(), ingress(), egress(),
computeChecksum(), deparse()) main;
)"));

ASSERT_TRUE(test);
EXPECT_EQ(0u, ::diagnosticCount());

auto register_ = findRegister(*test, "ingress.my_register");
ASSERT_TRUE(register_ != nullptr);
EXPECT_EQ(unsigned(P4Ids::REGISTER), register_->preamble().id() >> 24);
const auto& annotations = register_->preamble().annotations();
ASSERT_EQ(1, annotations.size());
EXPECT_EQ("@my_anno(\"This is an annotation!\")", annotations.Get(0));
EXPECT_EQ(128, register_->size());
const auto& typeSpec = register_->type_spec();
ASSERT_TRUE(typeSpec.has_tuple());
EXPECT_EQ(2, typeSpec.tuple().members_size());
{ // type parameter is tuple
auto register_ = findRegister(*test, "ingress.my_register_1");
ASSERT_TRUE(register_ != nullptr);
EXPECT_EQ(unsigned(P4Ids::REGISTER), register_->preamble().id() >> 24);
const auto& annotations = register_->preamble().annotations();
ASSERT_EQ(1, annotations.size());
EXPECT_EQ("@my_anno(\"This is an annotation!\")", annotations.Get(0));
EXPECT_EQ(128, register_->size());
const auto& typeSpec = register_->type_spec();
ASSERT_TRUE(typeSpec.has_tuple());
EXPECT_EQ(2, typeSpec.tuple().members_size());
}
{ // type parameter is header
auto register_ = findRegister(*test, "ingress.my_register_2");
ASSERT_TRUE(register_ != nullptr);
EXPECT_EQ(unsigned(P4Ids::REGISTER), register_->preamble().id() >> 24);
EXPECT_EQ(128, register_->size());
const auto& typeSpec = register_->type_spec();
ASSERT_TRUE(typeSpec.has_header());
EXPECT_EQ("Header", typeSpec.header().name());
}
}

class P4RuntimeDataTypeSpec : public P4Runtime {
Expand Down

0 comments on commit d50facb

Please sign in to comment.