|
enum | dependencies_t {
NONE = 1
, CONTROL_ACTION = (1 << 1)
, CONTROL_COND_TRUE = (1 << 2)
, CONTROL_COND_FALSE = (1 << 3)
,
CONTROL_TABLE_HIT = (1 << 4)
, CONTROL_TABLE_MISS = (1 << 5)
, CONTROL_DEFAULT_NEXT_TABLE = (1 << 6)
, CONTROL_EXIT = (1 << 19)
,
IXBAR_READ = (1 << 7)
, ACTION_READ = (1 << 8)
, OUTPUT = (1 << 9)
, REDUCTION_OR_READ = (1 << 10)
,
REDUCTION_OR_OUTPUT = (1 << 11)
, CONT_CONFLICT = (1 << 12)
, ANTI_EXIT = (1 << 13)
, ANTI_TABLE_READ = (1 << 14)
,
ANTI_ACTION_READ = (1 << 15)
, ANTI_NEXT_TABLE_DATA = (1 << 16)
, ANTI_NEXT_TABLE_CONTROL = (1 << 17)
, ANTI_NEXT_TABLE_METADATA = (1 << 18)
,
CONCURRENT = 0
} |
|
typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, boost::property< boost::vertex_table_t, const IR::MAU::Table * >, dependencies_t > | Graph |
|
enum | mau_dependencies_t { MAU_DEP_MATCH = 2
, MAU_DEP_ACTION = 1
, MAU_DEP_CONCURRENT = 0
} |
|
using | MinEdgeInfo = std::pair<const IR::MAU::Table *, dependencies_t> |
|
|
std::pair< typename Graph::edge_descriptor *, bool > | add_edge (const IR::MAU::Table *src, const IR::MAU::Table *dst, dependencies_t edge_label) |
|
Graph::vertex_descriptor | add_vertex (const IR::MAU::Table *label) |
|
void | clear () |
|
bool | container_conflict (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
TableGraphNode | create_node (const int id, const IR::MAU::Table *tbl) const |
|
int | critical_path_length () const |
|
int | dependence_tail_size (const IR::MAU::Table *t) const |
|
int | dependence_tail_size_control (const IR::MAU::Table *t) const |
|
int | dependence_tail_size_control_anti (const IR::MAU::Table *t) const |
|
int | dependence_tail_size_control_anti_split (const IR::MAU::Table *t) const |
|
void | fill_dep_stages_from_topo (const std::vector< ordered_set< DependencyGraph::Graph::vertex_descriptor > > &topo, bool include_stages, const TableSummary *summary) |
|
DependencyGraph::mau_dependencies_t | find_mau_dependency (const IR::MAU::Table *from, const IR::MAU::Table *to) |
|
std::optional< std::string > | get_ctrl_dependency_info (typename Graph::edge_descriptor edge) const |
|
std::optional< ordered_map< std::pair< const PHV::Field *, DependencyGraph::dependencies_t >, std::pair< ordered_set< const IR::MAU::Action * >, ordered_set< const IR::MAU::Action * > > > > | get_data_dependency_info (const IR::MAU::Table *upstream, const IR::MAU::Table *downstream) const |
|
std::optional< ordered_map< const PHV::Field *, std::pair< ordered_set< const IR::MAU::Action * >, ordered_set< const IR::MAU::Action * > > > > | get_data_dependency_info (typename Graph::edge_descriptor edge) const |
|
DependencyGraph::dependencies_t | get_dependency (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
const IR::MAU::Table * | get_vertex (typename Graph::vertex_descriptor v) const |
|
bool | happens_before_control (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
const std::vector< const IR::MAU::Table * > & | happens_before_dependences (const IR::MAU::Table *t) const |
|
bool | happens_logi_after (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
bool | happens_logi_before (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
bool | happens_phys_after (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
bool | happens_phys_before (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
bool | happens_phys_before_recursive (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
bool | happens_phys_before_recursive (const IR::MAU::Table *t1, const IR::MAU::TableSeq *s) const |
|
bool | has_back_edge (const IR::MAU::Table *src, const IR::MAU::Table *dst) |
|
bool | has_cycle () |
|
bool | is_anti_edge (DependencyGraph::dependencies_t dep) const |
|
bool | is_ctrl_edge (DependencyGraph::dependencies_t dep) const |
|
bool | is_edge_critical (typename Graph::edge_descriptor e) const |
|
bool | is_non_directional_edge (DependencyGraph::dependencies_t dep) const |
|
int | max_stage (const IR::MAU::Table *t) const |
|
int | min_stage (const IR::MAU::Table *t) const |
|
void | print_container_access (std::ostream &out) const |
|
void | print_dep_type_map (std::ostream &out) const |
|
void | to_json (Util::JsonObject *dgJson, const FlowGraph &fg, cstring passContext, bool placed) |
|
bool | unavoidable_container_conflict (const IR::MAU::Table *t1, const IR::MAU::Table *t2) const |
|
|
ordered_map< const IR::MAU::Table *, ordered_set< const IR::MAU::Table * > > | container_conflicts |
|
std::map< const IR::MAU::Table *, std::map< const PHV::Container, bool > > | containers_read_alu_ |
|
std::map< const IR::MAU::Table *, std::map< const PHV::Container, bool > > | containers_read_xbar_ |
|
std::map< const IR::MAU::Table *, std::map< const PHV::Container, bool > > | containers_write_ = {} |
|
ordered_map< typename Graph::edge_descriptor, std::string > | ctrl_annotations |
|
ordered_map< typename Graph::edge_descriptor, ordered_map< const PHV::Field *, std::pair< ordered_set< const IR::MAU::Action * >, ordered_set< const IR::MAU::Action * > > > > | data_annotations |
|
ordered_map< typename Graph::edge_descriptor, const PHV::Container > | data_annotations_conflicts |
|
ordered_map< typename Graph::edge_descriptor, const std::vector< const IR::MAU::Action * > > | data_annotations_exit |
|
ordered_map< typename Graph::edge_descriptor, const PHV::FieldSlice * > | data_annotations_metadata |
|
ordered_map< const IR::MAU::Table *, ordered_map< const IR::MAU::Table *, dependencies_t > > | dep_type_map |
|
ordered_map< std::pair< const IR::MAU::Table *, const IR::MAU::Table * >, DependencyGraph::dependencies_t > | dependency_map |
|
bool | display_min_edges = false |
|
bool | finalized |
|
Graph | g |
|
ordered_map< const IR::MAU::Table *, std::vector< const IR::MAU::Table * > > | happens_after_work_map |
|
ordered_map< const IR::MAU::Table *, ordered_set< const IR::MAU::Table * > > | happens_before_control_map |
|
ordered_map< const IR::MAU::Table *, std::vector< const IR::MAU::Table * > > | happens_before_work_map |
|
ordered_map< const IR::MAU::Table *, ordered_set< const IR::MAU::Table * > > | happens_logi_after_map |
|
ordered_map< const IR::MAU::Table *, ordered_set< const IR::MAU::Table * > > | happens_logi_before_map |
|
ordered_map< const IR::MAU::Table *, ordered_set< const IR::MAU::Table * > > | happens_phys_after_map |
|
ordered_map< const IR::MAU::Table *, ordered_set< const IR::MAU::Table * > > | happens_phys_before_map |
|
ordered_map< const IR::MAU::Table *, typename Graph::vertex_descriptor > | labelToVertex |
|
int | max_min_stage = -1 |
|
int | max_min_stage_per_gress [3] = {-1, -1, -1} |
|
assoc::hash_map< const IR::MAU::Table *, safe_vector< MinEdgeInfo > > | min_stage_edges |
|
ordered_map< cstring, const IR::MAU::Table * > | name_to_table |
|
cstring | passContext |
|
bool | placed = false |
|
ReductionOrInfo | red_info |
|
ordered_map< const IR::MAU::Table *, StageInfo > | stage_info |
|
std::map< std::pair< const IR::MAU::Table *, const IR::MAU::Table * >, DependencyGraph::mau_dependencies_t > | table_dep_ = {} |
|
ordered_map< const IR::MAU::Table *, ordered_set< const IR::MAU::Table * > > | unavoidable_container_conflicts |
|
std::vector< ordered_set< DependencyGraph::Graph::vertex_descriptor > > | vertex_rst |
|
ordered_map<const IR::MAU::Table *, ordered_set<const IR::MAU::Table *> > DependencyGraph::container_conflicts |
A map of all tables that cannot be placed in the same stage as the key table, because they share an ALU operation over a container. The following example will indicate why this is a problem:
action a1(bit<4> x1) { hdr.data.x1 = x1; } action a2(bit<4> x2) { hdr.data.x2 = x2; }
table t1 { key = { hdr.data.f1; } actions = { a1; } default_action = a1(1); } table t2 { key = { hdr.data.f1; } actions = { a2; } default_action = a2(1); }
apply { t1.apply(); t2.apply(); }
Now let's say that hdr.data.x1 and hdr.data.x2 are in the same 8 bit PHV container, i.e. B0. In the instruction memory, a1 and a2 will have its own VLIW instruction, which itself contains an opcode for every single PHV ALU. All actions in the ALUs run in parallel, and the individual operations to each ALU are brought in as a portion of one stage VLIW instruction.
This stage VLIW instruction is formed by ORing together all actions (each of which is its own VLIW instruction) that are intended to be run in the stage. Thus if a1 and a2 were to be run in the same stage, their operations over container B0 would be ORed together. In general ORing these opcodes will lose the meaning of the original operation.
Note that the constraint does not apply if the actions themselves are mutually exclusive, i.e. if the apply statement looked like the following:
apply { if (hdr.data.f1 == 1) { t1.apply() } else { t2.apply() } }
then it would be impossible for a1 and a2 to ever be called in the same packet, and thus the opcode for B0 would never be mucked up by the OR.
However, this is not to be considered an action dependency. If t2 were action dependent on t1, then t1 would have to happen before t2. This is not the case for this program as t2 does not affect any of the values that t1 is working on. Instead it just affects the containers