diff options
-rw-r--r-- | llvm/lib/Transforms/IPO/GlobalOpt.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index ddfc52273ca..812ee243738 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -87,9 +87,10 @@ namespace { bool ProcessInternalGlobal(GlobalVariable *GV,Module::global_iterator &GVI, const GlobalStatus &GS); bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn); - - bool isPointerValueDeadOnEntryToFunction(const Function *F, GlobalValue *GV); - + + bool isPointerValueDeadOnEntryToFunction(const Function *F, + GlobalValue *GV); + TargetLibraryInfo *TLI; SmallSet<const Comdat *, 8> NotDiscardableComdats; }; @@ -1770,6 +1771,19 @@ bool GlobalOpt::isPointerValueDeadOnEntryToFunction(const Function *F, GlobalVal auto &DT = getAnalysis<DominatorTreeWrapperPass>(*const_cast<Function *>(F)) .getDomTree(); + // The below check is quadratic. Check we're not going to do too many tests. + // FIXME: Even though this will always have worst-case quadratic time, we + // could put effort into minimizing the average time by putting stores that + // have been shown to dominate at least one load at the beginning of the + // Stores array, making subsequent dominance checks more likely to succeed + // early. + // + // The threshold here is fairly large because global->local demotion is a + // very powerful optimization should it fire. + const unsigned Threshold = 100; + if (Loads.size() * Stores.size() > Threshold) + return false; + for (auto *L : Loads) { auto *LTy = L->getType(); if (!std::any_of(Stores.begin(), Stores.end(), [&](StoreInst *S) { |