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

Fixes for P4_14->16 conversion of externs #310

Merged
merged 2 commits into from
Feb 16, 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
6 changes: 5 additions & 1 deletion backends/bmv2/bmv2stf.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,11 @@ def do_command(self, cmd):
interface, data = nextWord(cmd)
data = ''.join(data.split())
time.sleep(self.packetDelay)
self.interfaces[interface]._write_packet(HexToByte(data))
try:
self.interfaces[interface]._write_packet(HexToByte(data))
except ValueError:
reportError("Invalid packet data", data)
return FAILURE
self.interfaces[interface].flush()
self.packetDelay = 0
elif first == "expect":
Expand Down
6 changes: 3 additions & 3 deletions frontends/common/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,13 @@ void CompilerOptions::dumpPass(const char* manager, unsigned seq, const char* pa
P4::ToP4 toP4(stream, Log::verbose(), file);
node->apply(toP4);
}
break;
}
}
}

DebugHook CompilerOptions::getDebugHook() const {
auto dp = std::bind(&CompilerOptions::dumpPass, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4);
using namespace std::placeholders;
auto dp = std::bind(&CompilerOptions::dumpPass, this, _1, _2, _3, _4);
return dp;
}
1 change: 1 addition & 0 deletions frontends/common/parseInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const IR::P4Program* parseP4File(CompilerOptions& options) {
bool compiling10 = options.isv1();
if (compiling10) {
P4V1::Converter converter;
converter.addDebugHook(options.getDebugHook());
converter.loadModel();
// Model is loaded before parsing the input file.
// In this way the SourceInfo in the model comes first.
Expand Down
11 changes: 6 additions & 5 deletions frontends/p4-14/typecheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ class TypeCheck::Pass1 : public Transform {
const Visitor::Context *prop_ctxt = nullptr;
if (auto prop = findContext<IR::Property>(prop_ctxt)) {
if (auto bbox = prop_ctxt->parent->node->to<IR::Declaration_Instance>()) {
auto bbox_type = bbox->type->to<IR::Type_Extern>();
auto attr = bbox_type->attributes.get<IR::Attribute>(prop->name);
if (attr->locals && attr->locals->locals.count(ref->path->name)) {
return attr->locals->locals.at(ref->path->name); } } }
if (auto bbox_type = bbox->type->to<IR::Type_Extern>()) {
auto attr = bbox_type->attributes.get<IR::Attribute>(prop->name);
if (attr->locals && attr->locals->locals.count(ref->path->name)) {
return attr->locals->locals.at(ref->path->name); } } } }
if (auto bbox = findContext<IR::Declaration_Instance>()) {
if (auto bbox_type = bbox->type->to<IR::Type_Extern>()) {
if (auto attr = bbox_type->attributes.get<IR::Attribute>(ref->path->name))
return new IR::AttributeRef(ref->srcInfo, attr->type,
bbox->name, bbox_type, attr);
} else {
} else if (global) {
BUG("extern type is not extern_type?"); } }
return ref; }
const IR::Node *preorder(IR::Metadata *m) override {
Expand Down Expand Up @@ -92,6 +92,7 @@ class TypeCheck::Pass1 : public Transform {
const IR::Node *preorder(IR::Property *prop) override {
if (auto di = findContext<IR::Declaration_Instance>()) {
auto ext = di->type->to<IR::Type_Extern>();
if (!ext && !global) return prop;
BUG_CHECK(ext, "%s is not an extern", di);
if (auto attr = ext->attributes[prop->name]) {
if (attr->type->is<IR::Type::String>())
Expand Down
5 changes: 5 additions & 0 deletions frontends/p4/def_use.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,11 @@ bool ComputeWriteSet::setDefinitions(Definitions* defs, const IR::Node* node) {

/// For expressions we maintain the write-set in the writes std::map

bool ComputeWriteSet::preorder(const IR::Expression* expression) {
set(expression, LocationSet::empty);
return false;
}

bool ComputeWriteSet::preorder(const IR::DefaultExpression* expression) {
set(expression, LocationSet::empty);
return false;
Expand Down
1 change: 1 addition & 0 deletions frontends/p4/def_use.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ class ComputeWriteSet : public Inspector {
bool preorder(const IR::Operation_Unary* expression) override;
bool preorder(const IR::MethodCallExpression* expression) override;
bool preorder(const IR::DefaultExpression* expression) override;
bool preorder(const IR::Expression* expression) override;
// statements
bool preorder(const IR::ParserState* state) override;
bool preorder(const IR::P4Parser* parser) override;
Expand Down
24 changes: 21 additions & 3 deletions frontends/p4/fromv1.0/converters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,12 @@ const IR::Node* ExpressionConverter::postorder(IR::PathExpression *ref) {
if (ref->path->name.name == "next") {
return ref;
}
auto fl = structure->field_lists.get(ref->path->name);
if (fl != nullptr) {
if (auto fl = structure->field_lists.get(ref->path->name)) {
ExpressionConverter conv(structure);
return conv.convert(fl);
return conv.convert(fl); }
if (auto flc = structure->field_list_calculations.get(ref->path->name)) {
// FIXME -- what to do with the algorithm and width from flc?
return ExpressionConverter(structure).convert(flc->input_fields);
}
return ref;
}
Expand Down Expand Up @@ -169,6 +171,10 @@ const IR::Node* ExpressionConverter::postorder(IR::HeaderStackItemRef* ref) {
return ref;
}

const IR::Node* ExpressionConverter::postorder(IR::GlobalRef *ref) {
return new IR::PathExpression(new IR::Path(ref->srcInfo, ref->toString()));
}

const IR::Node* StatementConverter::preorder(IR::Apply* apply) {
auto table = structure->tables.get(apply->name);
auto newname = structure->tables.get(table);
Expand Down Expand Up @@ -478,6 +484,18 @@ class ComputeCallGraph : public Inspector {
structure->calledControls.calls(parent->name, name);
}
}
void postorder(const IR::GlobalRef *gref) override {
auto parent = findContext<IR::ActionFunction>();
BUG_CHECK(parent != nullptr, "%1%: GlobalRef not within action", gref);
if (auto ctr = gref->obj->to<IR::Counter>())
structure->calledCounters.calls(parent->name, ctr->name.name);
else if (auto mtr = gref->obj->to<IR::Meter>())
structure->calledMeters.calls(parent->name, mtr->name.name);
else if (auto reg = gref->obj->to<IR::Register>())
structure->calledRegisters.calls(parent->name, reg->name.name);
else if (auto ext = gref->obj->to<IR::Declaration_Instance>())
structure->calledExterns.calls(parent->name, ext->name.name);
}
};

class Rewriter : public Transform {
Expand Down
1 change: 1 addition & 0 deletions frontends/p4/fromv1.0/converters.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class ExpressionConverter : public Transform {
const IR::Node* postorder(IR::PathExpression* ref) override;
const IR::Node* postorder(IR::ConcreteHeaderRef* nhr) override;
const IR::Node* postorder(IR::HeaderStackItemRef* ref) override;
const IR::Node* postorder(IR::GlobalRef *gr) override;
const IR::Expression* convert(const IR::Node* node) {
auto result = node->apply(*this);
return result->to<IR::Expression>();
Expand Down
72 changes: 50 additions & 22 deletions frontends/p4/fromv1.0/programStructure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,25 +225,54 @@ void ProgramStructure::createStructures() {
declarations->push_back(headers);
}

void ProgramStructure::createExterns() {
for (auto it : extern_types) {
auto type = it.first;
IR::Type_Extern *modified_type = nullptr;
if (type->name != it.second) {
auto annos = addNameAnnotation(type->name.name, type->annotations);
type = modified_type = new IR::Type_Extern(type->srcInfo, it.second, type->methods,
type->attributes, annos); }
class ProgramStructure::FixupExtern : public Modifier {
ProgramStructure &self;
cstring origname, extname;
const IR::TypeParameters *typeParams = nullptr;

bool preorder(IR::Type_Extern *type) override {
BUG_CHECK(!origname, "Nested extern");
origname = type->name;
return true; }
void postorder(IR::Type_Extern *type) override {
if (extname != type->name) {
type->annotations = self.addNameAnnotation(type->name.name, type->annotations);
type->name = extname; }
// FIXME -- should create ctors based on attributes? For now just create a
// FIXME -- 0-arg one if needed
if (!type->lookupMethod(type->name, 0)) {
if (!modified_type)
type = modified_type = type->clone();
auto methods = type->methods->clone();
modified_type->methods = methods;
type->methods = methods;
methods->push_back(new IR::Method(type->name, new IR::Type_Method(
new IR::ParameterList()))); }
declarations->push_back(type);
}
new IR::ParameterList()))); } }
void postorder(IR::Method *meth) override {
if (meth->name == origname) meth->name = extname; }
// Convert extern methods that take a field_list_calculation to take a type param instead
bool preorder(IR::Type_MethodBase *mtype) override {
BUG_CHECK(!typeParams, "recursion failure");
typeParams = mtype->typeParameters;
return true; }
bool preorder(IR::Parameter *param) override {
BUG_CHECK(typeParams, "recursion failure");
if (param->type->is<IR::Type_FieldListCalculation>()) {
auto n = new IR::Type_Var(self.makeUniqueName("FL"));
param->type = n;
auto v = typeParams->parameters->clone();
v->push_back(n);
typeParams = new IR::TypeParameters(v); }
return false; }
void postorder(IR::Type_MethodBase *mtype) override {
BUG_CHECK(typeParams, "recursion failure");
mtype->typeParameters = typeParams;
typeParams = nullptr; }

public:
FixupExtern(ProgramStructure &self, cstring n) : self(self), extname(n) {}
};

void ProgramStructure::createExterns() {
for (auto it : extern_types)
declarations->push_back(it.first->apply(FixupExtern(*this, it.second)));
}

const IR::Expression* ProgramStructure::paramReference(const IR::Parameter* param) {
Expand Down Expand Up @@ -443,14 +472,13 @@ void ProgramStructure::include(cstring filename) {
CompilerOptions options;
options.langVersion = CompilerOptions::FrontendVersion::P4_16;
options.file = path.toString();
FILE* file = options.preprocess();
if (::errorCount() || file == nullptr)
return;
auto std = parse_P4_16_file(options.file, file);
if (::errorCount() || std == nullptr)
return;
for (auto decl : *std->declarations)
declarations->push_back(decl);
if (FILE* file = options.preprocess()) {
if (!::errorCount()) {
if (auto code = parse_P4_16_file(options.file, file)) {
if (!::errorCount()) {
for (auto decl : *code->declarations) {
declarations->push_back(decl); } } } }
options.closeInput(file); }
}

void ProgramStructure::loadModel() {
Expand Down
1 change: 1 addition & 0 deletions frontends/p4/fromv1.0/programStructure.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class ProgramStructure {
iterator begin() { return iterator(nameToObject.begin(), objectToNewName); }
iterator end() { return iterator(nameToObject.end(), objectToNewName); }
};
class FixupExtern;

public:
ProgramStructure();
Expand Down
1 change: 1 addition & 0 deletions frontends/p4/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class FrontEnd {
std::vector<DebugHook> hooks;
public:
FrontEnd() = default;
explicit FrontEnd(DebugHook hook) { hooks.push_back(hook); }
void addDebugHook(DebugHook hook) { hooks.push_back(hook); }
const IR::P4Program* run(const CompilerOptions& options, const IR::P4Program* program);
};
Expand Down