Beispiel #1
0
def make_allmetas_node(hlir):
    ctl_local_vars = hlir.controls.flatmap('controlLocals').filter(
        'node_type', 'Declaration_Variable')

    clv_to_struct = {}

    fldinfos = unique_everseen(
        (fld.name, fld.urtype) for fld in hlir.news.meta.flatmap('fields'))

    check_meta_fields(fldinfos)

    fldname_to_hdrfield = {
        fld.name: (hdr, fld, fld)
        for hdr in hlir.news.meta for fld in hdr.fields
    }

    allmeta_flds = list(make_metaflds(fldname_to_hdrfield)) + list(
        make_metaflds(clv_to_struct))

    hlir.allmetas = P4Node({'node_type': 'StructField'})
    hlir.allmetas.name = 'all_metadatas'
    hlir.allmetas.type = P4Node({'node_type': 'Type_Name'})
    hlir.allmetas.type.path = P4Node({'node_type': 'Path'})
    hlir.allmetas.type.path.absolute = True

    hlir.allmetas.type.type_ref = P4Node({'node_type': 'Type_Header'})
    hlir.allmetas.type.type_ref.name = 'all_metadatas_t'
    hlir.allmetas.type.type_ref.fields = P4Node(allmeta_flds)
Beispiel #2
0
def attrs_regroup_structs(hlir):
    structs = hlir.objects['Type_Struct']

    act_param_types = hlir.all_nodes.by_type('P4Control').flatmap(
        'controlLocals').filter(
            'node_type', 'P4Action').flatmap('parameters.parameters').filter(
                'type.node_type', 'Type_Name').map('type.type_ref')

    metas_by_varname = hlir.all_nodes.by_type('PathExpression').filter(
        'type.node_type',
        'Type_Struct').filter('path.name',
                              hlir.news.user_meta_var).map('type.name')
    param_metas = hlir.all_nodes.by_type('Parameter').filter(
        'name', hlir.news.user_meta_var).map('urtype').filter(
            'node_type', 'Type_Struct').map('name')

    meta_type_names = unique_everseen(hlir.news.meta_types + metas_by_varname +
                                      param_metas)

    hlir.news.meta = remove_nodes(
        structs.filter(lambda s: s.name in meta_type_names), hlir.objects)
    hlir.news.data = remove_nodes(hlir.objects['Type_Struct'], hlir.objects)

    assert (remaining := len(hlir.objects['Type_Struct'])
            ) == 0, f'{remaining} structs are not identified'
Beispiel #3
0
def attrs_hdr_metadata_insts(hlir):
    """Metadata instances and header instances"""
    def is_hdr(fld):
        return fld.urtype.node_type == 'Type_Header'

    def is_named_hdr(fld):
        return fld.urtype.node_type == 'Type_Name' and (
            res := resolve_type_name(
                hlir,
                fld.urtype)) is not None and res.node_type == 'Type_Header'

    for stk in hlir.header_stacks:
        # note: the 'size' attribute in T4P4S refers to the bitsize of the header
        #       this renaming avoids collision
        stk.type.stk_size = stk.type.size
        stk.type.del_attr('size')

    stack_infos = hlir.header_stacks.map(
        lambda stack: (stack, stack.name, stack.urtype.stk_size.value, stack.
                       urtype.elementType))

    hdr_names = unique_everseen(
        hlir.groups.pathexprs.under_header.flatmap('type.fields').map('name'))
    hdrs = hlir.news.data.flatmap('fields').filter(
        lambda fld: is_hdr(fld) or is_named_hdr(fld) and fld.name in hdr_names)
    hdr_stacks = list(
        create_hdr(hlir, f'{name}_{idx}', type, idx=idx, stack=stack)
        for (stack, name, stk_size, type) in stack_infos
        for idx in range(stk_size))
    local_hdrs = hlir.locals \
        .filter('node_type', 'Declaration_Variable') \
        .filter('type.node_type', 'Type_Name') \
        .filter(lambda hdr: hlir.headers.get(hdr.urtype.path.name) is not None) \
        .map(lambda hdr: create_hdr(hlir, hdr.name, hdr.type))
    local_hdr_node_ids = set(local_hdrs.map('Node_ID'))

    insts = hdrs + hdr_stacks + local_hdrs

    for hdrinst in insts:
        hdrinst.is_local = hdrinst.Node_ID in local_hdr_node_ids

        if 'path' in hdrinst.urtype and not hdrinst.urtype.path.absolute:
            hdrinst.type.type_ref = hlir.headers.get(hdrinst.urtype.path.name)

        is_stack = 'stack' in hdrinst and hdrinst.stack is not None

        # TODO find an even more reliable way to see if the header is skipped (extracted as _)
        hdrinst.is_skipped = not is_stack and hdrinst.is_local and 'annotations' not in hdrinst and hdrinst.name.startswith(
            'arg')

    set_header_meta_preparsed(hlir.allmetas, True)
    for hdr in hlir.headers:
        set_header_meta_preparsed(hdr, False)

    hlir.headers.append(hlir.allmetas.urtype)

    hlir.header_instances = P4Node(insts + [hlir.allmetas])
Beispiel #4
0
def resolve_metadata_hdr(hlir, typename_node, fld):
    results = hlir.news.meta.flatmap('fields').filter('name', fld.name)
    if len(results) == 1:
        return results[0]

    results = results.filterfalse('type.path.absolute')
    typenames = unique_everseen(results.map('urtype.name'))

    if len(typenames) > 1:
        hdrname = typename_node.parents.filter(
            lambda n: n.node_type == 'Type_Struct')[0].name
        typenames = ', '.join(typenames)
        assert False, f'Metadata field {hdrname}.{fld.name} has conflicting types ({typenames})'
    return results[0]
Beispiel #5
0
from compiler_log_warnings_errors import addError, addWarning
from compiler_common import types, generate_var_name, get_hdrfld_name, unique_everseen

#[ #include "dataplane_impl.h"
#[ #include "dataplane.h"
#[ #include "dataplane_stages.h"

# TODO make this an import from hardware_indep
#[ #include "dpdk_smem.h"

table_infos = [(table, table.short_name + ("/keyless" if table.key_length_bits == 0 else "") + ("/hidden" if table.is_hidden else "")) for table in hlir.tables]

################################################################################
# Table application

for type in unique_everseen([comp['type'] for table in hlir.tables for smem in table.direct_meters + table.direct_counters for comp in smem.components]):
    #[ void apply_direct_smem_$type(register_uint32_t* smem, uint32_t value, char* table_name, char* smem_type_name, char* smem_name) {
    #[    debug("     : applying apply_direct_smem_$type(register_uint32_t (*smem)[1], uint32_t value, char* table_name, char* smem_type_name, char* smem_name)");
    #[ }

################################################################################

#{ void reset_vw_fields(SHORT_STDPARAMS) {
for hdr in hlir.header_instances.filter('urtype.is_metadata', False):
    for fld in hdr.urtype.fields:
        if fld.is_vw:
            #[ pd->headers[HDR(${hdr.name})].var_width_field_bitwidth = 0;
#} }

#{ void reset_headers(SHORT_STDPARAMS) {
for hdr in hlir.header_instances.filter('urtype.is_metadata', False):
Beispiel #6
0
#[ #include "gen_include.h"

#[ #include "util_packet.h"

# Note: this is for Digest_t
#[ #include "ctrl_plane_backend.h"

# TODO this should not be here in the indep section
#[ #include "dpdk_smem.h"

#[ #define FIELD(name, length) uint8_t name[(length + 7) / 8];


#{ typedef enum {
for table in hlir.tables:
    for action in unique_everseen(table.actions):
        #[     action_${action.action_object.name},
    if len(table.actions) == 0:
        #[     action_,
#} } actions_t;

for ctl in hlir.controls:
    for act in ctl.actions:
        #{ typedef struct {
        for param in act.parameters.parameters:
            paramtype = param.urtype
            #[     ${format_type(param.urtype, varname = param.name)};

        if len(act.parameters.parameters) == 0:
            #[     FIELD(DUMMY_FIELD, 0);
        #} } action_${act.name}_params_t;
Beispiel #7
0
#{ void ctrl_setdefault(struct p4_ctrl_msg* ctrl_m) {
for table in hlir.tables:
    #{ if (strcmp("${table.canonical_name}", ctrl_m->table_name) == 0) {
    #[     ${table.name}_set_default_table_action(ctrl_m);
    #[     return;
    #} }

#[     debug(" $$[warning]{}{!!!! Table set default}: $$[warning]{}{unknown table name} $$[table]{}{%s}\n", ctrl_m->table_name);
#{     #ifdef T4P4S_DEBUG
#[         debug_show_possible_tables();
#}     #endif
#} }

hack_i = 0
for smem in unique_everseen([smem for table, smem in hlir.all_counters]):
    for target in smem.smem_for:
        if not smem.smem_for[target]:
            continue
        hack_i += 1
        if hack_i%2==1:
            for c in smem.components:
                cname = c['name']
                if smem.smem_type not in ["register", "direct_counter", "direct_meter"]:
                    #[ uint32_t ctrl_${cname}[${smem.amount}];

#{ uint32_t* read_counter_value_by_name(char* counter_name, int* size, bool is_bytes){
#[ int i;
hack_i = 0
for smem in unique_everseen([smem for table, smem in hlir.all_counters]):
    for target in smem.smem_for:
Beispiel #8
0
        #[


#[ #pragma once

#[ #include "common.h"
#[ #include "aliases.h"
#[ #include "dpdk_smem.h"
#[ #include "gen_include.h"

#{ typedef struct global_state_s {
for table, smem in hlir.all_meters + hlir.all_counters:
    if smem.smem_type not in ["direct_counter", "direct_meter"]:
        continue
    #= gen_make_smem_code(smem, table)
for smem in unique_everseen([smem for table, smem in hlir.all_meters + hlir.all_counters if smem.smem_type not in ["direct_counter", "direct_meter"]]):
    #= gen_make_smem_code(smem)
for smem in hlir.registers:
    #= gen_make_smem_code(smem)



all_locals = unique_everseen([(param.name, format_type(param.type)) for table in hlir.tables for local in table.control.controlLocals["P4Action"] for param in local.parameters.parameters])
all_locals_dict = dict(all_locals)
if len(all_locals) != len(all_locals_dict):
    names = [name for name, _type in all_locals]
    dups = unique_everseen([name for name in names if names.count(name) > 1])
    addError("Collecting counters, meters, registers and controls' local variables", "The following names are used with different types, which is currently unsupported: {}".format(", ".join(dups)))

for locname, loctype in all_locals:
    #[     $loctype $locname;
Beispiel #9
0
        tname = hexpr.urtype.name
        name = hexpr._expr.path.name

        if hexpr.type.name in hlir.news.meta_types:
            hexpr.hdr_ref = hlir.allmetas
        elif (found := hlir.news.data.get(tname)):
            hexpr.hdr_ref = found
        elif (found := hlir.news.meta.get(tname)):
            hexpr.hdr_ref = hlir.allmetas
        elif (found := hexpr.parents.filter(
                'node_type',
            ('P4Parser', 'P4Control')).flatmap('locals').get(name)):
            hexpr.hdr_ref = found
        elif len(founds := [
                hdrt for hdrt in unique_everseen(
                    hlir.header_instances.map('urtype').filter(
                        'name', hexpr.type.name))
        ]) == 1:
            hexpr.hdr_ref = founds[0]
            hexpr.type.type_ref = founds[0].urtype

    for pe in hlir.groups.pathexprs.table:
        pe.table_ref = hlir.map('controls').flatmap('locals').get(pe.path.name)

    for mcexpr in hlir.groups.pathexprs.under_mcall:
        mname = mcexpr.path.name

        if (found := hlir.methods.get(mname)):
            mcexpr.action_ref = found
        else:
            mcexpr.action_ref = hlir.controls.flatmap('locals').get(mname)