Skip to content

Commit af4285a

Browse files
committed
Start to use a concrete key data structure.
1 parent d815807 commit af4285a

File tree

4 files changed

+49
-51
lines changed

4 files changed

+49
-51
lines changed

Diff for: core/control_plane/control_plane_objects.cpp

+42-22
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "backends/p4tools/common/control_plane/symbolic_variables.h"
77
#include "backends/p4tools/common/lib/variables.h"
88
#include "backends/p4tools/modules/flay/core/control_plane/substitute_variable.h"
9+
#include "backends/p4tools/modules/flay/core/lib/simplify_expression.h"
910
#include "backends/p4tools/modules/flay/core/lib/z3_cache.h"
1011
#include "ir/irutils.h"
1112
#include "lib/timer.h"
@@ -290,6 +291,25 @@ Z3ControlPlaneAssignmentSet WildCardMatchEntry::computeZ3ControlPlaneAssignments
290291
TableConfiguration
291292
**************************************************************************************************/
292293

294+
const IR::Expression *buildKeyMatches(const KeyMap &keyMap) {
295+
if (keyMap.empty()) {
296+
return IR::BoolLiteral::get(false);
297+
}
298+
const IR::Expression *hitCondition = nullptr;
299+
for (const auto *key : keyMap) {
300+
const auto *matchExpr = key->computeControlPlaneConstraint();
301+
if (hitCondition == nullptr) {
302+
hitCondition = matchExpr;
303+
} else {
304+
hitCondition = new IR::LAnd(hitCondition, matchExpr);
305+
}
306+
}
307+
// The table can only "hit" when it is actually configured by the control-plane.
308+
// Pay attention to how we use "toString" for the path name here.
309+
// We need to match these choices correctly. TODO: Make this very explicit.
310+
return hitCondition;
311+
}
312+
293313
bool TableConfiguration::CompareTableMatch::operator()(const TableMatchEntry &left,
294314
const TableMatchEntry &right) {
295315
return left.priority() > right.priority();
@@ -306,10 +326,10 @@ bool TableConfiguration::operator<(const ControlPlaneItem &other) const {
306326
: typeid(*this).hash_code() < typeid(other).hash_code();
307327
}
308328

309-
void TableConfiguration::setTableKeyMatch(const IR::Expression *tableKeyMatch) {
310-
_tableKeyMatch = tableKeyMatch;
329+
void TableConfiguration::setTableKeyMatch(const KeyMap &tableKeyMap) {
330+
_tableKeyMatch = SimplifyExpression::simplify(buildKeyMatches(tableKeyMap));
311331
// When we set the table key match, we also need to recompute the match of all table entries.
312-
auto z3TableKeyMatch = Z3Cache::set(tableKeyMatch);
332+
auto z3TableKeyMatch = Z3Cache::set(_tableKeyMatch);
313333
for (const auto &tableMatchEntry : _tableEntries) {
314334
tableMatchEntry.get().setZ3Condition(z3TableKeyMatch);
315335
}
@@ -341,21 +361,21 @@ ControlPlaneAssignmentSet TableConfiguration::computeControlPlaneAssignments() c
341361
return defaultAssignments;
342362
}
343363

344-
// If we have more than kMaxEntriesPerTable entries we give up.
345-
// Set the entries symbolic and assume they can be executed freely.
346-
if (_tableEntries.size() > kMaxEntriesPerTable) {
347-
for (const auto &[symbol, assignment] : defaultAssignments) {
348-
const auto *symbolicVar =
349-
ToolsVariables::getSymbolicVariable(symbol.get().type, symbol.get().label + "*");
350-
auto it = defaultAssignments.find(symbol);
351-
if (it == defaultAssignments.end()) {
352-
defaultAssignments.emplace(symbol, *symbolicVar);
353-
} else {
354-
it->second = *symbolicVar;
355-
}
356-
}
357-
return defaultAssignments;
358-
}
364+
// // If we have more than kMaxEntriesPerTable entries we give up.
365+
// // Set the entries symbolic and assume they can be executed freely.
366+
// if (_tableEntries.size() > kMaxEntriesPerTable) {
367+
// for (const auto &[symbol, assignment] : defaultAssignments) {
368+
// const auto *symbolicVar =
369+
// ToolsVariables::getSymbolicVariable(symbol.get().type, symbol.get().label + "*");
370+
// auto it = defaultAssignments.find(symbol);
371+
// if (it == defaultAssignments.end()) {
372+
// defaultAssignments.emplace(symbol, *symbolicVar);
373+
// } else {
374+
// it->second = *symbolicVar;
375+
// }
376+
// }
377+
// return defaultAssignments;
378+
// }
359379

360380
for (const auto &tableEntry : _tableEntries) {
361381
const auto &actionAssignments = tableEntry.get().actionAssignment();
@@ -384,10 +404,10 @@ Z3ControlPlaneAssignmentSet TableConfiguration::computeZ3ControlPlaneAssignments
384404

385405
// If we have more than kMaxEntriesPerTable entries we give up.
386406
// Set the entries symbolic and assume they can be executed freely.
387-
if (_tableEntries.size() > kMaxEntriesPerTable) {
388-
defaultAssignments.setAllSymbolic();
389-
return defaultAssignments;
390-
}
407+
// if (_tableEntries.size() > kMaxEntriesPerTable) {
408+
// defaultAssignments.setAllSymbolic();
409+
// return defaultAssignments;
410+
// }
391411

392412
Util::ScopedTimer timer("computeZ3ControlPlaneAssignments");
393413
auto z3TableKeyMatchOpt = Z3Cache::get(_tableKeyMatch);

Diff for: core/control_plane/control_plane_objects.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ TableConfiguration
337337
/// The active set of table entries. Sorted by type.
338338
using TableEntrySet = std::set<std::reference_wrapper<TableMatchEntry>, std::less<TableMatchEntry>>;
339339

340+
using KeyMap = std::vector<const TableMatchKey *>;
341+
340342
/// Concrete configuration of a control plane table. May contain arbitrary many table match
341343
/// entries.
342344
class TableConfiguration : public Z3ControlPlaneItem {
@@ -365,7 +367,7 @@ class TableConfiguration : public Z3ControlPlaneItem {
365367
bool operator<(const ControlPlaneItem &other) const override;
366368

367369
/// Set the table key match expression.
368-
void setTableKeyMatch(const IR::Expression *tableKeyMatch);
370+
void setTableKeyMatch(const KeyMap &tableKeyMap);
369371

370372
/// Adds a new table entry.
371373
int addTableEntry(TableMatchEntry &tableMatchEntry, bool replace);

Diff for: core/interpreter/table_executor.cpp

+4-26
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ const IR::Key *TableExecutor::resolveKey(const IR::Key *key) const {
9898
KeyMap TableExecutor::computeHitCondition(const IR::Key &key) const {
9999
KeyMap keyMap;
100100
for (const auto *keyField : key.keyElements) {
101-
keyMap.insert(computeTargetMatchType(keyField));
101+
keyMap.push_back(computeTargetMatchType(keyField));
102102
}
103103
return keyMap;
104104
}
@@ -239,37 +239,16 @@ void TableExecutor::processTableActionOptions(
239239
}
240240
}
241241

242-
const IR::Expression *TableExecutor::buildKeyMatches(const KeyMap &keyMap) {
243-
if (keyMap.empty()) {
244-
return IR::BoolLiteral::get(false);
245-
}
246-
const IR::Expression *hitCondition = nullptr;
247-
for (const auto *key : keyMap) {
248-
const auto *matchExpr = key->computeControlPlaneConstraint();
249-
if (hitCondition == nullptr) {
250-
hitCondition = matchExpr;
251-
} else {
252-
hitCondition = new IR::LAnd(hitCondition, matchExpr);
253-
}
254-
}
255-
// The table can only "hit" when it is actually configured by the control-plane.
256-
// Pay attention to how we use "toString" for the path name here.
257-
// We need to match these choices correctly. TODO: Make this very explicit.
258-
return hitCondition;
259-
}
260-
261242
const IR::Expression *TableExecutor::processTable() {
262243
const auto &table = getP4Table();
263244
TableUtils::TableProperties properties;
264245
TableUtils::checkTableImmutability(table, properties);
265246

266247
// Then, resolve the key.
267248
const auto *key = table.getKey();
268-
const IR::Expression *tableKeyExpression = nullptr;
249+
KeyMap tableKeyMap;
269250
if (key != nullptr) {
270-
tableKeyExpression = buildKeyMatches(computeHitCondition(*resolveKey(key)));
271-
} else {
272-
tableKeyExpression = IR::BoolLiteral::get(false);
251+
tableKeyMap = computeHitCondition(*resolveKey(key));
273252
}
274253

275254
const auto *defaultActionPath = TableUtils::getDefaultActionName(table);
@@ -289,8 +268,7 @@ const IR::Expression *TableExecutor::processTable() {
289268
if (tableControlPlaneItem != controlPlaneConstraints().end()) {
290269
auto *tableControlPlaneConfiguration =
291270
tableControlPlaneItem->second.get().checkedTo<TableConfiguration>();
292-
tableControlPlaneConfiguration->setTableKeyMatch(
293-
SimplifyExpression::simplify(tableKeyExpression));
271+
tableControlPlaneConfiguration->setTableKeyMatch(tableKeyMap);
294272
} else {
295273
::P4::error("Table %s has no control plane configuration", table.controlPlaneName());
296274
}

Diff for: core/interpreter/table_executor.h

-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ namespace P4::P4Tools::Flay {
1515
/// Forward declaration of the calling expression resolver.
1616
class ExpressionResolver;
1717

18-
using KeyMap = std::set<const TableMatchKey *>;
19-
2018
/// Executes a table and synthesizes control plane action parameters.
2119
class TableExecutor {
2220
private:

0 commit comments

Comments
 (0)