in flexsai/p4/backend/json_stage/control.cpp [727:814]
bool ControlConverter::preorder(const IR::ControlBlock* block) {
auto bt = backend->pipeline_controls.find(block->container->name);
if (bt == backend->pipeline_controls.end()) {
return false;
}
const IR::P4Control* cont = block->container;
auto result = new Util::JsonObject();
auto it = backend->pipeline_namemap.find(block->container->name);
BUG_CHECK(it != backend->pipeline_namemap.end(),
"Expected to find %1% in control block name map", block->container->name);
result->emplace("name", it->second);
result->emplace("id", nextId("control"));
result->emplace_non_null("source_info", cont->sourceInfoJsonObj());
auto cfg = new CFG();
cfg->build(cont, refMap, typeMap);
bool success = cfg->checkImplementable();
if (!success)
return false;
if (cfg->entryPoint->successors.size() == 0) {
result->emplace("init_table", Util::JsonValue::null);
} else {
BUG_CHECK(cfg->entryPoint->successors.size() == 1, "Expected 1 start node for %1%", cont);
auto start = (*(cfg->entryPoint->successors.edges.begin()))->endpoint;
result->emplace("init_table", nodeName(start));
}
auto tables = mkArrayField(result, "tables");
auto action_profiles = mkArrayField(result, "action_profiles");
auto conditionals = mkArrayField(result, "conditionals");
SharedActionSelectorCheck selector_check(refMap, typeMap);
block->apply(selector_check);
std::set<const IR::P4Table*> done;
// Tables are created prior to the other local declarations
for (auto node : cfg->allNodes) {
auto tn = node->to<CFG::TableNode>();
if (tn != nullptr) {
if (done.find(tn->table) != done.end())
// The same table may appear in multiple nodes in the CFG.
// We emit it only once. Other checks should ensure that
// the CFG is implementable.
continue;
done.emplace(tn->table);
auto j = convertTable(tn, action_profiles, selector_check);
if (::errorCount() > 0)
return false;
tables->append(j);
} else if (node->is<CFG::IfNode>()) {
auto j = convertIf(node->to<CFG::IfNode>(), cont->name);
if (::errorCount() > 0)
return false;
conditionals->append(j);
}
}
// hanw: skip for PSA
for (auto c : cont->controlLocals) {
if (c->is<IR::Declaration_Constant>() ||
c->is<IR::Declaration_Variable>() ||
c->is<IR::P4Action>() ||
c->is<IR::P4Table>())
continue;
if (c->is<IR::Declaration_Instance>()) {
auto bl = block->getValue(c);
CHECK_NULL(bl);
if (bl->is<IR::ControlBlock>() || bl->is<IR::ParserBlock>())
// Since this block has not been inlined, it is probably unused
// So we don't do anything.
continue;
if (bl->is<IR::ExternBlock>()) {
auto eb = bl->to<IR::ExternBlock>();
std::cout <<"SAI IGNORING extern " << eb->toString() << std::endl;
// backend->getSaiSwitch()->convertExternInstances(c, eb, action_profiles,
// selector_check);
continue;
}
}
P4C_UNIMPLEMENTED("%1%: not yet handled", c);
}
json->pipelines->append(result);
return false;
}