Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[INLINER] allow inlining of blockaddresses if sole uses are callbrs
Summary: It was supposed that Ref LazyCallGraph::Edge's were being inserted by inlining, but that doesn't seem to be the case. Instead, it seems that there was no test for a blockaddress Constant in an instruction that referenced the function that contained the instruction. Ex: ``` define void @f() { %1 = alloca i8*, align 8 2: store i8* blockaddress(@f, %2), i8** %1, align 8 ret void } ``` When iterating blockaddresses, do not add the function they refer to back to the worklist if the blockaddress is referring to the contained function (as opposed to an external function). Because blockaddress has sligtly different semantics than GNU C's address of labels, there are 3 cases that can occur with blockaddress, where only 1 can happen in GNU C due to C's scoping rules: * blockaddress is within the function it refers to (possible in GNU C). * blockaddress is within a different function than the one it refers to (not possible in GNU C). * blockaddress is used in to declare a global (not possible in GNU C). The second case is tested in: ``` $ ./llvm/build/unittests/Analysis/AnalysisTests \ --gtest_filter=LazyCallGraphTest.HandleBlockAddress ``` This patch adjusts the iteration of blockaddresses in LazyCallGraph::visitReferences to not revisit the blockaddresses function in the first case. The Linux kernel contains code that's not semantically valid at -O0; specifically code passed to asm goto. It requires that asm goto be inline-able. This patch conservatively does not attempt to handle the more general case of inlining blockaddresses that have non-callbr users (pr/39560). https://bugs.llvm.org/show_bug.cgi?id=39560 https://bugs.llvm.org/show_bug.cgi?id=40722 ClangBuiltLinux/linux#6 https://reviews.llvm.org/rL212077 Reviewers: jyknight, eli.friedman, chandlerc Reviewed By: chandlerc Subscribers: george.burgess.iv, nathanchance, mgorny, craig.topper, mengxu.gatech, void, mehdi_amini, E5ten, chandlerc, efriedma, eraman, hiraditya, haicheng, pirama, llvm-commits, srhines Tags: #llvm Differential Revision: https://reviews.llvm.org/D58260 llvm-svn: 361173
- Loading branch information
1 parent
8fd2492
commit 21aa0bc
Showing
5 changed files
with
199 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
; RUN: opt -inline -S < %s | FileCheck %s | ||
; RUN: opt -passes='cgscc(inline)' -S < %s | FileCheck %s | ||
|
||
define dso_local i32 @main() #0 { | ||
%1 = alloca i32, align 4 | ||
store i32 0, i32* %1, align 4 | ||
%2 = call i32 @t32(i32 0) | ||
ret i32 %2 | ||
} | ||
|
||
define internal i32 @t32(i32) #0 { | ||
%2 = alloca i32, align 4 | ||
%3 = alloca i32, align 4 | ||
store i32 %0, i32* %3, align 4 | ||
%4 = load i32, i32* %3, align 4 | ||
callbr void asm sideeffect "testl $0, $0; jne ${1:l};", "r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %4, i8* blockaddress(@t32, %7), i8* blockaddress(@t32, %6)) #1 | ||
to label %5 [label %7, label %6] | ||
|
||
; <label>:5: ; preds = %1 | ||
store i32 0, i32* %2, align 4 | ||
br label %8 | ||
|
||
; <label>:6: ; preds = %1 | ||
store i32 1, i32* %2, align 4 | ||
br label %8 | ||
|
||
; <label>:7: ; preds = %1 | ||
store i32 2, i32* %2, align 4 | ||
br label %8 | ||
|
||
; <label>:8: ; preds = %7, %6, %5 | ||
%9 = load i32, i32* %2, align 4 | ||
ret i32 %9 | ||
} | ||
|
||
; Check that @t32 no longer exists after inlining, as it has now been inlined | ||
; into @main. | ||
|
||
; CHECK-NOT: @t32 | ||
; CHECK: define dso_local i32 @main | ||
; CHECK: callbr void asm sideeffect "testl $0, $0; jne ${1:l};", "r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %6, i8* blockaddress(@main, %9), i8* blockaddress(@main, %8)) | ||
; CHECK: to label %7 [label %9, label %8] | ||
; CHECK: 7: | ||
; CHECK-NEXT: store i32 0, i32* %1, align 4 | ||
; CHECK-NEXT: br label %t32.exit | ||
; CHECK: 8: | ||
; CHECK-NEXT: store i32 1, i32* %1, align 4 | ||
; CHECK-NEXT: br label %t32.exit | ||
; CHECK: 9: | ||
; CHECK-NEXT: store i32 2, i32* %1, align 4 | ||
; CHECK-NEXT: br label %t32.exit | ||
; CHECK: t32.exit: | ||
; CHECK-NEXT: %10 = load i32, i32* %1, align 4 | ||
; CHECK: ret i32 %10 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters