mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-16 08:29:43 +00:00
eca46e623a
routine. We were getting this wrong in small ways and generally being very inconsistent about it across loop passes. Instead, let's have a common place where we do this. One minor downside is that this will require some analyses like SCEV in more places than they are strictly needed. However, this seems benign as these analyses are complete no-ops, and without this consistency we can in many cases end up with the legacy pass manager scheduling deciding to split up a loop pass pipeline in order to run the function analysis half-way through. It is very, very annoying to fix these without just being very pedantic across the board. The only loop passes I've not updated here are ones that use AU.setPreservesAll() such as IVUsers (an analysis) and the pass printer. They seemed less relevant. With this patch, almost all of the problems in PR24804 around loop pass pipelines are fixed. The one remaining issue is that we run simplify-cfg and instcombine in the middle of the loop pass pipeline. We've recently added some loop variants of these passes that would seem substantially cleaner to use, but this at least gets us much closer to the previous state. Notably, the seven loop pass managers is down to three. I've not updated the loop passes using LoopAccessAnalysis because that analysis hasn't been fully wired into LoopSimplify/LCSSA, and it isn't clear that those transforms want to support those forms anyways. They all run late anyways, so this is harmless. Similarly, LSR is left alone because it already carefully manages its forms and doesn't need to get fused into a single loop pass manager with a bunch of other loop passes. LoopReroll didn't use loop simplified form previously, and I've updated the test case to match the trivially different output. Finally, I've also factored all the pass initialization for the passes that use this technique as well, so that should be done regularly and reliably. Thanks to James for the help reviewing and thinking about this stuff, and Ben for help thinking about it as well! Differential Revision: http://reviews.llvm.org/D17435 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261316 91177308-0d34-0410-b5e6-96231b3b80d8
90 lines
3.2 KiB
LLVM
90 lines
3.2 KiB
LLVM
; Test the particular pass pipelines have the expected structure. This is
|
|
; particularly important in order to check that the implicit scheduling of the
|
|
; legacy pass manager doesn't introduce unexpected structural changes in the
|
|
; pass pipeline.
|
|
;
|
|
; RUN: opt -disable-output -disable-verify -debug-pass=Structure \
|
|
; RUN: -O2 %s 2>&1 \
|
|
; RUN: | FileCheck %s --check-prefix=CHECK-O2
|
|
;
|
|
; In the first pipeline there should just be a function pass manager, no other
|
|
; pass managers.
|
|
; CHECK-O2: Pass Arguments:
|
|
; CHECK-O2-NOT: Manager
|
|
; CHECK-O2: FunctionPass Manager
|
|
; CHECK-O2-NOT: Manager
|
|
;
|
|
; CHECK-O2: Pass Arguments:
|
|
; CHECK-O2: ModulePass Manager
|
|
; CHECK-O2-NOT: Manager
|
|
; First function pass pipeline just does early opts.
|
|
; CHECK-O2: FunctionPass Manager
|
|
; CHECK-O2-NOT: Manager
|
|
; FIXME: It's a bit odd to do dead arg elim in the middle of early opts...
|
|
; CHECK-O2: Dead Argument Elimination
|
|
; CHECK-O2-NEXT: FunctionPass Manager
|
|
; CHECK-O2-NOT: Manager
|
|
; Very carefully asert the CGSCC pass pipeline as it is fragile and unusually
|
|
; susceptible to phase ordering issues.
|
|
; CHECK-O2: CallGraph Construction
|
|
; CHECK-O2-NEXT: Globals Alias Analysis
|
|
; CHECK-O2-NEXT: Call Graph SCC Pass Manager
|
|
; CHECK-O2-NEXT: Remove unused exception handling info
|
|
; CHECK-O2-NEXT: Function Integration/Inlining
|
|
; CHECK-O2-NEXT: Deduce function attributes
|
|
; Next up is the main function pass pipeline. It shouldn't be split up and
|
|
; should contain the main loop pass pipeline as well.
|
|
; CHECK-O2-NEXT: FunctionPass Manager
|
|
; CHECK-O2-NOT: Manager
|
|
; CHECK-O2: Loop Pass Manager
|
|
; CHECK-O2-NOT: Manager
|
|
; FIXME: We shouldn't be pulling out to simplify-cfg and instcombine and
|
|
; causing new loop pass managers.
|
|
; CHECK-O2: Simplify the CFG
|
|
; CHECK-O2-NOT: Manager
|
|
; CHECK-O2: Combine redundant instructions
|
|
; CHECK-O2-NOT: Manager
|
|
; CHECK-O2: Loop Pass Manager
|
|
; CHECK-O2-NOT: Manager
|
|
; FIXME: It isn't clear that we need yet another loop pass pipeline
|
|
; and run of LICM here.
|
|
; CHECK-O2-NOT: Manager
|
|
; CHECK-O2: Loop Pass Manager
|
|
; CHECK-O2-NEXT: Loop Invariant Code Motion
|
|
; CHECK-O2-NOT: Manager
|
|
; Next we break out of the main Function passes inside the CGSCC pipeline with
|
|
; a barrier pass.
|
|
; CHECK-O2: A No-Op Barrier Pass
|
|
; CHECK-O2-NOT: Manager
|
|
; Next is the late function pass pipeline.
|
|
; CHECK-O2: FunctionPass Manager
|
|
; CHECK-O2-NOT: Manager
|
|
; We rotate loops prior to vectorization.
|
|
; CHECK-O2: Loop Pass Manager
|
|
; CHECK-O2-NEXT: Rotate Loops
|
|
; CHECK-O2-NOT: Manager
|
|
; CHECK-O2: Loop Vectorization
|
|
; CHECK-O2-NOT: Manager
|
|
; CHECK-O2: SLP Vectorizer
|
|
; CHECK-O2-NOT: Manager
|
|
; After vectorization we do partial unrolling.
|
|
; CHECK-O2: Loop Pass Manager
|
|
; CHECK-O2-NEXT: Unroll loops
|
|
; CHECK-O2-NOT: Manager
|
|
; After vectorization and unrolling we try to do any cleanup of inserted code,
|
|
; including a run of LICM. This shouldn't run in the same loop pass manager as
|
|
; the runtime unrolling though.
|
|
; CHECK-O2: Loop Pass Manager
|
|
; CHECK-O2-NEXT: Loop Invariant Code Motion
|
|
; CHECK-O2-NOT: Manager
|
|
;
|
|
; FIXME: There really shouldn't be another pass manager, especially one that
|
|
; just builds the domtree. It doesn't even run the verifier.
|
|
; CHECK-O2: Pass Arguments:
|
|
; CHECK-O2-NEXT: FunctionPass Manager
|
|
; CHECK-O2-NEXT: Dominator Tree Construction
|
|
|
|
define void @foo() {
|
|
ret void
|
|
}
|