117 bool prelim_constraints_ok =
true;
119 struct ClassifiedSource {
126 friend std::ostream &operator<<(std::ostream &out,
127 const ActionPhvConstraints::ClassifiedSource &src);
129 using ClassifiedSources = std::array<ClassifiedSource, 2>;
133 struct NumContainers {
134 size_t num_allocated;
135 size_t num_unallocated;
136 bool double_unallocated =
false;
138 explicit NumContainers(
const size_t numAlloc,
const size_t numUnalloc)
139 : num_allocated(numAlloc), num_unallocated(numUnalloc) {}
141 NumContainers() : num_allocated(0), num_unallocated(0) {}
144 typedef enum action_data_uses_t {
145 SOME_AD_CONSTANT = 0,
147 COMPLEX_AD_PACKING_REQ = 2,
155 int unique_action_id = -1;
156 enum field_read_flags_t {
159 WHOLE_CONTAINER = (1 << 2),
160 ANOTHER_OPERAND = (1 << 3),
162 WHOLE_CONTAINER_SAME_FIELD = (1 << 5),
163 PART_OF_CONTAINER = (1 << 6),
170 unsigned special_ad = ActionAnalysis::ActionParam::NO_SPECIAL;
171 bool constant =
false;
172 int64_t const_value = 0;
173 std::optional<PHV::FieldSlice> phv_used = std::nullopt;
177 bool operator<(OperandInfo other)
const {
181 else if (!ad && other.ad)
183 else if (constant && !other.constant)
185 else if (!constant && other.constant)
187 else if (constant && other.constant)
188 return const_value < other.const_value;
189 else if (phv_used && !other.phv_used)
191 else if (!phv_used && other.phv_used)
193 else if (!phv_used && !other.phv_used)
195 else if (phv_used->field()->id != other.phv_used->field()->id)
196 return phv_used->field()->id < other.phv_used->field()->id;
197 else if (phv_used->range().lo != other.phv_used->range().lo)
198 return phv_used->range().lo < other.phv_used->range().lo;
200 return phv_used->range().hi < other.phv_used->range().hi;
203 bool operator==(OperandInfo other)
const {
204 return phv_used == other.phv_used && ad == other.ad && constant == other.constant &&
205 const_value == other.const_value;
208 bool operator==(
const PHV::Field *field)
const {
209 return phv_used && phv_used->field()->id == field->
id;
212 std::string toString()
const {
213 std::stringstream ss;
219 : unique_action_id(
id), phv_used(slice) {}
224 friend std::ostream &operator<<(std::ostream &out,
225 const ActionPhvConstraints::OperandInfo &
info);
227 friend std::ostream &operator<<(std::ostream &out,
230 class ConstraintTracker {
232 ActionPhvConstraints &self;
238 field_writes_to_actions;
256 write_to_reads_per_action;
261 read_to_writes_per_action;
271 static int current_action;
274 ConstraintTracker(
const PhvInfo &phv, ActionPhvConstraints &self) : phv(phv), self(self) {}
280 void add_action(
const IR::MAU::Action *act,
281 const ActionAnalysis::FieldActionsMap field_actions_map,
282 const IR::MAU::Table *tbl);
287 std::optional<bool> hasPHVSource(
const PHV::Field *field,
const IR::MAU::Action *act)
const;
292 std::optional<bool> hasActionDataOrConstantSource(
const PHV::Field *field,
293 const IR::MAU::Action *act)
const;
301 const IR::MAU::Action *act)
const;
306 const IR::MAU::Action *act)
const {
316 const IR::MAU::Action *act)
const;
321 const IR::MAU::Action *act)
const {
354 const IR::MAU::Action *act)
const;
361 const IR::MAU::Action *act)
const {
387 std::optional<int> can_be_both_sources(
const std::vector<PHV::AllocSlice> &slices,
392 void printMapStates()
const;
397 void print_field_ordering(
const std::vector<PHV::AllocSlice> &slices)
const;
404 getStatefulWrites()
const {
405 return statefulWrites;
409 const IR::MAU::Table *action_table(
const IR::MAU::Action *)
const;
412 ConstraintTracker constraint_tracker;
415 struct ActionContainerProperty {
417 NumContainers sources;
418 bool must_be_aligned;
425 bool aligned_one_unallocated =
false;
426 bool aligned_two_unallocated =
false;
427 bool aligned_unallocated_requires_aligment =
false;
430 using ActionPropertyMap =
440 bool preorder(
const IR::MAU::Action *act)
override;
443 void end_apply()
override;
445 void determine_same_byte_fields();
453 bool early_check_ok(
const IR::MAU::Action *action);
458 UnionFind<PHV::FieldSlice> classify_PHV_sources(
467 bool diagnoseInvalidPacking(
468 const IR::MAU::Action *action,
const PHV::SuperCluster::SliceList *list,
471 std::stringstream &ss)
const;
481 void throw_too_many_sources_error(
484 const UnionFind<PHV::FieldSlice> &phvSources,
486 const IR::MAU::Action *action, std::stringstream &ss)
const;
492 void throw_non_contiguous_mask_error(
496 std::stringstream &ss)
const;
506 const PHV::Allocation::MutuallyLiveSlices &container_state,
507 const IR::MAU::Action *action)
const;
514 std::optional<PHV::AllocSlice> getSourcePHVSlice(
const PHV::Allocation &alloc,
515 const std::vector<PHV::AllocSlice> &slices,
517 const IR::MAU::Action *action,
518 const int stage)
const;
523 bool has_ad_or_constant_sources(
524 const PHV::Allocation::MutuallyLiveSlices &slices,
const IR::MAU::Action *action,
525 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
531 ActionDataUses all_or_none_constant_sources(
532 const PHV::Allocation::MutuallyLiveSlices &slices,
const IR::MAU::Action *act,
533 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
542 int unallocated_bits(PHV::Allocation::MutuallyLiveSlices,
const PHV::Container)
const;
546 bool are_adjacent_field_slices(
const PHV::Allocation::MutuallyLiveSlices &state)
const;
551 unsigned count_container_holes(
const PHV::Allocation::MutuallyLiveSlices &state)
const;
557 bool valid_container_operation_type(
const IR::MAU::Action *act,
559 std::stringstream &ss)
const;
568 unsigned container_operation_type(
const IR::MAU::Action *,
569 const PHV::Allocation::MutuallyLiveSlices &,
570 const PHV::Allocation::LiveRangeShrinkingMap &)
const;
583 const PHV::Allocation::MutuallyLiveSlices &container_state,
584 PackingConstraints *packing_constraints,
585 const IR::MAU::Action *action,
bool pack_unallocated_only,
586 bool has_ad_source =
false)
const;
591 std::optional<ClassifiedSources> verify_two_container_alignment(
592 const PHV::Allocation &alloc,
const PHV::Allocation::MutuallyLiveSlices &container_state,
594 ActionContainerProperty *action_prop)
const;
600 inline int getOffset(le_bitrange a, le_bitrange b,
PHV::Container c)
const;
604 bool masks_valid(
const ClassifiedSources &sources)
const;
609 bool is_aligned(
const PHV::Allocation::MutuallyLiveSlices &container_state,
617 bool masks_valid(
const PHV::Allocation::MutuallyLiveSlices &container_state,
618 const IR::MAU::Action *action,
bool actionDataOnly,
619 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
624 bool masks_valid(
const PHV::Allocation::MutuallyLiveSlices &container_state,
625 const IR::MAU::Action *action)
const;
632 bool assign_containers_to_unallocated_sources(
633 const PHV::Allocation &alloc,
const UnionFind<PHV::FieldSlice> &copacking_constraints,
649 std::optional<PHV::FieldSlice> get_smaller_source_slice(
650 const PHV::Allocation &alloc,
const UnionFind<PHV::FieldSlice> &copacking_constraints,
653 std::optional<PHV::FieldSlice> get_unallocated_slice(
654 const PHV::Allocation &alloc,
const UnionFind<PHV::FieldSlice> &copacking_constraints,
673 bool check_speciality_packing(
const PHV::Allocation::MutuallyLiveSlices &container_state)
const;
683 bool check_and_generate_constraints_for_move_with_unallocated_sources(
685 const PHV::Allocation::MutuallyLiveSlices &container_state,
686 const PHV::Allocation::LiveRangeShrinkingMap &initActions,
687 ActionContainerProperty *action_props, PackingConstraints *copacking_constraints)
const;
691 bool generate_conditional_constraints_for_bitwise_op(
692 const PHV::Allocation::MutuallyLiveSlices &container_state,
const IR::MAU::Action *action,
694 PackingConstraints *copacking_constraints)
const;
704 bool check_and_generate_constraints_for_bitwise_op_with_unallocated_sources(
705 const IR::MAU::Action *action,
const PHV::Allocation::MutuallyLiveSlices &container_state,
706 const NumContainers &sources, PackingConstraints *copacking_constraints)
const;
729 CanPackErrorCode check_and_generate_constraints_for_bitwise_or_move(
731 const PHV::Allocation::MutuallyLiveSlices &container_state,
const PHV::Container &c,
732 const PHV::Allocation::LiveRangeShrinkingMap &initActions, ActionPropertyMap *action_props,
733 PackingConstraints *copack_constraints)
const;
736 CanPackErrorCode check_and_generate_rotational_alignment_constraints(
737 const PHV::Allocation &alloc,
const std::vector<PHV::AllocSlice> &slices,
738 const PHV::ActionSet &actions,
const PHV::Allocation::MutuallyLiveSlices &container_state,
742 CanPackErrorCode check_and_generate_copack_set(
743 const PHV::Allocation &alloc,
const PHV::Allocation::MutuallyLiveSlices &container_state,
744 const PackingConstraints &copack_constraints,
const ActionPropertyMap &action_props,
749 CanPackReturnType check_and_generate_conditional_constraints(
750 const PHV::Allocation &alloc,
const std::vector<PHV::AllocSlice> &slices,
751 const PHV::Allocation::MutuallyLiveSlices &container_state,
756 bool stateful_destinations_constraints_violated(
757 const PHV::Allocation::MutuallyLiveSlices &container_state)
const;
761 bool check_speciality_read_and_bitmask(
762 const PHV::Allocation::MutuallyLiveSlices &container_state,
763 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
767 PHV::ActionSet make_writing_action_set(
768 const PHV::Allocation &alloc,
const PHV::Allocation::MutuallyLiveSlices &container_state,
769 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
772 ActionPropertyMap make_action_container_properties(
774 const PHV::Allocation::MutuallyLiveSlices &container_state,
775 const PHV::Allocation::LiveRangeShrinkingMap &initActions,
bool is_mocha_or_dark)
const;
778 PackingConstraints make_initial_copack_constraints(
779 const PHV::ActionSet &actions,
780 const PHV::Allocation::MutuallyLiveSlices &container_state)
const;
785 std::set<int> stages(
const IR::MAU::Action *action,
bool physical_stage)
const;
791 bool has_const =
false;
810 constraint_tracker(ConstraintTracker(p, *this)) {}
814 return meter_color_destinations.count(f) > 0;
821 return meter_color_destinations_8bit.count(f) > 0;
826 return conflicts.hasPackConflict(fs1, fs2);
838 return meter_color_destinations;
843 return meter_color_destinations_8bit;
848 return meter_color_destinations_8bit;
859 return constraint_tracker.written_in(fieldSlice);
874 const PHV::Field *dest,
const std::vector<PHV::FieldSlice> &slices)
const;
882 const PHV::Field *src,
const std::vector<PHV::FieldSlice> &slices)
const;
887 const IR::MAU::Action *action)
const;
897 const PHV::Allocation::MutuallyLiveSlices &container_state,
898 const PHV::ActionSet &set_of_actions,
899 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
903 const std::vector<PHV::AllocSlice> &slices)
const;
912 const PHV::Container &c,
const PHV::Allocation::MutuallyLiveSlices &container_state)
const;
932 const std::vector<PHV::AllocSlice> &slices,
933 const PHV::Allocation::MutuallyLiveSlices &original_container_state,
934 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
939 const PHV::ActionSet &actions,
const PHV::Allocation::MutuallyLiveSlices &container_state,
940 const ActionPropertyMap *action_props)
const;
944 const std::vector<PHV::AllocSlice> &slices)
const;
950 const PHV::Allocation::LiveRangeShrinkingMap &initActions,
956 const std::vector<PHV::AllocSlice> &slices,
957 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
972 void sort(std::list<const PHV::SuperCluster::SliceList *> &slice_list)
const;
977 void sort(std::vector<PHV::FieldSlice> &slice_list)
const;
986 void dest_first_sort(std::vector<const PHV::SuperCluster::SliceList *> &slice_list)
const;
993 return constraint_tracker.reads(act);
998 ordered_set<const PHV::Field *>
actionWrites(
const IR::MAU::Action *act)
const;
1000 const ordered_set<PHV::FieldSlice> actionWritesSlices(
const IR::MAU::Action *act)
const {
1001 ordered_set<PHV::FieldSlice> rs;
1002 auto &writtenSlices = constraint_tracker.writes(act);
1003 for (
auto &
info : writtenSlices)
1004 if (
info.phv_used != std::nullopt) rs.insert(*(
info.phv_used));
1017 const PHV::Allocation &alloc)
const;
1022 bool can_pack_pov(
const PHV::SuperCluster::SliceList *slice_list,
const PHV::Field *f)
const;
1030 const ordered_map<PHV::FieldSlice, unsigned> &fieldAlignments,
1031 std::stringstream &error_msg)
const;
1035 bool written_in(
const PHV::Field *f,
const IR::MAU::Action *act)
const;
1041 return constraint_tracker.written_in(field_slice).count(act);
1113 const std::vector<PHV::AllocSlice> &slices,
1114 const PHV::Allocation::MutuallyLiveSlices &container_state,
const PHV::Container &c,
1115 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
1129 const PHV::Allocation &alloc,
const PHV::Allocation::MutuallyLiveSlices &container_state,
1130 const PHV::Container &c,
const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
1136 const PHV::Allocation &alloc,
const std::vector<PHV::AllocSlice> &candidates,
1137 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
1142 const PHV::Allocation &alloc,
const std::vector<PHV::AllocSlice> &candidates,
1143 const IR::MAU::Action *action,
1144 const PHV::Allocation::LiveRangeShrinkingMap &initActions)
const;
1149 const PHV::Allocation &alloc,
const std::vector<PHV::AllocSlice> &candidates,
1150 const IR::MAU::Action *action)
const;