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,12 @@ 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."); // 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 +1068,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,11 +1133,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 // there is exactly one write to the location and that write dominates an // arbitrary number of reads in the loop. @@ -1407,6 +1375,8 @@ ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater *MSSAU, ScalarEvolution *SE) { + if (!isSafeToMoveBefore(I, Dest)) + return; SafetyInfo.removeInstruction(&I); SafetyInfo.insertInstructionTo(&I, Dest.getParent()); I.moveBefore(&Dest);