From: Johannes Doerfert Date: Sun, 2 Aug 2020 05:44:08 +0000 (-0500) Subject: [Attributor] Bail early if AAMemoryLocation cannot derive anything X-Git-Tag: llvmorg-13-init~14433 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8abd69aa9e8c21b9958f531b03ad9801ec850154;p=platform%2Fupstream%2Fllvm.git [Attributor] Bail early if AAMemoryLocation cannot derive anything Before this change we looked through all memory operations in a function even if the first was an unknown call that could do anything. This did cost a lot of time but there is little use to do so. We also avoid creating AAs for things that we would have looked at in case no other AA will; that is the reason for the test changes. Running only the attributor-cgscc pass on a IR version of `llvm-test-suite/MultiSource/Applications/SPASS/clause.c` reduced the time we spend in `AAMemoryLocation::update` from 4% total to 0.9% (disclaimer: no accurate measurements). --- diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 81fc52c..a1bcec8 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -6628,7 +6628,9 @@ struct AAMemoryLocationFunction final : public AAMemoryLocationImpl { LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I << ": " << getMemoryLocationsAsStr(MLK) << "\n"); removeAssumedBits(inverseLocation(MLK, false, false)); - return true; + // Stop once only the valid bit set in the *not assumed location*, thus + // once we don't actually exclude any memory locations in the state. + return getAssumedNotAccessedLocation() != VALID_STATE; }; if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this)) diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll index 9a99539..3f8fb81 100644 --- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll @@ -280,6 +280,7 @@ define void @f7_2(i1 %c) { ; CHECK-SAME: (i1 [[C:%.*]]) ; CHECK-NEXT: [[PTR:%.*]] = tail call nonnull align 4 dereferenceable(4) i32* @unkown_ptr() ; CHECK-NEXT: [[A:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) [[PTR]]) +; CHECK-NEXT: [[ARG_A_0:%.*]] = load i32, i32* [[PTR]], align 4 ; CHECK-NEXT: [[B:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) [[PTR]]) ; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; CHECK: if.true: diff --git a/llvm/test/Transforms/Attributor/heap_to_stack.ll b/llvm/test/Transforms/Attributor/heap_to_stack.ll index 54e293e..28c0166 100644 --- a/llvm/test/Transforms/Attributor/heap_to_stack.ll +++ b/llvm/test/Transforms/Attributor/heap_to_stack.ll @@ -450,10 +450,11 @@ define i32 @irreducible_cfg(i32 %0) { ; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1 ; IS________OPM-NEXT: br label [[TMP8]] ; IS________OPM: 15: -; IS________OPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8* -; IS________OPM-NEXT: call void @free(i8* nocapture [[TMP16]]) -; IS________OPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP17]] +; IS________OPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________OPM-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8* +; IS________OPM-NEXT: call void @free(i8* nocapture [[TMP17]]) +; IS________OPM-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________OPM-NEXT: ret i32 [[TMP18]] ; ; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg ; IS________NPM-SAME: (i32 [[TMP0:%.*]]) diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll index 57017c5..f3bd7ef 100644 --- a/llvm/test/Transforms/Attributor/liveness.ll +++ b/llvm/test/Transforms/Attributor/liveness.ll @@ -1920,7 +1920,7 @@ define i32 @main() { ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[G_0]], 1 ; CHECK-NEXT: br label [[FOR_COND_0]] ; CHECK: for.end.0: -; CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 8) +; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 8) ; CHECK-NEXT: store i8* [[CALL]], i8** bitcast (%struct.a** @e to i8**), align 8 ; CHECK-NEXT: [[B:%.*]] = bitcast i8* [[CALL]] to %struct.a** ; CHECK-NEXT: store %struct.a* null, %struct.a** [[B]], align 8 diff --git a/llvm/test/Transforms/Attributor/noreturn_async.ll b/llvm/test/Transforms/Attributor/noreturn_async.ll index 4c0fc20..879fb16 100644 --- a/llvm/test/Transforms/Attributor/noreturn_async.ll +++ b/llvm/test/Transforms/Attributor/noreturn_async.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes -; RUN: opt -attributor -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s +; RUN: opt -attributor -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s ; ; This file is the same as noreturn_sync.ll but with a personality which ; indicates that the exception handler *can* catch asynchronous exceptions. As