Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -651,6 +651,13 @@ /// set to false, it returns the number of scalar registers. unsigned getNumberOfRegisters(bool Vector) const; + static const unsigned RegisterRichThreshold = 8192; + + /// \brief Return true if the target architecture is register-rich + bool isRegisterRich() const { + return getNumberOfRegisters(false) > RegisterRichThreshold; + } + /// \return The width of the largest scalar or vector register type. unsigned getRegisterBitWidth(bool Vector) const; Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -178,6 +178,8 @@ } } + bool isRegisterRich() { return false; } + bool hasBranchDivergence() { return false; } bool isSourceOfDivergence(const Value *V) { return false; } Index: lib/Transforms/Scalar/GVNHoist.cpp =================================================================== --- lib/Transforms/Scalar/GVNHoist.cpp +++ lib/Transforms/Scalar/GVNHoist.cpp @@ -48,6 +48,7 @@ #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/Analysis/PostDominators.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Argument.h" #include "llvm/IR/BasicBlock.h" @@ -256,8 +257,9 @@ class GVNHoist { public: GVNHoist(DominatorTree *DT, PostDominatorTree *PDT, AliasAnalysis *AA, - MemoryDependenceResults *MD, MemorySSA *MSSA) - : DT(DT), PDT(PDT), AA(AA), MD(MD), MSSA(MSSA), + MemoryDependenceResults *MD, MemorySSA *MSSA, + TargetTransformInfo &TTI) + : DT(DT), PDT(PDT), AA(AA), MD(MD), MSSA(MSSA), TTI(TTI), MSSAUpdater(llvm::make_unique(MSSA)) {} bool run(Function &F) { @@ -333,13 +335,13 @@ AliasAnalysis *AA; MemoryDependenceResults *MD; MemorySSA *MSSA; + TargetTransformInfo &TTI; std::unique_ptr MSSAUpdater; DenseMap DFSNumber; BBSideEffectsSet BBSideEffects; DenseSet HoistBarrier; SmallVector IDFBlocks; unsigned NumFuncArgs; - const bool HoistingGeps = false; enum InsKind { Unknown, Scalar, Load, Store }; @@ -1042,7 +1044,7 @@ if (!allOperandsAvailable(Repl, DestBB)) { // When HoistingGeps there is nothing more we can do to make the // operands available: just continue. - if (HoistingGeps) + if (TTI.isRegisterRich()) continue; // When not HoistingGeps we need to copy the GEPs. @@ -1121,7 +1123,7 @@ break; CI.insert(Call, VN); - } else if (HoistingGeps || !isa(&I1)) + } else if (TTI.isRegisterRich() || !isa(&I1)) // Do not hoist scalars past calls that may write to memory because // that could result in spills later. geps are handled separately. // TODO: We can relax this for targets like AArch64 as they have more @@ -1157,12 +1159,14 @@ auto &AA = getAnalysis().getAAResults(); auto &MD = getAnalysis().getMemDep(); auto &MSSA = getAnalysis().getMSSA(); + auto &TTI = getAnalysis().getTTI(F); - GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA); + GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA, TTI); return G.run(F); } void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -1182,7 +1186,8 @@ AliasAnalysis &AA = AM.getResult(F); MemoryDependenceResults &MD = AM.getResult(F); MemorySSA &MSSA = AM.getResult(F).getMSSA(); - GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA); + TargetTransformInfo &TTI = AM.getResult(F); + GVNHoist G(&DT, &PDT, &AA, &MD, &MSSA, TTI); if (!G.run(F)) return PreservedAnalyses::all();