diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -72,6 +72,7 @@ #include "llvm/Transforms/Scalar/LoopPassManager.h" #include "llvm/Transforms/Utils/AssumeBundleBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/CodeMoverUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" @@ -985,19 +986,6 @@ } namespace { -/// Return true if-and-only-if we know how to (mechanically) both hoist and -/// sink a given instruction out of a loop. Does not address legality -/// concerns such as aliasing or speculation safety. -bool isHoistableAndSinkableInst(Instruction &I) { - // Only these instructions are hoistable/sinkable. - return (isa(I) || isa(I) || isa(I) || - isa(I) || isa(I) || isa(I) || - isa(I) || isa(I) || - isa(I) || isa(I) || - isa(I) || isa(I) || - isa(I) || isa(I) || - isa(I) || isa(I)); -} /// Return true if all of the alias sets within this AST are known not to /// contain a Mod, or if MSSA knows thare are no MemoryDefs in the loop. bool isReadOnly(AliasSetTracker *CurAST, const MemorySSAUpdater *MSSAU, @@ -1041,19 +1029,15 @@ bool TargetExecutesOncePerLoop, SinkAndHoistLICMFlags *Flags, OptimizationRemarkEmitter *ORE) { - // If we don't understand the instruction, bail early. - if (!isHoistableAndSinkableInst(I)) - return false; - MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr; if (MSSA) assert(Flags != nullptr && "Flags cannot be null."); + // Check code motion candidate + if (!isSafeToMove(I)) + return false; // Loads have extra constraints we have to verify before we can hoist them. if (LoadInst *LI = dyn_cast(&I)) { - if (!LI->isUnordered()) - return false; // Don't sink/hoist volatile or ordered atomic loads! - // Loads from constant memory are always safe to move, even if they end up // in the same alias set as something that ends up being modified. if (AA->pointsToConstantMemory(LI->getOperand(0))) @@ -1087,14 +1071,6 @@ return !Invalidated; } else if (CallInst *CI = dyn_cast(&I)) { - // Don't sink or hoist dbg info; it's legal, but not useful. - if (isa(I)) - return false; - - // Don't sink calls which can throw. - if (CI->mayThrow()) - return false; - using namespace PatternMatch; if (match(CI, m_Intrinsic())) // Assumes don't actually alias anything or throw @@ -1160,9 +1136,6 @@ } else // MSSAU return isOnlyMemoryAccess(FI, CurLoop, MSSAU); } else if (auto *SI = dyn_cast(&I)) { - if (!SI->isUnordered()) - return false; // Don't sink/hoist volatile or ordered atomic store! - // We can only hoist a store that we can prove writes a value which is not // read or overwritten within the loop. For those cases, we fallback to // load store promotion instead. TODO: We can extend this to cases where