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

#include <action_analysis.h>

Public Types

enum  error_code_t {
  NO_PROBLEM = 0 , MULTIPLE_CONTAINER_ACTIONS = (1 << 0) , READ_PHV_MISMATCH = (1 << 1) , ACTION_DATA_MISMATCH = (1 << 2) ,
  CONSTANT_MISMATCH = (1 << 3) , TOO_MANY_PHV_SOURCES = (1 << 4) , IMPOSSIBLE_ALIGNMENT = (1 << 5) , CONSTANT_TO_ACTION_DATA = (1 << 6) ,
  MULTIPLE_ACTION_DATA = (1 << 7) , ILLEGAL_OVERWRITE = (1 << 8) , BIT_COLLISION = (1 << 9) , OPERAND_MISMATCH = (1 << 10) ,
  UNHANDLED_ACTION_DATA = (1 << 11) , DIFFERENT_READ_SIZE = (1 << 12) , MAU_GROUP_MISMATCH = (1 << 13) , PHV_AND_ACTION_DATA = (1 << 14) ,
  PARTIAL_OVERWRITE = (1 << 15) , MULTIPLE_SHIFTS = (1 << 16) , ILLEGAL_ACTION_DATA = (1 << 17) , REFORMAT_CONSTANT = (1 << 18) ,
  UNRESOLVED_REPEATED_ACTION_DATA = (1 << 19) , ATTACHED_OUTPUT_ILLEGAL_ALIGNMENT = (1 << 20) , CONSTANT_TO_HASH = (1 << 21) , ILLEGAL_MOCHA_OR_DARK_WRITE = (1 << 22) ,
  BIT_COLLISION_SET = (1 << 23) , MULTIPLE_SPECIALITIES = (1 << 24)
}
 

Public Member Functions

 ContainerAction (cstring n, const IR::MAU::Table *tbl)
 
bool action_data_isolated () const
 
bool ad_renamed () const
 
int ad_sources () const
 
int alignment_counts () const
 
bool convert_constant_to_actiondata () const
 
bool convert_constant_to_hash () const
 
void determine_implicit_bits (PHV::Container container, TotalAlignment &ad_alignment)
 
void determine_src1 ()
 
bool has_ad_or_constant () const
 
bool is_byte_rotate_merge (PHV::Container container, TotalAlignment &ad_alignment)
 
bool is_commutative () const
 
bool is_from_set () const
 
bool is_funnel_shift () const
 
bool is_shift () const
 
bool is_single_shift () const
 
bool is_total_overwrite_possible ()
 
void move_source_to_bit (safe_vector< int > &bit_uses, TotalAlignment &ta)
 
bool no_sources () const
 
int operands () const
 
bool partial_overwrite () const
 
int read_sources () const
 
bool set_invalidate_write_bits (le_bitrange write)
 
void set_mismatch (ActionParam::type_t type)
 
bitvec specialities () const
 
std::string to_string () const
 
int total_types ()
 
bitvec total_write () const
 
bool unresolved_ad () const
 
bool verify_alignment (PHV::Container &container)
 
bool verify_deposit_field_variant (PHV::Container container, TotalAlignment &ad_alignment)
 
bool verify_mocha_and_dark (cstring &error_message, PHV::Container container)
 
bool verify_multiple_action_data () const
 
bool verify_one_alignment (TotalAlignment &tot_alignment, int size, int &unaligned_count, int &non_contiguous_count)
 
bool verify_only_read (const PhvInfo &phv, int num_source)
 
bool verify_overwritten (PHV::Container container, const PhvInfo &phv)
 
bool verify_phv_mau_group (PHV::Container container)
 
bool verify_possible (cstring &error_message, PHV::Container container, cstring action_name, const PhvInfo &phv)
 
bool verify_set_alignment (PHV::Container, TotalAlignment &ad_alignment)
 
bool verify_shift (cstring &error_message, PHV::Container container, const PhvInfo &phv)
 
bool verify_source_to_bit (int operands, PHV::Container container)
 
bool verify_speciality (cstring &error_message, PHV::Container container, cstring action_name)
 

Public Attributes

ActionDataInfo adi
 
ConstantInfo ci
 
bool constant_to_ad = false
 
bool convert_instr_to_bitmasked_set = false
 
bool convert_instr_to_byte_rotate_merge = false
 
bool convert_instr_to_deposit_field = false
 
int counts [ActionParam::TOTAL_TYPES] = {0, 0, 0}
 
unsigned error_code = NO_PROBLEM
 
TotalAlignment extra_resize_reads
 
safe_vector< FieldActionfield_actions
 
bool implicit_src1 = false
 
bool implicit_src2 = false
 
bool impossible = false
 
ordered_map< PHV::Container, safe_vector< Alignment > > initialization_phv_alignment
 
bitvec invalidate_write_bits
 
bool is_background_source = false
 
bool is_deposit_field_variant = false
 
cstring name
 
std::multimap< PHV::Container, TotalAlignmentphv_alignment
 
const IR::MAU::Table * table_context = nullptr
 
bool total_overwrite_possible = false
 
bool unhandled_action = false
 
bool verbose = false
 

Static Public Attributes

static std::set< unsigned > codesForErrorCases
 
static const std::vector< cstringerror_code_string_t
 

Friends

std::ostream & operator<< (std::ostream &out, const ContainerAction &ca)
 

Detailed Description

Information on all of the individual reads and writes within a single PHV container in an action function. Essentially coordinate to all the action that can happen within a single VLIW ALU

Member Enumeration Documentation

◆ error_code_t

‍Eventually we want to craft correct backtrack/error messages from all of these error messages. In the meantime, used for tracking action data issues

Member Function Documentation

◆ alignment_counts()

int ActionAnalysis::ContainerAction::alignment_counts ( ) const
inline

Each alignment comes from an individual manipulation of alloc_slice or single contiguous slice of action format

◆ determine_implicit_bits()

void ActionAnalysis::ContainerAction::determine_implicit_bits ( PHV::Container container,
TotalAlignment & ad_alignment )

The implicit bits are calculated as bits that aren't directly written or read from fields in the PHV, but are written anyway by the operation. Either fields can possibly be dead, or padding, or just empty space within the allocation.

This function runs at the end of verify_alignment, when src1 and src2 are possibly known

◆ is_byte_rotate_merge()

bool ActionAnalysis::ContainerAction::is_byte_rotate_merge ( PHV::Container container,
TotalAlignment & ad_alignment )
See also
verify_set_alignment for description of byte-rotate-merge

◆ verify_deposit_field_variant()

bool ActionAnalysis::ContainerAction::verify_deposit_field_variant ( PHV::Container container,
TotalAlignment & ad_alignment )

Verifies that the instruction can be encoded as a deposit-field. As mentioned above verify_set_alignment, deposit field is the following:

deposit-field: dest = ((src1 << shift) & mask) | (src2 & ~mask)

The mask is a contiguous range, and has a single lo and hi. Thus if src1 is a contiguous range of data (which can go around the container boundary), then this is supportable. The range has to be contiguous after the shift.

In a deposit field, a source must at least either be aligned, or can be contiguous. A source can be both. A source that is not aligned must be src1, and a source that is not contiguous is src2.

If the single PHV field in a deposit-field cannot be src1 due to non-contiguity, but can be src2 because it is aligned

Generally in a single source set, this is translated to set C0(lo..hi), C1(lo..hi), but when the source is wrapped, the only way for the assembler to understand is an explicit deposit-field instruction.

The deposit field for a single sourced wrapped source will be the following:

deposit-field C0(lo..hi), C1(lo), C0

The assembler will not understand the C1 slice if lo > hi, but the deposit-field instruction technically only requires the lo bit to determine the right shift

◆ verify_only_read()

bool ActionAnalysis::ContainerAction::verify_only_read ( const PhvInfo & phv,
int num_source )

Ensure that a read field is the only field within that container

◆ verify_overwritten()

bool ActionAnalysis::ContainerAction::verify_overwritten ( PHV::Container container,
const PhvInfo & phv )

For nearly all instructions, the ALU operation acts over all bits in the container. The only instruction where this doesn't apply is the deposit-field instruction. That instruction can have a portion masked. Any other operation currently acts on the entire container, and all fields could be potentially affected.

◆ verify_phv_mau_group()

bool ActionAnalysis::ContainerAction::verify_phv_mau_group ( PHV::Container container)

Each PHV ALU can only pull from a local group of PHVs in an operation. This guarantees that this clustering constraint is met.

◆ verify_possible()

bool ActionAnalysis::ContainerAction::verify_possible ( cstring & error_message,
PHV::Container container,
cstring action_name,
const PhvInfo & phv )

The goal of this function is to validate a container operation given the allocation the write fields and the sources of the particular operation. The following checks are:

  • If the ALU operation requires too many sources
  • If the ALU operation has the wrong number of operands per bit
  • If the number of operands matches instruction number
  • If the PHV clustering algorithm is incorrect
  • If the alignment of the bits are allowed
  • If an overwriting operation overwrites the entire container

The reason these constraints exists are due to the Action ALU Instruction Set Architecture. If any of these are not true, then this instruction is not possible on Tofino.

◆ verify_set_alignment()

bool ActionAnalysis::ContainerAction::verify_set_alignment ( PHV::Container container,
TotalAlignment & ad_alignment )

Verifies that the set ContainerActions (which are translated from assignment operations) are possible to be translated to an instruction.

The following instructions are possible encodings of assignment statements. Note that all shifts are rotational, meaning that the container is rotated by this number of bits.

deposit-field: dest = ((src1 << shift) & mask) | (src2 & ~mask)

The mask is a contiguous range, and has a single lo and hi. Thus if src1 is a contiguous range of data (which can go around the container boundary), then this is supportable. The range has to be contiguous after the shift.

bitmasked-set: dest = (src1 & mask) | (src2 & ~mask)

where the src1 must come from action data, and everything must be aligned. The mask is not required to be contiguous. Instead the mask is stored as action data in the RAM entry.

byte-rotate-merge: dest = ((src1 << src1_shift) & mask) | ((src2 << src2_shift) & ~mask)

The limitation is that src1_shift and src2_shift % 8 must == 0. The mask is also a byte mask, requiring the entire byte to come from the source.

The purpose of this function is to verify that a ContainerAction can be translated to one of these possible instructions, and will return false if the action is impossible in the ALU. This also determines if the action cannot be output as a set in the assembly language. With a set operation, src2 (background) = destination is implicit, but in the case when this isn't true, the full field must be translated in the compiler, i.e: deposit-field C0(lo..hi), C1(lo..hi), C2

Each of these operations have different constraints:

  • Bitmasked-set requires both sources to be aligned
  • Byte-Rotate-Merge has neither alignment or contiguous constraints, but requires the shifts to be factors of 8 and each byte to be sourced by only one source
  • Deposit-Field explained:
    See also
    set_deposit_field_variant
    The worst case is that an instruction is encoded as a bitmasked-set, as this requires double the action data that would be necessary in a different instruction. Only when something is required to be a bitmasked-set is this instruction used

◆ verify_shift()

bool ActionAnalysis::ContainerAction::verify_shift ( cstring & error_message,
PHV::Container container,
const PhvInfo & phv )

Due to shifts being fairly unique when it comes to action constraints, a separate function is required. The following constraints are verified:

  • Only one field_action is allowed per container (Not technically a constraint, but difficult to verify this otherwise
  • No action data or constants are allowed as a shift, only one PHV
  • The writes and reads are the only fields within their containers (Again not technically a constraint, but difficult to verify as well)

◆ verify_source_to_bit()

bool ActionAnalysis::ContainerAction::verify_source_to_bit ( int operands,
PHV::Container container )

This checks to make sure that all bits are operated correctly, i.e. if the operation is a set, every bit in the write is either set once or not at all or e.g. add, subtract, or, each write bit has either two read bits, or no read bits affecting it (overwrite constraints are checked in a different verification)

When combining a conditional-set with another set, the number of operands is not perfect here, as the operands can be either one or two bits, i.e.

conditional-set f1, f2, arg1, cond-arg set f3, arg2

How many sources, the condtional-set would have either two sources, but the normal set would have one operand. Potentially can be rewritten

◆ verify_speciality()

bool ActionAnalysis::ContainerAction::verify_speciality ( cstring & error_message,
PHV::Container container,
cstring action_name )

Verifies that the use of a speciality argument is valid

For all cases:

  • At most one speciality is currently allowed per ALU operation (i.e. cannot combine HashDist with Control Plane or RNG)

For NO_SPECIAL (anything still applies)

For any non-HASH

  • Only one argument is currently allowed, as InstructionAdjustment is not able to handle all of the corner cases

For METER_ALU

  • The parameter headed to an ALU operation must correctly fit within a single action bus slot

For HASH:

  • Multiple Hash parameters as well as constants are allowed in the Hash. In the future, PHV could be allowed in the Hash as well.

Member Data Documentation

◆ codesForErrorCases

std::set< unsigned > ActionAnalysis::ContainerAction::codesForErrorCases
static
Initial value:
= {
MULTIPLE_CONTAINER_ACTIONS,
READ_PHV_MISMATCH,
ACTION_DATA_MISMATCH,
CONSTANT_MISMATCH,
TOO_MANY_PHV_SOURCES,
IMPOSSIBLE_ALIGNMENT,
ILLEGAL_OVERWRITE,
MAU_GROUP_MISMATCH,
PHV_AND_ACTION_DATA,
MULTIPLE_SHIFTS,
ATTACHED_OUTPUT_ILLEGAL_ALIGNMENT,
BIT_COLLISION_SET,
ILLEGAL_MOCHA_OR_DARK_WRITE}

◆ convert_instr_to_bitmasked_set

bool ActionAnalysis::ContainerAction::convert_instr_to_bitmasked_set = false

‍determined by tofino_compliance check

◆ convert_instr_to_byte_rotate_merge

bool ActionAnalysis::ContainerAction::convert_instr_to_byte_rotate_merge = false

‍determined by tofino_compliance_check

◆ error_code_string_t

const std::vector< cstring > ActionAnalysis::ContainerAction::error_code_string_t
static
Initial value:
= {
"MULTIPLE_CONTAINER_ACTIONS"_cs,
"READ_PHV_MISMATCH"_cs,
"ACTION_DATA_MISMATCH"_cs,
"CONSTANT_MISMATCH"_cs,
"TOO_MANY_PHV_SOURCES"_cs,
"IMPOSSIBLE_ALIGNMENT"_cs,
"CONSTANT_TO_ACTION_DATA"_cs,
"MULTIPLE_ACTION_DATA"_cs,
"ILLEGAL_OVERWRITE"_cs,
"BIT_COLLISION"_cs,
"OPERAND_MISMATCH"_cs,
"UNHANDLED_ACTION_DATA"_cs,
"DIFFERENT_READ_SIZE"_cs,
"MAU_GROUP_MISMATCH"_cs,
"PHV_AND_ACTION_DATA"_cs,
"PARTIAL_OVERWRITE"_cs,
"MULTIPLE_SHIFTS"_cs,
"ILLEGAL_ACTION_DATA"_cs,
"REFORMAT_CONSTANT"_cs,
"UNRESOLVED_REPEATED_ACTION_DATA"_cs,
"ATTACHED_OUTPUT_ILLEGAL_ALIGNMENT"_cs,
"CONSTANT_TO_HASH"_cs,
"ILLEGAL_MOCHA_OR_DARK_WRITE"_cs,
"BIT_COLLISION_SET"_cs,
}

◆ implicit_src2

bool ActionAnalysis::ContainerAction::implicit_src2 = false

‍determined by tofino_compliance_check

◆ impossible

bool ActionAnalysis::ContainerAction::impossible = false

‍determined by tofino_compliance_check