Skip to content

Commit 58f729a

Browse files
committed
Address comments from ellishg
1 parent b08aab8 commit 58f729a

File tree

6 files changed

+158
-116
lines changed

6 files changed

+158
-116
lines changed

llvm/lib/IR/StructuralHash.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,12 @@ class StructuralHashImpl {
8282
return hashGlobalValue(&GVar);
8383

8484
// Hash the contents of a string.
85-
if (GVar.getName().starts_with(".str"))
86-
return hashConstant(GVar.getInitializer());
85+
if (GVar.getName().starts_with(".str")) {
86+
auto *C = GVar.getInitializer();
87+
if (const auto *Seq = dyn_cast<ConstantDataSequential>(C))
88+
if (Seq->isString())
89+
return stable_hash_name(Seq->getAsString());
90+
}
8791

8892
// Hash structural contents of Objective-C metadata in specific sections.
8993
// This can be extended to other metadata if needed.
@@ -93,10 +97,9 @@ class StructuralHashImpl {
9397
};
9498
if (GVar.hasSection()) {
9599
StringRef SectionName = GVar.getSection();
96-
for (const char *Name : SectionNames) {
100+
for (const char *Name : SectionNames)
97101
if (SectionName.contains(Name))
98102
return hashConstant(GVar.getInitializer());
99-
}
100103
}
101104

102105
return hashGlobalValue(&GVar);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; This test verifies that global variables (ns constant) are hashed based on their initial contents,
2+
; allowing them to be merged even if they appear different due to their names.
3+
; Now they become identical functions that can be merged without creating a parameter
4+
5+
; RUN: llc -mtriple=arm64-apple-darwin -enable-global-merge-func=true -global-merging-skip-no-params=false < %s | FileCheck %s
6+
7+
; CHECK: _f1.Tgm
8+
; CHECK: _f2.Tgm
9+
10+
%struct.__NSConstantString_tag = type { ptr, i32, ptr, i64 }
11+
@__CFConstantStringClassReference = external global [0 x i32]
12+
@.str.2 = private unnamed_addr constant [9 x i8] c"cfstring\00", section "__TEXT,__cstring,cstring_literals", align 1
13+
@_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { ptr @__CFConstantStringClassReference, i32 1992, ptr @.str.2, i64 8 }, section "__DATA,__cfstring", align 8
14+
15+
@.str.3 = private unnamed_addr constant [9 x i8] c"cfstring\00", section "__TEXT,__cstring,cstring_literals", align 1
16+
@_unnamed_cfstring_.2 = private global %struct.__NSConstantString_tag { ptr @__CFConstantStringClassReference, i32 1992, ptr @.str.3, i64 8 }, section "__DATA,__cfstring", align 8
17+
18+
declare i32 @hoo(ptr noundef)
19+
20+
define i32 @f1() {
21+
entry:
22+
%call = tail call i32 @hoo(ptr noundef nonnull @_unnamed_cfstring_)
23+
%add = sub nsw i32 %call, 1
24+
ret i32 %add
25+
}
26+
27+
define i32 @f2() {
28+
entry:
29+
%call = tail call i32 @hoo(ptr noundef nonnull @_unnamed_cfstring_.2)
30+
%add = sub nsw i32 %call, 1
31+
ret i32 %add
32+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
; This test verifies that global variables (objc metadata) are hashed based on their initial contents,
3+
; allowing them to be merged even if they appear different due to their names.
4+
; Now they become identical functions that can be merged without creating a parameter
5+
6+
; RUN: llc -mtriple=arm64-apple-darwin -enable-global-merge-func=true -global-merging-skip-no-params=false < %s | FileCheck %s
7+
8+
; CHECK: _f1.Tgm
9+
; CHECK: _f2.Tgm
10+
11+
12+
%struct._class_t = type { ptr, ptr, ptr, ptr, ptr }
13+
14+
@"OBJC_CLASS_$_MyClass" = external global %struct._class_t
15+
@"OBJC_CLASSLIST_REFERENCES_$_" = internal global ptr @"OBJC_CLASS_$_MyClass", section "__DATA,__objc_classrefs,regular,no_dead_strip", align 8
16+
@"OBJC_CLASSLIST_REFERENCES_$_.1" = internal global ptr @"OBJC_CLASS_$_MyClass", section "__DATA,__objc_classrefs,regular,no_dead_strip", align 8
17+
18+
@OBJC_METH_VAR_NAME_ = private unnamed_addr constant [6 x i8] c"hello\00", section "__TEXT,__objc_methname,cstring_literals", align 1
19+
@OBJC_METH_VAR_NAME_.1 = private unnamed_addr constant [6 x i8] c"hello\00", section "__TEXT,__objc_methname,cstring_literals", align 1
20+
21+
@OBJC_SELECTOR_REFERENCES_ = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8
22+
@OBJC_SELECTOR_REFERENCES_.1 = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.1, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8
23+
24+
declare ptr @objc_msgSend(ptr, ptr, ...)
25+
26+
define i32 @f1() {
27+
entry:
28+
%0 = load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_", align 8
29+
%1 = load ptr, ptr @OBJC_SELECTOR_REFERENCES_, align 8
30+
%call = tail call i32 @objc_msgSend(ptr noundef %0, ptr noundef %1)
31+
ret i32 %call
32+
}
33+
34+
define i32 @f2() {
35+
entry:
36+
%0 = load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.1", align 8
37+
%1 = load ptr, ptr @OBJC_SELECTOR_REFERENCES_.1, align 8
38+
%call = tail call i32 @objc_msgSend(ptr noundef %0, ptr noundef %1)
39+
ret i32 %call
40+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; This test verifies that global variables (string) are hashed based on their initial contents,
2+
; allowing them to be merged even if they appear different due to their names.
3+
; Now they become identical functions that can be merged without creating a parameter.
4+
5+
; RUN: llc -mtriple=arm64-apple-darwin -enable-global-merge-func=true -global-merging-skip-no-params=false < %s | FileCheck %s
6+
7+
; CHECK: _f1.Tgm
8+
; CHECK: _f2.Tgm
9+
; CHECK-NOT: _f3.Tgm
10+
; CHECK-NOT: _f4.Tgm
11+
12+
; The initial contents of `.str` and `.str.1` are identical, but not with those of `.str.2` and `.str.3`.
13+
@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
14+
@.str.1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
15+
@.str.2 = private unnamed_addr constant [6 x i8] c"diff2\00", align 1
16+
@.str.3 = private unnamed_addr constant [6 x i8] c"diff3\00", align 1
17+
18+
declare i32 @goo(ptr noundef)
19+
20+
define i32 @f1() {
21+
entry:
22+
%call = tail call i32 @goo(ptr noundef nonnull @.str)
23+
%add = add nsw i32 %call, 1
24+
ret i32 %add
25+
}
26+
27+
define i32 @f2() {
28+
entry:
29+
%call = tail call i32 @goo(ptr noundef nonnull @.str.1)
30+
%add = add nsw i32 %call, 1
31+
ret i32 %add
32+
}
33+
34+
define i32 @f3() {
35+
entry:
36+
%call = tail call noundef i32 @goo(ptr noundef nonnull @.str.2)
37+
%add = sub nsw i32 %call, 1
38+
ret i32 %add
39+
}
40+
41+
define i32 @f4() {
42+
entry:
43+
%call = tail call noundef i32 @goo(ptr noundef nonnull @.str.3)
44+
%add = sub nsw i32 %call, 1
45+
ret i32 %add
46+
}

llvm/test/CodeGen/AArch64/cgdata-merge-gvar.ll

Lines changed: 0 additions & 91 deletions
This file was deleted.

llvm/test/CodeGen/AArch64/cgdata-outline-gvar.ll

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,62 @@
33

44
; RUN: split-file %s %t
55

6-
; Check if the outlined function is created locally.
7-
; RUN: llc -mtriple=arm64-apple-darwin -enable-machine-outliner -codegen-data-generate=true -aarch64-enable-collect-loh=false -filetype=obj %t/local-two.ll -o %t_write_base
8-
; RUN: llvm-objdump -d %t_write_base | FileCheck %s
6+
; The outlined function is created locally.
7+
; Note that `.str.3` is commonly used in both `f1()` and `f2()`.
8+
; RUN: llc -mtriple=arm64-apple-darwin -enable-machine-outliner -codegen-data-generate -aarch64-enable-collect-loh=false \
9+
; RUN: %t/local-two.ll -o - | FileCheck %s --check-prefix=WRITE
910

11+
; WRITE-LABEL: _OUTLINED_FUNCTION_{{.*}}:
12+
; WRITE: adrp x1, l_.str.3
13+
; WRITE-NEXT: add x1, x1, l_.str.3
14+
; WRITE-NEXT: mov w2
15+
; WRITE-NEXT: mov w3
16+
; WRITE-NEXT: mov w4
17+
; WRITE-NEXT: b
18+
19+
; Create an object file and merge it into the cgdata.
20+
; RUN: llc -mtriple=arm64-apple-darwin -enable-machine-outliner -codegen-data-generate -aarch64-enable-collect-loh=false \
21+
; RUN: -filetype=obj %t/local-two.ll -o %t_write_base
1022
; RUN: llvm-cgdata --merge %t_write_base -o %t_cgdata_base
1123

1224
; Read the cgdata in the machine outliner for optimistically outlining in local-one.ll.
13-
; RUN: llc -mtriple=arm64-apple-darwin -enable-machine-outliner -codegen-data-use-path=%t_cgdata_base -aarch64-enable-collect-loh=false -append-content-hash-outlined-name=false -filetype=obj %t/local-one.ll -o %t_read_base
14-
; RUN: llvm-objdump -d %t_read_base | FileCheck %s
15-
16-
; The names of globals `.str` and `.str.4` are different, but their initial contents are identical.
17-
; The outlined function now starts with a reference to that global ("hello\00").
18-
; CHECK: _OUTLINED_FUNCTION_{{.*}}:
19-
; CHECK-NEXT: adrp x1
20-
; CHECK-NEXT: add x1, x1
21-
; CHECK-NEXT: mov w2
22-
; CHECK-NEXT: mov w3
23-
; CHECK-NEXT: mov w4
24-
; CHECK-NEXT: b
25+
; Note that the hash of `.str.5` in local-one.ll matches that of `.str.3` in an outlined tree in the cgdata.
26+
27+
; RUN: llc -mtriple=arm64-apple-darwin -enable-machine-outliner -codegen-data-use-path=%t_cgdata_base -aarch64-enable-collect-loh=false \
28+
; RUN: %t/local-one.ll -o - | FileCheck %s --check-prefix=READ
29+
30+
; READ-LABEL: _OUTLINED_FUNCTION_{{.*}}:
31+
; READ: adrp x1, l_.str.5
32+
; READ-NEXT: add x1, x1, l_.str.5
33+
; READ-NEXT: mov w2
34+
; READ-NEXT: mov w3
35+
; READ-NEXT: mov w4
36+
; READ-NEXT: b
2537

2638
;--- local-two.ll
27-
@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
2839
@.str.1 = private unnamed_addr constant [3 x i8] c"f1\00", align 1
2940
@.str.2 = private unnamed_addr constant [3 x i8] c"f2\00", align 1
41+
@.str.3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
3042

3143
declare noundef i32 @goo(ptr noundef, ptr noundef, i32, i32, i32)
3244
define i32 @f1() minsize {
3345
entry:
34-
%call = tail call noundef i32 @goo(ptr noundef nonnull @.str.1, ptr noundef nonnull @.str, i32 1, i32 2, i32 3)
46+
%call = tail call noundef i32 @goo(ptr noundef nonnull @.str.1, ptr noundef nonnull @.str.3, i32 1, i32 2, i32 3)
3547
ret i32 %call
3648
}
3749
define i32 @f2() minsize {
3850
entry:
39-
%call = tail call noundef i32 @goo(ptr noundef nonnull @.str.2, ptr noundef nonnull @.str, i32 1, i32 2, i32 3)
51+
%call = tail call noundef i32 @goo(ptr noundef nonnull @.str.2, ptr noundef nonnull @.str.3, i32 1, i32 2, i32 3)
4052
ret i32 %call
4153
}
4254

4355
;--- local-one.ll
44-
@.str.3 = private unnamed_addr constant [3 x i8] c"f3\00", align 1
45-
@.str.4 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
56+
@.str.4 = private unnamed_addr constant [3 x i8] c"f3\00", align 1
57+
@.str.5 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
4658

4759
declare noundef i32 @goo(ptr noundef, ptr noundef, i32, i32, i32)
4860
define i32 @f1() minsize {
4961
entry:
50-
%call = tail call noundef i32 @goo(ptr noundef nonnull @.str.3, ptr noundef nonnull @.str.4, i32 1, i32 2, i32 3)
62+
%call = tail call noundef i32 @goo(ptr noundef nonnull @.str.4, ptr noundef nonnull @.str.5, i32 1, i32 2, i32 3)
5163
ret i32 %call
5264
}

0 commit comments

Comments
 (0)