decaf : a deparser optimization of copy assigned fields
More...
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.
tagalong PHV space (2k bits, half of normal PHV)
POV bits (128 bits per gress)
Parser constant extract (each state has 4xB, 2xH, 2xW constant extract bandwidth)
Table resources (logical ID, memory)
FD entries (abundant)
◆ 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::Field * dst
const IR::MAU::Instruction * instr = nullptr
const Value * src
◆ AssignChain
Public Member Functions
bool contains (const IR::MAU::Instruction *instr) const
void push_front (const Assign *assign)
◆ CollectHeaderValidity
struct CollectHeaderValidity
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
const IR::Node * apply_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
virtual bool check_global (cstring )
virtual void clear_globals ()
virtual Visitor * clone () const
virtual ControlFlowVisitor * controlFlowVisitor ()
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 Visitor & flow_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 Context * getChildContext () const
int getChildrenVisited () const
const Context * getContext () const
int getContextDepth () const
const IR::Node * getCurrentNode () const
template<class T>
const T * getCurrentNode () const
const IR::Node * getOriginal () 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)
template<class T>
bool isInContext () const
template<class T>
bool isInContext (const Context *&c) const
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 Visitor & setCalledBy (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
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 PhvInfo & phv
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
const Visitor * called_by = nullptr
cstring internalName
SplitFlowVisit_base *& split_link
SplitFlowVisit_base * split_link_mem = nullptr
◆ dbprint()
void CollectHeaderValidity::dbprint
(
std::ostream & out )
const
inline override virtual
◆ end_apply()
void CollectHeaderValidity::end_apply
(
)
inline override virtual
◆ 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.
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)
const IR::Node * apply_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
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 Context * getChildContext () const
int getChildrenVisited () const
const Context * getContext () const
int getContextDepth () const
const IR::Node * getCurrentNode () const
template<class T>
const T * getCurrentNode () const
const IR::Node * getOriginal () 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)
template<class T>
bool isInContext () const
template<class T>
bool isInContext (const Context *&c) const
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 Visitor & setCalledBy (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
const Visitor * called_by = nullptr
cstring internalName
SplitFlowVisit_base *& split_link
SplitFlowVisit_base * split_link_mem = nullptr
typedef Visitor_Context Context
static cstring demangle (const char *)
static bool warning_enabled (const Visitor *visitor, int warning_kind)
void visit_children (const IR::Node *, std::function< void()> fn)
bool dontForwardChildrenBeforePreorder = false
bool joinFlows = false
bool visitDagOnce = true
◆ dbprint()
void CollectWeakFields::dbprint
(
std::ostream & out )
const
override virtual
◆ 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?
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
const IR::Node * apply_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
virtual bool check_global (cstring )
virtual void clear_globals ()
virtual Visitor * clone () const
virtual ControlFlowVisitor * controlFlowVisitor ()
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 Visitor & flow_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 Context * getChildContext () const
int getChildrenVisited () const
const Context * getContext () const
int getContextDepth () const
const IR::Node * getCurrentNode () const
template<class T>
const T * getCurrentNode () const
const IR::Node * getOriginal () 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)
template<class T>
bool isInContext () const
template<class T>
bool isInContext (const Context *&c) const
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 Visitor & setCalledBy (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< FieldGroup > weak_field_groups
CollectWeakFields & weak_fields
const Visitor * called_by = nullptr
cstring internalName
SplitFlowVisit_base *& split_link
SplitFlowVisit_base * split_link_mem = nullptr
◆ 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.
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
◆ dbprint()
void CreateConstants::dbprint
(
std::ostream & out )
const
override virtual
◆ DeparserCopyOpt
Public Member Functions
DeparserCopyOpt (const PhvInfo &phv, PhvUse &uses, const FieldDefUse &defuse, const DependencyGraph &dg)
PassManager (cstring logFilePrefix, Logging::Mode logMode=Logging::Mode::CREATE )
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::Node * apply_visitor (const IR::Node *, const char *=0) override
bool backtrack (trigger &trig) override
PassManager * clone () 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)
virtual bool check_clone (const Visitor *a)
virtual bool check_global (cstring )
virtual void clear_globals ()
virtual ControlFlowVisitor * controlFlowVisitor ()
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 Visitor & flow_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 Context * getChildContext () const
int getChildrenVisited () const
const Context * getContext () const
int getContextDepth () const
const IR::Node * getCurrentNode () const
template<class T>
const T * getCurrentNode () const
const IR::Node * getOriginal () 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)
template<class T>
bool isInContext () const
template<class T>
bool isInContext (const Context *&c) const
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 Visitor & setCalledBy (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
RewriteDeparser rewrite_deparser
const Visitor * called_by = nullptr
cstring internalName
SplitFlowVisit_base *& split_link
SplitFlowVisit_base * split_link_mem = nullptr
◆ FieldGroup
Public Member Functions
FieldGroup (int i)
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_set & operator= (const ordered_set &a)
ordered_set & operator= (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
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::Field * key_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::Field * value_type
◆ 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.
◆ 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.
Public Member Functions
RewriteWeakFieldWrites (const ComputeValuesAtDeparser &values_at_deparser, const SynthesizePovEncoder &synth_pov_encoder)
const IR::Node * apply_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::Node * postorder (IR::Node *n)
virtual const IR::Node * preorder (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
virtual bool check_global (cstring )
virtual void clear_globals ()
virtual Visitor * clone () const
virtual ControlFlowVisitor * controlFlowVisitor ()
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 Visitor & flow_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 Context * getChildContext () const
int getChildrenVisited () const
const Context * getContext () const
int getContextDepth () const
const IR::Node * getCurrentNode () const
template<class T>
const T * getCurrentNode () const
const IR::Node * getOriginal () 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)
template<class T>
bool isInContext () const
template<class T>
bool isInContext (const Context *&c) const
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 Visitor & setCalledBy (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
◆ 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.
Public Member Functions
SynthesizePovEncoder (const CollectHeaderValidity &pov_bits, const ComputeValuesAtDeparser &values_at_deparser)
void dbprint (std::ostream &out) const override
const IR::Node * apply_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::Node * postorder (IR::Node *n)
virtual const IR::Node * preorder (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
virtual bool check_global (cstring )
virtual void clear_globals ()
virtual Visitor * clone () const
virtual ControlFlowVisitor * controlFlowVisitor ()
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 Visitor & flow_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 Context * getChildContext () const
int getChildrenVisited () const
const Context * getContext () const
int getContextDepth () const
const IR::Node * getCurrentNode () const
template<class T>
const T * getCurrentNode () const
const IR::Node * getOriginal () 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)
template<class T>
bool isInContext () const
template<class T>
bool isInContext (const Context *&c) const
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 Visitor & setCalledBy (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
const Visitor * called_by = nullptr
cstring internalName
SplitFlowVisit_base *& split_link
SplitFlowVisit_base * split_link_mem = nullptr
◆ dbprint()
void SynthesizePovEncoder::dbprint
(
std::ostream & out )
const
override virtual
◆ Value
Public Member Functions
Value (const IR::Constant *c)
Value (const PHV::Field *f)
Value (const Value &other)
bool operator< (const Value &other) const
Value & operator= (const Value &other)
bool operator== (const Value &other) const
std::string print () const
Public Attributes
const IR::Constant * constant = nullptr
const PHV::Field * field = nullptr
◆ VersionMap