Skip to content

Commit 6b368d5

Browse files
committed
Remove internal functions made unreachable by predicate expansion.
1 parent adb6469 commit 6b368d5

File tree

2 files changed

+130
-4
lines changed

2 files changed

+130
-4
lines changed

llvm/lib/Target/AMDGPU/AMDGPUExpandFeaturePredicates.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,30 @@ handlePredicate(const GCNSubtarget &ST, FunctionAnalysisManager &FAM,
127127
}
128128
} // Unnamed namespace.
129129

130+
static inline SmallVector<Function *> collectUsedFunctions(Module &M) {
131+
SmallVector<Function *> Ret;
132+
for (auto &&F : M) {
133+
if (F.isIntrinsic() || F.isDeclaration())
134+
continue;
135+
if (!F.hasInternalLinkage() && !F.hasPrivateLinkage())
136+
continue;
137+
if (F.hasNUndroppableUsesOrMore(1))
138+
Ret.push_back(&F);
139+
}
140+
141+
return Ret;
142+
}
143+
144+
template<typename Container0, typename Container1, typename Container2>
145+
static inline void removeUnreachable(const Container0 &Predicates,
146+
const Container1 &PredicatedFns,
147+
const Container2 &UnreachableFns) {
148+
for_each(Predicates, [](auto &&P) { P->eraseFromParent(); });
149+
for_each(PredicatedFns, [](auto &&F) { removeUnreachableBlocks(*F); });
150+
for_each(UnreachableFns,
151+
[](auto &&F) { if (F->getNumUses() == 0) F->eraseFromParent(); });
152+
}
153+
130154
PreservedAnalyses
131155
AMDGPUExpandFeaturePredicatesPass::run(Module &M, ModuleAnalysisManager &MAM) {
132156
if (M.empty())
@@ -148,6 +172,7 @@ AMDGPUExpandFeaturePredicatesPass::run(Module &M, ModuleAnalysisManager &MAM) {
148172

149173
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
150174
SmallPtrSet<Function *, 32> Predicated;
175+
SmallVector<Function *> MaybeUnreachable = collectUsedFunctions(M);
151176
auto Ret = PreservedAnalyses::all();
152177
for (auto &&P : Predicates) {
153178
auto R = handlePredicate(ST, FAM, Predicated, P);
@@ -158,10 +183,7 @@ AMDGPUExpandFeaturePredicatesPass::run(Module &M, ModuleAnalysisManager &MAM) {
158183
Ret.intersect(R.first);
159184
}
160185

161-
for (auto &&P : Predicates)
162-
P->eraseFromParent();
163-
for (auto &&F : Predicated)
164-
removeUnreachableBlocks(*F);
186+
removeUnreachable(Predicates, Predicated, MaybeUnreachable);
165187

166188
return Ret;
167189
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --scrub-attributes --version 5
2+
; REQUIRES: amdgpu-registered-target
3+
4+
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -passes='amdgpu-expand-feature-predicates' %s -o - | FileCheck --check-prefix=GFX906 %s
5+
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1201 -passes='amdgpu-expand-feature-predicates' %s -o - | FileCheck --check-prefix=GFX1201 %s
6+
7+
@llvm.amdgcn.is.gfx906 = external addrspace(1) externally_initialized constant i1
8+
@llvm.amdgcn.is.gfx1201 = external addrspace(1) externally_initialized constant i1
9+
10+
define external void @extern_linkage() {
11+
; GFX906-LABEL: define void @extern_linkage(
12+
; GFX906-SAME: ) #[[ATTR0:[0-9]+]] {
13+
; GFX906-NEXT: [[ENTRY:.*:]]
14+
; GFX906-NEXT: ret void
15+
;
16+
; GFX1201-LABEL: define void @extern_linkage(
17+
; GFX1201-SAME: ) #[[ATTR0:[0-9]+]] {
18+
; GFX1201-NEXT: [[ENTRY:.*:]]
19+
; GFX1201-NEXT: ret void
20+
;
21+
entry:
22+
ret void
23+
}
24+
25+
define private void @non_predicated_uses() {
26+
; GFX906-LABEL: define private void @non_predicated_uses(
27+
; GFX906-SAME: ) #[[ATTR0]] {
28+
; GFX906-NEXT: [[ENTRY:.*:]]
29+
; GFX906-NEXT: ret void
30+
;
31+
; GFX1201-LABEL: define private void @non_predicated_uses(
32+
; GFX1201-SAME: ) #[[ATTR0]] {
33+
; GFX1201-NEXT: [[ENTRY:.*:]]
34+
; GFX1201-NEXT: ret void
35+
;
36+
entry:
37+
ret void
38+
}
39+
40+
define internal void @remove_on_906() {
41+
; GFX1201-LABEL: define internal void @remove_on_906(
42+
; GFX1201-SAME: ) #[[ATTR0]] {
43+
; GFX1201-NEXT: [[ENTRY:.*:]]
44+
; GFX1201-NEXT: ret void
45+
;
46+
entry:
47+
ret void
48+
}
49+
50+
define internal void @remove_on_1201() {
51+
; GFX906-LABEL: define internal void @remove_on_1201(
52+
; GFX906-SAME: ) #[[ATTR0]] {
53+
; GFX906-NEXT: [[ENTRY:.*:]]
54+
; GFX906-NEXT: ret void
55+
;
56+
entry:
57+
ret void
58+
}
59+
60+
define void @foo() {
61+
; GFX906-LABEL: define void @foo(
62+
; GFX906-SAME: ) #[[ATTR0]] {
63+
; GFX906-NEXT: [[ENTRY:.*:]]
64+
; GFX906-NEXT: call void @non_predicated_uses()
65+
; GFX906-NEXT: br label %[[NOT_GFX1201:.*]]
66+
; GFX906: [[NOT_GFX1201]]:
67+
; GFX906-NEXT: br label %[[GFX906:.*]]
68+
; GFX906: [[GFX906]]:
69+
; GFX906-NEXT: call void @remove_on_1201()
70+
; GFX906-NEXT: br label %[[END:.*]]
71+
; GFX906: [[END]]:
72+
; GFX906-NEXT: ret void
73+
;
74+
; GFX1201-LABEL: define void @foo(
75+
; GFX1201-SAME: ) #[[ATTR0]] {
76+
; GFX1201-NEXT: [[ENTRY:.*:]]
77+
; GFX1201-NEXT: call void @non_predicated_uses()
78+
; GFX1201-NEXT: br label %[[GFX1201:.*]]
79+
; GFX1201: [[GFX1201]]:
80+
; GFX1201-NEXT: call void @remove_on_906()
81+
; GFX1201-NEXT: br label %[[END:.*]]
82+
; GFX1201: [[END]]:
83+
; GFX1201-NEXT: ret void
84+
;
85+
entry:
86+
call void @non_predicated_uses()
87+
%0 = load i1, ptr addrspace(1) @llvm.amdgcn.is.gfx1201, align 1
88+
br i1 %0, label %gfx1201, label %not.gfx1201
89+
90+
gfx1201:
91+
call void @remove_on_906()
92+
br label %end
93+
94+
not.gfx1201:
95+
%1 = load i1, ptr addrspace(1) @llvm.amdgcn.is.gfx906, align 1
96+
br i1 %1, label %gfx906, label %end
97+
98+
gfx906:
99+
call void @remove_on_1201()
100+
br label %end
101+
102+
end:
103+
ret void
104+
}

0 commit comments

Comments
 (0)