From 90e3c0a1f3dc4cd9c23e923a2ecb0eb654fed5fe Mon Sep 17 00:00:00 2001 From: fruffy Date: Mon, 25 Nov 2024 20:45:14 -0500 Subject: [PATCH 1/3] Start to clean up Tofino specs. Signed-off-by: fruffy --- CMakeLists.txt | 4 +- backends/tofino/CMakeLists.txt | 2 +- backends/tofino/bf-p4c/CMakeLists.txt | 24 +- backends/tofino/bf-p4c/arch/arch.cpp | 2 +- backends/tofino/bf-p4c/arch/arch.h | 2 +- backends/tofino/bf-p4c/arch/bridge_metadata.h | 2 +- .../bf-p4c/arch/check_extern_invocation.cpp | 2 +- .../tofino/bf-p4c/arch/fromv1.0/mirror.cpp | 2 +- .../bf-p4c/arch/fromv1.0/parser_counter.cpp | 2 +- .../tofino/bf-p4c/arch/fromv1.0/phase0.cpp | 2 +- .../bf-p4c/arch/fromv1.0/primitives.cpp | 2 +- .../bf-p4c/arch/fromv1.0/programStructure.cpp | 2 +- .../tofino/bf-p4c/arch/fromv1.0/resubmit.cpp | 2 +- .../bf-p4c/arch/fromv1.0/v1_converters.cpp | 2 +- .../arch/fromv1.0/v1_program_structure.h | 2 +- .../tofino/bf-p4c/arch/intrinsic_metadata.h | 2 +- .../tofino/bf-p4c/arch/program_structure.h | 2 +- .../tofino/bf-p4c/arch/psa/programStructure.h | 2 +- backends/tofino/bf-p4c/arch/psa/psa.cpp | 2 +- backends/tofino/bf-p4c/arch/psa/psa.h | 2 +- backends/tofino/bf-p4c/arch/tna.cpp | 2 +- .../tofino/bf-p4c/arch/tna/primitives.cpp | 2 +- backends/tofino/bf-p4c/arch/v1model.cpp | 2 +- backends/tofino/bf-p4c/arch/v1model.h | 2 +- backends/tofino/bf-p4c/asm.cpp | 2 +- backends/tofino/bf-p4c/backend.cpp | 2 +- .../tofino/bf-p4c/common/bridged_packing.h | 2 +- .../tofino/bf-p4c/common/extract_maupipe.h | 2 +- backends/tofino/bf-p4c/common/utils.cpp | 2 +- .../control-plane/bfruntime_arch_handler.h | 2 +- .../bf-p4c/control-plane/bfruntime_ext.h | 2 +- backends/tofino/bf-p4c/device.cpp | 61 -- backends/tofino/bf-p4c/ir/arch.def | 2 +- backends/tofino/bf-p4c/ir/parde-lowered.def | 9 +- backends/tofino/bf-p4c/ir/tofino.def | 20 +- backends/tofino/bf-p4c/logging/manifest.h | 2 +- backends/tofino/bf-p4c/logging/phv_logging.h | 4 +- backends/tofino/bf-p4c/logging/resources.cpp | 8 +- backends/tofino/bf-p4c/logging/resources.h | 2 +- .../tofino/bf-p4c/logging/resources_clot.cpp | 2 +- .../bf-p4c/logging/resources_parser.cpp | 2 +- .../tofino/bf-p4c/logging/resources_parser.h | 2 +- backends/tofino/bf-p4c/mau/action_format.h | 2 +- .../tofino/bf-p4c/mau/build_power_graph.cpp | 2 +- .../bf-p4c/mau/determine_power_usage.cpp | 2 +- .../tofino/bf-p4c/mau/determine_power_usage.h | 2 +- .../bf-p4c/mau/finalize_mau_pred_deps_power.h | 2 +- backends/tofino/bf-p4c/mau/gateway.cpp | 33 - backends/tofino/bf-p4c/mau/gateway.h | 15 +- backends/tofino/bf-p4c/mau/input_xbar.cpp | 2 +- backends/tofino/bf-p4c/mau/input_xbar.h | 2 +- .../bf-p4c/mau/instruction_adjustment.cpp | 2 +- .../bf-p4c/mau/instruction_adjustment.h | 2 +- .../tofino/bf-p4c/mau/instruction_memory.cpp | 2 +- .../tofino/bf-p4c/mau/instruction_memory.h | 2 +- .../tofino/bf-p4c/mau/jbay_next_table.cpp | 2 +- backends/tofino/bf-p4c/mau/mau_power.cpp | 2 +- backends/tofino/bf-p4c/mau/mau_power.h | 2 +- backends/tofino/bf-p4c/mau/memories.cpp | 2 +- backends/tofino/bf-p4c/mau/payload_gateway.h | 2 +- .../tofino/bf-p4c/mau/resource_estimate.cpp | 3 +- backends/tofino/bf-p4c/mau/stateful_alu.cpp | 37 - backends/tofino/bf-p4c/mau/stateful_alu.h | 20 +- .../bf-p4c/mau/table_dependency_graph.cpp | 2 +- .../bf-p4c/mau/table_dependency_graph.h | 2 +- backends/tofino/bf-p4c/mau/table_format.cpp | 4 +- .../tofino/bf-p4c/mau/table_placement.cpp | 4 +- backends/tofino/bf-p4c/mau/table_summary.cpp | 2 +- backends/tofino/bf-p4c/mau/table_summary.h | 2 +- .../tofino/bf-p4c/mau/tofino/asm_output.cpp | 12 +- .../tofino/bf-p4c/mau/tofino/input_xbar.cpp | 332 +++---- .../tofino/bf-p4c/mau/tofino/input_xbar.h | 382 ++++---- .../tofino/bf-p4c/mau/tofino/memories.cpp | 2 +- .../tofino/bf-p4c/mau/walk_power_graph.cpp | 4 +- backends/tofino/bf-p4c/mau/walk_power_graph.h | 2 +- .../bf-p4c/midend/check_header_alignment.cpp | 2 +- .../bf-p4c/midend/check_unsupported.cpp | 2 +- .../bf-p4c/midend/collect_pipelines.cpp | 2 +- .../bf-p4c/midend/desugar_varbit_extract.cpp | 2 +- .../midend/drop_packet_with_mirror_engine.cpp | 2 +- .../midend/drop_packet_with_mirror_engine.h | 2 +- .../midend/initialize_mirror_io_select.h | 2 +- .../midend/parser_enforce_depth_req.cpp | 2 +- .../bf-p4c/midend/ping_pong_generation.h | 2 +- .../bf-p4c/midend/register_read_write.cpp | 2 +- ...rewrite_egress_intrinsic_metadata_header.h | 2 +- .../tofino/bf-p4c/midend/simplify_nested_if.h | 2 +- backends/tofino/bf-p4c/p4c-barefoot.cpp | 5 +- .../bf-p4c/parde/add_parde_metadata.cpp | 2 +- .../tofino/bf-p4c/parde/adjust_extract.cpp | 2 +- .../bf-p4c/parde/allocate_parser_checksum.cpp | 2 +- .../parde/allocate_parser_match_register.cpp | 190 ++-- .../bf-p4c/parde/check_parser_multi_write.cpp | 2 +- backends/tofino/bf-p4c/parde/clot/clot.h | 2 +- .../tofino/bf-p4c/parde/clot/clot_info.cpp | 2 +- .../clot/merge_desugared_varbit_valids.cpp | 2 +- backends/tofino/bf-p4c/parde/decaf.cpp | 2 +- .../bf-p4c/parde/deparser_checksum_update.cpp | 2 +- .../tofino/bf-p4c/parde/deparser_output.cpp | 2 +- backends/tofino/bf-p4c/parde/dump_parser.h | 2 +- .../tofino/bf-p4c/parde/extract_deparser.cpp | 2 +- .../tofino/bf-p4c/parde/extract_deparser.h | 4 +- .../tofino/bf-p4c/parde/extract_parser.cpp | 2 +- backends/tofino/bf-p4c/parde/extract_parser.h | 2 +- backends/tofino/bf-p4c/parde/field_packing.h | 2 +- .../bf-p4c/parde/infer_payload_offset.cpp | 2 +- backends/tofino/bf-p4c/parde/lower_parser.cpp | 2 +- .../lowered/compute_buffer_requirements.cpp | 2 +- .../lowered/compute_lowered_deparser_ir.cpp | 2 +- .../parde/lowered/eliminate_empty_states.cpp | 2 +- .../lowered/hoist_common_match_operations.h | 2 +- backends/tofino/bf-p4c/parde/marshal.h | 2 +- .../tofino/bf-p4c/parde/match_register.cpp | 32 +- backends/tofino/bf-p4c/parde/match_register.h | 28 +- backends/tofino/bf-p4c/parde/parde_utils.h | 2 +- .../bf-p4c/parde/parser_header_sequences.h | 2 +- backends/tofino/bf-p4c/parde/parser_info.h | 2 +- .../tofino/bf-p4c/parde/parser_loops_info.cpp | 2 +- .../bf-p4c/parde/resolve_negative_extract.h | 2 +- .../bf-p4c/phv/action_phv_constraints.cpp | 2 +- backends/tofino/bf-p4c/phv/allocate_phv.cpp | 7 +- backends/tofino/bf-p4c/phv/allocate_phv.h | 4 +- .../allocate_temps_and_finalize_liverange.cpp | 4 +- .../bf-p4c/phv/analysis/dark_live_range.h | 2 +- .../bf-p4c/phv/analysis/dominator_tree.cpp | 2 +- .../bf-p4c/phv/analysis/jbay_phv_analysis.cpp | 2 +- backends/tofino/bf-p4c/phv/analysis/mocha.cpp | 4 +- .../phv/analysis/non_mocha_dark_fields.h | 2 +- backends/tofino/bf-p4c/phv/asm_output.cpp | 4 +- backends/tofino/bf-p4c/phv/asm_output.h | 2 +- .../bf-p4c/phv/cluster_phv_operations.h | 2 +- .../phv/create_thread_local_instances.cpp | 2 +- .../bf-p4c/phv/fieldslice_live_range.cpp | 4 +- .../tofino/bf-p4c/phv/fieldslice_live_range.h | 2 +- .../phv/finalize_physical_liverange.cpp | 4 +- .../bf-p4c/phv/finalize_physical_liverange.h | 2 +- .../tofino/bf-p4c/phv/live_range_split.cpp | 2 +- backends/tofino/bf-p4c/phv/make_clusters.h | 2 +- .../bf-p4c/phv/parser_extract_balance_score.h | 2 +- backends/tofino/bf-p4c/phv/phv.cpp | 259 +----- backends/tofino/bf-p4c/phv/phv.h | 306 +------ backends/tofino/bf-p4c/phv/phv_analysis.cpp | 86 +- backends/tofino/bf-p4c/phv/phv_analysis.h | 3 + backends/tofino/bf-p4c/phv/phv_fields.h | 4 +- .../tofino/bf-p4c/phv/phv_parde_mau_use.h | 4 +- .../bf-p4c/phv/pragma/pa_container_type.cpp | 2 +- .../bf-p4c/phv/pragma/pa_container_type.h | 2 +- backends/tofino/bf-p4c/phv/split_padding.cpp | 2 +- .../bf-p4c/phv/utils/live_range_report.h | 2 +- .../tofino/bf-p4c/phv/utils/slice_alloc.cpp | 2 +- .../tofino/bf-p4c/phv/utils/slice_alloc.h | 2 +- backends/tofino/bf-p4c/phv/utils/utils.cpp | 4 +- backends/tofino/bf-p4c/phv/utils/utils.h | 4 +- .../tofino/bf-p4c/phv/v2/allocator_base.cpp | 4 +- .../tofino/bf-p4c/phv/v2/allocator_base.h | 2 +- .../tofino/bf-p4c/phv/v2/allocator_metrics.h | 2 +- .../tofino/bf-p4c/phv/v2/greedy_allocator.cpp | 2 +- .../tofino/bf-p4c/phv/v2/greedy_tx_score.cpp | 6 +- .../phv/v2/parser_packing_validator.cpp | 4 +- backends/tofino/bf-p4c/phv/v2/phv_kit.h | 2 +- .../bf-p4c/phv/v2/trivial_allocator.cpp | 4 +- backends/tofino/bf-p4c/phv/v2/tx_score.cpp | 2 +- backends/tofino/bf-p4c/phv/v2/utils_v2.h | 2 +- .../tofino/bf-p4c/phv/validate_allocation.cpp | 4 +- .../bf-p4c/{arch => specs}/arch_spec.cpp | 2 +- .../tofino/bf-p4c/{arch => specs}/arch_spec.h | 9 +- backends/tofino/bf-p4c/specs/device.cpp | 131 +++ backends/tofino/bf-p4c/{ => specs}/device.h | 85 +- .../tofino/bf-p4c/{ir => specs}/gress.cpp | 0 backends/tofino/bf-p4c/{ir => specs}/gress.h | 6 +- .../match_register_spec.cpp} | 28 +- .../tofino/bf-p4c/specs/match_register_spec.h | 60 ++ .../tofino/bf-p4c/{mau => specs}/mau_spec.cpp | 18 +- .../tofino/bf-p4c/{mau => specs}/mau_spec.h | 67 +- .../bf-p4c/{parde => specs}/parde_spec.h | 58 +- backends/tofino/bf-p4c/specs/phv.cpp | 271 ++++++ backends/tofino/bf-p4c/specs/phv.h | 330 +++++++ .../tofino/bf-p4c/{phv => specs}/phv_spec.cpp | 137 +-- .../tofino/bf-p4c/{phv => specs}/phv_spec.h | 39 +- .../tofino/bf-p4c/{mau => specs}/power_spec.h | 6 +- .../test/gtest/action_format_helper.cpp | 2 +- .../bf-p4c/test/gtest/bf_gtest_helpers.cpp | 2 +- .../bf-p4c/test/gtest/container_action.cpp | 2 +- .../bf-p4c/test/gtest/dominator_tree.cpp | 2 +- .../tofino/bf-p4c/test/gtest/input_xbar.cpp | 2 +- .../bf-p4c/test/gtest/meta_live_range.cpp | 2 +- .../bf-p4c/test/gtest/phv/greedy_tx_score.cpp | 2 +- .../test/gtest/phv/slicing/iterator.cpp | 2 +- .../tofino/bf-p4c/test/gtest/phv_crush.cpp | 4 +- .../tofino/bf-p4c/test/gtest/phv_field.cpp | 2 +- .../tofino/bf-p4c/test/gtest/phv_jbay.cpp | 2 +- .../tofino/bf-p4c/test/gtest/phv_tofino.cpp | 2 +- .../bf-p4c/test/gtest/tofino_gtest_utils.h | 14 +- .../src/dynamic_hash/bfn_hash_algorithm.c | 281 ------ .../src/dynamic_hash/bfn_hash_algorithm.cpp | 2 + .../bf-utils/src/dynamic_hash/dynamic_hash.c | 831 ------------------ 196 files changed, 1860 insertions(+), 2741 deletions(-) delete mode 100644 backends/tofino/bf-p4c/device.cpp rename backends/tofino/bf-p4c/{arch => specs}/arch_spec.cpp (99%) rename backends/tofino/bf-p4c/{arch => specs}/arch_spec.h (95%) create mode 100644 backends/tofino/bf-p4c/specs/device.cpp rename backends/tofino/bf-p4c/{ => specs}/device.h (86%) rename backends/tofino/bf-p4c/{ir => specs}/gress.cpp (100%) rename backends/tofino/bf-p4c/{ir => specs}/gress.h (94%) rename backends/tofino/bf-p4c/{mau/tofino/mau_spec.cpp => specs/match_register_spec.cpp} (54%) create mode 100644 backends/tofino/bf-p4c/specs/match_register_spec.h rename backends/tofino/bf-p4c/{mau => specs}/mau_spec.cpp (91%) rename backends/tofino/bf-p4c/{mau => specs}/mau_spec.h (69%) rename backends/tofino/bf-p4c/{parde => specs}/parde_spec.h (94%) create mode 100644 backends/tofino/bf-p4c/specs/phv.cpp create mode 100644 backends/tofino/bf-p4c/specs/phv.h rename backends/tofino/bf-p4c/{phv => specs}/phv_spec.cpp (84%) rename backends/tofino/bf-p4c/{phv => specs}/phv_spec.h (94%) rename backends/tofino/bf-p4c/{mau => specs}/power_spec.h (98%) delete mode 100644 backends/tofino/bf-utils/src/dynamic_hash/bfn_hash_algorithm.c delete mode 100644 backends/tofino/bf-utils/src/dynamic_hash/dynamic_hash.c diff --git a/CMakeLists.txt b/CMakeLists.txt index bc21ef31e7..c46e6917dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -404,6 +404,8 @@ add_subdirectory (ir) # add extensions - before the frontends as they produce IR and extra frontend sources set(EXTENSION_IR_SOURCES) +# extra libraries that need to be linked with the generated IR. +set(EXTENSION_IR_LIBS) # extra sources that need to be linked directly into p4test so that # extensions can provide specific conversions (e.g., for externs) set(EXTENSION_P4_14_CONV_SOURCES) @@ -534,7 +536,7 @@ add_custom_target(genIR DEPENDS ${IR_GENERATED_SRCS}) set_source_files_properties(${IR_GENERATOR} PROPERTIES GENERATED TRUE) add_library(ir-generated OBJECT ${IR_GENERATED_SRCS} ${EXTENSION_IR_SOURCES}) add_dependencies(ir-generated ir genIR) -target_link_libraries(ir-generated PUBLIC ir ${P4C_LIB_DEPS}) +target_link_libraries(ir-generated PUBLIC ir ${P4C_LIB_DEPS} ${EXTENSION_IR_LIBS}) ######################################## IR Generation End ######################################## diff --git a/backends/tofino/CMakeLists.txt b/backends/tofino/CMakeLists.txt index 2ff4daed47..2e3491e481 100644 --- a/backends/tofino/CMakeLists.txt +++ b/backends/tofino/CMakeLists.txt @@ -218,7 +218,6 @@ set (BF_P4C_IR_SRCS bf-p4c/ir/control_flow_visitor.cpp bf-p4c/ir/ir_enums.cpp bf-p4c/ir/gateway_control_flow.cpp - bf-p4c/ir/gress.cpp bf-p4c/ir/mau.cpp bf-p4c/ir/thread_visitor.cpp bf-p4c/ir/tofino.cpp @@ -238,5 +237,6 @@ foreach(src IN LISTS BF_P4C_IR_SRCS) set(QUAL_BF_P4C_IR_SRCS ${QUAL_BF_P4C_IR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${src}) endforeach() set(EXTENSION_IR_SOURCES ${EXTENSION_IR_SOURCES} ${QUAL_BF_P4C_IR_SRCS} PARENT_SCOPE) +set(EXTENSION_IR_LIBS ${EXTENSION_IR_LIBS} tofinospecs PARENT_SCOPE) add_subdirectory(bf-p4c) diff --git a/backends/tofino/bf-p4c/CMakeLists.txt b/backends/tofino/bf-p4c/CMakeLists.txt index df143722cd..01c3565346 100644 --- a/backends/tofino/bf-p4c/CMakeLists.txt +++ b/backends/tofino/bf-p4c/CMakeLists.txt @@ -12,7 +12,7 @@ # specific language governing permissions and limitations under the License. # # SPDX-License-Identifier: Apache-2.0 -# # # #### Barefoot back-end +# # ##### Barefoot back-end MESSAGE("-- Adding p4c-barefoot") @@ -90,6 +90,19 @@ set (P4C_LIB_DEPS ${P4C_LIB_DEPS} PARENT_SCOPE) add_subdirectory(logging) +set (BF_P4C_SPEC_SRCS + specs/arch_spec.cpp + specs/device.cpp + specs/gress.cpp + specs/mau_spec.cpp + specs/match_register_spec.cpp + specs/phv.cpp + specs/phv_spec.cpp +) + +add_library(tofinospecs STATIC ${BF_P4C_SPEC_SRCS}) +target_link_libraries(tofinospecs PUBLIC p4ctoolkit) + set (BF_P4C_MIDEND_SRCS midend/annotate_with_in_hash.cpp midend/check_design_pattern.cpp @@ -214,7 +227,6 @@ set (BF_P4C_BACKEND_MAU_SRCS mau/jbay_next_table.cpp mau/mau_alloc.cpp mau/mau_power.cpp - mau/mau_spec.cpp mau/memories.cpp mau/payload_gateway.cpp mau/reduction_or.cpp @@ -242,7 +254,6 @@ set (BF_P4C_BACKEND_MAU_TOFINO_SRCS mau/tofino/action_data_bus.cpp mau/tofino/asm_output.cpp mau/tofino/input_xbar.cpp - mau/tofino/mau_spec.cpp mau/tofino/memories.cpp ) @@ -325,7 +336,6 @@ set (BF_P4C_BACKEND_PHV_SRCS phv/phv_analysis.cpp phv/phv_fields.cpp phv/phv_parde_mau_use.cpp - phv/phv_spec.cpp phv/split_padding.cpp phv/table_phv_constraints.cpp phv/validate_allocation.cpp @@ -391,7 +401,6 @@ set (BF_P4C_BACKEND_PHV_SRCS set (BF_P4C_BACKEND_ARCH_SRCS arch/arch.cpp - arch/arch_spec.cpp arch/add_t2na_meta.cpp arch/intrinsic_metadata.cpp arch/bridge_metadata.cpp @@ -443,7 +452,6 @@ set (BF_P4C_BACKEND_MAIN_SRCS asm.cpp backend.cpp bf-p4c-options.cpp - device.cpp midend.cpp ) @@ -806,7 +814,7 @@ endif() install (FILES ${P4C_BINARY_DIR}/p4c_src/main.py DESTINATION ${P4C_ARTIFACTS_OUTPUT_DIRECTORY}/p4c_src) -# # # ############# Proto +# # ############## Proto set (BFN_P4RUNTIME_DIR ${CMAKE_CURRENT_SOURCE_DIR}/control-plane/proto) set (BFN_P4RUNTIME_INFO_PROTO ${BFN_P4RUNTIME_DIR}/barefoot/p4info.proto) set (BFN_P4RUNTIME_INFO_GEN_SRCS ${P4C_BINARY_DIR}/control-plane/barefoot/p4info.pb.cc) @@ -840,7 +848,7 @@ target_link_libraries(bfn_p4runtime PUBLIC controlplane-gen PRIVATE absl::prefet set_source_files_properties(${BFN_P4RUNTIME_INFO_GEN_SRCS} PROPERTIES GENERATED TRUE) add_dependencies(bfn_p4runtime barefootdir controlplane) -# # # ############# Testing +# # ############## Testing if (ENABLE_GTESTS) # # Tofino-specific GTests. diff --git a/backends/tofino/bf-p4c/arch/arch.cpp b/backends/tofino/bf-p4c/arch/arch.cpp index 4bc5fbdd17..09a5511726 100644 --- a/backends/tofino/bf-p4c/arch/arch.cpp +++ b/backends/tofino/bf-p4c/arch/arch.cpp @@ -26,7 +26,7 @@ #include "backends/tofino/bf-p4c/arch/v1model.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/common/pragma/collect_global_pragma.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4/methodInstance.h" #include "ir/declaration.h" #include "ir/id.h" diff --git a/backends/tofino/bf-p4c/arch/arch.h b/backends/tofino/bf-p4c/arch/arch.h index f9c60440bb..5db027f625 100644 --- a/backends/tofino/bf-p4c/arch/arch.h +++ b/backends/tofino/bf-p4c/arch/arch.h @@ -30,9 +30,9 @@ #include "backends/tofino/bf-p4c/arch/program_structure.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/lib/assoc.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/options.h" #include "frontends/common/resolveReferences/referenceMap.h" #include "frontends/common/resolveReferences/resolveReferences.h" diff --git a/backends/tofino/bf-p4c/arch/bridge_metadata.h b/backends/tofino/bf-p4c/arch/bridge_metadata.h index f64a971c37..21aa3ae571 100644 --- a/backends/tofino/bf-p4c/arch/bridge_metadata.h +++ b/backends/tofino/bf-p4c/arch/bridge_metadata.h @@ -20,8 +20,8 @@ #define BF_P4C_ARCH_BRIDGE_METADATA_H_ #include "backends/tofino/bf-p4c/arch/program_structure.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/midend/path_linearizer.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "frontends/p4/evaluator/evaluator.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/arch/check_extern_invocation.cpp b/backends/tofino/bf-p4c/arch/check_extern_invocation.cpp index 982a8e10e7..77d1f2d61f 100644 --- a/backends/tofino/bf-p4c/arch/check_extern_invocation.cpp +++ b/backends/tofino/bf-p4c/arch/check_extern_invocation.cpp @@ -18,7 +18,7 @@ #include "check_extern_invocation.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/bitvec.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/arch/fromv1.0/mirror.cpp b/backends/tofino/bf-p4c/arch/fromv1.0/mirror.cpp index daa2e13de0..f02b8e90dc 100644 --- a/backends/tofino/bf-p4c/arch/fromv1.0/mirror.cpp +++ b/backends/tofino/bf-p4c/arch/fromv1.0/mirror.cpp @@ -21,8 +21,8 @@ #include "backends/tofino/bf-p4c/arch/bridge_metadata.h" #include "backends/tofino/bf-p4c/arch/intrinsic_metadata.h" #include "backends/tofino/bf-p4c/common/ir_utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/lib/pad_alignment.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4-14/fromv1.0/v1model.h" #include "frontends/p4/cloner.h" #include "frontends/p4/coreLibrary.h" diff --git a/backends/tofino/bf-p4c/arch/fromv1.0/parser_counter.cpp b/backends/tofino/bf-p4c/arch/fromv1.0/parser_counter.cpp index 1bd78453d3..63cc207b9e 100644 --- a/backends/tofino/bf-p4c/arch/fromv1.0/parser_counter.cpp +++ b/backends/tofino/bf-p4c/arch/fromv1.0/parser_counter.cpp @@ -21,7 +21,7 @@ #include #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/arch/fromv1.0/phase0.cpp b/backends/tofino/bf-p4c/arch/fromv1.0/phase0.cpp index d8fd7e827c..82a61505e0 100644 --- a/backends/tofino/bf-p4c/arch/fromv1.0/phase0.cpp +++ b/backends/tofino/bf-p4c/arch/fromv1.0/phase0.cpp @@ -24,12 +24,12 @@ #include "backends/tofino/bf-p4c/arch/fromv1.0/programStructure.h" #include "backends/tofino/bf-p4c/arch/tna.h" #include "backends/tofino/bf-p4c/common/asm_output.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/lib/pad_alignment.h" #include "backends/tofino/bf-p4c/midend/path_linearizer.h" #include "backends/tofino/bf-p4c/midend/type_categories.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" #include "backends/tofino/bf-p4c/parde/field_packing.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/resolveReferences/referenceMap.h" #include "frontends/p4-14/fromv1.0/v1model.h" #include "frontends/p4/cloner.h" diff --git a/backends/tofino/bf-p4c/arch/fromv1.0/primitives.cpp b/backends/tofino/bf-p4c/arch/fromv1.0/primitives.cpp index 023aa57d55..1d5e9c31b4 100644 --- a/backends/tofino/bf-p4c/arch/fromv1.0/primitives.cpp +++ b/backends/tofino/bf-p4c/arch/fromv1.0/primitives.cpp @@ -20,7 +20,7 @@ #include "backends/tofino/bf-p4c/arch/fromv1.0/programStructure.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4-14/fromv1.0/converters.h" namespace P4 { diff --git a/backends/tofino/bf-p4c/arch/fromv1.0/programStructure.cpp b/backends/tofino/bf-p4c/arch/fromv1.0/programStructure.cpp index 363aca7a32..55c035d305 100644 --- a/backends/tofino/bf-p4c/arch/fromv1.0/programStructure.cpp +++ b/backends/tofino/bf-p4c/arch/fromv1.0/programStructure.cpp @@ -23,7 +23,7 @@ #include "backends/tofino/bf-p4c/arch/fromv1.0/phase0.h" #include "backends/tofino/bf-p4c/arch/intrinsic_metadata.h" #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4-14/fromv1.0/converters.h" #include "frontends/p4-14/header_type.h" #include "frontends/p4-14/typecheck.h" diff --git a/backends/tofino/bf-p4c/arch/fromv1.0/resubmit.cpp b/backends/tofino/bf-p4c/arch/fromv1.0/resubmit.cpp index 30f3ac7645..fbedc45e65 100644 --- a/backends/tofino/bf-p4c/arch/fromv1.0/resubmit.cpp +++ b/backends/tofino/bf-p4c/arch/fromv1.0/resubmit.cpp @@ -19,8 +19,8 @@ #include "resubmit.h" #include "backends/tofino/bf-p4c/arch/intrinsic_metadata.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4-14/fromv1.0/v1model.h" #include "frontends/p4/cloner.h" #include "frontends/p4/coreLibrary.h" diff --git a/backends/tofino/bf-p4c/arch/fromv1.0/v1_converters.cpp b/backends/tofino/bf-p4c/arch/fromv1.0/v1_converters.cpp index 61722358cc..030a8196dc 100644 --- a/backends/tofino/bf-p4c/arch/fromv1.0/v1_converters.cpp +++ b/backends/tofino/bf-p4c/arch/fromv1.0/v1_converters.cpp @@ -22,7 +22,7 @@ #include "backends/tofino/bf-p4c/arch/bridge_metadata.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/map.h" #include "lib/ordered_map.h" #include "v1_program_structure.h" diff --git a/backends/tofino/bf-p4c/arch/fromv1.0/v1_program_structure.h b/backends/tofino/bf-p4c/arch/fromv1.0/v1_program_structure.h index 5a34ef47fd..d3d64b096d 100644 --- a/backends/tofino/bf-p4c/arch/fromv1.0/v1_program_structure.h +++ b/backends/tofino/bf-p4c/arch/fromv1.0/v1_program_structure.h @@ -20,7 +20,7 @@ #define BACKENDS_TOFINO_BF_P4C_ARCH_FROMV1_0_V1_PROGRAM_STRUCTURE_H_ #include "backends/tofino/bf-p4c/arch/program_structure.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "frontends/p4/evaluator/evaluator.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/arch/intrinsic_metadata.h b/backends/tofino/bf-p4c/arch/intrinsic_metadata.h index 2746ba257d..8a2b9fd50a 100644 --- a/backends/tofino/bf-p4c/arch/intrinsic_metadata.h +++ b/backends/tofino/bf-p4c/arch/intrinsic_metadata.h @@ -20,8 +20,8 @@ #define BF_P4C_ARCH_INTRINSIC_METADATA_H_ #include "backends/tofino/bf-p4c/arch/bridge_metadata.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4/cloner.h" #include "frontends/p4/typeChecking/typeChecker.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/arch/program_structure.h b/backends/tofino/bf-p4c/arch/program_structure.h index 423896b656..172870bc29 100644 --- a/backends/tofino/bf-p4c/arch/program_structure.h +++ b/backends/tofino/bf-p4c/arch/program_structure.h @@ -19,7 +19,7 @@ #ifndef BACKENDS_TOFINO_BF_P4C_ARCH_PROGRAM_STRUCTURE_H_ #define BACKENDS_TOFINO_BF_P4C_ARCH_PROGRAM_STRUCTURE_H_ -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "frontends/p4/evaluator/evaluator.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/arch/psa/programStructure.h b/backends/tofino/bf-p4c/arch/psa/programStructure.h index d1bc4bf697..9e46d01ff3 100644 --- a/backends/tofino/bf-p4c/arch/psa/programStructure.h +++ b/backends/tofino/bf-p4c/arch/psa/programStructure.h @@ -21,9 +21,9 @@ #include "backends/tofino/bf-p4c/arch/program_structure.h" #include "backends/tofino/bf-p4c/arch/psa/psa_model.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/midend/path_linearizer.h" #include "backends/tofino/bf-p4c/midend/type_categories.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "frontends/p4/evaluator/evaluator.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/arch/psa/psa.cpp b/backends/tofino/bf-p4c/arch/psa/psa.cpp index dd430a6a50..aaa4dcaa57 100644 --- a/backends/tofino/bf-p4c/arch/psa/psa.cpp +++ b/backends/tofino/bf-p4c/arch/psa/psa.cpp @@ -25,8 +25,8 @@ #include "backends/tofino/bf-p4c/arch/fromv1.0/add_metadata_parser_states.h" #include "backends/tofino/bf-p4c/arch/intrinsic_metadata.h" #include "backends/tofino/bf-p4c/arch/rewrite_action_selector.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" #include "lib/bitops.h" #include "midend/convertEnums.h" diff --git a/backends/tofino/bf-p4c/arch/psa/psa.h b/backends/tofino/bf-p4c/arch/psa/psa.h index c5af3d7dd6..7b31a90808 100644 --- a/backends/tofino/bf-p4c/arch/psa/psa.h +++ b/backends/tofino/bf-p4c/arch/psa/psa.h @@ -30,7 +30,7 @@ #include "backends/tofino/bf-p4c/arch/arch.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/options.h" #include "frontends/p4/cloner.h" #include "frontends/p4/coreLibrary.h" diff --git a/backends/tofino/bf-p4c/arch/tna.cpp b/backends/tofino/bf-p4c/arch/tna.cpp index 538ca939c2..196d1e1acb 100644 --- a/backends/tofino/bf-p4c/arch/tna.cpp +++ b/backends/tofino/bf-p4c/arch/tna.cpp @@ -23,9 +23,9 @@ #include "backends/tofino/bf-p4c/arch/fromv1.0/phase0.h" #include "backends/tofino/bf-p4c/arch/rewrite_action_selector.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" #include "backends/tofino/bf-p4c/parde/field_packing.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "frontends/p4/cloner.h" #include "frontends/p4/evaluator/evaluator.h" diff --git a/backends/tofino/bf-p4c/arch/tna/primitives.cpp b/backends/tofino/bf-p4c/arch/tna/primitives.cpp index 0835ca5f1e..132a8ba0c1 100644 --- a/backends/tofino/bf-p4c/arch/tna/primitives.cpp +++ b/backends/tofino/bf-p4c/arch/tna/primitives.cpp @@ -21,7 +21,7 @@ #include "backends/tofino/bf-p4c/arch/fromv1.0/programStructure.h" #include "backends/tofino/bf-p4c/arch/intrinsic_metadata.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4-14/fromv1.0/converters.h" // Converters for converting from P4-14 to TNA For a full list of supported diff --git a/backends/tofino/bf-p4c/arch/v1model.cpp b/backends/tofino/bf-p4c/arch/v1model.cpp index e6eb2e8aa6..f0f9a9fae2 100644 --- a/backends/tofino/bf-p4c/arch/v1model.cpp +++ b/backends/tofino/bf-p4c/arch/v1model.cpp @@ -27,9 +27,9 @@ #include "backends/tofino/bf-p4c/arch/fromv1.0/checksum.h" #include "backends/tofino/bf-p4c/arch/fromv1.0/parser_counter.h" #include "backends/tofino/bf-p4c/arch/program_structure.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/midend.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "ir/annotations.h" #include "lib/bitops.h" diff --git a/backends/tofino/bf-p4c/arch/v1model.h b/backends/tofino/bf-p4c/arch/v1model.h index 903a33b52a..f5c0098186 100644 --- a/backends/tofino/bf-p4c/arch/v1model.h +++ b/backends/tofino/bf-p4c/arch/v1model.h @@ -32,7 +32,7 @@ #include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" #include "backends/tofino/bf-p4c/common/pragma/collect_global_pragma.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/options.h" #include "frontends/p4/cloner.h" #include "frontends/p4/coreLibrary.h" diff --git a/backends/tofino/bf-p4c/asm.cpp b/backends/tofino/bf-p4c/asm.cpp index bea460b025..f65690955d 100644 --- a/backends/tofino/bf-p4c/asm.cpp +++ b/backends/tofino/bf-p4c/asm.cpp @@ -29,7 +29,7 @@ // #include "bf-asm/version.h" #include "backends/tofino/bf-p4c/common/run_id.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/backend.cpp b/backends/tofino/bf-p4c/backend.cpp index b6827fe75a..ab4a1ff618 100644 --- a/backends/tofino/bf-p4c/backend.cpp +++ b/backends/tofino/bf-p4c/backend.cpp @@ -79,7 +79,6 @@ #include "backends/tofino/bf-p4c/common/multiple_apply.h" #include "backends/tofino/bf-p4c/common/size_of.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/logging/filelog.h" #include "backends/tofino/bf-p4c/logging/phv_logging.h" #include "backends/tofino/bf-p4c/mau/adjust_byte_count.h" @@ -128,6 +127,7 @@ #include "backends/tofino/bf-p4c/phv/split_padding.h" #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" #include "backends/tofino/bf-p4c/phv/v2/metadata_initialization.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/pass_manager.h" #include "lib/indent.h" diff --git a/backends/tofino/bf-p4c/common/bridged_packing.h b/backends/tofino/bf-p4c/common/bridged_packing.h index 6c42594959..eeef8ef87d 100644 --- a/backends/tofino/bf-p4c/common/bridged_packing.h +++ b/backends/tofino/bf-p4c/common/bridged_packing.h @@ -33,8 +33,8 @@ #include "backends/tofino/bf-p4c/midend/type_checker.h" #include "backends/tofino/bf-p4c/phv/action_phv_constraints.h" #include "backends/tofino/bf-p4c/phv/constraints/constraints.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "frontends/common/resolveReferences/referenceMap.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "frontends/p4/methodInstance.h" diff --git a/backends/tofino/bf-p4c/common/extract_maupipe.h b/backends/tofino/bf-p4c/common/extract_maupipe.h index 8a266dc5c2..af7d093f3e 100644 --- a/backends/tofino/bf-p4c/common/extract_maupipe.h +++ b/backends/tofino/bf-p4c/common/extract_maupipe.h @@ -24,11 +24,11 @@ #include "backends/tofino/bf-p4c/arch/arch.h" #include "backends/tofino/bf-p4c/arch/fromv1.0/mirror.h" #include "backends/tofino/bf-p4c/arch/fromv1.0/resubmit.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/lib/assoc.h" #include "backends/tofino/bf-p4c/logging/source_info_logging.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/midend/param_binding.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/options.h" #include "frontends/common/resolveReferences/referenceMap.h" #include "frontends/p4/externInstance.h" diff --git a/backends/tofino/bf-p4c/common/utils.cpp b/backends/tofino/bf-p4c/common/utils.cpp index 99a88c192a..4764af4d83 100644 --- a/backends/tofino/bf-p4c/common/utils.cpp +++ b/backends/tofino/bf-p4c/common/utils.cpp @@ -21,7 +21,7 @@ #include #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" bool ghost_only_on_other_pipes(int pipe_id) { if (pipe_id < 0) return false; // invalid pipe id diff --git a/backends/tofino/bf-p4c/control-plane/bfruntime_arch_handler.h b/backends/tofino/bf-p4c/control-plane/bfruntime_arch_handler.h index 7ea94372a2..cb7c55e39a 100644 --- a/backends/tofino/bf-p4c/control-plane/bfruntime_arch_handler.h +++ b/backends/tofino/bf-p4c/control-plane/bfruntime_arch_handler.h @@ -33,7 +33,7 @@ #include "backends/tofino/bf-p4c/control-plane/bfruntime.h" #include "backends/tofino/bf-p4c/control-plane/p4runtime_force_std.h" #include "backends/tofino/bf-p4c/control-plane/runtime.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "barefoot/p4info.pb.h" #include "control-plane/flattenHeader.h" #include "control-plane/p4RuntimeArchHandler.h" diff --git a/backends/tofino/bf-p4c/control-plane/bfruntime_ext.h b/backends/tofino/bf-p4c/control-plane/bfruntime_ext.h index 82a4aee7c9..f9746f579a 100644 --- a/backends/tofino/bf-p4c/control-plane/bfruntime_ext.h +++ b/backends/tofino/bf-p4c/control-plane/bfruntime_ext.h @@ -24,7 +24,7 @@ #pragma GCC diagnostic ignored "-Wpedantic" #include "barefoot/p4info.pb.h" #pragma GCC diagnostic pop -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "backends/tofino/bf-utils/include/dynamic_hash/bfn_hash_algorithm.h" #include "bfruntime.h" diff --git a/backends/tofino/bf-p4c/device.cpp b/backends/tofino/bf-p4c/device.cpp deleted file mode 100644 index c3583f50e0..0000000000 --- a/backends/tofino/bf-p4c/device.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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 - */ - -#include "backends/tofino/bf-p4c/device.h" - -#include - -#include "lib/error.h" - -Device *Device::instance_ = nullptr; -int Device::numStagesRuntimeOverride_ = 0; - -void Device::init(cstring name) { - instance_ = nullptr; - - std::string lower_name(name); - std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); - - if (lower_name == "tofino") - instance_ = new TofinoDevice(); - else if (lower_name == "tofino2") - instance_ = new JBayDevice(); -#if BAREFOOT_INTERNAL - else if (lower_name == "tofino2h") - instance_ = new JBayHDevice(); -#endif /* BAREFOOT_INTERNAL */ - else if (lower_name == "tofino2m") - instance_ = new JBayMDevice(); - else if (lower_name == "tofino2u") - instance_ = new JBayUDevice(); - else if (lower_name == "tofino2a0") - instance_ = new JBayA0Device(); - else - BUG("Unknown device %s", name); -} - -void Device::overrideNumStages(int num) { - int realNumStages = Device::get().getNumStages(); - if (num < 0 || num > realNumStages) { - ::error("Trying to override mau stages count to %d but device is capped to %d.", num, - realNumStages); - return; - } - - numStagesRuntimeOverride_ = num; -} diff --git a/backends/tofino/bf-p4c/ir/arch.def b/backends/tofino/bf-p4c/ir/arch.def index 28ef523a3e..fd04f99a30 100644 --- a/backends/tofino/bf-p4c/ir/arch.def +++ b/backends/tofino/bf-p4c/ir/arch.def @@ -20,7 +20,7 @@ /* -*-C++-*- */ #emit -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "lib/ordered_map.h" #end diff --git a/backends/tofino/bf-p4c/ir/parde-lowered.def b/backends/tofino/bf-p4c/ir/parde-lowered.def index c6fd5c51d6..00aebd5e3b 100644 --- a/backends/tofino/bf-p4c/ir/parde-lowered.def +++ b/backends/tofino/bf-p4c/ir/parde-lowered.def @@ -26,7 +26,7 @@ #include "backends/tofino/bf-p4c/ir/ir_enums.h" #include "backends/tofino/bf-p4c/parde/clot/clot.h" #include "backends/tofino/bf-p4c/parde/match_register.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace BFN { struct FieldPacking; @@ -83,7 +83,12 @@ abstract LoweredParserPrimitive { } /// into a PHV container. class LoweredExtractPhv : LoweredParserPrimitive { #emit - /// Convenience constructors for accepting a raw PHV::Container. + /// Convenience constructors for accepting a raw PHV::SerializableContainer. + LoweredExtractPhv(PHV::SerializableContainer dest, const LoweredParserRVal* source) + : source(source), dest(new BFN::ContainerRef(dest)) { } + LoweredExtractPhv(Util::SourceInfo si, PHV::SerializableContainer dest, + const LoweredParserRVal* source) + : LoweredParserPrimitive(si), source(source), dest(new BFN::ContainerRef(dest)) { } LoweredExtractPhv(PHV::Container dest, const LoweredParserRVal* source) : source(source), dest(new BFN::ContainerRef(dest)) { } LoweredExtractPhv(Util::SourceInfo si, PHV::Container dest, diff --git a/backends/tofino/bf-p4c/ir/tofino.def b/backends/tofino/bf-p4c/ir/tofino.def index a8c49f078f..a3dd3b7ff6 100644 --- a/backends/tofino/bf-p4c/ir/tofino.def +++ b/backends/tofino/bf-p4c/ir/tofino.def @@ -24,20 +24,11 @@ #include "lib/bitvec.h" #include "backends/tofino/bf-p4c/common/debug_info.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "backends/tofino/bf-p4c/parde/clot/clot.h" #include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/lib/error_macros.h" -struct StageUse { - static constexpr int MAX_LOGICAL_IDS = 16; - static constexpr int MAX_SRAMS = 80; - static constexpr int MAX_TCAMS = 24; - static constexpr int MAX_MAPRAMS = 48; - static constexpr int MAX_IXBAR_BYTES = 128; - static constexpr int MAX_TERNARY_GROUPS = 12; -}; - /** * @namespace IR::BFN * @brief The namespace encapsulating Tofino 1/2-specific %IR nodes. @@ -398,16 +389,19 @@ class BFN::ContainerRef : BFN::Reference { static size_t nextId; #end - PHV::Container container; + PHV::SerializableContainer container; std::optional range; size_t id; #noconstructor - ContainerRef(PHV::Container c) : BFN::Reference(), container(c), id(nextId++) { } - ContainerRef(Util::SourceInfo si, PHV::Container c) : + ContainerRef(PHV::SerializableContainer c) : BFN::Reference(), container(c), id(nextId++) { } + ContainerRef(PHV::Container c) : BFN::Reference(), container(PHV::SerializableContainer(c)), id(nextId++) { } + ContainerRef(Util::SourceInfo si, PHV::SerializableContainer c) : BFN::Reference(si), container(c), id(nextId++) { } + ContainerRef(Util::SourceInfo si, PHV::Container c) : + BFN::Reference(si), container(PHV::SerializableContainer(c)), id(nextId++) { } validate { BUG_CHECK(bool(container), "Invalid PHV container in ContainerRef"); diff --git a/backends/tofino/bf-p4c/logging/manifest.h b/backends/tofino/bf-p4c/logging/manifest.h index 309013931e..9cd40875ae 100644 --- a/backends/tofino/bf-p4c/logging/manifest.h +++ b/backends/tofino/bf-p4c/logging/manifest.h @@ -31,7 +31,7 @@ #include "backends/tofino/bf-p4c/arch/arch.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "lib/cstring.h" namespace Logging { diff --git a/backends/tofino/bf-p4c/logging/phv_logging.h b/backends/tofino/bf-p4c/logging/phv_logging.h index 6dd2501891..a4d65c9b6a 100644 --- a/backends/tofino/bf-p4c/logging/phv_logging.h +++ b/backends/tofino/bf-p4c/logging/phv_logging.h @@ -23,7 +23,6 @@ #include #include "backends/tofino/bf-p4c/common/field_defuse.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/tofino_write_context.h" #include "backends/tofino/bf-p4c/logging/constrained_fields.h" #include "backends/tofino/bf-p4c/logging/group_constraint_extractor.h" @@ -36,9 +35,10 @@ #include "backends/tofino/bf-p4c/phv/make_clusters.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" -#include "backends/tofino/bf-p4c/phv/phv_spec.h" #include "backends/tofino/bf-p4c/phv/pragma/phv_pragmas.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv_spec.h" #include "ir/ir.h" using Logging::Phv_Schema_Logger; diff --git a/backends/tofino/bf-p4c/logging/resources.cpp b/backends/tofino/bf-p4c/logging/resources.cpp index 391426e17d..d374b76ade 100644 --- a/backends/tofino/bf-p4c/logging/resources.cpp +++ b/backends/tofino/bf-p4c/logging/resources.cpp @@ -438,8 +438,8 @@ ResourcesLogging::HashBitsResourceUsage *ResourcesLogging::logHashBits(unsigned using HashBitUsage = Resources_Schema_Logger::HashBitUsage; using ElementUsageHash = Resources_Schema_Logger::ElementUsageHash; - const auto nBits = 10 * Tofino::IXBar::HASH_INDEX_GROUPS + Tofino::IXBar::HASH_SINGLE_BITS; - const auto nFunctions = Tofino::IXBar::HASH_GROUPS; + const auto nBits = 10 * TofinoIXBarSpec::HASH_INDEX_GROUPS + TofinoIXBarSpec::HASH_SINGLE_BITS; + const auto nFunctions = TofinoIXBarSpec::HASH_GROUPS; auto hbru = new HashBitsResourceUsage(nBits, nFunctions); @@ -465,8 +465,8 @@ ResourcesLogging::HashDistResourceUsage *ResourcesLogging::logHashDist(unsigned using HashDistUnitUsage = Resources_Schema_Logger::HashDistributionUnitUsage; using ElementUsageHashDistribution = Resources_Schema_Logger::ElementUsageHashDistribution; - const auto nHashIds = Tofino::IXBar::HASH_DIST_UNITS; - const auto nUnitIds = Tofino::IXBar::HASH_DIST_SLICES; + const auto nHashIds = TofinoIXBarSpec::HASH_DIST_UNITS; + const auto nUnitIds = TofinoIXBarSpec::HASH_DIST_SLICES; auto hdru = new HashDistResourceUsage(nHashIds, nUnitIds); diff --git a/backends/tofino/bf-p4c/logging/resources.h b/backends/tofino/bf-p4c/logging/resources.h index 7c3561d8ce..bcbccccc94 100644 --- a/backends/tofino/bf-p4c/logging/resources.h +++ b/backends/tofino/bf-p4c/logging/resources.h @@ -26,7 +26,7 @@ #include #include "ir/ir.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "lib/cstring.h" #include "lib/ordered_map.h" #include "backends/tofino/bf-p4c/logging/resources_schema.h" diff --git a/backends/tofino/bf-p4c/logging/resources_clot.cpp b/backends/tofino/bf-p4c/logging/resources_clot.cpp index 523a29f93e..0a7cf40898 100644 --- a/backends/tofino/bf-p4c/logging/resources_clot.cpp +++ b/backends/tofino/bf-p4c/logging/resources_clot.cpp @@ -22,7 +22,7 @@ #include #include "backends/tofino/bf-p4c/common/asm_output.h" // canon_name #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" // ClotInfo -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "resources_clot.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/logging/resources_parser.cpp b/backends/tofino/bf-p4c/logging/resources_parser.cpp index 29d9f26bdb..aec3ed2cd5 100644 --- a/backends/tofino/bf-p4c/logging/resources_parser.cpp +++ b/backends/tofino/bf-p4c/logging/resources_parser.cpp @@ -18,7 +18,7 @@ #include "backends/tofino/bf-p4c/logging/resources_parser.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/logging/resources_parser.h b/backends/tofino/bf-p4c/logging/resources_parser.h index 91e9b4b091..969cc1c3f7 100644 --- a/backends/tofino/bf-p4c/logging/resources_parser.h +++ b/backends/tofino/bf-p4c/logging/resources_parser.h @@ -19,9 +19,9 @@ #ifndef _BACKENDS_TOFINO_BF_P4C_LOGGING_RESOURCES_PARSER_H_ #define _BACKENDS_TOFINO_BF_P4C_LOGGING_RESOURCES_PARSER_H_ -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/logging/resources_schema.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" using Logging::Resources_Schema_Logger; diff --git a/backends/tofino/bf-p4c/mau/action_format.h b/backends/tofino/bf-p4c/mau/action_format.h index a78fa46dfe..16e1b64113 100644 --- a/backends/tofino/bf-p4c/mau/action_format.h +++ b/backends/tofino/bf-p4c/mau/action_format.h @@ -27,7 +27,7 @@ #include "backends/tofino/bf-p4c/mau/action_analysis.h" #include "backends/tofino/bf-p4c/mau/attached_info.h" #include "backends/tofino/bf-p4c/mau/ixbar_expr.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "lib/bitops.h" #include "lib/bitvec.h" diff --git a/backends/tofino/bf-p4c/mau/build_power_graph.cpp b/backends/tofino/bf-p4c/mau/build_power_graph.cpp index d7c47986c0..38f1ca32f7 100644 --- a/backends/tofino/bf-p4c/mau/build_power_graph.cpp +++ b/backends/tofino/bf-p4c/mau/build_power_graph.cpp @@ -19,12 +19,12 @@ #include "backends/tofino/bf-p4c/mau/build_power_graph.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/mau/default_next.h" #include "backends/tofino/bf-p4c/mau/jbay_next_table.h" #include "backends/tofino/bf-p4c/mau/mau_power.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/simple_power_graph.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "lib/ordered_set.h" namespace MauPower { diff --git a/backends/tofino/bf-p4c/mau/determine_power_usage.cpp b/backends/tofino/bf-p4c/mau/determine_power_usage.cpp index b1d13c1562..8f94cd9c63 100644 --- a/backends/tofino/bf-p4c/mau/determine_power_usage.cpp +++ b/backends/tofino/bf-p4c/mau/determine_power_usage.cpp @@ -24,7 +24,7 @@ #include "backends/tofino/bf-p4c/mau/mau_power.h" #include "backends/tofino/bf-p4c/mau/resource_estimate.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace MauPower { diff --git a/backends/tofino/bf-p4c/mau/determine_power_usage.h b/backends/tofino/bf-p4c/mau/determine_power_usage.h index 4cc5c51df9..3b786873de 100644 --- a/backends/tofino/bf-p4c/mau/determine_power_usage.h +++ b/backends/tofino/bf-p4c/mau/determine_power_usage.h @@ -21,7 +21,6 @@ #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/logging/manifest.h" #include "backends/tofino/bf-p4c/logging/power_schema.h" #include "backends/tofino/bf-p4c/mau/build_power_graph.h" @@ -30,6 +29,7 @@ #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/resource.h" #include "backends/tofino/bf-p4c/mau/table_dependency_graph.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/error.h" #include "lib/json.h" diff --git a/backends/tofino/bf-p4c/mau/finalize_mau_pred_deps_power.h b/backends/tofino/bf-p4c/mau/finalize_mau_pred_deps_power.h index dcc1283d80..53a24d8cb8 100644 --- a/backends/tofino/bf-p4c/mau/finalize_mau_pred_deps_power.h +++ b/backends/tofino/bf-p4c/mau/finalize_mau_pred_deps_power.h @@ -23,13 +23,13 @@ #include #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/mau/build_power_graph.h" #include "backends/tofino/bf-p4c/mau/determine_power_usage.h" #include "backends/tofino/bf-p4c/mau/jbay_next_table.h" #include "backends/tofino/bf-p4c/mau/mau_power.h" #include "backends/tofino/bf-p4c/mau/table_dependency_graph.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "ir/pass_manager.h" namespace MauPower { diff --git a/backends/tofino/bf-p4c/mau/gateway.cpp b/backends/tofino/bf-p4c/mau/gateway.cpp index 727e570d8c..89dcef7874 100644 --- a/backends/tofino/bf-p4c/mau/gateway.cpp +++ b/backends/tofino/bf-p4c/mau/gateway.cpp @@ -28,39 +28,6 @@ #include "ir/pattern.h" #include "split_gateways.h" -const Device::GatewaySpec &TofinoDevice::getGatewaySpec() const { - static const Device::GatewaySpec spec = { - /* .PhvBytes = */ 4, - /* .HashBits = */ 12, - /* .PredicateBits = */ 0, - /* .MaxRows = */ 4, - /* .SupportXor = */ true, - /* .SupportRange = */ true, - /* .ExactShifts = */ 1, - /* .ByteSwizzle = */ true, - /* .PerByteMatch = */ 0, - /* .XorByteSlots = */ 0xf0, - }; - return spec; -} -#if HAVE_JBAY -const Device::GatewaySpec &JBayDevice::getGatewaySpec() const { - static const Device::GatewaySpec spec = { - /* .PhvBytes = */ 4, - /* .HashBits = */ 12, - /* .PredicateBits = */ 0, - /* .MaxRows = */ 4, - /* .SupportXor = */ true, - /* .SupportRange = */ true, - /* .ExactShifts = */ 5, - /* .ByteSwizzle = */ true, - /* .PerByteMatch = */ 0, - /* .XorByteSlots = */ 0xf0, - }; - return spec; -} -#endif - class CanonGatewayExpr::NeedNegate : public Inspector { bool rv = false; bool preorder(const IR::Expression *) override { return !rv; } diff --git a/backends/tofino/bf-p4c/mau/gateway.h b/backends/tofino/bf-p4c/mau/gateway.h index d7e0457cd5..5dc9511624 100644 --- a/backends/tofino/bf-p4c/mau/gateway.h +++ b/backends/tofino/bf-p4c/mau/gateway.h @@ -21,10 +21,10 @@ #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/mau/input_xbar.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/tofino/input_xbar.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/safe_vector.h" using namespace P4; @@ -35,19 +35,6 @@ class Field; class PhvInfo; -struct Device::GatewaySpec { - int PhvBytes; - int HashBits; - int PredicateBits; - int MaxRows; - bool SupportXor; - bool SupportRange; - int ExactShifts; - bool ByteSwizzle; // is the a byte swizzle between ixbar and gateway - int PerByteMatch; // lower bytes are shared per row, with 1 bit match per row - unsigned XorByteSlots; -}; - class CanonGatewayExpr : public MauTransform { public: CanonGatewayExpr() : _debugIndent(6) {} diff --git a/backends/tofino/bf-p4c/mau/input_xbar.cpp b/backends/tofino/bf-p4c/mau/input_xbar.cpp index a5372cde48..d37104f8d4 100644 --- a/backends/tofino/bf-p4c/mau/input_xbar.cpp +++ b/backends/tofino/bf-p4c/mau/input_xbar.cpp @@ -18,7 +18,6 @@ #include "input_xbar.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/logging/resources.h" #include "backends/tofino/bf-p4c/mau/gateway.h" #include "backends/tofino/bf-p4c/mau/ixbar_expr.h" @@ -26,6 +25,7 @@ #include "backends/tofino/bf-p4c/mau/resource_estimate.h" #include "backends/tofino/bf-p4c/mau/tofino/input_xbar.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "backends/tofino/bf-utils/include/dynamic_hash/dynamic_hash.h" #include "lib/algorithm.h" #include "lib/bitops.h" diff --git a/backends/tofino/bf-p4c/mau/input_xbar.h b/backends/tofino/bf-p4c/mau/input_xbar.h index 06f3ed2b9c..484873b070 100644 --- a/backends/tofino/bf-p4c/mau/input_xbar.h +++ b/backends/tofino/bf-p4c/mau/input_xbar.h @@ -28,13 +28,13 @@ #include "backends/tofino/bf-p4c/common/alloc.h" #include "backends/tofino/bf-p4c/common/asm_output.h" #include "backends/tofino/bf-p4c/common/slice.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/lib/autoclone.h" #include "backends/tofino/bf-p4c/lib/dyn_vector.h" #include "backends/tofino/bf-p4c/mau/attached_entries.h" #include "backends/tofino/bf-p4c/mau/ixbar_expr.h" #include "backends/tofino/bf-p4c/mau/table_layout.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" #include "lib/hex.h" #include "lib/safe_vector.h" diff --git a/backends/tofino/bf-p4c/mau/instruction_adjustment.cpp b/backends/tofino/bf-p4c/mau/instruction_adjustment.cpp index 6c04ad21a0..816e86b29b 100644 --- a/backends/tofino/bf-p4c/mau/instruction_adjustment.cpp +++ b/backends/tofino/bf-p4c/mau/instruction_adjustment.cpp @@ -1561,7 +1561,7 @@ bool AdjustStatefulInstructions::verify_on_search_bus(const IR::MAU::StatefulAlu int initial_offset = 0; if (Device::currentDevice() == Device::TOFINO) - initial_offset = Tofino::IXBar::TOFINO_METER_ALU_BYTE_OFFSET; + initial_offset = TofinoIXBarSpec::TOFINO_METER_ALU_BYTE_OFFSET; valid_start_positions.insert(initial_offset); valid_start_positions.insert(initial_offset + (phv_width / 8)); diff --git a/backends/tofino/bf-p4c/mau/instruction_adjustment.h b/backends/tofino/bf-p4c/mau/instruction_adjustment.h index 67986ecd71..b327e1034e 100644 --- a/backends/tofino/bf-p4c/mau/instruction_adjustment.h +++ b/backends/tofino/bf-p4c/mau/instruction_adjustment.h @@ -26,7 +26,7 @@ #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/resource.h" #include "backends/tofino/bf-p4c/mau/tofino/input_xbar.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/safe_vector.h" using namespace P4; diff --git a/backends/tofino/bf-p4c/mau/instruction_memory.cpp b/backends/tofino/bf-p4c/mau/instruction_memory.cpp index 67fa9f99f5..76aab67051 100644 --- a/backends/tofino/bf-p4c/mau/instruction_memory.cpp +++ b/backends/tofino/bf-p4c/mau/instruction_memory.cpp @@ -22,7 +22,7 @@ #include "backends/tofino/bf-p4c/mau/resource.h" #include "backends/tofino/bf-p4c/mau/table_format.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "backends/tofino/bf-p4c/mau/tofino/instruction_memory.h" diff --git a/backends/tofino/bf-p4c/mau/instruction_memory.h b/backends/tofino/bf-p4c/mau/instruction_memory.h index 8101e23baa..fa42c9cd30 100644 --- a/backends/tofino/bf-p4c/mau/instruction_memory.h +++ b/backends/tofino/bf-p4c/mau/instruction_memory.h @@ -21,7 +21,7 @@ /* clang-format off */ #include "backends/tofino/bf-p4c/mau/table_layout.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "backends/tofino/bf-p4c/common/alloc.h" using namespace P4; diff --git a/backends/tofino/bf-p4c/mau/jbay_next_table.cpp b/backends/tofino/bf-p4c/mau/jbay_next_table.cpp index e2f495c3f6..f39c6ecb3c 100644 --- a/backends/tofino/bf-p4c/mau/jbay_next_table.cpp +++ b/backends/tofino/bf-p4c/mau/jbay_next_table.cpp @@ -22,10 +22,10 @@ #include #include "backends/tofino/bf-p4c/common/table_printer.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/mau/memories.h" #include "backends/tofino/bf-p4c/mau/resource.h" #include "backends/tofino/bf-p4c/mau/table_layout.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/error.h" /* This pass calculates 2 data structures used during assembly generation: diff --git a/backends/tofino/bf-p4c/mau/mau_power.cpp b/backends/tofino/bf-p4c/mau/mau_power.cpp index 96ca762f6b..62e8e75cc4 100644 --- a/backends/tofino/bf-p4c/mau/mau_power.cpp +++ b/backends/tofino/bf-p4c/mau/mau_power.cpp @@ -22,8 +22,8 @@ #include #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/mau/memories.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/hex.h" #include "lib/map.h" diff --git a/backends/tofino/bf-p4c/mau/mau_power.h b/backends/tofino/bf-p4c/mau/mau_power.h index 6e879cfb6c..dc524e8035 100644 --- a/backends/tofino/bf-p4c/mau/mau_power.h +++ b/backends/tofino/bf-p4c/mau/mau_power.h @@ -25,10 +25,10 @@ #include #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/unique_id.h" #include "backends/tofino/bf-p4c/lib/dyn_vector.h" #include "backends/tofino/bf-p4c/logging/power_schema.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" namespace MauPower { diff --git a/backends/tofino/bf-p4c/mau/memories.cpp b/backends/tofino/bf-p4c/mau/memories.cpp index b1b95fb406..8efc665ed9 100644 --- a/backends/tofino/bf-p4c/mau/memories.cpp +++ b/backends/tofino/bf-p4c/mau/memories.cpp @@ -18,12 +18,12 @@ #include "backends/tofino/bf-p4c/mau/memories.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/payload_gateway.h" #include "backends/tofino/bf-p4c/mau/resource.h" #include "backends/tofino/bf-p4c/mau/resource_estimate.h" #include "backends/tofino/bf-p4c/mau/tofino/memories.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/bitops.h" #include "lib/range.h" diff --git a/backends/tofino/bf-p4c/mau/payload_gateway.h b/backends/tofino/bf-p4c/mau/payload_gateway.h index 2757833c36..3f02ec4ff1 100644 --- a/backends/tofino/bf-p4c/mau/payload_gateway.h +++ b/backends/tofino/bf-p4c/mau/payload_gateway.h @@ -20,7 +20,7 @@ #define BF_P4C_MAU_PAYLOAD_GATEWAY_H_ #include "backends/tofino/bf-p4c/mau/mau_visitor.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" using namespace P4; diff --git a/backends/tofino/bf-p4c/mau/resource_estimate.cpp b/backends/tofino/bf-p4c/mau/resource_estimate.cpp index 28c170ee34..402e3e31e2 100644 --- a/backends/tofino/bf-p4c/mau/resource_estimate.cpp +++ b/backends/tofino/bf-p4c/mau/resource_estimate.cpp @@ -18,6 +18,7 @@ #include "resource_estimate.h" +#include "backends/tofino/bf-p4c/mau/tofino/input_xbar.h" #include "hash_mask_annotations.h" #include "lib/bitops.h" #include "lib/log.h" @@ -1644,7 +1645,7 @@ bool RangeEntries::preorder(const IR::MAU::TableKey *ixbar_read) { // individual TCAM. After looking at the hardware requirements and talking to the driver // team, I'm not sure if this constraint actually exists. Will have to be verified by // packet testing. Currently the input xbar algorithm ignores this constraint - ERROR_CHECK(range_nibbles <= Tofino::IXBar::TERNARY_BYTES_PER_GROUP, + ERROR_CHECK(range_nibbles <= TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP, "%s: Currently in p4c, the table %s cannot perform a range match on key %s " "as the key does not fit in under 5 PHV nibbles", ixbar_read->srcInfo, tbl->name, field->name); diff --git a/backends/tofino/bf-p4c/mau/stateful_alu.cpp b/backends/tofino/bf-p4c/mau/stateful_alu.cpp index bb419a004e..c90951e4e7 100644 --- a/backends/tofino/bf-p4c/mau/stateful_alu.cpp +++ b/backends/tofino/bf-p4c/mau/stateful_alu.cpp @@ -29,43 +29,6 @@ #include "ixbar_expr.h" #include "lib/hex.h" -const Device::StatefulAluSpec &TofinoDevice::getStatefulAluSpec() const { - static const Device::StatefulAluSpec spec = {/* .CmpMask = */ false, - /* .CmpUnits = */ {"lo"_cs, "hi"_cs}, - /* .MaxSize = */ 32, - /* .MaxDualSize = */ 64, - /* .MaxPhvInputWidth = */ 32, - /* .MaxInstructions = */ 4, - /* .MaxInstructionConstWidth = */ 4, - /* .MinInstructionConstValue = */ -8, - /* .MaxInstructionConstValue = */ 7, - /* .OutputWords = */ 1, - /* .DivModUnit = */ false, - /* .FastClear = */ false, - /* .MaxRegfileRows = */ 4}; - return spec; -} - -#if HAVE_JBAY -const Device::StatefulAluSpec &JBayDevice::getStatefulAluSpec() const { - static const Device::StatefulAluSpec spec = { - /* .CmpMask = */ true, - /* .CmpUnits = */ {"cmp0"_cs, "cmp1"_cs, "cmp2"_cs, "cmp3"_cs}, - /* .MaxSize = */ 128, - /* .MaxDualSize = */ 128, - /* .MaxPhvInputWidth = */ 64, - /* .MaxInstructions = */ 4, - /* .MaxInstructionConstWidth = */ 4, - /* .MinInstructionConstValue = */ -8, - /* .MaxInstructionConstValue = */ 7, - /* .OutputWords = */ 4, - /* .DivModUnit = */ true, - /* .FastClear = */ true, - /* .MaxRegfileRows = */ 4}; - return spec; -} -#endif - /** * @brief This class detects a following pattern: * diff --git a/backends/tofino/bf-p4c/mau/stateful_alu.h b/backends/tofino/bf-p4c/mau/stateful_alu.h index 19a08d1ef7..35eb10a945 100644 --- a/backends/tofino/bf-p4c/mau/stateful_alu.h +++ b/backends/tofino/bf-p4c/mau/stateful_alu.h @@ -96,31 +96,13 @@ #include #include -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/resolveReferences/referenceMap.h" #include "ir/ir.h" #include "mau_visitor.h" using namespace P4; -struct Device::StatefulAluSpec { - bool CmpMask; // are cmp oprerands maskable? - std::vector CmpUnits; - int MaxSize; - int MaxDualSize; - int MaxPhvInputWidth; - int MaxInstructions; - int MaxInstructionConstWidth; - int MinInstructionConstValue; - int MaxInstructionConstValue; - int OutputWords; - bool DivModUnit; - bool FastClear; - int MaxRegfileRows; - - cstring cmpUnit(unsigned idx) const; -}; - /** * \ingroup stateful_alu * \brief The pass creates SALU VLIW instructions. diff --git a/backends/tofino/bf-p4c/mau/table_dependency_graph.cpp b/backends/tofino/bf-p4c/mau/table_dependency_graph.cpp index 22ffb4d127..71a9bcf655 100644 --- a/backends/tofino/bf-p4c/mau/table_dependency_graph.cpp +++ b/backends/tofino/bf-p4c/mau/table_dependency_graph.cpp @@ -30,7 +30,6 @@ #include #include "backends/tofino/bf-p4c/common/run_id.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/ir/table_tree.h" #include "backends/tofino/bf-p4c/ir/tofino_write_context.h" #include "backends/tofino/bf-p4c/lib/error_type.h" @@ -39,6 +38,7 @@ #include "backends/tofino/bf-p4c/mau/table_placement.h" #include "backends/tofino/bf-p4c/mau/table_summary.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "ir/ir.h" #include "lib/cstring.h" #include "lib/log.h" diff --git a/backends/tofino/bf-p4c/mau/table_dependency_graph.h b/backends/tofino/bf-p4c/mau/table_dependency_graph.h index a74824bc10..8b19535205 100644 --- a/backends/tofino/bf-p4c/mau/table_dependency_graph.h +++ b/backends/tofino/bf-p4c/mau/table_dependency_graph.h @@ -27,7 +27,6 @@ #include #include "backends/tofino/bf-p4c/common/asm_output.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/control_flow_visitor.h" #include "backends/tofino/bf-p4c/logging/pass_manager.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" @@ -35,6 +34,7 @@ #include "backends/tofino/bf-p4c/mau/table_flow_graph.h" #include "backends/tofino/bf-p4c/mau/table_mutex.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "lib/json.h" using namespace P4; diff --git a/backends/tofino/bf-p4c/mau/table_format.cpp b/backends/tofino/bf-p4c/mau/table_format.cpp index 20788dc57e..aa4822aebc 100644 --- a/backends/tofino/bf-p4c/mau/table_format.cpp +++ b/backends/tofino/bf-p4c/mau/table_format.cpp @@ -2059,7 +2059,7 @@ void TableFormat::Use::TCAM_use::set_midbyte(int _byte_group, int _byte_config) byte_config = _byte_config; if (byte_config == MID_BYTE_LO || byte_config == MID_BYTE_HI) - dirtcam.setbit(Tofino::IXBar::TERNARY_BYTES_PER_GROUP * 2); + dirtcam.setbit(TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP * 2); } void TableFormat::ternary_midbyte(int midbyte, size_t &index, bool lo_midbyte) { @@ -2118,7 +2118,7 @@ bool TableFormat::allocate_all_ternary_match() { for (auto &byte : match_ixbar->use) { LOG5(" Checking match ixbar use byte : " << byte); - if (byte.loc.byte == Tofino::IXBar::TERNARY_BYTES_PER_GROUP) { + if (byte.loc.byte == TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP) { // Reserves groups and the mid bytes used_midbytes.setbit(byte.loc.group / 2); std::pair lo_hi = {false, false}; diff --git a/backends/tofino/bf-p4c/mau/table_placement.cpp b/backends/tofino/bf-p4c/mau/table_placement.cpp index 9d7bfce1e5..2be0112094 100644 --- a/backends/tofino/bf-p4c/mau/table_placement.cpp +++ b/backends/tofino/bf-p4c/mau/table_placement.cpp @@ -5683,9 +5683,7 @@ IR::Node *TransformTables::preorder(IR::MAU::Table *tbl) { return rv; } -IR::Node *TransformTables::postorder(IR::MAU::Table *tbl) { - return Device::mauSpec().postTransformTables(tbl); -} +IR::Node *TransformTables::postorder(IR::MAU::Table *tbl) { return tbl; } IR::Node *TransformTables::preorder(IR::MAU::BackendAttached *ba) { LOG5("TransformTables::preorder BackendAttached " << ba->attached->name); diff --git a/backends/tofino/bf-p4c/mau/table_summary.cpp b/backends/tofino/bf-p4c/mau/table_summary.cpp index abcc9ca133..8d4f3d500c 100644 --- a/backends/tofino/bf-p4c/mau/table_summary.cpp +++ b/backends/tofino/bf-p4c/mau/table_summary.cpp @@ -72,11 +72,11 @@ #include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/common/table_printer.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/logging/filelog.h" #include "backends/tofino/bf-p4c/mau/memories.h" #include "backends/tofino/bf-p4c/mau/resource_estimate.h" #include "backends/tofino/bf-p4c/mau/table_placement.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "lib/hex.h" #include "lib/map.h" using namespace State; diff --git a/backends/tofino/bf-p4c/mau/table_summary.h b/backends/tofino/bf-p4c/mau/table_summary.h index c9a2923854..023272aa0a 100644 --- a/backends/tofino/bf-p4c/mau/table_summary.h +++ b/backends/tofino/bf-p4c/mau/table_summary.h @@ -22,12 +22,12 @@ #include #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/resource.h" #include "backends/tofino/bf-p4c/mau/resource_estimate.h" #include "backends/tofino/bf-p4c/mau/table_dependency_graph.h" #include "backends/tofino/bf-p4c/mau/table_layout.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace Logging { class FileLog; diff --git a/backends/tofino/bf-p4c/mau/tofino/asm_output.cpp b/backends/tofino/bf-p4c/mau/tofino/asm_output.cpp index 7caaa0eb99..c149abed34 100644 --- a/backends/tofino/bf-p4c/mau/tofino/asm_output.cpp +++ b/backends/tofino/bf-p4c/mau/tofino/asm_output.cpp @@ -294,7 +294,7 @@ void Tofino::IXBar::Use::emit_ixbar_asm(const PhvInfo &phv, std::ostream &out, i emit_ixbar_gather_bytes(phv, use, sort, midbytes, tbl, type == IXBar::Use::TERNARY_MATCH, type == IXBar::Use::ATCAM_MATCH); } - for (int hash_group = 0; hash_group < IXBar::HASH_GROUPS; hash_group++) { + for (int hash_group = 0; hash_group < TofinoIXBarSpec::HASH_GROUPS; hash_group++) { unsigned hash_table_input = hash_table_inputs[hash_group]; bitvec hash_seed = this->hash_seed[hash_group]; int ident_bits_prev_alloc = 0; @@ -309,7 +309,7 @@ void Tofino::IXBar::Use::emit_ixbar_asm(const PhvInfo &phv, std::ostream &out, i emit_ixbar_hash(phv, out, indent, match_data, ghost, this, hash_group, ident_bits_prev_alloc); if (is_parity_enabled()) - out << indent << IXBar::HASH_PARITY_BIT << ": parity" << std::endl; + out << indent << TofinoIXBarSpec::HASH_PARITY_BIT << ": parity" << std::endl; --indent; } out << indent++ << "hash group " << hash_group << ":" << std::endl; @@ -356,8 +356,8 @@ bool Tofino::ActionDataBus::Use::emit_adb_asm(std::ostream &out, const IR::MAU:: int immed_hi = immed_lo + (8 << rs.location.type) - 1; le_bitrange immed_range = {immed_lo, immed_hi}; for (int i = 0; i < 2; i++) { - le_bitrange immed_impact = {i * IXBar::HASH_DIST_BITS, - (i + 1) * IXBar::HASH_DIST_BITS - 1}; + le_bitrange immed_impact = {i * TofinoIXBarSpec::HASH_DIST_BITS, + (i + 1) * TofinoIXBarSpec::HASH_DIST_BITS - 1}; if (!immed_impact.overlaps(immed_range)) continue; slot_hash_dist_units.setbit(i); } @@ -374,8 +374,8 @@ bool Tofino::ActionDataBus::Use::emit_adb_asm(std::ostream &out, const IR::MAU:: // Byte slots need a particular byte range of hash dist if (rs.location.type == ActionData::BYTE) { - int slot_range_shift = (immed_range.lo / IXBar::HASH_DIST_BITS); - slot_range_shift *= IXBar::HASH_DIST_BITS; + int slot_range_shift = (immed_range.lo / TofinoIXBarSpec::HASH_DIST_BITS); + slot_range_shift *= TofinoIXBarSpec::HASH_DIST_BITS; le_bitrange slot_range = immed_range.shiftedByBits(-1 * slot_range_shift); out << ", " << slot_range.lo << ".." << slot_range.hi; } diff --git a/backends/tofino/bf-p4c/mau/tofino/input_xbar.cpp b/backends/tofino/bf-p4c/mau/tofino/input_xbar.cpp index 24f4d78d7b..f1276107e2 100644 --- a/backends/tofino/bf-p4c/mau/tofino/input_xbar.cpp +++ b/backends/tofino/bf-p4c/mau/tofino/input_xbar.cpp @@ -15,11 +15,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ - -/* clang-format off */ #include "input_xbar.h" + #include "backends/tofino/bf-p4c/common/slice.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/logging/resources.h" #include "backends/tofino/bf-p4c/mau/asm_hash_output.h" #include "backends/tofino/bf-p4c/mau/gateway.h" @@ -27,18 +25,18 @@ #include "backends/tofino/bf-p4c/mau/resource.h" #include "backends/tofino/bf-p4c/mau/resource_estimate.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "backends/tofino/bf-utils/include/dynamic_hash/dynamic_hash.h" #include "lib/algorithm.h" -#include "lib/bitvec.h" #include "lib/bitops.h" #include "lib/bitrange.h" +#include "lib/bitvec.h" #include "lib/hex.h" -#include "lib/range.h" #include "lib/log.h" +#include "lib/range.h" #include "lib/safe_vector.h" -/* clang-format on */ -constexpr le_bitrange Tofino::IXBar::SELECT_BIT_RANGE; +constexpr le_bitrange TofinoIXBarSpec::SELECT_BIT_RANGE; // = le_bitrange(RAM_SELECT_BIT_START, METER_ALU_HASH_BITS-1); // helper functions for logging -- these need to not be in namespace Tofino or they @@ -154,10 +152,10 @@ safe_vector IXBar::Use::bits_per_search_bus() const { int hash_index = 0; for (auto &single_match : match_bytes) { - int bits_per[IXBar::EXACT_GROUPS] = {0}; - int bytes_per[IXBar::EXACT_GROUPS] = {0}; - int group_per[IXBar::EXACT_GROUPS]; - std::fill(group_per, group_per + IXBar::EXACT_GROUPS, -1); + int bits_per[TofinoIXBarSpec::EXACT_GROUPS] = {0}; + int bytes_per[TofinoIXBarSpec::EXACT_GROUPS] = {0}; + int group_per[TofinoIXBarSpec::EXACT_GROUPS]; + std::fill(group_per, group_per + TofinoIXBarSpec::EXACT_GROUPS, -1); for (auto &b : *single_match) { assert(b.loc.group >= 0 && b.loc.group < 8); @@ -173,7 +171,7 @@ safe_vector IXBar::Use::bits_per_search_bus() const { safe_vector sizes; int search_bus_index = 0; - for (int i = 0; i < IXBar::EXACT_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::EXACT_GROUPS; i++) { if (bits_per[i] == 0) continue; sizes.emplace_back(search_bus_index, group_per[i], bytes_per[i], bits_per[i]); search_bus_index++; @@ -191,7 +189,7 @@ safe_vector IXBar::Use::bits_per_search_bus() const { unsigned IXBar::Use::compute_hash_tables() { unsigned hash_table_input = 0; for (auto &b : use) { - assert(b.loc.group >= 0 && b.loc.group < HASH_TABLES / 2); + assert(b.loc.group >= 0 && b.loc.group < TofinoIXBarSpec::HASH_TABLES / 2); unsigned grp = 1U << (b.loc.group * 2); if (b.loc.byte >= 8) grp <<= 1; hash_table_input |= grp; @@ -282,7 +280,7 @@ IXBar::Use::TotalBytes IXBar::Use::match_hash(safe_vector *hash_groups) con } int IXBar::Use::ternary_align(const Loc &loc) const { - size_t byte_offset = loc.group * IXBar::TERNARY_BYTES_PER_GROUP; + size_t byte_offset = loc.group * TofinoIXBarSpec::TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP; byte_offset += (loc.group + 1) / 2; // adjust for mid-byte byte_offset += loc.byte; return byte_offset % 4; @@ -295,7 +293,9 @@ void IXBar::Use::update_resources(int stage, BFN::Resources::StageResources &sta // Used for the upper 12 bits of gateways for (auto &bits : bit_use) { for (int b = 0; b < bits.width; b++) { - int bit = bits.bit + b + IXBar::HASH_INDEX_GROUPS * TableFormat::RAM_GHOST_BITS; + int bit = + bits.bit + b + + TofinoIXBarSpec::TofinoIXBarSpec::HASH_INDEX_GROUPS * TableFormat::RAM_GHOST_BITS; auto key = std::make_pair(bit, bits.group); LOG_FEATURE("resources", 3, @@ -343,7 +343,6 @@ void IXBar::Use::update_resources(int stage, BFN::Resources::StageResources &sta } } -constexpr int IXBar::HASH_INDEX_GROUPS; constexpr IXBar::HashDistDest_t IXBar::HD_STATS_ADR; unsigned IXBar::hash_table_inputs(const HashDistUse &hdu) { @@ -412,7 +411,7 @@ void IXBar::clear() { memset(hash_single_bit_inuse, 0, sizeof(hash_single_bit_inuse)); memset(hash_group_use, 0, sizeof(hash_group_use)); memset(hash_group_parity_use, 0, sizeof(hash_group_parity_use)); - for (int i = 0; i < HASH_TABLES; ++i) { + for (int i = 0; i < TofinoIXBarSpec::HASH_TABLES; ++i) { hash_dist_inuse[i] = bitvec(); hash_dist_bit_inuse[i] = bitvec(); } @@ -443,22 +442,22 @@ void IXBar::update_hash_parity(IXBar::Use &use, int hash_group) { bool IXBar::hash_matrix_reqs::fit_requirements(bitvec hash_matrix_in_use) const { if (!hash_dist) { int free_indexes = 0; - for (int i = 0; i < HASH_INDEX_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::TofinoIXBarSpec::HASH_INDEX_GROUPS; i++) { bitvec idx_use = hash_matrix_in_use.getslice(i * RAM_LINE_SELECT_BITS, RAM_LINE_SELECT_BITS); if (idx_use.empty()) free_indexes++; } if (free_indexes < index_groups) return false; - bitvec select_use = - hash_matrix_in_use.getslice(RAM_SELECT_BIT_START, IXBar::get_hash_single_bits()); + bitvec select_use = hash_matrix_in_use.getslice(TofinoIXBarSpec::RAM_SELECT_BIT_START, + IXBar::get_hash_single_bits()); if (IXBar::get_hash_single_bits() - select_use.popcount() < select_bits) return false; return true; } return false; } -static int align_flags[IXBar::REPEATING_CONSTRAINT_SECT] = { +static int align_flags[TofinoIXBarSpec::REPEATING_CONSTRAINT_SECT] = { /* these flags are the alignment restrictions that FAIL for each byte in 4 */ IXBar::Use::Align16hi | IXBar::Use::Align32hi, IXBar::Use::Align16lo | IXBar::Use::Align32hi, @@ -467,19 +466,24 @@ static int align_flags[IXBar::REPEATING_CONSTRAINT_SECT] = { }; bitvec IXBar::can_use_from_flags(int flags) const { - bitvec rv(0, REPEATING_CONSTRAINT_SECT); - for (int i = 0; i < REPEATING_CONSTRAINT_SECT; i++) { + bitvec rv(0, TofinoIXBarSpec::REPEATING_CONSTRAINT_SECT); + for (int i = 0; i < TofinoIXBarSpec::REPEATING_CONSTRAINT_SECT; i++) { if ((flags & align_flags[i]) != 0) rv.clrbit(i); } return rv; } -int inline IXBar::groups(bool ternary) const { return ternary ? TERNARY_GROUPS : EXACT_GROUPS; } +int inline IXBar::groups(bool ternary) const { + return ternary ? TofinoIXBarSpec::TERNARY_GROUPS : TofinoIXBarSpec::EXACT_GROUPS; +} -int inline IXBar::mid_bytes(bool ternary) const { return ternary ? BYTE_GROUPS : 0; } +int inline IXBar::mid_bytes(bool ternary) const { + return ternary ? TofinoIXBarSpec::BYTE_GROUPS : 0; +} int inline IXBar::bytes_per_group(bool ternary) const { - return ternary ? TERNARY_BYTES_PER_GROUP : EXACT_BYTES_PER_GROUP; + return ternary ? TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP + : TofinoIXBarSpec::EXACT_BYTES_PER_GROUP; } void IXBar::increase_ternary_ixbar_space(int &groups_needed, int &nibbles_needed, @@ -505,7 +509,8 @@ bool IXBar::calculate_sizes(safe_vector &alloc_use, bool ternary, if (ternary) { groups_needed = 1; nibbles_needed = 0; - while (groups_needed * TERNARY_BYTES_PER_GROUP + (nibbles_needed + 1) / 2 < + while (groups_needed * TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP + + (nibbles_needed + 1) / 2 < total_bytes_needed) { increase_ternary_ixbar_space(groups_needed, nibbles_needed, requires_versioning); } @@ -537,20 +542,22 @@ bool IXBar::calculate_sizes(safe_vector &alloc_use, bool ternary, */ void IXBar::calculate_available_hash_dist_groups(safe_vector &order, hash_matrix_reqs &hm_reqs) { - for (int i = 0; i < HASH_DIST_UNITS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_DIST_UNITS; i++) { if (hash_dist_groups[i] == -1) continue; auto hash_tables = hash_group_use[hash_dist_groups[i]]; bitvec slices_used; for (auto &grp : order) { for (int i = 0; i < 2; i++) { if ((hash_tables & (1U << (2 * grp.group + i))) == 0U) continue; - for (int hash_slice = 0; hash_slice < HASH_DIST_SLICES; hash_slice++) { + for (int hash_slice = 0; hash_slice < TofinoIXBarSpec::HASH_DIST_SLICES; + hash_slice++) { if (hash_dist_inuse[2 * grp.group + i].getbit(hash_slice)) slices_used.setbit(hash_slice); } } } - if (HASH_DIST_SLICES - slices_used.popcount() >= hm_reqs.index_groups) continue; + if (TofinoIXBarSpec::HASH_DIST_SLICES - slices_used.popcount() >= hm_reqs.index_groups) + continue; for (auto bit : bitvec(hash_tables)) { order[bit / 2].hash_open[bit % 2] = false; } @@ -597,7 +604,7 @@ void IXBar::calculate_available_groups(safe_vector &order, hash_matrix_ for (int i = 0; i < 2; i++) { int ways_available = 0; int select_bits_available = 0; - for (int hg = 0; hg < HASH_INDEX_GROUPS; hg++) { + for (int hg = 0; hg < TofinoIXBarSpec::HASH_INDEX_GROUPS; hg++) { if (!(hash_index_inuse[hg] & (1 << (2 * grp.group + i)))) ways_available++; } for (int sb = 0; sb < IXBar::get_hash_single_bits(); sb++) { @@ -622,7 +629,7 @@ void IXBar::calculate_available_groups(safe_vector &order, hash_matrix_ /** Determine if a group is either for hash distribution or match only */ IXBar::grp_use::type_t IXBar::is_group_for_hash_dist(int hash_table) { - for (int i = 0; i < HASH_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_GROUPS; i++) { bool hash_dist = false; if (i == hash_dist_groups[0] || i == hash_dist_groups[1]) { hash_dist = true; @@ -686,7 +693,7 @@ void IXBar::calculate_found(safe_vector &unalloced, safe_vec for (auto &need : unalloced) { for (auto &p : Values(fields.equal_range(need->container))) { - if (ternary && p.byte == TERNARY_BYTES_PER_GROUP) { + if (ternary && p.byte == TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP) { if (need->is_range()) continue; if (byte_group_use[p.group / 2].second == need->lo) { mid_byte_order[p.group / 2].found[0] = true; @@ -728,7 +735,9 @@ void IXBar::calculate_free(safe_vector &order, safe_vector &order, safe_vector &unalloced auto &fields = this->fields(ternary); int found_bytes = grp->found.popcount(); int ixbar_bytes_placed = 0; - int total_match_bytes = ternary ? TERNARY_BYTES_PER_GROUP : EXACT_BYTES_PER_GROUP; + int total_match_bytes = ternary ? TofinoIXBarSpec::TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP + : TofinoIXBarSpec::EXACT_BYTES_PER_GROUP; for (size_t i = 0; i < unalloced.size(); i++) { auto &need = *(unalloced[i]); if (found_bytes == 0) break; @@ -772,7 +784,8 @@ void IXBar::found_bytes(grp_use *grp, safe_vector &unalloced if (need.is_range() && grp->range_set() && need.range_index != grp->range_index) continue; for (auto &p : Values(fields.equal_range(need.container))) { - if (ternary && p.byte == TERNARY_BYTES_PER_GROUP) continue; + if (ternary && p.byte == TofinoIXBarSpec::TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP) + continue; if ((grp->group == p.group) && (use[p.group][p.byte].second == need.lo)) { if (!grp->found.getbit(p.byte)) continue; @@ -808,7 +821,8 @@ void IXBar::found_mid_bytes(mid_byte_use *mb_grp, safe_vector= total_match_bytes) break; for (auto &p : Values(fields.equal_range(need.container))) { - if (!(ternary && p.byte == TERNARY_BYTES_PER_GROUP)) continue; + if (!(ternary && p.byte == TofinoIXBarSpec::TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP)) + continue; if (only_alloc_nibble && !need.only_one_nibble_in_use()) continue; @@ -834,9 +848,10 @@ void IXBar::free_bytes(grp_use *grp, safe_vector &unalloced, if (!grp) return; int ixbar_bytes_placed = 0; int free_bytes = grp->max_free().popcount(); - int total_match_bytes = ternary ? TERNARY_BYTES_PER_GROUP : EXACT_BYTES_PER_GROUP; - int ternary_offset = (grp->group / 2) * TERNARY_BYTES_PER_BIG_GROUP; - ternary_offset += (grp->group % 2) * (TERNARY_BYTES_PER_GROUP + 1); + int total_match_bytes = + ternary ? TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP : TofinoIXBarSpec::EXACT_BYTES_PER_GROUP; + int ternary_offset = (grp->group / 2) * TofinoIXBarSpec::TERNARY_BYTES_PER_BIG_GROUP; + ternary_offset += (grp->group % 2) * (TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP + 1); int align_offset = ternary ? ternary_offset : 0; int align = align_offset & 3; @@ -884,7 +899,8 @@ void IXBar::free_mid_bytes(mid_byte_use *mb_grp, safe_vector int ixbar_bytes_placed = 0; int free_bytes = 1; - int align_offset = (mb_grp->group * TERNARY_BYTES_PER_BIG_GROUP) + TERNARY_BYTES_PER_GROUP; + int align_offset = (mb_grp->group * TofinoIXBarSpec::TERNARY_BYTES_PER_BIG_GROUP) + + TofinoIXBarSpec::TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP; int align = align_offset & 3; int total_match_bytes = 1; @@ -1055,7 +1071,7 @@ void IXBar::allocate_mid_bytes(safe_vector &unalloced, // for gathering information about constraints if (only_alloc_nibble && !byte->only_one_nibble_in_use()) continue; bitvec key_bv = can_use_from_flags(byte->flags); - int key = key_bv.getrange(0, REPEATING_CONSTRAINT_SECT); + int key = key_bv.getrange(0, TofinoIXBarSpec::REPEATING_CONSTRAINT_SECT); if (constraints_to_reqs.count(key) == 0) constraints_to_reqs[key] = 1; else @@ -1276,7 +1292,7 @@ void IXBar::allocate_groups(safe_vector &unalloced, for (auto byte : unalloced) { bitvec key_bv = can_use_from_flags(byte->flags); - int key = key_bv.getrange(0, REPEATING_CONSTRAINT_SECT); + int key = key_bv.getrange(0, TofinoIXBarSpec::REPEATING_CONSTRAINT_SECT); if (constraints_to_reqs.count(key) == 0) constraints_to_reqs[key] = 1; else @@ -1419,7 +1435,7 @@ void IXBar::layout_option_calculation(const LayoutOption *layout_option, size_t unsigned IXBar::index_groups_used(bitvec bv) const { unsigned rv = 0; - for (int i = 0; i < HASH_INDEX_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_INDEX_GROUPS; i++) { if (bv.getrange(i * RAM_LINE_SELECT_BITS, RAM_LINE_SELECT_BITS)) rv |= (1 << i); } return rv; @@ -1427,8 +1443,8 @@ unsigned IXBar::index_groups_used(bitvec bv) const { unsigned IXBar::select_bits_used(bitvec bv) const { unsigned rv = 0; - for (int i = RAM_SELECT_BIT_START; i < get_hash_matrix_size(); i++) { - if (bv.getbit(i)) rv |= (1 << (i - RAM_SELECT_BIT_START)); + for (int i = TofinoIXBarSpec::RAM_SELECT_BIT_START; i < get_hash_matrix_size(); i++) { + if (bv.getbit(i)) rv |= (1 << (i - TofinoIXBarSpec::RAM_SELECT_BIT_START)); } return rv; } @@ -1446,7 +1462,8 @@ IXBar::hash_matrix_reqs IXBar::match_hash_reqs(const LayoutOption *lo, size_t st bits_required += ceil_log2(lo->way_sizes[index]); } bits_required = std::min(bits_required, IXBar::get_hash_single_bits()); - int groups_required = std::min(last - start, static_cast(IXBar::HASH_INDEX_GROUPS)); + int groups_required = + std::min(last - start, static_cast(TofinoIXBarSpec::HASH_INDEX_GROUPS)); return hash_matrix_reqs(groups_required, bits_required, false); } @@ -1557,7 +1574,7 @@ bool IXBar::allocMatch(bool ternary, const IR::MAU::Table *tbl, const PhvInfo &p unsigned IXBar::find_balanced_group(Use &alloc, int way_size) { std::map sliceDepths; for (unsigned i = 0; i < alloc.way_use.size(); ++i) { - int slice_group = INDEX_RANGE_SUBGROUP(alloc.way_use[i].index); + int slice_group = TofinoIXBarSpec::INDEX_RANGE_SUBGROUP(alloc.way_use[i].index); int slice_ways = (1U << bitvec(alloc.way_use[i].select_mask).popcount()); sliceDepths[slice_group] += slice_ways; } @@ -1568,7 +1585,7 @@ unsigned IXBar::find_balanced_group(Use &alloc, int way_size) { bitvec slice_way_mask(alloc.way_use[i].select_mask); int slice_way_bits = slice_way_mask.popcount(); if (way_bits > slice_way_bits) continue; - int slice_group = INDEX_RANGE_SUBGROUP(alloc.way_use[i].index); + int slice_group = TofinoIXBarSpec::INDEX_RANGE_SUBGROUP(alloc.way_use[i].index); unsigned sliceDepth = way_size + sliceDepths[slice_group]; if (sliceDepth < minWayDepth) { minWayDepth = sliceDepth; @@ -1600,7 +1617,7 @@ unsigned IXBar::find_balanced_group(Use &alloc, int way_size) { int IXBar::getHashGroup(unsigned hash_table_input, const hash_matrix_reqs *hm_reqs) { // One can assume that the find legal bytes will have legal space within the hash function // If not the higher functions will find space - for (int i = 0; i < HASH_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_GROUPS; i++) { if (hash_group_use[i] == hash_table_input) { return i; } @@ -1612,24 +1629,24 @@ int IXBar::getHashGroup(unsigned hash_table_input, const hash_matrix_reqs *hm_re bitvec ht_usage; // Gather all the hash matrix currently in use, to verify that there is space for the // other bits to possibly share. - for (auto idx : Range(0, HASH_INDEX_GROUPS - 1)) { + for (auto idx : Range(0, TofinoIXBarSpec::HASH_INDEX_GROUPS - 1)) { if ((hash_index_inuse[idx] & hash_table_input) != 0) ht_usage.setrange(idx * RAM_LINE_SELECT_BITS, RAM_LINE_SELECT_BITS); } for (auto single_bit : Range(0, IXBar::get_hash_single_bits() - 1)) { if ((hash_single_bit_inuse[single_bit] & hash_table_input) != 0) - ht_usage.setbit(single_bit + RAM_SELECT_BIT_START); + ht_usage.setbit(single_bit + TofinoIXBarSpec::RAM_SELECT_BIT_START); } for (auto ht : bitvec(hash_table_input)) ht_usage |= hash_dist_bit_inuse[ht]; LOG6("\t\tht_usage 0x" << ht_usage << " 0x" << hex(hash_table_input)); bitvec hash_table_input_bv(hash_table_input); - bitvec hash_matrix_usage_hf[HASH_GROUPS]; - bitvec hash_matrix_usage_collision[HASH_GROUPS]; + bitvec hash_matrix_usage_hf[TofinoIXBarSpec::HASH_GROUPS]; + bitvec hash_matrix_usage_collision[TofinoIXBarSpec::HASH_GROUPS]; - for (int i = 0; i < HASH_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_GROUPS; i++) { bool is_hash_dist_group = hash_dist_groups[0] == i || hash_dist_groups[1] == i; if (is_hash_dist_group) continue; bitvec max_usage(0, get_hash_matrix_size()); @@ -1641,7 +1658,7 @@ int IXBar::getHashGroup(unsigned hash_table_input, const hash_matrix_reqs *hm_re unsigned collision_ht = hash_table_input & ~hash_group_use[i]; LOG6("\t\thash group " << i << " 0x" << hex(hash_group_use[i])); LOG6("\t\twith_ht 0x" << hex(hf_ht) << " without_ht 0x" << hex(collision_ht)); - for (auto idx : Range(0, HASH_INDEX_GROUPS - 1)) { + for (auto idx : Range(0, TofinoIXBarSpec::HASH_INDEX_GROUPS - 1)) { if ((hash_index_inuse[idx] & hf_ht) != 0) curr_usage_hf.setrange(idx * RAM_LINE_SELECT_BITS, RAM_LINE_SELECT_BITS); if ((hash_index_inuse[idx] & collision_ht) != 0) @@ -1649,9 +1666,9 @@ int IXBar::getHashGroup(unsigned hash_table_input, const hash_matrix_reqs *hm_re } for (auto single_bit : Range(0, IXBar::get_hash_single_bits() - 1)) { if ((hash_single_bit_inuse[single_bit] & hf_ht) != 0) - curr_usage_hf.setbit(single_bit + RAM_SELECT_BIT_START); + curr_usage_hf.setbit(single_bit + TofinoIXBarSpec::RAM_SELECT_BIT_START); if ((hash_single_bit_inuse[single_bit] & collision_ht) != 0) - curr_usage_collision.setbit(single_bit + RAM_SELECT_BIT_START); + curr_usage_collision.setbit(single_bit + TofinoIXBarSpec::RAM_SELECT_BIT_START); } hash_matrix_usage_hf[i] = curr_usage_hf; hash_matrix_usage_collision[i] = curr_usage_collision; @@ -1662,7 +1679,7 @@ int IXBar::getHashGroup(unsigned hash_table_input, const hash_matrix_reqs *hm_re // Only pick a hash function that has the legal amount of space, as well as a hash // function that is already in use. - for (int i = 0; i < HASH_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_GROUPS; i++) { if (hash_group_use[i] == 0) continue; bool is_hash_dist_group = hash_dist_groups[0] == i || hash_dist_groups[1] == i; if (is_hash_dist_group != hm_reqs->hash_dist) continue; @@ -1675,13 +1692,13 @@ int IXBar::getHashGroup(unsigned hash_table_input, const hash_matrix_reqs *hm_re // if an allocation that shares space with another hash function cannot share that // hash function, it's better if the allocation is not on those ixbar bytes. The // second try will guarantee that the sharing is minimized - for (int i = 0; i < HASH_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_GROUPS; i++) { if (hash_group_use[i] == 0) continue; if ((hash_group_use[i] & hash_table_input) != 0U) return -1; } } - for (int i = 0; i < HASH_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_GROUPS; i++) { if (hash_group_use[i] == 0) { return i; } @@ -1696,11 +1713,12 @@ int IXBar::getHashGroup(unsigned hash_table_input, const hash_matrix_reqs *hm_re * used, what hash function (8x52 bit hashes) are available. At most two options are * possible for hash distribution. */ -void IXBar::getHashDistGroups(unsigned hash_table_input, int hash_group_opt[HASH_DIST_UNITS]) { +void IXBar::getHashDistGroups(unsigned hash_table_input, + int hash_group_opt[TofinoIXBarSpec::HASH_DIST_UNITS]) { std::set groups_with_overlap; // If both groups overlap with the given requirement, then this will lead to hash collisions // and will not work - for (int i = 0; i < HASH_DIST_UNITS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_DIST_UNITS; i++) { if (hash_dist_groups[i] >= 0 && (hash_table_input & hash_group_use[hash_dist_groups[i]]) != 0U) groups_with_overlap.insert(i); @@ -1711,7 +1729,7 @@ void IXBar::getHashDistGroups(unsigned hash_table_input, int hash_group_opt[HASH if (groups_with_overlap.size() > 1) { return; } else if (groups_with_overlap.size() == 1) { - for (int i = 0; i < HASH_DIST_UNITS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_DIST_UNITS; i++) { if (groups_with_overlap.count(i) > 0) hash_group_opt[i] = hash_dist_groups[i]; else @@ -1722,7 +1740,7 @@ void IXBar::getHashDistGroups(unsigned hash_table_input, int hash_group_opt[HASH // A new group might be required, so create at most one new group bool first_unused = false; - for (int i = 0; i < HASH_DIST_UNITS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_DIST_UNITS; i++) { if (hash_dist_groups[i] == -1) { if (!first_unused) { first_unused = true; @@ -1816,7 +1834,7 @@ bool IXBar::allocProxyHashKey(const IR::MAU::Table *tbl, const PhvInfo &phv, con // Determining what bits are available are within the hash matrix bitvec unavailable_bits; - for (int index = 0; index < HASH_INDEX_GROUPS; index++) { + for (int index = 0; index < TofinoIXBarSpec::HASH_INDEX_GROUPS; index++) { for (auto ht : bitvec(hash_table_input)) { if ((1 << ht) & hash_index_inuse[index]) { unavailable_bits.setrange(index * RAM_LINE_SELECT_BITS, RAM_LINE_SELECT_BITS); @@ -1826,7 +1844,7 @@ bool IXBar::allocProxyHashKey(const IR::MAU::Table *tbl, const PhvInfo &phv, con for (int bit = 0; bit < IXBar::get_hash_single_bits(); bit++) { for (auto ht : bitvec(hash_table_input)) { if ((1 << ht) & hash_single_bit_inuse[bit]) { - unavailable_bits.setbit(bit + RAM_SELECT_BIT_START); + unavailable_bits.setbit(bit + TofinoIXBarSpec::RAM_SELECT_BIT_START); } } } @@ -1986,7 +2004,7 @@ bool IXBar::allocAllHashWays(bool ternary, const IR::MAU::Table *tbl, Use &alloc << hex(hf_hash_table_input)); int free_groups = 0; int group; - for (group = 0; group < HASH_INDEX_GROUPS; group++) { + for (group = 0; group < TofinoIXBarSpec::HASH_INDEX_GROUPS; group++) { if (!(hash_index_inuse[group] & hf_hash_table_input)) { free_groups++; } @@ -2039,8 +2057,8 @@ bool IXBar::allocAllHashWays(bool ternary, const IR::MAU::Table *tbl, Use &alloc std::map>> requiredSeedCombinations; for (auto way : alloc.way_use) - requiredSeedCombinations[way.source].emplace(INDEX_RANGE_SUBGROUP(way.index), - way.select_mask); + requiredSeedCombinations[way.source].emplace( + TofinoIXBarSpec::INDEX_RANGE_SUBGROUP(way.index), way.select_mask); for (auto kv : requiredSeedCombinations) { unsigned group = kv.first; @@ -2081,12 +2099,12 @@ bool IXBar::allocHashWay(const IR::MAU::Table *tbl, const LayoutOption *layout_o bool shared = false; LOG3("\tNeed " << way_bits << " mask bits for way " << alloc.way_use.size() << " in table " << tbl->name); - for (group = 0; group < HASH_INDEX_GROUPS; group++) { + for (group = 0; group < TofinoIXBarSpec::HASH_INDEX_GROUPS; group++) { if (!(hash_index_inuse[group] & hf_hash_table_input)) { break; } } - if (group >= HASH_INDEX_GROUPS) { + if (group >= TofinoIXBarSpec::HASH_INDEX_GROUPS) { if (alloc.way_use.empty()) { group = 0; // share with another table? BUG("Group was allocated with no available space to push hash ways"); @@ -2105,7 +2123,8 @@ bool IXBar::allocHashWay(const IR::MAU::Table *tbl, const LayoutOption *layout_o } } for (auto &way_use : alloc.way_use) { - BUG_CHECK(way_use.select.lo == RAM_SELECT_BIT_START, "invalid select range for tofino"); + BUG_CHECK(way_use.select.lo == TofinoIXBarSpec::RAM_SELECT_BIT_START, + "invalid select range for tofino"); } if (way_bits == 0) { @@ -2142,7 +2161,8 @@ bool IXBar::allocHashWay(const IR::MAU::Table *tbl, const LayoutOption *layout_o slice_to_select_bits[group] |= bitvec(way_mask); - alloc.way_use.emplace_back(hash_group, INDEX_BIT_RANGE(group), SELECT_BIT_RANGE, way_mask); + alloc.way_use.emplace_back(hash_group, TofinoIXBarSpec::INDEX_BIT_RANGE(group), + TofinoIXBarSpec::SELECT_BIT_RANGE, way_mask); LOG3("\tAllocation of way " << hash_group << " " << group << " 0x" << hex(way_mask)); hash_index_inuse[group] |= hf_hash_table_input; for (auto bit : bitvec(way_mask)) { @@ -2219,7 +2239,7 @@ bool IXBar::allocPartition(const IR::MAU::Table *tbl, const PhvInfo &phv, Use &m unsigned hf_hash_table_input = local_hash_table_input | hash_group_use[hash_group]; int group = -1; - for (int i = 0; i < HASH_INDEX_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_INDEX_GROUPS; i++) { if ((hash_index_inuse[i] & hf_hash_table_input) == 0) { group = i; break; @@ -2253,8 +2273,8 @@ bool IXBar::allocPartition(const IR::MAU::Table *tbl, const PhvInfo &phv, Use &m match_alloc.hash_table_inputs[hash_group] = local_hash_table_input; hash_group_use[hash_group] |= local_hash_table_input; update_hash_parity(match_alloc, hash_group); - match_alloc.way_use.emplace_back(hash_group, INDEX_BIT_RANGE(group), SELECT_BIT_RANGE, - way_mask); + match_alloc.way_use.emplace_back(hash_group, TofinoIXBarSpec::INDEX_BIT_RANGE(group), + TofinoIXBarSpec::SELECT_BIT_RANGE, way_mask); hash_index_inuse[group] |= hf_hash_table_input; for (auto bit : bitvec(way_mask)) { hash_single_bit_inuse[bit] |= hf_hash_table_input; @@ -2352,7 +2372,7 @@ bool IXBar::allocGateway(const IR::MAU::Table *tbl, const PhvInfo &phv, Use &all if (collect->bytes > 0) { alloc.gw_search_bus = true; alloc.gw_search_bus_bytes = collect->bytes; - if (xor_required) alloc.gw_search_bus_bytes += GATEWAY_SEARCH_BYTES; + if (xor_required) alloc.gw_search_bus_bytes += TofinoIXBarSpec::GATEWAY_SEARCH_BYTES; } if (collect->bits > 0) { @@ -2433,11 +2453,11 @@ int IXBar::max_bit_to_byte(bitvec bit_mask) { int IXBar::max_index_group(int max_bit) { int total_max = (max_bit + TableFormat::RAM_GHOST_BITS - 1) / TableFormat::RAM_GHOST_BITS; - return std::min(total_max, HASH_INDEX_GROUPS); + return std::min(total_max, TofinoIXBarSpec::HASH_INDEX_GROUPS); } int IXBar::max_index_single_bit(int max_bit) { - int max_single_bit = max_bit - TableFormat::RAM_GHOST_BITS * HASH_INDEX_GROUPS; + int max_single_bit = max_bit - TableFormat::RAM_GHOST_BITS * TofinoIXBarSpec::HASH_INDEX_GROUPS; max_single_bit = std::max(max_single_bit, 0); BUG_CHECK(max_single_bit <= IXBar::get_hash_single_bits(), "Requesting a bit beyond the size of the Galois matrix"); @@ -2445,7 +2465,7 @@ int IXBar::max_index_single_bit(int max_bit) { } bool IXBar::hash_use_free(int max_group, int max_single_bit, unsigned hash_table_input) { - for (int i = 0; i < HASH_TABLES; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_TABLES; i++) { if (((1 << i) & hash_table_input) == 0) continue; for (int j = 0; j < max_group; j++) { if ((hash_index_inuse[j] & (1 << i)) != 0) return false; @@ -2459,7 +2479,7 @@ bool IXBar::hash_use_free(int max_group, int max_single_bit, unsigned hash_table void IXBar::write_hash_use(int max_group, int max_single_bit, unsigned hash_table_input, cstring name) { - for (int i = 0; i < HASH_TABLES; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_TABLES; i++) { if (((1 << i) & hash_table_input) == 0) continue; for (int j = 0; j < max_group; j++) { hash_index_use[i][j] = name; @@ -2541,8 +2561,9 @@ bool IXBar::allocSelector(const IR::MAU::Selector *as, const IR::MAU::Table *tbl mah.allocated = true; mah.group = hash_group; mah.algorithm = as->algorithm; - int mode_width_bits = as->mode == IR::MAU::SelectorMode::RESILIENT ? RESILIENT_MODE_HASH_BITS - : FAIR_MODE_HASH_BITS; + int mode_width_bits = as->mode == IR::MAU::SelectorMode::RESILIENT + ? TofinoIXBarSpec::RESILIENT_MODE_HASH_BITS + : TofinoIXBarSpec::FAIR_MODE_HASH_BITS; if (mah.algorithm.size_from_algorithm()) { if (mode_width_bits > mah.algorithm.size) { // FIXME: Debatably be moved to an error, but have to wait on a p4-tests update @@ -2687,11 +2708,12 @@ bool IXBar::allocMeter(const IR::MAU::Meter *mtr, const IR::MAU::Table *tbl, con return a_fi < b_fi; }); // Byte mask for a meter is 4 bytes - byte_mask = ((1U << LPF_INPUT_BYTES) - 1); - if (Device::currentDevice() == Device::TOFINO) byte_mask <<= TOFINO_METER_ALU_BYTE_OFFSET; + byte_mask = ((1U << TofinoIXBarSpec::LPF_INPUT_BYTES) - 1); + if (Device::currentDevice() == Device::TOFINO) + byte_mask <<= TofinoIXBarSpec::TOFINO_METER_ALU_BYTE_OFFSET; hm_reqs.max_search_buses = 1; } else { - hm_reqs.index_groups = HASH_INDEX_GROUPS; + hm_reqs.index_groups = TofinoIXBarSpec::HASH_INDEX_GROUPS; } LOG3("Alloc meter " << mtr->name << " on_search_bus " << on_search_bus << " with " @@ -2821,8 +2843,9 @@ bool IXBar::setup_stateful_search_bus(const IR::MAU::StatefulAlu *salu, Use &all byte_offset += width; } - const int ixbar_initial_position = - Device::currentDevice() == Device::TOFINO ? TOFINO_METER_ALU_BYTE_OFFSET : 0; + const int ixbar_initial_position = Device::currentDevice() == Device::TOFINO + ? TofinoIXBarSpec::TOFINO_METER_ALU_BYTE_OFFSET + : 0; for (auto source : sources.phv_sources) { for (auto &range : Keys(source.second)) { unsigned source_byte_mask = (1 << ((range.size() + 7) / 8)) - 1; @@ -2936,18 +2959,18 @@ bool IXBar::setup_stateful_hash_bus(const PhvInfo &, const IR::MAU::StatefulAlu // Parity Enabled - Bits Avail [47..0] auto parity_status = hash_group_parity_use[hash_group]; if (parity_status == PARITY_NONE) { - if (end_bit >= METER_ALU_HASH_BITS) return false; - if (end_bit >= METER_ALU_HASH_PARITY_BYTE_START) { + if (end_bit >= TofinoIXBarSpec::METER_ALU_HASH_BITS) return false; + if (end_bit >= TofinoIXBarSpec::METER_ALU_HASH_PARITY_BYTE_START) { // Explicitly disable parity on the hash group as we do not // want any other shared resource to enable it hash_group_parity_use[hash_group] = PARITY_DISABLED; } } else if (parity_status == PARITY_ENABLED) { - if (end_bit >= METER_ALU_HASH_PARITY_BYTE_START) { + if (end_bit >= TofinoIXBarSpec::METER_ALU_HASH_PARITY_BYTE_START) { return false; } } else if (parity_status == PARITY_DISABLED) { - if (end_bit >= METER_ALU_HASH_BITS) return false; + if (end_bit >= TofinoIXBarSpec::METER_ALU_HASH_BITS) return false; } phv_src_inuse[alu_slot_index] = true; mah.computed_expressions[start_bit] = slice; @@ -3143,7 +3166,7 @@ bool IXBar::isHashDistAddress(HashDistDest_t dest) const { * inputs to hash distribution) */ void IXBar::determineHashDistInUse(int hash_group, bitvec &units_in_use, bitvec &hash_bits_in_use) { - for (int i = 0; i < HASH_TABLES; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_TABLES; i++) { if (((1 << i) & hash_group_use[hash_group]) == 0) continue; units_in_use |= hash_dist_inuse[i]; hash_bits_in_use |= hash_dist_bit_inuse[i]; @@ -3166,18 +3189,19 @@ bool IXBar::allocHashDistSection(bitvec post_expand_bits, bitvec possible_shifts determineHashDistInUse(hash_group, units_in_use, hash_bits_in_use); bool found = false; - for (int i = 0; i < HASH_DIST_SLICES; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_DIST_SLICES; i++) { if (units_in_use.getbit(i)) continue; unit_allocated = i; - bitvec hash_bits_in_unit = hash_bits_in_use.getslice(i * HASH_DIST_BITS, HASH_DIST_BITS); + bitvec hash_bits_in_unit = hash_bits_in_use.getslice(i * TofinoIXBarSpec::HASH_DIST_BITS, + TofinoIXBarSpec::HASH_DIST_BITS); for (auto possible_shift : possible_shifts) { bitvec hash_bits_to_be_used = post_expand_bits << possible_shift; - BUG_CHECK(hash_bits_to_be_used.max().index() < HASH_DIST_BITS, + BUG_CHECK(hash_bits_to_be_used.max().index() < TofinoIXBarSpec::HASH_DIST_BITS, "Data is not " "contained within a single hash dist unit"); if ((hash_bits_to_be_used & hash_bits_in_unit).empty()) { found = true; - hash_bits_allocated = hash_bits_to_be_used << (i * HASH_DIST_BITS); + hash_bits_allocated = hash_bits_to_be_used << (i * TofinoIXBarSpec::HASH_DIST_BITS); break; } } @@ -3205,16 +3229,18 @@ bool IXBar::allocHashDistWideAddress(bitvec post_expand_bits, bitvec possible_sh bool found = false; - for (int i = 0; i < HASH_DIST_SLICES - 1; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_DIST_SLICES - 1; i++) { if (units_in_use.getbit(i)) continue; - if (chained_addr && units_in_use.getbit(HASH_DIST_SLICES - 1)) continue; + if (chained_addr && units_in_use.getbit(TofinoIXBarSpec::HASH_DIST_SLICES - 1)) continue; unit_allocated = i; for (auto possible_shift : possible_shifts) { bitvec shifted_bits = post_expand_bits << possible_shift; - bitvec lower_bits = shifted_bits.getslice(0, HASH_DIST_BITS); - bitvec upper_bits = shifted_bits.getslice(HASH_DIST_BITS, HASH_DIST_EXPAND_BITS); - hash_bits_allocated = lower_bits << (i * HASH_DIST_BITS); - hash_bits_allocated |= upper_bits << (HASH_DIST_BITS * 2 + HASH_DIST_EXPAND_BITS * i); + bitvec lower_bits = shifted_bits.getslice(0, TofinoIXBarSpec::HASH_DIST_BITS); + bitvec upper_bits = shifted_bits.getslice(TofinoIXBarSpec::HASH_DIST_BITS, + TofinoIXBarSpec::HASH_DIST_EXPAND_BITS); + hash_bits_allocated = lower_bits << (i * TofinoIXBarSpec::HASH_DIST_BITS); + hash_bits_allocated |= upper_bits << (TofinoIXBarSpec::HASH_DIST_BITS * 2 + + TofinoIXBarSpec::HASH_DIST_EXPAND_BITS * i); if ((hash_bits_allocated & hash_bits_in_use).empty()) { found = true; break; @@ -3369,20 +3395,20 @@ void IXBar::lockInHashDistArrays(safe_vector *alloced, int hash_gro unsigned hash_table_input, int asm_unit, bitvec hash_bits_used, HashDistDest_t /* dest */, cstring name) { if (alloced) fill_out_use(*alloced, false); - for (int i = 0; i < HASH_TABLES; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_TABLES; i++) { if (((1 << i) & hash_table_input) == 0) continue; - hash_dist_use[i][asm_unit % HASH_DIST_SLICES] = name; - hash_dist_inuse[i].setbit(asm_unit % HASH_DIST_SLICES); + hash_dist_use[i][asm_unit % TofinoIXBarSpec::HASH_DIST_SLICES] = name; + hash_dist_inuse[i].setbit(asm_unit % TofinoIXBarSpec::HASH_DIST_SLICES); } - for (int i = 0; i < HASH_TABLES; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_TABLES; i++) { if (((1 << i) & hash_table_input) == 0) continue; for (auto bit : hash_bits_used) { hash_dist_bit_use[i][bit] = name; hash_dist_bit_inuse[i].setbit(bit); } } - hash_dist_groups[asm_unit / HASH_DIST_SLICES] = hash_group; + hash_dist_groups[asm_unit / TofinoIXBarSpec::HASH_DIST_SLICES] = hash_group; hash_group_use[hash_group] |= hash_table_input; hash_used_per_function[hash_group] |= hash_bits_used; @@ -3478,7 +3504,7 @@ bool IXBar::allocHashDist(safe_vector &alloc_reqs, Hash create_alloc(map_alloc, all_reqs.use); bool wide_address = false; - if (bits_in_use.max().index() >= HASH_DIST_BITS) { + if (bits_in_use.max().index() >= TofinoIXBarSpec::HASH_DIST_BITS) { BUG_CHECK(isHashDistAddress(dest), "Allocating illegal hash_dist"); wide_address = true; } @@ -3501,7 +3527,7 @@ bool IXBar::allocHashDist(safe_vector &alloc_reqs, Hash bitvec possible_shifts(0, 1); unsigned hash_table_input = all_reqs.compute_hash_tables(); - int hash_group_opts[HASH_DIST_UNITS] = {-1, -1}; + int hash_group_opts[TofinoIXBarSpec::HASH_DIST_UNITS] = {-1, -1}; getHashDistGroups(hash_table_input, hash_group_opts); bool can_allocate_hash = false; @@ -3512,7 +3538,7 @@ bool IXBar::allocHashDist(safe_vector &alloc_reqs, Hash // Determine the galois matrix positions, as well has hash_function (of 8) associated hash // functions. - for (int i = 0; i < HASH_DIST_UNITS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_DIST_UNITS; i++) { if (hash_group_opts[i] == -1) continue; hash_group = hash_group_opts[i]; three_unit_section = i; @@ -3540,12 +3566,13 @@ bool IXBar::allocHashDist(safe_vector &alloc_reqs, Hash lockInHashDistArrays(&alloced, hash_group, hash_table_input, asm_unit, hash_bits_used, dest, name); - if (wide_address) use.expand = (asm_unit % HASH_DIST_SLICES) * 7; + if (wide_address) use.expand = (asm_unit % TofinoIXBarSpec::HASH_DIST_SLICES) * 7; use.unit = asm_unit; if (dest != HD_PRECOLOR) { use.shift = post_expand_shift; - use.shift += (hash_bits_used.min().index() % HASH_DIST_BITS) - bits_in_use.min().index(); - use.mask = bits_in_use.getslice(0, HASH_DIST_MAX_MASK_BITS); + use.shift += (hash_bits_used.min().index() % TofinoIXBarSpec::HASH_DIST_BITS) - + bits_in_use.min().index(); + use.mask = bits_in_use.getslice(0, TofinoIXBarSpec::HASH_DIST_MAX_MASK_BITS); if (chained_addr) use.outputs.insert("lo"_cs); } @@ -3583,7 +3610,7 @@ void IXBar::createChainedHashDist(const HashDistUse &hd_alloc, HashDistUse &chai curr.p4_hash_range = ir_alloc.p4_hash_range; curr.dest = HD_IMMED_HI; curr.created_hd = ir_alloc.created_hd; - for (int i = 0; i < HASH_GROUPS; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_GROUPS; i++) { curr_use.hash_table_inputs[i] = ir_alloc_use.hash_table_inputs[i]; } curr_use.hash_dist_hash.allocated = true; @@ -3594,16 +3621,17 @@ void IXBar::createChainedHashDist(const HashDistUse &hd_alloc, HashDistUse &chai chained_hd_alloc.ir_allocations.emplace_back(curr); } - chained_hd_alloc.unit = (hd_alloc.unit / HASH_DIST_SLICES) * HASH_DIST_SLICES + 2; + chained_hd_alloc.unit = + (hd_alloc.unit / TofinoIXBarSpec::HASH_DIST_SLICES) * TofinoIXBarSpec::HASH_DIST_SLICES + 2; chained_hd_alloc.shift = hd_alloc.expand; - chained_hd_alloc.mask = bitvec(chained_hd_alloc.shift, HASH_DIST_EXPAND_BITS); + chained_hd_alloc.mask = bitvec(chained_hd_alloc.shift, TofinoIXBarSpec::HASH_DIST_EXPAND_BITS); chained_hd_alloc.outputs.insert("hi"_cs); unsigned ht_inputs = hash_table_inputs(chained_hd_alloc); - for (int ht = 0; ht < HASH_TABLES; ht++) { + for (int ht = 0; ht < TofinoIXBarSpec::HASH_TABLES; ht++) { if (((1 << ht) & ht_inputs) == 0) continue; - hash_dist_use[ht][chained_hd_alloc.unit % HASH_DIST_SLICES] = name; - hash_dist_inuse[ht].setbit(chained_hd_alloc.unit % HASH_DIST_SLICES); + hash_dist_use[ht][chained_hd_alloc.unit % TofinoIXBarSpec::HASH_DIST_SLICES] = name; + hash_dist_inuse[ht].setbit(chained_hd_alloc.unit % TofinoIXBarSpec::HASH_DIST_SLICES); } } @@ -3795,14 +3823,16 @@ void IXBar::XBarHashDist::immediate_inputs() { if (hash == nullptr) continue; le_bitrange immed_range = {pos.first, pos.first + hash->size() - 1}; for (int i = 0; i < 2; i++) { - le_bitrange immed_impact = {i * HASH_DIST_BITS, (i + 1) * HASH_DIST_BITS - 1}; + le_bitrange immed_impact = {i * TofinoIXBarSpec::HASH_DIST_BITS, + (i + 1) * TofinoIXBarSpec::HASH_DIST_BITS - 1}; auto boost_sl = toClosedRange( immed_range.intersectWith(immed_impact)); if (boost_sl == std::nullopt) continue; le_bitrange overlap = *boost_sl; int hash_bits_shift = (-1 * pos.first); le_bitrange hash_range = overlap.shiftedByBits(hash_bits_shift); - le_bitrange hash_dist_range = overlap.shiftedByBits(-1 * i * HASH_DIST_BITS); + le_bitrange hash_dist_range = + overlap.shiftedByBits(-1 * i * TofinoIXBarSpec::HASH_DIST_BITS); P4HashFunction *func = new P4HashFunction(hash->func()); func->slice(hash_range); HashDistDest_t dest = static_cast(i); @@ -4207,19 +4237,22 @@ void IXBar::update(cstring name, const ::IXBar::Use &alloc_) { hash_group_use[bits.group] |= alloc.hash_table_inputs[bits.group]; update_hash_parity(bits.group); hash_group_print_use[bits.group] = name; - hash_used_per_function[bits.group].setrange(bits.bit + RAM_SELECT_BIT_START, bits.width); + hash_used_per_function[bits.group].setrange( + bits.bit + TofinoIXBarSpec::RAM_SELECT_BIT_START, bits.width); } for (auto &way : alloc.way_use) { hash_group_use[way.source] |= alloc.hash_table_inputs[way.source]; update_hash_parity(way.source); hash_group_print_use[way.source] = name; hash_used_per_function[way.source].setrange(way.index.lo, way.index.size()); - BUG_CHECK(way.select.lo == RAM_SELECT_BIT_START, "invalid select range for tofino"); + BUG_CHECK(way.select.lo == TofinoIXBarSpec::RAM_SELECT_BIT_START, + "invalid select range for tofino"); hash_used_per_function[way.source] |= bitvec(way.select_mask) << way.select.lo; - hash_index_inuse[INDEX_RANGE_SUBGROUP(way.index)] |= alloc.hash_table_inputs[way.source]; + hash_index_inuse[TofinoIXBarSpec::INDEX_RANGE_SUBGROUP(way.index)] |= + alloc.hash_table_inputs[way.source]; for (int hash : bitvec(alloc.hash_table_inputs[way.source])) { - if (!hash_index_use[hash][INDEX_RANGE_SUBGROUP(way.index)]) - hash_index_use[hash][INDEX_RANGE_SUBGROUP(way.index)] = name; + if (!hash_index_use[hash][TofinoIXBarSpec::INDEX_RANGE_SUBGROUP(way.index)]) + hash_index_use[hash][TofinoIXBarSpec::INDEX_RANGE_SUBGROUP(way.index)] = name; for (auto bit : bitvec(way.select_mask)) { hash_single_bit_inuse[bit] |= alloc.hash_table_inputs[way.source]; if (!hash_single_bit_use[hash][bit]) hash_single_bit_use[hash][bit] = name; @@ -4251,7 +4284,7 @@ void IXBar::update(cstring name, const ::IXBar::Use &alloc_) { cstring local_name = name; if (!hdh.name.isNullOrEmpty()) local_name = hdh.name; - for (int i = 0; i < HASH_TABLES; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_TABLES; i++) { if (((1U << i) & alloc.hash_table_inputs[hdh.group]) == 0) continue; for (auto bit : bitvec(hdh.galois_matrix_bits)) { if (!hash_dist_bit_use[i][bit]) { @@ -4277,7 +4310,7 @@ void IXBar::update(cstring name, const ::IXBar::Use &alloc_) { if (alloc.proxy_hash_key_use.allocated) { auto &ph = alloc.proxy_hash_key_use; - for (int ht = 0; ht < HASH_TABLES; ht++) { + for (int ht = 0; ht < TofinoIXBarSpec::HASH_TABLES; ht++) { if (((1U << ht) & alloc.hash_table_inputs[ph.group]) == 0) continue; unsigned indexes = index_groups_used(ph.hash_bits); for (auto idx : bitvec(indexes)) { @@ -4309,14 +4342,14 @@ void IXBar::update(cstring name, const HashDistUse &hash_dist_alloc) { update(name, *ir_alloc.use); } - for (int i = 0; i < HASH_TABLES; i++) { + for (int i = 0; i < TofinoIXBarSpec::HASH_TABLES; i++) { if (((1U << i) & hash_table_inputs(hash_dist_alloc)) == 0) continue; - int slice = hash_dist_alloc.unit % HASH_DIST_SLICES; + int slice = hash_dist_alloc.unit % TofinoIXBarSpec::HASH_DIST_SLICES; if (!hash_dist_use[i][slice].isNull()) hash_dist_use[i][slice] = name; hash_dist_inuse[i].setbit(slice); } - int hash_dist_48_bit_unit = hash_dist_alloc.unit / HASH_DIST_SLICES; + int hash_dist_48_bit_unit = hash_dist_alloc.unit / TofinoIXBarSpec::HASH_DIST_SLICES; if (hash_dist_groups[hash_dist_48_bit_unit] != hash_dist_alloc.hash_group() && hash_dist_groups[hash_dist_48_bit_unit] != -1) BUG("Conflicting hash distribution unit groups"); @@ -4356,8 +4389,8 @@ void IXBar::update(const IR::MAU::Table *tbl) { * ixbar group 2. This is to guarantee that this space is reserved. */ void IXBar::add_collisions() { - for (int hg = 0; hg < HASH_GROUPS; hg++) { - for (int idx = 0; idx < HASH_INDEX_GROUPS; idx++) { + for (int hg = 0; hg < TofinoIXBarSpec::HASH_GROUPS; hg++) { + for (int idx = 0; idx < TofinoIXBarSpec::HASH_INDEX_GROUPS; idx++) { if ((hash_group_use[hg] & hash_index_inuse[idx]) != 0) { for (auto ht : bitvec(hash_group_use[hg])) { if (hash_index_use[ht][idx].isNull()) hash_index_use[ht][idx] = "$collision"_cs; @@ -4385,16 +4418,16 @@ void IXBar::add_collisions() { * to be set, which is currently only guaranteed on update. */ void IXBar::verify_hash_matrix() const { - for (int hg = 0; hg < HASH_GROUPS; hg++) { - std::vector index_groups(HASH_INDEX_GROUPS, cstring()); - for (int idx = 0; idx < HASH_INDEX_GROUPS; idx++) { + for (int hg = 0; hg < TofinoIXBarSpec::HASH_GROUPS; hg++) { + std::vector index_groups(TofinoIXBarSpec::HASH_INDEX_GROUPS, cstring()); + for (int idx = 0; idx < TofinoIXBarSpec::HASH_INDEX_GROUPS; idx++) { bitvec idx_in_use = hash_used_per_function[hg].getslice(idx * RAM_LINE_SELECT_BITS, RAM_LINE_SELECT_BITS); if (idx_in_use.empty()) continue; - BUG_CHECK(idx < HASH_INDEX_GROUPS, "Illegal idx %1%", idx); + BUG_CHECK(idx < TofinoIXBarSpec::HASH_INDEX_GROUPS, "Illegal idx %1%", idx); unsigned relevant_hash_tables = hash_group_use[hg] & hash_index_inuse[idx]; for (auto ht : bitvec(relevant_hash_tables)) { - BUG_CHECK(ht < HASH_TABLES, "Illegal hash table %1%", ht); + BUG_CHECK(ht < TofinoIXBarSpec::HASH_TABLES, "Illegal hash table %1%", ht); if (index_groups[idx].isNull()) index_groups[idx] = hash_index_use[ht][idx]; else @@ -4407,11 +4440,12 @@ void IXBar::verify_hash_matrix() const { std::vector single_bits(IXBar::get_hash_single_bits(), cstring()); for (int bit = 0; bit < IXBar::get_hash_single_bits(); bit++) { - if (!hash_used_per_function[hg].getbit(bit + RAM_SELECT_BIT_START)) continue; + if (!hash_used_per_function[hg].getbit(bit + TofinoIXBarSpec::RAM_SELECT_BIT_START)) + continue; unsigned relevant_hash_tables = hash_group_use[hg] & hash_single_bit_inuse[bit]; BUG_CHECK(bit < IXBar::get_hash_single_bits(), "Illegal bit %1%", bit); for (auto ht : bitvec(relevant_hash_tables)) { - BUG_CHECK(ht < HASH_TABLES, "Illegal hash table %1%", ht); + BUG_CHECK(ht < TofinoIXBarSpec::HASH_TABLES, "Illegal hash table %1%", ht); if (single_bits[bit].isNull()) single_bits[bit] = hash_single_bit_use[ht][bit]; else @@ -4436,9 +4470,9 @@ void IXBar::dbprint(std::ostream &out) const { add_names(byte_group_use, fields); sort_names(fields); out << "exact ixbar groups ternary ixbar groups" << Log::endl; - for (int r = 0; r < IXBar::EXACT_GROUPS; r++) { + for (int r = 0; r < TofinoIXBarSpec::EXACT_GROUPS; r++) { write_group(out, exact_use[r], fields); - if (r < IXBar::BYTE_GROUPS) { + if (r < TofinoIXBarSpec::BYTE_GROUPS) { out << " "; write_group(out, ternary_use[2 * r], fields); out << " "; @@ -4469,12 +4503,12 @@ void IXBar::dbprint(std::ostream &out) const { sort_names(tables); out << "hash select bits Groups hd /- hash dist bits --- (Groups: " << hash_dist_groups[0] << " " << hash_dist_groups[1] << ")" << Log::endl; - for (int h = 0; h < IXBar::HASH_TABLES; ++h) { + for (int h = 0; h < TofinoIXBarSpec::HASH_TABLES; ++h) { write_group(out, hash_index_use[h], tables); out << " "; write_group(out, hash_single_bit_use[h], tables); out << " "; - if (h < IXBar::HASH_GROUPS) { + if (h < TofinoIXBarSpec::HASH_GROUPS) { write_one(out, hash_group_print_use[h], tables); out << hex(hash_group_use[h], 4, '0'); } else { diff --git a/backends/tofino/bf-p4c/mau/tofino/input_xbar.h b/backends/tofino/bf-p4c/mau/tofino/input_xbar.h index fc27e94225..66d31044e9 100644 --- a/backends/tofino/bf-p4c/mau/tofino/input_xbar.h +++ b/backends/tofino/bf-p4c/mau/tofino/input_xbar.h @@ -19,76 +19,36 @@ #ifndef BF_P4C_MAU_TOFINO_INPUT_XBAR_H_ #define BF_P4C_MAU_TOFINO_INPUT_XBAR_H_ -/* clang-format off */ -#include "backends/tofino/bf-p4c/mau/input_xbar.h" #include "backends/tofino/bf-p4c/common/alloc.h" +#include "backends/tofino/bf-p4c/mau/input_xbar.h" namespace Tofino { using namespace P4; struct IXBar : public ::IXBar { - // FIXME -- make these per-device params - static constexpr int EXACT_GROUPS = 8; - static constexpr int EXACT_BYTES_PER_GROUP = 16; - static constexpr int HASH_TABLES = 16; - static constexpr int HASH_GROUPS = 8; - static constexpr int HASH_INDEX_GROUPS = 4; /* groups of 10 bits for indexing */ - static constexpr int HASH_SINGLE_BITS = 12; /* top 12 bits of hash table individually */ - static constexpr int HASH_PARITY_BIT = 51; /* If enabled reserved parity bit position */ - static constexpr int RAM_SELECT_BIT_START = 40; - static constexpr int RAM_LINE_SELECT_BITS = 10; - static constexpr int HASH_MATRIX_SIZE = RAM_SELECT_BIT_START + HASH_SINGLE_BITS; - static constexpr int HASH_DIST_SLICES = 3; - static constexpr int HASH_DIST_BITS = 16; - static constexpr int HASH_DIST_EXPAND_BITS = 7; - static constexpr int HASH_DIST_MAX_MASK_BITS = HASH_DIST_BITS + HASH_DIST_EXPAND_BITS; - static constexpr int HASH_DIST_UNITS = 2; - static constexpr int TOFINO_METER_ALU_BYTE_OFFSET = 8; - static constexpr int LPF_INPUT_BYTES = 4; - static constexpr int TERNARY_GROUPS = StageUse::MAX_TERNARY_GROUPS; - static constexpr int BYTE_GROUPS = StageUse::MAX_TERNARY_GROUPS/2; - static constexpr int TERNARY_BYTES_PER_GROUP = 5; - static constexpr int TERNARY_BYTES_PER_BIG_GROUP = 11; - static constexpr int GATEWAY_SEARCH_BYTES = 4; - static constexpr int RESILIENT_MODE_HASH_BITS = 51; - static constexpr int FAIR_MODE_HASH_BITS = 14; - static constexpr int METER_ALU_HASH_BITS = 52; - static constexpr int METER_ALU_HASH_PARITY_BYTE_START = 48; - static constexpr int METER_PRECOLOR_SIZE = 2; - static constexpr int REPEATING_CONSTRAINT_SECT = 4; - static constexpr int MAX_HASH_BITS = 52; - static constexpr le_bitrange SELECT_BIT_RANGE = - le_bitrange(RAM_SELECT_BIT_START, METER_ALU_HASH_BITS-1); - static constexpr le_bitrange INDEX_BIT_RANGE(int group) { - return le_bitrange(group*RAM_LINE_SELECT_BITS, (group+1)*RAM_LINE_SELECT_BITS - 1); } - static constexpr int INDEX_RANGE_SUBGROUP(le_bitrange r) { return r.lo / RAM_LINE_SELECT_BITS; } - static int get_meter_alu_hash_bits() { // If hash parity is enabled reserve a bit for parity - if (!BackendOptions().disable_gfm_parity) - return METER_ALU_HASH_BITS - 1; - return METER_ALU_HASH_BITS; + if (!BackendOptions().disable_gfm_parity) return TofinoIXBarSpec::METER_ALU_HASH_BITS - 1; + return TofinoIXBarSpec::METER_ALU_HASH_BITS; } static int get_hash_single_bits() { static bool disable_gfm_parity = BackendOptions().disable_gfm_parity; // If hash parity is enabled reserve a bit for parity - if (!disable_gfm_parity) - return HASH_SINGLE_BITS - 1; - return HASH_SINGLE_BITS; + if (!disable_gfm_parity) return TofinoIXBarSpec::HASH_SINGLE_BITS - 1; + return TofinoIXBarSpec::HASH_SINGLE_BITS; } private: static int get_hash_matrix_size() { - return RAM_SELECT_BIT_START + get_hash_single_bits(); + return TofinoIXBarSpec::RAM_SELECT_BIT_START + get_hash_single_bits(); } static int get_max_hash_bits() { // If hash parity is enabled reserve a bit for parity - if (!BackendOptions().disable_gfm_parity) - return MAX_HASH_BITS - 1; - return MAX_HASH_BITS; + if (!BackendOptions().disable_gfm_parity) return TofinoIXBarSpec::MAX_HASH_BITS - 1; + return TofinoIXBarSpec::MAX_HASH_BITS; } using Loc = ::IXBar::Loc; @@ -111,57 +71,68 @@ struct IXBar : public ::IXBar { /** IXBar tracks the use of all the input xbar bytes in a single stage. Each byte use is set * to record the container it will be getting and the bit offset within the container. * NOTE: Changes here require changes to .gdbinit pretty printer */ - BFN::Alloc2D, EXACT_GROUPS, EXACT_BYTES_PER_GROUP> - exact_use; - BFN::Alloc2D, TERNARY_GROUPS, TERNARY_BYTES_PER_GROUP> - ternary_use; - BFN::Alloc1D, BYTE_GROUPS> byte_group_use; + BFN::Alloc2D, TofinoIXBarSpec::EXACT_GROUPS, + TofinoIXBarSpec::EXACT_BYTES_PER_GROUP> + exact_use; + BFN::Alloc2D, TofinoIXBarSpec::TERNARY_GROUPS, + TofinoIXBarSpec::TERNARY_BYTES_PER_GROUP> + ternary_use; + BFN::Alloc1D, TofinoIXBarSpec::BYTE_GROUPS> byte_group_use; BFN::Alloc2Dbase> &use(bool ternary) { if (ternary) return ternary_use; - return exact_use; } + return exact_use; + } /* reverse maps of the above, mapping containers sets of group+byte */ - std::multimap exact_fields; - std::multimap ternary_fields; + std::multimap exact_fields; + std::multimap ternary_fields; std::multimap &fields(bool ternary) { - return ternary ? ternary_fields : exact_fields; } + return ternary ? ternary_fields : exact_fields; + } // map from container to tables that use those fields (mostly for debugging) - std::map> field_users; + std::map> field_users; /* Track the use of hashtables/groups too -- FIXME -- should it be a separate data structure? * strings here are table names * NOTE: Changes here require changes to .gdbinit pretty printer */ - unsigned hash_index_inuse[HASH_INDEX_GROUPS] = { 0 }; - BFN::Alloc2D hash_index_use; - BFN::Alloc2D hash_single_bit_use; - unsigned hash_single_bit_inuse[HASH_SINGLE_BITS] = { 0 }; - BFN::Alloc1D hash_group_print_use; - unsigned hash_group_use[HASH_GROUPS] = { 0 }; - BFN::Alloc2D hash_dist_use; - bitvec hash_dist_inuse[HASH_TABLES] = { bitvec() }; - BFN::Alloc2D hash_dist_bit_use; - bitvec hash_dist_bit_inuse[HASH_TABLES] = { bitvec() }; - parity_status_t hash_group_parity_use[HASH_GROUPS] = { PARITY_NONE }; + unsigned hash_index_inuse[TofinoIXBarSpec::HASH_INDEX_GROUPS] = {0}; + BFN::Alloc2D + hash_index_use; + BFN::Alloc2D + hash_single_bit_use; + unsigned hash_single_bit_inuse[TofinoIXBarSpec::HASH_SINGLE_BITS] = {0}; + BFN::Alloc1D hash_group_print_use; + unsigned hash_group_use[TofinoIXBarSpec::HASH_GROUPS] = {0}; + BFN::Alloc2D + hash_dist_use; + bitvec hash_dist_inuse[TofinoIXBarSpec::HASH_TABLES] = {bitvec()}; + BFN::Alloc2D + hash_dist_bit_use; + bitvec hash_dist_bit_inuse[TofinoIXBarSpec::HASH_TABLES] = {bitvec()}; + parity_status_t hash_group_parity_use[TofinoIXBarSpec::HASH_GROUPS] = {PARITY_NONE}; // Added on update to be verified - bitvec hash_used_per_function[HASH_GROUPS] = { bitvec() }; + bitvec hash_used_per_function[TofinoIXBarSpec::HASH_GROUPS] = {bitvec()}; - int hash_dist_groups[HASH_DIST_UNITS] = {-1, -1}; + int hash_dist_groups[TofinoIXBarSpec::HASH_DIST_UNITS] = {-1, -1}; friend class IXBarRealign; /* API for unit tests */ public: BFN::Alloc2Dbase> &get_exact_use() { return exact_use; } BFN::Alloc2Dbase> &get_ternary_use() { return ternary_use; } - BFN::Alloc1D, BYTE_GROUPS> &get_byte_group_use() { - return byte_group_use; } + BFN::Alloc1D, TofinoIXBarSpec::BYTE_GROUPS> & + get_byte_group_use() { + return byte_group_use; + } // map (type, group, byte) coordinate to linear xbar output space unsigned toIXBarOutputByte(bool ternary, int group, int byte) { unsigned offset = 0; if (ternary) { unsigned mid_byte_count = (group / 2) + (group % 2); - offset = (group / 2) * 10 + (group % 2) * 5 + byte + mid_byte_count; + offset = (group / 2) * 10 + (group % 2) * 5 + byte + mid_byte_count; } else { offset = group * 16 + byte; } @@ -169,7 +140,7 @@ struct IXBar : public ::IXBar { } private: - std::set dleft_updates; + std::set dleft_updates; public: using byte_type_t = ::IXBar::byte_type_t; @@ -190,9 +161,9 @@ struct IXBar : public ::IXBar { static constexpr auto HD_DESTS = ::IXBar::HD_DESTS; struct Use : public ::IXBar::Use { - bool gw_search_bus = false; - int gw_search_bus_bytes = 0; - bool gw_hash_group = false; + bool gw_search_bus = false; + int gw_search_bus_bytes = 0; + bool gw_hash_group = false; parity_status_t parity = PARITY_NONE; bool search_data() const { return gw_search_bus || gw_hash_group; } @@ -200,26 +171,28 @@ struct IXBar : public ::IXBar { HashDistDest_t hash_dist_type = HD_DESTS; std::string hash_dist_used_for() const override { - return IXBar::hash_dist_name(hash_dist_type); } + return IXBar::hash_dist_name(hash_dist_type); + } /* which of the 16 hash tables we are using (bitvec) */ - unsigned hash_table_inputs[HASH_GROUPS] = { 0 }; + unsigned hash_table_inputs[TofinoIXBarSpec::HASH_GROUPS] = {0}; /* hash seed for different hash groups */ - bitvec hash_seed[HASH_GROUPS]; + bitvec hash_seed[TofinoIXBarSpec::HASH_GROUPS]; /* tracking bits that are placed into the upper 12 bits of a hash group * (with an identity hash) for use by a gateway */ struct Bits { - cstring field; - int group; - int lo, bit, width; - bool valid; + cstring field; + int group; + int lo, bit, width; + bool valid; Bits(cstring f, int g, int l, int b, int w) - : field(f), group(g), lo(l), bit(b), width(w), valid(false) {} + : field(f), group(g), lo(l), bit(b), width(w), valid(false) {} Bits(cstring f, int g, int l, int b, int w, bool v) - : field(f), group(g), lo(l), bit(b), width(w), valid(v) {} - int hi() const { return lo + width - 1; } }; - safe_vector bit_use; + : field(f), group(g), lo(l), bit(b), width(w), valid(v) {} + int hi() const { return lo + width - 1; } + }; + safe_vector bit_use; /* tracks hash use for Stateful and Selectors (and meter?) */ struct MeterAluHash { @@ -238,7 +211,8 @@ struct IXBar : public ::IXBar { } } meter_alu_hash; const std::map &hash_computed_expressions() const override { - return meter_alu_hash.computed_expressions; } + return meter_alu_hash.computed_expressions; + } /* tracks hash dist use (and hashes */ struct HashDistHash { @@ -247,8 +221,8 @@ struct IXBar : public ::IXBar { bitvec galois_matrix_bits; IR::MAU::HashFunction algorithm; std::map galois_start_bit_to_p4_hash; - const IR::Expression *hash_gen_expr = nullptr; // expression from HashGenExpr - cstring name; // Original name in case of hash distribution unit sharing + const IR::Expression *hash_gen_expr = nullptr; // expression from HashGenExpr + cstring name; // Original name in case of hash distribution unit sharing void clear() { allocated = false; @@ -273,8 +247,8 @@ struct IXBar : public ::IXBar { } proxy_hash_key_use; struct SaluInputSource { - unsigned data_bytemask = 0; - unsigned hash_bytemask = 0; // redundant with meter_alu_hash.bit_mask? + unsigned data_bytemask = 0; + unsigned hash_bytemask = 0; // redundant with meter_alu_hash.bit_mask? void clear() { data_bytemask = hash_bytemask = 0; } bool empty() const { return !data_bytemask && !hash_bytemask; } @@ -302,9 +276,10 @@ struct IXBar : public ::IXBar { } Use *clone() const override { return new Use(*this); } bool empty() const override { - return ::IXBar::Use::empty() && bit_use.empty() && - !meter_alu_hash.allocated && !hash_dist_hash.allocated && - !proxy_hash_key_use.allocated && salu_input_source.empty(); } + return ::IXBar::Use::empty() && bit_use.empty() && !meter_alu_hash.allocated && + !hash_dist_hash.allocated && !proxy_hash_key_use.allocated && + salu_input_source.empty(); + } void dbprint(std::ostream &) const override; void add(const Use &alloc); @@ -312,13 +287,15 @@ struct IXBar : public ::IXBar { safe_vector bits_per_search_bus() const override; unsigned compute_hash_tables() override; bool emit_gateway_asm(const MauAsmOutput &, std::ostream &, indent_t, - const IR::MAU::Table *) const override { return false; } - void emit_ixbar_asm(const PhvInfo &phv, std::ostream& out, indent_t indent, + const IR::MAU::Table *) const override { + return false; + } + void emit_ixbar_asm(const PhvInfo &phv, std::ostream &out, indent_t indent, const TableMatch *fmt, const IR::MAU::Table *) const override; void emit_salu_bytemasks(std::ostream &out, indent_t indent) const override; void emit_ixbar_hash_table(int hash_table, safe_vector &match_data, - safe_vector &ghost, const TableMatch *fmt, - std::map> &sort) const override; + safe_vector &ghost, const TableMatch *fmt, + std::map> &sort) const override; bitvec galois_matrix_bits() const override { return hash_dist_hash.galois_matrix_bits; } int hash_groups() const override; TotalBytes match_hash(safe_vector *hash_groups = nullptr) const override; @@ -327,8 +304,10 @@ struct IXBar : public ::IXBar { int total_input_bits() const override { int rv = 0; for (auto fl : field_list_order) { - rv += fl->type->width_bits(); } - return rv; } + rv += fl->type->width_bits(); + } + return rv; + } void update_resources(int, BFN::Resources::StageResources &) const override; const char *way_source_kind() const override { return "group"; } }; @@ -360,9 +339,9 @@ struct IXBar : public ::IXBar { public: HashDistAllocPostExpand(P4HashFunction *f, le_bitrange b, HashDistDest_t d, int s) : func(f), bits_in_use(b), dest(d), shift(s) {} - bool operator<(const HashDistAllocPostExpand& hd) const { + bool operator<(const HashDistAllocPostExpand &hd) const { return std::tie(dest, shift, bits_in_use, chained_addr) < - std::tie(hd.dest, hd.shift, hd.bits_in_use, hd.chained_addr); + std::tie(hd.dest, hd.shift, hd.bits_in_use, hd.chained_addr); } }; @@ -423,10 +402,10 @@ struct IXBar : public ::IXBar { void build_action_data_req(const IR::MAU::HashDist *hd); void build_req(const IR::MAU::HashDist *hd, const IR::Node *rel_node, - bool created_hd = false); + bool created_hd = false); void build_function(const IR::MAU::HashDist *hd, P4HashFunction **func, - le_bitrange *bits = nullptr); + le_bitrange *bits = nullptr); bool preorder(const IR::MAU::HashDist *) override; bool preorder(const IR::MAU::TableSeq *) override { return false; } bool preorder(const IR::MAU::AttachedOutput *) override { return false; } @@ -437,15 +416,15 @@ struct IXBar : public ::IXBar { void hash_action(); bool allocate_hash_dist(); XBarHashDist(IXBar &s, const PhvInfo &p, const IR::MAU::Table *t, - const ActionData::Format::Use *a, const LayoutOption *l, TableResourceAlloc *r, - const attached_entries_t &ae) + const ActionData::Format::Use *a, const LayoutOption *l, TableResourceAlloc *r, + const attached_entries_t &ae) : self(s), phv(p), tbl(t), af(a), lo(l), resources(r), attached_entries(ae) {} }; private: enum AvailBytesPerRepeatingSect_t { AV_FULL = 1, AV_HALF = 2, AV_BYTE = 4 }; -/* An individual SRAM group or half of a TCAM group */ + /* An individual SRAM group or half of a TCAM group */ struct grp_use : public IHasDbPrint { enum type_t { MATCH, HASH_DIST, FREE }; int group; @@ -469,27 +448,26 @@ struct IXBar : public ::IXBar { * * @sa is_better_group in input_xbar.cpp */ - std::array _free = { { bitvec() } }; + std::array _free = {{bitvec()}}; bitvec free(bitvec can_use) const { bitvec rv; - for (auto bit : can_use) - rv |= _free.at(bit); + for (auto bit : can_use) rv |= _free.at(bit); return rv; } - bitvec max_free() const { return free(bitvec(0, REPEATING_CONSTRAINT_SECT)); } + bitvec max_free() const { + return free(bitvec(0, TofinoIXBarSpec::REPEATING_CONSTRAINT_SECT)); + } bool attempted = false; - bool hash_open[2] = { true, true }; - type_t hash_table_type[2] = { FREE, FREE }; + bool hash_open[2] = {true, true}; + type_t hash_table_type[2] = {FREE, FREE}; int range_index = -1; bool hash_dist_avail(int ht) const { return hash_table_type[ht] == HASH_DIST || hash_table_type[ht] == FREE; } - bool hash_dist_only(int ht) const { - return hash_table_type[ht] == HASH_DIST; - } + bool hash_dist_only(int ht) const { return hash_table_type[ht] == HASH_DIST; } void dbprint(std::ostream &out) const { out << group << " found: 0x" << found << " free: 0x" << max_free(); @@ -498,8 +476,8 @@ struct IXBar : public ::IXBar { int total_avail() const { return found.popcount() + max_free().popcount(); } bool range_set() const { return range_index != -1; } - bool is_better_group(const grp_use &b, bool prefer_found, - int required_allocation_bytes, std::map &constraints_to_reqs) const; + bool is_better_group(const grp_use &b, bool prefer_found, int required_allocation_bytes, + std::map &constraints_to_reqs) const; explicit grp_use(int g) : group(g) {} }; @@ -517,13 +495,12 @@ struct IXBar : public ::IXBar { static hash_matrix_reqs max(bool hd, bool ternary = false) { hash_matrix_reqs rv; - if (ternary) - return rv; + if (ternary) return rv; rv.hash_dist = hd; if (rv.hash_dist) { - rv.index_groups = HASH_DIST_SLICES; + rv.index_groups = TofinoIXBarSpec::HASH_DIST_SLICES; } else { - rv.index_groups = HASH_INDEX_GROUPS; + rv.index_groups = TofinoIXBarSpec::HASH_INDEX_GROUPS; rv.select_bits = IXBar::get_hash_single_bits(); } return rv; @@ -540,13 +517,13 @@ struct IXBar : public ::IXBar { // Used to determine what phv fields need to be allocated on the input xbar for the // stateful ALU to work. Private internal to allocStateful class FindSaluSources : public MauInspector { - const PhvInfo &phv; - ContByteConversion &map_alloc; + const PhvInfo &phv; + ContByteConversion &map_alloc; safe_vector &field_list_order; // Holds which bitranges of fields have been requested, and will not allocate // if a bitrange has been requested multiple times - std::map fields_needed; - const IR::MAU::Table *tbl; + std::map fields_needed; + const IR::MAU::Table *tbl; profile_t init_apply(const IR::Node *root) override; bool preorder(const IR::MAU::StatefulAlu *) override; @@ -564,40 +541,40 @@ struct IXBar : public ::IXBar { public: FindSaluSources(IXBar &, const PhvInfo &phv, ContByteConversion &ma, safe_vector &flo, const IR::MAU::Table *t) - : phv(phv), map_alloc(ma), field_list_order(flo), tbl(t) {} + : phv(phv), map_alloc(ma), field_list_order(flo), tbl(t) {} - ordered_map> - phv_sources; - std::vector hash_sources; - bool dleft = false; + ordered_map> phv_sources; + std::vector hash_sources; + bool dleft = false; }; void clear(); bool allocMatch(bool ternary, const IR::MAU::Table *tbl, const PhvInfo &phv, Use &alloc, safe_vector &alloced, hash_matrix_reqs &hm_reqs); - bool allocPartition(const IR::MAU::Table *tbl, const PhvInfo &phv, Use &alloc, - bool second_try); + bool allocPartition(const IR::MAU::Table *tbl, const PhvInfo &phv, Use &alloc, bool second_try); int getHashGroup(unsigned hash_table_input, const hash_matrix_reqs *hm_reqs = nullptr); - void getHashDistGroups(unsigned hash_table_input, int hash_group_opt[HASH_DIST_UNITS]); - bool allocProxyHash(const IR::MAU::Table *tbl, const PhvInfo &phv, - const LayoutOption *lo, Use &alloc, Use &proxy_hash_alloc); + void getHashDistGroups(unsigned hash_table_input, + int hash_group_opt[TofinoIXBarSpec::HASH_DIST_UNITS]); + bool allocProxyHash(const IR::MAU::Table *tbl, const PhvInfo &phv, const LayoutOption *lo, + Use &alloc, Use &proxy_hash_alloc); bool allocProxyHashKey(const IR::MAU::Table *tbl, const PhvInfo &phv, const LayoutOption *lo, - Use &proxy_hash_alloc, hash_matrix_reqs &hm_reqs); + Use &proxy_hash_alloc, hash_matrix_reqs &hm_reqs); bool allocAllHashWays(bool ternary, const IR::MAU::Table *tbl, Use &alloc, - const LayoutOption *layout_option, size_t start, size_t last, - const hash_matrix_reqs &hm_reqs); - bool allocHashWay(const IR::MAU::Table *tbl, const LayoutOption *layout_option, - size_t index, std::map &slice_to_select_bits, Use &alloc, - unsigned local_hash_table_input, unsigned hf_hash_table_input, int hash_group); + const LayoutOption *layout_option, size_t start, size_t last, + const hash_matrix_reqs &hm_reqs); + bool allocHashWay(const IR::MAU::Table *tbl, const LayoutOption *layout_option, size_t index, + std::map &slice_to_select_bits, Use &alloc, + unsigned local_hash_table_input, unsigned hf_hash_table_input, + int hash_group); bool allocGateway(const IR::MAU::Table *, const PhvInfo &phv, Use &alloc, - const LayoutOption *lo, bool second_try); + const LayoutOption *lo, bool second_try); bool allocSelector(const IR::MAU::Selector *, const IR::MAU::Table *, const PhvInfo &phv, Use &alloc, cstring name); bool allocStateful(const IR::MAU::StatefulAlu *, const IR::MAU::Table *, const PhvInfo &phv, Use &alloc, bool on_search_bus); - bool allocMeter(const IR::MAU::Meter *, const IR::MAU::Table *, const PhvInfo &phv, - Use &alloc, bool on_search_bus); + bool allocMeter(const IR::MAU::Meter *, const IR::MAU::Table *, const PhvInfo &phv, Use &alloc, + bool on_search_bus); bool allocTable(const IR::MAU::Table *tbl, const PhvInfo &phv, TableResourceAlloc &alloc, const LayoutOption *lo, const ActionData::Format::Use *af, @@ -616,16 +593,16 @@ struct IXBar : public ::IXBar { const Loc *findExactByte(PHV::Container c, int byte) const { for (auto &p : Values(exact_fields.equal_range(c))) - if (exact_use.at(p.group, p.byte).second/8 == byte) - return &p; + if (exact_use.at(p.group, p.byte).second / 8 == byte) return &p; /* FIXME -- what if it's in more than one place? */ - return nullptr; } + return nullptr; + } unsigned find_balanced_group(Use &alloc, int way_size); public: // for gtest bool find_alloc(safe_vector &alloc_use, bool ternary, - safe_vector &alloced, hash_matrix_reqs &hm_reqs, - unsigned byte_mask = ~0U); + safe_vector &alloced, hash_matrix_reqs &hm_reqs, + unsigned byte_mask = ~0U); private: bitvec can_use_from_flags(int flags) const; @@ -634,53 +611,53 @@ struct IXBar : public ::IXBar { int bytes_per_group(bool ternary) const; void increase_ternary_ixbar_space(int &groups_needed, int &nibbles_needed, - bool requires_versioning); + bool requires_versioning); bool calculate_sizes(safe_vector &alloc_use, bool ternary, int &total_bytes_needed, - int &groups_needed, int &mid_bytes_needed, bool requires_versioning); + int &groups_needed, int &mid_bytes_needed, bool requires_versioning); void initialize_orders(safe_vector &order, safe_vector &mid_byte_order, - bool ternary); + bool ternary); void setup_byte_vectors(safe_vector &alloc_use, bool ternary, - safe_vector &unalloced, safe_vector &alloced, - safe_vector &order, safe_vector &mid_byte_order, - hash_matrix_reqs &hm_reqs, unsigned byte_mask); + safe_vector &unalloced, safe_vector &alloced, + safe_vector &order, safe_vector &mid_byte_order, + hash_matrix_reqs &hm_reqs, unsigned byte_mask); void print_groups(safe_vector &order, safe_vector &mid_byte_order, - bool ternary); + bool ternary); void fill_out_use(safe_vector &alloced, bool ternary); void calculate_available_groups(safe_vector &order, hash_matrix_reqs &hm_reqs); void calculate_available_hash_dist_groups(safe_vector &order, - hash_matrix_reqs &hm_reqs); + hash_matrix_reqs &hm_reqs); grp_use::type_t is_group_for_hash_dist(int hash_table); - bool violates_hash_constraints(safe_vector &order, bool hash_dist, int group, - int byte); + bool violates_hash_constraints(safe_vector &order, bool hash_dist, int group, + int byte); void reset_orders(safe_vector &order, safe_vector &mid_byte_order); void calculate_found(safe_vector &unalloced, safe_vector &order, - safe_vector &mid_byte_order, bool ternary, bool hash_dist, - unsigned byte_mask); + safe_vector &mid_byte_order, bool ternary, bool hash_dist, + unsigned byte_mask); void calculate_free(safe_vector &order, safe_vector &mid_byte_order, - bool ternary, bool hash_dist, unsigned byte_mask); + bool ternary, bool hash_dist, unsigned byte_mask); void found_bytes(grp_use *grp, safe_vector &unalloced, bool ternary, - int &match_bytes_placed, int search_bus); - void found_mid_bytes(mid_byte_use *mb_grp, safe_vector &unalloced, - bool ternary, int &match_bytes_placed, int search_bus, bool &prefer_half_bytes, - bool only_alloc_nibble); + int &match_bytes_placed, int search_bus); + void found_mid_bytes(mid_byte_use *mb_grp, safe_vector &unalloced, bool ternary, + int &match_bytes_placed, int search_bus, bool &prefer_half_bytes, + bool only_alloc_nibble); void free_bytes(grp_use *grp, safe_vector &unalloced, - safe_vector &alloced, bool ternary, bool hash_dist, int &match_bytes_placed, - int search_bus); + safe_vector &alloced, bool ternary, bool hash_dist, + int &match_bytes_placed, int search_bus); void free_mid_bytes(mid_byte_use *mb_grp, safe_vector &unalloced, - safe_vector &alloced, int &match_bytes_placed, int search_bus, - bool &prefer_half_bytes, bool only_alloc_nibble); + safe_vector &alloced, int &match_bytes_placed, int search_bus, + bool &prefer_half_bytes, bool only_alloc_nibble); void allocate_byte(bitvec *bv, safe_vector &unalloced, - safe_vector *alloced, IXBar::Use::Byte &need, int group, - int byte, size_t &index, int &free_bytes, int &ixbar_bytes_placed, - int &match_bytes_placed, int search_bus, int *range_index); - void allocate_mid_bytes(safe_vector &unalloced, - safe_vector &alloced, bool ternary, bool prefer_found, - safe_vector &order, safe_vector &mid_byte_order, - int nibbles_needed, int &bytes_to_allocate); + safe_vector *alloced, IXBar::Use::Byte &need, int group, + int byte, size_t &index, int &free_bytes, int &ixbar_bytes_placed, + int &match_bytes_placed, int search_bus, int *range_index); + void allocate_mid_bytes(safe_vector &unalloced, safe_vector &alloced, + bool ternary, bool prefer_found, safe_vector &order, + safe_vector &mid_byte_order, int nibbles_needed, + int &bytes_to_allocate); int determine_best_group(safe_vector &unalloced, safe_vector &order, - bool ternary, bool prefer_found, int required_allocation_bytes); + bool ternary, bool prefer_found, int required_allocation_bytes); void allocate_groups(safe_vector &unalloced, safe_vector &alloced, bool ternary, bool prefer_found, safe_vector &order, @@ -690,13 +667,12 @@ struct IXBar : public ::IXBar { safe_vector &alloced, bool ternary, safe_vector &order, safe_vector &mid_byte_order, - int &bytes_to_allocate, bool hash_dist, - unsigned byte_mask, int search_bus); + int &bytes_to_allocate, bool hash_dist, unsigned byte_mask, + int search_bus); hash_matrix_reqs match_hash_reqs(const LayoutOption *lo, size_t start, size_t end, - bool ternary); - void layout_option_calculation(const LayoutOption *layout_option, - size_t &start, size_t &last); + bool ternary); + void layout_option_calculation(const LayoutOption *layout_option, size_t &start, size_t &last); int max_bit_to_byte(bitvec bit_mask); int max_index_group(int max_bit); @@ -704,45 +680,45 @@ struct IXBar : public ::IXBar { unsigned index_groups_used(bitvec bv) const; unsigned select_bits_used(bitvec bv) const; bool hash_use_free(int max_group, int max_single_bit, unsigned hash_table_input); - void write_hash_use(int max_group, int max_single_bit, unsigned hash_table_input, - cstring name); + void write_hash_use(int max_group, int max_single_bit, unsigned hash_table_input, cstring name); bool can_allocate_on_search_bus(Use &alloc, const PHV::Field *field, le_bitrange range, - int ixbar_position); + int ixbar_position); bool setup_stateful_search_bus(const IR::MAU::StatefulAlu *salu, Use &alloc, const FindSaluSources &sources, unsigned &byte_mask); bool setup_stateful_hash_bus(const PhvInfo &, const IR::MAU::StatefulAlu *salu, Use &alloc, const FindSaluSources &sources); bitvec determine_final_xor(const IR::MAU::HashFunction *hf, const PhvInfo &phv, - std::map &bit_starts, - safe_vector field_list, int total_input_bits); + std::map &bit_starts, + safe_vector field_list, + int total_input_bits); void determine_proxy_hash_alg(const PhvInfo &, const IR::MAU::Table *tbl, Use &use, int group); bool isHashDistAddress(HashDistDest_t dest) const; void determineHashDistInUse(int hash_group, bitvec &units_in_use, bitvec &hash_bits_in_use); void buildHashDistIRUse(HashDistAllocPostExpand &alloc_req, HashDistUse &use, - IXBar::Use &all_reqs, const PhvInfo &phv, int hash_group, bitvec hash_bits_used, - bitvec total_post_expand_bits, const IR::MAU::Table* tbl, cstring name); + IXBar::Use &all_reqs, const PhvInfo &phv, int hash_group, + bitvec hash_bits_used, bitvec total_post_expand_bits, + const IR::MAU::Table *tbl, cstring name); void lockInHashDistArrays(safe_vector *alloced, int hash_group, - unsigned hash_table_input, int asm_unit, bitvec hash_bits_used, HashDistDest_t dest, - cstring name); - + unsigned hash_table_input, int asm_unit, bitvec hash_bits_used, + HashDistDest_t dest, cstring name); bool allocHashDistSection(bitvec post_expand_bits, bitvec possible_shifts, int hash_group, - int &unit_allocated, bitvec &hash_bits_allocated); + int &unit_allocated, bitvec &hash_bits_allocated); bool allocHashDistWideAddress(bitvec post_expand_bits, bitvec possible_shifts, int hash_group, - bool chained_addr, int &unit_allocated, bitvec &hash_bits_allocated); + bool chained_addr, int &unit_allocated, + bitvec &hash_bits_allocated); bool allocHashDist(safe_vector &alloc_reqs, HashDistUse &use, - const PhvInfo &phv, cstring name, const IR::MAU::Table* tbl, bool second_try); + const PhvInfo &phv, cstring name, const IR::MAU::Table *tbl, + bool second_try); void createChainedHashDist(const HashDistUse &hd_alloc, HashDistUse &chained_hd_alloc, - cstring name); + cstring name); void update_hash_parity(IXBar::Use &use, int hash_group); parity_status_t update_hash_parity(int hash_group); }; } // namespace Tofino -/* clang-format on */ - #endif /* BF_P4C_MAU_TOFINO_INPUT_XBAR_H_ */ diff --git a/backends/tofino/bf-p4c/mau/tofino/memories.cpp b/backends/tofino/bf-p4c/mau/tofino/memories.cpp index c309e1a184..ac1fdd3647 100644 --- a/backends/tofino/bf-p4c/mau/tofino/memories.cpp +++ b/backends/tofino/bf-p4c/mau/tofino/memories.cpp @@ -21,11 +21,11 @@ #include #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/payload_gateway.h" #include "backends/tofino/bf-p4c/mau/resource.h" #include "backends/tofino/bf-p4c/mau/resource_estimate.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/bitops.h" #include "lib/log.h" #include "lib/range.h" diff --git a/backends/tofino/bf-p4c/mau/walk_power_graph.cpp b/backends/tofino/bf-p4c/mau/walk_power_graph.cpp index 7a727149c5..47d43b5396 100644 --- a/backends/tofino/bf-p4c/mau/walk_power_graph.cpp +++ b/backends/tofino/bf-p4c/mau/walk_power_graph.cpp @@ -26,8 +26,6 @@ #include "backends/tofino/bf-p4c/common/asm_output.h" #include "backends/tofino/bf-p4c/common/run_id.h" -#include "backends/tofino/bf-p4c/device.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/ir/unique_id.h" #include "backends/tofino/bf-p4c/logging/manifest.h" #include "backends/tofino/bf-p4c/logging/power_schema.h" @@ -38,6 +36,8 @@ #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/memories.h" #include "backends/tofino/bf-p4c/mau/simple_power_graph.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "backends/tofino/bf-p4c/version.h" #include "lib/json.h" #include "lib/set.h" diff --git a/backends/tofino/bf-p4c/mau/walk_power_graph.h b/backends/tofino/bf-p4c/mau/walk_power_graph.h index 8b422bcc8e..b44f1735b9 100644 --- a/backends/tofino/bf-p4c/mau/walk_power_graph.h +++ b/backends/tofino/bf-p4c/mau/walk_power_graph.h @@ -24,7 +24,6 @@ #include #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/logging/power_schema.h" #include "backends/tofino/bf-p4c/mau/build_power_graph.h" #include "backends/tofino/bf-p4c/mau/determine_power_usage.h" @@ -33,6 +32,7 @@ #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/table_dependency_graph.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/gress.h" namespace MauPower { diff --git a/backends/tofino/bf-p4c/midend/check_header_alignment.cpp b/backends/tofino/bf-p4c/midend/check_header_alignment.cpp index f9cf33da59..16b3ee191e 100644 --- a/backends/tofino/bf-p4c/midend/check_header_alignment.cpp +++ b/backends/tofino/bf-p4c/midend/check_header_alignment.cpp @@ -19,8 +19,8 @@ #include "backends/tofino/bf-p4c/midend/check_header_alignment.h" #include "backends/tofino/bf-p4c/common/bridged_packing.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/lib/pad_alignment.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4/typeMap.h" #include "ir/ir.h" #include "lib/cstring.h" diff --git a/backends/tofino/bf-p4c/midend/check_unsupported.cpp b/backends/tofino/bf-p4c/midend/check_unsupported.cpp index 2e62dd0391..974e7a259a 100644 --- a/backends/tofino/bf-p4c/midend/check_unsupported.cpp +++ b/backends/tofino/bf-p4c/midend/check_unsupported.cpp @@ -18,8 +18,8 @@ #include "backends/tofino/bf-p4c/midend/check_unsupported.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/lib/safe_width.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/midend/collect_pipelines.cpp b/backends/tofino/bf-p4c/midend/collect_pipelines.cpp index a03ad5f3a7..58bfcdae7d 100644 --- a/backends/tofino/bf-p4c/midend/collect_pipelines.cpp +++ b/backends/tofino/bf-p4c/midend/collect_pipelines.cpp @@ -21,7 +21,7 @@ */ #include "collect_pipelines.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/midend/desugar_varbit_extract.cpp b/backends/tofino/bf-p4c/midend/desugar_varbit_extract.cpp index 0af5255a19..b913c93b7f 100644 --- a/backends/tofino/bf-p4c/midend/desugar_varbit_extract.cpp +++ b/backends/tofino/bf-p4c/midend/desugar_varbit_extract.cpp @@ -22,7 +22,7 @@ #include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/constantFolding.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/midend/drop_packet_with_mirror_engine.cpp b/backends/tofino/bf-p4c/midend/drop_packet_with_mirror_engine.cpp index 290a10bd8d..d9d0a978a8 100644 --- a/backends/tofino/bf-p4c/midend/drop_packet_with_mirror_engine.cpp +++ b/backends/tofino/bf-p4c/midend/drop_packet_with_mirror_engine.cpp @@ -18,7 +18,7 @@ #include "drop_packet_with_mirror_engine.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/midend/drop_packet_with_mirror_engine.h b/backends/tofino/bf-p4c/midend/drop_packet_with_mirror_engine.h index 8ba7e5fdae..b45607cfb6 100644 --- a/backends/tofino/bf-p4c/midend/drop_packet_with_mirror_engine.h +++ b/backends/tofino/bf-p4c/midend/drop_packet_with_mirror_engine.h @@ -35,7 +35,7 @@ #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" #include "backends/tofino/bf-p4c/common/pragma/collect_global_pragma.h" #include "backends/tofino/bf-p4c/common/pragma/pragma.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "ir/ir.h" #include "type_checker.h" diff --git a/backends/tofino/bf-p4c/midend/initialize_mirror_io_select.h b/backends/tofino/bf-p4c/midend/initialize_mirror_io_select.h index d87dc144a2..f3bc96b3be 100644 --- a/backends/tofino/bf-p4c/midend/initialize_mirror_io_select.h +++ b/backends/tofino/bf-p4c/midend/initialize_mirror_io_select.h @@ -22,7 +22,7 @@ #include "backends/tofino/bf-p4c/arch/arch.h" #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" #include "backends/tofino/bf-p4c/common/pragma/collect_global_pragma.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" #include "type_checker.h" diff --git a/backends/tofino/bf-p4c/midend/parser_enforce_depth_req.cpp b/backends/tofino/bf-p4c/midend/parser_enforce_depth_req.cpp index 5e9a7922c2..1d837271eb 100644 --- a/backends/tofino/bf-p4c/midend/parser_enforce_depth_req.cpp +++ b/backends/tofino/bf-p4c/midend/parser_enforce_depth_req.cpp @@ -24,9 +24,9 @@ #include #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/midend/parser_graph.h" #include "backends/tofino/bf-p4c/parde/parser_loops_info.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/midend/ping_pong_generation.h b/backends/tofino/bf-p4c/midend/ping_pong_generation.h index e8e75970d8..a6b962bcf6 100644 --- a/backends/tofino/bf-p4c/midend/ping_pong_generation.h +++ b/backends/tofino/bf-p4c/midend/ping_pong_generation.h @@ -19,9 +19,9 @@ #ifndef BACKENDS_TOFINO_BF_P4C_MIDEND_PING_PONG_GENERATION_H_ #define BACKENDS_TOFINO_BF_P4C_MIDEND_PING_PONG_GENERATION_H_ -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/midend/collect_pipelines.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/resolveReferences/referenceMap.h" #include "frontends/p4/methodInstance.h" #include "frontends/p4/typeMap.h" diff --git a/backends/tofino/bf-p4c/midend/register_read_write.cpp b/backends/tofino/bf-p4c/midend/register_read_write.cpp index 252ad84a2b..b1052af3e4 100644 --- a/backends/tofino/bf-p4c/midend/register_read_write.cpp +++ b/backends/tofino/bf-p4c/midend/register_read_write.cpp @@ -20,8 +20,8 @@ #include "backends/tofino/bf-p4c/arch/helpers.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/mau/stateful_alu.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4/methodInstance.h" namespace BFN { diff --git a/backends/tofino/bf-p4c/midend/rewrite_egress_intrinsic_metadata_header.h b/backends/tofino/bf-p4c/midend/rewrite_egress_intrinsic_metadata_header.h index a882ba6593..bafd65284d 100644 --- a/backends/tofino/bf-p4c/midend/rewrite_egress_intrinsic_metadata_header.h +++ b/backends/tofino/bf-p4c/midend/rewrite_egress_intrinsic_metadata_header.h @@ -19,7 +19,7 @@ #ifndef BF_P4C_MIDEND_REWRITE_EGRESS_INTRINSIC_METADATA_HEADER_H_ #define BF_P4C_MIDEND_REWRITE_EGRESS_INTRINSIC_METADATA_HEADER_H_ -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace P4 { class TypeMap; diff --git a/backends/tofino/bf-p4c/midend/simplify_nested_if.h b/backends/tofino/bf-p4c/midend/simplify_nested_if.h index b09f28caa4..36138c8426 100644 --- a/backends/tofino/bf-p4c/midend/simplify_nested_if.h +++ b/backends/tofino/bf-p4c/midend/simplify_nested_if.h @@ -25,10 +25,10 @@ */ #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/midend/path_linearizer.h" #include "backends/tofino/bf-p4c/midend/type_categories.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/resolveReferences/resolveReferences.h" #include "frontends/p4/simplify.h" #include "frontends/p4/strengthReduction.h" diff --git a/backends/tofino/bf-p4c/p4c-barefoot.cpp b/backends/tofino/bf-p4c/p4c-barefoot.cpp index d7ffc0ec03..4fcc2efb18 100644 --- a/backends/tofino/bf-p4c/p4c-barefoot.cpp +++ b/backends/tofino/bf-p4c/p4c-barefoot.cpp @@ -98,7 +98,6 @@ #include "backends/tofino/bf-p4c/common/pragma/collect_global_pragma.h" #include "backends/tofino/bf-p4c/common/run_id.h" #include "backends/tofino/bf-p4c/control-plane/runtime.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/frontend.h" #include "backends/tofino/bf-p4c/lib/error_type.h" #include "backends/tofino/bf-p4c/logging/collect_diagnostic_checks.h" @@ -112,6 +111,7 @@ #include "backends/tofino/bf-p4c/mau/table_flow_graph.h" #include "backends/tofino/bf-p4c/midend/type_checker.h" #include "backends/tofino/bf-p4c/parde/parser_header_sequences.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/common/constantFolding.h" #include "frontends/p4-14/header_type.h" #include "frontends/p4-14/typecheck.h" @@ -427,7 +427,8 @@ int main(int ac, char **av) { return handle_return(INVOCATION_ERROR, options); options.setInputFile(); - Device::init(options.target); + Device::init(options.target, + {options.phv_scale_factor, options.no_tagalong, options.tof2lab44_workaround}); // Initialize EventLogger if (BackendOptions().debugInfo) { diff --git a/backends/tofino/bf-p4c/parde/add_parde_metadata.cpp b/backends/tofino/bf-p4c/parde/add_parde_metadata.cpp index 0bca68bc79..10ccf23de8 100644 --- a/backends/tofino/bf-p4c/parde/add_parde_metadata.cpp +++ b/backends/tofino/bf-p4c/parde/add_parde_metadata.cpp @@ -23,7 +23,7 @@ #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" #include "backends/tofino/bf-p4c/common/pragma/collect_global_pragma.h" #include "backends/tofino/bf-p4c/common/pragma/pragma.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/exceptions.h" bool AddParserMetadata::preorder(IR::BFN::Parser *parser) { diff --git a/backends/tofino/bf-p4c/parde/adjust_extract.cpp b/backends/tofino/bf-p4c/parde/adjust_extract.cpp index 67ff4fb4e7..6d4fb16ce1 100644 --- a/backends/tofino/bf-p4c/parde/adjust_extract.cpp +++ b/backends/tofino/bf-p4c/parde/adjust_extract.cpp @@ -21,7 +21,7 @@ #include #include -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" void AdjustExtract::postorder(IR::BFN::ParserState *state) { if (!hasMarshaled(state)) return; diff --git a/backends/tofino/bf-p4c/parde/allocate_parser_checksum.cpp b/backends/tofino/bf-p4c/parde/allocate_parser_checksum.cpp index 396a76d204..d72acac6b9 100644 --- a/backends/tofino/bf-p4c/parde/allocate_parser_checksum.cpp +++ b/backends/tofino/bf-p4c/parde/allocate_parser_checksum.cpp @@ -21,9 +21,9 @@ #include #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" #include "backends/tofino/bf-p4c/parde/dump_parser.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/bitrange.h" #include "lib/cstring.h" diff --git a/backends/tofino/bf-p4c/parde/allocate_parser_match_register.cpp b/backends/tofino/bf-p4c/parde/allocate_parser_match_register.cpp index 934c4e2b11..b12cc1344c 100644 --- a/backends/tofino/bf-p4c/parde/allocate_parser_match_register.cpp +++ b/backends/tofino/bf-p4c/parde/allocate_parser_match_register.cpp @@ -16,21 +16,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -/* clang-format off */ -#include +#include "backends/tofino/bf-p4c/parde/allocate_parser_match_register.h" + #include + #include -#include "backends/tofino/bf-p4c/common/asm_output.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" -#include "backends/tofino/bf-p4c/phv/phv_fields.h" -#include "backends/tofino/bf-p4c/parde/allocate_parser_match_register.h" #include "backends/tofino/bf-p4c/parde/clot/clot.h" #include "backends/tofino/bf-p4c/parde/collect_parser_usedef.h" -#include "backends/tofino/bf-p4c/parde/dump_parser.h" +#include "backends/tofino/bf-p4c/parde/match_register.h" #include "backends/tofino/bf-p4c/parde/parser_info.h" -#include "match_register.h" +#include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" using namespace Parser; @@ -116,7 +114,7 @@ struct ResolveOutOfBufferSaves : public ParserTransform { if (max_save.rv >= 0) { return int(t->shift + max_save.rv / 8 + 1) > - Device::pardeSpec().byteInputBufferSize(); + Device::pardeSpec().byteInputBufferSize(); } // If scratch regs are available, we may need the additional choice of @@ -133,7 +131,7 @@ struct ResolveOutOfBufferSaves : public ParserTransform { if (d->state->name == next->name) { if (auto buf = d->rval->to()) { if (int(t->shift + buf->range.hi / 8 + 1) > - Device::pardeSpec().byteInputBufferSize()) { + Device::pardeSpec().byteInputBufferSize()) { return true; } } @@ -386,7 +384,7 @@ struct AllocationResult { transition_saves; // Registers to scratches on this transition. - std::map> transition_scratches; + std::map> transition_scratches; // The register slices that this select should match against. std::map>> save_reg_slices; @@ -646,9 +644,9 @@ class MatcherAllocator : public Visitor { /// Given the registers allocated to a group, compute the /// the fields' layout within each register (slices) - std::vector> calc_reg_slices_for_use( - const Use *use, const std::vector &group_regs) const { - std::vector> reg_slices; + std::vector> calc_reg_slices_for_use( + const Use *use, const std::vector &group_regs) const { + std::vector> reg_slices; auto def_states = get_def_states(); auto state = def_states.at(0); // pick first state as representative @@ -744,15 +742,15 @@ class MatcherAllocator : public Visitor { /// sort uses by their position in the input buffer void sort_use_group(std::vector &group, const UseDef &use_def) { std::stable_sort(group.begin(), group.end(), [&use_def](const Use *a, const Use *b) { - int a_min, b_min; - a_min = b_min = Device::pardeSpec().byteInputBufferSize() * 8; + int a_min, b_min; + a_min = b_min = Device::pardeSpec().byteInputBufferSize() * 8; for (auto def : use_def.use_to_defs.at(a)) a_min = std::min(a_min, def->rval->range.lo); for (auto def : use_def.use_to_defs.at(b)) b_min = std::min(b_min, def->rval->range.lo); - return a_min < b_min; - }); + return a_min < b_min; + }); } std::vector coalesce_group(const std::vector &group, @@ -892,9 +890,9 @@ class MatcherAllocator : public Visitor { } struct Allocation { - std::map> group_to_alloc_regs; + std::map> group_to_alloc_regs; std::map group_to_def_set; - std::map> group_to_scratch_reg_map; + std::map> group_to_scratch_reg_map; }; /// Contains the match and scratch registers available for a given UseGroup DefSet, @@ -919,9 +917,9 @@ class MatcherAllocator : public Visitor { /// class AvailableRegisters { public: - std::vector match_regs; - std::vector unconstrained_scratch_regs; - std::vector constrained_scratch_regs; + std::vector match_regs; + std::vector unconstrained_scratch_regs; + std::vector constrained_scratch_regs; /// The constrained_layout vector contains the match register layout of the UseGroup /// which has the most scratch register constraints with the current UseGroup DefSet. @@ -929,7 +927,7 @@ class MatcherAllocator : public Visitor { /// /// The ranges are byte-aligned in order to include all bits actually /// loaded in the registers. - std::vector> constraint_layout; + std::vector> constraint_layout; unsigned get_total_size_byte() const { unsigned total_reg_bytes = 0; @@ -944,7 +942,7 @@ class MatcherAllocator : public Visitor { /// unconstrained. Information about the associated group constraints /// is set up. void add_scratch_regs(const Allocation &allocation, - const std::vector &scratch_regs, + const std::vector &scratch_regs, const ordered_set &subset_defs_groups) { const UseGroup *constraint_group = nullptr; int max_regs = 0; @@ -978,10 +976,10 @@ class MatcherAllocator : public Visitor { }; /// Looks for a constrained scratch register at bit_range_offset. - bool get_constrained_scratch_reg(int bit_range_offset, MatchRegister ®) const { + bool get_constrained_scratch_reg(int bit_range_offset, MatchRegisterSpec ®) const { for (auto &l : constraint_layout) { if (l.second.contains(bit_range_offset)) { - MatchRegister constraint_reg = l.first; + MatchRegisterSpec constraint_reg = l.first; cstring name; if (MatcherAllocator::is_scratch_register(constraint_reg)) @@ -1028,11 +1026,11 @@ class MatcherAllocator : public Visitor { }; /// Match register allocation function that supports scratch registers. - std::vector alloc_ascend_with_scratch(const UseGroup *group, - const AvailableRegisters avail_regs) { + std::vector alloc_ascend_with_scratch(const UseGroup *group, + const AvailableRegisters avail_regs) { LOG3("match register allocation with scratch"); - std::vector allocated_regs; - std::vector unconstraint_regs; + std::vector allocated_regs; + std::vector unconstraint_regs; // Create vector for all unconstrained registers. for (auto ® : avail_regs.match_regs) unconstraint_regs.push_back(reg); @@ -1040,7 +1038,7 @@ class MatcherAllocator : public Visitor { // Get constraint group register range layout. LOG3(" constraint group registers layout:" << std::endl - << avail_regs.print_constraint_layout()); + << avail_regs.print_constraint_layout()); // Get the range of the group to allocate. std::vector def_states = group->get_def_states(); @@ -1052,11 +1050,11 @@ class MatcherAllocator : public Visitor { // scratch registers. If this is not possible, then allocate an unconstrained // match or scratch register. int bit_offset_in_range = group_range.lo; - std::vector::iterator unconstraint_regs_it = unconstraint_regs.begin(); + std::vector::iterator unconstraint_regs_it = unconstraint_regs.begin(); while (bit_offset_in_range <= group_range.hi) { - MatchRegister allocated_reg; - MatchRegister constraint_group_reg; + MatchRegisterSpec allocated_reg; + MatchRegisterSpec constraint_group_reg; if (avail_regs.get_constrained_scratch_reg(bit_offset_in_range, allocated_reg)) { // Here, offset bit_offset_in_range falls into the constrained // group register range, while the associated constrained @@ -1104,7 +1102,7 @@ class MatcherAllocator : public Visitor { const DefSet &other_def_set = gr.second; if (other_def_set.count(transition)) { if (group->have_subset_defs(other_group) || - other_group->have_subset_defs(group)) { + other_group->have_subset_defs(group)) { if (!subset_defs_groups.count(other_group)) subset_defs_groups.push_back(other_group); continue; @@ -1123,11 +1121,11 @@ class MatcherAllocator : public Visitor { AvailableRegisters get_available_regs(const IR::BFN::Parser *parser, const UseGroup *group, const Allocation &allocation, const DefSet &def_set, - bool allow_scratch_regs) { + bool allow_scratch_regs) { AvailableRegisters avail_regs; auto &graph = parser_info.graph(parser); - ordered_set used_regs; + ordered_set used_regs; for (auto &their : allocation.group_to_alloc_regs) { auto they = their.first; @@ -1168,7 +1166,7 @@ class MatcherAllocator : public Visitor { if (allow_scratch_regs) { ordered_set subset_defs_groups; - std::vector scratch_regs; + std::vector scratch_regs; for (auto ® : Device::pardeSpec().scratchRegisters()) { if (!used_regs.count(reg)) { @@ -1191,7 +1189,8 @@ class MatcherAllocator : public Visitor { // Check if scratch register can be used based on // current allocation and if so, if there are // any constraints associated to it. - if (can_scratch(group, reg, allocation, def_set, subset_defs_groups)) { + if (can_scratch(group, MatchRegister(reg), allocation, def_set, + subset_defs_groups)) { scratch_regs.push_back(reg); } } @@ -1212,7 +1211,7 @@ class MatcherAllocator : public Visitor { /// Given a set of available registers to the group, choose a /// set of registers that will cover all select fields. - std::vector allocate(const UseGroup *group, AvailableRegisters avail_regs) { + std::vector allocate(const UseGroup *group, AvailableRegisters avail_regs) { auto select_bytes = group->bytes_in_group(); unsigned total_reg_bytes = avail_regs.get_total_size_byte(); @@ -1221,7 +1220,7 @@ class MatcherAllocator : public Visitor { return {}; // try allocating in ascending order of container size - std::vector alloc_ascend; + std::vector alloc_ascend; unsigned reg_bytes_ascend = 0; for (auto ® : avail_regs.match_regs) { @@ -1246,7 +1245,7 @@ class MatcherAllocator : public Visitor { // now try allocating in descending order of container size std::reverse(avail_regs.match_regs.begin(), avail_regs.match_regs.end()); - std::vector alloc_descend; + std::vector alloc_descend; unsigned reg_bytes_descend = 0; for (auto ® : avail_regs.match_regs) { @@ -1268,7 +1267,7 @@ class MatcherAllocator : public Visitor { return alloc_ascend; } - static MatchRegister get_match_register(MatchRegister scratch) { + static MatchRegisterSpec get_match_register(const MatchRegisterSpec &scratch) { for (auto reg : Device::pardeSpec().matchRegisters()) { if (reg.name == scratch.name.substr(5)) return reg; } @@ -1276,7 +1275,7 @@ class MatcherAllocator : public Visitor { BUG("Match register does not exist for %1%", scratch); } - static bool is_scratch_register(const MatchRegister reg) { + static bool is_scratch_register(const MatchRegisterSpec reg) { return reg.name.startsWith("save_"); } @@ -1309,7 +1308,7 @@ class MatcherAllocator : public Visitor { /// Set do_not_shift to true when dealing with scratch registers that /// are located at a fixed position in the input buffer. void bind_def(const IR::BFN::Parser *parser, const UseGroup *group, - const std::vector &alloc_regs, const DefSet &def_set, + const std::vector &alloc_regs, const DefSet &def_set, bool do_not_shift) { auto &graph = parser_info.graph(parser); @@ -1358,13 +1357,13 @@ class MatcherAllocator : public Visitor { nw_byterange reg_range(lo, lo + reg.size - 1); BUG_CHECK(size_t(reg_range.size()) <= reg.size, - "saved bits greater than register size?"); + "saved bits greater than register size?"); // The state splitter should have split the states such that the branch // word is withtin current state. This is the pre-condition of this pass. BUG_CHECK((reg_range.lo >= 0 && reg_range.hi <= Device::pardeSpec().byteInputBufferSize()) || - Device::pardeSpec().byteScratchRegisterRangeValid(reg_range), + Device::pardeSpec().byteScratchRegisterRangeValid(reg_range), "branch word out of current input buffer!"); bool scratch = false; @@ -1377,7 +1376,7 @@ class MatcherAllocator : public Visitor { auto save = new IR::BFN::SaveToRegister( new IR::BFN::PacketRVal(reg_range.toUnit(), partial_hdr_err_proc), - reg); + MatchRegister(reg)); bool saved = false; for (auto s : result.transition_saves[transition]) { @@ -1396,14 +1395,16 @@ class MatcherAllocator : public Visitor { } } - void bind_use(const UseGroup *group, const std::vector &alloc_regs, + void bind_use(const UseGroup *group, const std::vector &alloc_regs, const Allocation &allocation) { // use - for (auto &use : group->members) { + for (const auto &use : group->members) { auto reg_slices = group->calc_reg_slices_for_use(use, alloc_regs); + std::vector> serializable_reg_slices; + // Map scratch register with match register allocated by scratch groups. - for (auto ®_slice : reg_slices) { + for (const auto ®_slice : reg_slices) { if (!is_scratch_register(reg_slice.first)) continue; cstring name = reg_slice.first.name; @@ -1414,20 +1415,21 @@ class MatcherAllocator : public Visitor { BUG_CHECK(allocation.group_to_scratch_reg_map.at(group).count(name), "scratch register %1% not found in allocation", name); - MatchRegister reg = allocation.group_to_scratch_reg_map.at(group).at(name); - reg_slice.first.name = reg.name; - + MatchRegisterSpec reg = allocation.group_to_scratch_reg_map.at(group).at(name); + serializable_reg_slices.emplace_back( + MatchRegister(allocation.group_to_scratch_reg_map.at(group).at(name)), + reg_slice.second); LOG3("update slice: " << name << " --> " << reg.name << " [" << reg_slice.second.lo << ".." << reg_slice.second.hi << "]"); } if (result.save_reg_slices.count(use)) { - bool eq = equiv(result.save_reg_slices.at(use), reg_slices); + bool eq = equiv(result.save_reg_slices.at(use), serializable_reg_slices); BUG_CHECK(eq, "select has different allocations based on the use context: %1%", use->print()); } else { - result.save_reg_slices[use] = reg_slices; + result.save_reg_slices[use] = serializable_reg_slices; } } } @@ -1458,7 +1460,7 @@ class MatcherAllocator : public Visitor { // "allocation" is updated only when both allocations are successful in order // to allow to rolling back when the second allocation fails. Allocation allocation_tmp = allocation; - std::vector scratch_regs; + std::vector scratch_regs; bool success = false; LOG3(">>>>>>>>>>>>>>>>"); @@ -1599,8 +1601,8 @@ class MatcherAllocator : public Visitor { std::vector allocate_scratch_groups( const IR::BFN::Parser *parser, const UseGroup *group, - const std::vector &scratch_regs, Allocation &allocation, - bool is_top_down = false) { + const std::vector &scratch_regs, Allocation &allocation, + bool is_top_down = false) { const IR::BFN::ParserState *state = group->get_use_state(); std::vector scratch_groups; UseDef *use_def = new UseDef(); @@ -1642,8 +1644,8 @@ class MatcherAllocator : public Visitor { return {}; // Match registers allocated to handle matching of scratch register. - std::vector alloc_regs = - allocation.group_to_alloc_regs.at(scratch_group); + std::vector alloc_regs = + allocation.group_to_alloc_regs.at(scratch_group); // Associate the scratch register to the match register allocated. LOG3("match registers to store scratch registers for matching:"); @@ -1652,7 +1654,7 @@ class MatcherAllocator : public Visitor { BUG_CHECK(use_to_scratch_reg.count(member), "Member (use) not found."); cstring name = use_to_scratch_reg[member]; - MatchRegister alloc_reg = alloc_regs.at(i++); + MatchRegisterSpec alloc_reg = alloc_regs.at(i++); LOG3(" " << name << " --> " << alloc_reg.name); allocation.group_to_scratch_reg_map[group][name] = alloc_reg; @@ -1713,7 +1715,7 @@ struct InsertSaveAndSelect : public ParserModifier { if (rst.transition_scratches.count(original_transition)) { for (auto reg : rst.transition_scratches.at(original_transition)) { - transition->scratches.insert(reg); + transition->scratches.insert(MatchRegister(reg)); } } } @@ -2016,40 +2018,38 @@ AllocateParserMatchRegisters::AllocateParserMatchRegisters(const PhvInfo &phv) { addPasses({LOGGING(4) ? new DumpParser("before_parser_match_alloc") : nullptr, new InsertInitSaveState, parserInfo, collectUseDef, resolveOobDefs, - LOGGING(4) ? new DumpParser("after_resolve_oob_saves") : nullptr, - [allocator, this]() { - // Resets that need to occur before the first iteration of the allocator. - // - // delay_defs are stored for comparison with the last round, so reset these here - // so that an empty set it copied - this->iteration = 0; - allocator->prev_delay_defs.clear(); - allocator->delay_defs.clear(); - }, - new PassRepeated( - { - parserInfo, - collectUseDef, - [allocator, this]() { - // Record whether this is the final iteration so that - // the allocator can report an error even if it can identify - // potential defs to delay - allocator->final_iteration = ++this->iteration == MAX_ALLOC_ATTEMPTS; - }, - allocator, - new PassIf( - [allocator]() { - return allocator->delay_defs[INGRESS].size() != 0 || - allocator->delay_defs[EGRESS].size() != 0; - }, - { - new DelayDefs(*parserInfo, allocator->delay_defs), - }), + LOGGING(4) ? new DumpParser("after_resolve_oob_saves") : nullptr, + [allocator, this]() { + // Resets that need to occur before the first iteration of the allocator. + // + // delay_defs are stored for comparison with the last round, so reset these here + // so that an empty set it copied + this->iteration = 0; + allocator->prev_delay_defs.clear(); + allocator->delay_defs.clear(); + }, + new PassRepeated( + { + parserInfo, + collectUseDef, + [allocator, this]() { + // Record whether this is the final iteration so that + // the allocator can report an error even if it can identify + // potential defs to delay + allocator->final_iteration = ++this->iteration == MAX_ALLOC_ATTEMPTS; + }, + allocator, + new PassIf( + [allocator]() { + return allocator->delay_defs[INGRESS].size() != 0 || + allocator->delay_defs[EGRESS].size() != 0; + }, + { + new DelayDefs(*parserInfo, allocator->delay_defs), + }), }, MAX_ALLOC_ATTEMPTS), new InsertSaveAndSelect(allocator->result), new AdjustMatchValue, new RemoveEmptyStartStateAndMatchExtract, new RemoveEmptyStallState, LOGGING(4) ? new DumpParser("after_parser_match_alloc") : nullptr}); } - -/* clang-format on */ diff --git a/backends/tofino/bf-p4c/parde/check_parser_multi_write.cpp b/backends/tofino/bf-p4c/parde/check_parser_multi_write.cpp index d4d95ad962..ca5879fd97 100644 --- a/backends/tofino/bf-p4c/parde/check_parser_multi_write.cpp +++ b/backends/tofino/bf-p4c/parde/check_parser_multi_write.cpp @@ -19,13 +19,13 @@ #include "check_parser_multi_write.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/parde/dump_parser.h" #include "backends/tofino/bf-p4c/parde/parde_utils.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" #include "backends/tofino/bf-p4c/parde/parser_info.h" #include "backends/tofino/bf-p4c/parde/parser_query.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/error_reporter.h" const char *CHECKSUM_VERIFY_OR_SUGGESTION = diff --git a/backends/tofino/bf-p4c/parde/clot/clot.h b/backends/tofino/bf-p4c/parde/clot/clot.h index 161d62d695..63f92bd806 100644 --- a/backends/tofino/bf-p4c/parde/clot/clot.h +++ b/backends/tofino/bf-p4c/parde/clot/clot.h @@ -23,8 +23,8 @@ #include #include -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/lib/cmp.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "lib/exceptions.h" #include "lib/ordered_map.h" diff --git a/backends/tofino/bf-p4c/parde/clot/clot_info.cpp b/backends/tofino/bf-p4c/parde/clot/clot_info.cpp index 0d4f205935..d194eccbed 100644 --- a/backends/tofino/bf-p4c/parde/clot/clot_info.cpp +++ b/backends/tofino/bf-p4c/parde/clot/clot_info.cpp @@ -26,12 +26,12 @@ #include #include "backends/tofino/bf-p4c/common/table_printer.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/logging/logging.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" #include "backends/tofino/bf-p4c/parde/parser_info.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "clot_candidate.h" #include "field_slice_extract_info.h" #include "lib/bitvec.h" diff --git a/backends/tofino/bf-p4c/parde/clot/merge_desugared_varbit_valids.cpp b/backends/tofino/bf-p4c/parde/clot/merge_desugared_varbit_valids.cpp index 215eb8ba04..f19a0899bb 100644 --- a/backends/tofino/bf-p4c/parde/clot/merge_desugared_varbit_valids.cpp +++ b/backends/tofino/bf-p4c/parde/clot/merge_desugared_varbit_valids.cpp @@ -21,12 +21,12 @@ #include #include "backends/tofino/bf-p4c/common/alias.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" #include "backends/tofino/bf-p4c/parde/parser_info.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/pragma/pa_alias.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "ir/ir.h" using namespace P4; diff --git a/backends/tofino/bf-p4c/parde/decaf.cpp b/backends/tofino/bf-p4c/parde/decaf.cpp index 40658bad7c..b5fc2a960a 100644 --- a/backends/tofino/bf-p4c/parde/decaf.cpp +++ b/backends/tofino/bf-p4c/parde/decaf.cpp @@ -21,7 +21,7 @@ #include #include "backends/tofino/bf-p4c/common/table_printer.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" template static std::vector to_vector(const ordered_set &data) { diff --git a/backends/tofino/bf-p4c/parde/deparser_checksum_update.cpp b/backends/tofino/bf-p4c/parde/deparser_checksum_update.cpp index 64c35c8321..3185789966 100644 --- a/backends/tofino/bf-p4c/parde/deparser_checksum_update.cpp +++ b/backends/tofino/bf-p4c/parde/deparser_checksum_update.cpp @@ -22,10 +22,10 @@ #include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/logging/filelog.h" #include "backends/tofino/bf-p4c/parde/create_pov_encoder.h" #include "backends/tofino/bf-p4c/parde/parser_info.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" #include "ir/pattern.h" #include "lib/error.h" diff --git a/backends/tofino/bf-p4c/parde/deparser_output.cpp b/backends/tofino/bf-p4c/parde/deparser_output.cpp index 1bf6e497be..8192cbc80d 100644 --- a/backends/tofino/bf-p4c/parde/deparser_output.cpp +++ b/backends/tofino/bf-p4c/parde/deparser_output.cpp @@ -20,10 +20,10 @@ #include "backends/tofino/bf-p4c/common/asm_output.h" #include "backends/tofino/bf-p4c/common/autoindent.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/parde/asm_output.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" #include "backends/tofino/bf-p4c/parde/field_packing.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/hex.h" namespace { diff --git a/backends/tofino/bf-p4c/parde/dump_parser.h b/backends/tofino/bf-p4c/parde/dump_parser.h index 497f81f325..7aa96b40ec 100644 --- a/backends/tofino/bf-p4c/parde/dump_parser.h +++ b/backends/tofino/bf-p4c/parde/dump_parser.h @@ -26,8 +26,8 @@ #include #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/parde/parser_info.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "ir/dump.h" #include "lib/log.h" diff --git a/backends/tofino/bf-p4c/parde/extract_deparser.cpp b/backends/tofino/bf-p4c/parde/extract_deparser.cpp index ee69aa59a9..033787d481 100644 --- a/backends/tofino/bf-p4c/parde/extract_deparser.cpp +++ b/backends/tofino/bf-p4c/parde/extract_deparser.cpp @@ -21,7 +21,7 @@ #include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/common/ir_utils.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "frontends/p4/methodInstance.h" #include "ir/pattern.h" diff --git a/backends/tofino/bf-p4c/parde/extract_deparser.h b/backends/tofino/bf-p4c/parde/extract_deparser.h index e6cfd2bc2d..48d381a59e 100644 --- a/backends/tofino/bf-p4c/parde/extract_deparser.h +++ b/backends/tofino/bf-p4c/parde/extract_deparser.h @@ -24,9 +24,9 @@ #include "backends/tofino/bf-p4c/common/ir_utils.h" #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" #include "backends/tofino/bf-p4c/common/pragma/collect_global_pragma.h" -#include "backends/tofino/bf-p4c/device.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/resolveReferences/referenceMap.h" #include "frontends/p4/typeMap.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/parde/extract_parser.cpp b/backends/tofino/bf-p4c/parde/extract_parser.cpp index 0823317bba..0a800cd7e4 100644 --- a/backends/tofino/bf-p4c/parde/extract_parser.cpp +++ b/backends/tofino/bf-p4c/parde/extract_parser.cpp @@ -26,11 +26,11 @@ #include "backends/tofino/bf-p4c/arch/arch.h" #include "backends/tofino/bf-p4c/common/asm_output.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/midend/parser_graph.h" #include "backends/tofino/bf-p4c/parde/add_parde_metadata.h" #include "backends/tofino/bf-p4c/parde/dump_parser.h" #include "backends/tofino/bf-p4c/parde/parser_loops_info.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" #include "lib/log.h" diff --git a/backends/tofino/bf-p4c/parde/extract_parser.h b/backends/tofino/bf-p4c/parde/extract_parser.h index 336c56d6d7..770d40a5c0 100644 --- a/backends/tofino/bf-p4c/parde/extract_parser.h +++ b/backends/tofino/bf-p4c/parde/extract_parser.h @@ -20,9 +20,9 @@ #define BF_P4C_PARDE_EXTRACT_PARSER_H_ #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/logging/pass_manager.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "frontends/common/resolveReferences/referenceMap.h" #include "frontends/p4/typeMap.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/parde/field_packing.h b/backends/tofino/bf-p4c/parde/field_packing.h index ec090c2ebc..6ea32626af 100644 --- a/backends/tofino/bf-p4c/parde/field_packing.h +++ b/backends/tofino/bf-p4c/parde/field_packing.h @@ -22,7 +22,7 @@ #include #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "lib/cstring.h" namespace P4 { diff --git a/backends/tofino/bf-p4c/parde/infer_payload_offset.cpp b/backends/tofino/bf-p4c/parde/infer_payload_offset.cpp index af9c05d7a2..aa99d9dc56 100644 --- a/backends/tofino/bf-p4c/parde/infer_payload_offset.cpp +++ b/backends/tofino/bf-p4c/parde/infer_payload_offset.cpp @@ -20,12 +20,12 @@ #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/lib/assoc.h" #include "backends/tofino/bf-p4c/parde/dump_parser.h" #include "backends/tofino/bf-p4c/parde/parde_utils.h" #include "backends/tofino/bf-p4c/parde/parser_info.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" +#include "backends/tofino/bf-p4c/specs/device.h" static bool is_mutable_field(const FieldDefUse &defuse, const PHV::Field *f) { auto all_defs = defuse.getAllDefs(f->id); diff --git a/backends/tofino/bf-p4c/parde/lower_parser.cpp b/backends/tofino/bf-p4c/parde/lower_parser.cpp index 7f9e3fbc79..ef2b5e8e06 100644 --- a/backends/tofino/bf-p4c/parde/lower_parser.cpp +++ b/backends/tofino/bf-p4c/parde/lower_parser.cpp @@ -36,7 +36,6 @@ #include "backends/tofino/bf-p4c/common/ir_utils.h" #include "backends/tofino/bf-p4c/common/slice.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" #include "backends/tofino/bf-p4c/mau/resource.h" @@ -66,6 +65,7 @@ #include "backends/tofino/bf-p4c/parde/split_parser_state.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/pragma/pa_no_init.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/safe_vector.h" #include "lib/stringref.h" diff --git a/backends/tofino/bf-p4c/parde/lowered/compute_buffer_requirements.cpp b/backends/tofino/bf-p4c/parde/lowered/compute_buffer_requirements.cpp index 147f855f11..7f3e76da12 100644 --- a/backends/tofino/bf-p4c/parde/lowered/compute_buffer_requirements.cpp +++ b/backends/tofino/bf-p4c/parde/lowered/compute_buffer_requirements.cpp @@ -18,7 +18,7 @@ #include "compute_buffer_requirements.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace Parde::Lowered { diff --git a/backends/tofino/bf-p4c/parde/lowered/compute_lowered_deparser_ir.cpp b/backends/tofino/bf-p4c/parde/lowered/compute_lowered_deparser_ir.cpp index 426a44c234..1f15d36497 100644 --- a/backends/tofino/bf-p4c/parde/lowered/compute_lowered_deparser_ir.cpp +++ b/backends/tofino/bf-p4c/parde/lowered/compute_lowered_deparser_ir.cpp @@ -20,7 +20,7 @@ #include "backends/tofino/bf-p4c/common/ir_utils.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "helpers.h" namespace Parde::Lowered { diff --git a/backends/tofino/bf-p4c/parde/lowered/eliminate_empty_states.cpp b/backends/tofino/bf-p4c/parde/lowered/eliminate_empty_states.cpp index 5b6235b3a0..85d4711fcc 100644 --- a/backends/tofino/bf-p4c/parde/lowered/eliminate_empty_states.cpp +++ b/backends/tofino/bf-p4c/parde/lowered/eliminate_empty_states.cpp @@ -18,7 +18,7 @@ #include "eliminate_empty_states.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace Parde::Lowered { diff --git a/backends/tofino/bf-p4c/parde/lowered/hoist_common_match_operations.h b/backends/tofino/bf-p4c/parde/lowered/hoist_common_match_operations.h index 113510c31c..afcda707ee 100644 --- a/backends/tofino/bf-p4c/parde/lowered/hoist_common_match_operations.h +++ b/backends/tofino/bf-p4c/parde/lowered/hoist_common_match_operations.h @@ -19,10 +19,10 @@ #ifndef BACKENDS_TOFINO_BF_P4C_PARDE_LOWERED_HOIST_COMMON_MATCH_OPERATIONS_H_ #define BACKENDS_TOFINO_BF_P4C_PARDE_LOWERED_HOIST_COMMON_MATCH_OPERATIONS_H_ -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/lib/assoc.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "compute_lowered_parser_ir.h" namespace Parde::Lowered { diff --git a/backends/tofino/bf-p4c/parde/marshal.h b/backends/tofino/bf-p4c/parde/marshal.h index af8b49efb7..1a5e9f3e1b 100644 --- a/backends/tofino/bf-p4c/parde/marshal.h +++ b/backends/tofino/bf-p4c/parde/marshal.h @@ -21,7 +21,7 @@ #include -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "lib/cstring.h" namespace P4 { diff --git a/backends/tofino/bf-p4c/parde/match_register.cpp b/backends/tofino/bf-p4c/parde/match_register.cpp index bddbb046df..d35d8854fc 100644 --- a/backends/tofino/bf-p4c/parde/match_register.cpp +++ b/backends/tofino/bf-p4c/parde/match_register.cpp @@ -18,40 +18,26 @@ #include "match_register.h" -#include - -#include "ir/ir.h" #include "ir/json_generator.h" #include "ir/json_loader.h" +#include "ir/json_parser.h" +#include "lib/exceptions.h" -int MatchRegister::s_id = 0; - -cstring MatchRegister::toString() const { - std::stringstream tmp; - tmp << *this; - return tmp.str(); -} - -MatchRegister::MatchRegister() : name(""), size(0), id(0) {} - -MatchRegister::MatchRegister(cstring n) : name(n), id(s_id++) { - if (name.find("byte")) - size = 1; - else if (name.find("half")) - size = 2; - else - BUG("Invalid parser match register %s", name); -} +namespace P4 { void MatchRegister::toJSON(JSONGenerator &json) const { json << *this; } /* static */ MatchRegister MatchRegister::fromJSON(JSONLoader &json) { - if (auto *v = json.json->to()) return MatchRegister(cstring(v->c_str())); + if (auto *v = json.json->to()) { + return MatchRegister(cstring(v->c_str())); + } BUG("Couldn't decode JSON value to parser match register"); - return MatchRegister(); + return {}; } P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const MatchRegister &c) { return out << c.toString(); } + +} // namespace P4 diff --git a/backends/tofino/bf-p4c/parde/match_register.h b/backends/tofino/bf-p4c/parde/match_register.h index 10337890f6..8dd9ebfe03 100644 --- a/backends/tofino/bf-p4c/parde/match_register.h +++ b/backends/tofino/bf-p4c/parde/match_register.h @@ -21,6 +21,7 @@ #include +#include "backends/tofino/bf-p4c/specs/match_register_spec.h" #include "lib/cstring.h" namespace P4 { @@ -28,34 +29,15 @@ namespace P4 { class JSONGenerator; class JSONLoader; -class MatchRegister { +class MatchRegister : public MatchRegisterSpec { public: - MatchRegister(); - explicit MatchRegister(cstring); - - cstring toString() const; - - bool operator==(const MatchRegister &other) const { return name == other.name; } + MatchRegister() = default; + explicit MatchRegister(cstring n) : MatchRegisterSpec(n) {} + explicit MatchRegister(const MatchRegisterSpec &spec) : MatchRegisterSpec(spec) {} /// JSON serialization/deserialization. void toJSON(JSONGenerator &json) const; static MatchRegister fromJSON(JSONLoader &json); - - cstring name; - size_t size; - int id; - - static int s_id; - - bool operator<(const MatchRegister &other) const { - if (size < other.size) return true; - if (other.size < size) return false; - if (id < other.id) return true; - if (other.id > id) return false; - return false; - } - - friend std::ostream &operator<<(std::ostream &out, const MatchRegister &c); }; inline std::ostream &operator<<(std::ostream &out, const MatchRegister &c) { return out << c.name; } diff --git a/backends/tofino/bf-p4c/parde/parde_utils.h b/backends/tofino/bf-p4c/parde/parde_utils.h index 08fe169a8e..d8f3fa3d89 100644 --- a/backends/tofino/bf-p4c/parde/parde_utils.h +++ b/backends/tofino/bf-p4c/parde/parde_utils.h @@ -19,7 +19,7 @@ #ifndef BACKENDS_TOFINO_BF_P4C_PARDE_PARDE_UTILS_H_ #define BACKENDS_TOFINO_BF_P4C_PARDE_PARDE_UTILS_H_ -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" static const IR::BFN::PacketRVal *get_packet_range(const IR::BFN::ParserPrimitive *p) { if (auto e = p->to()) { diff --git a/backends/tofino/bf-p4c/parde/parser_header_sequences.h b/backends/tofino/bf-p4c/parde/parser_header_sequences.h index 73b0db4f7c..6d039aeaa9 100644 --- a/backends/tofino/bf-p4c/parde/parser_header_sequences.h +++ b/backends/tofino/bf-p4c/parde/parser_header_sequences.h @@ -20,9 +20,9 @@ #define BF_P4C_PARDE_PARSER_HEADER_SEQUENCES_H_ #include "backends/tofino/bf-p4c/ir/control_flow_visitor.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "ir/ir.h" #include "ir/visitor.h" diff --git a/backends/tofino/bf-p4c/parde/parser_info.h b/backends/tofino/bf-p4c/parde/parser_info.h index aa080615b1..77204ef16b 100644 --- a/backends/tofino/bf-p4c/parde/parser_info.h +++ b/backends/tofino/bf-p4c/parde/parser_info.h @@ -28,9 +28,9 @@ #include #include "backends/tofino/bf-p4c/ir/control_flow_visitor.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/lib/assoc.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "ir/ir.h" #include "lib/cstring.h" diff --git a/backends/tofino/bf-p4c/parde/parser_loops_info.cpp b/backends/tofino/bf-p4c/parde/parser_loops_info.cpp index 620581f4d4..53e84a514c 100644 --- a/backends/tofino/bf-p4c/parde/parser_loops_info.cpp +++ b/backends/tofino/bf-p4c/parde/parser_loops_info.cpp @@ -26,10 +26,10 @@ #include "backends/tofino/bf-p4c/arch/arch.h" #include "backends/tofino/bf-p4c/common/asm_output.h" #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/midend/parser_graph.h" #include "backends/tofino/bf-p4c/parde/add_parde_metadata.h" #include "backends/tofino/bf-p4c/parde/dump_parser.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "ir/ir.h" #include "lib/log.h" diff --git a/backends/tofino/bf-p4c/parde/resolve_negative_extract.h b/backends/tofino/bf-p4c/parde/resolve_negative_extract.h index 67121fa0c3..04de144e31 100644 --- a/backends/tofino/bf-p4c/parde/resolve_negative_extract.h +++ b/backends/tofino/bf-p4c/parde/resolve_negative_extract.h @@ -24,11 +24,11 @@ #include #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/parde/dump_parser.h" #include "backends/tofino/bf-p4c/parde/parde_visitor.h" #include "backends/tofino/bf-p4c/parde/parser_dominator_builder.h" #include "backends/tofino/bf-p4c/parde/parser_info.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "lib/indent.h" #include "lib/ordered_map.h" diff --git a/backends/tofino/bf-p4c/phv/action_phv_constraints.cpp b/backends/tofino/bf-p4c/phv/action_phv_constraints.cpp index 32ffd16937..9408f76094 100644 --- a/backends/tofino/bf-p4c/phv/action_phv_constraints.cpp +++ b/backends/tofino/bf-p4c/phv/action_phv_constraints.cpp @@ -28,11 +28,11 @@ #include "backends/tofino/bf-p4c/common/scc_toposort.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" #include "backends/tofino/bf-p4c/phv/cluster_phv_operations.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/solver/action_constraint_solver.h" #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/algorithm.h" #include "lib/exceptions.h" diff --git a/backends/tofino/bf-p4c/phv/allocate_phv.cpp b/backends/tofino/bf-p4c/phv/allocate_phv.cpp index 74c1edb345..a8e7908b71 100644 --- a/backends/tofino/bf-p4c/phv/allocate_phv.cpp +++ b/backends/tofino/bf-p4c/phv/allocate_phv.cpp @@ -28,9 +28,7 @@ #include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/logging/event_logger.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" #include "backends/tofino/bf-p4c/parde/parser_query.h" @@ -40,7 +38,6 @@ #include "backends/tofino/bf-p4c/phv/live_range_split.h" #include "backends/tofino/bf-p4c/phv/optimize_phv.h" #include "backends/tofino/bf-p4c/phv/parser_extract_balance_score.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/slicing/phv_slicing_iterator.h" #include "backends/tofino/bf-p4c/phv/slicing/phv_slicing_split.h" @@ -48,6 +45,9 @@ #include "backends/tofino/bf-p4c/phv/utils/report.h" #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/gress.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "lib/error.h" #include "lib/exceptions.h" @@ -56,7 +56,6 @@ const std::vector StateExtractUsage::extractor_sizes = {PHV::Size::b8, PHV::Size::b16, PHV::Size::b32}; - // AllocScore metrics. namespace { diff --git a/backends/tofino/bf-p4c/phv/allocate_phv.h b/backends/tofino/bf-p4c/phv/allocate_phv.h index cd0fd209af..88d5d6f2a9 100644 --- a/backends/tofino/bf-p4c/phv/allocate_phv.h +++ b/backends/tofino/bf-p4c/phv/allocate_phv.h @@ -24,7 +24,6 @@ #include "backends/tofino/bf-p4c/common/field_defuse.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" #include "backends/tofino/bf-p4c/phv/action_phv_constraints.h" #include "backends/tofino/bf-p4c/phv/action_source_tracker.h" @@ -36,7 +35,6 @@ #include "backends/tofino/bf-p4c/phv/fieldslice_live_range.h" #include "backends/tofino/bf-p4c/phv/make_clusters.h" #include "backends/tofino/bf-p4c/phv/mau_backtracker.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" #include "backends/tofino/bf-p4c/phv/pragma/phv_pragmas.h" @@ -45,6 +43,8 @@ #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" #include "backends/tofino/bf-p4c/phv/utils/tables_to_ids.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/gress.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/bitvec.h" #include "lib/symbitmatrix.h" diff --git a/backends/tofino/bf-p4c/phv/allocate_temps_and_finalize_liverange.cpp b/backends/tofino/bf-p4c/phv/allocate_temps_and_finalize_liverange.cpp index a129450f39..5b4fe304f7 100644 --- a/backends/tofino/bf-p4c/phv/allocate_temps_and_finalize_liverange.cpp +++ b/backends/tofino/bf-p4c/phv/allocate_temps_and_finalize_liverange.cpp @@ -21,12 +21,12 @@ #include #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/mau/table_placement.h" #include "backends/tofino/bf-p4c/mau/table_summary.h" #include "backends/tofino/bf-p4c/phv/finalize_physical_liverange.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" +#include "backends/tofino/bf-p4c/specs/gress.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace PHV { diff --git a/backends/tofino/bf-p4c/phv/analysis/dark_live_range.h b/backends/tofino/bf-p4c/phv/analysis/dark_live_range.h index ac5fb81a18..6dc15ac2ac 100644 --- a/backends/tofino/bf-p4c/phv/analysis/dark_live_range.h +++ b/backends/tofino/bf-p4c/phv/analysis/dark_live_range.h @@ -29,11 +29,11 @@ #include "backends/tofino/bf-p4c/phv/analysis/dominator_tree.h" #include "backends/tofino/bf-p4c/phv/analysis/non_mocha_dark_fields.h" #include "backends/tofino/bf-p4c/phv/mau_backtracker.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" #include "backends/tofino/bf-p4c/phv/pragma/phv_pragmas.h" #include "backends/tofino/bf-p4c/phv/utils/live_range_report.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/symbitmatrix.h" // Structure that represents the live range map. diff --git a/backends/tofino/bf-p4c/phv/analysis/dominator_tree.cpp b/backends/tofino/bf-p4c/phv/analysis/dominator_tree.cpp index 1f3b0b43ab..9c8cbb4899 100644 --- a/backends/tofino/bf-p4c/phv/analysis/dominator_tree.cpp +++ b/backends/tofino/bf-p4c/phv/analysis/dominator_tree.cpp @@ -21,7 +21,7 @@ #include #include -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" using namespace boost; diff --git a/backends/tofino/bf-p4c/phv/analysis/jbay_phv_analysis.cpp b/backends/tofino/bf-p4c/phv/analysis/jbay_phv_analysis.cpp index 60b8dae7a3..1c0b56aab8 100644 --- a/backends/tofino/bf-p4c/phv/analysis/jbay_phv_analysis.cpp +++ b/backends/tofino/bf-p4c/phv/analysis/jbay_phv_analysis.cpp @@ -18,9 +18,9 @@ #include "jbay_phv_analysis.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" +#include "backends/tofino/bf-p4c/specs/device.h" Visitor::profile_t JbayPhvAnalysis::init_apply(const IR::Node *root) { profile_t rv = Inspector::init_apply(root); diff --git a/backends/tofino/bf-p4c/phv/analysis/mocha.cpp b/backends/tofino/bf-p4c/phv/analysis/mocha.cpp index 205be86b55..d963261b24 100644 --- a/backends/tofino/bf-p4c/phv/analysis/mocha.cpp +++ b/backends/tofino/bf-p4c/phv/analysis/mocha.cpp @@ -19,6 +19,8 @@ #include "backends/tofino/bf-p4c/phv/analysis/mocha.h" #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" +#include "backends/tofino/bf-p4c/phv/phv_analysis.h" +#include "backends/tofino/bf-p4c/specs/device.h" Visitor::profile_t CollectMochaCandidates::init_apply(const IR::Node *root) { profile_t rv = Inspector::init_apply(root); @@ -28,7 +30,7 @@ Visitor::profile_t CollectMochaCandidates::init_apply(const IR::Node *root) { BUG_CHECK(root->is(), "IR root is not a BFN::Pipe: %s", root); const auto *root_ = root->to(); - Device::phvSpec().applyGlobalPragmas(root_->global_pragmas); + applyGlobalPragmas(Device::phvSpec(), root_->global_pragmas); for (auto *anno : root_->global_pragmas) { if (anno->name.name == PragmaAllowPOVonMocha::name) { diff --git a/backends/tofino/bf-p4c/phv/analysis/non_mocha_dark_fields.h b/backends/tofino/bf-p4c/phv/analysis/non_mocha_dark_fields.h index af135bae86..4e8ffafa59 100644 --- a/backends/tofino/bf-p4c/phv/analysis/non_mocha_dark_fields.h +++ b/backends/tofino/bf-p4c/phv/analysis/non_mocha_dark_fields.h @@ -21,9 +21,9 @@ #include "backends/tofino/bf-p4c/common/field_defuse.h" #include "backends/tofino/bf-p4c/mau/action_analysis.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/pragma/phv_pragmas.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" class NonMochaDarkFields : public Inspector { diff --git a/backends/tofino/bf-p4c/phv/asm_output.cpp b/backends/tofino/bf-p4c/phv/asm_output.cpp index 41825d3458..9bb414a646 100644 --- a/backends/tofino/bf-p4c/phv/asm_output.cpp +++ b/backends/tofino/bf-p4c/phv/asm_output.cpp @@ -24,9 +24,9 @@ #include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/common/asm_output.h" #include "backends/tofino/bf-p4c/common/field_defuse.h" -#include "backends/tofino/bf-p4c/device.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/stringref.h" PhvAsmOutput::PhvAsmOutput(const PhvInfo &p, const FieldDefUse &defuse, diff --git a/backends/tofino/bf-p4c/phv/asm_output.h b/backends/tofino/bf-p4c/phv/asm_output.h index 378aff7e63..91d37b9d5f 100644 --- a/backends/tofino/bf-p4c/phv/asm_output.h +++ b/backends/tofino/bf-p4c/phv/asm_output.h @@ -23,9 +23,9 @@ #include "backends/tofino/bf-p4c/common/field_defuse.h" #include "backends/tofino/bf-p4c/mau/table_summary.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/utils/live_range_report.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/ordered_set.h" class PhvAsmOutput { diff --git a/backends/tofino/bf-p4c/phv/cluster_phv_operations.h b/backends/tofino/bf-p4c/phv/cluster_phv_operations.h index 29372727a5..d959ca0e3a 100644 --- a/backends/tofino/bf-p4c/phv/cluster_phv_operations.h +++ b/backends/tofino/bf-p4c/phv/cluster_phv_operations.h @@ -20,8 +20,8 @@ #define BF_P4C_PHV_CLUSTER_PHV_OPERATIONS_H_ #include "backends/tofino/bf-p4c/ir/thread_visitor.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "lib/map.h" #include "lib/ordered_map.h" diff --git a/backends/tofino/bf-p4c/phv/create_thread_local_instances.cpp b/backends/tofino/bf-p4c/phv/create_thread_local_instances.cpp index cfd3d9fe2b..c050d1f436 100644 --- a/backends/tofino/bf-p4c/phv/create_thread_local_instances.cpp +++ b/backends/tofino/bf-p4c/phv/create_thread_local_instances.cpp @@ -18,9 +18,9 @@ #include "backends/tofino/bf-p4c/phv/create_thread_local_instances.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/ir/thread_visitor.h" #include "backends/tofino/bf-p4c/mau/mau_visitor.h" +#include "backends/tofino/bf-p4c/specs/gress.h" namespace { diff --git a/backends/tofino/bf-p4c/phv/fieldslice_live_range.cpp b/backends/tofino/bf-p4c/phv/fieldslice_live_range.cpp index 32d76fa732..8b185637c6 100644 --- a/backends/tofino/bf-p4c/phv/fieldslice_live_range.cpp +++ b/backends/tofino/bf-p4c/phv/fieldslice_live_range.cpp @@ -23,9 +23,9 @@ #include "backends/tofino/bf-p4c/common/field_defuse.h" #include "backends/tofino/bf-p4c/common/table_printer.h" -#include "backends/tofino/bf-p4c/device.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/exceptions.h" #include "lib/safe_vector.h" diff --git a/backends/tofino/bf-p4c/phv/fieldslice_live_range.h b/backends/tofino/bf-p4c/phv/fieldslice_live_range.h index 62c7a2321b..1145b061a0 100644 --- a/backends/tofino/bf-p4c/phv/fieldslice_live_range.h +++ b/backends/tofino/bf-p4c/phv/fieldslice_live_range.h @@ -25,8 +25,8 @@ #include "backends/tofino/bf-p4c/common/map_tables_to_actions.h" #include "backends/tofino/bf-p4c/mau/action_analysis.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/pragma/phv_pragmas.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/safe_vector.h" #include "mau_backtracker.h" diff --git a/backends/tofino/bf-p4c/phv/finalize_physical_liverange.cpp b/backends/tofino/bf-p4c/phv/finalize_physical_liverange.cpp index a015d48276..c07c1b8bac 100644 --- a/backends/tofino/bf-p4c/phv/finalize_physical_liverange.cpp +++ b/backends/tofino/bf-p4c/phv/finalize_physical_liverange.cpp @@ -22,13 +22,13 @@ #include #include "backends/tofino/bf-p4c/common/field_defuse.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" #include "backends/tofino/bf-p4c/mau/table_summary.h" #include "backends/tofino/bf-p4c/parde/clot/clot.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/exceptions.h" #include "lib/safe_vector.h" diff --git a/backends/tofino/bf-p4c/phv/finalize_physical_liverange.h b/backends/tofino/bf-p4c/phv/finalize_physical_liverange.h index fdec3be832..23970eff6c 100644 --- a/backends/tofino/bf-p4c/phv/finalize_physical_liverange.h +++ b/backends/tofino/bf-p4c/phv/finalize_physical_liverange.h @@ -23,9 +23,9 @@ #include "backends/tofino/bf-p4c/ir/tofino_write_context.h" #include "backends/tofino/bf-p4c/mau/table_mutex.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/pragma/pa_no_init.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" namespace PHV { diff --git a/backends/tofino/bf-p4c/phv/live_range_split.cpp b/backends/tofino/bf-p4c/phv/live_range_split.cpp index 59bc3adcef..38ad25790a 100644 --- a/backends/tofino/bf-p4c/phv/live_range_split.cpp +++ b/backends/tofino/bf-p4c/phv/live_range_split.cpp @@ -18,10 +18,10 @@ #include "live_range_split.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/phv/allocate_phv.h" #include "backends/tofino/bf-p4c/phv/fieldslice_live_range.h" #include "backends/tofino/bf-p4c/phv/utils/report.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace PHV { diff --git a/backends/tofino/bf-p4c/phv/make_clusters.h b/backends/tofino/bf-p4c/phv/make_clusters.h index ba36a8816d..2dd2b4ba69 100644 --- a/backends/tofino/bf-p4c/phv/make_clusters.h +++ b/backends/tofino/bf-p4c/phv/make_clusters.h @@ -30,11 +30,11 @@ #include "backends/tofino/bf-p4c/phv/action_phv_constraints.h" #include "backends/tofino/bf-p4c/phv/alloc_setting.h" #include "backends/tofino/bf-p4c/phv/analysis/pack_conflicts.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" #include "backends/tofino/bf-p4c/phv/pragma/pa_byte_pack.h" #include "backends/tofino/bf-p4c/phv/pragma/pa_container_size.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "ir/visitor.h" #include "lib/map.h" diff --git a/backends/tofino/bf-p4c/phv/parser_extract_balance_score.h b/backends/tofino/bf-p4c/phv/parser_extract_balance_score.h index ab4dbae839..73eb51bf4f 100644 --- a/backends/tofino/bf-p4c/phv/parser_extract_balance_score.h +++ b/backends/tofino/bf-p4c/phv/parser_extract_balance_score.h @@ -30,7 +30,7 @@ #include #include "backends/tofino/bf-p4c/common/table_printer.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" struct StateExtractUsage { static const std::vector extractor_sizes; diff --git a/backends/tofino/bf-p4c/phv/phv.cpp b/backends/tofino/bf-p4c/phv/phv.cpp index b1e05e948f..bb6b7d5379 100644 --- a/backends/tofino/bf-p4c/phv/phv.cpp +++ b/backends/tofino/bf-p4c/phv/phv.cpp @@ -19,267 +19,24 @@ #include "backends/tofino/bf-p4c/phv/phv.h" #include -#include -#include -#include "ir/ir.h" +#include "ir/json_generator.h" #include "ir/json_loader.h" -#include "lib/cstring.h" +#include "ir/json_parser.h" namespace PHV { +void SerializableContainer::toJSON(P4::JSONGenerator &json) const { json << *this; } -Type::Type(Type::TypeEnum te) { - switch (te) { - case Type::B: - kind_ = Kind::normal; - size_ = Size::b8; - break; - case Type::H: - kind_ = Kind::normal; - size_ = Size::b16; - break; - case Type::W: - kind_ = Kind::normal; - size_ = Size::b32; - break; - case Type::TB: - kind_ = Kind::tagalong; - size_ = Size::b8; - break; - case Type::TH: - kind_ = Kind::tagalong; - size_ = Size::b16; - break; - case Type::TW: - kind_ = Kind::tagalong; - size_ = Size::b32; - break; - case Type::MB: - kind_ = Kind::mocha; - size_ = Size::b8; - break; - case Type::MH: - kind_ = Kind::mocha; - size_ = Size::b16; - break; - case Type::MW: - kind_ = Kind::mocha; - size_ = Size::b32; - break; - case Type::DB: - kind_ = Kind::dark; - size_ = Size::b8; - break; - case Type::DH: - kind_ = Kind::dark; - size_ = Size::b16; - break; - case Type::DW: - kind_ = Kind::dark; - size_ = Size::b32; - break; - default: - BUG("Unknown PHV type"); +/* static */ SerializableContainer SerializableContainer::fromJSON(P4::JSONLoader &json) { + if (auto *v = json.json->to()) { + return {v->c_str()}; } -} - -Type::Type(const char *name, bool abort_if_invalid) { - const char *n = name; - - switch (*n) { - case 'T': - kind_ = Kind::tagalong; - n++; - break; - case 'M': - kind_ = Kind::mocha; - n++; - break; - case 'D': - kind_ = Kind::dark; - n++; - break; - default: - kind_ = Kind::normal; - } - - switch (*n++) { - case 'B': - size_ = Size::b8; - break; - case 'H': - size_ = Size::b16; - break; - case 'W': - size_ = Size::b32; - break; - default: - size_ = Size::null; - if (abort_if_invalid) BUG("Invalid PHV type '%s'", name); - } - - if (*n && abort_if_invalid) BUG("Invalid PHV type '%s'", name); -} - -unsigned Type::log2sz() const { - switch (size_) { - case Size::b8: - return 0; - case Size::b16: - return 1; - case Size::b32: - return 2; - default: - BUG("Called log2sz() on an invalid container"); - } -} - -cstring Type::toString() const { - std::stringstream tmp; - tmp << *this; - return tmp.str(); -} - -Container::Container(const char *name, bool abort_if_invalid) { - const char *n = name + strcspn(name, "0123456789"); - type_ = Type(std::string(name, n - name).c_str(), abort_if_invalid); - - char *end = nullptr; - auto v = strtol(n, &end, 10); - index_ = v; - if (end == n || *end || index_ != static_cast(v)) { - type_ = Type(); - if (abort_if_invalid) BUG("Invalid register '%s'", name); - } -} - -cstring Container::toString() const { - std::stringstream tmp; - tmp << *this; - return tmp.str(); -} - -void Container::toJSON(P4::JSONGenerator &json) const { json << *this; } - -/* static */ Container Container::fromJSON(P4::JSONLoader &json) { - if (auto *v = json.json->to()) return Container(v->c_str()); BUG("Couldn't decode JSON value to container"); - return Container(); -} - -cstring FieldUse::toString(unsigned dark) const { - if (use_ == 0) return ""_cs; - std::stringstream ss; - bool checkLiveness = true; - if (use_ & READ) { - ss << (dark & READ ? "R" : "r"); - checkLiveness = false; - } - if (use_ & WRITE) { - ss << (dark & WRITE ? "W" : "w"); - checkLiveness = false; - } - if (checkLiveness && (use_ & LIVE)) ss << "~"; - return ss.str(); + return {}; } -bool LiveRange::is_disjoint(const LiveRange &other) const { - const StageAndAccess &a = this->start; - const StageAndAccess &b = this->end; - const StageAndAccess &c = other.start; - const StageAndAccess &d = other.end; - - // if any of the pairs is [xR, xR] pair, which represents an empty live range, - // it is considered to be disjoint to any other live range. - if ((a == b && a.second == PHV::FieldUse(PHV::FieldUse::READ)) || - (c == d && c.second == PHV::FieldUse(PHV::FieldUse::READ))) { - return true; - } - // If the live ranges of current slice is [aA, bB] and that of other slice is [cC, dD], where - // the small letters indicate stage and the capital letters indicate access type (read or - // write). - // The live ranges are disjoint only if: - // ((a < c || (a == c && A < C)) && (b < c || (b == c && B < C))) || - // ((c < a || (c == a && C < A)) && (d < a || (d == a && D < A))) - // TODO: this is compatible with physical live range mode. So even if there is a - // much easier way to check disjoint in physical live range mode, we can keep using this. - if ((((a.first < c.first) || (a.first == c.first && a.second < c.second)) && - ((b.first < c.first) || (b.first == c.first && b.second < c.second))) || - (((c.first < a.first) || (c.first == a.first && c.second < a.second)) && - ((d.first < a.first) || (d.first == a.first && d.second < a.second)))) - return true; - return false; -} - -void LiveRange::extend(const StageAndAccess &access) { - if (access.first < start.first) { - start = access; - } else if (end.first < access.first) { - end = access; - } - if (access.first == start.first) { - start.second |= access.second; - } - if (access.first == end.first) { - end.second |= access.second; - } -} - -std::ostream &operator<<(std::ostream &out, const PHV::Kind k) { - switch (k) { - case PHV::Kind::normal: - return out << ""; - case PHV::Kind::tagalong: - return out << "T"; - case PHV::Kind::mocha: - return out << "M"; - case PHV::Kind::dark: - return out << "D"; - default: - BUG("Unknown PHV container kind"); - } -} - -std::ostream &operator<<(std::ostream &out, const PHV::Size sz) { - switch (sz) { - case PHV::Size::b8: - return out << "B"; - case PHV::Size::b16: - return out << "H"; - case PHV::Size::b32: - return out << "W"; - default: - return out << "null"; - } -} - -std::ostream &operator<<(std::ostream &out, PHV::Type t) { return out << t.kind() << t.size(); } - -std::ostream &operator<<(std::ostream &out, const PHV::Container c) { - return out << c.type() << c.index(); -} - -P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const PHV::Container c) { +P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const PHV::SerializableContainer c) { return out << c.toString(); } -std::ostream &operator<<(std::ostream &out, ordered_set &c_set) { - out << "{"; - for (auto &c : c_set) { - out << *c << ","; - } - out << "}"; - return out; -} - -std::ostream &operator<<(std::ostream &out, const PHV::FieldUse u) { return out << u.toString(); } - -std::ostream &operator<<(std::ostream &out, const StageAndAccess &s) { - return out << s.first << s.second; -} - -std::ostream &operator<<(std::ostream &out, const LiveRange &s) { - return out << "[" << s.start << ", " << s.end << "]"; -} - } // namespace PHV diff --git a/backends/tofino/bf-p4c/phv/phv.h b/backends/tofino/bf-p4c/phv/phv.h index f8c6ef063b..a67667fa74 100644 --- a/backends/tofino/bf-p4c/phv/phv.h +++ b/backends/tofino/bf-p4c/phv/phv.h @@ -19,321 +19,39 @@ #ifndef BF_P4C_PHV_PHV_H_ #define BF_P4C_PHV_PHV_H_ -#include -#include - -#include - -#include "lib/exceptions.h" -#include "lib/ordered_set.h" +#include "backends/tofino/bf-p4c/specs/phv.h" +#include "ir/json_generator.h" namespace P4 { -class bitvec; -class cstring; class JSONGenerator; class JSONLoader; } // namespace P4 -using namespace P4; -using namespace P4::literals; - namespace PHV { -/// all possible PHV container kinds in BFN devices -/// The values here are used to define operator< on Kinds. -enum class Kind : unsigned short { tagalong = 0, dark = 1, mocha = 2, normal = 3 }; - -const Kind KINDS[] = {Kind::tagalong, Kind::dark, Kind::mocha, Kind::normal}; - -const std::map STR_OF_KIND = {{Kind::tagalong, "tagalong"_cs}, - {Kind::dark, "dark"_cs}, - {Kind::mocha, "mocha"_cs}, - {Kind::normal, "normal"_cs}}; - -// all possible contexts a PHV container can participate in -enum class Context : unsigned short { - parde = 0, - ixbar = 1, - vliw = 2, - vliw_set = 3 // Whole container move only -}; - -inline std::vector all_contexts(Kind kind) { - switch (kind) { - case PHV::Kind::normal: - return {Context::parde, Context::ixbar, Context::vliw, Context::vliw_set}; - - case PHV::Kind::tagalong: - return {Context::parde}; - - case PHV::Kind::mocha: - return {Context::parde, Context::ixbar, Context::vliw_set}; // move only - - case PHV::Kind::dark: - return {Context::vliw_set}; // move only - - default: - BUG("Unknown PHV container kind"); - } -} - -/** Provides a total ordering over PHV container kinds, denoting a refinement of the ordering - * induced by subset inclusion over the set of capabilities each kind supports. For example, - * `tagalong < normal`, because tagalong containers don't support reads/writes in the MAU, whereas - * normal containers do. - */ -// TODO: This was previously a partial order. Turned into a total order so that things behave -// properly when Kind is used as a key in std::map or an element in std::set. It's hard to search -// for all the places where this operator is used, so I'm not confident that this won't break -// anything. -// -// Previous ordering: normal > mocha > dark, mocha > tagalong. Deep had a comment that dark and -// tagalong don't occur together, so an ordering between them didn't need to be established, but -// the same could be said for tagalong and mocha. -// -// Current ordering: normal > mocha > dark > tagalong. -inline bool operator<(Kind left, Kind right) { - // Unfortunately, using the all_contexts map to define this inequality causes a massive slowdown - // (>2x) in compilation times. - // TODO: Figure out a way to use the all_contexts map to define this inequality. - - return (size_t)left < (size_t)right; -} - -inline bool operator<=(Kind left, Kind right) { return left == right || left < right; } - -inline bool operator>(Kind left, Kind right) { return right < left; } - -inline bool operator>=(Kind left, Kind right) { return left == right || left > right; } - -/// all possible PHV container sizes in BFN devices -enum class Size : unsigned short { null = 0, b8 = 8, b16 = 16, b32 = 32 }; - -const Size SIZES[] = {Size::null, Size::b8, Size::b16, Size::b32}; - -class Type { - Kind kind_; - Size size_; - - public: - enum TypeEnum { // all possible PHV container types in BFN devices - B, // 8-b normal - H, // 16-b | - W, // 32-b _| - TB, // 8-b tagalong - TH, // 16-b | - TW, // 32-b _| - MB, // 8-b mocha - MH, // 16-b | - MW, // 32-b _| - DB, // 8-b dark - DH, // 16-b | - DW // 32-b _| - }; - - Type() : kind_(Kind::normal), size_(Size::null) {} - Type(Kind k, Size s) : kind_(k), size_(s) {} - Type(const Type &t) : kind_(t.kind_), size_(t.size_) {} - - Type(TypeEnum te); // NOLINT(runtime/explicit) - Type(const char *name, bool abort_if_invalid = true); // NOLINT(runtime/explicit) - - unsigned log2sz() const; - Kind kind() const { return kind_; } - Size size() const { return size_; } - - Type &operator=(const Type &t) { - kind_ = t.kind_; - size_ = t.size_; - return *this; - } - - bool operator==(Type c) const { return (kind_ == c.kind_) && (size_ == c.size_); } - - bool operator!=(Type c) const { return !(*this == c); } - - bool operator<(Type c) const { - if (kind_ < c.kind_) return true; - if (c.kind_ < kind_) return false; - if (size_ < c.size_) return true; - if (size_ > c.size_) return false; - return false; - } - - friend size_t hash_value(const Type &c) { - size_t h = 0; - boost::hash_combine(h, c.kind_); - boost::hash_combine(h, c.size_); - return h; - } - - bool valid() const { return size_ != Size::null; } - - /// @return a string representation of this container type. - cstring toString() const; -}; - -class Container { - static constexpr unsigned MAX_INDEX = std::numeric_limits::max(); - - Type type_; - unsigned index_; - - Container(Kind k, Size s, unsigned i) : type_(k, s), index_(i) {} +class SerializableContainer : public Container { + SerializableContainer(Kind k, Size s, unsigned i) : Container(k, s, i) {} public: - /// Construct an empty container. Most operations aren't defined on empty - /// containers. (Use `operator bool()` to check if a container is empty.) - Container() : type_(), index_(0) {} + SerializableContainer() = default; + explicit SerializableContainer(const Container &container) : Container(container) {} /// Construct a container from @name - e.g., "B0" for container B0. - Container(const char *name, bool abort_if_invalid = true); // NOLINT(runtime/explicit) + /// NOLINTNEXTLINE(runtime/explicit) + SerializableContainer(const char *name, bool abort_if_invalid = true) + : Container(name, abort_if_invalid) {} /// Construct a container from @p kind and @p index - e.g., (Kind::B, 0) for /// container B0. - Container(PHV::Type t, unsigned index) : type_(t), index_(index) {} - - size_t size() const { return size_t(type_.size()); } - unsigned log2sz() const { return type_.log2sz(); } - size_t msb() const { return size() - 1; } - size_t lsb() const { return 0; } - - PHV::Type type() const { return type_; } - unsigned index() const { return index_; } - - bool is(PHV::Kind k) const { return k == type_.kind(); } - bool is(PHV::Size sz) const { return sz == type_.size(); } - - /// @return true if this container is nonempty (i.e., refers to an actual - /// PHV container). - explicit operator bool() const { return type_.valid(); } - - Container operator++() { - if (index_ != MAX_INDEX) ++index_; - return *this; - } - Container operator++(int) { - Container rv = *this; - ++*this; - return rv; - } - bool operator==(Container c) const { return type_ == c.type_ && index_ == c.index_; } - bool operator!=(Container c) const { return !(*this == c); } - bool operator<(Container c) const { - if (type_ < c.type_) return true; - if (c.type_ < type_) return false; - if (index_ < c.index_) return true; - if (c.index_ < index_) return false; - return false; - } - - friend size_t hash_value(const Container &c) { - size_t h = 0; - boost::hash_combine(h, c.type_); - boost::hash_combine(h, c.index_); - return h; - } + SerializableContainer(PHV::Type t, unsigned index) : Container(t, index) {} /// JSON serialization/deserialization. void toJSON(P4::JSONGenerator &json) const; - static Container fromJSON(P4::JSONLoader &json); - - /// @return a string representation of this container. - cstring toString() const; -}; - -/** This class describes the state of the use of a PHV container. In any given unit, the PHV may be - * read, written, both read and written, or merely be live. - */ -class FieldUse { - unsigned use_; - - public: - enum use_t { READ = 1, WRITE = 2, READWRITE = READ | WRITE, LIVE = 4 }; - - // Construct an empty use, which is neither read, write, or live. - FieldUse() : use_(0) {} - - // Construct a FieldUse object, given a specific kind of use. - explicit FieldUse(unsigned u) { - BUG_CHECK(u == READ || u == WRITE || u == READWRITE || u == LIVE, - "Invalid value %1% used to create a FieldUse object. Valid values are " - "1: READ, 2: WRITE, 3: READWRITE, 4: LIVE", - u); - use_ = u; - } - - bool isRead() const { return use_ & READ; } - bool isOnlyReadAndNotLive() const { return use_ == READ; } - bool isOnlyWriteAndNotLive() const { return use_ == WRITE; } - bool isWrite() const { return use_ & WRITE; } - bool isLive() const { return use_ & LIVE; } - bool isReadWrite() const { return use_ & READWRITE; } - bool isReadAndWrite() const { return use_ == READWRITE; } - - bool operator==(FieldUse u) const { return use_ == u.use_; } - bool operator!=(FieldUse u) const { return !(*this == u); } - bool operator<(FieldUse u) const { return use_ < u.use_; } - bool operator>(FieldUse u) const { return use_ > u.use_; } - bool operator<=(FieldUse u) const { return use_ <= u.use_; } - bool operator>=(FieldUse u) const { return use_ >= u.use_; } - explicit operator bool() const { return use_ == 0; } - - FieldUse operator|(const FieldUse &u) const { - FieldUse ru; - ru.use_ = use_ | u.use_; - BUG_CHECK(ru.use_ <= (READWRITE | LIVE), "invalid use of FieldUse %1%", ru.use_); - return ru; - } - - FieldUse &operator|=(const FieldUse &u) { - use_ |= u.use_; - BUG_CHECK(use_ <= (READWRITE | LIVE), "invalid use of FieldUse%1%", use_); - return *this; - } - - FieldUse operator&(const FieldUse &u) const { - FieldUse ru; - ru.use_ = use_ & u.use_; - BUG_CHECK(ru.use_ <= (READWRITE | LIVE), "invalid use of FieldUse%1%", ru.use_); - return ru; - } - - cstring toString(unsigned dark = 0) const; -}; - -// Pair of stage number and type of access for the field. -using StageAndAccess = std::pair; - -// Pair of two accesses. -struct LiveRange { - StageAndAccess start; - StageAndAccess end; - LiveRange(const StageAndAccess &start, const StageAndAccess &end) : start(start), end(end) {} - bool is_disjoint(const LiveRange &other) const; - // extend live range to include @p access. - void extend(const StageAndAccess &access); - bool operator<(const LiveRange &other) const { - if (start.first != other.start.first) - return start.first < other.start.first; - else - return end.first < other.end.first; - } - bool operator==(const LiveRange &other) const { - return start == other.start && end == other.end; - } + static SerializableContainer fromJSON(P4::JSONLoader &json); }; -std::ostream &operator<<(std::ostream &out, const PHV::Kind k); -std::ostream &operator<<(std::ostream &out, const PHV::Size sz); -std::ostream &operator<<(std::ostream &out, const PHV::Type t); -std::ostream &operator<<(std::ostream &out, const PHV::Container c); -std::ostream &operator<<(std::ostream &out, ordered_set &c_set); -std::ostream &operator<<(std::ostream &out, const PHV::FieldUse u); -std::ostream &operator<<(std::ostream &out, const StageAndAccess &s); -std::ostream &operator<<(std::ostream &out, const LiveRange &s); +P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const PHV::SerializableContainer c); -P4::JSONGenerator &operator<<(P4::JSONGenerator &out, const PHV::Container c); } // namespace PHV #endif /* BF_P4C_PHV_PHV_H_ */ diff --git a/backends/tofino/bf-p4c/phv/phv_analysis.cpp b/backends/tofino/bf-p4c/phv/phv_analysis.cpp index c391376e4e..adf1d67d48 100644 --- a/backends/tofino/bf-p4c/phv/phv_analysis.cpp +++ b/backends/tofino/bf-p4c/phv/phv_analysis.cpp @@ -22,13 +22,11 @@ #include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" #include "backends/tofino/bf-p4c/logging/event_logger.h" -#include "backends/tofino/bf-p4c/mau/action_mutex.h" #include "backends/tofino/bf-p4c/phv/add_initialization.h" #include "backends/tofino/bf-p4c/phv/add_special_constraints.h" #include "backends/tofino/bf-p4c/phv/allocate_phv.h" #include "backends/tofino/bf-p4c/phv/analysis/dark.h" #include "backends/tofino/bf-p4c/phv/analysis/deparser_zero.h" -#include "backends/tofino/bf-p4c/phv/analysis/jbay_phv_analysis.h" #include "backends/tofino/bf-p4c/phv/analysis/memoize_min_stage.h" #include "backends/tofino/bf-p4c/phv/analysis/mocha.h" #include "backends/tofino/bf-p4c/phv/analysis/mutex_overlay.h" @@ -40,10 +38,92 @@ #include "backends/tofino/bf-p4c/phv/table_phv_constraints.h" #include "backends/tofino/bf-p4c/phv/v2/phv_allocation_v2.h" #include "backends/tofino/bf-p4c/phv/validate_allocation.h" +#include "frontends/parsers/p4/p4parser.hpp" #include "ir/visitor.h" class PhvInfo; +void applyGlobalPragmas(const PhvSpec &phvspec, + const std::vector &global_pragmas) { + // clear all the cached values + auto phvCache = phvspec.mutablePhvCache(); + phvCache.physical_containers_i.clear(); + phvCache.mau_groups_i.clear(); + phvCache.ingress_only_containers_i.clear(); + phvCache.egress_only_containers_i.clear(); + phvCache.tagalong_collections_i.clear(); + phvCache.individually_assigned_containers_i.clear(); + std::set typesSeen; + for (auto *annot : global_pragmas) { + if (annot->name != PragmaPhvLimit::name) continue; + phvspec.physicalContainers(); // create the cache if needed + PHV::Container startRange, prev; + bool negate = false; + for (auto *tok : annot->getUnparsed()) { + PHV::Container c(tok->text.c_str(), false); + if (startRange) { + if (tok->token_type == P4::P4Parser::token_type::TOK_INTEGER) + c = PHV::Container(startRange.type(), atoi(tok->text.c_str())); + if (!c || c.type() != startRange.type() || startRange.index() > c.index()) { + error(ErrorType::ERR_INVALID, "invalid container range %2%-%3% in %1%", annot, + startRange, tok->text); + } else if (!phvspec.typeIdMap().count(c.type())) { + // container type not present on this target -- ignore; + } else { + bitvec r = phvspec.range(c.type(), startRange.index(), + c.index() - startRange.index() + 1); + if (negate) + phvCache.physical_containers_i -= r; + else + phvCache.physical_containers_i |= r; + } + startRange = PHV::Container(); + } else if (tok->text == ",") { + negate = false; + } else if (tok->text == "-") { + if (!(startRange = prev)) negate = true; + } else if (c) { + if (phvspec.typeIdMap().count(c.type())) { + if (!typesSeen.count(c.type())) { + typesSeen.insert(c.type()); + if (!negate) { + phvCache.physical_containers_i -= phvspec.filterContainerSet( + phvCache.physical_containers_i, c.type()); + } + phvCache.physical_containers_i[phvspec.containerToId(c)] = !negate; + } + } + } else if (negate && tok->text == "D") { + phvCache.physical_containers_i -= + phvspec.filterContainerSet(phvCache.physical_containers_i, PHV::Kind::dark); + } else if (negate && tok->text == "M") { + phvCache.physical_containers_i -= + phvspec.filterContainerSet(phvCache.physical_containers_i, PHV::Kind::mocha); + } else if (negate && tok->text == "T") { + phvCache.physical_containers_i -= + phvspec.filterContainerSet(phvCache.physical_containers_i, PHV::Kind::tagalong); + } else { + error(ErrorType::ERR_INVALID, "invalid container %2% in %1%", annot, tok->text); + } + prev = c; + } + } + if (phvCache.physical_containers_i) { + // propagate assignment restrictions to other sets; + phvspec.mauGroups(); + for (auto &v : Values(phvCache.mau_groups_i)) + for (auto &bv : v) bv &= phvCache.physical_containers_i; + phvspec.ingressOnly(); + phvCache.ingress_only_containers_i &= phvCache.physical_containers_i; + phvspec.egressOnly(); + phvCache.egress_only_containers_i &= phvCache.physical_containers_i; + phvspec.tagalongCollections(); + for (auto &bv : phvCache.tagalong_collections_i) bv &= phvCache.physical_containers_i; + phvspec.individuallyAssignedContainers(); + phvCache.individually_assigned_containers_i &= phvCache.physical_containers_i; + } +} + /// collect and apply PHV-related global pragmas. class ApplyGlobalPragmas : public Visitor { private: @@ -54,7 +134,7 @@ class ApplyGlobalPragmas : public Visitor { BUG_CHECK(root_->is(), "IR root is not a BFN::Pipe: %s", root_); const auto *root = root_->to(); // phv container pragma - Device::phvSpec().applyGlobalPragmas(root->global_pragmas); + applyGlobalPragmas(Device::phvSpec(), root->global_pragmas); // single parser gress pragma // Check if pragma pa_parser_group_monogress is contained in the p4 program for (auto *anno : root->global_pragmas) { diff --git a/backends/tofino/bf-p4c/phv/phv_analysis.h b/backends/tofino/bf-p4c/phv/phv_analysis.h index ac85956fc1..7165154317 100644 --- a/backends/tofino/bf-p4c/phv/phv_analysis.h +++ b/backends/tofino/bf-p4c/phv/phv_analysis.h @@ -59,6 +59,9 @@ #include "backends/tofino/bf-p4c/phv/v2/phv_kit.h" #include "backends/tofino/bf-p4c/phv/v2/table_replay_friendly_constraints.h" +void applyGlobalPragmas(const PhvSpec &phvspec, + const std::vector &global_pragmas); + /** This is the main PHV allocation pass manager. */ class PHV_AnalysisPass : public Logging::PassManager { diff --git a/backends/tofino/bf-p4c/phv/phv_fields.h b/backends/tofino/bf-p4c/phv/phv_fields.h index 00826fe1e3..ae996eaa60 100644 --- a/backends/tofino/bf-p4c/phv/phv_fields.h +++ b/backends/tofino/bf-p4c/phv/phv_fields.h @@ -26,7 +26,6 @@ #include #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" #include "backends/tofino/bf-p4c/ir/thread_visitor.h" #include "backends/tofino/bf-p4c/ir/tofino_write_context.h" @@ -34,9 +33,10 @@ #include "backends/tofino/bf-p4c/lib/cmp.h" #include "backends/tofino/bf-p4c/lib/union_find.hpp" #include "backends/tofino/bf-p4c/phv/constraints/constraints.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "lib/algorithm.h" #include "lib/map.h" diff --git a/backends/tofino/bf-p4c/phv/phv_parde_mau_use.h b/backends/tofino/bf-p4c/phv/phv_parde_mau_use.h index c46dde2275..d50e6e7c28 100644 --- a/backends/tofino/bf-p4c/phv/phv_parde_mau_use.h +++ b/backends/tofino/bf-p4c/phv/phv_parde_mau_use.h @@ -21,10 +21,10 @@ #include "backends/tofino/bf-p4c/common/header_stack.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/ir/thread_visitor.h" #include "backends/tofino/bf-p4c/ir/tofino_write_context.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/gress.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" using namespace P4; diff --git a/backends/tofino/bf-p4c/phv/pragma/pa_container_type.cpp b/backends/tofino/bf-p4c/phv/pragma/pa_container_type.cpp index 24d9e3fe80..24c51a7da5 100644 --- a/backends/tofino/bf-p4c/phv/pragma/pa_container_type.cpp +++ b/backends/tofino/bf-p4c/phv/pragma/pa_container_type.cpp @@ -22,8 +22,8 @@ #include #include "backends/tofino/bf-p4c/common/utils.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/pragma/phv_pragmas.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/log.h" namespace { diff --git a/backends/tofino/bf-p4c/phv/pragma/pa_container_type.h b/backends/tofino/bf-p4c/phv/pragma/pa_container_type.h index 5f17fbc76b..277e0feeda 100644 --- a/backends/tofino/bf-p4c/phv/pragma/pa_container_type.h +++ b/backends/tofino/bf-p4c/phv/pragma/pa_container_type.h @@ -21,8 +21,8 @@ #include -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" using namespace P4; diff --git a/backends/tofino/bf-p4c/phv/split_padding.cpp b/backends/tofino/bf-p4c/phv/split_padding.cpp index b3c9e6c5c5..3aa13aa2c4 100644 --- a/backends/tofino/bf-p4c/phv/split_padding.cpp +++ b/backends/tofino/bf-p4c/phv/split_padding.cpp @@ -20,8 +20,8 @@ #include "backends/tofino/bf-p4c/common/ir_utils.h" #include "backends/tofino/bf-p4c/common/slice.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" /** * @brief Split padding extracts that span container boundaries diff --git a/backends/tofino/bf-p4c/phv/utils/live_range_report.h b/backends/tofino/bf-p4c/phv/utils/live_range_report.h index 08534efc9a..295b31bb90 100644 --- a/backends/tofino/bf-p4c/phv/utils/live_range_report.h +++ b/backends/tofino/bf-p4c/phv/utils/live_range_report.h @@ -21,8 +21,8 @@ #include "backends/tofino/bf-p4c/common/field_defuse.h" #include "backends/tofino/bf-p4c/mau/table_summary.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "lib/log.h" diff --git a/backends/tofino/bf-p4c/phv/utils/slice_alloc.cpp b/backends/tofino/bf-p4c/phv/utils/slice_alloc.cpp index 92e0d9a11b..4a7987a88d 100644 --- a/backends/tofino/bf-p4c/phv/utils/slice_alloc.cpp +++ b/backends/tofino/bf-p4c/phv/utils/slice_alloc.cpp @@ -24,8 +24,8 @@ #include #include "backends/tofino/bf-p4c/mau/table_summary.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace PHV { diff --git a/backends/tofino/bf-p4c/phv/utils/slice_alloc.h b/backends/tofino/bf-p4c/phv/utils/slice_alloc.h index fa15fb06df..1e770aa320 100644 --- a/backends/tofino/bf-p4c/phv/utils/slice_alloc.h +++ b/backends/tofino/bf-p4c/phv/utils/slice_alloc.h @@ -22,7 +22,7 @@ #include #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "lib/bitvec.h" #include "lib/symbitmatrix.h" diff --git a/backends/tofino/bf-p4c/phv/utils/utils.cpp b/backends/tofino/bf-p4c/phv/utils/utils.cpp index 3506010ef8..856902876a 100644 --- a/backends/tofino/bf-p4c/phv/utils/utils.cpp +++ b/backends/tofino/bf-p4c/phv/utils/utils.cpp @@ -26,13 +26,13 @@ #include #include "backends/tofino/bf-p4c/common/table_printer.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" #include "backends/tofino/bf-p4c/phv/utils/live_range_report.h" #include "backends/tofino/bf-p4c/phv/utils/report.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/algorithm.h" static int cluster_id_g = 0; // global counter for assigning cluster ids diff --git a/backends/tofino/bf-p4c/phv/utils/utils.h b/backends/tofino/bf-p4c/phv/utils/utils.h index d7dc1933a4..05150aab43 100644 --- a/backends/tofino/bf-p4c/phv/utils/utils.h +++ b/backends/tofino/bf-p4c/phv/utils/utils.h @@ -22,12 +22,12 @@ #include #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/phv/error.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/pragma/pa_no_init.h" #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" +#include "backends/tofino/bf-p4c/specs/gress.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/bitvec.h" #include "lib/symbitmatrix.h" diff --git a/backends/tofino/bf-p4c/phv/v2/allocator_base.cpp b/backends/tofino/bf-p4c/phv/v2/allocator_base.cpp index 29ced1051f..ef269d9ca4 100644 --- a/backends/tofino/bf-p4c/phv/v2/allocator_base.cpp +++ b/backends/tofino/bf-p4c/phv/v2/allocator_base.cpp @@ -27,10 +27,8 @@ #include #include "backends/tofino/bf-p4c/common/table_printer.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/phv/action_phv_constraints.h" #include "backends/tofino/bf-p4c/phv/action_source_tracker.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/utils/container_equivalence.h" #include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h" @@ -40,6 +38,8 @@ #include "backends/tofino/bf-p4c/phv/v2/phv_kit.h" #include "backends/tofino/bf-p4c/phv/v2/tx_score.h" #include "backends/tofino/bf-p4c/phv/v2/utils_v2.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/exceptions.h" namespace PHV { diff --git a/backends/tofino/bf-p4c/phv/v2/allocator_base.h b/backends/tofino/bf-p4c/phv/v2/allocator_base.h index 78d06483e7..9fe9a3c490 100644 --- a/backends/tofino/bf-p4c/phv/v2/allocator_base.h +++ b/backends/tofino/bf-p4c/phv/v2/allocator_base.h @@ -19,13 +19,13 @@ #ifndef BF_P4C_PHV_V2_ALLOCATOR_BASE_H_ #define BF_P4C_PHV_V2_ALLOCATOR_BASE_H_ -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" #include "backends/tofino/bf-p4c/phv/v2/allocator_metrics.h" #include "backends/tofino/bf-p4c/phv/v2/copacker.h" #include "backends/tofino/bf-p4c/phv/v2/phv_kit.h" #include "backends/tofino/bf-p4c/phv/v2/utils_v2.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace PHV { namespace v2 { diff --git a/backends/tofino/bf-p4c/phv/v2/allocator_metrics.h b/backends/tofino/bf-p4c/phv/v2/allocator_metrics.h index 0109042855..8caf92d4a4 100644 --- a/backends/tofino/bf-p4c/phv/v2/allocator_metrics.h +++ b/backends/tofino/bf-p4c/phv/v2/allocator_metrics.h @@ -21,7 +21,7 @@ #include -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace PHV { namespace v2 { diff --git a/backends/tofino/bf-p4c/phv/v2/greedy_allocator.cpp b/backends/tofino/bf-p4c/phv/v2/greedy_allocator.cpp index c36c4d0a13..ad05156acb 100644 --- a/backends/tofino/bf-p4c/phv/v2/greedy_allocator.cpp +++ b/backends/tofino/bf-p4c/phv/v2/greedy_allocator.cpp @@ -18,7 +18,6 @@ #include "backends/tofino/bf-p4c/phv/v2/greedy_allocator.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/parde/clot/clot.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" #include "backends/tofino/bf-p4c/phv/v2/allocator_base.h" @@ -28,6 +27,7 @@ #include "backends/tofino/bf-p4c/phv/v2/sort_macros.h" #include "backends/tofino/bf-p4c/phv/v2/trivial_allocator.h" #include "backends/tofino/bf-p4c/phv/v2/utils_v2.h" +#include "backends/tofino/bf-p4c/specs/device.h" namespace PHV { namespace v2 { diff --git a/backends/tofino/bf-p4c/phv/v2/greedy_tx_score.cpp b/backends/tofino/bf-p4c/phv/v2/greedy_tx_score.cpp index b09715c3c5..d1fb72c6c9 100644 --- a/backends/tofino/bf-p4c/phv/v2/greedy_tx_score.cpp +++ b/backends/tofino/bf-p4c/phv/v2/greedy_tx_score.cpp @@ -24,14 +24,14 @@ #include #include "backends/tofino/bf-p4c/common/table_printer.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/ir/gress.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" #include "backends/tofino/bf-p4c/phv/v2/kind_size_indexed_map.h" #include "backends/tofino/bf-p4c/phv/v2/sort_macros.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/gress.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace PHV { namespace v2 { diff --git a/backends/tofino/bf-p4c/phv/v2/parser_packing_validator.cpp b/backends/tofino/bf-p4c/phv/v2/parser_packing_validator.cpp index abf93d93ec..903ffb85b1 100644 --- a/backends/tofino/bf-p4c/phv/v2/parser_packing_validator.cpp +++ b/backends/tofino/bf-p4c/phv/v2/parser_packing_validator.cpp @@ -18,10 +18,10 @@ #include "backends/tofino/bf-p4c/phv/v2/parser_packing_validator.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "lib/algorithm.h" diff --git a/backends/tofino/bf-p4c/phv/v2/phv_kit.h b/backends/tofino/bf-p4c/phv/v2/phv_kit.h index 8bee3e05ca..905ee3ad75 100644 --- a/backends/tofino/bf-p4c/phv/v2/phv_kit.h +++ b/backends/tofino/bf-p4c/phv/v2/phv_kit.h @@ -30,13 +30,13 @@ #include "backends/tofino/bf-p4c/phv/collect_table_keys.h" #include "backends/tofino/bf-p4c/phv/fieldslice_live_range.h" #include "backends/tofino/bf-p4c/phv/make_clusters.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" #include "backends/tofino/bf-p4c/phv/pragma/phv_pragmas.h" #include "backends/tofino/bf-p4c/phv/slicing/types.h" #include "backends/tofino/bf-p4c/phv/v2/action_packing_validator.h" #include "backends/tofino/bf-p4c/phv/v2/parser_packing_validator.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace PHV { namespace v2 { diff --git a/backends/tofino/bf-p4c/phv/v2/trivial_allocator.cpp b/backends/tofino/bf-p4c/phv/v2/trivial_allocator.cpp index b791527e52..541227268d 100644 --- a/backends/tofino/bf-p4c/phv/v2/trivial_allocator.cpp +++ b/backends/tofino/bf-p4c/phv/v2/trivial_allocator.cpp @@ -20,13 +20,13 @@ #include -#include "backends/tofino/bf-p4c/device.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/slicing/types.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" #include "backends/tofino/bf-p4c/phv/v2/allocator_base.h" #include "backends/tofino/bf-p4c/phv/v2/tx_score.h" #include "backends/tofino/bf-p4c/phv/v2/utils_v2.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" namespace PHV { namespace v2 { diff --git a/backends/tofino/bf-p4c/phv/v2/tx_score.cpp b/backends/tofino/bf-p4c/phv/v2/tx_score.cpp index 6e3316e5a3..907ce93c89 100644 --- a/backends/tofino/bf-p4c/phv/v2/tx_score.cpp +++ b/backends/tofino/bf-p4c/phv/v2/tx_score.cpp @@ -20,8 +20,8 @@ #include -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/exceptions.h" namespace PHV { diff --git a/backends/tofino/bf-p4c/phv/v2/utils_v2.h b/backends/tofino/bf-p4c/phv/v2/utils_v2.h index 7f3dcce0bb..6cb1e382b5 100644 --- a/backends/tofino/bf-p4c/phv/v2/utils_v2.h +++ b/backends/tofino/bf-p4c/phv/v2/utils_v2.h @@ -25,11 +25,11 @@ #include #include -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" #include "backends/tofino/bf-p4c/phv/v2/tx_score.h" #include "backends/tofino/bf-p4c/phv/v2/types.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/cstring.h" #include "lib/exceptions.h" diff --git a/backends/tofino/bf-p4c/phv/validate_allocation.cpp b/backends/tofino/bf-p4c/phv/validate_allocation.cpp index 2eb9588105..e431865d8a 100644 --- a/backends/tofino/bf-p4c/phv/validate_allocation.cpp +++ b/backends/tofino/bf-p4c/phv/validate_allocation.cpp @@ -25,14 +25,14 @@ #include #include "backends/tofino/bf-p4c/arch/bridge_metadata.h" -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" #include "backends/tofino/bf-p4c/mau/action_analysis.h" #include "backends/tofino/bf-p4c/parde/clot/clot_info.h" #include "backends/tofino/bf-p4c/parde/lower_parser.h" -#include "backends/tofino/bf-p4c/phv/phv.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" #include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "ir/ir.h" #include "lib/cstring.h" #include "lib/exceptions.h" diff --git a/backends/tofino/bf-p4c/arch/arch_spec.cpp b/backends/tofino/bf-p4c/specs/arch_spec.cpp similarity index 99% rename from backends/tofino/bf-p4c/arch/arch_spec.cpp rename to backends/tofino/bf-p4c/specs/arch_spec.cpp index a9634dee31..a8fe2b14ab 100644 --- a/backends/tofino/bf-p4c/arch/arch_spec.cpp +++ b/backends/tofino/bf-p4c/specs/arch_spec.cpp @@ -16,7 +16,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "backends/tofino/bf-p4c/arch/arch_spec.h" +#include "backends/tofino/bf-p4c/specs/arch_spec.h" ArchSpec::ArchSpec() { // ingress_intrinsic_metadata_for_tm diff --git a/backends/tofino/bf-p4c/arch/arch_spec.h b/backends/tofino/bf-p4c/specs/arch_spec.h similarity index 95% rename from backends/tofino/bf-p4c/arch/arch_spec.h rename to backends/tofino/bf-p4c/specs/arch_spec.h index 1e7f10a876..4b492281c7 100644 --- a/backends/tofino/bf-p4c/arch/arch_spec.h +++ b/backends/tofino/bf-p4c/specs/arch_spec.h @@ -16,11 +16,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BACKENDS_TOFINO_BF_P4C_ARCH_ARCH_SPEC_H_ -#define BACKENDS_TOFINO_BF_P4C_ARCH_ARCH_SPEC_H_ +#ifndef BACKENDS_TOFINO_BF_P4C_SPECS_ARCH_SPEC_H_ +#define BACKENDS_TOFINO_BF_P4C_SPECS_ARCH_SPEC_H_ -#include "backends/tofino/bf-p4c/ir/gress.h" -#include "ir/ir.h" +#include "backends/tofino/bf-p4c/specs/gress.h" struct IntrinsicField { public: @@ -157,4 +156,4 @@ class JBayArchSpec : public ArchSpec { JBayArchSpec(); }; -#endif /* BACKENDS_TOFINO_BF_P4C_ARCH_ARCH_SPEC_H_ */ +#endif /* BACKENDS_TOFINO_BF_P4C_SPECS_ARCH_SPEC_H_ */ diff --git a/backends/tofino/bf-p4c/specs/device.cpp b/backends/tofino/bf-p4c/specs/device.cpp new file mode 100644 index 0000000000..223ead98e1 --- /dev/null +++ b/backends/tofino/bf-p4c/specs/device.cpp @@ -0,0 +1,131 @@ +/** + * 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 + */ + +#include "backends/tofino/bf-p4c/specs/device.h" + +#include + +#include "lib/error.h" + +Device *Device::instance_ = nullptr; +int Device::numStagesRuntimeOverride_ = 0; + +void Device::init(cstring name, Options options) { + instance_ = nullptr; + + std::string lower_name(name); + std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower); + + if (lower_name == "tofino") + instance_ = new TofinoDevice(options); + else if (lower_name == "tofino2") + instance_ = new JBayDevice(options); +#if BAREFOOT_INTERNAL + else if (lower_name == "tofino2h") + instance_ = new JBayHDevice(options); +#endif /* BAREFOOT_INTERNAL */ + else if (lower_name == "tofino2m") + instance_ = new JBayMDevice(options); + else if (lower_name == "tofino2u") + instance_ = new JBayUDevice(options); + else if (lower_name == "tofino2a0") + instance_ = new JBayA0Device(options); + else + BUG("Unknown device %s", name); +} + +void Device::overrideNumStages(int num) { + int realNumStages = Device::get().getNumStages(); + if (num < 0 || num > realNumStages) { + ::error("Trying to override mau stages count to %d but device is capped to %d.", num, + realNumStages); + return; + } + + numStagesRuntimeOverride_ = num; +} + +const Device::StatefulAluSpec &TofinoDevice::getStatefulAluSpec() const { + static const Device::StatefulAluSpec spec = {/* .CmpMask = */ false, + /* .CmpUnits = */ {"lo"_cs, "hi"_cs}, + /* .MaxSize = */ 32, + /* .MaxDualSize = */ 64, + /* .MaxPhvInputWidth = */ 32, + /* .MaxInstructions = */ 4, + /* .MaxInstructionConstWidth = */ 4, + /* .MinInstructionConstValue = */ -8, + /* .MaxInstructionConstValue = */ 7, + /* .OutputWords = */ 1, + /* .DivModUnit = */ false, + /* .FastClear = */ false, + /* .MaxRegfileRows = */ 4}; + return spec; +} + +#if HAVE_JBAY +const Device::StatefulAluSpec &JBayDevice::getStatefulAluSpec() const { + static const Device::StatefulAluSpec spec = { + /* .CmpMask = */ true, + /* .CmpUnits = */ {"cmp0"_cs, "cmp1"_cs, "cmp2"_cs, "cmp3"_cs}, + /* .MaxSize = */ 128, + /* .MaxDualSize = */ 128, + /* .MaxPhvInputWidth = */ 64, + /* .MaxInstructions = */ 4, + /* .MaxInstructionConstWidth = */ 4, + /* .MinInstructionConstValue = */ -8, + /* .MaxInstructionConstValue = */ 7, + /* .OutputWords = */ 4, + /* .DivModUnit = */ true, + /* .FastClear = */ true, + /* .MaxRegfileRows = */ 4}; + return spec; +} +#endif + +const Device::GatewaySpec &TofinoDevice::getGatewaySpec() const { + static const Device::GatewaySpec spec = { + /* .PhvBytes = */ 4, + /* .HashBits = */ 12, + /* .PredicateBits = */ 0, + /* .MaxRows = */ 4, + /* .SupportXor = */ true, + /* .SupportRange = */ true, + /* .ExactShifts = */ 1, + /* .ByteSwizzle = */ true, + /* .PerByteMatch = */ 0, + /* .XorByteSlots = */ 0xf0, + }; + return spec; +} +#if HAVE_JBAY +const Device::GatewaySpec &JBayDevice::getGatewaySpec() const { + static const Device::GatewaySpec spec = { + /* .PhvBytes = */ 4, + /* .HashBits = */ 12, + /* .PredicateBits = */ 0, + /* .MaxRows = */ 4, + /* .SupportXor = */ true, + /* .SupportRange = */ true, + /* .ExactShifts = */ 5, + /* .ByteSwizzle = */ true, + /* .PerByteMatch = */ 0, + /* .XorByteSlots = */ 0xf0, + }; + return spec; +} +#endif diff --git a/backends/tofino/bf-p4c/device.h b/backends/tofino/bf-p4c/specs/device.h similarity index 86% rename from backends/tofino/bf-p4c/device.h rename to backends/tofino/bf-p4c/specs/device.h index eb193c27e6..4cb326c9e2 100644 --- a/backends/tofino/bf-p4c/device.h +++ b/backends/tofino/bf-p4c/specs/device.h @@ -16,20 +16,27 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BACKENDS_TOFINO_BF_P4C_DEVICE_H_ -#define BACKENDS_TOFINO_BF_P4C_DEVICE_H_ +#ifndef BACKENDS_TOFINO_BF_P4C_SPECS_DEVICE_H_ +#define BACKENDS_TOFINO_BF_P4C_SPECS_DEVICE_H_ -#include "backends/tofino/bf-p4c/arch/arch_spec.h" -#include "backends/tofino/bf-p4c/ir/gress.h" -#include "backends/tofino/bf-p4c/mau/mau_spec.h" -#include "backends/tofino/bf-p4c/mau/power_spec.h" -#include "backends/tofino/bf-p4c/parde/parde_spec.h" -#include "backends/tofino/bf-p4c/phv/phv_spec.h" +#include "backends/tofino/bf-p4c/specs/arch_spec.h" +#include "backends/tofino/bf-p4c/specs/gress.h" +#include "backends/tofino/bf-p4c/specs/mau_spec.h" +#include "backends/tofino/bf-p4c/specs/parde_spec.h" +#include "backends/tofino/bf-p4c/specs/phv_spec.h" +#include "backends/tofino/bf-p4c/specs/power_spec.h" #include "lib/cstring.h" #include "lib/exceptions.h" #include "lib/range.h" class Device { + protected: + struct Options { + float phv_scale_factor; + bool no_tagalong; + bool tof2lab44_workaround; + } options_; + public: enum Device_t { TOFINO, @@ -42,7 +49,7 @@ class Device { * This should be called as early as possible at startup, since the Device * singleton is available everywhere in the compiler. */ - static void init(cstring name); + static void init(cstring name, Options options); static const Device &get() { BUG_CHECK(instance_ != nullptr, "Target device not initialized!"); @@ -54,9 +61,37 @@ class Device { static const PhvSpec &phvSpec() { return Device::get().getPhvSpec(); } static const PardeSpec &pardeSpec() { return Device::get().getPardeSpec(); } - struct GatewaySpec; + struct GatewaySpec { + int PhvBytes; + int HashBits; + int PredicateBits; + int MaxRows; + bool SupportXor; + bool SupportRange; + int ExactShifts; + bool ByteSwizzle; // is the a byte swizzle between ixbar and gateway + int PerByteMatch; // lower bytes are shared per row, with 1 bit match per row + unsigned XorByteSlots; + }; + static const GatewaySpec &gatewaySpec() { return Device::get().getGatewaySpec(); } - struct StatefulAluSpec; + struct StatefulAluSpec { + bool CmpMask; // are cmp oprerands maskable? + std::vector CmpUnits; + int MaxSize; + int MaxDualSize; + int MaxPhvInputWidth; + int MaxInstructions; + int MaxInstructionConstWidth; + int MinInstructionConstValue; + int MaxInstructionConstValue; + int OutputWords; + bool DivModUnit; + bool FastClear; + int MaxRegfileRows; + + cstring cmpUnit(unsigned idx) const; + }; static const StatefulAluSpec &statefulAluSpec() { return Device::get().getStatefulAluSpec(); } static const ArchSpec &archSpec() { return Device::get().getArchSpec(); } static const MauPowerSpec &mauPowerSpec() { return Device::get().getMauPowerSpec(); } @@ -65,7 +100,8 @@ class Device { static const IMemSpec &imemSpec() { return Device::get().getMauSpec().getIMemSpec(); } static int numPipes() { return Device::get().getNumPipes(); } static int numStages() { - return numStagesRuntimeOverride_ ? numStagesRuntimeOverride_ : Device::get().getNumStages(); + return (numStagesRuntimeOverride_ != 0) ? numStagesRuntimeOverride_ + : Device::get().getNumStages(); } static void overrideNumStages(int num); static int numLongBranchTags() { return Device::get().getLongBranchTags(); } @@ -115,7 +151,7 @@ class Device { } protected: - explicit Device(cstring name) : name_(name) {} + explicit Device(Options options, cstring name) : options_(options), name_(name) {} virtual Device_t device_type() const = 0; virtual cstring get_name() const = 0; @@ -177,7 +213,10 @@ class TofinoDevice : public Device { const TofinoArchSpec arch_; public: - TofinoDevice() : Device("Tofino"_cs), parde_() {} + explicit TofinoDevice(Options options) + : Device(options, "Tofino"_cs), + phv_(options.phv_scale_factor, options.no_tagalong), + parde_() {} Device::Device_t device_type() const override { return Device::TOFINO; } cstring get_name() const override { return "Tofino"_cs; } int getNumPipes() const override { return 4; } @@ -251,7 +290,10 @@ class JBayDevice : public Device { #endif public: - JBayDevice() : Device("Tofino2"_cs), parde_() {} + explicit JBayDevice(Options options) + : Device(options, "Tofino2"_cs), + phv_(options.phv_scale_factor), + parde_(options.tof2lab44_workaround) {} Device::Device_t device_type() const override { return Device::JBAY; } cstring get_name() const override { return "Tofino2"_cs; } int getNumPipes() const override { return 4; } @@ -308,6 +350,8 @@ class JBayHDevice : public JBayDevice { public: int getNumStages() const override { return 6; } cstring get_name() const override { return "Tofino2H"_cs; } + + explicit JBayHDevice(Options options) : JBayDevice(options) {} }; #endif /* BAREFOOT_INTERNAL */ @@ -315,19 +359,26 @@ class JBayMDevice : public JBayDevice { public: int getNumStages() const override { return 12; } cstring get_name() const override { return "Tofino2M"_cs; } + + explicit JBayMDevice(Options options) : JBayDevice(options) {} }; class JBayUDevice : public JBayDevice { public: int getNumStages() const override { return 20; } cstring get_name() const override { return "Tofino2U"_cs; } + + explicit JBayUDevice(Options options) : JBayDevice(options) {} }; class JBayA0Device : public JBayDevice { public: - const JBayA0PardeSpec parde_{}; + const JBayA0PardeSpec parde_; const PardeSpec &getPardeSpec() const override { return parde_; } cstring get_name() const override { return "Tofino2A0"_cs; } + + explicit JBayA0Device(Options options) + : JBayDevice(options), parde_(options.tof2lab44_workaround) {} }; -#endif /* BACKENDS_TOFINO_BF_P4C_DEVICE_H_ */ +#endif /* BACKENDS_TOFINO_BF_P4C_SPECS_DEVICE_H_ */ diff --git a/backends/tofino/bf-p4c/ir/gress.cpp b/backends/tofino/bf-p4c/specs/gress.cpp similarity index 100% rename from backends/tofino/bf-p4c/ir/gress.cpp rename to backends/tofino/bf-p4c/specs/gress.cpp diff --git a/backends/tofino/bf-p4c/ir/gress.h b/backends/tofino/bf-p4c/specs/gress.h similarity index 94% rename from backends/tofino/bf-p4c/ir/gress.h rename to backends/tofino/bf-p4c/specs/gress.h index 8d668e9666..152939737a 100644 --- a/backends/tofino/bf-p4c/ir/gress.h +++ b/backends/tofino/bf-p4c/specs/gress.h @@ -16,8 +16,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_P4C_IR_GRESS_H_ -#define BF_P4C_IR_GRESS_H_ +#ifndef BF_P4C_SPECS_GRESS_H_ +#define BF_P4C_SPECS_GRESS_H_ #include #include @@ -47,4 +47,4 @@ std::ostream &operator<<(std::ostream &out, gress_t gress); std::ostream &operator<<(std::ostream &out, std::optional gress); bool operator>>(cstring s, gress_t &gressOut); -#endif /* BF_P4C_IR_GRESS_H_ */ +#endif /* BF_P4C_SPECS_GRESS_H_ */ diff --git a/backends/tofino/bf-p4c/mau/tofino/mau_spec.cpp b/backends/tofino/bf-p4c/specs/match_register_spec.cpp similarity index 54% rename from backends/tofino/bf-p4c/mau/tofino/mau_spec.cpp rename to backends/tofino/bf-p4c/specs/match_register_spec.cpp index 1aaf7b5c01..2aae87a48f 100644 --- a/backends/tofino/bf-p4c/mau/tofino/mau_spec.cpp +++ b/backends/tofino/bf-p4c/specs/match_register_spec.cpp @@ -16,16 +16,28 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "backends/tofino/bf-p4c/mau/mau_spec.h" +#include "match_register_spec.h" -#include "input_xbar.h" +#include "lib/exceptions.h" -int TofinoIXBarSpec::getExactOrdBase(int group) const { - return group * Tofino::IXBar::EXACT_BYTES_PER_GROUP; +namespace P4 { +int MatchRegisterSpec::s_id = 0; + +cstring MatchRegisterSpec::toString() const { + std::stringstream tmp; + tmp << *this; + return tmp.str(); } -int TofinoIXBarSpec::getTernaryOrdBase(int group) const { - return Tofino::IXBar::EXACT_GROUPS * Tofino::IXBar::EXACT_BYTES_PER_GROUP + - (group / 2) * Tofino::IXBar::TERNARY_BYTES_PER_BIG_GROUP + - (group % 2) * (Tofino::IXBar::TERNARY_BYTES_PER_GROUP + 1 /* mid byte */); +MatchRegisterSpec::MatchRegisterSpec() : name(""), size(0), id(0) {} + +MatchRegisterSpec::MatchRegisterSpec(cstring n) : name(n), id(s_id++) { + if (name.find("byte")) + size = 1; + else if (name.find("half")) + size = 2; + else + BUG("Invalid parser match register %s", name); } + +} // namespace P4 diff --git a/backends/tofino/bf-p4c/specs/match_register_spec.h b/backends/tofino/bf-p4c/specs/match_register_spec.h new file mode 100644 index 0000000000..1071bd76b4 --- /dev/null +++ b/backends/tofino/bf-p4c/specs/match_register_spec.h @@ -0,0 +1,60 @@ +/** + * 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 + */ + +#ifndef BACKENDS_TOFINO_BF_P4C_SPECS_MATCH_REGISTER_SPEC_H_ +#define BACKENDS_TOFINO_BF_P4C_SPECS_MATCH_REGISTER_SPEC_H_ + +#include + +#include "lib/cstring.h" + +namespace P4 { + +class MatchRegisterSpec { + public: + MatchRegisterSpec(); + explicit MatchRegisterSpec(cstring); + + cstring toString() const; + + bool operator==(const MatchRegisterSpec &other) const { return name == other.name; } + + cstring name; + size_t size; + int id; + + static int s_id; + + bool operator<(const MatchRegisterSpec &other) const { + if (size < other.size) return true; + if (other.size < size) return false; + if (id < other.id) return true; + if (other.id > id) return false; + return false; + } + + friend std::ostream &operator<<(std::ostream &out, const MatchRegisterSpec &c); +}; + +inline std::ostream &operator<<(std::ostream &out, const MatchRegisterSpec &c) { + return out << c.name; +} + +} // namespace P4 + +#endif /* BACKENDS_TOFINO_BF_P4C_SPECS_MATCH_REGISTER_SPEC_H_ */ diff --git a/backends/tofino/bf-p4c/mau/mau_spec.cpp b/backends/tofino/bf-p4c/specs/mau_spec.cpp similarity index 91% rename from backends/tofino/bf-p4c/mau/mau_spec.cpp rename to backends/tofino/bf-p4c/specs/mau_spec.cpp index ff85eadd98..12a5f99cc8 100644 --- a/backends/tofino/bf-p4c/mau/mau_spec.cpp +++ b/backends/tofino/bf-p4c/specs/mau_spec.cpp @@ -16,7 +16,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "backends/tofino/bf-p4c/mau/mau_spec.h" +#include "backends/tofino/bf-p4c/specs/mau_spec.h" + +#include "backends/tofino/bf-p4c/specs/device.h" +#include "lib/exceptions.h" #define MAU_SPEC_UNSUPPORTED \ BUG("Unsupported: a base class was used in a context/place " \ @@ -84,11 +87,7 @@ int IXBarSpec::resilientModeHashBits() const { MAU_SPEC_UNSUPPORTED } int IXBarSpec::ternaryBytesPerBigGroup() const { MAU_SPEC_UNSUPPORTED } -int IXBarSpec::tofinoMeterAluByteOffset() const {MAU_SPEC_UNSUPPORTED} - -IR::Node *MauSpec::postTransformTables(IR::MAU::Table *const table) const { - return table; -} +int IXBarSpec::tofinoMeterAluByteOffset() const { MAU_SPEC_UNSUPPORTED } int MauSpec::tcam_rows() const { return Tofino_tcam_rows; } @@ -175,3 +174,10 @@ const IMemSpec &TofinoMauSpec::getIMemSpec() const { return imem_; } const IMemSpec &JBayMauSpec::getIMemSpec() const { return imem_; } const IXBarSpec &JBayMauSpec::getIXBarSpec() const { return ixbar_; } + +int TofinoIXBarSpec::getExactOrdBase(int group) const { return group * EXACT_BYTES_PER_GROUP; } + +int TofinoIXBarSpec::getTernaryOrdBase(int group) const { + return EXACT_GROUPS * EXACT_BYTES_PER_GROUP + (group / 2) * TERNARY_BYTES_PER_BIG_GROUP + + (group % 2) * (TERNARY_BYTES_PER_GROUP + 1 /* mid byte */); +} diff --git a/backends/tofino/bf-p4c/mau/mau_spec.h b/backends/tofino/bf-p4c/specs/mau_spec.h similarity index 69% rename from backends/tofino/bf-p4c/mau/mau_spec.h rename to backends/tofino/bf-p4c/specs/mau_spec.h index d984b13fd4..5c25070277 100644 --- a/backends/tofino/bf-p4c/mau/mau_spec.h +++ b/backends/tofino/bf-p4c/specs/mau_spec.h @@ -16,13 +16,28 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BACKENDS_TOFINO_BF_P4C_MAU_MAU_SPEC_H_ -#define BACKENDS_TOFINO_BF_P4C_MAU_MAU_SPEC_H_ +#ifndef BACKENDS_TOFINO_BF_P4C_SPECS_MAU_SPEC_H_ +#define BACKENDS_TOFINO_BF_P4C_SPECS_MAU_SPEC_H_ -#include "ir/ir.h" +#include "lib/bitrange.h" + +namespace P4::IR { +namespace MAU { +class Table; +} // namespace MAU +class Node; +} // namespace P4::IR // device-specific parameters for MAU/PPU. -using namespace P4; + +struct StageUse { + static constexpr int MAX_LOGICAL_IDS = 16; + static constexpr int MAX_SRAMS = 80; + static constexpr int MAX_TCAMS = 24; + static constexpr int MAX_MAPRAMS = 48; + static constexpr int MAX_IXBAR_BYTES = 128; + static constexpr int MAX_TERNARY_GROUPS = 12; +}; class IMemSpec { public: @@ -97,10 +112,6 @@ class MauSpec { virtual const IXBarSpec &getIXBarSpec() const = 0; // pure virtual virtual const IMemSpec &getIMemSpec() const = 0; // pure virtual - // Called at the end of table rewriting in TablePlacement::TransformTables to do - // any target-specific fixups needed - virtual IR::Node *postTransformTables(IR::MAU::Table *const table) const; - // The next 4 lines: correct data for Tof.1 + Tof.2 + Tof.3; must override elsewhere for Tof.5 virtual int tcam_rows() const; virtual int tcam_columns() const; @@ -110,6 +121,44 @@ class MauSpec { class TofinoIXBarSpec : public IXBarSpec { public: + static constexpr int EXACT_GROUPS = 8; + static constexpr int EXACT_BYTES_PER_GROUP = 16; + static constexpr int HASH_TABLES = 16; + static constexpr int HASH_GROUPS = 8; + static constexpr int HASH_INDEX_GROUPS = 4; /* groups of 10 bits for indexing */ + static constexpr int HASH_SINGLE_BITS = 12; /* top 12 bits of hash table individually */ + static constexpr int HASH_PARITY_BIT = 51; /* If enabled reserved parity bit position */ + static constexpr int RAM_SELECT_BIT_START = 40; + static constexpr int RAM_LINE_SELECT_BITS = 10; + static constexpr int HASH_MATRIX_SIZE = RAM_SELECT_BIT_START + HASH_SINGLE_BITS; + static constexpr int HASH_DIST_SLICES = 3; + static constexpr int HASH_DIST_BITS = 16; + static constexpr int HASH_DIST_EXPAND_BITS = 7; + static constexpr int HASH_DIST_MAX_MASK_BITS = HASH_DIST_BITS + HASH_DIST_EXPAND_BITS; + static constexpr int HASH_DIST_UNITS = 2; + static constexpr int TOFINO_METER_ALU_BYTE_OFFSET = 8; + static constexpr int LPF_INPUT_BYTES = 4; + static constexpr int TERNARY_GROUPS = StageUse::MAX_TERNARY_GROUPS; + static constexpr int BYTE_GROUPS = StageUse::MAX_TERNARY_GROUPS / 2; + static constexpr int TERNARY_BYTES_PER_GROUP = 5; + static constexpr int TERNARY_BYTES_PER_BIG_GROUP = 11; + static constexpr int GATEWAY_SEARCH_BYTES = 4; + static constexpr int RESILIENT_MODE_HASH_BITS = 51; + static constexpr int FAIR_MODE_HASH_BITS = 14; + static constexpr int METER_ALU_HASH_BITS = 52; + static constexpr int METER_ALU_HASH_PARITY_BYTE_START = 48; + static constexpr int METER_PRECOLOR_SIZE = 2; + static constexpr int REPEATING_CONSTRAINT_SECT = 4; + static constexpr int MAX_HASH_BITS = 52; + static constexpr P4::le_bitrange SELECT_BIT_RANGE = + P4::le_bitrange(RAM_SELECT_BIT_START, METER_ALU_HASH_BITS - 1); + static constexpr P4::le_bitrange INDEX_BIT_RANGE(int group) { + return {group * RAM_LINE_SELECT_BITS, (group + 1) * RAM_LINE_SELECT_BITS - 1}; + } + static constexpr int INDEX_RANGE_SUBGROUP(P4::le_bitrange r) { + return r.lo / RAM_LINE_SELECT_BITS; + } + TofinoIXBarSpec(); int byteGroups() const override; @@ -185,4 +234,4 @@ class JBayMauSpec : public MauSpec { const IMemSpec &getIMemSpec() const override; }; -#endif /* BACKENDS_TOFINO_BF_P4C_MAU_MAU_SPEC_H_ */ +#endif /* BACKENDS_TOFINO_BF_P4C_SPECS_MAU_SPEC_H_ */ diff --git a/backends/tofino/bf-p4c/parde/parde_spec.h b/backends/tofino/bf-p4c/specs/parde_spec.h similarity index 94% rename from backends/tofino/bf-p4c/parde/parde_spec.h rename to backends/tofino/bf-p4c/specs/parde_spec.h index c8991efbc3..c6bb5471c5 100644 --- a/backends/tofino/bf-p4c/parde/parde_spec.h +++ b/backends/tofino/bf-p4c/specs/parde_spec.h @@ -5,7 +5,7 @@ * 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 + * http://www.apache.org/ilcenses/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 @@ -16,15 +16,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BACKENDS_TOFINO_BF_P4C_PARDE_PARDE_SPEC_H_ -#define BACKENDS_TOFINO_BF_P4C_PARDE_PARDE_SPEC_H_ +#ifndef BACKENDS_TOFINO_BF_P4C_SPECS_PARDE_SPEC_H_ +#define BACKENDS_TOFINO_BF_P4C_SPECS_PARDE_SPEC_H_ #include +#include #include -#include "backends/tofino/bf-p4c/bf-p4c-options.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" -#include "backends/tofino/bf-p4c/parde/match_register.h" +#include "backends/tofino/bf-p4c/specs/gress.h" +#include "backends/tofino/bf-p4c/specs/match_register_spec.h" using namespace P4::literals; @@ -419,13 +420,13 @@ class PardeSpec { virtual const std::map &extractorSpec() const = 0; /// Specifies the available match registers - virtual const std::vector matchRegisters() const = 0; + virtual const std::vector matchRegisters() const = 0; /// Specifies the available scracth registers - virtual const std::vector scratchRegisters() const = 0; + virtual const std::vector scratchRegisters() const = 0; // Region in the input buffer where the specified scratch register is located. - virtual const nw_bitrange bitScratchRegisterRange(const MatchRegister ®) const = 0; + virtual const nw_bitrange bitScratchRegisterRange(const MatchRegisterSpec ®) const = 0; // Verifies if the provided range is a valid scratch register location. virtual bool byteScratchRegisterRangeValid(nw_byterange range) const = 0; @@ -510,19 +511,20 @@ class TofinoPardeSpec : public PardeSpec { return extractorSpec; } - const std::vector matchRegisters() const override { - static std::vector spec; + const std::vector matchRegisters() const override { + static std::vector spec; if (spec.empty()) { - spec = {MatchRegister("half"_cs), MatchRegister("byte0"_cs), MatchRegister("byte1"_cs)}; + spec = {MatchRegisterSpec("half"_cs), MatchRegisterSpec("byte0"_cs), + MatchRegisterSpec("byte1"_cs)}; } return spec; } - const std::vector scratchRegisters() const override { return {}; } + const std::vector scratchRegisters() const override { return {}; } - const nw_bitrange bitScratchRegisterRange(const MatchRegister ®) const override { + const nw_bitrange bitScratchRegisterRange(const MatchRegisterSpec ®) const override { // Bug check while silencing unused variable warning. BUG("Scratch registers not available in Tofino. Register: %1%", reg.name); return nw_bitrange(); @@ -573,7 +575,11 @@ class TofinoPardeSpec : public PardeSpec { }; class JBayPardeSpec : public PardeSpec { + bool tof2lab44_workaround_; + public: + explicit JBayPardeSpec(bool tof2lab44_workaround) + : tof2lab44_workaround_(tof2lab44_workaround) {} size_t bytePhase0Size() const override { return 16; } size_t byteIngressPrePacketPaddingSize() const override { return 8; } @@ -582,31 +588,31 @@ class JBayPardeSpec : public PardeSpec { return extractorSpec; } - const std::vector matchRegisters() const override { - static std::vector spec; + const std::vector matchRegisters() const override { + static std::vector spec; if (spec.empty()) { - spec = {MatchRegister("byte0"_cs), MatchRegister("byte1"_cs), MatchRegister("byte2"_cs), - MatchRegister("byte3"_cs)}; + spec = {MatchRegisterSpec("byte0"_cs), MatchRegisterSpec("byte1"_cs), + MatchRegisterSpec("byte2"_cs), MatchRegisterSpec("byte3"_cs)}; } return spec; } - const std::vector scratchRegisters() const override { - static std::vector spec; + const std::vector scratchRegisters() const override { + static std::vector spec; if (spec.empty()) { matchRegisters(); // make sure the match registers are created first - spec = {MatchRegister("save_byte0"_cs), MatchRegister("save_byte1"_cs), - MatchRegister("save_byte2"_cs), MatchRegister("save_byte3"_cs)}; + spec = {MatchRegisterSpec("save_byte0"_cs), MatchRegisterSpec("save_byte1"_cs), + MatchRegisterSpec("save_byte2"_cs), MatchRegisterSpec("save_byte3"_cs)}; } return spec; } - const nw_bitrange bitScratchRegisterRange(const MatchRegister ®) const override { + const nw_bitrange bitScratchRegisterRange(const MatchRegisterSpec ®) const override { if (reg.name == "save_byte0") return nw_bitrange(504, 511); else if (reg.name == "save_byte1") @@ -631,9 +637,7 @@ class JBayPardeSpec : public PardeSpec { unsigned maxClotsPerState() const override { return 2; } // Cap max size to 56 as a workaround of TF2LAB-44 - unsigned byteMaxClotSize() const override { - return BackendOptions().tof2lab44_workaround ? 56 : 64; - } + unsigned byteMaxClotSize() const override { return tof2lab44_workaround_ ? 56 : 64; } unsigned numClotsPerGress() const override { return 64; } unsigned maxClotsLivePerGress() const override { return 16; } @@ -669,7 +673,9 @@ class JBayPardeSpec : public PardeSpec { class JBayA0PardeSpec : public JBayPardeSpec { public: + explicit JBayA0PardeSpec(bool tof2lab44_workaround) : JBayPardeSpec(tof2lab44_workaround) {} + unsigned numDeparserInvertChecksumUnits() const override { return 0; } }; -#endif /* BACKENDS_TOFINO_BF_P4C_PARDE_PARDE_SPEC_H_ */ +#endif /* BACKENDS_TOFINO_BF_P4C_SPECS_PARDE_SPEC_H_ */ diff --git a/backends/tofino/bf-p4c/specs/phv.cpp b/backends/tofino/bf-p4c/specs/phv.cpp new file mode 100644 index 0000000000..9fa846aa81 --- /dev/null +++ b/backends/tofino/bf-p4c/specs/phv.cpp @@ -0,0 +1,271 @@ +/** + * 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 + */ + +#include "backends/tofino/bf-p4c/specs/phv.h" + +#include +#include +#include + +#include "lib/cstring.h" + +namespace PHV { + +Type::Type(Type::TypeEnum te) { + switch (te) { + case Type::B: + kind_ = Kind::normal; + size_ = Size::b8; + break; + case Type::H: + kind_ = Kind::normal; + size_ = Size::b16; + break; + case Type::W: + kind_ = Kind::normal; + size_ = Size::b32; + break; + case Type::TB: + kind_ = Kind::tagalong; + size_ = Size::b8; + break; + case Type::TH: + kind_ = Kind::tagalong; + size_ = Size::b16; + break; + case Type::TW: + kind_ = Kind::tagalong; + size_ = Size::b32; + break; + case Type::MB: + kind_ = Kind::mocha; + size_ = Size::b8; + break; + case Type::MH: + kind_ = Kind::mocha; + size_ = Size::b16; + break; + case Type::MW: + kind_ = Kind::mocha; + size_ = Size::b32; + break; + case Type::DB: + kind_ = Kind::dark; + size_ = Size::b8; + break; + case Type::DH: + kind_ = Kind::dark; + size_ = Size::b16; + break; + case Type::DW: + kind_ = Kind::dark; + size_ = Size::b32; + break; + default: + BUG("Unknown PHV type"); + } +} + +Type::Type(const char *name, bool abort_if_invalid) { + const char *n = name; + + switch (*n) { + case 'T': + kind_ = Kind::tagalong; + n++; + break; + case 'M': + kind_ = Kind::mocha; + n++; + break; + case 'D': + kind_ = Kind::dark; + n++; + break; + default: + kind_ = Kind::normal; + } + + switch (*n++) { + case 'B': + size_ = Size::b8; + break; + case 'H': + size_ = Size::b16; + break; + case 'W': + size_ = Size::b32; + break; + default: + size_ = Size::null; + if (abort_if_invalid) BUG("Invalid PHV type '%s'", name); + } + + if (*n && abort_if_invalid) BUG("Invalid PHV type '%s'", name); +} + +unsigned Type::log2sz() const { + switch (size_) { + case Size::b8: + return 0; + case Size::b16: + return 1; + case Size::b32: + return 2; + default: + BUG("Called log2sz() on an invalid container"); + } +} + +cstring Type::toString() const { + std::stringstream tmp; + tmp << *this; + return tmp.str(); +} + +Container::Container(const char *name, bool abort_if_invalid) { + const char *n = name + strcspn(name, "0123456789"); + type_ = Type(std::string(name, n - name).c_str(), abort_if_invalid); + + char *end = nullptr; + auto v = strtol(n, &end, 10); + index_ = v; + if (end == n || *end || index_ != static_cast(v)) { + type_ = Type(); + if (abort_if_invalid) BUG("Invalid register '%s'", name); + } +} + +cstring Container::toString() const { + std::stringstream tmp; + tmp << *this; + return tmp.str(); +} + +cstring FieldUse::toString(unsigned dark) const { + if (use_ == 0) return ""_cs; + std::stringstream ss; + bool checkLiveness = true; + if (use_ & READ) { + ss << (dark & READ ? "R" : "r"); + checkLiveness = false; + } + if (use_ & WRITE) { + ss << (dark & WRITE ? "W" : "w"); + checkLiveness = false; + } + if (checkLiveness && (use_ & LIVE)) ss << "~"; + return ss.str(); +} + +bool LiveRange::is_disjoint(const LiveRange &other) const { + const StageAndAccess &a = this->start; + const StageAndAccess &b = this->end; + const StageAndAccess &c = other.start; + const StageAndAccess &d = other.end; + + // if any of the pairs is [xR, xR] pair, which represents an empty live range, + // it is considered to be disjoint to any other live range. + if ((a == b && a.second == PHV::FieldUse(PHV::FieldUse::READ)) || + (c == d && c.second == PHV::FieldUse(PHV::FieldUse::READ))) { + return true; + } + // If the live ranges of current slice is [aA, bB] and that of other slice is [cC, dD], where + // the small letters indicate stage and the capital letters indicate access type (read or + // write). + // The live ranges are disjoint only if: + // ((a < c || (a == c && A < C)) && (b < c || (b == c && B < C))) || + // ((c < a || (c == a && C < A)) && (d < a || (d == a && D < A))) + // TODO: this is compatible with physical live range mode. So even if there is a + // much easier way to check disjoint in physical live range mode, we can keep using this. + if ((((a.first < c.first) || (a.first == c.first && a.second < c.second)) && + ((b.first < c.first) || (b.first == c.first && b.second < c.second))) || + (((c.first < a.first) || (c.first == a.first && c.second < a.second)) && + ((d.first < a.first) || (d.first == a.first && d.second < a.second)))) + return true; + return false; +} + +void LiveRange::extend(const StageAndAccess &access) { + if (access.first < start.first) { + start = access; + } else if (end.first < access.first) { + end = access; + } + if (access.first == start.first) { + start.second |= access.second; + } + if (access.first == end.first) { + end.second |= access.second; + } +} + +std::ostream &operator<<(std::ostream &out, const PHV::Kind k) { + switch (k) { + case PHV::Kind::normal: + return out << ""; + case PHV::Kind::tagalong: + return out << "T"; + case PHV::Kind::mocha: + return out << "M"; + case PHV::Kind::dark: + return out << "D"; + default: + BUG("Unknown PHV container kind"); + } +} + +std::ostream &operator<<(std::ostream &out, const PHV::Size sz) { + switch (sz) { + case PHV::Size::b8: + return out << "B"; + case PHV::Size::b16: + return out << "H"; + case PHV::Size::b32: + return out << "W"; + default: + return out << "null"; + } +} + +std::ostream &operator<<(std::ostream &out, PHV::Type t) { return out << t.kind() << t.size(); } + +std::ostream &operator<<(std::ostream &out, const PHV::Container c) { + return out << c.type() << c.index(); +} + +std::ostream &operator<<(std::ostream &out, ordered_set &c_set) { + out << "{"; + for (auto &c : c_set) { + out << *c << ","; + } + out << "}"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const PHV::FieldUse u) { return out << u.toString(); } + +std::ostream &operator<<(std::ostream &out, const StageAndAccess &s) { + return out << s.first << s.second; +} + +std::ostream &operator<<(std::ostream &out, const LiveRange &s) { + return out << "[" << s.start << ", " << s.end << "]"; +} + +} // namespace PHV diff --git a/backends/tofino/bf-p4c/specs/phv.h b/backends/tofino/bf-p4c/specs/phv.h new file mode 100644 index 0000000000..77aa36822f --- /dev/null +++ b/backends/tofino/bf-p4c/specs/phv.h @@ -0,0 +1,330 @@ +/** + * 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 + */ + +#ifndef BF_P4C_SPECS_PHV_H_ +#define BF_P4C_SPECS_PHV_H_ + +#include +#include + +#include + +#include "lib/bitvec.h" +#include "lib/cstring.h" +#include "lib/exceptions.h" +#include "lib/ordered_set.h" + +using namespace P4; +using namespace P4::literals; + +namespace PHV { + +/// all possible PHV container kinds in BFN devices +/// The values here are used to define operator< on Kinds. +enum class Kind : unsigned short { tagalong = 0, dark = 1, mocha = 2, normal = 3 }; + +const Kind KINDS[] = {Kind::tagalong, Kind::dark, Kind::mocha, Kind::normal}; + +const std::map STR_OF_KIND = {{Kind::tagalong, "tagalong"_cs}, + {Kind::dark, "dark"_cs}, + {Kind::mocha, "mocha"_cs}, + {Kind::normal, "normal"_cs}}; + +// all possible contexts a PHV container can participate in +enum class Context : unsigned short { + parde = 0, + ixbar = 1, + vliw = 2, + vliw_set = 3 // Whole container move only +}; + +inline std::vector all_contexts(Kind kind) { + switch (kind) { + case PHV::Kind::normal: + return {Context::parde, Context::ixbar, Context::vliw, Context::vliw_set}; + + case PHV::Kind::tagalong: + return {Context::parde}; + + case PHV::Kind::mocha: + return {Context::parde, Context::ixbar, Context::vliw_set}; // move only + + case PHV::Kind::dark: + return {Context::vliw_set}; // move only + + default: + BUG("Unknown PHV container kind"); + } +} + +/** Provides a total ordering over PHV container kinds, denoting a refinement of the ordering + * induced by subset inclusion over the set of capabilities each kind supports. For example, + * `tagalong < normal`, because tagalong containers don't support reads/writes in the MAU, whereas + * normal containers do. + */ +// TODO: This was previously a partial order. Turned into a total order so that things behave +// properly when Kind is used as a key in std::map or an element in std::set. It's hard to search +// for all the places where this operator is used, so I'm not confident that this won't break +// anything. +// +// Previous ordering: normal > mocha > dark, mocha > tagalong. Deep had a comment that dark and +// tagalong don't occur together, so an ordering between them didn't need to be established, but +// the same could be said for tagalong and mocha. +// +// Current ordering: normal > mocha > dark > tagalong. +inline bool operator<(Kind left, Kind right) { + // Unfortunately, using the all_contexts map to define this inequality causes a massive slowdown + // (>2x) in compilation times. + // TODO: Figure out a way to use the all_contexts map to define this inequality. + + return (size_t)left < (size_t)right; +} + +inline bool operator<=(Kind left, Kind right) { return left == right || left < right; } + +inline bool operator>(Kind left, Kind right) { return right < left; } + +inline bool operator>=(Kind left, Kind right) { return left == right || left > right; } + +/// all possible PHV container sizes in BFN devices +enum class Size : unsigned short { null = 0, b8 = 8, b16 = 16, b32 = 32 }; + +const Size SIZES[] = {Size::null, Size::b8, Size::b16, Size::b32}; + +class Type { + Kind kind_; + Size size_; + + public: + enum TypeEnum { // all possible PHV container types in BFN devices + B, // 8-b normal + H, // 16-b | + W, // 32-b _| + TB, // 8-b tagalong + TH, // 16-b | + TW, // 32-b _| + MB, // 8-b mocha + MH, // 16-b | + MW, // 32-b _| + DB, // 8-b dark + DH, // 16-b | + DW // 32-b _| + }; + + Type() : kind_(Kind::normal), size_(Size::null) {} + Type(Kind k, Size s) : kind_(k), size_(s) {} + Type(const Type &t) : kind_(t.kind_), size_(t.size_) {} + + Type(TypeEnum te); // NOLINT(runtime/explicit) + Type(const char *name, bool abort_if_invalid = true); // NOLINT(runtime/explicit) + + unsigned log2sz() const; + Kind kind() const { return kind_; } + Size size() const { return size_; } + + Type &operator=(const Type &t) { + kind_ = t.kind_; + size_ = t.size_; + return *this; + } + + bool operator==(Type c) const { return (kind_ == c.kind_) && (size_ == c.size_); } + + bool operator!=(Type c) const { return !(*this == c); } + + bool operator<(Type c) const { + if (kind_ < c.kind_) return true; + if (c.kind_ < kind_) return false; + if (size_ < c.size_) return true; + if (size_ > c.size_) return false; + return false; + } + + friend size_t hash_value(const Type &c) { + size_t h = 0; + boost::hash_combine(h, c.kind_); + boost::hash_combine(h, c.size_); + return h; + } + + bool valid() const { return size_ != Size::null; } + + /// @return a string representation of this container type. + cstring toString() const; +}; + +class Container { + protected: + static constexpr unsigned MAX_INDEX = std::numeric_limits::max(); + + Type type_; + unsigned index_; + + Container(Kind k, Size s, unsigned i) : type_(k, s), index_(i) {} + + public: + /// Construct an empty container. Most operations aren't defined on empty + /// containers. (Use `operator bool()` to check if a container is empty.) + Container() : type_(), index_(0) {} + + /// Construct a container from @name - e.g., "B0" for container B0. + Container(const char *name, bool abort_if_invalid = true); // NOLINT(runtime/explicit) + + /// Construct a container from @p kind and @p index - e.g., (Kind::B, 0) for + /// container B0. + Container(PHV::Type t, unsigned index) : type_(t), index_(index) {} + + size_t size() const { return size_t(type_.size()); } + unsigned log2sz() const { return type_.log2sz(); } + size_t msb() const { return size() - 1; } + size_t lsb() const { return 0; } + + PHV::Type type() const { return type_; } + unsigned index() const { return index_; } + + bool is(PHV::Kind k) const { return k == type_.kind(); } + bool is(PHV::Size sz) const { return sz == type_.size(); } + + /// @return true if this container is nonempty (i.e., refers to an actual + /// PHV container). + explicit operator bool() const { return type_.valid(); } + + Container operator++() { + if (index_ != MAX_INDEX) ++index_; + return *this; + } + Container operator++(int) { + Container rv = *this; + ++*this; + return rv; + } + bool operator==(Container c) const { return type_ == c.type_ && index_ == c.index_; } + bool operator!=(Container c) const { return !(*this == c); } + bool operator<(Container c) const { + if (type_ < c.type_) return true; + if (c.type_ < type_) return false; + if (index_ < c.index_) return true; + if (c.index_ < index_) return false; + return false; + } + + friend size_t hash_value(const Container &c) { + size_t h = 0; + boost::hash_combine(h, c.type_); + boost::hash_combine(h, c.index_); + return h; + } + + /// @return a string representation of this container. + cstring toString() const; +}; + +/** This class describes the state of the use of a PHV container. In any given unit, the PHV may be + * read, written, both read and written, or merely be live. + */ +class FieldUse { + unsigned use_; + + public: + enum use_t { READ = 1, WRITE = 2, READWRITE = READ | WRITE, LIVE = 4 }; + + // Construct an empty use, which is neither read, write, or live. + FieldUse() : use_(0) {} + + // Construct a FieldUse object, given a specific kind of use. + explicit FieldUse(unsigned u) { + BUG_CHECK(u == READ || u == WRITE || u == READWRITE || u == LIVE, + "Invalid value %1% used to create a FieldUse object. Valid values are " + "1: READ, 2: WRITE, 3: READWRITE, 4: LIVE", + u); + use_ = u; + } + + bool isRead() const { return use_ & READ; } + bool isOnlyReadAndNotLive() const { return use_ == READ; } + bool isOnlyWriteAndNotLive() const { return use_ == WRITE; } + bool isWrite() const { return use_ & WRITE; } + bool isLive() const { return use_ & LIVE; } + bool isReadWrite() const { return use_ & READWRITE; } + bool isReadAndWrite() const { return use_ == READWRITE; } + + bool operator==(FieldUse u) const { return use_ == u.use_; } + bool operator!=(FieldUse u) const { return !(*this == u); } + bool operator<(FieldUse u) const { return use_ < u.use_; } + bool operator>(FieldUse u) const { return use_ > u.use_; } + bool operator<=(FieldUse u) const { return use_ <= u.use_; } + bool operator>=(FieldUse u) const { return use_ >= u.use_; } + explicit operator bool() const { return use_ == 0; } + + FieldUse operator|(const FieldUse &u) const { + FieldUse ru; + ru.use_ = use_ | u.use_; + BUG_CHECK(ru.use_ <= (READWRITE | LIVE), "invalid use of FieldUse %1%", ru.use_); + return ru; + } + + FieldUse &operator|=(const FieldUse &u) { + use_ |= u.use_; + BUG_CHECK(use_ <= (READWRITE | LIVE), "invalid use of FieldUse%1%", use_); + return *this; + } + + FieldUse operator&(const FieldUse &u) const { + FieldUse ru; + ru.use_ = use_ & u.use_; + BUG_CHECK(ru.use_ <= (READWRITE | LIVE), "invalid use of FieldUse%1%", ru.use_); + return ru; + } + + cstring toString(unsigned dark = 0) const; +}; + +// Pair of stage number and type of access for the field. +using StageAndAccess = std::pair; + +// Pair of two accesses. +struct LiveRange { + StageAndAccess start; + StageAndAccess end; + LiveRange(const StageAndAccess &start, const StageAndAccess &end) : start(start), end(end) {} + bool is_disjoint(const LiveRange &other) const; + // extend live range to include @p access. + void extend(const StageAndAccess &access); + bool operator<(const LiveRange &other) const { + if (start.first != other.start.first) + return start.first < other.start.first; + else + return end.first < other.end.first; + } + bool operator==(const LiveRange &other) const { + return start == other.start && end == other.end; + } +}; + +std::ostream &operator<<(std::ostream &out, const PHV::Kind k); +std::ostream &operator<<(std::ostream &out, const PHV::Size sz); +std::ostream &operator<<(std::ostream &out, const PHV::Type t); +std::ostream &operator<<(std::ostream &out, const PHV::Container c); +std::ostream &operator<<(std::ostream &out, ordered_set &c_set); +std::ostream &operator<<(std::ostream &out, const PHV::FieldUse u); +std::ostream &operator<<(std::ostream &out, const StageAndAccess &s); +std::ostream &operator<<(std::ostream &out, const LiveRange &s); + +} // namespace PHV + +#endif /* BF_P4C_SPECS_PHV_H_ */ diff --git a/backends/tofino/bf-p4c/phv/phv_spec.cpp b/backends/tofino/bf-p4c/specs/phv_spec.cpp similarity index 84% rename from backends/tofino/bf-p4c/phv/phv_spec.cpp rename to backends/tofino/bf-p4c/specs/phv_spec.cpp index 7a43f0c578..85043c951d 100644 --- a/backends/tofino/bf-p4c/phv/phv_spec.cpp +++ b/backends/tofino/bf-p4c/specs/phv_spec.cpp @@ -16,24 +16,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "backends/tofino/bf-p4c/phv/phv_spec.h" +#include "backends/tofino/bf-p4c/specs/phv_spec.h" #include #include -#include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/common/pragma/all_pragmas.h" -#include "frontends/parsers/p4/p4parser.hpp" #include "lib/bitvec.h" #include "lib/cstring.h" #include "lib/exceptions.h" +#include "lib/log.h" void PhvSpec::addType(PHV::Type t) { const size_t typeId = definedTypes.size(); definedTypes.push_back(t); definedSizes.insert(t.size()); definedKinds.insert(t.kind()); - typeIdMap[t] = typeId; + typeIdMap_[t] = typeId; } const std::vector &PhvSpec::containerTypes() const { return definedTypes; } @@ -55,7 +53,7 @@ PHV::Type PhvSpec::idToContainerType(unsigned id) const { return definedTypes[id]; } -unsigned PhvSpec::containerTypeToId(PHV::Type type) const { return typeIdMap.at(type); } +unsigned PhvSpec::containerTypeToId(PHV::Type type) const { return typeIdMap_.at(type); } PHV::Container PhvSpec::idToContainer(unsigned id) const { // Ids are assigned to containers in ascending order by index, with the @@ -148,13 +146,13 @@ bitvec PhvSpec::range(PHV::Type t, unsigned start, unsigned length) const { } const bitvec &PhvSpec::physicalContainers() const { - if (physical_containers_i) return physical_containers_i; + if (cache_.physical_containers_i) return cache_.physical_containers_i; bitvec containers; for (auto sg : mauGroups()) for (auto g : sg.second) containers |= g; for (auto g : tagalongCollections()) containers |= g; - physical_containers_i = std::move(containers); - return physical_containers_i; + cache_.physical_containers_i = std::move(containers); + return cache_.physical_containers_i; } bitvec PhvSpec::mauGroup(unsigned container_id) const { @@ -177,7 +175,7 @@ bitvec PhvSpec::mauGroup(unsigned container_id) const { } const std::map> &PhvSpec::mauGroups() const { - if (!mau_groups_i.empty()) return mau_groups_i; + if (!cache_.mau_groups_i.empty()) return cache_.mau_groups_i; std::map> mau_groups; for (auto sizeSpec : mauGroupSpec) { @@ -204,8 +202,8 @@ const std::map> &PhvSpec::mauGroups() const { mau_groups[groupSize].push_back(sizeRange); } } - mau_groups_i = std::move(mau_groups); - return mau_groups_i; + cache_.mau_groups_i = std::move(mau_groups); + return cache_.mau_groups_i; } bitvec PhvSpec::ingressOrEgressOnlyContainers( @@ -225,15 +223,15 @@ bitvec PhvSpec::ingressOrEgressOnlyContainers( } const bitvec &PhvSpec::ingressOnly() const { - if (ingress_only_containers_i) return ingress_only_containers_i; - ingress_only_containers_i = ingressOrEgressOnlyContainers(ingressOnlyMauGroupIds); - return ingress_only_containers_i; + if (cache_.ingress_only_containers_i) return cache_.ingress_only_containers_i; + cache_.ingress_only_containers_i = ingressOrEgressOnlyContainers(ingressOnlyMauGroupIds); + return cache_.ingress_only_containers_i; } const bitvec &PhvSpec::egressOnly() const { - if (egress_only_containers_i) return egress_only_containers_i; - egress_only_containers_i = ingressOrEgressOnlyContainers(egressOnlyMauGroupIds); - return egress_only_containers_i; + if (cache_.egress_only_containers_i) return cache_.egress_only_containers_i; + cache_.egress_only_containers_i = ingressOrEgressOnlyContainers(egressOnlyMauGroupIds); + return cache_.egress_only_containers_i; } unsigned PhvSpec::getTagalongCollectionId(PHV::Container c) const { @@ -246,7 +244,7 @@ unsigned PhvSpec::getTagalongCollectionId(PHV::Container c) const { } const std::vector &PhvSpec::tagalongCollections() const { - if (!tagalong_collections_i.empty()) return tagalong_collections_i; + if (!cache_.tagalong_collections_i.empty()) return cache_.tagalong_collections_i; std::vector tagalong_collections; for (unsigned coll_num = 0; coll_num < numTagalongCollections; ++coll_num) { @@ -259,8 +257,8 @@ const std::vector &PhvSpec::tagalongCollections() const { tagalong_collections.push_back(collection); } - tagalong_collections_i = std::move(tagalong_collections); - return tagalong_collections_i; + cache_.tagalong_collections_i = std::move(tagalong_collections); + return cache_.tagalong_collections_i; } bitvec PhvSpec::tagalongCollection(unsigned container_id) const { @@ -366,7 +364,7 @@ PhvSpec::AddressSpec TofinoPhvSpec::_physicalAddresses = { {PHV::Type::H, {128, 1, 128, 0, 0, 0}}, {PHV::Type::TW, {256, 1, 32, 0, 0, 0}}, {PHV::Type::TB, {288, 1, 32, 0, 0, 0}}, {PHV::Type::TH, {320, 1, 48, 0, 0, 0}}}; -TofinoPhvSpec::TofinoPhvSpec() { +TofinoPhvSpec::TofinoPhvSpec(float phv_scale_factor, bool no_tagalong) { addType(PHV::Type::B); addType(PHV::Type::H); addType(PHV::Type::W); @@ -374,8 +372,6 @@ TofinoPhvSpec::TofinoPhvSpec() { addType(PHV::Type::TH); addType(PHV::Type::TW); - auto phv_scale_factor = BackendOptions().phv_scale_factor; - BUG_CHECK(unsigned(phv_scale_factor * 4) >= 1, "PHV scale factor %1% too small", phv_scale_factor); @@ -434,7 +430,7 @@ TofinoPhvSpec::TofinoPhvSpec() { numTagalongCollections = 8 * phv_scale_factor; - if (BackendOptions().no_tagalong) numTagalongCollections = 0; + if (no_tagalong) numTagalongCollections = 0; deparserGroupSize = {{PHV::Type::B, 8 * phv_scale_factor}, {PHV::Type::H, 8 * phv_scale_factor}, @@ -484,11 +480,11 @@ unsigned TofinoPhvSpec::deparserGroupId(const PHV::Container &c) const { } const bitvec &TofinoPhvSpec::individuallyAssignedContainers() const { - if (individually_assigned_containers_i) return individually_assigned_containers_i; + if (cache_.individually_assigned_containers_i) return cache_.individually_assigned_containers_i; bitvec containers = range(PHV::Type::B, 56, 8) | range(PHV::Type::H, 88, 8) | range(PHV::Type::W, 60, 4); - individually_assigned_containers_i = std::move(containers); - return individually_assigned_containers_i; + cache_.individually_assigned_containers_i = std::move(containers); + return cache_.individually_assigned_containers_i; } unsigned TofinoPhvSpec::physicalAddress(unsigned id, ArchBlockType_t /* interface */) const { @@ -526,7 +522,7 @@ PhvSpec::AddressSpec JBayPhvSpec::_physicalDeparserAddresses = { {PHV::Type::H, {128, 6, 12, 16, 0, 0}}, {PHV::Type::MH, {140, 6, 4, 16, 0, 0}}, }; -JBayPhvSpec::JBayPhvSpec() { +JBayPhvSpec::JBayPhvSpec(float phv_scale_factor) { addType(PHV::Type::W); addType(PHV::Type::MW); addType(PHV::Type::DW); @@ -537,7 +533,6 @@ JBayPhvSpec::JBayPhvSpec() { addType(PHV::Type::MH); addType(PHV::Type::DH); - auto phv_scale_factor = BackendOptions().phv_scale_factor; if (phv_scale_factor != 1.0) P4C_UNIMPLEMENTED("phv_scale_factor not yet implemented for Tofino2"); @@ -680,13 +675,13 @@ unsigned JBayPhvSpec::deparserGroupId(const PHV::Container &c) const { } const bitvec &JBayPhvSpec::individuallyAssignedContainers() const { - return individually_assigned_containers_i; + return cache_.individually_assigned_containers_i; } unsigned JBayPhvSpec::physicalAddress(unsigned id, ArchBlockType_t interface) const { const PHV::Type containerType = idToContainerType(id % numContainerTypes()); const unsigned index = id / numContainerTypes(); - RangeSpec physicalRange; + RangeSpec physicalRange{}; if (interface == MAU) { BUG_CHECK(_physicalMauAddresses.find(containerType) != _physicalMauAddresses.end(), "PHV container %1% has unrecognized type %2%", idToContainer(id), containerType); @@ -713,81 +708,3 @@ unsigned JBayPhvSpec::physicalAddress(unsigned id, ArchBlockType_t interface) co return physicalRange.start + block * physicalRange.incr + ((blockOffset << physicalRange.shl) >> physicalRange.shr); } - -void PhvSpec::applyGlobalPragmas(const std::vector &global_pragmas) const { - // clear all the cached values - physical_containers_i.clear(); - mau_groups_i.clear(); - ingress_only_containers_i.clear(); - egress_only_containers_i.clear(); - tagalong_collections_i.clear(); - individually_assigned_containers_i.clear(); - std::set typesSeen; - for (auto *annot : global_pragmas) { - if (annot->name != PragmaPhvLimit::name) continue; - physicalContainers(); // create the cache if needed - PHV::Container startRange, prev; - bool negate = false; - for (auto *tok : annot->getUnparsed()) { - PHV::Container c(tok->text.c_str(), false); - if (startRange) { - if (tok->token_type == P4::P4Parser::token_type::TOK_INTEGER) - c = PHV::Container(startRange.type(), atoi(tok->text.c_str())); - if (!c || c.type() != startRange.type() || startRange.index() > c.index()) { - error(ErrorType::ERR_INVALID, "invalid container range %2%-%3% in %1%", annot, - startRange, tok->text); - } else if (!typeIdMap.count(c.type())) { - // container type not present on this target -- ignore; - } else { - bitvec r = - range(c.type(), startRange.index(), c.index() - startRange.index() + 1); - if (negate) - physical_containers_i -= r; - else - physical_containers_i |= r; - } - startRange = PHV::Container(); - } else if (tok->text == ",") { - negate = false; - } else if (tok->text == "-") { - if (!(startRange = prev)) negate = true; - } else if (c) { - if (typeIdMap.count(c.type())) { - if (!typesSeen.count(c.type())) { - typesSeen.insert(c.type()); - if (!negate) { - physical_containers_i -= - filterContainerSet(physical_containers_i, c.type()); - } - physical_containers_i[containerToId(c)] = !negate; - } - } - } else if (negate && tok->text == "D") { - physical_containers_i -= filterContainerSet(physical_containers_i, PHV::Kind::dark); - } else if (negate && tok->text == "M") { - physical_containers_i -= - filterContainerSet(physical_containers_i, PHV::Kind::mocha); - } else if (negate && tok->text == "T") { - physical_containers_i -= - filterContainerSet(physical_containers_i, PHV::Kind::tagalong); - } else { - error(ErrorType::ERR_INVALID, "invalid container %2% in %1%", annot, tok->text); - } - prev = c; - } - } - if (physical_containers_i) { - // propagate assignment restrictions to other sets; - mauGroups(); - for (auto &v : Values(mau_groups_i)) - for (auto &bv : v) bv &= physical_containers_i; - ingressOnly(); - ingress_only_containers_i &= physical_containers_i; - egressOnly(); - egress_only_containers_i &= physical_containers_i; - tagalongCollections(); - for (auto &bv : tagalong_collections_i) bv &= physical_containers_i; - individuallyAssignedContainers(); - individually_assigned_containers_i &= physical_containers_i; - } -} diff --git a/backends/tofino/bf-p4c/phv/phv_spec.h b/backends/tofino/bf-p4c/specs/phv_spec.h similarity index 94% rename from backends/tofino/bf-p4c/phv/phv_spec.h rename to backends/tofino/bf-p4c/specs/phv_spec.h index 87bc88b00c..633535fe25 100644 --- a/backends/tofino/bf-p4c/phv/phv_spec.h +++ b/backends/tofino/bf-p4c/specs/phv_spec.h @@ -16,15 +16,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BACKENDS_TOFINO_BF_P4C_PHV_PHV_SPEC_H_ -#define BACKENDS_TOFINO_BF_P4C_PHV_PHV_SPEC_H_ +#ifndef BACKENDS_TOFINO_BF_P4C_SPECS_PHV_SPEC_H_ +#define BACKENDS_TOFINO_BF_P4C_SPECS_PHV_SPEC_H_ #include #include -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "lib/bitvec.h" -#include "lib/json.h" #include "lib/ordered_map.h" namespace P4 { @@ -59,14 +58,19 @@ class PhvSpec { }; using AddressSpec = std::map; + // All cache fields + struct PhVCache { + bitvec physical_containers_i; + std::map> mau_groups_i; + bitvec ingress_only_containers_i; + bitvec egress_only_containers_i; + std::vector tagalong_collections_i; + bitvec individually_assigned_containers_i; + }; + protected: // All cache fields - mutable bitvec physical_containers_i; - mutable std::map> mau_groups_i; - mutable bitvec ingress_only_containers_i; - mutable bitvec egress_only_containers_i; - mutable std::vector tagalong_collections_i; - mutable bitvec individually_assigned_containers_i; + mutable PhVCache cache_; /// All types of containers supported by the device. std::vector definedTypes; @@ -75,7 +79,7 @@ class PhvSpec { /// All kinds of containers supported by the device. std::set definedKinds; - ordered_map typeIdMap; + ordered_map typeIdMap_; std::map> sizeToTypeMap; @@ -135,6 +139,10 @@ class PhvSpec { const std::map &numContainersPerGroup) const; public: + PhVCache &mutablePhvCache() const { return cache_; } + + const ordered_map &typeIdMap() const { return typeIdMap_; } + /// @return the PHV container types available on this device. const std::vector &containerTypes() const; @@ -307,14 +315,11 @@ class PhvSpec { /// in the pipeline: PARSER, MAU, DEPARSER. std::optional physicalAddressToContainer(unsigned address, ArchBlockType_t interface) const; - - /// apply global pragmas to cached info about available PHV containers - void applyGlobalPragmas(const std::vector &global_pragmas) const; }; class TofinoPhvSpec : public PhvSpec { public: - TofinoPhvSpec(); + TofinoPhvSpec(float phv_scale_factor, bool no_tagalong); /// @see PhvSpec::parserGroup(unsigned id). bitvec parserGroup(unsigned id) const override; @@ -352,7 +357,7 @@ class TofinoPhvSpec : public PhvSpec { class JBayPhvSpec : public PhvSpec { public: - JBayPhvSpec(); + explicit JBayPhvSpec(float phv_scale_factor); /// @see PhvSpec::parserGroup(unsigned id). bitvec parserGroup(unsigned id) const override; @@ -398,4 +403,4 @@ class JBayPhvSpec : public PhvSpec { static AddressSpec _physicalDeparserAddresses; }; -#endif /* BACKENDS_TOFINO_BF_P4C_PHV_PHV_SPEC_H_ */ +#endif /* BACKENDS_TOFINO_BF_P4C_SPECS_PHV_SPEC_H_ */ diff --git a/backends/tofino/bf-p4c/mau/power_spec.h b/backends/tofino/bf-p4c/specs/power_spec.h similarity index 98% rename from backends/tofino/bf-p4c/mau/power_spec.h rename to backends/tofino/bf-p4c/specs/power_spec.h index 7cfcdbf008..a29c8eff98 100644 --- a/backends/tofino/bf-p4c/mau/power_spec.h +++ b/backends/tofino/bf-p4c/specs/power_spec.h @@ -16,8 +16,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BACKENDS_TOFINO_BF_P4C_MAU_POWER_SPEC_H_ -#define BACKENDS_TOFINO_BF_P4C_MAU_POWER_SPEC_H_ +#ifndef BACKENDS_TOFINO_BF_P4C_SPECS_POWER_SPEC_H_ +#define BACKENDS_TOFINO_BF_P4C_SPECS_POWER_SPEC_H_ /** * This class encapsulates MAU power-related elements of the target device model, @@ -241,4 +241,4 @@ class JBayUMauPowerSpec : public JBayMauPowerSpec { JBayUMauPowerSpec() {} }; -#endif /* BACKENDS_TOFINO_BF_P4C_MAU_POWER_SPEC_H_ */ +#endif /* BACKENDS_TOFINO_BF_P4C_SPECS_POWER_SPEC_H_ */ diff --git a/backends/tofino/bf-p4c/test/gtest/action_format_helper.cpp b/backends/tofino/bf-p4c/test/gtest/action_format_helper.cpp index 708b8e93b4..26c9c7e52b 100644 --- a/backends/tofino/bf-p4c/test/gtest/action_format_helper.cpp +++ b/backends/tofino/bf-p4c/test/gtest/action_format_helper.cpp @@ -17,7 +17,7 @@ */ #include "backends/tofino/bf-p4c/mau/action_format.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "gtest/gtest.h" #include "lib/log.h" diff --git a/backends/tofino/bf-p4c/test/gtest/bf_gtest_helpers.cpp b/backends/tofino/bf-p4c/test/gtest/bf_gtest_helpers.cpp index b14fff10ea..b9b066521e 100644 --- a/backends/tofino/bf-p4c/test/gtest/bf_gtest_helpers.cpp +++ b/backends/tofino/bf-p4c/test/gtest/bf_gtest_helpers.cpp @@ -453,7 +453,7 @@ TestCode::TestCode(Hdr header, std::string code, for (const auto &arg : options) argv.push_back(const_cast(arg.data())); argv.push_back(nullptr); o.process(argv.size() - 1, argv.data()); - Device::init(o.target); + Device::init(o.target, {o.phv_scale_factor, o.no_tagalong, o.tof2lab44_workaround}); BFN::Architecture::init(o.arch); std::stringstream source; diff --git a/backends/tofino/bf-p4c/test/gtest/container_action.cpp b/backends/tofino/bf-p4c/test/gtest/container_action.cpp index 4658ff25c5..a5e03b9796 100644 --- a/backends/tofino/bf-p4c/test/gtest/container_action.cpp +++ b/backends/tofino/bf-p4c/test/gtest/container_action.cpp @@ -23,9 +23,9 @@ #include -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/mau/action_analysis.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h" namespace P4::Test { diff --git a/backends/tofino/bf-p4c/test/gtest/dominator_tree.cpp b/backends/tofino/bf-p4c/test/gtest/dominator_tree.cpp index c605b64a05..26b5b67e66 100644 --- a/backends/tofino/bf-p4c/test/gtest/dominator_tree.cpp +++ b/backends/tofino/bf-p4c/test/gtest/dominator_tree.cpp @@ -25,7 +25,7 @@ #include #include "backends/tofino/bf-p4c/common/header_stack.h" -#include "backends/tofino/bf-p4c/ir/gress.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h" #include "gtest/gtest.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/test/gtest/input_xbar.cpp b/backends/tofino/bf-p4c/test/gtest/input_xbar.cpp index 6f3f58245c..651bec386d 100644 --- a/backends/tofino/bf-p4c/test/gtest/input_xbar.cpp +++ b/backends/tofino/bf-p4c/test/gtest/input_xbar.cpp @@ -20,8 +20,8 @@ #include -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h" #include "gtest/gtest.h" diff --git a/backends/tofino/bf-p4c/test/gtest/meta_live_range.cpp b/backends/tofino/bf-p4c/test/gtest/meta_live_range.cpp index 6e253580c7..607f28f734 100644 --- a/backends/tofino/bf-p4c/test/gtest/meta_live_range.cpp +++ b/backends/tofino/bf-p4c/test/gtest/meta_live_range.cpp @@ -27,11 +27,11 @@ #include "backends/tofino/bf-p4c/common/elim_unused.h" #include "backends/tofino/bf-p4c/common/field_defuse.h" #include "backends/tofino/bf-p4c/common/header_stack.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/mau/instruction_selection.h" #include "backends/tofino/bf-p4c/mau/table_dependency_graph.h" #include "backends/tofino/bf-p4c/phv/mau_backtracker.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h" #include "gtest/gtest.h" #include "ir/ir.h" diff --git a/backends/tofino/bf-p4c/test/gtest/phv/greedy_tx_score.cpp b/backends/tofino/bf-p4c/test/gtest/phv/greedy_tx_score.cpp index c96d01e8ab..5883172a88 100644 --- a/backends/tofino/bf-p4c/test/gtest/phv/greedy_tx_score.cpp +++ b/backends/tofino/bf-p4c/test/gtest/phv/greedy_tx_score.cpp @@ -18,7 +18,7 @@ #include "backends/tofino/bf-p4c/phv/v2/greedy_tx_score.h" -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "gtest/gtest.h" namespace P4::Test { diff --git a/backends/tofino/bf-p4c/test/gtest/phv/slicing/iterator.cpp b/backends/tofino/bf-p4c/test/gtest/phv/slicing/iterator.cpp index 4077fe4728..4cb5eab23a 100644 --- a/backends/tofino/bf-p4c/test/gtest/phv/slicing/iterator.cpp +++ b/backends/tofino/bf-p4c/test/gtest/phv/slicing/iterator.cpp @@ -18,8 +18,8 @@ #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h" #include "gtest/gtest.h" #include "lib/bitvec.h" diff --git a/backends/tofino/bf-p4c/test/gtest/phv_crush.cpp b/backends/tofino/bf-p4c/test/gtest/phv_crush.cpp index 26a804ae04..fadf81281f 100644 --- a/backends/tofino/bf-p4c/test/gtest/phv_crush.cpp +++ b/backends/tofino/bf-p4c/test/gtest/phv_crush.cpp @@ -18,11 +18,11 @@ #include -#include "backends/tofino/bf-p4c/device.h" -#include "backends/tofino/bf-p4c/ir/gress.h" #include "backends/tofino/bf-p4c/phv/allocate_phv.h" #include "backends/tofino/bf-p4c/phv/slicing/phv_slicing_split.h" #include "backends/tofino/bf-p4c/phv/utils/utils.h" +#include "backends/tofino/bf-p4c/specs/device.h" +#include "backends/tofino/bf-p4c/specs/gress.h" #include "backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h" #include "gtest/gtest.h" #include "lib/bitvec.h" diff --git a/backends/tofino/bf-p4c/test/gtest/phv_field.cpp b/backends/tofino/bf-p4c/test/gtest/phv_field.cpp index 0cbb1ea837..bd0e322bcc 100644 --- a/backends/tofino/bf-p4c/test/gtest/phv_field.cpp +++ b/backends/tofino/bf-p4c/test/gtest/phv_field.cpp @@ -18,9 +18,9 @@ #include -#include "backends/tofino/bf-p4c/device.h" #include "backends/tofino/bf-p4c/ir/bitrange.h" #include "backends/tofino/bf-p4c/phv/phv_fields.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h" #include "gtest/gtest.h" #include "lib/bitvec.h" diff --git a/backends/tofino/bf-p4c/test/gtest/phv_jbay.cpp b/backends/tofino/bf-p4c/test/gtest/phv_jbay.cpp index 5470c0c913..ab0ee3630c 100644 --- a/backends/tofino/bf-p4c/test/gtest/phv_jbay.cpp +++ b/backends/tofino/bf-p4c/test/gtest/phv_jbay.cpp @@ -19,7 +19,7 @@ #include #include -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "gtest/gtest.h" #include "ir/ir.h" #include "ir/json_loader.h" diff --git a/backends/tofino/bf-p4c/test/gtest/phv_tofino.cpp b/backends/tofino/bf-p4c/test/gtest/phv_tofino.cpp index 270f126f86..896bc0a71a 100644 --- a/backends/tofino/bf-p4c/test/gtest/phv_tofino.cpp +++ b/backends/tofino/bf-p4c/test/gtest/phv_tofino.cpp @@ -19,7 +19,7 @@ #include #include -#include "backends/tofino/bf-p4c/phv/phv.h" +#include "backends/tofino/bf-p4c/specs/phv.h" #include "gtest/gtest.h" #include "ir/ir.h" #include "ir/json_loader.h" diff --git a/backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h b/backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h index 1075f040ca..2b209a574b 100644 --- a/backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h +++ b/backends/tofino/bf-p4c/test/gtest/tofino_gtest_utils.h @@ -24,7 +24,7 @@ #include "backends/tofino/bf-p4c/arch/arch.h" #include "backends/tofino/bf-p4c/bf-p4c-options.h" -#include "backends/tofino/bf-p4c/device.h" +#include "backends/tofino/bf-p4c/specs/device.h" #include "gtest/gtest.h" #include "lib/compile_context.h" @@ -80,13 +80,21 @@ class BackendTest : public ::testing::Test { /// A GTest fixture for Tofino tests. class TofinoBackendTest : public BackendTest { public: - TofinoBackendTest() { Device::init("Tofino"_cs); } + TofinoBackendTest() { + auto &options = BackendOptions(); + Device::init("Tofino"_cs, + {options.phv_scale_factor, options.no_tagalong, options.tof2lab44_workaround}); + } }; /// A GTest fixture for JBay tests. class JBayBackendTest : public BackendTest { public: - JBayBackendTest() { Device::init("Tofino2"_cs); } + JBayBackendTest() { + auto &options = BackendOptions(); + Device::init("Tofino2"_cs, + {options.phv_scale_factor, options.no_tagalong, options.tof2lab44_workaround}); + } }; } // namespace P4::Test diff --git a/backends/tofino/bf-utils/src/dynamic_hash/bfn_hash_algorithm.c b/backends/tofino/bf-utils/src/dynamic_hash/bfn_hash_algorithm.c deleted file mode 100644 index 4207819a3d..0000000000 --- a/backends/tofino/bf-utils/src/dynamic_hash/bfn_hash_algorithm.c +++ /dev/null @@ -1,281 +0,0 @@ -#include "backends/tofino/bf-utils/include/dynamic_hash/bfn_hash_algorithm.h" - -#include -#include -#include -#include -#include - -/** - * These values are based on the crc calculations provided at this url: - * http://reveng.sourceforge.net/crc-catalogue/all.htm - * - * It is understood that the top bit of the the polynomial is known to be == 1, - * but any polynomial over 64 bits would not fit. Thus the strings do not have - * this value - */ -static crc_alg_info_t standard_crc_algs[CRC_INVALID] = { - {"crc_8", 0x07, false, 0, 0}, - {"crc_8_darc", 0x39, true, 0, 0}, - {"crc_8_i_code", 0x1d, false, 0xfd, 0}, - {"crc_8_itu", 0x07, false, 0x55, 0x55}, - {"crc_8_maxim", 0x31, true, 0, 0}, - {"crc_8_rohc", 0x07, true, 0xff, 0}, - {"crc_8_wcdma", 0x9b, true, 0, 0}, - {"crc_16", 0x8005, true, 0, 0}, - {"crc_16_bypass", 0x8005, false, 0, 0}, - {"crc_16_dds_110", 0x8005, false, 0x800d, 0}, - // This one doesn't appear on the website, but kept to not break - // regressions - {"crc_16_dect", 0x0589, false, 1, 1}, - {"crc_16_dect_r", 0x0589, false, 0, 1}, - {"crc_16_dect_x", 0x0589, false, 0, 0}, - {"crc_16_dnp", 0x3d65, true, 0, 0xffff}, - {"crc_16_en_13757", 0x3d65, false, 0, 0xffff}, - {"crc_16_genibus", 0x1021, false, 0xffff, 0xffff}, - {"crc_16_maxim", 0x8005, true, 0, 0xffff}, - {"crc_16_mcrf4xx", 0x1021, true, 0xffff, 0}, - {"crc_16_riello", 0x1021, true, 0xb2aa, 0}, - {"crc_16_t10_dif", 0x8bb7, false, 0, 0}, - {"crc_16_teledisk", 0xa097, false, 0, 0}, - {"crc_16_usb", 0x8005, true, 0xffff, 0xffff}, - {"x_25", 0x1021, true, 0xffff, 0xffff}, - {"xmodem", 0x1021, false, 0, 0}, - {"modbus", 0x8005, true, 0xffff, 0}, - {"kermit", 0x1021, true, 0, 0}, - {"crc_ccitt_false", 0x1021, false, 0xffff, 0}, - {"crc_aug_ccitt", 0x1021, false, 0x1d0f, 0}, - {"crc_32", 0x04c11db7, true, 0xffffffff, 0xffffffff}, - {"crc_32_bzip2", 0x04c11db7, false, 0xffffffff, 0xffffffff}, - {"crc_32c", 0x1edc6f41, true, 0xffffffff, 0xffffffff}, - {"crc_32d", 0xa833982b, true, 0xffffffff, 0xffffffff}, - {"crc_32_mpeg", 0x04c11db7, false, 0xffffffff, 0}, - {"posix", 0x04c11db7, false, 0, 0xffffffff}, - {"crc_32q", 0x814141ab, false, 0, 0}, - {"jamcrc", 0x04c11db7, true, 0xffffffff, 0}, - {"xfer", 0x000000af, false, 0, 0}, - {"crc_64", 0x42f0e1eba9ea3693, false, 0, 0}, - {"crc_64_go_iso", 0x000000000000001b, true, 0xffffffffffffffff, 0xffffffffffffffff}, - {"crc_64_we", 0x42f0e1eba9ea3693, false, 0xffffffffffffffff, 0xffffffffffffffff}, - // This one doesn't appear on the website, but kept to not break - // regressions - {"crc_64_jones", 0xad93d23594c935a9, true, 0xffffffffffffffff, 0}}; - -int determine_msb(uint64_t value) { - int rv = -1; -#if defined(__GNUC__) || defined(__clang__) - if (value) rv = 63 - __builtin_clzl(value); -#else - for (int i = 63; i >= 0; i--) { - if (((1ULL << i) & value) != 0ULL) return i; - } -#endif - return rv; -} - -#define BUILD_CRC_ERRORS - -static char *bfn_crc_errors[BUILD_CRC_ERRORS] = { - "Polynomial is not odd", - "Init value is larger than the polynomial", - "Final xor value is larger than the polynomial", -}; - -bool verify_algorithm(bfn_hash_algorithm_t *alg, char **error_message) { - if ((alg->poly & 1) == 0) { - if (error_message) *error_message = bfn_crc_errors[0]; - return false; - } - if (alg->init && determine_msb(alg->init) + 1 > alg->hash_bit_width) { - if (error_message) *error_message = bfn_crc_errors[1]; - return false; - } - if (alg->final_xor && determine_msb(alg->final_xor) + 1 > alg->hash_bit_width) { - if (error_message) *error_message = bfn_crc_errors[2]; - return false; - } - return true; -} - -/** - * Builds the algorithm from the standard crc algorithm position - */ -void build_standard_crc_algorithm(bfn_hash_algorithm_t *alg, bfn_crc_alg_t crc_alg) { - if (crc_alg >= CRC_8 && crc_alg <= CRC_8_WCDMA) - alg->hash_bit_width = 8; - else if (crc_alg >= CRC_16 && crc_alg <= CRC_AUG_CCITT) - alg->hash_bit_width = 16; - else if (crc_alg >= CRC_32 && crc_alg <= XFER) - alg->hash_bit_width = 32; - else if (crc_alg >= CRC_64 && crc_alg <= CRC_64_JONES) - alg->hash_bit_width = 64; - - crc_alg_info_t crc_alg_info = standard_crc_algs[(int)crc_alg]; - alg->poly = crc_alg_info.poly; - alg->reverse = crc_alg_info.reverse; - alg->init = crc_alg_info.init; - alg->final_xor = crc_alg_info.final_xor; - alg->crc_type = crc_alg_str_to_type(crc_alg_info.crc_name); -} - -void initialize_algorithm(bfn_hash_algorithm_t *alg, bfn_hash_alg_type_t hash_alg, bool msb, - bool extend, bfn_crc_alg_t crc_alg) { - alg->hash_alg = hash_alg; - alg->msb = msb; - alg->extend = extend; - if (crc_alg != CRC_INVALID) build_standard_crc_algorithm(alg, crc_alg); -} - -static uint64_t invert_poly(uint64_t poly, int bit_width) { - uint64_t ret = 0, i = 0; - while (poly > 0) { - ret |= ((poly & 0x1) << (bit_width - i - 1)); - i++; - poly >>= 1; - } - return ret; -} - -static void construct_stream(bfn_hash_algorithm_t *alg, uint64_t val, uint8_t *stream) { - uint8_t width = (alg->hash_bit_width + 7) / 8; - for (uint8_t i = 0; i < width; i++) { - stream[width - i - 1] = (val >> (i * 8)); - } - return; -} - -static void shift_right(uint8_t *stream, uint8_t bit_width) { - uint8_t width = (bit_width + 7) / 8; - for (int i = width - 1; i >= 0; i--) { - stream[i] >>= 1; - if (i > 0) { - stream[i] |= (stream[i - 1] & 0x1) << 7; - } - } -} - -static void shift_left(uint8_t *stream, uint8_t bit_width) { - uint8_t width = (bit_width + 7) / 8; - for (uint8_t i = 0; i < width; i++) { - stream[i] <<= 1; - if (i < width - 1) { - stream[i] |= (stream[i + 1] >> 7) & 0x1; - } - } -} - -void initialize_crc_matrix(bfn_hash_algorithm_t *alg) { - if (alg->hash_alg != CRC_DYN) { - return; - } - - uint32_t width = (alg->hash_bit_width + 7) / 8, i = 0; - uint8_t poly[width], rem[width]; - memset(poly, 0, width * sizeof(uint8_t)); - memset(rem, 0, width * sizeof(uint8_t)); - - uint64_t poly_val = alg->poly; - if (alg->reverse) { - poly_val = invert_poly(poly_val, alg->hash_bit_width); - } - construct_stream(alg, poly_val, poly); - uint32_t byte = 0, bit = 0; - bool xor = false; - if (alg->reverse) { - for (byte = 0; byte < 256; byte++) { - memset(rem, 0, width * sizeof(uint8_t)); - rem[width - 1] = byte; - for (bit = 0; bit < 8; bit++) { - xor = rem[width - 1] & 0x1; - shift_right(rem, alg->hash_bit_width); - if (xor) { - for (i = 0; i < width; i++) { - rem[i] ^= poly[i]; - } - } - } - memcpy(alg->crc_matrix[byte], rem, width); - } - } else { - uint8_t offset = alg->hash_bit_width % 8; - uint8_t top_bit = offset == 0 ? 0x80 : 1 << ((offset - 1) % 8); - uint8_t top_mask = top_bit == 0x80 ? 0xff : (top_bit << 1) - 1; - for (byte = 0; byte < 256; byte++) { - memset(rem, 0, width * sizeof(uint8_t)); - if (offset == 0) { - rem[0] = byte; - } else { - rem[0] = byte >> (8 - offset); - rem[1] = byte << offset; - } - for (bit = 0; bit < 8; bit++) { - xor = rem[0] & top_bit; - shift_left(rem, alg->hash_bit_width); - if (xor) { - for (i = 0; i < width; i++) { - rem[i] ^= poly[i]; - } - } - rem[0] &= top_mask; - } - memcpy(alg->crc_matrix[byte], rem, width); - } - } - - return; -} - -static uint8_t get_byte(uint8_t *stream, uint8_t index, uint8_t offset) { - if (offset == 0) { - return stream[index]; - } - return ((stream[index] << (8 - offset)) | (stream[index + 1] >> offset)); -} - -void calculate_crc(bfn_hash_algorithm_t *alg, uint32_t hash_output_bits, uint8_t *stream, - uint32_t stream_len, uint8_t *crc) { - uint32_t i = 0; - uint8_t idx = 0; - uint8_t width = (alg->hash_bit_width + 7) / 8; - uint8_t hash_output_bytes = (hash_output_bits + 7) / 8; - uint8_t final_xor[width]; - memset(crc, 0, hash_output_bytes * sizeof(uint8_t)); - memset(final_xor, 0, width * sizeof(uint8_t)); - construct_stream(alg, alg->init, crc); - construct_stream(alg, alg->final_xor, final_xor); - uint8_t *crc_str = crc + hash_output_bytes - width; - - for (i = 0; i < stream_len; i++) { - if (alg->reverse) { - idx = crc_str[width - 1] ^ stream[i]; - for (int j = width - 1; j > 0; j--) { - crc_str[j] = crc_str[j - 1] ^ alg->crc_matrix[idx][j]; - } - crc_str[0] = alg->crc_matrix[idx][0]; - } else { - uint8_t offset = alg->hash_bit_width % 8; - uint8_t mask = offset == 0 ? 0xff : (1 << offset) - 1; - idx = get_byte(crc_str, 0, offset) ^ stream[i]; - for (uint8_t j = 0; j < width - 1; j++) { - crc_str[j] = (crc_str[j + 1] ^ alg->crc_matrix[idx][j]) & mask; - mask = 0xff; - } - crc_str[width - 1] = alg->crc_matrix[idx][width - 1]; - } - } - - for (i = 0; i < width; i++) { - crc_str[i] ^= final_xor[i]; - } - - if (alg->extend) { - for (i = 0; i < (uint32_t)(hash_output_bytes - width); i++) { - *(crc_str - i - 1) = crc_str[width - i % width - 1]; - } - if (hash_output_bits % 8) { - crc[0] &= (1 << (hash_output_bits % 8)) - 1; - } - } - - return; -} diff --git a/backends/tofino/bf-utils/src/dynamic_hash/bfn_hash_algorithm.cpp b/backends/tofino/bf-utils/src/dynamic_hash/bfn_hash_algorithm.cpp index 2439b2c540..78560870d6 100644 --- a/backends/tofino/bf-utils/src/dynamic_hash/bfn_hash_algorithm.cpp +++ b/backends/tofino/bf-utils/src/dynamic_hash/bfn_hash_algorithm.cpp @@ -6,6 +6,8 @@ #include #include +#include + /** * These values are based on the crc calculations provided at this url: * http://reveng.sourceforge.net/crc-catalogue/all.htm diff --git a/backends/tofino/bf-utils/src/dynamic_hash/dynamic_hash.c b/backends/tofino/bf-utils/src/dynamic_hash/dynamic_hash.c deleted file mode 100644 index 5f76c8ea72..0000000000 --- a/backends/tofino/bf-utils/src/dynamic_hash/dynamic_hash.c +++ /dev/null @@ -1,831 +0,0 @@ -#include "backends/tofino/bf-utils/include/dynamic_hash/dynamic_hash.h" - -#include -#include -#include -#include -#include -#include - -#define assert_macro assert -#define calloc_macro calloc -#define free_macro free - -#define ALLOC_CHECK(ptr, str) \ - do { \ - if (ptr == NULL) { \ - printf("%s\n", str); \ - assert_macro(0); \ - return; \ - } \ - } while (0) - -bool determine_identity_gfm(uint32_t input_bit, uint32_t p4_hash_output_bit) { - return input_bit == p4_hash_output_bit; -} - -bool determine_random_gfm() { return random() & 1; } - -static bool determine_xor_gfm(uint32_t input_bit, uint32_t p4_hash_output_bit, uint32_t width, - uint32_t total_input_bits) { - /* -- The message (input registers) is handled as a big integer - the - * highest bit of the integer is the beginning of the message. Zero-th - * bit is the end of the message. If the message is not aligned with - * the algorithm's width, zero bits must be appended after the end - * of the message - that's the reason of shifting the input bit - * by total_input_bits. */ - return (p4_hash_output_bit < width) && - ((input_bit + width * width - total_input_bits) % width) == p4_hash_output_bit; -} - -/** - * The point of this funciton is to get up to a 64 bit value from the - * bitvector. - * - * This is potientially broken up into two separate lookups, if the boundary - * of the write crosses a 64 bit section. The bitvec is an array of 64 bit - * values. Thus if the algorithm wanted to get a 16 bit value at position - * 56, the value returned would be the upper 8 bits of bitvec[0] starting at - * bit 0, ORed with the lower 8 bits of bitvec[1] starting at bit 8. - * - * The lower_* values in the previous example would deal with any reads - * to bitvec[0], while all upper_* values deal with any reads to bitvec[1] - */ -uint64_t get_from_bitvec(const uint64_t *val, uint32_t bitvec_sz, uint32_t start_bit, - uint32_t size) { - uint64_t current_value = 0ULL; - uint32_t mod_pos = start_bit % 64; - uint32_t bitvec_pos = start_bit / 64; - uint64_t upper_mask = (1ULL << mod_pos) - 1; - uint64_t lower_mask = ULLONG_MAX & ~upper_mask; - - uint64_t upper_value = 0ULL; - if (mod_pos && bitvec_pos + 1 < bitvec_sz) { - upper_value = upper_mask & *(val + bitvec_pos + 1); - upper_value <<= 64 - mod_pos; - } - - uint64_t lower_value = lower_mask & *(val + bitvec_pos); - lower_value >>= mod_pos; - current_value = lower_value | upper_value; - - uint64_t mask = 0ULL; - if (size >= 64ULL) { - mask = ULLONG_MAX; - } else { - mask = (1ULL << size) - 1; - } - - return current_value & mask; -} - -/** - * The point of this function is to write up to a 64 bit value into a position - * of the bitvector. - * - * This is potentially broken up into two separate assignment, if the boundary - * of the write crosses a 64 bit section. The bitvec is an array of 64 bit - * values. Thus if the algorithm wanted to write a 16 bit value into the - * bitvec at position 56, bitvec[0] upper 8 bits would be written and - * bitvec[1] lower 8 bits would be written. - * - * The lower_* values in the previous example would deal with any writes - * to bitvec[0], while all upper_* values deal with any writes to bitvec[1] - */ -void set_into_bitvec(uint64_t *val, uint32_t bitvec_sz, uint64_t current_value, uint32_t start_bit, - uint32_t size) { - uint64_t mask = 0ULL; - if (size >= 64ULL) { - mask = ULLONG_MAX; - } else { - mask = (1ULL << size) - 1; - } - uint32_t mod_pos = start_bit % 64; - uint32_t bitvec_pos = start_bit / 64; - - // Bits of the current_value headed to the lower bitvec position - uint64_t lower_mask = ULLONG_MAX; - if (mod_pos != 0) lower_mask = (1ULL << (64 - mod_pos)) - 1; - // Bits of the current_value headed to the upper bitvec position - uint64_t upper_mask = ULLONG_MAX & ~lower_mask; - uint64_t upper_value = upper_mask & current_value & mask; - if (mod_pos) - upper_value >>= 64 - mod_pos; - else - upper_value = 0; - - // Bits of the upper bitvecs that will be written into - uint64_t upper_set_mask = ULLONG_MAX; - if (mod_pos != 0) upper_set_mask = ~(mask >> (64 - mod_pos)) & ULLONG_MAX; - - uint64_t lower_value = lower_mask & current_value & mask; - lower_value <<= mod_pos; - // Bits of the lower bitvecs that will be written into - uint64_t lower_set_mask = ~(mask << mod_pos) & ULLONG_MAX; - - if (bitvec_pos + 1 < bitvec_sz) { - *(val + bitvec_pos + 1) = upper_value | (upper_set_mask & *(val + bitvec_pos + 1)); - } - *(val + bitvec_pos) = lower_value | (lower_set_mask & *(val + bitvec_pos)); -} - -uint32_t compute_bitvec_sz(const bfn_hash_algorithm_t *alg, uint32_t total_input_bits) { - uint32_t total_msb = (((total_input_bits - 1) + 7) / 8) * 8; - if (alg->hash_alg == CRC_DYN) total_msb += alg->hash_bit_width; - return (total_msb + 63) / 64; -} - -/** - * The constants from the hash field inputs need to be correctly added to - * the initial bit vector. This function writes these constants into - * the bit vector at the correct location. - * - * The purpose of this library is to determine each relevant hash matrix bit - * which has a corresponding input and output bit. All input bits correspond - * to a PHV bit, as that is the input to the hash matrix. For constant inputs, - * these constants have no single input xbar bit, and thus have no single row - * in the hash matrix that they coordinate to. However, in order to calculate - * each individual row's matrix, the constants must be included in every - * calculation of that data. - */ -void initialize_input_data_stream(const bfn_hash_algorithm_t *alg, uint64_t *val, - uint32_t bitvec_sz, const ixbar_input_t *inputs, - uint32_t inputs_sz) { - int start_bit = 0; - if (alg->hash_alg == CRC_DYN) start_bit += alg->hash_bit_width; - for (uint32_t i = 0; i < inputs_sz; i++) { - const ixbar_input_t *input = inputs + i; - if (input->type == tCONST) { - // For reverse algorithms, the inputs are byte reversed. This is - // true for any constant input as well. - if (alg->hash_alg == CRC_DYN && alg->reverse) { - for (uint32_t j = 0; j < input->bit_size; j++) { - uint32_t val_bit_pos = start_bit + j; - val_bit_pos -= alg->hash_bit_width; - val_bit_pos ^= 7; - val_bit_pos += alg->hash_bit_width; - uint64_t val_bit_val = (input->u.constant >> j) & 1ULL; - set_into_bitvec(val, bitvec_sz, val_bit_val, val_bit_pos, 1); - } - - // All other algorithms have the constants in order, so we add them - // in order - } else { - uint32_t val_bit_pos = start_bit; - uint32_t val_bit_len = input->bit_size; - uint64_t val_bit_val = input->u.constant; - set_into_bitvec(val, bitvec_sz, val_bit_val, val_bit_pos, val_bit_len); - } - } - start_bit += input->bit_size; - } -} - -/** - * The matrix position i, j where: - * - * i - the input bit of the data stream - * j - the output bit of the hash function - * - * will be equal to whether: - * (1 << output_bit) & crc(alg, data_stream)) == (1 << output), - * - * where the data stream is an all 0 bitstream except for a single bit at the - * input_bit position. - * - * The output of the crc is the remainder of a polynomial division modulo two - * of a data stream with a polynomial. From msb to lsb, the polynomial is - * XORed with the value in the data stream until each bit in the data stream - * has been XORed. The general details of the CRC algorithm are publicly - * available. - * - * The bfn_hash_algorithm_t holds certain parameters that impact the crc - * calculation: - * - * poly - The polynomial to XOR with the data stream. Currently assumed - * that the upper bit is always 1, and is not stored directly in the - * polynomial. This is done to hold all possible polynomials for a - * 64 bit crc. - * init - The initial value of the crc. THIS IS XORed with the first - * portion of the data stream. (Note: not appended to the msb of the - * data stream) - * reverse - This indicates two values. First, the byte ordering, remains - * the same, but each byte of the crc is msb to lsb, rather than the - * standard lsb to msb. Secondly, the output of the crc is - * bit-reversed as well. - * final_xor - This is a value that is XORed at the end of the calculation. - * This doesn't apply to the hash_matrix, but the seed, as isn't - * necessary for this function - * - * In order to fully convert this to a Galois Matrix, a couple extra steps - * are required. If the crc has an init value, then the all 0 input to the - * matrix will have a non all 0 result before the final xor. However, in - * a matrix multiplication, no matter what, the all zero input will be an all - * zero output. - * - * Thus in order to capture the all 0 input, the seed register per hash - * function must represent the result of the all 0 input of the crc function, - * as it must capture this init value. This seed value must then be xored - * out of each matrix row calculation - */ -bool determine_crc_gfm(const bfn_hash_algorithm_t *alg, uint64_t *init_data, uint32_t bitvec_sz, - uint32_t input_bit, bool use_input_bit, uint32_t p4_hash_output_bit, - uint32_t total_input_bits) { - // The input stream is 0 extended to the byte. Always start with highest - // bit, as constants could be included in the calculation - uint32_t total_msb = alg->hash_bit_width - 1; - total_msb += ((total_input_bits + 7) / 8) * 8; - - uint32_t val_bit = input_bit; - // Reverse the input bytes - if (alg->reverse) { - val_bit ^= 7; - } - - // This is the data stream, and is saved as a bit vector - uint64_t val[bitvec_sz]; - memset(val, 0, sizeof(val)); - for (uint32_t i = 0; i < bitvec_sz; i++) val[i] = init_data[i]; - - if (use_input_bit) { - int val_bit_pos = val_bit + alg->hash_bit_width; - set_into_bitvec(val, bitvec_sz, 1ULL, val_bit_pos, 1); - } - - ///> XOR the initial value into the data stream - if (alg->init != 0ULL) { - int init_lsb = total_msb - (alg->hash_bit_width - 1); - uint64_t current_value = get_from_bitvec(val, bitvec_sz, init_lsb, alg->hash_bit_width); - current_value ^= alg->init; - set_into_bitvec(val, bitvec_sz, current_value, init_lsb, alg->hash_bit_width); - } - - ///> Calculate crc at each bit position - for (int i = total_msb - alg->hash_bit_width; i >= 0; i--) { - int upper_bit_position = (i + alg->hash_bit_width); - uint64_t upper_value = get_from_bitvec(val, bitvec_sz, upper_bit_position, 1); - upper_value &= 1ULL; - if (upper_value == 1ULL) { - set_into_bitvec(val, bitvec_sz, 0ULL, upper_bit_position, 1); - uint64_t current_value = get_from_bitvec(val, bitvec_sz, i, alg->hash_bit_width); - current_value ^= alg->poly; - set_into_bitvec(val, bitvec_sz, current_value, i, alg->hash_bit_width); - } - } - - ///> Xor the final xor - uint64_t hash_calc = get_from_bitvec(val, bitvec_sz, 0, alg->hash_bit_width) ^ alg->final_xor; - - ///> Reverse the output bits - uint64_t mask = (1ULL << p4_hash_output_bit); - if (alg->reverse) { - mask = (1ULL << ((alg->hash_bit_width - 1) - p4_hash_output_bit)); - } - - return (mask & hash_calc) != 0ULL; -} - -bool get_matrix_bit(hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN], - uint32_t ixbar_input_bit, uint32_t galois_bit) { - uint32_t matrix_index0 = ixbar_input_bit / 64; - uint32_t matrix_index1 = galois_bit; - - uint32_t bit_offset = ixbar_input_bit % 64; - return (hash_matrix[matrix_index0][matrix_index1].column_value & (1ULL << bit_offset)) != 0ULL; -} - -void initialize_matrix_bit(hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN], - uint32_t ixbar_input_bit, uint32_t galois_bit, bool set_bit) { - uint32_t matrix_index0 = ixbar_input_bit / 64; - uint32_t matrix_index1 = galois_bit; - - uint32_t bit_offset = ixbar_input_bit % 64; - uint32_t byte_offset = bit_offset / 8; - if (set_bit) hash_matrix[matrix_index0][matrix_index1].column_value |= (1ULL << bit_offset); - hash_matrix[matrix_index0][matrix_index1].byte_used |= (1ULL << byte_offset); -} - -/** - * The purpose of this function is to determine the bit for hash matrix - * position input_bit x output_bit is set to 1 or 0. The parameters - * for the function are the following: - * - * Note that the hash_matrix[ixbar_input_bit][galois_bit] is always the - * bit which is modified. So it doesn't depend upon the logical input_bit - * or logical p4_hash_output_bit. The content of this bit, however, - * depends upon the logical input/output. - * - * ixbar_input_bit - The bit on the 1024 bit input xbar array. - * input_bit - the logical input bit on the total list of field bits. - * total_input_bits - the size of the input stream for the hash - * calculation. This is required for crc algorithms. - * p4_hash_output_bit - The logical hash bit output - * galois_bit - the output bit of the 52 bits hash calculation - * total_output_bits - the total size of the hash calculation. Required - * for msb/extensions of hash calculations. - */ -void determine_matrix_bit(hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN], - const bfn_hash_algorithm_t *alg, const ixbar_input_t *inputs, - uint32_t inputs_sz, uint32_t ixbar_input_bit, uint32_t input_bit, - uint32_t total_input_bits, uint32_t p4_hash_output_bit, - uint32_t galois_bit) { - bool set_bit = false; - - uint32_t virtual_p4_hash_output_bit = p4_hash_output_bit; - if (alg->extend) { - virtual_p4_hash_output_bit = virtual_p4_hash_output_bit % alg->hash_bit_width; - } - - ///> Initialize the input bitvec with the constant inputs - if (alg->hash_alg == IDENTITY_DYN) { - set_bit = determine_identity_gfm(input_bit, virtual_p4_hash_output_bit); - } else if (alg->hash_alg == RANDOM_DYN) { - set_bit = determine_random_gfm(); - } else if (alg->hash_alg == XOR_DYN) { - set_bit = determine_xor_gfm(input_bit, virtual_p4_hash_output_bit, alg->hash_bit_width, - total_input_bits); - } else if (alg->hash_alg == CRC_DYN) { - uint32_t bitvec_sz = compute_bitvec_sz(alg, total_input_bits); - uint64_t val[bitvec_sz]; - memset(val, 0, sizeof(val)); - initialize_input_data_stream(alg, val, bitvec_sz, inputs, inputs_sz); - // See comments above the dete - set_bit = determine_crc_gfm(alg, val, bitvec_sz, input_bit, true, - virtual_p4_hash_output_bit, total_input_bits) ^ - determine_crc_gfm(alg, val, bitvec_sz, 0, /* input_bit */ - false, virtual_p4_hash_output_bit, total_input_bits); - } - - initialize_matrix_bit(hash_matrix, ixbar_input_bit, galois_bit, set_bit); -} - -/** - * This function is used to determine the seed. For CRC functions, this - * coordinates to the all 0 input result as described in the determine_crc_gfm - * comments. For random functions, this will provide a random number as - * the seed. - */ -void determine_seed_bit(hash_seed_t *hash_seed, uint64_t *init_data, /* bit vec */ - uint32_t init_data_sz, const bfn_hash_algorithm_t *alg, - uint32_t p4_hash_output_bit, uint32_t total_input_bits, - uint32_t galois_bit) { - bool set_bit = false; - if (alg->hash_alg == RANDOM_DYN) { - set_bit = random() & 1; - } else if (alg->hash_alg == CRC_DYN && total_input_bits != 0) { - if (alg->extend) { - p4_hash_output_bit = p4_hash_output_bit % alg->hash_bit_width; - } - set_bit = determine_crc_gfm(alg, init_data, init_data_sz, 0, false, p4_hash_output_bit, - total_input_bits); - } else if (alg->hash_alg == IDENTITY_DYN) { - set_bit = get_from_bitvec(init_data, init_data_sz, p4_hash_output_bit, 1) == 1ULL; - } else if (alg->hash_alg == XOR_DYN) { - if (p4_hash_output_bit < ((uint32_t)alg->hash_bit_width)) { - uint64_t acc = 0; - int32_t i = - p4_hash_output_bit - alg->hash_bit_width + total_input_bits % alg->hash_bit_width; - if (i < 0) i += alg->hash_bit_width; - for (; i < ((int32_t)total_input_bits); i += alg->hash_bit_width) { - acc ^= get_from_bitvec(init_data, init_data_sz, i, 1); - } - set_bit = acc == 1ULL; - } else { - set_bit = false; - } - } - hash_seed->hash_seed_used |= (1ULL << galois_bit); - - if (set_bit) hash_seed->hash_seed_value |= (1ULL << galois_bit); -} - -void print_hash_matrix(hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]) { - printf("Hash matrix ---> \n"); - uint32_t n_nibbles = 16; - for (uint32_t i = 0; i < PARITY_GROUPS_DYN; i++) { - for (uint32_t j = 0; j < n_nibbles; j++) { - for (uint32_t k = 0; k < HASH_MATRIX_WIDTH_DYN; k++) { - printf("%" PRIx64 " ", ((hash_matrix[i][k].column_value >> (j * 4)) & 0xf)); - } - printf("\n"); - } - } -} - -void print_hash_matrix_used(hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]) { - printf("Hash matrix Used bytes ---> \n"); - for (uint32_t i = 0; i < PARITY_GROUPS_DYN; i++) { - for (uint32_t j = 0; j < HASH_MATRIX_WIDTH_DYN; j++) { - printf("%x ", hash_matrix[i][j].byte_used); - } - printf("\n"); - } -} - -static void rotate_seed(hash_calc_rotate_info_t *rot_info, hash_seed_t *hash_seed) { - uint32_t bit_posn = 0, idx = 0; - bool hash_seed_value[HASH_SEED_LENGTH] = {0}; - bool hash_seed_used[HASH_SEED_LENGTH] = {0}; - bool rotate_temp_value[HASH_SEED_LENGTH] = {0}; - bool rotate_temp_used[HASH_SEED_LENGTH] = {0}; - uint64_t rotate = rot_info->rotate; - uint32_t num_tot_hash_bits = rot_info->num_hash_bits; - /* Dissect into an array */ - while (bit_posn < num_tot_hash_bits) { - idx = rot_info->p4_hash_output_bit_posn[bit_posn]; - hash_seed_value[idx] = hash_seed->hash_seed_value & (1ULL << idx); - hash_seed_used[idx] = hash_seed->hash_seed_used & (1ULL << idx); - bit_posn++; - } - - /* Safeguard the rotated bits. */ - bit_posn = 0; - while (bit_posn < rotate) { - idx = rot_info->p4_hash_output_bit_posn[(num_tot_hash_bits - 1) - (rotate - 1) + bit_posn]; - rotate_temp_value[bit_posn] = hash_seed_value[idx]; - rotate_temp_used[bit_posn] = hash_seed_used[idx]; - bit_posn++; - } - - /* Right shift as per rotation. */ - for (int rot_idx = num_tot_hash_bits - (rotate + 1); rot_idx >= 0; rot_idx--) { - idx = rot_info->p4_hash_output_bit_posn[rot_idx]; - hash_seed_value[(idx + rotate) % HASH_SEED_LENGTH] = hash_seed_value[idx]; - hash_seed_used[(idx + rotate) % HASH_SEED_LENGTH] = hash_seed_used[idx]; - } - - /* Get rotated bits to position. */ - for (bit_posn = 0; bit_posn < rotate; bit_posn++) { - idx = rot_info->p4_hash_output_bit_posn[bit_posn]; - hash_seed_value[idx] = rotate_temp_value[bit_posn]; - hash_seed_used[idx] = rotate_temp_used[bit_posn]; - } - bit_posn = 0; - /* Reform the seed. */ - while (bit_posn < num_tot_hash_bits) { - idx = rot_info->p4_hash_output_bit_posn[bit_posn]; - /* Reset the original bit posn value. */ - hash_seed->hash_seed_value &= ~(1ULL << idx); - hash_seed->hash_seed_used &= ~(1ULL << idx); - if (hash_seed_value[idx]) { - hash_seed->hash_seed_value |= (1ULL << idx); - } - if (hash_seed_used[idx]) { - hash_seed->hash_seed_used |= (1ULL << idx); - } - bit_posn++; - } -} - -static void rotate_matrix(hash_calc_rotate_info_t *rot_info, - hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]) { - uint32_t p4_hash_bit_idx = 0, idx = 0; - hash_column_t temp_col[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]; - uint64_t rotate = rot_info->rotate; - uint32_t num_tot_hash_bits = rot_info->num_hash_bits; - /* Safeguard the rotated coloumn. */ - for (uint32_t i = 0; i < rotate; i++) { - for (uint32_t k = 0; k < PARITY_GROUPS_DYN; k++) { - p4_hash_bit_idx = - rot_info->p4_hash_output_bit_posn[(num_tot_hash_bits - 1) - (rotate - 1) + i]; - idx = rot_info->gfm_bit_posn[p4_hash_bit_idx]; - temp_col[k][i].column_value = hash_matrix[k][idx].column_value; - temp_col[k][i].byte_used = hash_matrix[k][idx].byte_used; - } - } - - /* Right shift as per rotation. */ - for (int i = num_tot_hash_bits - (rotate + 1); i >= 0; i--) { - for (uint32_t k = 0; k < PARITY_GROUPS_DYN; k++) { - p4_hash_bit_idx = rot_info->p4_hash_output_bit_posn[i]; - idx = rot_info->gfm_bit_posn[p4_hash_bit_idx]; - hash_matrix[k][(idx + rotate) % num_tot_hash_bits].column_value = - hash_matrix[k][idx].column_value; - hash_matrix[k][(idx + rotate) % num_tot_hash_bits].byte_used = - hash_matrix[k][idx].byte_used; - } - } - - /* Get rotated bits to position. */ - for (uint32_t i = 0; i < rotate; i++) { - for (uint32_t k = 0; k < PARITY_GROUPS_DYN; k++) { - p4_hash_bit_idx = rot_info->p4_hash_output_bit_posn[i]; - idx = rot_info->gfm_bit_posn[p4_hash_bit_idx]; - hash_matrix[k][idx].column_value = temp_col[k][i].column_value; - hash_matrix[k][idx].byte_used = temp_col[k][i].byte_used; - } - } -} - -/** - * Updates the hash matrix for symmetric fields. - * Every field taking part in symmetric hashing has a sym_group and - * a sib_sym_group. For example if (src_ip, dst_ip) are symmetrically - * hashed, src_ip bits can have group as 1 and sib_sym_group as 2. - * The reverse for dst_ip. Use these groups to figure out which field - * inputs need to be XOR'ed. - * The following property is used if (f2,f3) are symmetric and - * (f4,f5) are symmetric. - * - * symmetric(f1,f2,f3,f4,f5) = crc(f1,f2,f3,f4,f5) ^ crc(f1,f3,f2,f5,f4) - * == crc(f1, f2^f3, f3^f2, f4^f5, f5^f4) - * - */ -void update_symmetric_bits(const ixbar_init_t *ixbar_init, const ixbar_input_t *inputs, - uint32_t inputs_sz, - hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]) { - uint32_t n_groups = 0; - uint32_t *groups = NULL; - uint32_t *sibling_groups = NULL; - bool symmetric_present = false; - hash_column_t hash_matrix_old[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]; - - // Check the input first. If there are no symmetric fields present, - // return - for (uint32_t i = 0; i < inputs_sz; i++) { - const ixbar_input_t *input = inputs + i; - if (input->type == tPHV && !input->u.valid) continue; - if (input->type == tCONST) continue; - if (input->symmetric_info.is_symmetric == false) continue; - symmetric_present = true; - } - if (!symmetric_present) return; - - memcpy(hash_matrix_old, hash_matrix, - sizeof(hash_column_t) * PARITY_GROUPS_DYN * HASH_MATRIX_WIDTH_DYN); - - groups = calloc_macro(inputs_sz, sizeof(uint32_t)); - ALLOC_CHECK(groups, "failed to allocate groups"); - - sibling_groups = calloc_macro(inputs_sz, sizeof(uint32_t)); - ALLOC_CHECK(sibling_groups, "failed to allocate sibling_groups"); - - // preprocess the input and record all the groups and sibling groups - for (uint32_t i = 0; i < inputs_sz; i++) { - const ixbar_input_t *input = inputs + i; - if (input->type == tPHV && !input->u.valid) continue; - if (input->type == tCONST) continue; - if (input->symmetric_info.is_symmetric == false) continue; - - groups[n_groups] = input->symmetric_info.sym_group; - sibling_groups[n_groups] = input->symmetric_info.sib_sym_group; - n_groups++; - } - - for (uint32_t g = 0; g < n_groups; g++) { - uint32_t cur_sym_count = 0; - for (uint32_t i = 0; i < inputs_sz; i++) { - const ixbar_input_t *input = inputs + i; - if (input->type == tPHV && !input->u.valid) continue; - if (input->type == tCONST) continue; - if (input->symmetric_info.is_symmetric == false) continue; - // Process each group at a time - if (input->symmetric_info.sym_group != groups[g]) continue; - - uint32_t sib_sym_count = 0; - const ixbar_input_t *sib_input = NULL; - bool sib_found = false; - // Find the corresponding sibling bit - for (uint32_t a = 0; a < inputs_sz; a++) { - sib_input = inputs + a; - // Check if the prospective sibling's sym_group is the same as - // the sibling group we are trying to find - if (sib_input->symmetric_info.sym_group == sibling_groups[g]) { - if (cur_sym_count == sib_sym_count) { - sib_found = true; - break; - } - sib_sym_count++; - if (sib_sym_count > cur_sym_count) break; - } - } - // If sibling wasn't found, just continue - if (!sib_found) continue; - // Sibling was found. A few sanity checks like comparing bit_size - if (input->bit_size != sib_input->bit_size) continue; - - cur_sym_count++; - - // modify hash_matrix for input with xor of sib_input - - for (uint32_t j = 0; j < input->bit_size; j++) { - uint32_t ixbar_input_bit = input->ixbar_bit_position + j; - uint32_t sib_ixbar_input_bit = sib_input->ixbar_bit_position + j; - - for (uint32_t k = 0; k < ixbar_init->outputs_sz; k++) { - hash_matrix_output_t *output = ixbar_init->hash_matrix_outputs + k; - for (uint32_t l = 0; l < output->bit_size; l++) { - uint32_t galois_bit = output->gfm_start_bit + l; - bool set_bit = - get_matrix_bit(hash_matrix_old, sib_ixbar_input_bit, galois_bit) ^ - get_matrix_bit(hash_matrix_old, ixbar_input_bit, galois_bit); - initialize_matrix_bit(hash_matrix, ixbar_input_bit, galois_bit, set_bit); - } - } - } - } - } - if (groups) free_macro(groups); - if (sibling_groups) free_macro(sibling_groups); -} - -void determine_hash_matrix(const ixbar_init_t *ixbar_init, const ixbar_input_t *inputs, - uint32_t inputs_sz, const bfn_hash_algorithm_t *alg, - hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]) { - uint32_t total_input_bits = 0; - for (uint32_t i = 0; i < inputs_sz; i++) { - const ixbar_input_t *input = inputs + i; - total_input_bits += input->bit_size; - } - - ///> Initialize the GFM matrix with the corresponding inputs - int input_bit = 0; - for (uint32_t i = 0; i < inputs_sz; i++) { - const ixbar_input_t *input = inputs + i; - ///> Potential holes in inputs during partial crc calculations during the - /// compiler require valid inputs - if (input->type == tPHV && !input->u.valid) { - input_bit += input->bit_size; - continue; - } else if (input->type == tCONST) { - input_bit += input->bit_size; - continue; - } - - ///> Iterate through all inputs and all outputs bit by bit to calculate the - /// bit positions - for (uint32_t j = 0; j < input->bit_size; j++) { - uint32_t ixbar_input_bit = input->ixbar_bit_position + j; - for (uint32_t k = 0; k < ixbar_init->outputs_sz; k++) { - const hash_matrix_output_t *output = ixbar_init->hash_matrix_outputs + k; - for (uint32_t l = 0; l < output->bit_size; l++) { - uint32_t p4_hash_output_bit = output->p4_hash_output_bit + l; - uint32_t galois_bit = output->gfm_start_bit + l; - determine_matrix_bit(hash_matrix, alg, inputs, inputs_sz, ixbar_input_bit, - input_bit, total_input_bits, p4_hash_output_bit, - galois_bit); - } - } - input_bit++; - } - } - - ///> Mark all fields not included in the inputs as used and marked as 0 - for (uint32_t i = 0; i < ixbar_init->inputs_sz; i++) { - ixbar_input_t *input = ixbar_init->ixbar_inputs + i; - if (input->type == tPHV && !input->u.valid) { - continue; - } - if (input->type == tCONST) continue; - for (uint32_t j = 0; j < input->bit_size; j++) { - uint32_t ixbar_input_bit = input->ixbar_bit_position + j; - for (uint32_t k = 0; k < ixbar_init->outputs_sz; k++) { - hash_matrix_output_t *output = ixbar_init->hash_matrix_outputs + k; - for (uint32_t l = 0; l < output->bit_size; l++) { - uint32_t galois_bit = output->gfm_start_bit + l; - initialize_matrix_bit(hash_matrix, ixbar_input_bit, galois_bit, false); - } - } - } - } -} - -void determine_seed(const hash_matrix_output_t *hash_matrix_outputs, uint32_t outputs_sz, - const ixbar_input_t *inputs, uint32_t inputs_sz, uint32_t total_input_bits, - const bfn_hash_algorithm_t *alg, hash_seed_t *hash_seed) { - ///> Initialize the input bitvec with the constant inputs - uint32_t bitvec_sz = compute_bitvec_sz(alg, total_input_bits); - // This is the data stream, and is saved as a bit vector - uint64_t val[bitvec_sz]; - memset(val, 0, sizeof(val)); - initialize_input_data_stream(alg, val, bitvec_sz, inputs, inputs_sz); - - for (uint32_t i = 0; i < outputs_sz; i++) { - const hash_matrix_output_t *output = hash_matrix_outputs + i; - for (uint32_t j = 0; j < output->bit_size; j++) { - uint32_t p4_hash_output_bit = output->p4_hash_output_bit + j; - uint32_t galois_bit = output->gfm_start_bit + j; - determine_seed_bit(hash_seed, val, bitvec_sz, alg, p4_hash_output_bit, total_input_bits, - galois_bit); - } - } -} - -/** - * This builds the changes to the galois field matrix for this particular hash - * function. - */ -void determine_tofino_gfm_delta(hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN], - hash_regs_t *regs) { - int galois_delta_count = 0; - ///> Determine the number of registers that require a change - for (int i = 0; i < PARITY_GROUPS_DYN; i++) { - for (int j = 0; j < HASH_MATRIX_WIDTH_DYN; j++) { - for (int k = 0; k < 8; k += 2) { - if (((1 << k) & hash_matrix[i][j].byte_used) != 0 || - ((1 << (k + 1)) & hash_matrix[i][j].byte_used) != 0) { - galois_delta_count++; - } - } - } - } - - regs->galois_field_matrix_regs = - calloc_macro(galois_delta_count, sizeof(galois_field_matrix_delta_t)); - if (!regs->galois_field_matrix_regs) { - assert_macro(0); - return; - } - - regs->gfm_sz = galois_delta_count; - - ///> Build the array of registers that require the change. - uint32_t gfm_index = 0; - for (int i = 0; i < PARITY_GROUPS_DYN; i++) { - for (int j = 0; j < HASH_MATRIX_WIDTH_DYN; j++) { - for (int k = 0; k < 8; k += 2) { - int byte0_shift = k * 8; - int byte1_shift = (k + 1) * 8; - - if (((1 << k) & hash_matrix[i][j].byte_used) == 0 && - ((1 << (k + 1)) & hash_matrix[i][j].byte_used) == 0) - continue; - - // NOTE: Must be freed after use outside of this - galois_field_matrix_delta_t *gfm_delta = regs->galois_field_matrix_regs + gfm_index; - gfm_delta->byte_pair_index = i * BYTE_PAIRS_PER_PARITY_GROUP + k / 2; - gfm_delta->hash_bit = j; - gfm_delta->byte0 = (hash_matrix[i][j].column_value >> byte0_shift) & 0xffUL; - gfm_delta->byte1 = (hash_matrix[i][j].column_value >> byte1_shift) & 0xffUL; - gfm_delta->valid0 = 0; - gfm_delta->valid1 = 0; - gfm_index++; - } - } - } -} - -void determine_seed_delta(const hash_seed_t *hash_seed, hash_regs_t *regs, uint32_t parity_group) { - int seed_delta_count = 0; - - ///> Determine the number of registers that require a change - for (int i = 0; i < HASH_MATRIX_WIDTH_DYN; i++) { - if (((1ULL << i) & hash_seed->hash_seed_used) != 0ULL) seed_delta_count++; - } - - // NOTE: Must be freed after use outside of this - regs->hash_seed_regs = calloc_macro(seed_delta_count, sizeof(hash_seed_delta_t)); - if (!regs->hash_seed_regs) { - assert_macro(0); - return; - } - - regs->hs_sz = seed_delta_count; - - ///> Build the array of registers that require the change - uint32_t seed_index = 0; - for (int i = 0; i < HASH_MATRIX_WIDTH_DYN; i++) { - uint64_t mask = (1ULL << i); - if ((mask & hash_seed->hash_seed_used) == 0ULL) continue; - uint64_t seed_value = (mask & hash_seed->hash_seed_value) >> i; - hash_seed_delta_t *hs_delta = regs->hash_seed_regs + seed_index; - - hs_delta->hash_bit = i; - hs_delta->hash_seed_and_value = 0xff & ~(1 << parity_group); - hs_delta->hash_seed_or_value = (seed_value << parity_group); - seed_index++; - } -} - -void determine_tofino_regs(const ixbar_init_t *ixbar_init, const ixbar_input_t *inputs, - uint32_t inputs_sz, const bfn_hash_algorithm_t *alg, - hash_calc_rotate_info_t *rot_info, hash_regs_t *regs) { - hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]; - memset(hash_matrix, 0, sizeof(hash_column_t) * PARITY_GROUPS_DYN * HASH_MATRIX_WIDTH_DYN); - - hash_seed_t hash_seed; - memset(&hash_seed, 0, sizeof(hash_seed_t)); - - uint32_t total_input_bits = 0; - for (uint32_t i = 0; i < inputs_sz; i++) { - const ixbar_input_t *input = inputs + i; - total_input_bits += input->bit_size; - } - determine_hash_matrix(ixbar_init, inputs, inputs_sz, alg, hash_matrix); - update_symmetric_bits(ixbar_init, inputs, inputs_sz, hash_matrix); - if (rot_info->rotate) { - rotate_matrix(rot_info, hash_matrix); - } -#ifdef HASH_DEBUG - print_hash_matrix(hash_matrix); - print_hash_matrix_used(hash_matrix); -#endif - determine_seed(ixbar_init->hash_matrix_outputs, ixbar_init->outputs_sz, inputs, inputs_sz, - total_input_bits, alg, &hash_seed); - if (rot_info->rotate) { - rotate_seed(rot_info, &hash_seed); - } - - determine_tofino_gfm_delta(hash_matrix, regs); - determine_seed_delta(&hash_seed, regs, ixbar_init->parity_group); -} From ad24e06fadee72c5054cb77feef18b8650e86d83 Mon Sep 17 00:00:00 2001 From: fruffy Date: Sat, 7 Dec 2024 19:21:37 -0500 Subject: [PATCH 2/3] Make the json loader and parser independent from the generated ir files. Signed-off-by: fruffy --- frontends/common/constantParsing.h | 46 +----------------- ir/CMakeLists.txt | 40 +++++----------- ir/inode.h | 77 ++++++++++++++++++++++++++++++ ir/json_loader.h | 5 +- ir/node.h | 45 +---------------- ir/unpacker_table.h | 18 +++++++ ir/unparsed_constant.h | 70 +++++++++++++++++++++++++++ ir/visitor.cpp | 1 - tools/ir-generator/irclass.cpp | 4 +- 9 files changed, 185 insertions(+), 121 deletions(-) create mode 100644 ir/inode.h create mode 100644 ir/unpacker_table.h create mode 100644 ir/unparsed_constant.h diff --git a/frontends/common/constantParsing.h b/frontends/common/constantParsing.h index b2d4c5376f..37a4a4bfdf 100644 --- a/frontends/common/constantParsing.h +++ b/frontends/common/constantParsing.h @@ -17,7 +17,7 @@ limitations under the License. #ifndef FRONTENDS_COMMON_CONSTANTPARSING_H_ #define FRONTENDS_COMMON_CONSTANTPARSING_H_ -#include "lib/cstring.h" +#include "ir/unparsed_constant.h" namespace P4::IR { class Constant; @@ -29,50 +29,6 @@ class SourceInfo; namespace P4 { -/** - * An unparsed numeric constant. We produce these as token values during - * lexing. The parser is responsible for actually interpreting the raw text as a - * numeric value and transforming it into an IR::Constant using parseConstant(). - * - * To illustrate how a numeric constant is represented using this struct, - * here is a breakdown of '16w0x12': - * - * ___ - * / ___ - * | / - * | bitwidth (if @hasWidth) | 16 - * | \___ - * | - * | ___ - * | / - * | separator (if @hasWidth) | w - * | \___ - * @text | - * | ___ - * | / - * | ignored prefix of length @skip | 0x - * | \___ - * | - * | ___ - * | / - * | numeric value in base @base | w - * | \___ - * \___ - * - * Simple numeric constants like '5' are specified by setting @hasWidth to - * false and providing a @skip length of 0. - */ -struct UnparsedConstant { - cstring text; /// Raw P4 text which was recognized as a numeric constant. - unsigned skip; /// An ignored prefix of the numeric constant (e.g. '0x'). - unsigned base; /// The base in which the constant is expressed. - bool hasWidth; /// If true, a bitwidth and separator are present. -}; - -std::ostream &operator<<(std::ostream &out, const UnparsedConstant &constant); - -bool operator<(const UnparsedConstant &a, const UnparsedConstant &b); - /** * Parses an UnparsedConstant @constant into an IR::Constant object, with * location information taken from @srcInfo. If parsing fails, an IR::Constant diff --git a/ir/CMakeLists.txt b/ir/CMakeLists.txt index 242f6d104c..31e3189237 100644 --- a/ir/CMakeLists.txt +++ b/ir/CMakeLists.txt @@ -12,10 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. +set (IR_LIB_SRCS + bitrange.cpp + json_parser.cpp +) + +add_library (ir_lib STATIC ${IR_LIB_SRCS}) +target_link_libraries(ir_lib PRIVATE p4ctoolkit absl::flat_hash_map ${LIBGC_LIBRARIES}) + + set (IR_SRCS annotations.cpp base.cpp - bitrange.cpp dbprint.cpp dbprint-expression.cpp dbprint-stmt.cpp @@ -25,9 +33,8 @@ set (IR_SRCS expression.cpp ir.cpp irutils.cpp - json_parser.cpp - loop-visitor.cpp node.cpp + loop-visitor.cpp pass_manager.cpp pass_utils.cpp type.cpp @@ -35,31 +42,6 @@ set (IR_SRCS write_context.cpp ) -set (IR_HDRS - annotations.h - configuration.h - dbprint.h - dump.h - id.h - indexed_vector.h - ir-inline.h - ir-tree-macros.h - ir.h - ir-traversal.h - ir-traversal-internal.h - irutils.h - json_generator.h - json_loader.h - json_parser.h - namemap.h - node.h - nodemap.h - pass_manager.h - pass_utils.h - vector.h - visitor.h -) - set (BASE_IR_DEF_FILES ${CMAKE_CURRENT_SOURCE_DIR}/base.def ${CMAKE_CURRENT_SOURCE_DIR}/type.def @@ -70,7 +52,7 @@ set (BASE_IR_DEF_FILES set (IR_DEF_FILES ${IR_DEF_FILES} ${BASE_IR_DEF_FILES} PARENT_SCOPE) add_library (ir STATIC ${IR_SRCS}) -target_link_libraries(ir PRIVATE absl::flat_hash_map ${LIBGC_LIBRARIES}) +target_link_libraries(ir PUBLIC ir_lib PRIVATE absl::flat_hash_map ${LIBGC_LIBRARIES}) add_dependencies(ir genIR) diff --git a/ir/inode.h b/ir/inode.h new file mode 100644 index 0000000000..6f39d1a062 --- /dev/null +++ b/ir/inode.h @@ -0,0 +1,77 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +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. +*/ + +#ifndef IR_INODE_H_ +#define IR_INODE_H_ + +#include "lib/castable.h" +#include "lib/cstring.h" +#include "lib/exceptions.h" +#include "lib/rtti.h" +#include "lib/source_file.h" + +namespace P4 { +class JSONGenerator; +class JSONLoader; +} // namespace P4 + +namespace P4::IR { + +class Node; + +/// SFINAE helper to check if given class has a `static_type_name` +/// method. Definite node classes have them while interfaces do not +template +struct has_static_type_name : std::false_type {}; + +template +struct has_static_type_name> : std::true_type {}; + +template +inline constexpr bool has_static_type_name_v = has_static_type_name::value; + +// node interface +class INode : public Util::IHasSourceInfo, public IHasDbPrint, public ICastable { + public: + virtual ~INode() {} + virtual const Node *getNode() const = 0; + virtual Node *getNode() = 0; + virtual void toJSON(JSONGenerator &) const = 0; + virtual cstring node_type_name() const = 0; + virtual void validate() const {} + + // default checkedTo implementation for nodes: just fallback to generic ICastable method + template + std::enable_if_t, const T *> checkedTo() const { + return ICastable::checkedTo(); + } + + // alternative checkedTo implementation that produces slightly better error message + // due to node_type_name() / static_type_name() being available + template + std::enable_if_t, const T *> checkedTo() const { + const auto *result = to(); + BUG_CHECK(result, "Cast failed: %1% with type %2% is not a %3%.", this, node_type_name(), + T::static_type_name()); + return result; + } + + DECLARE_TYPEINFO(INode); +}; + +} // namespace P4::IR + +#endif /* IR_INODE_H_ */ diff --git a/ir/json_loader.h b/ir/json_loader.h index b8d027b4b5..ee48a5a534 100644 --- a/ir/json_loader.h +++ b/ir/json_loader.h @@ -30,6 +30,7 @@ limitations under the License. #include "lib/cstring.h" #include "lib/ltbitmatrix.h" #include "lib/match.h" +#include "lib/null.h" #include "lib/ordered_map.h" #include "lib/ordered_set.h" #include "lib/safe_vector.h" @@ -80,7 +81,9 @@ class JSONLoader { if (id >= 0) { if (node_refs.find(id) == node_refs.end()) { if (auto fn = get(IR::unpacker_table, json->as().get_type())) { - node_refs[id] = fn(*this); + auto *node = fn(*this)->to(); + CHECK_NULL(node); + node_refs[id] = node; // Creating JsonObject from source_info read from jsonFile // and setting SourceInfo for each node // when "--fromJSON" flag is used diff --git a/ir/node.h b/ir/node.h index 53e5eab1b1..027920a075 100644 --- a/ir/node.h +++ b/ir/node.h @@ -19,11 +19,10 @@ limitations under the License. #include -#include "ir-tree-macros.h" #include "ir/gen-tree-macro.h" -#include "lib/castable.h" +#include "ir/inode.h" +#include "ir/ir-tree-macros.h" #include "lib/cstring.h" -#include "lib/exceptions.h" #include "lib/source_file.h" namespace P4 { @@ -51,46 +50,6 @@ class Vector; // IWYU pragma: keep template class IndexedVector; // IWYU pragma: keep -/// SFINAE helper to check if given class has a `static_type_name` -/// method. Definite node classes have them while interfaces do not -template -struct has_static_type_name : std::false_type {}; - -template -struct has_static_type_name> : std::true_type {}; - -template -inline constexpr bool has_static_type_name_v = has_static_type_name::value; - -// node interface -class INode : public Util::IHasSourceInfo, public IHasDbPrint, public ICastable { - public: - virtual ~INode() {} - virtual const Node *getNode() const = 0; - virtual Node *getNode() = 0; - virtual void toJSON(JSONGenerator &) const = 0; - virtual cstring node_type_name() const = 0; - virtual void validate() const {} - - // default checkedTo implementation for nodes: just fallback to generic ICastable method - template - std::enable_if_t, const T *> checkedTo() const { - return ICastable::checkedTo(); - } - - // alternative checkedTo implementation that produces slightly better error message - // due to node_type_name() / static_type_name() being available - template - std::enable_if_t, const T *> checkedTo() const { - const auto *result = to(); - BUG_CHECK(result, "Cast failed: %1% with type %2% is not a %3%.", this, node_type_name(), - T::static_type_name()); - return result; - } - - DECLARE_TYPEINFO_WITH_TYPEID(INode, NodeKind::INode); -}; - class Node : public virtual INode { public: virtual bool apply_visitor_preorder(Modifier &v); diff --git a/ir/unpacker_table.h b/ir/unpacker_table.h new file mode 100644 index 0000000000..1c88aea176 --- /dev/null +++ b/ir/unpacker_table.h @@ -0,0 +1,18 @@ +#ifndef IR_UNPACKER_TABLE_H_ +#define IR_UNPACKER_TABLE_H_ + +#include "ir/inode.h" +#include "lib/cstring.h" + +namespace P4 { +class JSONLoader; + +using NodeFactoryFn = IR::INode *(*)(JSONLoader &); +namespace IR { +extern std::map unpacker_table; + +} // namespace IR + +} // namespace P4 + +#endif /* IR_UNPACKER_TABLE_H_ */ diff --git a/ir/unparsed_constant.h b/ir/unparsed_constant.h new file mode 100644 index 0000000000..b5adaf871d --- /dev/null +++ b/ir/unparsed_constant.h @@ -0,0 +1,70 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +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. +*/ + +#ifndef IR_UNPARSED_CONSTANT_H_ +#define IR_UNPARSED_CONSTANT_H_ + +#include "lib/cstring.h" + +namespace P4 { + +/** + * An unparsed numeric constant. We produce these as token values during + * lexing. The parser is responsible for actually interpreting the raw text as a + * numeric value and transforming it into an IR::Constant using parseConstant(). + * + * To illustrate how a numeric constant is represented using this struct, + * here is a breakdown of '16w0x12': + * + * ___ + * / ___ + * | / + * | bitwidth (if @hasWidth) | 16 + * | \___ + * | + * | ___ + * | / + * | separator (if @hasWidth) | w + * | \___ + * @text | + * | ___ + * | / + * | ignored prefix of length @skip | 0x + * | \___ + * | + * | ___ + * | / + * | numeric value in base @base | w + * | \___ + * \___ + * + * Simple numeric constants like '5' are specified by setting @hasWidth to + * false and providing a @skip length of 0. + */ +struct UnparsedConstant { + cstring text; /// Raw P4 text which was recognized as a numeric constant. + unsigned skip; /// An ignored prefix of the numeric constant (e.g. '0x'). + unsigned base; /// The base in which the constant is expressed. + bool hasWidth; /// If true, a bitwidth and separator are present. +}; + +std::ostream &operator<<(std::ostream &out, const UnparsedConstant &constant); + +bool operator<(const UnparsedConstant &a, const UnparsedConstant &b); + +} // namespace P4 + +#endif /* IR_UNPARSED_CONSTANT_H_ */ diff --git a/ir/visitor.cpp b/ir/visitor.cpp index 4224c25c17..5c71f6c77d 100644 --- a/ir/visitor.cpp +++ b/ir/visitor.cpp @@ -23,7 +23,6 @@ limitations under the License. #include "absl/container/flat_hash_map.h" #include "absl/time/clock.h" #include "absl/time/time.h" -#include "ir/ir-generated.h" #include "lib/hash.h" #if HAVE_CXXABI_H diff --git a/tools/ir-generator/irclass.cpp b/tools/ir-generator/irclass.cpp index 013ca5d48d..59e1449fac 100644 --- a/tools/ir-generator/irclass.cpp +++ b/tools/ir-generator/irclass.cpp @@ -131,16 +131,16 @@ void IrDefinitions::generate(std::ostream &t, std::ostream &out, std::ostream &i << "#include \"ir/namemap.h\" // IWYU pragma: keep\n" << "#include \"ir/node.h\" // IWYU pragma: keep\n" << "#include \"ir/nodemap.h\" // IWYU pragma: keep\n" + << "#include \"ir/unpacker_table.h\" // IWYU pragma: keep\n" << "#include \"ir/vector.h\" // IWYU pragma: keep\n" << "#include \"lib/ordered_map.h\" // IWYU pragma: keep\n" << std::endl << "namespace P4 {\n" << std::endl << "class JSONLoader;\n" - << "using NodeFactoryFn = IR::Node*(*)(JSONLoader&);\n" + << "using NodeFactoryFn = IR::INode*(*)(JSONLoader&);\n" << std::endl << "namespace IR {\n" - << "extern std::map unpacker_table;\n" << "using namespace P4::literals;\n" << "}\n"; From 4449f619478bc62defb62e10ae56ee9d0f8144a2 Mon Sep 17 00:00:00 2001 From: fruffy Date: Fri, 13 Dec 2024 15:34:17 +0100 Subject: [PATCH 3/3] Revert custom lib usage. Signed-off-by: fruffy --- backends/tofino/bf-p4c/CMakeLists.txt | 2 + frontends/common/constantParsing.h | 46 +++++++++++++++++- ir/CMakeLists.txt | 40 ++++++++++----- ir/inode.h | 3 +- ir/unpacker_table.h | 18 ------- ir/unparsed_constant.h | 70 --------------------------- tools/ir-generator/irclass.cpp | 4 +- 7 files changed, 80 insertions(+), 103 deletions(-) delete mode 100644 ir/unpacker_table.h delete mode 100644 ir/unparsed_constant.h diff --git a/backends/tofino/bf-p4c/CMakeLists.txt b/backends/tofino/bf-p4c/CMakeLists.txt index 01c3565346..18a5e56c27 100644 --- a/backends/tofino/bf-p4c/CMakeLists.txt +++ b/backends/tofino/bf-p4c/CMakeLists.txt @@ -102,6 +102,8 @@ set (BF_P4C_SPEC_SRCS add_library(tofinospecs STATIC ${BF_P4C_SPEC_SRCS}) target_link_libraries(tofinospecs PUBLIC p4ctoolkit) +# We depend on the gen-tree-macro.h file, which is generated. +add_dependencies(tofinospecs genIR) set (BF_P4C_MIDEND_SRCS midend/annotate_with_in_hash.cpp diff --git a/frontends/common/constantParsing.h b/frontends/common/constantParsing.h index 37a4a4bfdf..b2d4c5376f 100644 --- a/frontends/common/constantParsing.h +++ b/frontends/common/constantParsing.h @@ -17,7 +17,7 @@ limitations under the License. #ifndef FRONTENDS_COMMON_CONSTANTPARSING_H_ #define FRONTENDS_COMMON_CONSTANTPARSING_H_ -#include "ir/unparsed_constant.h" +#include "lib/cstring.h" namespace P4::IR { class Constant; @@ -29,6 +29,50 @@ class SourceInfo; namespace P4 { +/** + * An unparsed numeric constant. We produce these as token values during + * lexing. The parser is responsible for actually interpreting the raw text as a + * numeric value and transforming it into an IR::Constant using parseConstant(). + * + * To illustrate how a numeric constant is represented using this struct, + * here is a breakdown of '16w0x12': + * + * ___ + * / ___ + * | / + * | bitwidth (if @hasWidth) | 16 + * | \___ + * | + * | ___ + * | / + * | separator (if @hasWidth) | w + * | \___ + * @text | + * | ___ + * | / + * | ignored prefix of length @skip | 0x + * | \___ + * | + * | ___ + * | / + * | numeric value in base @base | w + * | \___ + * \___ + * + * Simple numeric constants like '5' are specified by setting @hasWidth to + * false and providing a @skip length of 0. + */ +struct UnparsedConstant { + cstring text; /// Raw P4 text which was recognized as a numeric constant. + unsigned skip; /// An ignored prefix of the numeric constant (e.g. '0x'). + unsigned base; /// The base in which the constant is expressed. + bool hasWidth; /// If true, a bitwidth and separator are present. +}; + +std::ostream &operator<<(std::ostream &out, const UnparsedConstant &constant); + +bool operator<(const UnparsedConstant &a, const UnparsedConstant &b); + /** * Parses an UnparsedConstant @constant into an IR::Constant object, with * location information taken from @srcInfo. If parsing fails, an IR::Constant diff --git a/ir/CMakeLists.txt b/ir/CMakeLists.txt index 31e3189237..242f6d104c 100644 --- a/ir/CMakeLists.txt +++ b/ir/CMakeLists.txt @@ -12,18 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -set (IR_LIB_SRCS - bitrange.cpp - json_parser.cpp -) - -add_library (ir_lib STATIC ${IR_LIB_SRCS}) -target_link_libraries(ir_lib PRIVATE p4ctoolkit absl::flat_hash_map ${LIBGC_LIBRARIES}) - - set (IR_SRCS annotations.cpp base.cpp + bitrange.cpp dbprint.cpp dbprint-expression.cpp dbprint-stmt.cpp @@ -33,8 +25,9 @@ set (IR_SRCS expression.cpp ir.cpp irutils.cpp - node.cpp + json_parser.cpp loop-visitor.cpp + node.cpp pass_manager.cpp pass_utils.cpp type.cpp @@ -42,6 +35,31 @@ set (IR_SRCS write_context.cpp ) +set (IR_HDRS + annotations.h + configuration.h + dbprint.h + dump.h + id.h + indexed_vector.h + ir-inline.h + ir-tree-macros.h + ir.h + ir-traversal.h + ir-traversal-internal.h + irutils.h + json_generator.h + json_loader.h + json_parser.h + namemap.h + node.h + nodemap.h + pass_manager.h + pass_utils.h + vector.h + visitor.h +) + set (BASE_IR_DEF_FILES ${CMAKE_CURRENT_SOURCE_DIR}/base.def ${CMAKE_CURRENT_SOURCE_DIR}/type.def @@ -52,7 +70,7 @@ set (BASE_IR_DEF_FILES set (IR_DEF_FILES ${IR_DEF_FILES} ${BASE_IR_DEF_FILES} PARENT_SCOPE) add_library (ir STATIC ${IR_SRCS}) -target_link_libraries(ir PUBLIC ir_lib PRIVATE absl::flat_hash_map ${LIBGC_LIBRARIES}) +target_link_libraries(ir PRIVATE absl::flat_hash_map ${LIBGC_LIBRARIES}) add_dependencies(ir genIR) diff --git a/ir/inode.h b/ir/inode.h index 6f39d1a062..fd9da360c1 100644 --- a/ir/inode.h +++ b/ir/inode.h @@ -17,6 +17,7 @@ limitations under the License. #ifndef IR_INODE_H_ #define IR_INODE_H_ +#include "ir/gen-tree-macro.h" #include "lib/castable.h" #include "lib/cstring.h" #include "lib/exceptions.h" @@ -69,7 +70,7 @@ class INode : public Util::IHasSourceInfo, public IHasDbPrint, public ICastable return result; } - DECLARE_TYPEINFO(INode); + DECLARE_TYPEINFO_WITH_TYPEID(INode, NodeKind::INode); }; } // namespace P4::IR diff --git a/ir/unpacker_table.h b/ir/unpacker_table.h deleted file mode 100644 index 1c88aea176..0000000000 --- a/ir/unpacker_table.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef IR_UNPACKER_TABLE_H_ -#define IR_UNPACKER_TABLE_H_ - -#include "ir/inode.h" -#include "lib/cstring.h" - -namespace P4 { -class JSONLoader; - -using NodeFactoryFn = IR::INode *(*)(JSONLoader &); -namespace IR { -extern std::map unpacker_table; - -} // namespace IR - -} // namespace P4 - -#endif /* IR_UNPACKER_TABLE_H_ */ diff --git a/ir/unparsed_constant.h b/ir/unparsed_constant.h deleted file mode 100644 index b5adaf871d..0000000000 --- a/ir/unparsed_constant.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -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. -*/ - -#ifndef IR_UNPARSED_CONSTANT_H_ -#define IR_UNPARSED_CONSTANT_H_ - -#include "lib/cstring.h" - -namespace P4 { - -/** - * An unparsed numeric constant. We produce these as token values during - * lexing. The parser is responsible for actually interpreting the raw text as a - * numeric value and transforming it into an IR::Constant using parseConstant(). - * - * To illustrate how a numeric constant is represented using this struct, - * here is a breakdown of '16w0x12': - * - * ___ - * / ___ - * | / - * | bitwidth (if @hasWidth) | 16 - * | \___ - * | - * | ___ - * | / - * | separator (if @hasWidth) | w - * | \___ - * @text | - * | ___ - * | / - * | ignored prefix of length @skip | 0x - * | \___ - * | - * | ___ - * | / - * | numeric value in base @base | w - * | \___ - * \___ - * - * Simple numeric constants like '5' are specified by setting @hasWidth to - * false and providing a @skip length of 0. - */ -struct UnparsedConstant { - cstring text; /// Raw P4 text which was recognized as a numeric constant. - unsigned skip; /// An ignored prefix of the numeric constant (e.g. '0x'). - unsigned base; /// The base in which the constant is expressed. - bool hasWidth; /// If true, a bitwidth and separator are present. -}; - -std::ostream &operator<<(std::ostream &out, const UnparsedConstant &constant); - -bool operator<(const UnparsedConstant &a, const UnparsedConstant &b); - -} // namespace P4 - -#endif /* IR_UNPARSED_CONSTANT_H_ */ diff --git a/tools/ir-generator/irclass.cpp b/tools/ir-generator/irclass.cpp index 59e1449fac..013ca5d48d 100644 --- a/tools/ir-generator/irclass.cpp +++ b/tools/ir-generator/irclass.cpp @@ -131,16 +131,16 @@ void IrDefinitions::generate(std::ostream &t, std::ostream &out, std::ostream &i << "#include \"ir/namemap.h\" // IWYU pragma: keep\n" << "#include \"ir/node.h\" // IWYU pragma: keep\n" << "#include \"ir/nodemap.h\" // IWYU pragma: keep\n" - << "#include \"ir/unpacker_table.h\" // IWYU pragma: keep\n" << "#include \"ir/vector.h\" // IWYU pragma: keep\n" << "#include \"lib/ordered_map.h\" // IWYU pragma: keep\n" << std::endl << "namespace P4 {\n" << std::endl << "class JSONLoader;\n" - << "using NodeFactoryFn = IR::INode*(*)(JSONLoader&);\n" + << "using NodeFactoryFn = IR::Node*(*)(JSONLoader&);\n" << std::endl << "namespace IR {\n" + << "extern std::map unpacker_table;\n" << "using namespace P4::literals;\n" << "}\n";