P4C
The P4 Compiler
Loading...
Searching...
No Matches
PHV::Field Class Reference
Inheritance diagram for PHV::Field:
[legend]

Classes

struct  mirror_field_list_t
 A mirror field points to its field list (one of eight) More...
 

Public Types

enum  alloc_code_t {
  EMPTY = 0 , REFERENCED = 1 << 0 , HAS_PHV_ALLOCATION = 1 << 1 , FULLY_PHV_ALLOCATED = 1 << 2 ,
  HAS_CLOT_ALLOCATION = 1 << 3
}
 
typedef unsigned AllocState
 

Public Member Functions

void add_alloc (const PHV::AllocSlice &alloc)
 Allocate a slice of this field.
 
PHV::AllocSliceadd_and_return_alloc (const Field *f, PHV::Container c, int fb, int cb, int w, const ActionSet &a)
 
bool add_wide_arith_start_bit (int start_bit)
 
size_t alloc_size () const
 
bool bit_is_wide_arith_lo (int slice_bit) const
 
bool bit_used_in_wide_arith (int slice_bit) const
 
le_bitrange byteAlignedRangeInBits () const
 
void clear_alloc ()
 Clear any PHV allocation for this field.
 
void clearExternalName ()
 Clear the external name, if any has been set.
 
int container_bytes (std::optional< le_bitrange > bits=std::nullopt) const
 
bool deparsed () const
 
bool deparsed_bottom_bits () const
 
bool deparsed_to_tm () const
 
bool deparsed_top_bits () const
 
bool emitted () const
 
void erase_alignment ()
 
void eraseAlignment ()
 Erase the alignment requirement for this field.
 
bool exact_containers () const
 
cstring externalName () const
 
const PHV::AllocSlicefor_bit (int bit) const
 
void foreach_alloc (const IR::MAU::Table *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_alloc (const le_bitrange *r, const IR::MAU::Table *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_alloc (const le_bitrange *r, const PHV::AllocContext *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_alloc (const PHV::AllocContext *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_alloc (le_bitrange r, const IR::MAU::Table *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_alloc (le_bitrange r, const PHV::AllocContext *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_alloc (le_bitrange r, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_alloc (std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_byte (const IR::MAU::Table *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_byte (const le_bitrange *r, const IR::MAU::Table *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_byte (const le_bitrange *r, const PHV::AllocContext *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_byte (const PHV::AllocContext *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_byte (le_bitrange r, const IR::MAU::Table *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
void foreach_byte (le_bitrange r, const PHV::AllocContext *ctxt, const PHV::FieldUse *use, std::function< void(const PHV::AllocSlice &)> fn, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
bool fullyPhvAllocated (AllocState s) const
 
safe_vector< PHV::AllocSlice > & get_alloc ()
 
const safe_vector< PHV::AllocSlice > & get_alloc () const
 
const std::vector< PHV::AllocSliceget_combined_alloc_bytes (const PHV::AllocContext *ctxt, const PHV::FieldUse *use, SliceMatch useTblRefs=SliceMatch::DFLT) const
 
const std::vector< PHV::AllocSliceget_combined_alloc_slices (le_bitrange bits, const PHV::AllocContext *ctxt, const PHV::FieldUse *use) const
 
const Constraints::AlignmentConstraintgetAlignmentConstraint () const
 
const Constraints::DigestConstraintgetDigestConstraint () const
 
int getMaxContainerBytes () const
 
const Constraints::SolitaryConstraintgetSolitaryConstraint () const
 
bitvec getStartBits (PHV::Size size) const
 
bool has_no_split_at_pos () const
 
bool hasAllocation (AllocState s) const
 Determines whether s has a PHV allocation or a CLOT allocation.
 
bool hasClotAllocation (AllocState s) const
 
bool hasExternalName () const
 
bool hasMaxContainerBytesConstraint () const
 
bool hasPhvAllocation (AllocState s) const
 Utility functions to get field allocation status.
 
cstring header () const
 
bool is_avoid_alloc () const
 
bool is_checksummed () const
 
bool is_dark_candidate () const
 
bool is_deparser_zero_candidate () const
 
bool is_digest () const
 
bool is_fixed_size_header () const
 
bool is_flexible () const
 
bool is_ignore_alloc () const
 
bool is_intrinsic () const
 
bool is_invalidate_from_arch () const
 
bool is_marshaled () const
 
bool is_mocha_candidate () const
 
bool is_overlayable () const
 
bool is_padding () const
 
bool is_solitary () const
 
bool is_tphv_candidate (const PhvUse &uses) const
 
bool is_unallocated () const
 
bool is_upcasted () const
 
bool isCompilerGeneratedPaddingField () const
 
bool isGhostField () const
 
bool isPacketField () const
 
bool isReferenced (AllocState s) const
 
const std::optional< bitvec > & limited_container_ids () const
 
bool no_holes () const
 
bool no_split () const
 
bool no_split_at (int pos) const
 
int no_split_container_size () const
 
std::vector< le_bitrangeno_split_ranges () const
 
size_t num_pack_conflicts () const
 
safe_vector< FieldOperation > & operations ()
 
const safe_vector< FieldOperation > & operations () const
 
bool operator< (const Field &other) const
 Orders by name.
 
bool parsed () const
 
bool partiallyPhvAllocated (AllocState s) const
 
PHV::Size prefer_container_size () const
 
bool same_container_group () const
 
void set_alignment (Constraints::AlignmentConstraint &c)
 
void set_alignment (unsigned r, unsigned v)
 
void set_alloc (const safe_vector< PHV::AllocSlice > &alloc)
 Set all allocated slices of this field.
 
void set_avoid_alloc (bool a)
 
void set_dark_candidate (bool c)
 
void set_deparsed (bool b)
 
void set_deparsed_bottom_bits (bool b)
 
void set_deparsed_to_tm (bool b)
 
void set_deparsed_top_bits (bool b)
 
void set_deparser_zero_candidate (bool c)
 
void set_digest (uint32_t source)
 
void set_emitted (bool b)
 
void set_exact_containers (bool b)
 
void set_fixed_size_header (bool f)
 
void set_flexible (bool b)
 
void set_ignore_alloc (bool b)
 
void set_intrinsic (bool b)
 
void set_invalidate_from_arch (bool b)
 
void set_is_checksummed (bool b)
 
void set_is_marshaled (bool b)
 
void set_limited_container_ids (const std::optional< bitvec > &ids)
 
void set_mocha_candidate (bool c)
 
void set_no_holes (bool b)
 
void set_no_split (bool b)
 
void set_no_split_at (le_bitrange range)
 
void set_no_split_container_size (int size)
 
void set_num_pack_conflicts (size_t no)
 
void set_overlayable (bool p)
 
void set_padding (bool p)
 
void set_parsed (bool b)
 
void set_prefer_container_size (PHV::Size cnt_size)
 
void set_same_container_group (bool b)
 
void set_solitary (uint32_t reason)
 
void set_upcasted (bool c)
 
void set_written_in_force_immediate (bool b)
 
void setExternalName (cstring name)
 
void setMaxContainerBytes (int size)
 
void setStartBits (PHV::Size size, bitvec startPositions)
 
void setStartBitsToLowerBitsOfBottomByte ()
 
void sort_alloc ()
 Sort by field MSB.
 
void updateAlignment (PHV::AlignmentReason, const FieldAlignment &newAlignment, const Util::SourceInfo &newAlignmentSource)
 
void updateValidContainerRange (nw_bitrange newValidRange)
 
bool used_in_wide_arith () const
 
nw_bitrange validContainerRange () const
 
bool written_in_force_immediate_table () const
 
- Public Member Functions inherited from LiftLess< Field >
 OPERATOR (equal, Equal)
 
 OPERATOR (greater, Greater)
 
 OPERATOR (greater_equal, GreaterEqual)
 
 OPERATOR (less, Less)
 
 OPERATOR (less_equal, LessEqual)
 
 OPERATOR (not_equal, NotEqual)
 
bool operator!= (const Field &other) const
 
virtual bool operator< (const Field &) const=0
 
bool operator<= (const Field &other) const
 
bool operator== (const Field &other) const
 
bool operator> (const Field &other) const
 
bool operator>= (const Field &other) const
 

Public Attributes

const PHV::FieldaliasSource = nullptr
 
std::optional< FieldAlignmentalignment
 
std::list< std::pair< FieldAlignment, Util::SourceInfo > > alignmentSources
 List of alignment sources for this field (mainly for error printing)
 
bool bridged = false
 True if this Field is metadata bridged from ingress to egress.
 
bool emitted_i = false
 True if this field is emitted by the deparser onto the wire.
 
gress_t gress = INGRESS
 Whether the Field is ingress or egress.
 
int id = 0
 Unique field ID.
 
bool intrinsic_i = false
 True if this Field is intrinsic.
 
bool invalidate_from_arch_i = false
 
bool metadata = false
 True if this Field is metadata.
 
struct PHV::Field::mirror_field_list_t mirror_field_list = {nullptr, -1}
 
cstring name
 
int offset = 0
 Offset of lsb from lsb (last) bit of containing header.
 
bool overlayable = false
 
bool padding = false
 True if this Field is a padding field.
 
bool pov = false
 True if this Field is a validity bit.
 
int size = 0
 Total size of Field in bits.
 
std::optional< Util::SourceInfosrcInfo
 Associate source info to each field.
 
nw_bitrange validContainerRange_i = ZeroToMax()
 

Friends

std::ostream & operator<< (std::ostream &out, const Field &field)
 

Member Function Documentation

◆ alloc_size()

size_t PHV::Field::alloc_size ( ) const
inline
Returns
the number of allocated slices of this field.

◆ byteAlignedRangeInBits()

le_bitrange PHV::Field::byteAlignedRangeInBits ( ) const
inline

Returns a range of bits in the header that captures the byte aligned offset of this field within its header.

◆ container_bytes()

int PHV::Field::container_bytes ( std::optional< le_bitrange > bits = std::nullopt) const
Returns
the number of distinct container bytes that contain slices of the bits of this field.

◆ deparsed()

bool PHV::Field::deparsed ( ) const
inline

NB: Fields satisfying the deparsed constraint are not necessarily emitted. To determine whether a field is emitted by the deparser onto the wire, see emitted_i.

◆ externalName()

cstring PHV::Field::externalName ( ) const
inline

Get the external name of this field. If PHV::Field::externalName is not std::nullopt, use that; otherwise, use PHV::Field::name.

◆ for_bit()

const PHV::AllocSlice & PHV::Field::for_bit ( int bit) const
Returns
the PHV::AllocSlice in which field bit is allocated. Fails catastrophically if bit is not allocated or not within the range of this field's size. FIXME – should take an AllocContext and FieldUse like foreach_byte below?

◆ foreach_alloc() [1/3]

void PHV::Field::foreach_alloc ( const le_bitrange * r,
const PHV::AllocContext * ctxt,
const PHV::FieldUse * use,
std::function< void(const PHV::AllocSlice &)> fn,
SliceMatch useTblRefs = SliceMatch::DFLT ) const
inline

Equivalent to foreach_alloc(StartLen(0, this->size), ctxt, use, fn), or to foreach_alloc(ctxt, fn) when r is null.

See also
foreach_alloc(le_bitrange, const IR::BFN::Unit *, std::function<void(const PHV::AllocSlice&)>).

◆ foreach_alloc() [2/3]

void PHV::Field::foreach_alloc ( const PHV::AllocContext * ctxt,
const PHV::FieldUse * use,
std::function< void(const PHV::AllocSlice &)> fn,
SliceMatch useTblRefs = SliceMatch::DFLT ) const
inline

Equivalent to foreach_alloc(StartLen(0, this->size), ctxt, fn).

See also
foreach_alloc(le_bitrange, const IR::BFN::Unit *, const PHV::FieldUse&, std::function<void(const PHV::AllocSlice&)>).

◆ foreach_alloc() [3/3]

void PHV::Field::foreach_alloc ( le_bitrange r,
const PHV::AllocContext * ctxt,
const PHV::FieldUse * use,
std::function< void(const PHV::AllocSlice &)> fn,
SliceMatch useTblRefs = SliceMatch::DFLT ) const

Apply fn to each PHV::AllocSlice within the specified ctxt to which this has been allocated (if any). ctxt can be one of ParserState, Table, Deparser, or null for no filter. use can be READ or WRITE. For now, the context is the entire pipeline, as PHV allocation is global.

◆ foreach_byte() [1/2]

void PHV::Field::foreach_byte ( const le_bitrange * r,
const PHV::AllocContext * ctxt,
const PHV::FieldUse * use,
std::function< void(const PHV::AllocSlice &)> fn,
SliceMatch useTblRefs = SliceMatch::DFLT ) const
inline

Equivalent to foreach_byte(*r, fn), or foreach_byte(StartLen(0, this->size), fn) when r is null.

See also
foreach_byte(le_bitrange, std::function<void(const PHV::AllocSlice&)>).

◆ foreach_byte() [2/2]

void PHV::Field::foreach_byte ( le_bitrange r,
const PHV::AllocContext * ctxt,
const PHV::FieldUse * use,
std::function< void(const PHV::AllocSlice &)> fn,
PHV::SliceMatch useTblRefs = SliceMatch::DFLT ) const

For each byte-aligned container byte of each allocated slice of this field, construct an alloc_slice representing that allocated byte (or fraction thereof) and apply fn to it, BUT ONLY if the container is NOT a TPHV container.

For example, suppose a 16b field (f) is allocated as follows:

C8 [4:0] <— f [15:11] C8 [7:7] <— f [10:10] C16 [9:0] <— f [9:0]

Where C8 is an 8b container and C16 is a 16b container.

Invoking `f->foreach_byte(1, 14, fn)` should invoke fn on the following alloc_slices (in this order):

C16 [7:1] <— f [7:1] C16 [9:8] <— f [9:8] C8 [7:7] <— f [10:10] C8 [3:0] <— f [14:11]

◆ get_alloc()

const safe_vector< PHV::AllocSlice > & PHV::Field::get_alloc ( ) const
inline
Returns
the PHV allocation for this field, if any.

◆ get_combined_alloc_bytes()

const std::vector< PHV::AllocSlice > PHV::Field::get_combined_alloc_bytes ( const PHV::AllocContext * ctxt,
const PHV::FieldUse * use,
SliceMatch useTblRefs = SliceMatch::DFLT ) const
Returns
a vector of PHV::AllocSlice, such that multiple PHV::AllocSlice within the same byte of the same container are combined into the same new PHV::AllocSlice. This is necessary because input crossbar allocation combines multiple slices of the same field in the same container into a single Use object.

◆ get_combined_alloc_slices()

const std::vector< PHV::AllocSlice > PHV::Field::get_combined_alloc_slices ( le_bitrange bits,
const PHV::AllocContext * ctxt,
const PHV::FieldUse * use ) const
Returns
a vector of PHV::AllocSlice, such that multiple PHV::AllocSlice within the same container are combined into the same new PHV::AllocSlice, if the ranges of the two PHV::AllocSlice are contiguous. This is necessary because parser validation checks has this invariant.

◆ getStartBits()

bitvec PHV::Field::getStartBits ( PHV::Size size) const
Returns
the bit positions (little Endian) at which the least significant bit of this field may be placed.

◆ hasExternalName()

bool PHV::Field::hasExternalName ( ) const
inline
Returns
true if this field as an external name set independently of its name.

◆ header()

cstring PHV::Field::header ( ) const
inline
Returns
the header to which this field belongs.

◆ is_tphv_candidate()

bool PHV::Field::is_tphv_candidate ( const PhvUse & uses) const
Returns
true if this field can be placed in TPHV containers.

◆ is_unallocated()

bool PHV::Field::is_unallocated ( ) const
inline
Returns
true if there are no allocated slices of this field.

◆ isCompilerGeneratedPaddingField()

bool PHV::Field::isCompilerGeneratedPaddingField ( ) const
inline
Returns
true if the field has been generated by the compiler for padding marshalled fields.

◆ isGhostField()

bool PHV::Field::isGhostField ( ) const
inline
Returns
true if the Field is a ghost field. TODO: Right now, ghost fields are marked as ingress fields, so we use string comparison for this method. Ideally, we should use the gress member directly and not have a separate ghost field.

◆ isPacketField()

bool PHV::Field::isPacketField ( ) const
inline
Returns
true if this field is a packet field.

◆ setExternalName()

void PHV::Field::setExternalName ( cstring name)
inline

Set the external name of this field, which will be used in place of PHV::Field::name when generating assembly.

◆ setStartBits()

void PHV::Field::setStartBits ( PHV::Size size,
bitvec startPositions )

Sets the valid starting bit positions (little Endian) for this field. For example, setStartBits(PHV::Size::b8, bitvec(0,1)) means that the least significant bit of this field must start at bit 0 in 8b containers.

◆ setStartBitsToLowerBitsOfBottomByte()

void PHV::Field::setStartBitsToLowerBitsOfBottomByte ( )

setStartBitsToLowerBitsOfBottomByte will set the start bit of this field to be limited to the [0..x]-th (little endian) bit of any-sized containers, where x equals to (1) for field.size <= 8-bit, x = 8 - size; (2) for 8 < field.size <= 16, x = 16 - size; (3) for 16 < field.size, x = 7.

◆ updateAlignment()

void PHV::Field::updateAlignment ( PHV::AlignmentReason reason,
const FieldAlignment & newAlignment,
const Util::SourceInfo & newAlignmentSource )

Update the alignment requirement for this field. Reports an error if conflicting requirements render the alignment unsatisfiable.

◆ updateValidContainerRange()

void PHV::Field::updateValidContainerRange ( nw_bitrange newValidRange)

Update the valid range of container positions for this field. Reports an error if conflicting requirements render the constraint unsatisfiable.

Parameters
newValidRangeA new valid range constraint. This is intersected with any existing valid range constraint to produce a new overall valid container range for this field.

◆ validContainerRange()

nw_bitrange PHV::Field::validContainerRange ( ) const
inline

The range of possible bit positions at which this field can be placed in a container, in network order. For example, suppose we have an 8-bit field with validContainerRange = [0, 11] and a 16-bit container.

 0              15  (network order)

| -------------— | container ^ ^ X Y

The entire field must be placed between X and Y (inclusive).

Note that field-->container assignment is usually in little Endian. From that perspective the picture looks like:

 15             0   (little Endian order)

| -------------— | container ^ ^ X Y

And so the field must be placed in what are considered the "upper" bits of the container.

TODO: This range always starts at 0, which is an invariant that other parts of the compiler rely on.

Member Data Documentation

◆ aliasSource

const PHV::Field* PHV::Field::aliasSource = nullptr

If this field is an alias destination, then maintain a pointer to the alias source. Alias destinations are the canonical representation for alias sources.

For example, if we have

@pa_alias("ingress", "h.f", "h.f1")
@pa_alias("ingress", "h.f", "h.f2")

then h.f (the first field mentioned in each annotation) is an alias destination for h.f1 and h.f2, which are sources (the second field in each annotation). The ReplaceAllAliases pass replaces references to h.f1 with an h.f reference that has h.f1 as its alias source, and similarly for references to h.f2.

◆ alignment

std::optional<FieldAlignment> PHV::Field::alignment

The alignment requirement of this field. If std::nullopt, there is no particular alignment requirement.

◆ invalidate_from_arch_i

bool PHV::Field::invalidate_from_arch_i = false

True if this field needs to invalid when reaching the deparser and is not written by the user (on Tofino).

◆ name

cstring PHV::Field::name

Field name, following this scheme:

  • "gress::header.field"
  • "gress::header.field[i]" where "i" is a positive integer
  • "gress::header.$valid"

◆ overlayable

bool PHV::Field::overlayable = false

True if this Field can always be overlayable with other fields. Used for padding fields for bridged metadata.

◆ validContainerRange_i

nw_bitrange PHV::Field::validContainerRange_i = ZeroToMax()
See also
Field::validContainerRange().