Skip to content

Commit 7da94fa

Browse files
scampanonicopybara-github
authored andcommitted
This change exposes the core APIs of the resource sharing pass by changing their visibility from private to public.
PiperOrigin-RevId: 848278144
1 parent 7a58ea1 commit 7da94fa

File tree

2 files changed

+148
-95
lines changed

2 files changed

+148
-95
lines changed

xls/passes/resource_sharing_pass.cc

Lines changed: 55 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -63,34 +63,6 @@
6363

6464
namespace xls {
6565

66-
namespace {
67-
68-
// TODO: replace with a single visibility analysis that computes a variety of
69-
// conservative visibility expressions with different trade-offs and that
70-
// can be queried to provide the simplest visibility expressions it knows which
71-
// prove the mutual exclusivity of a set of nodes.
72-
struct VisibilityAnalyses {
73-
const VisibilityAnalysis& general;
74-
const SingleSelectVisibilityAnalysis& single_select;
75-
};
76-
77-
struct MutuallyExclPair {
78-
Node* one;
79-
Node* other;
80-
MutuallyExclPair(Node* a, Node* b)
81-
: one(std::min(a, b, NodeIdLessThan)),
82-
other(std::max(a, b, NodeIdLessThan)) {}
83-
bool operator==(const MutuallyExclPair& o) const {
84-
return one == o.one && other == o.other;
85-
}
86-
template <typename H>
87-
friend H AbslHashValue(H h, const MutuallyExclPair& d) {
88-
return H::combine(std::move(h), d.one, d.other);
89-
}
90-
};
91-
92-
} // namespace
93-
9466
class TimingAnalysis {
9567
public:
9668
TimingAnalysis(
@@ -250,7 +222,6 @@ bool CanMapOpInto(Node* node_to_map, Node* folding_destination) {
250222
// Check if we are currently capable to potentially handle the node given as
251223
// input for folding.
252224
bool CanTarget(Node* n) {
253-
// We handle multipliers and adders
254225
if (n->OpIn({Op::kUMul, Op::kSMul, Op::kAdd, Op::kSub, Op::kShrl, Op::kShra,
255226
Op::kShll, Op::kDynamicBitSlice})) {
256227
return true;
@@ -298,19 +269,10 @@ bool CanTarget(Node* n, Node* selector,
298269
return !nda.IsDependent(n, selector);
299270
}
300271

301-
// This function computes the set of mutual exclusive pairs of instructions.
302-
// Each pair of instruction is associated with the select (of any kind) that
303-
// made them mutually exclusive.
304-
// We later use this association to extract the conditions to decide which
305-
// inputs to use at the folded remaining node.
306-
//
307-
// This analysis is conservative and as such it might generate false negatives.
308-
// In other words, some mutually-exclusive pairs of instructions might not be
309-
// detected by this analysis.
310-
// Hence, this analysis can be improved in the future.
311-
absl::StatusOr<absl::flat_hash_set<MutuallyExclPair>>
312-
ComputeMutualExclusionAnalysis(FunctionBase* f, OptimizationContext& context,
313-
const VisibilityAnalyses& visibility) {
272+
absl::StatusOr<absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>>
273+
ResourceSharingPass::ComputeMutualExclusionAnalysis(
274+
FunctionBase* f, OptimizationContext& context,
275+
const VisibilityAnalyses& visibility) {
314276
absl::flat_hash_set<MutuallyExclPair> mutual_exclusivity;
315277

316278
std::vector<Node*> relevant_nodes;
@@ -357,10 +319,8 @@ ComputeMutualExclusionAnalysis(FunctionBase* f, OptimizationContext& context,
357319
return mutual_exclusivity;
358320
}
359321

360-
// This function returns all possible folding actions that we can legally
361-
// perform.
362322
absl::StatusOr<std::vector<std::unique_ptr<BinaryFoldingAction>>>
363-
ComputeFoldableActions(
323+
ResourceSharingPass::ComputeFoldableActions(
364324
FunctionBase* f, absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
365325
const VisibilityAnalyses& visibility) {
366326
std::vector<std::unique_ptr<BinaryFoldingAction>> foldable_actions;
@@ -452,12 +412,8 @@ bool GreaterBitwidthComparator(BinaryFoldingAction* a0,
452412
return a0_bitwidth > a1_bitwidth;
453413
}
454414

455-
// MakeNaryFoldingActions creates a single n-ary folding action from as many of
456-
// the provided binary foldings as possible, given our understanding of the
457-
// visibility of these nodes. It is possible that one of the binary foldings is
458-
// on a node whose conservative visibility expression is too complicated to
459-
// analyze efficiently, in which case we must drop that binary folding.
460-
absl::StatusOr<std::unique_ptr<NaryFoldingAction>> MakeNaryFoldingAction(
415+
absl::StatusOr<std::unique_ptr<NaryFoldingAction>>
416+
ResourceSharingPass::MakeNaryFoldingAction(
461417
std::vector<BinaryFoldingAction*>& subset_of_edges_to_n, double area_saved,
462418
const VisibilityAnalyses& visibility) {
463419
XLS_RET_CHECK_NE(subset_of_edges_to_n.size(), 0);
@@ -520,8 +476,9 @@ absl::StatusOr<std::unique_ptr<NaryFoldingAction>> MakeNaryFoldingAction(
520476
// For example, when only multiplications that have the same bit-widths are
521477
// considered.
522478
absl::StatusOr<std::vector<std::unique_ptr<NaryFoldingAction>>>
523-
SelectFoldingActionsBasedOnCliques(FoldingGraph* folding_graph,
524-
const VisibilityAnalyses& visibility) {
479+
SelectFoldingActionsBasedOnCliques(
480+
FoldingGraph* folding_graph,
481+
const ResourceSharingPass::VisibilityAnalyses& visibility) {
525482
std::vector<std::unique_ptr<NaryFoldingAction>> folding_actions_to_perform;
526483

527484
// Choose all of them matching the maximum cliques of the folding graph
@@ -558,8 +515,8 @@ SelectFoldingActionsBasedOnCliques(FoldingGraph* folding_graph,
558515

559516
// Create a single n-ary folding action for the whole clique
560517
std::unique_ptr<NaryFoldingAction> new_action;
561-
XLS_ASSIGN_OR_RETURN(new_action,
562-
MakeNaryFoldingAction(folds, area_saved, visibility));
518+
XLS_ASSIGN_OR_RETURN(new_action, ResourceSharingPass::MakeNaryFoldingAction(
519+
folds, area_saved, visibility));
563520
folding_actions_to_perform.push_back(std::move(new_action));
564521
}
565522

@@ -625,14 +582,16 @@ absl::StatusOr<double> EstimateAreaForNegatingNode(Node* n,
625582
// into a single n-ary folding on the same destination. Note that binary
626583
// foldings are sorted by benefit (e.g maximizing area savings) in descending
627584
// order, meaning 'previous' is more important than 'next'.
628-
bool CanFoldTogether(absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
585+
bool CanFoldTogether(absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>&
586+
mutual_exclusivity,
629587
BinaryFoldingAction* next, BinaryFoldingAction* previous) {
630588
if (previous->GetTo() != next->GetTo()) {
631589
return false;
632590
}
633591
Node* prev_node = previous->GetFrom();
634592
Node* next_node = next->GetFrom();
635-
if (mutual_exclusivity.contains(MutuallyExclPair(prev_node, next_node))) {
593+
if (mutual_exclusivity.contains(
594+
ResourceSharingPass::MutuallyExclPair(prev_node, next_node))) {
636595
return true;
637596
}
638597
VLOG(4) << " Excluding the following source because it is not "
@@ -769,8 +728,10 @@ absl::StatusOr<NaryFoldEstimate> SelectSubsetOfFolds(
769728
absl::StatusOr<std::vector<std::unique_ptr<NaryFoldingAction>>>
770729
ListOfAllFoldingActionsWithDestination(
771730
Node* n, FoldingGraph* folding_graph,
772-
absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
773-
const VisibilityAnalyses& visibility, const AreaEstimator& area_estimator,
731+
absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>&
732+
mutual_exclusivity,
733+
const ResourceSharingPass::VisibilityAnalyses& visibility,
734+
const AreaEstimator& area_estimator,
774735
const CriticalPathDelayAnalysis& critical_path_delay,
775736
VisibilityEstimator* visibility_estimator) {
776737
std::vector<std::unique_ptr<NaryFoldingAction>>
@@ -844,9 +805,9 @@ ListOfAllFoldingActionsWithDestination(
844805
// Create the hyper-edge by merging all these edges
845806
// Notice this is possible because all edges in @edges_to_n are guaranteed
846807
// to have @n as destination.
847-
XLS_ASSIGN_OR_RETURN(
848-
std::unique_ptr<NaryFoldingAction> new_action,
849-
MakeNaryFoldingAction(estimate.folds, estimate.area_saved, visibility));
808+
XLS_ASSIGN_OR_RETURN(std::unique_ptr<NaryFoldingAction> new_action,
809+
ResourceSharingPass::MakeNaryFoldingAction(
810+
estimate.folds, estimate.area_saved, visibility));
850811
potential_folding_actions_to_perform.push_back(std::move(new_action));
851812

852813
return potential_folding_actions_to_perform;
@@ -857,8 +818,10 @@ ListOfAllFoldingActionsWithDestination(
857818
absl::StatusOr<std::vector<std::unique_ptr<NaryFoldingAction>>>
858819
ListOfFoldingActionsWithDestination(
859820
Node* n, FoldingGraph* folding_graph,
860-
absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
861-
const VisibilityAnalyses& visibility, const AreaEstimator& area_estimator,
821+
absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>&
822+
mutual_exclusivity,
823+
const ResourceSharingPass::VisibilityAnalyses& visibility,
824+
const AreaEstimator& area_estimator,
862825
const CriticalPathDelayAnalysis& critical_path_delay,
863826
VisibilityEstimator* visibility_estimator) {
864827
std::vector<std::unique_ptr<NaryFoldingAction>>
@@ -954,25 +917,20 @@ ListOfFoldingActionsWithDestination(
954917
// Create the hyper-edge by merging all these edges
955918
// Notice this is possible because all edges in @edges_to_n are guaranteed
956919
// to have @n as destination.
957-
XLS_ASSIGN_OR_RETURN(
958-
std::unique_ptr<NaryFoldingAction> new_action,
959-
MakeNaryFoldingAction(estimate.folds, estimate.area_saved, visibility));
920+
XLS_ASSIGN_OR_RETURN(std::unique_ptr<NaryFoldingAction> new_action,
921+
ResourceSharingPass::MakeNaryFoldingAction(
922+
estimate.folds, estimate.area_saved, visibility));
960923
potential_folding_actions_to_perform.push_back(std::move(new_action));
961924
}
962925
return potential_folding_actions_to_perform;
963926
}
964927

965-
// Legalizes a sequence of folding actions by removing or modifying actions
966-
// that conflict.
967-
//
968-
// Returns a pair where the first element is the legalized sequence of
969-
// actions and the second element is a boolean that is true if the input
970-
// sequence was modified.
971928
absl::StatusOr<std::pair<std::vector<std::unique_ptr<NaryFoldingAction>>, bool>>
972-
LegalizeSequenceOfFolding(
929+
ResourceSharingPass::LegalizeSequenceOfFolding(
973930
absl::Span<const std::unique_ptr<NaryFoldingAction>>
974931
potential_folding_actions_to_perform,
975-
absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
932+
absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>&
933+
mutual_exclusivity,
976934
std::optional<const AreaEstimator*> area_estimator) {
977935
std::vector<std::unique_ptr<NaryFoldingAction>> folding_actions_to_perform;
978936
bool modified = false;
@@ -1286,8 +1244,10 @@ void SortNodesInDescendingOrderOfTheirInDegree(std::vector<Node*>& nodes,
12861244
absl::StatusOr<std::vector<std::unique_ptr<NaryFoldingAction>>>
12871245
SelectFoldingActionsBasedOnInDegree(
12881246
OptimizationContext& context, FoldingGraph* folding_graph,
1289-
absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
1290-
const VisibilityAnalyses& visibility, const AreaEstimator& area_estimator,
1247+
absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>&
1248+
mutual_exclusivity,
1249+
const ResourceSharingPass::VisibilityAnalyses& visibility,
1250+
const AreaEstimator& area_estimator,
12911251
const CriticalPathDelayAnalysis& critical_path_delay,
12921252
VisibilityEstimator* visibility_estimator) {
12931253
// Get the nodes of the folding graph
@@ -1379,7 +1339,7 @@ SelectFoldingActionsBasedOnInDegree(
13791339
std::vector<std::unique_ptr<NaryFoldingAction>> folding_actions_to_perform;
13801340
XLS_ASSIGN_OR_RETURN(
13811341
std::tie(folding_actions_to_perform, std::ignore),
1382-
LegalizeSequenceOfFolding(
1342+
ResourceSharingPass::LegalizeSequenceOfFolding(
13831343
std::move(
13841344
potential_folding_actions_to_perform_without_timing_problems),
13851345
mutual_exclusivity, &area_estimator));
@@ -1401,8 +1361,10 @@ SelectFoldingActionsBasedOnInDegree(
14011361
absl::StatusOr<std::vector<std::unique_ptr<NaryFoldingAction>>>
14021362
SelectAllFoldingActions(
14031363
OptimizationContext& context, FoldingGraph* folding_graph,
1404-
absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
1405-
const VisibilityAnalyses& visibility, const AreaEstimator& area_estimator,
1364+
absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>&
1365+
mutual_exclusivity,
1366+
const ResourceSharingPass::VisibilityAnalyses& visibility,
1367+
const AreaEstimator& area_estimator,
14061368
const CriticalPathDelayAnalysis& critical_path_delay,
14071369
VisibilityEstimator* visibility_estimator) {
14081370
// Get the nodes of the folding graph
@@ -1466,10 +1428,10 @@ SelectAllFoldingActions(
14661428
// However, a given n-ary folding action might be illegal if another one run
14671429
// before.
14681430
std::vector<std::unique_ptr<NaryFoldingAction>> folding_actions_to_perform;
1469-
XLS_ASSIGN_OR_RETURN(
1470-
std::tie(folding_actions_to_perform, std::ignore),
1471-
LegalizeSequenceOfFolding(std::move(potential_folding_actions_to_perform),
1472-
mutual_exclusivity, &area_estimator));
1431+
XLS_ASSIGN_OR_RETURN(std::tie(folding_actions_to_perform, std::ignore),
1432+
ResourceSharingPass::LegalizeSequenceOfFolding(
1433+
std::move(potential_folding_actions_to_perform),
1434+
mutual_exclusivity, &area_estimator));
14731435

14741436
return folding_actions_to_perform;
14751437
}
@@ -1480,8 +1442,9 @@ SelectAllFoldingActions(
14801442
absl::StatusOr<std::vector<std::unique_ptr<NaryFoldingAction>>>
14811443
SelectRandomlyFoldingActions(
14821444
FoldingGraph* folding_graph,
1483-
absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
1484-
const VisibilityAnalyses& visibility) {
1445+
absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>&
1446+
mutual_exclusivity,
1447+
const ResourceSharingPass::VisibilityAnalyses& visibility) {
14851448
std::vector<std::unique_ptr<NaryFoldingAction>> folding_actions_to_perform;
14861449

14871450
// Get all edges of the folding graph
@@ -1529,8 +1492,8 @@ SelectRandomlyFoldingActions(
15291492

15301493
// Create a single n-ary folding action
15311494
std::unique_ptr<NaryFoldingAction> new_action;
1532-
XLS_ASSIGN_OR_RETURN(new_action,
1533-
MakeNaryFoldingAction(folds, area_saved, visibility));
1495+
XLS_ASSIGN_OR_RETURN(new_action, ResourceSharingPass::MakeNaryFoldingAction(
1496+
folds, area_saved, visibility));
15341497

15351498
// Add the new n-ary folding action to the list of actions to perform
15361499
folding_actions_to_perform.push_back(std::move(new_action));
@@ -1545,8 +1508,9 @@ SelectRandomlyFoldingActions(
15451508
absl::StatusOr<std::vector<std::unique_ptr<NaryFoldingAction>>>
15461509
SelectFoldingActions(OptimizationContext& context, FoldingGraph* folding_graph,
15471510
ResourceSharingPass::ProfitabilityGuard heuristics,
1548-
absl::flat_hash_set<MutuallyExclPair>& mutual_exclusivity,
1549-
const VisibilityAnalyses& visibility,
1511+
absl::flat_hash_set<ResourceSharingPass::MutuallyExclPair>&
1512+
mutual_exclusivity,
1513+
const ResourceSharingPass::VisibilityAnalyses& visibility,
15501514
const AreaEstimator& area_estimator,
15511515
const CriticalPathDelayAnalysis& critical_path_delay,
15521516
VisibilityEstimator* visibility_estimator) {
@@ -1625,11 +1589,7 @@ SelectFoldingActions(OptimizationContext& context, FoldingGraph* folding_graph,
16251589
return folding_actions_to_perform;
16261590
}
16271591

1628-
// This function performs the folding actions specified in its input following
1629-
// the order specified.
1630-
// @next_node_id is used to determine what nodes were generated by this pass
1631-
// and is only used for logging purposes; see ToMathNotation.
1632-
absl::StatusOr<bool> PerformFoldingActions(
1592+
absl::StatusOr<bool> ResourceSharingPass::PerformFoldingActions(
16331593
FunctionBase* f, int64_t next_node_id,
16341594
VisibilityBuilder* visibility_builder,
16351595
const std::vector<std::unique_ptr<NaryFoldingAction>>&

0 commit comments

Comments
 (0)