diff --git a/include/llvm/Transforms/Scalar/GVN.h b/include/llvm/Transforms/Scalar/GVN.h index 784de7f9fe2..9827678b89f 100644 --- a/include/llvm/Transforms/Scalar/GVN.h +++ b/include/llvm/Transforms/Scalar/GVN.h @@ -27,6 +27,7 @@ #include "llvm/IR/Dominators.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include @@ -180,7 +181,12 @@ private: // Map the block to reversed postorder traversal number. It is used to // find back edge easily. - DenseMap BlockRPONumber; + DenseMap, uint32_t> BlockRPONumber; + + // This is set 'true' initially and also when new blocks have been added to + // the function being analyzed. This boolean is used to control the updating + // of BlockRPONumber prior to accessing the contents of BlockRPONumber. + bool InvalidBlockRPONumbers = true; using LoadDepVect = SmallVector; using AvailValInBlkVect = SmallVector; diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 9598e595c5e..9861948c829 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1645,10 +1645,12 @@ static bool isOnlyReachableViaThisEdge(const BasicBlockEdge &E, } void GVN::assignBlockRPONumber(Function &F) { + BlockRPONumber.clear(); uint32_t NextBlockNumber = 1; ReversePostOrderTraversal RPOT(&F); for (BasicBlock *BB : RPOT) BlockRPONumber[BB] = NextBlockNumber++; + InvalidBlockRPONumbers = false; } // Tries to replace instruction with const, using information from @@ -1992,6 +1994,7 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT, ICF = &ImplicitCFT; VN.setMemDep(MD); ORE = RunORE; + InvalidBlockRPONumbers = true; bool Changed = false; bool ShouldContinue = true; @@ -2021,7 +2024,6 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT, // Fabricate val-num for dead-code in order to suppress assertion in // performPRE(). assignValNumForDeadCode(); - assignBlockRPONumber(F); bool PREChanged = true; while (PREChanged) { PREChanged = performPRE(F); @@ -2183,6 +2185,10 @@ bool GVN::performScalarPRE(Instruction *CurInst) { BasicBlock *PREPred = nullptr; BasicBlock *CurrentBlock = CurInst->getParent(); + // Update the RPO numbers for this function. + if (InvalidBlockRPONumbers) + assignBlockRPONumber(*CurrentBlock->getParent()); + SmallVector, 8> predMap; for (BasicBlock *P : predecessors(CurrentBlock)) { // We're not interested in PRE where blocks with predecessors that are @@ -2194,6 +2200,8 @@ bool GVN::performScalarPRE(Instruction *CurInst) { // It is not safe to do PRE when P->CurrentBlock is a loop backedge, and // when CurInst has operand defined in CurrentBlock (so it may be defined // by phi in the loop header). + assert(BlockRPONumber.count(P) && BlockRPONumber.count(CurrentBlock) && + "Invalid BlockRPONumber map."); if (BlockRPONumber[P] >= BlockRPONumber[CurrentBlock] && llvm::any_of(CurInst->operands(), [&](const Use &U) { if (auto *Inst = dyn_cast(U.get())) @@ -2341,6 +2349,7 @@ BasicBlock *GVN::splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ) { SplitCriticalEdge(Pred, Succ, CriticalEdgeSplittingOptions(DT)); if (MD) MD->invalidateCachedPredecessors(); + InvalidBlockRPONumbers = true; return BB; } @@ -2355,6 +2364,7 @@ bool GVN::splitCriticalEdges() { CriticalEdgeSplittingOptions(DT)); } while (!toSplit.empty()); if (MD) MD->invalidateCachedPredecessors(); + InvalidBlockRPONumbers = true; return true; } @@ -2381,6 +2391,7 @@ void GVN::cleanupGlobalSets() { BlockRPONumber.clear(); TableAllocator.Reset(); ICF->clear(); + InvalidBlockRPONumbers = true; } /// Verify that the specified instruction does not occur in our