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

start to add metadata handling #8

Merged
merged 1 commit into from
May 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions backends/bmv2/analyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ class ProgramParts {
std::map<const IR::P4Action*, unsigned> ids;
// All local variables
std::vector<const IR::Declaration_Variable*> variables;
// All the parsers
std::vector<const IR::P4Parser *> parsers;

ProgramParts() {}
void analyze(const IR::ToplevelBlock* toplevel);
Expand All @@ -197,6 +199,7 @@ class DiscoverStructure : public Inspector {
void postorder(const IR::ParameterList* paramList) override;
void postorder(const IR::P4Action* action) override;
void postorder(const IR::Declaration_Variable* decl) override;
void postorder(const IR::P4Parser *p) override { structure->parsers.push_back(p); }
};

} // namespace BMV2
Expand Down
23 changes: 22 additions & 1 deletion backends/bmv2/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,26 @@ void Backend::createActions(Util::JsonArray* actions) {
}
}

// stdMeta and userMeta seem to change when moving from one declared control to another
// and drive the expression converter to use the right parameter
// still have not figured out where the metadata is actually generated!!
void Backend::createMetadata() {
for ( auto parser : structure.parsers ) {
std::cerr << "Found " << parser << std::endl;
userMetadataParameter = parser->type->applyParams->getParameter(
v1model.parser.metadataParam.index);
stdMetadataParameter = parser->type->applyParams->getParameter(
v1model.parser.standardMetadataParam.index);
auto mdType = typeMap.getType(userMetadataParameter, true);
auto mt = mdType->to<IR::Type_Struct>();
if (mt == nullptr) {
::error("Expected metadata %1% to be a struct", mdType);
return;
}
// break; // we need only one??
}
}

void Backend::addErrors(Util::JsonArray* errors) {
for (const auto &p : errorCodesMap) {
auto name = p.first->getName().name.c_str();
Expand Down Expand Up @@ -408,12 +428,13 @@ void Backend::convert(const IR::ToplevelBlock* tb) {
externs = mkArrayField(&toplevel, "extern_instances");

// This visitor is used in multiple passes to convert expression to json
conv = new ExpressionConverter(&refMap, &typeMap, &structure, &errorCodesMap);
conv = new ExpressionConverter(this);

PassManager codegen_passes = {
new VisitFunctor([this](){ addMetaInformation(); }),
new VisitFunctor([this](){ addEnums(enums); }),
new VisitFunctor([this](){ createScalars(); }),
new VisitFunctor([this](){ createMetadata(); }),
new ConvertHeaders(this),
new VisitFunctor([this](){ addLocals(); }),
new VisitFunctor([this](){ padScalars(); }),
Expand Down
4 changes: 4 additions & 0 deletions backends/bmv2/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class Backend : public PassManager {
const unsigned boolWidth = 1;
unsigned scalars_width = 0;
cstring scalarsName;
const IR::Parameter* userMetadataParameter;
const IR::Parameter* stdMetadataParameter;

// We place scalar user metadata fields (i.e., bit<>, bool)
// in the "scalars" metadata object, so we may need to rename
Expand All @@ -96,6 +98,7 @@ class Backend : public PassManager {
void convertActionBody(const IR::Vector<IR::StatOrDecl>* body, Util::JsonArray* result);
void createActions(Util::JsonArray* actions);
void createScalars();
void createMetadata();
void genExternMethod(Util::JsonArray* result, P4::ExternMethod *em);
void padScalars();

Expand All @@ -109,6 +112,7 @@ class Backend : public PassManager {
void serialize(std::ostream& out) const
{ toplevel.serialize(out); }
P4::P4CoreLibrary & getCoreLibrary() const { return corelib; }
ErrorCodesMap & getErrorCodesMap() { return errorCodesMap; }
ExpressionConverter * getExpressionConverter() { return conv; };
DirectCounterMap & getDirectCounterMap() { return directCounterMap; }
DirectMeterMap & getMeterMap() { return meterMap; }
Expand Down
3 changes: 2 additions & 1 deletion backends/bmv2/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void Control::convertTableEntries(const IR::P4Table *table,
::error("%1% invalid range key expression", k);
}
} else {
::error("unkown key type %1% for key %2%", matchType, k);
::error("unkown key type '%1%' for key %2%", matchType, k);
}
matchKeys->append(key);
keyIndex++;
Expand Down Expand Up @@ -163,6 +163,7 @@ cstring Control::getKeyMatchType(const IR::KeyElement *ke) {
cstring match_type = "invalid";
if (mt->name.name == backend->getCoreLibrary().exactMatch.name ||
mt->name.name == backend->getCoreLibrary().ternaryMatch.name) {
match_type = mt->name.name;
if (expr->is<IR::MethodCallExpression>()) {
auto mi = P4::MethodInstance::resolve(expr->to<IR::MethodCallExpression>(),
&backend->getRefMap(), &backend->getTypeMap());
Expand Down
33 changes: 17 additions & 16 deletions backends/bmv2/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,16 @@ void ExpressionConverter::postorder(const IR::BoolLiteral* expression) {
}

void ExpressionConverter::postorder(const IR::MethodCallExpression* expression) {
auto instance = P4::MethodInstance::resolve(expression, refMap, typeMap);
auto instance = P4::MethodInstance::resolve(expression,
&backend->getRefMap(), &backend->getTypeMap());
if (instance->is<P4::ExternMethod>()) {
auto em = instance->to<P4::ExternMethod>();
if (em->originalExternType->name == corelib.packetIn.name &&
em->method->name == corelib.packetIn.lookahead.name) {
BUG_CHECK(expression->typeArguments->size() == 1,
"Expected 1 type parameter for %1%", em->method);
auto targ = expression->typeArguments->at(0);
auto typearg = typeMap->getTypeType(targ, true);
auto typearg = backend->getTypeMap().getTypeType(targ, true);
int width = typearg->width_bits();
BUG_CHECK(width > 0, "%1%: unknown width", targ);
auto j = new Util::JsonObject();
Expand Down Expand Up @@ -175,11 +176,11 @@ const IR::Parameter* ExpressionConverter::enclosingParamReference(const IR::Expr
return nullptr;

auto pe = expression->to<IR::PathExpression>();
auto decl = refMap->getDeclaration(pe->path, true);
auto decl = backend->getRefMap().getDeclaration(pe->path, true);
auto param = decl->to<IR::Parameter>();
if (param == nullptr)
return param;
if (structure->nonActionParameters.count(param) > 0)
if (backend->getStructure().nonActionParameters.count(param) > 0)
return param;
return nullptr;
}
Expand All @@ -188,7 +189,7 @@ void ExpressionConverter::postorder(const IR::Member* expression) {
// TODO: deal with references that return bool
auto result = new Util::JsonObject();

auto parentType = typeMap->getType(expression->expr, true);
auto parentType = backend->getTypeMap().getType(expression->expr, true);
cstring fieldName = expression->member.name;
if (parentType->is<IR::Type_StructLike>()) {
auto st = parentType->to<IR::Type_StructLike>();
Expand All @@ -199,11 +200,11 @@ void ExpressionConverter::postorder(const IR::Member* expression) {
}

{
auto type = typeMap->getType(expression, true);
auto type = backend->getTypeMap().getType(expression, true);
if (type->is<IR::Type_Error>()) {
result->emplace("type", "hexstr");
auto decl = type->to<IR::Type_Error>()->getDeclByName(expression->member.name);
auto errorValue = errorCodesMap->at(decl);
auto errorValue = backend->getErrorCodesMap().at(decl);
result->emplace("value", Util::toString(errorValue));
map.emplace(expression, result);
return;
Expand All @@ -212,7 +213,7 @@ void ExpressionConverter::postorder(const IR::Member* expression) {

auto param = enclosingParamReference(expression->expr);
if (param != nullptr) {
auto type = typeMap->getType(expression, true);
auto type = backend->getTypeMap().getType(expression, true);
LOG1("Parameter: " << param);
//FIXME:
#if 0
Expand Down Expand Up @@ -256,7 +257,7 @@ void ExpressionConverter::postorder(const IR::Member* expression) {
if (expression->expr->is<IR::Member>()) {
// array.next.field => type: "stack_field", value: [ array, field ]
auto mem = expression->expr->to<IR::Member>();
auto memtype = typeMap->getType(mem->expr, true);
auto memtype = backend->getTypeMap().getType(mem->expr, true);
if (memtype->is<IR::Type_Stack>() && mem->member == IR::Type_Stack::last) {
auto l = get(mem->expr);
CHECK_NULL(l);
Expand Down Expand Up @@ -419,7 +420,7 @@ void ExpressionConverter::postorder(const IR::Operation_Unary* expression) {

void ExpressionConverter::postorder(const IR::PathExpression* expression) {
// This is useful for action bodies mostly
auto decl = refMap->getDeclaration(expression->path, true);
auto decl = backend->getRefMap().getDeclaration(expression->path, true);
if (auto param = decl->to<IR::Parameter>()) {
LOG1("Expression: " << param << " " << expression);
#if 0
Expand All @@ -432,20 +433,20 @@ void ExpressionConverter::postorder(const IR::PathExpression* expression) {
return;
}
#endif
if (structure->nonActionParameters.find(param) !=
structure->nonActionParameters.end()) {
if (backend->getStructure().nonActionParameters.find(param) !=
backend->getStructure().nonActionParameters.end()) {
map.emplace(expression, new Util::JsonValue(param->name.name));
return;
}
auto result = new Util::JsonObject();
result->emplace("type", "runtime_data");
unsigned paramIndex = ::get(structure->index, param);
unsigned paramIndex = ::get(&backend->getStructure().index, param);
result->emplace("value", paramIndex);
map.emplace(expression, result);
} else if (auto var = decl->to<IR::Declaration_Variable>()) {
LOG1("Variable to json " << var);
auto result = new Util::JsonObject();
auto type = typeMap->getType(var, true);
auto type = backend->getTypeMap().getType(var, true);
if (type->is<IR::Type_StructLike>()) {
result->emplace("type", "header");
result->emplace("value", var->name);
Expand Down Expand Up @@ -498,7 +499,7 @@ void ExpressionConverter::postorder(const IR::Expression* expression) {
Util::IJson* ExpressionConverter::convert(const IR::Expression* e, bool doFixup, bool wrap, bool convertBool) {
const IR::Expression *expr = e;
if (doFixup) {
ArithmeticFixup af(typeMap);
ArithmeticFixup af(&backend->getTypeMap());
auto r = e->apply(af);
CHECK_NULL(r);
expr = r->to<IR::Expression>();
Expand Down Expand Up @@ -543,7 +544,7 @@ Util::IJson* ExpressionConverter::convert(const IR::Expression* e, bool doFixup,
Util::IJson* ExpressionConverter::convertLeftValue(const IR::Expression* e) {
leftValue = true;
const IR::Expression *expr = e;
ArithmeticFixup af(typeMap);
ArithmeticFixup af(&backend->getTypeMap());
auto r = e->apply(af);
CHECK_NULL(r);
expr = r->to<IR::Expression>();
Expand Down
11 changes: 3 additions & 8 deletions backends/bmv2/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,16 @@ class ArithmeticFixup : public Transform {
};

class ExpressionConverter : public Inspector {
P4::ReferenceMap* refMap;
P4::TypeMap* typeMap;
Backend *backend;
P4::P4CoreLibrary& corelib;
ProgramParts* structure;
ErrorCodesMap* errorCodesMap;
cstring scalarsName = "scalars";

/// after translating an Expression to JSON, save the result to 'map'.
std::map<const IR::Expression*, Util::IJson*> map;
bool leftValue; // true if converting a left value
public:
explicit ExpressionConverter(P4::ReferenceMap* refMap, P4::TypeMap* typeMap,
ProgramParts* structure, ErrorCodesMap* errorCodesMap):
refMap(refMap), typeMap(typeMap), corelib(P4::P4CoreLibrary::instance),
structure(structure), errorCodesMap(errorCodesMap),
explicit ExpressionConverter(Backend *b) :
backend(b), corelib(P4::P4CoreLibrary::instance),
leftValue(false), simpleExpressionsOnly(false) {}
bool simpleExpressionsOnly; // if set we fail to convert complex expressions

Expand Down
7 changes: 6 additions & 1 deletion backends/bmv2/extern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ bool Extern::preorder(const IR::Declaration_Instance* decl) {
auto result = new Util::JsonObject();
result->emplace("name", decl->name);
result->emplace("id", nextId("extern_instances"));
result->emplace("type", decl->type->to<IR::Type_Specialized>()->baseType->toString());
if (decl->type->is<IR::Type_Specialized>())
result->emplace("type", decl->type->to<IR::Type_Specialized>()->baseType->toString());
else if (decl->type->is<IR::Type_Name>())
result->emplace("type", decl->type->to<IR::Type_Name>()->path->name.toString());
else
P4C_UNIMPLEMENTED("extern support for %1%", decl);
auto attributes = mkArrayField(result, "attribute_values");
addExternAttributes(decl, externBlock, attributes);
backend->externs->append(result);
Expand Down
3 changes: 3 additions & 0 deletions backends/bmv2/v1model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ using BMV2::nextId;

namespace P4V1 {

cstring jsonMetadataParameterName = "standard_metadata";



static void addToFieldList(BMV2::Backend *bmv2, const IR::Expression* expr,
Util::JsonArray* fl)
Expand Down