[llvm] r339378 - [LICM] hoist fences out of loops w/o memory operations
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 9 14:16:37 PDT 2018
Build bot failure seen due to a warning in debug mode. Fixed in 339388.
On 08/09/2018 01:18 PM, Philip Reames via llvm-commits wrote:
> Author: reames
> Date: Thu Aug 9 13:18:42 2018
> New Revision: 339378
>
> URL: http://llvm.org/viewvc/llvm-project?rev=339378&view=rev
> Log:
> [LICM] hoist fences out of loops w/o memory operations
>
> The motivating case is an otherwise dead loop with a fence in it. At the moment, this goes all the way through the optimizer and we end up emitting an entirely pointless loop on x86. This case may seem a bit contrived, but we've seen it in real code as the result of otherwise reasonable lowering strategies combined w/thread local memory optimizations (such as escape analysis).
>
> To handle this simple case, we can teach LICM to hoist must execute fences when there is no other memory operation within the loop.
>
> Differential Revision: https://reviews.llvm.org/D50489
>
>
> Modified:
> llvm/trunk/include/llvm/Analysis/AliasSetTracker.h
> llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> llvm/trunk/test/Transforms/LICM/fence.ll
>
> Modified: llvm/trunk/include/llvm/Analysis/AliasSetTracker.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasSetTracker.h?rev=339378&r1=339377&r2=339378&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/AliasSetTracker.h (original)
> +++ llvm/trunk/include/llvm/Analysis/AliasSetTracker.h Thu Aug 9 13:18:42 2018
> @@ -224,6 +224,20 @@ public:
> // track of the list's exact size.
> unsigned size() { return SetSize; }
>
> + /// If this alias set is known to contain a single instruction and *only* a
> + /// single unique instruction, return it. Otherwise, return nullptr.
> + Instruction* getUniqueInstruction() {
> + if (size() != 0)
> + // Can't track source of pointer, might be many instruction
> + return nullptr;
> + if (AliasAny)
> + // May have collapses alias set
> + return nullptr;
> + if (1 != UnknownInsts.size())
> + return nullptr;
> + return cast<Instruction>(UnknownInsts[0]);
> + }
> +
> void print(raw_ostream &OS) const;
> void dump() const;
>
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=339378&r1=339377&r2=339378&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Thu Aug 9 13:18:42 2018
> @@ -582,6 +582,7 @@ namespace {
> bool isHoistableAndSinkableInst(Instruction &I) {
> // Only these instructions are hoistable/sinkable.
> return (isa<LoadInst>(I) || isa<CallInst>(I) ||
> + isa<FenceInst>(I) ||
> isa<BinaryOperator>(I) || isa<CastInst>(I) ||
> isa<SelectInst>(I) || isa<GetElementPtrInst>(I) ||
> isa<CmpInst>(I) || isa<InsertElementInst>(I) ||
> @@ -684,6 +685,20 @@ bool llvm::canSinkOrHoistInst(Instructio
> // sink the call.
>
> return false;
> + } else if (auto *FI = dyn_cast<FenceInst>(&I)) {
> + // Fences alias (most) everything to provide ordering. For the moment,
> + // just give up if there are any other memory operations in the loop.
> + auto Begin = CurAST->begin();
> + assert(Begin != CurAST->end() && "must contain FI");
> + if (std::next(Begin) != CurAST->end())
> + // constant memory for instance, TODO: handle better
> + return false;
> + auto *UniqueI = Begin->getUniqueInstruction();
> + if (!UniqueI)
> + // other memory op, give up
> + return false;
> + assert(UniqueI == FI && "AS must contain FI");
> + return true;
> }
>
> assert(!I.mayReadOrWriteMemory() && "unhandled aliasing");
>
> Modified: llvm/trunk/test/Transforms/LICM/fence.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/fence.ll?rev=339378&r1=339377&r2=339378&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/LICM/fence.ll (original)
> +++ llvm/trunk/test/Transforms/LICM/fence.ll Thu Aug 9 13:18:42 2018
> @@ -3,8 +3,8 @@
>
> define void @test1(i64 %n) {
> ; CHECK-LABEL: @test1
> -; CHECK-LABEL: loop:
> ; CHECK: fence
> +; CHECK-LABEL: loop:
> entry:
> br label %loop
> loop:
> @@ -19,8 +19,8 @@ exit:
>
> define void @test2(i64 %n) {
> ; CHECK-LABEL: @test2
> -; CHECK-LABEL: loop:
> ; CHECK: fence
> +; CHECK-LABEL: loop:
> entry:
> br label %loop
> loop:
> @@ -35,8 +35,8 @@ exit:
>
> define void @test3(i64 %n) {
> ; CHECK-LABEL: @test3
> -; CHECK-LABEL: loop:
> ; CHECK: fence
> +; CHECK-LABEL: loop:
> entry:
> br label %loop
> loop:
> @@ -51,8 +51,8 @@ exit:
>
> define void @test4(i64 %n) {
> ; CHECK-LABEL: @test4
> -; CHECK-LABEL: loop:
> ; CHECK: fence
> +; CHECK-LABEL: loop:
> entry:
> br label %loop
> loop:
> @@ -99,8 +99,10 @@ exit:
> ret void
> }
>
> -define void @testfp1(i64 %n, i64* %p) {
> -; CHECK-LABEL: @testfp1
> +; Note: While a false negative for LICM on it's own, O3 does get this
> +; case by combining the fences.
> +define void @testfn1(i64 %n, i64* %p) {
> +; CHECK-LABEL: @testfn1
> ; CHECK-LABEL: loop:
> ; CHECK: fence
> entry:
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list