Skip to content

Commit 0988b2b

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 0988b2b

9 files changed

+161
-27
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: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <cstdint>
1919
#include <optional>
2020
#include <ostream>
21+
#include <utility>
2122
#include <vector>
2223

2324
#include "absl/container/flat_hash_map.h"
@@ -26,7 +27,7 @@
2627
#include "xls/ir/function_base.h"
2728
#include "xls/ir/node.h"
2829
#include "xls/ir/nodes.h"
29-
#include "xls/ir/topo_sort.h"
30+
#include "xls/passes/optimization_pass.h"
3031
#include "xls/passes/predicate_state.h"
3132

3233
namespace xls {
@@ -97,15 +98,16 @@ class AnalysisHelper {
9798
.previous = kRootPredicateId,
9899
.distance_to_root = 0};
99100

100-
explicit AnalysisHelper(FunctionBase* func) : function_(func) {}
101+
AnalysisHelper(FunctionBase* func, OptimizationContext& context)
102+
: function_(func), context_(context) {}
101103

102104
absl::flat_hash_map<Node*, PredicateState> Analyze() {
103105
CHECK(node_states_.empty());
104106
CHECK(predicate_stacks_.empty());
105107
node_states_.reserve(function_->node_count());
106108
predicate_stacks_.push_back(kRootPredicateStackNode);
107109
// Run in reverse topo sort order. Handle users before the values they use.
108-
for (Node* node : ReverseTopoSort(function_)) {
110+
for (Node* node : context_.ReverseTopoSort(function_)) {
109111
HandleNode(node);
110112
}
111113

@@ -259,15 +261,17 @@ class AnalysisHelper {
259261

260262
private:
261263
FunctionBase* function_;
264+
OptimizationContext& context_;
262265
// Map of node to the predicate list head they are guarded by.
263266
absl::flat_hash_map<Node*, PredicateStackId> node_states_;
264267
// Map from 'PredicateStackId' to the predicate node.
265268
std::vector<PredicateStackNode> predicate_stacks_;
266269
};
267270
} // namespace
268271

269-
PredicateDominatorAnalysis PredicateDominatorAnalysis::Run(FunctionBase* f) {
270-
AnalysisHelper helper(f);
272+
PredicateDominatorAnalysis PredicateDominatorAnalysis::Run(
273+
FunctionBase* f, OptimizationContext& context) {
274+
AnalysisHelper helper(f, context);
271275
return PredicateDominatorAnalysis(helper.Analyze());
272276
}
273277

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)