[LICM] Drop -licm-n2-threshold option

This was a diagnostic option used to demonstrate a weakness in
the AST-based LICM implementation. This problem does not exist
in the MSSA-based LICM implementation, which has been enabled
for a long time now. As such, this option is no longer relevant.
This commit is contained in:
Nikita Popov 2021-08-17 22:34:33 +02:00
parent 108ba4f4a4
commit e918ba6958
4 changed files with 11 additions and 148 deletions

View File

@ -117,13 +117,6 @@ static cl::opt<uint32_t> MaxNumUsesTraversed(
cl::desc("Max num uses visited for identifying load "
"invariance in loop using invariant start (default = 8)"));
// Default value of zero implies we use the regular alias set tracker mechanism
// instead of the cross product using AA to identify aliasing of the memory
// location we are interested in.
static cl::opt<int>
LICMN2Theshold("licm-n2-threshold", cl::Hidden, cl::init(0),
cl::desc("How many instruction to cross product using AA"));
// Experimental option to allow imprecision in LICM in pathological cases, in
// exchange for faster compile. This is to be removed if MemorySSA starts to
// address the same issue. This flag applies only when LICM uses MemorySSA
@ -2413,48 +2406,7 @@ LoopInvariantCodeMotion::collectAliasInfoForLoop(Loop *L, LoopInfo *LI,
static bool pointerInvalidatedByLoop(MemoryLocation MemLoc,
AliasSetTracker *CurAST, Loop *CurLoop,
AAResults *AA) {
// First check to see if any of the basic blocks in CurLoop invalidate *V.
bool isInvalidatedAccordingToAST = CurAST->getAliasSetFor(MemLoc).isMod();
if (!isInvalidatedAccordingToAST || !LICMN2Theshold)
return isInvalidatedAccordingToAST;
// Check with a diagnostic analysis if we can refine the information above.
// This is to identify the limitations of using the AST.
// The alias set mechanism used by LICM has a major weakness in that it
// combines all things which may alias into a single set *before* asking
// modref questions. As a result, a single readonly call within a loop will
// collapse all loads and stores into a single alias set and report
// invalidation if the loop contains any store. For example, readonly calls
// with deopt states have this form and create a general alias set with all
// loads and stores. In order to get any LICM in loops containing possible
// deopt states we need a more precise invalidation of checking the mod ref
// info of each instruction within the loop and LI. This has a complexity of
// O(N^2), so currently, it is used only as a diagnostic tool since the
// default value of LICMN2Threshold is zero.
// Don't look at nested loops.
if (CurLoop->begin() != CurLoop->end())
return true;
int N = 0;
for (BasicBlock *BB : CurLoop->getBlocks())
for (Instruction &I : *BB) {
if (N >= LICMN2Theshold) {
LLVM_DEBUG(dbgs() << "Alasing N2 threshold exhausted for "
<< *(MemLoc.Ptr) << "\n");
return true;
}
N++;
auto Res = AA->getModRefInfo(&I, MemLoc);
if (isModSet(Res)) {
LLVM_DEBUG(dbgs() << "Aliasing failed on " << I << " for "
<< *(MemLoc.Ptr) << "\n");
return true;
}
}
LLVM_DEBUG(dbgs() << "Aliasing okay for " << *(MemLoc.Ptr) << "\n");
return false;
return CurAST->getAliasSetFor(MemLoc).isMod();
}
bool pointerInvalidatedByLoopWithMSSA(MemorySSA *MSSA, MemoryUse *MU,

View File

@ -1,9 +1,5 @@
; RUN: opt -S -basic-aa -licm -licm-n2-threshold=0 -verify-memoryssa %s -enable-new-pm=0 | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -licm -basic-aa -licm-n2-threshold=200 < %s -S -enable-new-pm=0 | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=200 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -S -basic-aa -licm -verify-memoryssa %s -enable-new-pm=0 | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
declare i32 @foo() readonly argmemonly nounwind
declare i32 @foo2() readonly nounwind
@ -13,9 +9,6 @@ define void @test(i32* %loc) {
; CHECK-LABEL: @test
; CHECK: @foo
; CHECK-LABEL: loop:
; ALIAS-N2-LABEL: @test
; ALIAS-N2: @foo
; ALIAS-N2-LABEL: loop:
br label %loop
loop:
@ -29,9 +22,6 @@ define void @test_neg(i32* %loc) {
; CHECK-LABEL: @test_neg
; CHECK-LABEL: loop:
; CHECK: @foo
; ALIAS-N2-LABEL: @test_neg
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: @foo
br label %loop
loop:
@ -44,9 +34,6 @@ define void @test2(i32* noalias %loc, i32* noalias %loc2) {
; CHECK-LABEL: @test2
; CHECK: @bar
; CHECK-LABEL: loop:
; ALIAS-N2-LABEL: @test2
; ALIAS-N2: @bar
; ALIAS-N2-LABEL: loop:
br label %loop
loop:
@ -60,9 +47,6 @@ define void @test3(i32* %loc) {
; CHECK-LABEL: @test3
; CHECK-LABEL: loop:
; CHECK: @bar
; ALIAS-N2-LABEL: @test3
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: @bar
br label %loop
loop:
@ -78,9 +62,6 @@ define void @test4(i32* %loc, i32* %loc2) {
; CHECK-LABEL: @test4
; CHECK-LABEL: loop:
; CHECK: @bar
; ALIAS-N2-LABEL: @test4
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: @bar
br label %loop
loop:
@ -90,20 +71,11 @@ loop:
}
declare i32 @foo_new(i32*) readonly
; With the default AST mechanism used by LICM for alias analysis,
; we clump foo_new with bar.
; With the N2 Alias analysis diagnostic tool, we are able to hoist the
; argmemonly bar call out of the loop.
; Using MemorySSA we can also hoist bar.
define void @test5(i32* %loc2, i32* noalias %loc) {
; ALIAS-N2-LABEL: @test5
; ALIAS-N2: @bar
; ALIAS-N2-LABEL: loop:
; CHECK-LABEL: @test5
; CHECK: @bar
; CHECK-LABEL: loop:
; CHECK: @bar
br label %loop
loop:
@ -121,10 +93,6 @@ define void @test6(i32* noalias %loc, i32* noalias %loc2) {
; CHECK: %val = load i32, i32* %loc2
; CHECK-LABEL: loop:
; CHECK: @llvm.memcpy
; ALIAS-N2-LABEL: @test6
; ALIAS-N2: %val = load i32, i32* %loc2
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: @llvm.memcpy
br label %loop
loop:
@ -141,10 +109,6 @@ define void @test7(i32* noalias %loc, i32* noalias %loc2) {
; CHECK: %val = load i32, i32* %loc2
; CHECK-LABEL: loop:
; CHECK: @custom_memcpy
; ALIAS-N2-LABEL: @test7
; ALIAS-N2: %val = load i32, i32* %loc2
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: @custom_memcpy
br label %loop
loop:

View File

@ -1,7 +1,5 @@
; RUN: opt -licm -basic-aa -licm-n2-threshold=0 < %s -S | FileCheck %s
; RUN: opt -licm -basic-aa -licm-n2-threshold=200 < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=200 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -licm -basic-aa < %s -S | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
define void @test1(i1 %cond, i32* %ptr) {
; CHECK-LABEL: @test1(
@ -10,12 +8,6 @@ define void @test1(i1 %cond, i32* %ptr) {
; CHECK: %val = load i32, i32* %ptr
; CHECK-LABEL: loop:
; ALIAS-N2-LABEL: @test1(
; ALIAS-N2-LABEL: entry:
; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
; ALIAS-N2: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: loop:
entry:
br label %loop
@ -35,12 +27,6 @@ define void @test2(i1 %cond, i32* %ptr) {
; CHECK: %val = load i32, i32* %ptr
; CHECK-LABEL: loop:
; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %piv)
; ALIAS-N2-LABEL: @test2(
; ALIAS-N2-LABEL: entry:
; ALIAS-N2: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %piv)
entry:
br label %loop
@ -59,12 +45,6 @@ define void @test3(i1 %cond, i32* %ptr) {
; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
; CHECK: %val = load i32, i32* %ptr
; CHECK-LABEL: loop:
; ALIAS-N2-LABEL: @test3(
; ALIAS-N2-LABEL: entry:
; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
; ALIAS-N2: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: loop:
entry:
br label %loop
@ -87,13 +67,6 @@ define void @test4(i1 %cond, i32* %ptr) {
; CHECK: store i32 0, i32* %ptr
; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
; CHECK: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: @test4(
; ALIAS-N2-LABEL: entry:
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: store i32 0, i32* %ptr
; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
; ALIAS-N2: %val = load i32, i32* %ptr
entry:
br label %loop
@ -114,13 +87,6 @@ define void @test5(i1 %cond, i32* %ptr) {
; CHECK: store i32 0, i32* %ptr
; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
; CHECK: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: @test5(
; ALIAS-N2-LABEL: entry:
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: store i32 0, i32* %ptr
; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
; ALIAS-N2: %val = load i32, i32* %ptr
entry:
br label %loop

View File

@ -1,9 +1,5 @@
; RUN: opt -S -basic-aa -licm -licm-n2-threshold=0 %s -enable-new-pm=0 | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -licm -basic-aa -licm-n2-threshold=200 < %s -S -enable-new-pm=0 | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=200 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
; RUN: opt -S -basic-aa -licm %s -enable-new-pm=0 | FileCheck %s
; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
; We should be able to hoist loads in presence of read only calls and stores
; that do not alias.
@ -22,13 +18,8 @@ declare void @foo(i64, i32*) readonly
define void @test1(i32* %ptr) {
; CHECK-LABEL: @test1(
; CHECK-LABEL: entry:
; CHECK: %val = load i32, i32* %ptr
; CHECK-LABEL: loop:
; CHECK: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: @test1(
; ALIAS-N2-LABEL: entry:
; ALIAS-N2: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: loop:
entry:
br label %loop
@ -46,13 +37,8 @@ loop:
define void @test2(i32* %ptr) {
; CHECK-LABEL: @test2(
; CHECK-LABEL: entry:
; CHECK: %val = load i32, i32* %ptr
; CHECK: %val = load i32, i32* %ptr
; CHECK-LABEL: loop:
; ALIAS-N2-LABEL: @test2(
; ALIAS-N2-LABEL: entry:
; ALIAS-N2: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: loop:
entry:
br label %loop
@ -69,12 +55,7 @@ define void @test3(i32* %ptr) {
; CHECK-LABEL: @test3(
; CHECK-LABEL: entry:
; CHECK-LABEL: loop:
; CHECK: %val = load i32, i32* %ptr
; ALIAS-N2-LABEL: @test3(
; ALIAS-N2-LABEL: entry:
; ALIAS-N2-LABEL: loop:
; ALIAS-N2: %val = load i32, i32* %ptr
; CHECK: %val = load i32, i32* %ptr
entry:
br label %loop