P4C
The P4 Compiler
Loading...
Searching...
No Matches
DeparserCopyOpt

decaf : a deparser optimization of copy assigned fields More...

Collaboration diagram for DeparserCopyOpt:

Classes

struct  Assign
 
class  AssignChain
 
struct  CollectHeaderValidity
 
class  CollectWeakFields
 
class  ComputeValuesAtDeparser
 
class  CreateConstants
 
class  DeparserCopyOpt
 Top level PassManager. More...
 
struct  FieldGroup
 
class  RewriteDeparser
 
class  RewriteWeakFieldWrites
 
class  SynthesizePovEncoder
 
struct  Value
 
struct  VersionMap
 

Detailed Description

decaf : a deparser optimization of copy assigned fields

Copyright (C) 2024 Intel Corporation

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

SPDX-License-Identifier: Apache-2.0

author: zhao ma

The observation is that there is a high degree of data movement in many common data-plane program patterns (e.g. tunneling, label switching), i.e. a large number of fields participate in copy assignment only. These are the fields whose final value is that of another such copied only field.

Based on this observation, we devise an optimization to resolve data copies directly in the deparser rather than using the MAU to move the data, costing normal PHV containers.

Consider the program below:

 action a1() { modify_field(data.a, data.b); }
 action a2() { modify_field(data.a, 0x0800); }
 action a3() { modify_field(data.a, data.c); }
 table t1 {
     reads { data.m : exact; }
     actions { a1; a2; a3; nop; }
 }
 action a4() { modify_field(data.b, data.a); }
 action a5() { modify_field(data.b, 0x0866); }
 table t2 {
     reads { data.k : exact; }
     actions { a4; a5; nop; }
 }
 control ingress {
     apply(t1);
     apply(t2);
 }

The possible values for each field (and reaching action sequence) are:

 data.a : v0: 0x0800:   t1.a2 -> *
          v1: data.b:   t1.a1 -> *
          v2: data.c:   t1.a3 -> *
          v3: data.a:  t1.nop -> *
 data.b : v0: 0x0800:  t1.a2 -> t2.a4
          v1: 0x0866:      * -> t2.a5
          v2: data.a: t1.nop -> t2.a4
          v3: data.c:  t1.a3 -> t2.a4
          v4: data.b:  t1.a1 -> t2.nop
 data.c : data.c (read-only)

Let's assign a bit to each action, and another bit to each version for a field's final value. The function between the action bits and version bits can be represented as a truth table.

 a1  a2  a3  a4  a5 | a_v0 a_v1 a_v2 a_v3  b_v0 b_v1 b_v2 b_v3 b_v4
 -------------------------------------------------------------------
 1   0   0   0   0  | 0    1    0    0     0    0    0    0    1
 0   1   0   0   0  | 1    0    0    0     0    0    0    0    1
 0   0   1   0   0  | 0    1    0    1     0    0    0    0    1
 0   1   0   1   0  | 1    0    0    0     1    0    0    0    0
 0   0   0   0   1  | 0    0    0    1     0    1    0    0    0
   ...
   ...

Conveniently, the truth table can be implemented in Tofino as a match action table (using static entries). The version bits are wired to the FD as POV bits for the deparser to disambiguate which version to use for each field to reconstruct final packet, and with each version allocated to its own FD entry. Finally, all versions of value can be parsed into tagalong containers.

TODO

Tagalong containers, though abundant, are not unlimited. In addition, other resources also need to be managed. The list below is all resources need to be managed in the order of scarcity (most scarce to least). We need to make sure we don't over-fit any of these. Given a list of fields that can be decaf'd, we need to establish a partial order between any two fields such that one requires less resource than the other.

  1. tagalong PHV space (2k bits, half of normal PHV)
  2. POV bits (128 bits per gress)
  3. Parser constant extract (each state has 4xB, 2xH, 2xW constant extract bandwidth)
  4. Table resources (logical ID, memory)
  5. FD entries (abundant)

Class Documentation

◆ Assign

struct Assign

Public Member Functions

 Assign (const IR::MAU::Instruction *instr, const PHV::Field *dst, const IR::Constant *src)
 
 Assign (const IR::MAU::Instruction *instr, const PHV::Field *dst, const PHV::Field *src)
 
std::string print () const
 

Public Attributes

const PHV::Fielddst
 
const IR::MAU::Instruction * instr = nullptr
 
const Valuesrc
 

◆ AssignChain

class AssignChain
Inheritance diagram for AssignChain:
[legend]

Public Member Functions

bool contains (const IR::MAU::Instruction *instr) const
 
void push_front (const Assign *assign)
 

◆ CollectHeaderValidity

struct CollectHeaderValidity
Inheritance diagram for CollectHeaderValidity:
[legend]

Public Member Functions

 CollectHeaderValidity (const PhvInfo &phv)
 
void dbprint (std::ostream &out) const override
 
void end_apply () override
 
const IR::Expression * get_valid_bit_expr (const PHV::Field *f) const
 
bool preorder (const IR::BFN::Emit *emit) override
 
bool preorder (const IR::MAU::Instruction *instr) override
 
- Public Member Functions inherited from P4::Inspector
const IR::Nodeapply_visitor (const IR::Node *, const char *name=0) override
 
profile_t init_apply (const IR::Node *root) override
 
virtual void loop_revisit (const IR::Node *)
 
virtual void postorder (const IR::Node *)
 
virtual bool preorder (const IR::Node *)
 
virtual void revisit (const IR::Node *)
 
void revisit_visited ()
 
bool visit_in_progress (const IR::Node *n) const
 
void visitAgain () const override
 
void visitOnce () const override
 
- Public Member Functions inherited from P4::Visitor
virtual bool check_global (cstring)
 
virtual void clear_globals ()
 
virtual Visitorclone () const
 
virtual ControlFlowVisitorcontrolFlowVisitor ()
 
virtual void end_apply (const IR::Node *root)
 
virtual void erase_global (cstring)
 
template<class T >
const T * findContext () const
 
template<class T >
const T * findContext (const Context *&c) const
 
template<class T >
const T * findOrigCtxt () const
 
template<class T >
const T * findOrigCtxt (const Context *&c) const
 
virtual Visitorflow_clone ()
 
virtual void flow_merge (Visitor &)
 
virtual bool flow_merge_closure (Visitor &)
 
virtual void flow_merge_global_from (cstring)
 
virtual void flow_merge_global_to (cstring)
 
const ContextgetChildContext () const
 
int getChildrenVisited () const
 
const ContextgetContext () const
 
int getContextDepth () const
 
const IR::NodegetCurrentNode () const
 
template<class T >
const T * getCurrentNode () const
 
const IR::NodegetOriginal () const
 
template<class T >
const T * getOriginal () const
 
template<class T >
const T * getParent () const
 
virtual bool has_flow_joins () const
 
profile_t init_apply (const IR::Node *root, const Context *parent_context)
 
bool isInContext (const IR::Node *n) const
 
virtual const char * name () const
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name=0)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name=0)
 
void print_context () const
 
const VisitorsetCalledBy (const Visitor *visitor)
 
void setName (const char *name)
 
void visit (const IR::Node &n, const char *name, int cidx)
 
void visit (const IR::Node &n, const char *name=0)
 
void visit (const IR::Node *&n, const char *name, int cidx)
 
void visit (const IR::Node *&n, const char *name=0)
 
void visit (const IR::Node *const &n, const char *name, int cidx)
 
void visit (const IR::Node *const &n, const char *name=0)
 
void visit (IR::Node &n, const char *name, int cidx)
 
void visit (IR::Node &n, const char *name=0)
 
void visit (IR::Node *&, const char *=0, int=0)
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>, class... Args>
void warn (const int kind, const char *format, const T &node, Args &&...args)
 The const ref variant of the above.
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
void warn (const int kind, const char *format, const T *node, Args &&...args)
 
bool warning_enabled (int warning_kind) const
 
- Public Member Functions inherited from P4::IHasDbPrint
void print () const
 

Public Attributes

assoc::map< const PHV::Field *, const IR::Expression * > field_to_expr
 
ordered_map< const PHV::Field *, const PHV::Field * > field_to_valid_bit
 
assoc::map< const PHV::Field *, ordered_set< const IR::MAU::Action * > > invalidate_to_action
 
const PhvInfophv
 
assoc::map< const PHV::Field *, ordered_set< const IR::MAU::Action * > > validate_to_action
 
assoc::map< const PHV::Field *, ordered_set< const IR::BFN::ParserState * > > validate_to_extract
 
- Public Attributes inherited from P4::Visitor
const Visitorcalled_by = nullptr
 
cstring internalName
 
SplitFlowVisit_base *& split_link
 
SplitFlowVisit_basesplit_link_mem = nullptr
 

Additional Inherited Members

- Public Types inherited from P4::Visitor
typedef Visitor_Context Context
 
- Static Public Member Functions inherited from P4::Visitor
static cstring demangle (const char *)
 
static bool warning_enabled (const Visitor *visitor, int warning_kind)
 
- Protected Member Functions inherited from P4::Visitor
virtual void init_join_flows (const IR::Node *)
 
virtual bool join_flows (const IR::Node *)
 
virtual void post_join_flows (const IR::Node *, const IR::Node *)
 
void visit_children (const IR::Node *, std::function< void()> fn)
 
- Protected Attributes inherited from P4::Visitor
bool dontForwardChildrenBeforePreorder = false
 
bool joinFlows = false
 
bool visitDagOnce = true
 

Member Function Documentation

◆ dbprint()

void CollectHeaderValidity::dbprint ( std::ostream & out) const
inlineoverridevirtual

Implements P4::IHasDbPrint.

◆ end_apply()

void CollectHeaderValidity::end_apply ( )
inlineoverridevirtual

Reimplemented from P4::Visitor.

◆ CollectWeakFields

class CollectWeakFields

We categorize fields that are referenced in the control flow as either strong or weak. The strong fields are ones that participate in match, non-move instruction, action data bus read, or other reasons (non packet defs, is part of a checksum update or digest). The weak fields are, by exclusion, the ones that are not strong. Weak fields also shall not have a transitive strong source. All weak fields are then decaf candidates.

Inheritance diagram for CollectWeakFields:
[legend]

Public Member Functions

 CollectWeakFields (const PhvInfo &phv, const PhvUse &uses, const FieldDefUse &defuse, const DependencyGraph &dg)
 
void dbprint (std::ostream &out) const override
 
const IR::MAU::Action * get_action (const Assign *assign) const
 
const IR::MAU::Table * get_table (const Assign *assign) const
 
std::string print_assign (const Assign *assign) const
 
std::string print_assign_context (const Assign *assign) const
 
void remove_weak_field (const PHV::Field *field)
 
- Public Member Functions inherited from P4::Inspector
const IR::Nodeapply_visitor (const IR::Node *, const char *name=0) override
 
profile_t init_apply (const IR::Node *root) override
 
virtual void loop_revisit (const IR::Node *)
 
virtual void postorder (const IR::Node *)
 
virtual bool preorder (const IR::Node *)
 
virtual void revisit (const IR::Node *)
 
void revisit_visited ()
 
bool visit_in_progress (const IR::Node *n) const
 
void visitAgain () const override
 
void visitOnce () const override
 
- Public Member Functions inherited from P4::Visitor
virtual void end_apply (const IR::Node *root)
 
template<class T >
const T * findContext () const
 
template<class T >
const T * findContext (const Context *&c) const
 
template<class T >
const T * findOrigCtxt () const
 
template<class T >
const T * findOrigCtxt (const Context *&c) const
 
virtual bool flow_merge_closure (Visitor &)
 
const ContextgetChildContext () const
 
int getChildrenVisited () const
 
const ContextgetContext () const
 
int getContextDepth () const
 
const IR::NodegetCurrentNode () const
 
template<class T >
const T * getCurrentNode () const
 
const IR::NodegetOriginal () const
 
template<class T >
const T * getOriginal () const
 
template<class T >
const T * getParent () const
 
profile_t init_apply (const IR::Node *root, const Context *parent_context)
 
bool isInContext (const IR::Node *n) const
 
virtual const char * name () const
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name=0)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name=0)
 
void print_context () const
 
const VisitorsetCalledBy (const Visitor *visitor)
 
void setName (const char *name)
 
void visit (const IR::Node &n, const char *name, int cidx)
 
void visit (const IR::Node &n, const char *name=0)
 
void visit (const IR::Node *&n, const char *name, int cidx)
 
void visit (const IR::Node *&n, const char *name=0)
 
void visit (const IR::Node *const &n, const char *name, int cidx)
 
void visit (const IR::Node *const &n, const char *name=0)
 
void visit (IR::Node &n, const char *name, int cidx)
 
void visit (IR::Node &n, const char *name=0)
 
void visit (IR::Node *&, const char *=0, int=0)
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>, class... Args>
void warn (const int kind, const char *format, const T &node, Args &&...args)
 The const ref variant of the above.
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
void warn (const int kind, const char *format, const T *node, Args &&...args)
 
bool warning_enabled (int warning_kind) const
 

Public Attributes

std::map< gress_t, ordered_set< const IR::Constant * > > all_constants
 
ordered_map< const PHV::Field *, ordered_set< const Assign * > > field_to_weak_assigns
 
FieldGroup read_only_weak_fields
 
- Public Attributes inherited from P4::Visitor
const Visitorcalled_by = nullptr
 
cstring internalName
 
SplitFlowVisit_base *& split_link
 
SplitFlowVisit_basesplit_link_mem = nullptr
 

Additional Inherited Members

- Public Types inherited from P4::Visitor
typedef Visitor_Context Context
 
- Static Public Member Functions inherited from P4::Visitor
static cstring demangle (const char *)
 
static bool warning_enabled (const Visitor *visitor, int warning_kind)
 
- Protected Member Functions inherited from P4::Visitor
void visit_children (const IR::Node *, std::function< void()> fn)
 
- Protected Attributes inherited from P4::Visitor
bool dontForwardChildrenBeforePreorder = false
 
bool joinFlows = false
 
bool visitDagOnce = true
 

Member Function Documentation

◆ dbprint()

void CollectWeakFields::dbprint ( std::ostream & out) const
overridevirtual

Implements P4::IHasDbPrint.

◆ ComputeValuesAtDeparser

class ComputeValuesAtDeparser

Perform copy/constant propagation for the weak fields on table dependency. For each weak field, what are the all possible values that are reachable at the deparser?

Inheritance diagram for ComputeValuesAtDeparser:
[legend]

Public Member Functions

 ComputeValuesAtDeparser (CollectWeakFields &weak_fields)
 
bool is_weak_assign (const IR::MAU::Instruction *instr) const
 
std::string print_assign_chain (const AssignChain &chain) const
 
std::string print_assign_chains (const ordered_set< AssignChain > &chains) const
 
std::string print_value_map (const FieldGroup &weak_field_group, const ordered_set< AssignChain > &all_chains_in_group) const
 
- Public Member Functions inherited from P4::Inspector
const IR::Nodeapply_visitor (const IR::Node *, const char *name=0) override
 
profile_t init_apply (const IR::Node *root) override
 
virtual void loop_revisit (const IR::Node *)
 
virtual void postorder (const IR::Node *)
 
virtual bool preorder (const IR::Node *)
 
virtual void revisit (const IR::Node *)
 
void revisit_visited ()
 
bool visit_in_progress (const IR::Node *n) const
 
void visitAgain () const override
 
void visitOnce () const override
 
- Public Member Functions inherited from P4::Visitor
virtual bool check_global (cstring)
 
virtual void clear_globals ()
 
virtual Visitorclone () const
 
virtual ControlFlowVisitorcontrolFlowVisitor ()
 
virtual void end_apply ()
 
virtual void end_apply (const IR::Node *root)
 
virtual void erase_global (cstring)
 
template<class T >
const T * findContext () const
 
template<class T >
const T * findContext (const Context *&c) const
 
template<class T >
const T * findOrigCtxt () const
 
template<class T >
const T * findOrigCtxt (const Context *&c) const
 
virtual Visitorflow_clone ()
 
virtual void flow_merge (Visitor &)
 
virtual bool flow_merge_closure (Visitor &)
 
virtual void flow_merge_global_from (cstring)
 
virtual void flow_merge_global_to (cstring)
 
const ContextgetChildContext () const
 
int getChildrenVisited () const
 
const ContextgetContext () const
 
int getContextDepth () const
 
const IR::NodegetCurrentNode () const
 
template<class T >
const T * getCurrentNode () const
 
const IR::NodegetOriginal () const
 
template<class T >
const T * getOriginal () const
 
template<class T >
const T * getParent () const
 
virtual bool has_flow_joins () const
 
profile_t init_apply (const IR::Node *root, const Context *parent_context)
 
bool isInContext (const IR::Node *n) const
 
virtual const char * name () const
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name=0)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name=0)
 
void print_context () const
 
const VisitorsetCalledBy (const Visitor *visitor)
 
void setName (const char *name)
 
void visit (const IR::Node &n, const char *name, int cidx)
 
void visit (const IR::Node &n, const char *name=0)
 
void visit (const IR::Node *&n, const char *name, int cidx)
 
void visit (const IR::Node *&n, const char *name=0)
 
void visit (const IR::Node *const &n, const char *name, int cidx)
 
void visit (const IR::Node *const &n, const char *name=0)
 
void visit (IR::Node &n, const char *name, int cidx)
 
void visit (IR::Node &n, const char *name=0)
 
void visit (IR::Node *&, const char *=0, int=0)
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>, class... Args>
void warn (const int kind, const char *format, const T &node, Args &&...args)
 The const ref variant of the above.
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
void warn (const int kind, const char *format, const T *node, Args &&...args)
 
bool warning_enabled (int warning_kind) const
 

Public Attributes

ordered_map< const PHV::Field *, ordered_map< Value, ordered_set< AssignChain > > > value_to_chains
 
std::vector< FieldGroupweak_field_groups
 
CollectWeakFieldsweak_fields
 
- Public Attributes inherited from P4::Visitor
const Visitorcalled_by = nullptr
 
cstring internalName
 
SplitFlowVisit_base *& split_link
 
SplitFlowVisit_basesplit_link_mem = nullptr
 

Additional Inherited Members

- Public Types inherited from P4::Visitor
typedef Visitor_Context Context
 
- Static Public Member Functions inherited from P4::Visitor
static cstring demangle (const char *)
 
static bool warning_enabled (const Visitor *visitor, int warning_kind)
 
- Protected Member Functions inherited from P4::Visitor
virtual void init_join_flows (const IR::Node *)
 
virtual bool join_flows (const IR::Node *)
 
virtual void post_join_flows (const IR::Node *, const IR::Node *)
 
void visit_children (const IR::Node *, std::function< void()> fn)
 
- Protected Attributes inherited from P4::Visitor
bool dontForwardChildrenBeforePreorder = false
 
bool joinFlows = false
 
bool visitDagOnce = true
 

◆ CreateConstants

class CreateConstants

Certain weak fields may have constant values. These constants need to be extracted by the parser in Tofino. In JBay, the deparser comes with 8 bytes of constants we can use, the rest still need to be extracted in the parser.

Inheritance diagram for CreateConstants:
[legend]

Public Member Functions

 CreateConstants (const ComputeValuesAtDeparser &values_at_deparser)
 
void dbprint (std::ostream &out) const override
 
bool is_inserted (const IR::TempVar *constant) const
 

Public Attributes

std::map< gress_t, ordered_map< uint8_t, const IR::TempVar * > > byte_to_temp_var
 
std::map< gress_t, ordered_map< const IR::Constant *, std::vector< uint8_t > > > const_to_bytes
 
std::map< gress_t, ordered_set< uint8_t > > deparser_bytes
 

Member Function Documentation

◆ dbprint()

void CreateConstants::dbprint ( std::ostream & out) const
overridevirtual

Implements P4::IHasDbPrint.

◆ DeparserCopyOpt

class DeparserCopyOpt

Top level PassManager.

Inheritance diagram for DeparserCopyOpt:
[legend]

Public Member Functions

 DeparserCopyOpt (const PhvInfo &phv, PhvUse &uses, const FieldDefUse &defuse, const DependencyGraph &dg)
 
- Public Member Functions inherited from Logging::PassManager
 PassManager (cstring logFilePrefix, Logging::Mode logMode=Logging::Mode::CREATE)
 
- Public Member Functions inherited from P4::PassManager
 PassManager (const PassManager &)=default
 
 PassManager (const std::initializer_list< VisitorRef > &init)
 
 PassManager (PassManager &&)=default
 
void addDebugHook (DebugHook h, bool recursive=false)
 
void addDebugHooks (std::vector< DebugHook > hooks, bool recursive=false)
 
void addPasses (const std::initializer_list< VisitorRef > &init)
 
const IR::Nodeapply_visitor (const IR::Node *, const char *=0) override
 
bool backtrack (trigger &trig) override
 
PassManagerclone () const override
 
void early_exit ()
 
void listPasses (std::ostream &, cstring sep) const
 
bool never_backtracks () override
 
void removePasses (const std::vector< cstring > &exclude)
 
void setStopOnError (bool stop)
 
- Public Member Functions inherited from P4::Visitor
virtual bool check_clone (const Visitor *a)
 
virtual bool check_global (cstring)
 
virtual void clear_globals ()
 
virtual ControlFlowVisitorcontrolFlowVisitor ()
 
virtual void end_apply (const IR::Node *root)
 
virtual void erase_global (cstring)
 
template<class T >
const T * findContext () const
 
template<class T >
const T * findContext (const Context *&c) const
 
template<class T >
const T * findOrigCtxt () const
 
template<class T >
const T * findOrigCtxt (const Context *&c) const
 
virtual Visitorflow_clone ()
 
virtual void flow_merge (Visitor &)
 
virtual bool flow_merge_closure (Visitor &)
 
virtual void flow_merge_global_from (cstring)
 
virtual void flow_merge_global_to (cstring)
 
const ContextgetChildContext () const
 
int getChildrenVisited () const
 
const ContextgetContext () const
 
int getContextDepth () const
 
const IR::NodegetCurrentNode () const
 
template<class T >
const T * getCurrentNode () const
 
const IR::NodegetOriginal () const
 
template<class T >
const T * getOriginal () const
 
template<class T >
const T * getParent () const
 
virtual bool has_flow_joins () const
 
profile_t init_apply (const IR::Node *root, const Context *parent_context)
 
bool isInContext (const IR::Node *n) const
 
virtual const char * name () const
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name=0)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name=0)
 
void print_context () const
 
const VisitorsetCalledBy (const Visitor *visitor)
 
void setName (const char *name)
 
void visit (const IR::Node &n, const char *name, int cidx)
 
void visit (const IR::Node &n, const char *name=0)
 
void visit (const IR::Node *&n, const char *name, int cidx)
 
void visit (const IR::Node *&n, const char *name=0)
 
void visit (const IR::Node *const &n, const char *name, int cidx)
 
void visit (const IR::Node *const &n, const char *name=0)
 
void visit (IR::Node &n, const char *name, int cidx)
 
void visit (IR::Node &n, const char *name=0)
 
void visit (IR::Node *&, const char *=0, int=0)
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>, class... Args>
void warn (const int kind, const char *format, const T &node, Args &&...args)
 The const ref variant of the above.
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
void warn (const int kind, const char *format, const T *node, Args &&...args)
 
bool warning_enabled (int warning_kind) const
 
- Public Member Functions inherited from P4::Backtrack

Public Attributes

RewriteDeparser rewrite_deparser
 
- Public Attributes inherited from P4::Visitor
const Visitorcalled_by = nullptr
 
cstring internalName
 
SplitFlowVisit_base *& split_link
 
SplitFlowVisit_basesplit_link_mem = nullptr
 

Additional Inherited Members

- Public Types inherited from P4::Visitor
typedef Visitor_Context Context
 
- Static Public Member Functions inherited from Logging::PassManager
static cstring getNewLogFileName (const cstring &prefix)
 
- Static Public Member Functions inherited from P4::Visitor
static cstring demangle (const char *)
 
static bool warning_enabled (const Visitor *visitor, int warning_kind)
 
- Protected Member Functions inherited from Logging::PassManager
void end_apply () override
 
profile_t init_apply (const IR::Node *root) override
 
- Protected Member Functions inherited from P4::PassManager
profile_t init_apply (const IR::Node *root) override
 
void runDebugHooks (const char *visitorName, const IR::Node *node)
 
- Protected Member Functions inherited from P4::Visitor
virtual void init_join_flows (const IR::Node *)
 
virtual bool join_flows (const IR::Node *)
 
virtual void post_join_flows (const IR::Node *, const IR::Node *)
 
void visit_children (const IR::Node *, std::function< void()> fn)
 
virtual void visitAgain () const
 
virtual void visitOnce () const
 
- Protected Attributes inherited from Logging::PassManager
Logging::FileLog_logFile
 
cstring _logFilePrefix
 
Logging::Mode _logMode
 
- Protected Attributes inherited from P4::PassManager
safe_vector< DebugHookdebugHooks
 
safe_vector< Visitor * > passes
 
bool running = false
 
unsigned seqNo = 0
 
bool stop_on_error = true
 
- Protected Attributes inherited from P4::Visitor
bool dontForwardChildrenBeforePreorder = false
 
bool joinFlows = false
 
bool visitDagOnce = true
 
- Static Protected Attributes inherited from Logging::PassManager
static int invocationCount = -1
 

◆ FieldGroup

struct FieldGroup
Inheritance diagram for FieldGroup:
[legend]

Public Member Functions

 FieldGroup (int i)
 
- Public Member Functions inherited from P4::ordered_set< const PHV::Field * >
 ordered_set (const ordered_set &a)
 
 ordered_set (InputIt first, InputIt last)
 
 ordered_set (ordered_set &&a)=default
 
 ordered_set (std::initializer_list< const PHV::Field * > init)
 
reference back () const noexcept
 
const_iterator begin () const noexcept
 
iterator begin () noexcept
 
const_iterator cbegin () const noexcept
 
const_iterator cend () const noexcept
 
void clear ()
 
size_type count (const const PHV::Field *&a) const
 
const_reverse_iterator crbegin () const noexcept
 
const_reverse_iterator crend () const noexcept
 
std::pair< iterator, bool > emplace (Args &&...args)
 
std::pair< iterator, bool > emplace_back (Args &&...args)
 
bool empty () const noexcept
 
const_iterator end () const noexcept
 
iterator end () noexcept
 
size_type erase (const const PHV::Field *&v)
 
iterator erase (const_iterator pos)
 
iterator find (const const PHV::Field *&a)
 
const_iterator find (const const PHV::Field *&a) const
 
reference front () const noexcept
 
std::pair< iterator, bool > insert (const const PHV::Field *&v)
 
std::pair< iterator, bool > insert (const PHV::Field *&&v)
 
iterator insert (const_iterator pos, const const PHV::Field *&v)
 
iterator insert (const_iterator pos, const PHV::Field *&&v)
 
void insert (ordered_set::const_iterator begin, ordered_set::const_iterator end)
 
iterator lower_bound (const const PHV::Field *&a)
 
const_iterator lower_bound (const const PHV::Field *&a) const
 
size_type max_size () const noexcept
 
bool operator!= (const ordered_set &a) const
 
bool operator< (const ordered_set &a) const
 
ordered_setoperator= (const ordered_set &a)
 
ordered_setoperator= (ordered_set &&a)=default
 
bool operator== (const ordered_set &a) const
 
void push_back (const const PHV::Field *&v)
 
void push_back (const PHV::Field *&&v)
 
const_reverse_iterator rbegin () const noexcept
 
reverse_iterator rbegin () noexcept
 
const_reverse_iterator rend () const noexcept
 
reverse_iterator rend () noexcept
 
size_type size () const noexcept
 
sorted_iterator sorted_begin () const noexcept
 
sorted_iterator sorted_end () const noexcept
 
iterator upper_bound (const const PHV::Field *&a)
 
const_iterator upper_bound (const const PHV::Field *&a) const
 

Public Attributes

int id = -1
 

Additional Inherited Members

- Public Types inherited from P4::ordered_set< const PHV::Field * >
typedef std::allocator< const PHV::Field * > allocator_type
 
typedef list_type::const_iterator const_iterator
 
typedef const const PHV::Field *& const_reference
 
typedef std::reverse_iterator< const_iterator > const_reverse_iterator
 
typedef list_type::const_iterator iterator
 
typedef std::less< const PHV::Field * > key_compare
 
typedef const PHV::Fieldkey_type
 
typedef const const PHV::Field *& reference
 
typedef std::reverse_iterator< iterator > reverse_iterator
 
typedef map_type::size_type size_type
 
typedef std::less< const PHV::Field * > value_compare
 
typedef const PHV::Fieldvalue_type
 

◆ RewriteDeparser

class RewriteDeparser

Rewrite deparser to insert new emits created for each of the weak field's reachable value at the deparser. Each value emit is predicated by the synthesized POV bit created in the SynthesizePovEncoder pass.

Inheritance diagram for RewriteDeparser:
[legend]

Public Member Functions

 RewriteDeparser (const PhvInfo &phv, const SynthesizePovEncoder &synth_pov_encoder, const CreateConstants &create_consts)
 

Public Attributes

ordered_set< cstringmust_split_fields
 

◆ RewriteWeakFieldWrites

class RewriteWeakFieldWrites

Replace all move instructions that weak fields are involved in by a single bit set to the $ctl bits for each action that the move instructions are in. Typically, these are the tunnel encap/decap actions.

Inheritance diagram for RewriteWeakFieldWrites:
[legend]

Public Member Functions

 RewriteWeakFieldWrites (const ComputeValuesAtDeparser &values_at_deparser, const SynthesizePovEncoder &synth_pov_encoder)
 
- Public Member Functions inherited from P4::Transform
const IR::Nodeapply_visitor (const IR::Node *, const char *name=0) override
 
profile_t init_apply (const IR::Node *root) override
 
virtual void loop_revisit (const IR::Node *)
 
virtual const IR::Nodepostorder (IR::Node *n)
 
virtual const IR::Nodepreorder (IR::Node *n)
 
void prune ()
 
virtual void revisit (const IR::Node *, const IR::Node *)
 
void revisit_visited ()
 
bool visit_in_progress (const IR::Node *) const
 
void visitAgain () const override
 
void visitOnce () const override
 
- Public Member Functions inherited from P4::Visitor
virtual bool check_global (cstring)
 
virtual void clear_globals ()
 
virtual Visitorclone () const
 
virtual ControlFlowVisitorcontrolFlowVisitor ()
 
virtual void end_apply (const IR::Node *root)
 
virtual void erase_global (cstring)
 
template<class T >
const T * findContext () const
 
template<class T >
const T * findContext (const Context *&c) const
 
template<class T >
const T * findOrigCtxt () const
 
template<class T >
const T * findOrigCtxt (const Context *&c) const
 
virtual Visitorflow_clone ()
 
virtual void flow_merge (Visitor &)
 
virtual bool flow_merge_closure (Visitor &)
 
virtual void flow_merge_global_from (cstring)
 
virtual void flow_merge_global_to (cstring)
 
const ContextgetChildContext () const
 
int getChildrenVisited () const
 
const ContextgetContext () const
 
int getContextDepth () const
 
const IR::NodegetCurrentNode () const
 
template<class T >
const T * getCurrentNode () const
 
const IR::NodegetOriginal () const
 
template<class T >
const T * getOriginal () const
 
template<class T >
const T * getParent () const
 
virtual bool has_flow_joins () const
 
profile_t init_apply (const IR::Node *root, const Context *parent_context)
 
bool isInContext (const IR::Node *n) const
 
virtual const char * name () const
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name=0)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name=0)
 
void print_context () const
 
const VisitorsetCalledBy (const Visitor *visitor)
 
void setName (const char *name)
 
void visit (const IR::Node &n, const char *name, int cidx)
 
void visit (const IR::Node &n, const char *name=0)
 
void visit (const IR::Node *&n, const char *name, int cidx)
 
void visit (const IR::Node *&n, const char *name=0)
 
void visit (const IR::Node *const &n, const char *name, int cidx)
 
void visit (const IR::Node *const &n, const char *name=0)
 
void visit (IR::Node &n, const char *name, int cidx)
 
void visit (IR::Node &n, const char *name=0)
 
void visit (IR::Node *&, const char *=0, int=0)
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>, class... Args>
void warn (const int kind, const char *format, const T &node, Args &&...args)
 The const ref variant of the above.
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
void warn (const int kind, const char *format, const T *node, Args &&...args)
 
bool warning_enabled (int warning_kind) const
 

Additional Inherited Members

- Public Types inherited from P4::Visitor
typedef Visitor_Context Context
 
- Static Public Member Functions inherited from P4::Visitor
static cstring demangle (const char *)
 
static bool warning_enabled (const Visitor *visitor, int warning_kind)
 
- Public Attributes inherited from P4::Visitor
const Visitorcalled_by = nullptr
 
cstring internalName
 
SplitFlowVisit_base *& split_link
 
SplitFlowVisit_basesplit_link_mem = nullptr
 
- Protected Member Functions inherited from P4::Transform
const IR::Nodetransform_child (const IR::Node *child)
 
- Protected Member Functions inherited from P4::Visitor
virtual void init_join_flows (const IR::Node *)
 
virtual bool join_flows (const IR::Node *)
 
virtual void post_join_flows (const IR::Node *, const IR::Node *)
 
void visit_children (const IR::Node *, std::function< void()> fn)
 
- Protected Attributes inherited from P4::Transform
bool forceClone = false
 
- Protected Attributes inherited from P4::Visitor
bool dontForwardChildrenBeforePreorder = false
 
bool joinFlows = false
 
bool visitDagOnce = true
 

◆ SynthesizePovEncoder

class SynthesizePovEncoder

Given a set of weak fields, and their reaching values/action chains at the deparser, we construct tables to synthesize the POV bits needed to deparse the right version at runtime.

Inheritance diagram for SynthesizePovEncoder:
[legend]

Public Member Functions

 SynthesizePovEncoder (const CollectHeaderValidity &pov_bits, const ComputeValuesAtDeparser &values_at_deparser)
 
void dbprint (std::ostream &out) const override
 
- Public Member Functions inherited from P4::Transform
const IR::Nodeapply_visitor (const IR::Node *, const char *name=0) override
 
profile_t init_apply (const IR::Node *root) override
 
virtual void loop_revisit (const IR::Node *)
 
virtual const IR::Nodepostorder (IR::Node *n)
 
virtual const IR::Nodepreorder (IR::Node *n)
 
void prune ()
 
virtual void revisit (const IR::Node *, const IR::Node *)
 
void revisit_visited ()
 
bool visit_in_progress (const IR::Node *) const
 
void visitAgain () const override
 
void visitOnce () const override
 
- Public Member Functions inherited from P4::Visitor
virtual bool check_global (cstring)
 
virtual void clear_globals ()
 
virtual Visitorclone () const
 
virtual ControlFlowVisitorcontrolFlowVisitor ()
 
virtual void end_apply (const IR::Node *root)
 
virtual void erase_global (cstring)
 
template<class T >
const T * findContext () const
 
template<class T >
const T * findContext (const Context *&c) const
 
template<class T >
const T * findOrigCtxt () const
 
template<class T >
const T * findOrigCtxt (const Context *&c) const
 
virtual Visitorflow_clone ()
 
virtual void flow_merge (Visitor &)
 
virtual bool flow_merge_closure (Visitor &)
 
virtual void flow_merge_global_from (cstring)
 
virtual void flow_merge_global_to (cstring)
 
const ContextgetChildContext () const
 
int getChildrenVisited () const
 
const ContextgetContext () const
 
int getContextDepth () const
 
const IR::NodegetCurrentNode () const
 
template<class T >
const T * getCurrentNode () const
 
const IR::NodegetOriginal () const
 
template<class T >
const T * getOriginal () const
 
template<class T >
const T * getParent () const
 
virtual bool has_flow_joins () const
 
profile_t init_apply (const IR::Node *root, const Context *parent_context)
 
bool isInContext (const IR::Node *n) const
 
virtual const char * name () const
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (const IR::Vector< T > &v, const char *name=0)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name, int cidx)
 
template<class T >
void parallel_visit (IR::Vector< T > &v, const char *name=0)
 
void print_context () const
 
const VisitorsetCalledBy (const Visitor *visitor)
 
void setName (const char *name)
 
void visit (const IR::Node &n, const char *name, int cidx)
 
void visit (const IR::Node &n, const char *name=0)
 
void visit (const IR::Node *&n, const char *name, int cidx)
 
void visit (const IR::Node *&n, const char *name=0)
 
void visit (const IR::Node *const &n, const char *name, int cidx)
 
void visit (const IR::Node *const &n, const char *name=0)
 
void visit (IR::Node &n, const char *name, int cidx)
 
void visit (IR::Node &n, const char *name=0)
 
void visit (IR::Node *&, const char *=0, int=0)
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T> && !std::is_pointer_v<T>>, class... Args>
void warn (const int kind, const char *format, const T &node, Args &&...args)
 The const ref variant of the above.
 
template<class T , typename = std::enable_if_t<Util::has_SourceInfo_v<T>>, class... Args>
void warn (const int kind, const char *format, const T *node, Args &&...args)
 
bool warning_enabled (int warning_kind) const
 

Public Attributes

ordered_map< const IR::MAU::Action *, const IR::TempVar * > action_to_ctl_bit
 
ordered_map< const IR::MAU::Instruction *, const IR::TempVar * > assign_to_version_bit
 
ordered_map< const PHV::Field *, const IR::TempVar * > default_pov_bit
 
ordered_map< const PHV::Field *, ordered_map< Value, const IR::TempVar * > > value_to_pov_bit
 
- Public Attributes inherited from P4::Visitor
const Visitorcalled_by = nullptr
 
cstring internalName
 
SplitFlowVisit_base *& split_link
 
SplitFlowVisit_basesplit_link_mem = nullptr
 

Additional Inherited Members

- Public Types inherited from P4::Visitor
typedef Visitor_Context Context
 
- Static Public Member Functions inherited from P4::Visitor
static cstring demangle (const char *)
 
static bool warning_enabled (const Visitor *visitor, int warning_kind)
 
- Protected Member Functions inherited from P4::Transform
const IR::Nodetransform_child (const IR::Node *child)
 
- Protected Member Functions inherited from P4::Visitor
virtual void init_join_flows (const IR::Node *)
 
virtual bool join_flows (const IR::Node *)
 
virtual void post_join_flows (const IR::Node *, const IR::Node *)
 
void visit_children (const IR::Node *, std::function< void()> fn)
 
- Protected Attributes inherited from P4::Transform
bool forceClone = false
 
- Protected Attributes inherited from P4::Visitor
bool dontForwardChildrenBeforePreorder = false
 
bool joinFlows = false
 
bool visitDagOnce = true
 

Member Function Documentation

◆ dbprint()

void SynthesizePovEncoder::dbprint ( std::ostream & out) const
overridevirtual

Implements P4::IHasDbPrint.

◆ Value

struct Value

Public Member Functions

 Value (const IR::Constant *c)
 
 Value (const PHV::Field *f)
 
 Value (const Value &other)
 
bool operator< (const Value &other) const
 
Valueoperator= (const Value &other)
 
bool operator== (const Value &other) const
 
std::string print () const
 

Public Attributes

const IR::Constant * constant = nullptr
 
const PHV::Fieldfield = nullptr
 

◆ VersionMap

struct VersionMap

Public Member Functions

ordered_set< const IR::TempVar * > get_all_version_bits () const
 

Public Attributes

ordered_map< const PHV::Field *, const IR::TempVar * > default_version
 
ordered_map< const PHV::Field *, ordered_map< Value, const IR::TempVar * > > value_to_version