Skip to content

Commit 6520e1d

Browse files
allightcopybara-github
authored andcommitted
Add OptimizationContext to analysis passes and visitors.
This change modifies several analysis and pass implementations to accept and utilize an OptimizationContext. This allows them to leverage pre-computed topological sorts from the context, avoiding redundant computations. Specifically: - DataflowVisitor and BitProvenanceAnalysis are updated to use `OptimizationContext` for topological sorts. - PredicateDominatorAnalysis is updated to use `OptimizationContext` for reverse topological sorts. - DataflowSimplificationPass and SelectSimplificationPass now pass the `OptimizationContext` to the analyses they use. - Benchmarks for PredicateDominatorAnalysis are updated to test with and without sharing the `OptimizationContext`. PiperOrigin-RevId: 861883547
1 parent 4cdc72d commit 6520e1d

9 files changed

+154
-26
lines changed

xls/passes/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,7 @@ cc_library(
13371337
srcs = ["predicate_dominator_analysis.cc"],
13381338
hdrs = ["predicate_dominator_analysis.h"],
13391339
deps = [
1340+
":optimization_pass",
13401341
":predicate_state",
13411342
"//xls/common:strong_int",
13421343
"//xls/ir",
@@ -3193,6 +3194,7 @@ cc_test(
31933194
name = "predicate_dominator_analysis_test",
31943195
srcs = ["predicate_dominator_analysis_test.cc"],
31953196
deps = [
3197+
":optimization_pass",
31963198
":predicate_dominator_analysis",
31973199
":predicate_state",
31983200
"//xls/common:xls_gunit_main",
@@ -4080,6 +4082,7 @@ cc_library(
40804082
hdrs = ["bit_provenance_analysis.h"],
40814083
deps = [
40824084
":dataflow_visitor",
4085+
":optimization_pass",
40834086
":query_engine",
40844087
"//xls/common/status:ret_check",
40854088
"//xls/common/status:status_macros",

xls/passes/bit_provenance_analysis.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "xls/ir/nodes.h"
3535
#include "xls/ir/type.h"
3636
#include "xls/passes/dataflow_visitor.h"
37+
#include "xls/passes/optimization_pass.h"
3738
#include "xls/passes/query_engine.h"
3839

3940
namespace xls {
@@ -301,6 +302,13 @@ BitProvenanceAnalysis::CreatePrepopulated(FunctionBase* func) {
301302
XLS_RETURN_IF_ERROR(result.Populate(func));
302303
return result;
303304
}
305+
/* static */ absl::StatusOr<BitProvenanceAnalysis>
306+
BitProvenanceAnalysis::CreatePrepopulated(FunctionBase* func,
307+
OptimizationContext& context) {
308+
BitProvenanceAnalysis result;
309+
XLS_RETURN_IF_ERROR(result.Populate(func, context));
310+
return result;
311+
}
304312

305313
BitProvenanceAnalysis::BitProvenanceAnalysis()
306314
: visitor_{std::make_unique<internal::BitProvenanceVisitor>()} {}
@@ -320,6 +328,14 @@ absl::Status BitProvenanceAnalysis::Populate(FunctionBase* func) {
320328
XLS_RETURN_IF_ERROR(func->Accept(visitor_.get()));
321329
return absl::OkStatus();
322330
}
331+
absl::Status BitProvenanceAnalysis::Populate(FunctionBase* func,
332+
OptimizationContext& context) {
333+
for (Node* node : context.TopoSort(func)) {
334+
XLS_RETURN_IF_ERROR(node->VisitSingleNode(visitor_.get()));
335+
visitor_->MarkVisited(node);
336+
}
337+
return absl::OkStatus();
338+
}
323339

324340
absl::StatusOr<TreeBitLocation> BitProvenanceAnalysis::GetSource(
325341
const TreeBitLocation& bit) const {

xls/passes/bit_provenance_analysis.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "absl/types/span.h"
2929
#include "xls/data_structures/leaf_type_tree.h"
3030
#include "xls/ir/node.h"
31+
#include "xls/passes/optimization_pass.h"
3132
#include "xls/passes/query_engine.h"
3233

3334
namespace xls {
@@ -157,6 +158,8 @@ class BitProvenanceAnalysis {
157158
// invalid if the function is modified.
158159
static absl::StatusOr<BitProvenanceAnalysis> CreatePrepopulated(
159160
FunctionBase* func);
161+
static absl::StatusOr<BitProvenanceAnalysis> CreatePrepopulated(
162+
FunctionBase* func, OptimizationContext& context);
160163

161164
// constructors and destructors need to be declared here and implemented in
162165
// the .cc file to avoid the compiler inserting constructors and destructors
@@ -170,6 +173,7 @@ class BitProvenanceAnalysis {
170173
BitProvenanceAnalysis& operator=(BitProvenanceAnalysis&& other);
171174

172175
absl::Status Populate(FunctionBase* func);
176+
absl::Status Populate(FunctionBase* func, OptimizationContext& context);
173177

174178
// Get the tree-bit-location which provides the original source of the given
175179
// bit.

xls/passes/dataflow_simplification_pass.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,14 @@ absl::StatusOr<bool> DataflowSimplificationPass::RunOnFunctionBaseInternal(
8686
FunctionBase* func, const OptimizationPassOptions& options,
8787
PassResults* results, OptimizationContext& context) const {
8888
NodeSourceDataflowVisitor visitor;
89-
XLS_RETURN_IF_ERROR(func->Accept(&visitor));
89+
for (Node* node : context.TopoSort(func)) {
90+
XLS_RETURN_IF_ERROR(node->VisitSingleNode(&visitor));
91+
}
9092
bool changed = false;
9193
// Hashmap from the LTT<NodeSource> of a node to the Node*. If two nodes have
9294
// the same LTT<NodeSource> they are necessarily equivalent.
9395
absl::flat_hash_map<LeafTypeTreeView<NodeSource>, Node*> source_map;
96+
source_map.reserve(func->node_count());
9497
for (Node* node : context.TopoSort(func)) {
9598
LeafTypeTreeView<NodeSource> source = visitor.GetValue(node);
9699
VLOG(3) << absl::StrFormat("Considering `%s`: %s", node->GetName(),

xls/passes/narrowing_pass.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2258,7 +2258,7 @@ absl::StatusOr<bool> NarrowingPass::RunOnFunctionBaseInternal(
22582258
XLS_ASSIGN_OR_RETURN(AliasingQueryEngine query_engine,
22592259
GetQueryEngine(f, RealAnalysis(options), context));
22602260

2261-
PredicateDominatorAnalysis pda = PredicateDominatorAnalysis::Run(f);
2261+
PredicateDominatorAnalysis pda = PredicateDominatorAnalysis::Run(f, context);
22622262
SpecializedQueryEngines sqe(RealAnalysis(options), pda, query_engine);
22632263

22642264
NarrowVisitor narrower(sqe, RealAnalysis(options), options,

xls/passes/predicate_dominator_analysis.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
#include <cstddef>
1818
#include <cstdint>
19+
#include <functional>
1920
#include <optional>
2021
#include <ostream>
22+
#include <utility>
2123
#include <vector>
2224

2325
#include "absl/container/flat_hash_map.h"
@@ -27,6 +29,7 @@
2729
#include "xls/ir/node.h"
2830
#include "xls/ir/nodes.h"
2931
#include "xls/ir/topo_sort.h"
32+
#include "xls/passes/optimization_pass.h"
3033
#include "xls/passes/predicate_state.h"
3134

3235
namespace xls {
@@ -97,15 +100,16 @@ class AnalysisHelper {
97100
.previous = kRootPredicateId,
98101
.distance_to_root = 0};
99102

100-
explicit AnalysisHelper(FunctionBase* func) : function_(func) {}
103+
AnalysisHelper(FunctionBase* func, OptimizationContext& context)
104+
: function_(func), context_(context) {}
101105

102106
absl::flat_hash_map<Node*, PredicateState> Analyze() {
103107
CHECK(node_states_.empty());
104108
CHECK(predicate_stacks_.empty());
105109
node_states_.reserve(function_->node_count());
106110
predicate_stacks_.push_back(kRootPredicateStackNode);
107111
// Run in reverse topo sort order. Handle users before the values they use.
108-
for (Node* node : ReverseTopoSort(function_)) {
112+
for (Node* node : context_.ReverseTopoSort(function_)) {
109113
HandleNode(node);
110114
}
111115

@@ -259,15 +263,17 @@ class AnalysisHelper {
259263

260264
private:
261265
FunctionBase* function_;
266+
OptimizationContext& context_;
262267
// Map of node to the predicate list head they are guarded by.
263268
absl::flat_hash_map<Node*, PredicateStackId> node_states_;
264269
// Map from 'PredicateStackId' to the predicate node.
265270
std::vector<PredicateStackNode> predicate_stacks_;
266271
};
267272
} // namespace
268273

269-
PredicateDominatorAnalysis PredicateDominatorAnalysis::Run(FunctionBase* f) {
270-
AnalysisHelper helper(f);
274+
PredicateDominatorAnalysis PredicateDominatorAnalysis::Run(
275+
FunctionBase* f, OptimizationContext& context) {
276+
AnalysisHelper helper(f, context);
271277
return PredicateDominatorAnalysis(helper.Analyze());
272278
}
273279

xls/passes/predicate_dominator_analysis.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "absl/container/flat_hash_map.h"
2121
#include "xls/ir/function_base.h"
2222
#include "xls/ir/node.h"
23+
#include "xls/passes/optimization_pass.h"
2324
#include "xls/passes/predicate_state.h"
2425

2526
namespace xls {
@@ -38,7 +39,8 @@ class PredicateDominatorAnalysis {
3839
PredicateDominatorAnalysis& operator=(PredicateDominatorAnalysis&&) = default;
3940

4041
// Execute this analysis and return results.
41-
static PredicateDominatorAnalysis Run(FunctionBase* f);
42+
static PredicateDominatorAnalysis Run(FunctionBase* f,
43+
OptimizationContext& context);
4244

4345
// Returns a single element of the common predicate dominators which is
4446
// closest to the node (ie the last predicate which gates the use of this

0 commit comments

Comments
 (0)