19#ifndef BF_P4C_PHV_ALLOCATE_PHV_H_
20#define BF_P4C_PHV_ALLOCATE_PHV_H_
25#include "backends/tofino/bf-p4c/common/field_defuse.h"
26#include "backends/tofino/bf-p4c/ir/bitrange.h"
27#include "backends/tofino/bf-p4c/ir/gress.h"
28#include "backends/tofino/bf-p4c/parde/clot/clot_info.h"
29#include "backends/tofino/bf-p4c/phv/action_phv_constraints.h"
30#include "backends/tofino/bf-p4c/phv/action_source_tracker.h"
31#include "backends/tofino/bf-p4c/phv/alloc_setting.h"
32#include "backends/tofino/bf-p4c/phv/analysis/critical_path_clusters.h"
33#include "backends/tofino/bf-p4c/phv/analysis/dark_live_range.h"
34#include "backends/tofino/bf-p4c/phv/analysis/live_range_shrinking.h"
35#include "backends/tofino/bf-p4c/phv/collect_strided_headers.h"
36#include "backends/tofino/bf-p4c/phv/fieldslice_live_range.h"
37#include "backends/tofino/bf-p4c/phv/make_clusters.h"
38#include "backends/tofino/bf-p4c/phv/mau_backtracker.h"
39#include "backends/tofino/bf-p4c/phv/phv.h"
40#include "backends/tofino/bf-p4c/phv/phv_fields.h"
41#include "backends/tofino/bf-p4c/phv/phv_parde_mau_use.h"
42#include "backends/tofino/bf-p4c/phv/pragma/phv_pragmas.h"
43#include "backends/tofino/bf-p4c/phv/slicing/types.h"
44#include "backends/tofino/bf-p4c/phv/table_phv_constraints.h"
45#include "backends/tofino/bf-p4c/phv/utils/slice_alloc.h"
46#include "backends/tofino/bf-p4c/phv/utils/tables_to_ids.h"
47#include "backends/tofino/bf-p4c/phv/utils/utils.h"
48#include "lib/bitvec.h"
49#include "lib/symbitmatrix.h"
105 clustering(clustering),
109 source_tracker(source_tracker),
110 meta_init(meta_init),
111 dark_init(dark_init),
112 field_to_parser_states(field_to_parser_states),
113 parser_critical_path(parser_critical_path),
114 parser_info(parser_info),
115 strided_headers(strided_headers),
116 physical_liverange_db(physical_liverange_db),
119 tablePackOpt(tablePackOpt) {}
121 const SymBitMatrix &mutex()
const {
return phv.field_mutex(); }
175 const std::list<PHV::SuperCluster *> &cluster_groups);
180 const PhvUse &uses,
const std::list<PHV::SuperCluster *> &cluster_groups_input);
184 const ClotInfo &clot, std::list<PHV::SuperCluster *> clusters);
190 const std::list<PHV::SuperCluster *> &cluster_groups);
200namespace Diagnostics {
218 using FieldPair = std::pair<const PHV::Field *, const PHV::Field *>;
219 std::map<const PHV::Field *, int> opportunities;
220 std::map<FieldPair, int> opportunities_after;
223 std::vector<const PHV::Field *> fieldsInOrder(
224 const std::list<PHV::SuperCluster *> &sorted_clusters)
const;
226 bool isExtractedOrUninitialized(
const PHV::Field *f)
const;
259 using ContainerAllocStatus = PHV::Allocation::ContainerAllocStatus;
295 ContainerAllocStatus calcContainerStatus(
const PHV::Container &container,
303std::ostream &operator<<(std::ostream &s,
const AllocScore &score);
314 bool stop_at_first_i =
false;
321 : name_i(name), stop_at_first_i(stop_at_first), is_better_i(is_better) {}
327 const int bitmasks = 0)
const;
330 return is_better_i(left, right);
333 bool stop_at_first()
const {
return stop_at_first_i; }
337 cloned.packing_opportunities_i = packing;
354 bool control_flow_overlay;
355 bool physical_liverange_overlay;
356 bool metadata_overlay;
364 const bool disableMetadataInit;
366 bool singleGressParserGroups =
false;
368 bool prioritizeARAinits =
false;
370 std::optional<PHV::Transaction> alloc_super_cluster_with_alignment(
373 const std::list<const PHV::SuperCluster::SliceList *> &sorted_slice_lists,
377 std::vector<AllocAlignment> build_alignments(
int max_n,
383 std::vector<AllocAlignment> build_slicelist_alignment(
385 const PHV::SuperCluster::SliceList *slice_list)
const;
387 bool check_metadata_and_dark_overlay(
388 const PHV::Container &c, std::vector<PHV::AllocSlice> &complex_overlay_slices,
389 std::vector<PHV::AllocSlice> &candidate_slices,
392 std::optional<PHV::Allocation::LiveRangeShrinkingMap> &initNodes,
401 std::optional<std::vector<PHV::AllocSlice>> prepare_candidate_slices(
408 std::optional<PHV::Allocation::LiveRangeShrinkingMap> &initNodes,
416 bool try_dark_overlay(std::vector<PHV::AllocSlice> &dark_slices,
418 std::vector<PHV::AllocSlice> &candidate_slices,
423 bool try_pack_slice_list(
424 std::vector<PHV::AllocSlice> &candidate_slices,
PHV::Transaction &perContainerAlloc,
426 std::optional<PHV::Allocation::LiveRangeShrinkingMap> &initNodes,
const PHV::Container &c,
428 std::optional<PHV::Allocation::ConditionalConstraints> &action_constraints,
429 int &num_bitmasks)
const;
432 PHV::SuperCluster::SliceList *hi_slice,
441 bool find_previous_allocation(
450 : utils_i(utils), disableMetadataInit(disable_metainit) {}
484 std::vector<PHV::AllocSlice> &candidate_slices)
const;
492 void set_single_gress_parser_group() { singleGressParserGroups =
true; }
493 bool get_single_gress_parser_group() {
return singleGressParserGroups; }
496 void set_prioritize_ARA_inits() { prioritizeARAinits =
true; }
497 bool get_prioririze_ARA_inits() {
return prioritizeARAinits; }
525 std::optional<const PHV::SuperCluster::SliceList *> find_first_unallocated_slicelist(
526 const PHV::Allocation &alloc,
const std::list<PHV::ContainerGroup *> &container_groups,
538 bool checkDarkOverlay(
const std::vector<PHV::AllocSlice> &candidate_slices,
591 const PHV::SuperCluster &super_cluster,
const PHV::SuperCluster::SliceList &slice_list,
597 PHV::DarkInitMap &slices,
602 bool hasCrossingLiveranges(std::vector<PHV::AllocSlice> candidate_slices,
615 const std::vector<PHV::AllocSlice> &candidates,
619enum class AllocResultCode {
627 AllocResultCode status;
629 std::list<const PHV::SuperCluster *> remaining_clusters;
633 std::list<const PHV::SuperCluster *> &&c)
634 : status(r), transaction(t), remaining_clusters(c) {}
658 : name(name), utils_i(utils), core_alloc_i(core) {}
668 const std::list<PHV::SuperCluster *> &cluster_groups_input,
669 const std::list<PHV::ContainerGroup *> &container_groups) = 0;
678 int max_failure_retry;
684 int max_sl_alignment;
686 std::optional<std::unordered_set<Device::Device_t>> unsupported_devices;
689 bool pre_slicing_validation;
691 bool enable_ara_in_overlays;
698 std::optional<const PHV::SuperCluster::SliceList *> unallocatable_list_i;
708 const std::list<PHV::SuperCluster *> &cluster_groups_input,
709 const std::list<PHV::ContainerGroup *> &container_groups)
override;
711 std::optional<const PHV::SuperCluster::SliceList *> get_unallocatable_list()
const {
712 return unallocatable_list_i;
715 int getPipeId()
const {
return pipe_id_i; }
719 const PHV::Allocation &alloc,
const std::list<PHV::SuperCluster *> &cluster_groups_input,
720 const std::list<PHV::ContainerGroup *> &container_groups,
723 std::list<PHV::SuperCluster *> crush_clusters(
724 const std::list<PHV::SuperCluster *> &cluster_groups);
728 const std::list<PHV::SuperCluster *> &cluster_groups,
729 const std::list<PHV::ContainerGroup *> &container_groups,
730 std::list<const PHV::SuperCluster *> &unsliceable);
733 void sortClusters(std::list<PHV::SuperCluster *> &cluster_groups);
735 bool tryAllocSlicing(
const std::list<PHV::SuperCluster *> &slicing,
736 const std::list<PHV::ContainerGroup *> &container_groups,
739 bool tryAllocStride(
const std::list<PHV::SuperCluster *> &stride,
740 const std::list<PHV::ContainerGroup *> &container_groups,
743 bool tryAllocStrideWithLeaderAllocated(
const std::list<PHV::SuperCluster *> &stride,
747 bool tryAllocSlicingStrided(
unsigned num_strides,
const std::list<PHV::SuperCluster *> &slicing,
748 const std::list<PHV::ContainerGroup *> &container_groups,
753 const std::list<PHV::ContainerGroup *> &container_groups,
const ScoreContext &score_ctx,
754 std::stringstream &alloc_history);
756 std::list<PHV::SuperCluster *> allocLoop(
758 const std::list<PHV::ContainerGroup *> &container_groups,
const ScoreContext &score_ctx);
772 const std::set<PHV::Allocation::AvailableSpot> &spots);
785 const std::list<PHV::ContainerGroup *> &container_groups);
788 std::optional<const PHV::SuperCluster::SliceList *> diagnose_slicing(
789 const std::list<PHV::SuperCluster *> &slicing,
790 const std::list<PHV::ContainerGroup *> &container_groups)
const;
796 std::optional<const PHV::SuperCluster::SliceList *> preslice_validation(
797 const std::list<PHV::SuperCluster *> &sliced,
798 const std::list<PHV::ContainerGroup *> &container_groups)
const;
819 const IR::BFN::Pipe *root =
nullptr;
822 std::list<const PHV::SuperCluster *> &unallocated_i;
826 const IR::Node *apply_visitor(
const IR::Node *root,
const char *name = 0)
override;
830 static void formatAndThrowUnsat(
const std::list<const PHV::SuperCluster *> &unallocated);
840 std::vector<const PHV::SuperCluster::SliceList *> &unallocatable_lists,
841 std::list<PHV::SuperCluster *> &cluster_groups,
842 const std::list<PHV::ContainerGroup *> &container_groups,
const int pipe_id)
const;
847 std::list<const PHV::SuperCluster *> &unallocated)
853 unallocated_i(unallocated) {}
858 static bool diagnoseFailures(
const std::list<const PHV::SuperCluster *> &unallocated,
864 const std::list<const PHV::SuperCluster *> &unallocated);
883 const IR::Node *apply_visitor(
const IR::Node *root,
const char *name = 0)
override;
890 core_alloc_i(utils,
true),
892 settings_i(settings),
893 temp_vars_i(temp_vars) {}
Definition action_phv_constraints.h:107
bool hasPackConflict(const PHV::FieldSlice fs1, const PHV::FieldSlice fs2) const
Definition action_phv_constraints.h:825
Definition allocate_phv.h:813
static bool diagnoseFailures(const std::list< const PHV::SuperCluster * > &unallocated, const PHV::AllocUtils &utils)
Definition allocate_phv.cpp:4285
static void formatAndThrowError(const PHV::Allocation &alloc, const std::list< const PHV::SuperCluster * > &unallocated)
Definition allocate_phv.cpp:4463
Definition allocate_phv.h:650
virtual AllocResult tryAllocation(const PHV::Allocation &alloc, const std::list< PHV::SuperCluster * > &cluster_groups_input, const std::list< PHV::ContainerGroup * > &container_groups)=0
Definition allocate_phv.h:694
void sortClusters(std::list< PHV::SuperCluster * > &cluster_groups)
Sort list of superclusters into the order in which they should be allocated.
Definition allocate_phv.cpp:4979
AllocResult tryAllocation(const PHV::Allocation &alloc, const std::list< PHV::SuperCluster * > &cluster_groups_input, const std::list< PHV::ContainerGroup * > &container_groups) override
Definition allocate_phv.cpp:4940
std::optional< PHV::Transaction > tryVariousSlicing(PHV::Transaction &rst, PHV::SuperCluster *cluster_group, const std::list< PHV::ContainerGroup * > &container_groups, const ScoreContext &score_ctx, std::stringstream &alloc_history)
Definition allocate_phv.cpp:5548
std::list< PHV::SuperCluster * > preslice_clusters(const std::list< PHV::SuperCluster * > &cluster_groups, const std::list< PHV::ContainerGroup * > &container_groups, std::list< const PHV::SuperCluster * > &unsliceable)
slice clusters into clusters with container-sized chunks.
Definition allocate_phv.cpp:4797
std::list< PHV::SuperCluster * > pounderRoundAllocLoop(PHV::Transaction &rst, std::list< PHV::SuperCluster * > &cluster_groups, const std::list< PHV::ContainerGroup * > &container_groups)
Definition allocate_phv.cpp:4698
ordered_set< bitvec > calc_slicing_schemas(const PHV::SuperCluster *sc, const std::set< PHV::Allocation::AvailableSpot > &spots)
Definition allocate_phv.cpp:4594
std::list< PHV::SuperCluster * > allocDeparserZeroSuperclusters(PHV::Transaction &rst, std::list< PHV::SuperCluster * > &cluster_groups)
Definition allocate_phv.cpp:4635
Definition optimize_phv.h:64
Definition parser_critical_path.h:131
Definition clot_info.h:41
Builds "clusters" of field slices that must be placed in the same group.
Definition make_clusters.h:67
bool no_pack(const PHV::Field *a, const PHV::Field *b) const
Definition make_clusters.h:552
const std::list< PHV::SuperCluster * > & cluster_groups() const
Definition make_clusters.h:548
Definition allocate_phv.h:352
std::optional< PHV::Transaction > tryAllocSliceList(const PHV::Allocation &alloc, const PHV::ContainerGroup &group, const PHV::SuperCluster &super_cluster, const PHV::Allocation::ConditionalConstraint &start_positions, const ScoreContext &score_ctx) const
Definition allocate_phv.cpp:2800
std::optional< PHV::Transaction > try_alloc(const PHV::Allocation &alloc, const PHV::ContainerGroup &group, PHV::SuperCluster &cluster, int max_alignment_tries, const ScoreContext &score_ctx) const
Definition allocate_phv.cpp:3744
static bool some_overlay(const SymBitMatrix &mutually_exclusive_field_ids, const PHV::Field *f, const ordered_set< PHV::AllocSlice > &slices)
Definition allocate_phv.cpp:1158
std::optional< PHV::Transaction > try_deparser_zero_alloc(const PHV::Allocation &alloc, PHV::SuperCluster &cluster, PhvInfo &phv) const
Definition allocate_phv.cpp:4655
bool satisfies_constraints(std::vector< PHV::AllocSlice > slices, const PHV::Allocation &alloc) const
Definition allocate_phv.cpp:1211
PHV::Transaction make_speculated_alloc(const PHV::Transaction &alloc, const PHV::SuperCluster &sc, const std::vector< PHV::AllocSlice > &candidates, const PHV::Container &c) const
bool hasARAinits(ordered_set< PHV::AllocSlice > slices) const
@look for ARA inits in set of slices
Definition allocate_phv.cpp:1179
static bool can_overlay(const SymBitMatrix &mutually_exclusive_field_ids, const PHV::Field *f, const ordered_set< PHV::AllocSlice > &slices)
Definition allocate_phv.cpp:1150
bool rangesOverlap(const PHV::AllocSlice &slice, const IR::BFN::ParserPrimitive *prim) const
Do the slice and prim have overlapping field ranges.
Definition allocate_phv.cpp:1986
bool can_physical_liverange_overlay(const PHV::AllocSlice &slice, const ordered_set< PHV::AllocSlice > &allocated) const
Definition allocate_phv.cpp:1165
bool checkParserExtractions(const std::vector< PHV::AllocSlice > &candidate_slices, const PHV::Transaction &alloc) const
Definition allocate_phv.cpp:2009
Definition dark_live_range.h:389
Definition allocate_phv.h:213
FieldPackingOpportunity(const std::list< PHV::SuperCluster * > &sorted_clusters, const ActionPhvConstraints &actions, const PhvUse &uses, const FieldDefUse &defuse, const SymBitMatrix &mutex)
sorted_clusters is a list of clusters that we will allocated, in this order.
Definition allocate_phv.cpp:5766
int nOpportunitiesAfter(const PHV::Field *f1, const PHV::Field *f2) const
Definition allocate_phv.cpp:5789
int nOpportunities(const PHV::Field *f) const
How many fields, after f is allocated, can be packed with f.
Definition allocate_phv.h:236
Definition allocate_phv.h:873
Definition live_range_shrinking.h:183
Definition mau_backtracker.h:29
bool disableMetadataInitialization() const
Definition mau_backtracker.h:105
Definition symbitmatrix.h:27
Definition ordered_map.h:32
ActionSourceTracker collects all source-to-destination for all field slices.
Definition action_source_tracker.h:49
Definition slice_alloc.h:136
Definition phv/utils/utils.h:117
Definition phv/utils/utils.h:506
Definition phv/utils/utils.h:37
Definition phv_fields.h:154
int id
Unique field ID.
Definition phv_fields.h:164
bool padding
True if this Field is a padding field.
Definition phv_fields.h:222
Definition phv_fields.h:898
const PHV::Field * field() const override
Definition phv_fields.h:977
Definition fieldslice_live_range.h:152
Definition phv_pragmas.h:46
The interface that the iterator must satisfy.
Definition slicing/types.h:108
Definition phv/utils/utils.h:1049
Definition phv/utils/utils.h:561
bool is_referenced(const PHV::Field *f) const
Definition phv_parde_mau_use.cpp:179
Definition phv_fields.h:1095
Definition phv_parde_mau_use.h:154
ScoreContext can compute a alloc score for an PHV::Transaction.
Definition allocate_phv.h:306
Definition table_phv_constraints.h:97
Definition field_defuse.h:77
The namespace encapsulating PHV-related stuff.
Definition gateway.h:32
Definition alloc_setting.h:25
AllocAlignment has two maps used by tryAllocSliceList.
Definition allocate_phv.h:343
ordered_map< PHV::FieldSlice, int > slice_alignment
a slice_alignment maps field slice to start bit location in a container.
Definition allocate_phv.h:345
ordered_map< const PHV::AlignedCluster *, int > cluster_alignment
a cluster_alignment maps aligned cluster to start bit location in a container.
Definition allocate_phv.h:347
Definition allocate_phv.h:626
Definition allocate_phv.h:258
std::function< bool(const AllocScore &left, const AllocScore &right)> IsBetterFunc
IsBetterFunc returns true if left is better than right.
Definition allocate_phv.h:262
static const std::vector< MetricName > g_by_kind_metrics
container-kind-specific scores.
Definition allocate_phv.h:786
cstring MetricName
type of the name of a metric.
Definition allocate_phv.h:265
static const std::vector< MetricName > g_general_metrics
general metrics
Definition allocate_phv.h:780
Definition allocate_phv.h:672
Map field to the parser states in which they are extracted or assigned from checksums.
Definition phv_fields.h:1755
Definition allocate_phv.h:55
static std::list< PHV::SuperCluster * > remove_clot_allocated_clusters(const ClotInfo &clot, std::list< PHV::SuperCluster * > clusters)
Definition allocate_phv.cpp:771
static bool is_clot_allocated(const ClotInfo &clots, const PHV::SuperCluster &sc)
Definition allocate_phv.cpp:688
static void bind_slices(const PHV::ConcreteAllocation &alloc, PhvInfo &phv)
Definition allocate_phv.cpp:3847
static std::list< PHV::SuperCluster * > remove_unref_clusters(const PhvUse &uses, const std::list< PHV::SuperCluster * > &cluster_groups_input)
Definition allocate_phv.cpp:757
static void clear_slices(PhvInfo &phv)
clear alloc_slices allocated in phv, if any.
Definition allocate_phv.cpp:3842
static std::list< PHV::SuperCluster * > remove_singleton_metadata_slicelist(const std::list< PHV::SuperCluster * > &cluster_groups)
Definition allocate_phv.cpp:717
static std::list< PHV::ContainerGroup * > make_device_container_groups()
Definition allocate_phv.cpp:3809
static void sort_and_merge_alloc_slices(PhvInfo &phv)
Definition allocate_phv.cpp:4036
std::list< PHV::SuperCluster * > make_superclusters() const
Definition allocate_phv.h:136
static std::list< PHV::SuperCluster * > create_strided_clusters(const CollectStridedHeaders &strided_headers, const std::list< PHV::SuperCluster * > &cluster_groups)
Definition allocate_phv.cpp:3937
static bool update_refs(AllocSlice &slc, const PhvInfo &p, const FieldDefUse::LocPairSet &refs, FieldUse fuse)
Definition allocate_phv.cpp:3872