Skip to content

Commit d94e847

Browse files
committed
[GlobalOpt] Extend CleanupPointerRootUsers to handle CE users.
Extend CleanupPointerRootUsers to iterate over a worklist, add users of constant expressions to the worklist to enable additional cleanups. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D144468
1 parent cf2d80b commit d94e847

File tree

4 files changed

+41
-14
lines changed

4 files changed

+41
-14
lines changed

llvm/lib/Transforms/IPO/GlobalOpt.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,10 @@ CleanupPointerRootUsers(GlobalVariable *GV,
206206
// chain of computation and the store to the global in Dead[n].second.
207207
SmallVector<std::pair<Instruction *, Instruction *>, 32> Dead;
208208

209+
SmallVector<User *> Worklist(GV->users());
209210
// Constants can't be pointers to dynamically allocated memory.
210-
for (User *U : llvm::make_early_inc_range(GV->users())) {
211+
while (!Worklist.empty()) {
212+
User *U = Worklist.pop_back_val();
211213
if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
212214
Value *V = SI->getValueOperand();
213215
if (isa<Constant>(V)) {
@@ -238,7 +240,8 @@ CleanupPointerRootUsers(GlobalVariable *GV,
238240
if (CE->use_empty()) {
239241
CE->destroyConstant();
240242
Changed = true;
241-
}
243+
} else if (isa<GEPOperator>(CE))
244+
append_range(Worklist, CE->users());
242245
} else if (Constant *C = dyn_cast<Constant>(U)) {
243246
if (isSafeToDestroyConstant(C)) {
244247
C->destroyConstant();

llvm/test/ThinLTO/X86/import-constant.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@
3232
; IMPORT-NEXT: @_ZL3Obj.llvm.{{.*}} = available_externally hidden constant %struct.S { i32 4, i32 8, ptr @val }
3333
; IMPORT-NEXT: @outer = internal local_unnamed_addr global %struct.Q zeroinitializer
3434

35-
; OPT: @outer = internal unnamed_addr global %struct.Q zeroinitializer
35+
; @outer is a write-only variable that's stored to once, so the store and the global can be removed.
36+
; OPT-NOT: @outer
3637

3738
; OPT: define dso_local i32 @main()
3839
; OPT-NEXT: entry:
39-
; OPT-NEXT: store ptr null, ptr getelementptr inbounds (%struct.Q, ptr @outer, i64 1, i32 0)
4040
; OPT-NEXT: ret i32 12
4141

4242
; NOREFS: @_ZL3Obj.llvm.{{.*}} = external hidden constant %struct.S

llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-gep-constexpr.ll

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ declare i32 @fn3()
1616
define void @stores_single_use_gep_constexpr() {
1717
; CHECK-LABEL: @stores_single_use_gep_constexpr(
1818
; CHECK-NEXT: entry:
19-
; CHECK-NEXT: store ptr @fn1, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR:%.*]], ptr @global.20ptr, i64 0, i32 1), align 8
20-
; CHECK-NEXT: store ptr @fn2, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 2), align 8
21-
; CHECK-NEXT: store ptr @fn3, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 3), align 8
22-
; CHECK-NEXT: store ptr @fn0, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 4), align 8
23-
; CHECK-NEXT: store ptr @fn1, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 5), align 8
24-
; CHECK-NEXT: store ptr @fn2, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 6), align 8
25-
; CHECK-NEXT: store ptr @fn3, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 7), align 8
26-
; CHECK-NEXT: store ptr @fn0, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 8), align 8
2719
; CHECK-NEXT: ret void
2820
;
2921
entry:
@@ -42,8 +34,6 @@ entry:
4234
define void @stores_multi_use_gep_constexpr() {
4335
; CHECK-LABEL: @stores_multi_use_gep_constexpr(
4436
; CHECK-NEXT: entry:
45-
; CHECK-NEXT: store i32 0, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR:%.*]], ptr @global.20ptr, i64 0, i32 16), align 8
46-
; CHECK-NEXT: store i32 0, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 16), align 8
4737
; CHECK-NEXT: ret void
4838
;
4939
entry:
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -passes=globalopt -S %s | FileCheck %s
3+
4+
%struct.global.20ptr = type { ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }
5+
6+
@global.20ptr = internal unnamed_addr global %struct.global.20ptr zeroinitializer
7+
8+
declare i32 @fn0()
9+
10+
declare i32 @fn1()
11+
12+
define void @stores_single_use_gep_constexpr() {
13+
; CHECK-LABEL: @stores_single_use_gep_constexpr(
14+
; CHECK-NEXT: entry:
15+
; CHECK-NEXT: store ptr @fn0, ptr @global.20ptr, align 8
16+
; CHECK-NEXT: store ptr @fn1, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR:%.*]], ptr @global.20ptr, i64 0, i32 1), align 8
17+
; CHECK-NEXT: ret void
18+
;
19+
entry:
20+
store ptr @fn0, ptr getelementptr inbounds (%struct.global.20ptr, ptr @global.20ptr, i64 0, i32 0), align 8
21+
store ptr @fn1, ptr getelementptr inbounds (%struct.global.20ptr, ptr @global.20ptr, i64 0, i32 1), align 8
22+
ret void
23+
}
24+
25+
define void @stores_ptrtoint_constexpr() {
26+
; CHECK-LABEL: @stores_ptrtoint_constexpr(
27+
; CHECK-NEXT: entry:
28+
; CHECK-NEXT: store i32 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @global.20ptr to i64), i64 200) to ptr), align 8
29+
; CHECK-NEXT: ret void
30+
;
31+
entry:
32+
store i32 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @global.20ptr to i64), i64 200) to ptr), align 8
33+
ret void
34+
}

0 commit comments

Comments
 (0)