[llvm] r331557 - [LICM] Compute a must execute property for the prefix of the header as we go

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri May 4 14:40:34 PDT 2018


Forgot to include that this was reviewed here: 
https://reviews.llvm.org/D46211


On 05/04/2018 02:35 PM, Philip Reames via llvm-commits wrote:
> Author: reames
> Date: Fri May  4 14:35:00 2018
> New Revision: 331557
>
> URL: http://llvm.org/viewvc/llvm-project?rev=331557&view=rev
> Log:
> [LICM] Compute a must execute property for the prefix of the header as we go
>
> Computing this property within the existing walk ensures that the cost is linear with the size of the block. If we did this from within isGuaranteedToExecute, it would be quadratic without some very fancy caching.
>
> This allows us to reliably catch a hoistable instruction within a header which may throw at some point *after* our hoistable instruction. It doesn't do anything for non-header cases, but given how common single block loops are, this seems very worthwhile.
>
>
> Modified:
>      llvm/trunk/lib/Transforms/Scalar/LICM.cpp
>      llvm/trunk/test/Transforms/LICM/preheader-safe.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=331557&r1=331556&r2=331557&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Fri May  4 14:35:00 2018
> @@ -449,6 +449,11 @@ bool llvm::hoistRegion(DomTreeNode *N, A
>       if (inSubLoop(BB, CurLoop, LI))
>         continue;
>   
> +    // Keep track of whether the prefix of instructions visited so far are such
> +    // that the next instruction visited is guaranteed to execute if the loop
> +    // is entered.
> +    bool IsMustExecute = CurLoop->getHeader() == BB;
> +
>       for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
>         Instruction &I = *II++;
>         // Try constant folding this instruction.  If all the operands are
> @@ -496,10 +501,16 @@ bool llvm::hoistRegion(DomTreeNode *N, A
>         //
>         if (CurLoop->hasLoopInvariantOperands(&I) &&
>             canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, SafetyInfo, ORE) &&
> -          isSafeToExecuteUnconditionally(
> -              I, DT, CurLoop, SafetyInfo, ORE,
> -              CurLoop->getLoopPreheader()->getTerminator()))
> +          (IsMustExecute ||
> +           isSafeToExecuteUnconditionally(
> +               I, DT, CurLoop, SafetyInfo, ORE,
> +               CurLoop->getLoopPreheader()->getTerminator()))) {
>           Changed |= hoist(I, DT, CurLoop, SafetyInfo, ORE);
> +        continue;
> +      }
> +
> +      if (IsMustExecute)
> +        IsMustExecute = isGuaranteedToTransferExecutionToSuccessor(&I);
>       }
>     }
>   
>
> Modified: llvm/trunk/test/Transforms/LICM/preheader-safe.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/preheader-safe.ll?rev=331557&r1=331556&r2=331557&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/LICM/preheader-safe.ll (original)
> +++ llvm/trunk/test/Transforms/LICM/preheader-safe.ll Fri May  4 14:35:00 2018
> @@ -55,7 +55,27 @@ loop:
>     br label %loop
>   }
>   
> +; Similiar to the above, but the hoistable instruction (%y in this case)
> +; happens not to be the first instruction in the block.
> +define void @throw_header_after_nonfirst(i64* %xp, i64* %yp, i1* %cond) {
> +; CHECK-LABEL: throw_header_after_nonfirst
> +; CHECK: %y = load i64, i64* %yp
> +; CHECK-LABEL: loop
> +; CHECK: %x = load i64, i64* %gep
> +; CHECK: %div = udiv i64 %x, %y
> +; CHECK: call void @use(i64 %div)
> +entry:
> +  br label %loop
>   
> +loop:                                         ; preds = %entry, %for.inc
> +  %iv = phi i64 [0, %entry], [%div, %loop]
> +  %gep = getelementptr i64, i64* %xp, i64 %iv
> +  %x = load i64, i64* %gep
> +  %y = load i64, i64* %yp
> +  %div = udiv i64 %x, %y
> +  call void @use(i64 %div) readonly
> +  br label %loop
> +}
>   
>   ; Negative test
>   define void @throw_header_before(i64 %x, i64 %y, i1* %cond) {
>
>
> _______________________________________________
> 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