P4C
The P4 Compiler
Loading...
Searching...
No Matches
ActionAnalysis::TotalAlignment Struct Reference

#include <action_analysis.h>

Public Member Functions

void add_alignment (le_bitrange wb, le_bitrange rb)
 
bool aligned () const
 
bool bitrange_contiguous () const
 
int bitrange_contiguous_size () const
 
int bitrange_cover_size () const
 
bitvec brm_src_mask (PHV::Container container) const
 
bitvec byte_rotate_merge_byte_mask (PHV::Container container) const
 
bool contiguous () const
 
bool deposit_field_src1 () const
 
bool deposit_field_src2 (PHV::Container container) const
 
void determine_brm_implicit_bits (PHV::Container container, bitvec src1_mask)
 
void determine_df_implicit_bits (PHV::Container container)
 
bitvec df_src1_mask () const
 
bitvec df_src2_mask (PHV::Container container) const
 
bool equiv_bit_totals () const
 
void implicit_bits_full (PHV::Container container)
 
bool is_byte_rotate_merge_src (PHV::Container container) const
 
bool is_wrapped_shift (PHV::Container container, int *lo=nullptr, int *hi=nullptr) const
 
TotalAlignment operator| (const TotalAlignment &ta)
 
bitvec read_bits () const
 
void set_implicit_bits_from_mask (bitvec mask, PHV::Container container)
 
bool verify_individual_alignments (PHV::Container &container)
 
bitvec write_bits () const
 

Public Attributes

bitvec direct_read_bits
 
bitvec direct_write_bits
 
bitvec implicit_read_bits
 
bitvec implicit_write_bits
 
safe_vector< Alignmentindiv_alignments
 
bool is_src1 = false
 
int right_shift = 0
 
bitvec unused_container_bits
 
bool verbose = false
 

Friends

std::ostream & operator<< (std::ostream &out, const TotalAlignment &ta)
 

Detailed Description

Information on all PHV reads affecting a single container. Again used for verification and combining fields into MultiOperand. Understood to be the bits written and read by the entire container, rather than in individual instruction in the container. From these total alignment structures, we can determine if deposit-fields or bitmasked-sets are possible/necessary

Member Function Documentation

◆ bitrange_contiguous_size()

int ActionAnalysis::TotalAlignment::bitrange_contiguous_size ( ) const
inline

A size that fits all the write bits provided they are continuous, or -1 if they are not. Value -1 therefore indicates that deposit-field instruction cannot be used.

◆ bitrange_cover_size()

int ActionAnalysis::TotalAlignment::bitrange_cover_size ( ) const
inline

Returns a size that fits all the non-zero bits of writes. The writes need not be contiguous.

◆ brm_src_mask()

bitvec ActionAnalysis::TotalAlignment::brm_src_mask ( PHV::Container container) const

Based on what bits that are written and unused, this is the possible source mask bit by bit. Because of unused bits, the actual source mask can be a subset of this

◆ byte_rotate_merge_byte_mask()

bitvec ActionAnalysis::TotalAlignment::byte_rotate_merge_byte_mask ( PHV::Container container) const

The byte mask appearing in the instruction

◆ deposit_field_src1()

bool ActionAnalysis::TotalAlignment::deposit_field_src1 ( ) const

Src1 of a deposit-field does not have to be aligned, but must be contiguous after it has been rotated

◆ deposit_field_src2()

bool ActionAnalysis::TotalAlignment::deposit_field_src2 ( PHV::Container container) const

Src2 of a deposit-field has to be be aligned, but not contiguous, as long as there is only one hole within the deposit-field

◆ df_src1_mask()

bitvec ActionAnalysis::TotalAlignment::df_src1_mask ( ) const

The following functions are used during verify_alignment in order to determine which source each parameter is as well as determine which bits are written by src1/src2

The unused_container_bits are bits that are not live at the same time of any bits of fields in the same container, and thus can be written to.

For the deposit-field src1, the written bits must be a lo to hi that is contiguous on the write bits. For deposit-field src2, the opposite is true, as the write must contain a single contiguous hole.

For src1, this contiguous range can either container directly written bits, or unused container bits that can be read

◆ df_src2_mask()

bitvec ActionAnalysis::TotalAlignment::df_src2_mask ( PHV::Container container) const

See comments above df_src1_mask for context.

The goal of this function is to find what bits are to be written by the src2 of the deposit field. This looks for a single contiguous hole in the bits written, and returns the reverse of this hole

The algorithm looks for holes in the direct_write_bits. These may actually not be the hole for the deposit-field if those bits are entirely unused_container_bits. Thus if the hole is not all unused_container_bits, this is assumed to be the hole.

If there are multiple holes, then the deposit-field mask is returned empty

◆ is_wrapped_shift()

bool ActionAnalysis::TotalAlignment::is_wrapped_shift ( PHV::Container container,
int * lo = nullptr,
int * hi = nullptr ) const

Determines if the source is to be wrapped around the container. If the thing is wrapped, the low position of the source is required to determine the location

A deposit-field operation has source that can be rotated bit by bit. This rotation can rotate the data around the container. The destination of a deposit-field src1 has to be contiguous, but this doesn't mean that the source is contiguous.

Say for example you were writing a 4 bit field, i.e. f1 = f2. The allocation could be

B0 [5..2] = f1[3..0] B1 [7..6] = f2[1..0] B1 [1..0] = f2[3..2]

By right rotating B1 by 4 bits, this will shift the B1 into the correct place. But notice that the field f2 is non contiguous in it's own container.

The instructions in the assembly file, when writing one slice to another slice are:

  • set dest_container(dest_bit_hi..dest_bit_lo), src_container(src_bit_hi..src_bit_lo)

However, this is impossible to write with a source that is wrapped, as src_bit_hi is less than src_bit_lo. This is instead synthesized as a direct deposit-field instruction:

- deposit_field B0[5..2], B1(1), B0

This funciton returns true if the instruction has to be synthesized directly as a deposit-field because the source slice is not a lo to hi range. It also can return a lo and hi value for the IR::MAU::WrappedSlice

2 corner cases:

  1. The source is the entire container (thus if the source is shifted at all, it is wrapped)
  2. The source is a portion of a container (bitvec operations)

> lo is the bit of the read bits that needs to be aligned with bit 0

‍hi is the bit that needs to be aligned with container.size() - 1.

◆ verify_individual_alignments()

bool ActionAnalysis::TotalAlignment::verify_individual_alignments ( PHV::Container & container)

Guarantees that a single alignment is aligned correctly. The checks are:

  • Each individual field write by write are aligned at the same offset on their read
  • Sources are not both non-contiguous and non-aligned

Member Data Documentation

◆ right_shift

int ActionAnalysis::TotalAlignment::right_shift = 0

‍The amount to bits to rotate right the write_bits in order to get the read_bits. The deposit-field write shift is the opposite, i.e. the amount to rotate right the read bits in order to get the write bits