[llvm] r290734 - [LICM] Make logic in promoteLoopAccessesToScalars easier to follow. NFC.
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 29 16:57:48 PST 2016
Very nice cleanup. Thank you.
Philip
On 12/29/2016 04:39 PM, Michael Kuperstein via llvm-commits wrote:
> Author: mkuper
> Date: Thu Dec 29 18:39:00 2016
> New Revision: 290734
>
> URL: http://llvm.org/viewvc/llvm-project?rev=290734&view=rev
> Log:
> [LICM] Make logic in promoteLoopAccessesToScalars easier to follow. NFC.
>
> Modified:
> llvm/trunk/lib/Transforms/Scalar/LICM.cpp
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=290734&r1=290733&r2=290734&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Thu Dec 29 18:39:00 2016
> @@ -904,23 +904,24 @@ bool llvm::promoteLoopAccessesToScalars(
> // is not safe, because *P may only be valid to access if 'c' is true.
> //
> // The safety property divides into two parts:
> - // 1) The memory may not be dereferenceable on entry to the loop. In this
> + // p1) The memory may not be dereferenceable on entry to the loop. In this
> // case, we can't insert the required load in the preheader.
> - // 2) The memory model does not allow us to insert a store along any dynamic
> + // p2) The memory model does not allow us to insert a store along any dynamic
> // path which did not originally have one.
> //
> - // It is safe to promote P if all uses are direct load/stores and if at
> - // least one is guaranteed to be executed.
> - bool GuaranteedToExecute = false;
> -
> - // It is also safe to promote P if we can prove that speculating a load into
> - // the preheader is safe (i.e. proving dereferenceability on all
> - // paths through the loop), and that the memory can be proven thread local
> - // (so that the memory model requirement doesn't apply.) We first establish
> - // the former, and then run a capture analysis below to establish the later.
> - // We can use any access within the alias set to prove dereferenceability
> + // If at least one store is guaranteed to execute, both properties are
> + // satisfied, and promotion is legal.
> + // This, however, is not a necessary condition. Even if no store/load is
> + // guaranteed to execute, we can still establish these properties:
> + // (p1) by proving that hoisting the load into the preheader is
> + // safe (i.e. proving dereferenceability on all paths through the loop). We
> + // can use any access within the alias set to prove dereferenceability,
> // since they're all must alias.
> - bool CanSpeculateLoad = false;
> + // (p2) by proving the memory is thread-local, so the memory model
> + // requirement does not apply, and stores are safe to insert.
> +
> + bool DereferenceableInPH = false;
> + bool SafeToInsertStore = false;
>
> SmallVector<Instruction *, 64> LoopUses;
> SmallPtrSet<Value *, 4> PointerMustAliases;
> @@ -969,8 +970,8 @@ bool llvm::promoteLoopAccessesToScalars(
> if (!Load->isSimple())
> return Changed;
>
> - if (!GuaranteedToExecute && !CanSpeculateLoad)
> - CanSpeculateLoad = isSafeToExecuteUnconditionally(
> + if (!DereferenceableInPH)
> + DereferenceableInPH = isSafeToExecuteUnconditionally(
> *Load, DT, CurLoop, SafetyInfo, Preheader->getTerminator());
> } else if (const StoreInst *Store = dyn_cast<StoreInst>(UI)) {
> // Stores *of* the pointer are not interesting, only stores *to* the
> @@ -981,28 +982,29 @@ bool llvm::promoteLoopAccessesToScalars(
> if (!Store->isSimple())
> return Changed;
>
> - // Note that we only check GuaranteedToExecute inside the store case
> - // so that we do not introduce stores where they did not exist before
> - // (which would break the LLVM concurrency model).
> -
> - // If the alignment of this instruction allows us to specify a more
> - // restrictive (and performant) alignment and if we are sure this
> - // instruction will be executed, update the alignment.
> - // Larger is better, with the exception of 0 being the best alignment.
> + // If the store is guaranteed to execute, both properties are satisfied.
> + // We may want to check if a store is guaranteed to execute even if we
> + // already know that promotion is safe, since it may have higher
> + // alignment than any other guaranteed stores, in which case we can
> + // raise the alignment on the promoted store.
> unsigned InstAlignment = Store->getAlignment();
> - if ((InstAlignment > Alignment || InstAlignment == 0) &&
> - Alignment != 0) {
> + if (!InstAlignment)
> + InstAlignment =
> + MDL.getABITypeAlignment(Store->getValueOperand()->getType());
> +
> + if (!DereferenceableInPH || !SafeToInsertStore ||
> + (InstAlignment > Alignment)) {
> if (isGuaranteedToExecute(*UI, DT, CurLoop, SafetyInfo)) {
> - GuaranteedToExecute = true;
> - Alignment = InstAlignment;
> + DereferenceableInPH = true;
> + SafeToInsertStore = true;
> + Alignment = std::max(Alignment, InstAlignment);
> }
> - } else if (!GuaranteedToExecute) {
> - GuaranteedToExecute =
> - isGuaranteedToExecute(*UI, DT, CurLoop, SafetyInfo);
> }
>
> - if (!GuaranteedToExecute && !CanSpeculateLoad) {
> - CanSpeculateLoad = isDereferenceableAndAlignedPointer(
> + // If the store is not guaranteed to execute, we may still get
> + // deref info through it.
> + if (!DereferenceableInPH) {
> + DereferenceableInPH = isDereferenceableAndAlignedPointer(
> Store->getPointerOperand(), Store->getAlignment(), MDL,
> Preheader->getTerminator(), DT);
> }
> @@ -1021,18 +1023,23 @@ bool llvm::promoteLoopAccessesToScalars(
> }
> }
>
> - // Check legality per comment above. Otherwise, we can't promote.
> - bool PromotionIsLegal = GuaranteedToExecute;
> - if (!PromotionIsLegal && CanSpeculateLoad) {
> - // If this is a thread local location, then we can insert stores along
> - // paths which originally didn't have them without violating the memory
> - // model.
> +
> + // If we couldn't prove we can hoist the load, bail.
> + if (!DereferenceableInPH)
> + return Changed;
> +
> + // We know we can hoist the load, but don't have a guaranteed store.
> + // Check whether the location is thread-local. If it is, then we can insert
> + // stores along paths which originally didn't have them without violating the
> + // memory model.
> + if (!SafeToInsertStore) {
> Value *Object = GetUnderlyingObject(SomePtr, MDL);
> - PromotionIsLegal =
> + SafeToInsertStore =
> isAllocLikeFn(Object, TLI) && !PointerMayBeCaptured(Object, true, true);
> }
>
> - if (!PromotionIsLegal)
> + // If we've still failed to prove we can sink the store, give up.
> + if (!SafeToInsertStore)
> return Changed;
>
> // Otherwise, this is safe to promote, lets do it!
>
>
> _______________________________________________
> 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