56 MAU_DEP_CONCURRENT = 0
60 CONTROL_ACTION = (1 << 1),
61 CONTROL_COND_TRUE = (1 << 2),
63 CONTROL_COND_FALSE = (1 << 3),
65 CONTROL_TABLE_HIT = (1 << 4),
66 CONTROL_TABLE_MISS = (1 << 5),
67 CONTROL_DEFAULT_NEXT_TABLE = (1 << 6),
68 CONTROL_EXIT = (1 << 19),
70 IXBAR_READ = (1 << 7),
71 ACTION_READ = (1 << 8),
74 REDUCTION_OR_READ = (1 << 10),
77 REDUCTION_OR_OUTPUT = (1 << 11),
80 CONT_CONFLICT = (1 << 12),
82 ANTI_EXIT = (1 << 13),
83 ANTI_TABLE_READ = (1 << 14),
85 ANTI_ACTION_READ = (1 << 15),
87 ANTI_NEXT_TABLE_DATA = (1 << 16),
89 ANTI_NEXT_TABLE_CONTROL = (1 << 17),
91 ANTI_NEXT_TABLE_METADATA = (1 << 18),
94 static const unsigned ANTI = ANTI_EXIT | ANTI_TABLE_READ | ANTI_ACTION_READ |
95 ANTI_NEXT_TABLE_DATA | ANTI_NEXT_TABLE_METADATA;
96 static const unsigned CONTROL =
97 CONTROL_ACTION | CONTROL_COND_TRUE | CONTROL_COND_FALSE | CONTROL_TABLE_HIT |
98 CONTROL_TABLE_MISS | CONTROL_DEFAULT_NEXT_TABLE | CONTROL_EXIT | ANTI_NEXT_TABLE_CONTROL;
99 static const unsigned CONTROL_AND_ANTI = CONTROL | ANTI;
100 typedef boost::adjacency_list<
101 boost::vecS, boost::vecS,
102 boost::bidirectionalS,
103 boost::property<boost::vertex_table_t, const IR::MAU::Table *>,
160 void check_finalized()
const {
161 if (!finalized) BUG(
"Dependency graph used before being fully constructed.");
164 void check_stage_info_exist(
const IR::MAU::Table *t)
const {
165 if (!stage_info.count(t)) {
166 BUG(
"table not exists in Dependency graph: %1%", cstring::to_cstring(t));
170 typedef DependencyGraph::Graph::edge_descriptor GraphEdge;
171 struct cycle_detector :
public boost::dfs_visitor<> {
172 cycle_detector(
DependencyGraph &dg,
bool &has_cycle) : _dg(dg), _has_cycle(has_cycle) {}
174 void back_edge(
const GraphEdge e,
const DependencyGraph::Graph &g) {
175 auto source = _dg.get_vertex(boost::source(e, g));
176 auto target = _dg.get_vertex(boost::target(e, g));
177 LOG6(
" Found back-edge : " << source->name <<
" ==> " << target->name);
206 happens_before_work_map;
215 happens_phys_before_map;
220 happens_before_control_map;
230 happens_logi_before_map;
240 DependencyGraph::dependencies_t>
249 data_annotations_exit;
256 std::map<const IR::MAU::Table *, std::map<const PHV::Container, bool>> containers_write_ = {};
258 std::map<const IR::MAU::Table *, std::map<const PHV::Container, bool>> containers_read_xbar_ =
261 std::map<const IR::MAU::Table *, std::map<const PHV::Container, bool>> containers_read_alu_ =
266 std::map<std::pair<const IR::MAU::Table *, const IR::MAU::Table *>,
267 DependencyGraph::mau_dependencies_t>
275 dep_stages_control, dep_stages_control_anti, dep_stages_control_anti_split,
276 dep_stages_dom_frontier;
281 using MinEdgeInfo = std::pair<const IR::MAU::Table *, dependencies_t>;
282 bool display_min_edges =
false;
289 int max_min_stage = -1;
291 std::vector<ordered_set<DependencyGraph::Graph::vertex_descriptor>> vertex_rst;
304 name_to_table.clear();
305 happens_after_work_map.clear();
306 happens_before_work_map.clear();
307 happens_phys_after_map.clear();
308 happens_before_control_map.clear();
309 happens_logi_after_map.clear();
310 happens_logi_before_map.clear();
311 dep_type_map.clear();
312 labelToVertex.clear();
313 dependency_map.clear();
314 data_annotations.clear();
315 data_annotations_exit.clear();
316 data_annotations_conflicts.clear();
317 data_annotations_metadata.clear();
318 ctrl_annotations.clear();
320 min_stage_edges.clear();
322 display_min_edges =
false;
326 containers_write_.clear();
327 containers_read_xbar_.clear();
328 containers_read_alu_.clear();
339 bool is_anti_edge(DependencyGraph::dependencies_t dep)
const;
342 bool is_ctrl_edge(DependencyGraph::dependencies_t dep)
const;
356 bool has_back_edge(
const IR::MAU::Table *src,
const IR::MAU::Table *dst) {
357 bool backEdgePresent =
false;
358 DependencyGraph::Graph::edge_descriptor backEdge;
360 auto src_v = labelToVertex.at(dst);
361 auto dst_v = labelToVertex.at(src);
362 boost::tie(backEdge, backEdgePresent) = boost::edge(src_v, dst_v, g);
364 return backEdgePresent;
369 bool has_cycle =
false;
370 cycle_detector vis(*
this, has_cycle);
371 boost::depth_first_search(g, visitor(vis));
377 const IR::MAU::Table *get_vertex(
typename Graph::vertex_descriptor v)
const {
378 return boost::get(boost::vertex_table, g)[v];
383 typename Graph::vertex_descriptor add_vertex(
const IR::MAU::Table *label) {
384 if (labelToVertex.count(label)) {
385 return labelToVertex.at(label);
387 auto v = boost::add_vertex(label, g);
388 labelToVertex[label] = v;
389 stage_info[label] = {0, 0, 0, 0, 0, 0, 0};
397 std::pair<typename Graph::edge_descriptor *, bool> add_edge(
const IR::MAU::Table *src,
398 const IR::MAU::Table *dst,
399 dependencies_t edge_label);
401 bool container_conflict(
const IR::MAU::Table *t1,
const IR::MAU::Table *t2)
const {
407 bool unavoidable_container_conflict(
const IR::MAU::Table *t1,
const IR::MAU::Table *t2)
const {
416 bool happens_phys_before(
const IR::MAU::Table *t1,
const IR::MAU::Table *t2)
const {
418 if (happens_phys_before_map.count(t1)) {
419 return happens_phys_before_map.at(t1).count(t2);
425 bool happens_phys_after(
const IR::MAU::Table *t1,
const IR::MAU::Table *t2)
const {
427 if (happens_phys_after_map.count(t1)) {
428 return happens_phys_after_map.at(t1).count(t2);
436 bool happens_phys_before_recursive(
const IR::MAU::Table *t1,
const IR::MAU::TableSeq *s)
const {
438 if (happens_phys_before_map.count(t1))
439 for (
auto *t2 : s->tables)
440 if (happens_phys_before_recursive(t1, t2))
return true;
445 bool happens_phys_before_recursive(
const IR::MAU::Table *t1,
const IR::MAU::Table *t2)
const {
447 if (happens_phys_before_map.count(t1)) {
448 if (t2 != t1 && happens_phys_before_map.at(t1).count(t2))
return true;
449 for (
auto *next : Values(t2->next))
450 if (happens_phys_before_recursive(t1, next))
return true;
455 bool happens_before_control(
const IR::MAU::Table *t1,
const IR::MAU::Table *t2)
const {
457 if (happens_before_control_map.count(t1))
458 return happens_before_control_map.at(t1).count(t2);
463 bool happens_logi_before(
const IR::MAU::Table *t1,
const IR::MAU::Table *t2)
const {
465 if (happens_logi_before_map.count(t1))
466 return happens_logi_before_map.at(t1).count(t2);
471 bool happens_logi_after(
const IR::MAU::Table *t1,
const IR::MAU::Table *t2)
const {
473 if (happens_logi_after_map.count(t1))
474 return happens_logi_after_map.at(t1).count(t2);
479 std::optional<ordered_map<const PHV::Field *, std::pair<ordered_set<const IR::MAU::Action *>,
481 get_data_dependency_info(
typename Graph::edge_descriptor edge)
const {
482 if (!data_annotations.count(edge)) {
483 LOG4(
"Data dependency edge not found");
486 return data_annotations.at(edge);
489 std::optional<std::string> get_ctrl_dependency_info(
490 typename Graph::edge_descriptor edge)
const {
491 if (!ctrl_annotations.count(edge)) {
492 LOG4(
"Control dependency edge not found");
495 return ctrl_annotations.at(edge);
510 std::pair<const PHV::Field *, DependencyGraph::dependencies_t>,
512 get_data_dependency_info(
const IR::MAU::Table *upstream,
513 const IR::MAU::Table *downstream)
const;
515 void print_dep_type_map(std::ostream &out)
const;
516 void print_container_access(std::ostream &out)
const;
528 const IR::MAU::Table *to);
535 const IR::MAU::Table *t2)
const {
536 if (!finalized) BUG(
"Dependence graph used before being fully constructed.");
538 auto p = std::make_pair(t1, t2);
539 if (dependency_map.find(p) != dependency_map.end()) {
540 return dependency_map.at(p);
543 return DependencyGraph::CONCURRENT;
546 int dependence_tail_size(
const IR::MAU::Table *t)
const {
548 check_stage_info_exist(t);
549 return stage_info.at(t).dep_stages;
552 int dependence_tail_size_control(
const IR::MAU::Table *t)
const {
554 check_stage_info_exist(t);
555 return stage_info.at(t).dep_stages_control;
558 int dependence_tail_size_control_anti(
const IR::MAU::Table *t)
const {
560 check_stage_info_exist(t);
561 return stage_info.at(t).dep_stages_control_anti;
564 int dependence_tail_size_control_anti_split(
const IR::MAU::Table *t)
const {
566 check_stage_info_exist(t);
567 return stage_info.at(t).dep_stages_control_anti_split;
570 int min_stage(
const IR::MAU::Table *t)
const {
572 check_stage_info_exist(t);
573 return stage_info.at(t).min_stage;
576 int max_stage(
const IR::MAU::Table *t)
const {
578 check_stage_info_exist(t);
579 return stage_info.at(t).max_stage;
582 const std::vector<const IR::MAU::Table *> &happens_before_dependences(
583 const IR::MAU::Table *t)
const {
585 return happens_before_work_map.at(t);
588 friend std::ostream &operator<<(std::ostream &,
const DependencyGraph &);
589 static cstring dep_to_name(dependencies_t dep);
592 static dependencies_t get_control_edge_type(
cstring annot);
594 TableGraphNode create_node(
const int id,
const IR::MAU::Table *tbl)
const;
612 cstring exit_action_name =
""_cs;
613 bool is_critical =
false;
615 std::vector<TableGraphField> dep_fields;
616 std::vector<cstring> tags;
617 bool condition_value;
618 DependencyGraph::dependencies_t label;
627 if (!s)
return false;
631 f.gress = toString(s->
gress);
634 dep_fields.push_back(f);
635 LOG5(
" Adding Dep Field: " << f.name <<
"[" << f.hi <<
":" << f.lo <<
"] (" << f.gress
642 if (dep_fields.size() > 0) {
643 for (
auto field : dep_fields) {
645 edgeMdDepField->emplace(
"gress"_cs, field.gress);
646 edgeMdDepField->emplace(
"field_name"_cs, field.name);
647 edgeMdDepField->emplace(
"start_bit"_cs, field.lo);
648 edgeMdDepField->emplace(
"width"_cs, field.hi - field.lo + 1);
649 edgeMdDepFields->append(edgeMdDepField);
652 edgeMdJson->emplace(
"dep_fields"_cs, edgeMdDepFields);
656 auto act_name = cstring::to_cstring(
canon_name(action_name));
657 edgeMdJson->emplace(
"action_name"_cs, act_name);
661 auto act_name = cstring::to_cstring(
canon_name(exit_action_name));
662 edgeMdJson->emplace(
"action_name"_cs, act_name);
666 edgeMdJson->emplace(
"phv_number"_cs, phv_number);
670 if (labels_to_conds.count(label) == 0)
671 BUG(
"Invalid edge type. Cannot determine condition value");
672 bool condition_value = labels_to_conds[label];
673 edgeMdJson->emplace(
"condition_value"_cs, condition_value);
677 if (labels_to_anti_types.count(label) == 0)
678 BUG(
"Invalid edge type. Cannot determine anti type");
680 auto anti_type = labels_to_anti_types[label];
681 edgeMdJson->emplace(
"anti_type"_cs, anti_type);
685 if (labels_to_types.count(label) == 0) BUG(
"Invalid edge type");
687 auto type = labels_to_types[label];
688 edgeMdJson->emplace(
"type"_cs, type);
692 if (labels_to_sub_types.count(label) == 0)
693 BUG(
"Invalid edge type. Cannot determine sub type.");
695 auto sub_type = labels_to_sub_types[label];
696 edgeMdJson->emplace(
"sub_type"_cs, sub_type);
702 add_type_json(edgeMdJson);
703 add_sub_type_json(edgeMdJson);
706 case DependencyGraph::IXBAR_READ:
707 add_dep_fields_json(edgeMdJson);
710 case DependencyGraph::ACTION_READ:
711 add_dep_fields_json(edgeMdJson);
712 add_action_name_json(edgeMdJson);
715 case DependencyGraph::OUTPUT:
716 add_dep_fields_json(edgeMdJson);
719 case DependencyGraph::CONT_CONFLICT:
720 add_phv_number_json(edgeMdJson);
723 case DependencyGraph::REDUCTION_OR_READ:
724 case DependencyGraph::REDUCTION_OR_OUTPUT:
725 add_dep_fields_json(edgeMdJson);
728 case DependencyGraph::ANTI_TABLE_READ:
729 case DependencyGraph::ANTI_ACTION_READ:
730 case DependencyGraph::ANTI_NEXT_TABLE_DATA:
731 case DependencyGraph::ANTI_NEXT_TABLE_CONTROL:
732 case DependencyGraph::ANTI_NEXT_TABLE_METADATA:
733 add_anti_type_json(edgeMdJson);
734 add_dep_fields_json(edgeMdJson);
737 case DependencyGraph::ANTI_EXIT:
738 add_exit_action_name_json(edgeMdJson);
741 case DependencyGraph::CONTROL_ACTION:
742 add_action_name_json(edgeMdJson);
745 case DependencyGraph::CONTROL_COND_TRUE:
746 case DependencyGraph::CONTROL_COND_FALSE:
747 add_condition_value_json(edgeMdJson);
750 case DependencyGraph::CONTROL_TABLE_HIT:
751 case DependencyGraph::CONTROL_TABLE_MISS:
752 case DependencyGraph::CONTROL_DEFAULT_NEXT_TABLE:
753 case DependencyGraph::CONTROL_EXIT:
758 BUG(
"Invalid dependency graph edge type");
761 if (is_critical) edgeMdJson->emplace(
"is_critical"_cs, is_critical);
763 if (tags.size() > 0) {
765 for (
auto t : tags) edgeMdTags->append(t);
766 edgeMdJson->emplace(
"tags"_cs, edgeMdTags);
775 edgeJson->emplace(
"source"_cs,
new Util::JsonValue(std::to_string(source)));
776 edgeJson->emplace(
"target"_cs,
new Util::JsonValue(std::to_string(target)));
777 edgeJson->emplace(
"metadata"_cs, create_edge_md_json());