Skip to content

Commit dd36815

Browse files
angelomatni1copybara-github
authored andcommitted
Introduce ReachabilityAnalysis to lazily compute what nodes are reachable
Use it in resource sharing pass. PiperOrigin-RevId: 826393302
1 parent 7a20457 commit dd36815

File tree

7 files changed

+303
-172
lines changed

7 files changed

+303
-172
lines changed

xls/passes/BUILD

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ xls_pass(
10651065
":pass_base",
10661066
":post_dominator_analysis",
10671067
":query_engine",
1068+
":reachability_analysis",
10681069
"//xls/common/status:ret_check",
10691070
"//xls/common/status:status_macros",
10701071
"//xls/estimators/area_model:area_estimator",
@@ -1083,8 +1084,6 @@ xls_pass(
10831084
"@com_google_absl//absl/random",
10841085
"@com_google_absl//absl/status:statusor",
10851086
"@com_google_absl//absl/types:span",
1086-
"@com_google_ortools//ortools/graph",
1087-
"@com_google_ortools//ortools/graph:cliques",
10881087
"@cppitertools",
10891088
],
10901089
)
@@ -1507,6 +1506,34 @@ cc_test(
15071506
],
15081507
)
15091508

1509+
cc_library(
1510+
name = "reachability_analysis",
1511+
srcs = ["reachability_analysis.cc"],
1512+
hdrs = ["reachability_analysis.h"],
1513+
deps = [
1514+
":lazy_node_data",
1515+
"//xls/ir",
1516+
"@com_google_absl//absl/container:flat_hash_set",
1517+
"@com_google_absl//absl/status",
1518+
"@com_google_absl//absl/types:span",
1519+
],
1520+
)
1521+
1522+
cc_test(
1523+
name = "reachability_analysis_test",
1524+
srcs = ["reachability_analysis_test.cc"],
1525+
deps = [
1526+
":reachability_analysis",
1527+
"//xls/common:xls_gunit_main",
1528+
"//xls/common/status:matchers",
1529+
"//xls/ir",
1530+
"//xls/ir:function_builder",
1531+
"//xls/ir:ir_test_base",
1532+
"//xls/ir:op",
1533+
"@googletest//:gtest",
1534+
],
1535+
)
1536+
15101537
cc_library(
15111538
name = "lazy_query_engine",
15121539
hdrs = [
@@ -4310,6 +4337,7 @@ cc_test(
43104337
":optimization_pass",
43114338
":pass_base",
43124339
":query_engine",
4340+
":reachability_analysis",
43134341
":resource_sharing_pass",
43144342
"//xls/common:xls_gunit_main",
43154343
"//xls/common/fuzzing:fuzztest",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2025 The XLS Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "xls/passes/reachability_analysis.h"
16+
17+
#include "absl/container/flat_hash_set.h"
18+
#include "absl/status/status.h"
19+
#include "absl/types/span.h"
20+
#include "xls/ir/node.h"
21+
22+
namespace xls {
23+
24+
bool ReachabilityAnalysis::IsReachableFrom(Node* end, Node* start) const {
25+
return GetInfo(end)->contains(start);
26+
}
27+
28+
absl::flat_hash_set<Node*> ReachabilityAnalysis::ComputeInfo(
29+
Node* end,
30+
absl::Span<const absl::flat_hash_set<Node*>* const> operand_infos) const {
31+
int max_size = 0;
32+
for (const absl::flat_hash_set<Node*>* operand_info : operand_infos) {
33+
max_size += operand_info->size();
34+
}
35+
absl::flat_hash_set<Node*> can_reach_end{end};
36+
can_reach_end.reserve(max_size + 1);
37+
for (const absl::flat_hash_set<Node*>* operand_info : operand_infos) {
38+
can_reach_end.insert(operand_info->begin(), operand_info->end());
39+
}
40+
return can_reach_end;
41+
}
42+
43+
absl::Status ReachabilityAnalysis::MergeWithGiven(
44+
absl::flat_hash_set<Node*>& info,
45+
const absl::flat_hash_set<Node*>& given) const {
46+
info.insert(given.begin(), given.end());
47+
return absl::OkStatus();
48+
}
49+
50+
} // namespace xls

xls/passes/reachability_analysis.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2025 The XLS Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef XLS_PASSES_REACHABILITY_ANALYSIS_H_
16+
#define XLS_PASSES_REACHABILITY_ANALYSIS_H_
17+
18+
#include "absl/container/flat_hash_set.h"
19+
#include "absl/status/status.h"
20+
#include "absl/types/span.h"
21+
#include "xls/ir/node.h"
22+
#include "xls/passes/lazy_node_data.h"
23+
24+
namespace xls {
25+
26+
class ReachabilityAnalysis : public LazyNodeData<absl::flat_hash_set<Node*>> {
27+
public:
28+
// Returns if `end` can be reached by traversing users beginning at `start`.
29+
bool IsReachableFrom(Node* end, Node* start) const;
30+
31+
const absl::flat_hash_set<Node*>& NodesThatCanReach(Node* end) const {
32+
return *GetInfo(end);
33+
}
34+
35+
protected:
36+
// Computes the set of nodes reach-able from `start` by traversing users.
37+
absl::flat_hash_set<Node*> ComputeInfo(
38+
Node* end,
39+
absl::Span<const absl::flat_hash_set<Node*>* const> operand_infos)
40+
const override;
41+
42+
absl::Status MergeWithGiven(
43+
absl::flat_hash_set<Node*>& info,
44+
const absl::flat_hash_set<Node*>& given) const override;
45+
};
46+
47+
} // namespace xls
48+
49+
#endif // XLS_PASSES_REACHABILITY_ANALYSIS_H_
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2025 The XLS Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "xls/passes/reachability_analysis.h"
16+
17+
#include "gtest/gtest.h"
18+
#include "xls/common/status/matchers.h"
19+
#include "xls/ir/function_builder.h"
20+
#include "xls/ir/ir_test_base.h"
21+
#include "xls/ir/node.h"
22+
#include "xls/ir/op.h"
23+
#include "xls/ir/package.h"
24+
25+
namespace xls {
26+
namespace {
27+
28+
class ReachabilityAnalysisTest : public IrTestBase {
29+
protected:
30+
bool IsReachableFrom(const ReachabilityAnalysis& reachability, Node* end,
31+
Node* start) {
32+
return reachability.IsReachableFrom(end, start);
33+
}
34+
};
35+
36+
TEST_F(ReachabilityAnalysisTest, SuccessorsAreReachableButPredecessorsAreNot) {
37+
auto p = CreatePackage();
38+
FunctionBuilder fb(TestName(), p.get());
39+
BValue x = fb.Param("x", p->GetBitsType(4));
40+
BValue y = fb.Add(x, x);
41+
BValue z = fb.UMul(x, y);
42+
BValue w = fb.Subtract(z, x);
43+
XLS_ASSERT_OK(fb.BuildWithReturnValue(w));
44+
ReachabilityAnalysis reachability;
45+
46+
EXPECT_TRUE(IsReachableFrom(reachability, x.node(), x.node()));
47+
EXPECT_TRUE(IsReachableFrom(reachability, y.node(), x.node()));
48+
EXPECT_TRUE(IsReachableFrom(reachability, z.node(), x.node()));
49+
EXPECT_TRUE(IsReachableFrom(reachability, w.node(), x.node()));
50+
EXPECT_TRUE(IsReachableFrom(reachability, z.node(), y.node()));
51+
EXPECT_TRUE(IsReachableFrom(reachability, w.node(), y.node()));
52+
EXPECT_TRUE(IsReachableFrom(reachability, z.node(), y.node()));
53+
EXPECT_FALSE(IsReachableFrom(reachability, x.node(), y.node()));
54+
EXPECT_FALSE(IsReachableFrom(reachability, x.node(), z.node()));
55+
EXPECT_FALSE(IsReachableFrom(reachability, x.node(), w.node()));
56+
EXPECT_FALSE(IsReachableFrom(reachability, y.node(), z.node()));
57+
EXPECT_FALSE(IsReachableFrom(reachability, y.node(), w.node()));
58+
EXPECT_FALSE(IsReachableFrom(reachability, z.node(), w.node()));
59+
}
60+
61+
TEST_F(ReachabilityAnalysisTest, SiblingsCannotReachEachOther) {
62+
auto p = CreatePackage();
63+
FunctionBuilder fb(TestName(), p.get());
64+
BValue a = fb.Param("a", p->GetBitsType(4));
65+
BValue b = fb.Param("b", p->GetBitsType(4));
66+
BValue x = fb.Or(a, b);
67+
BValue y1 = fb.Add(x, a);
68+
BValue y2 = fb.Subtract(x, b);
69+
BValue z = fb.UMul(y1, y2);
70+
XLS_ASSERT_OK(fb.BuildWithReturnValue(z));
71+
ReachabilityAnalysis reachability;
72+
73+
EXPECT_FALSE(IsReachableFrom(reachability, y1.node(), y2.node()));
74+
EXPECT_FALSE(IsReachableFrom(reachability, y2.node(), y1.node()));
75+
}
76+
77+
} // namespace
78+
} // namespace xls

0 commit comments

Comments
 (0)