diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp --- a/llvm/lib/CodeGen/MachineCSE.cpp +++ b/llvm/lib/CodeGen/MachineCSE.cpp @@ -130,6 +130,12 @@ DenseMap &OpenChildren); bool PerformCSE(MachineDomTreeNode *Node); + bool isPotentiallyReachableWithoutPassing(const BasicBlock *BBA, + const BasicBlock *BBB, + const BasicBlock *ExclusionBB, + const DominatorTree *DT, + const LoopInfo *LI); + bool isPRECandidate(MachineInstr *MI); bool ProcessBlockPRE(MachineDominatorTree *MDT, MachineBasicBlock *MBB); bool PerformSimplePRE(MachineDominatorTree *DT); @@ -779,6 +785,22 @@ return true; } +/// Determine whether block 'To' is reachable from 'From', without passing +/// through ExclusionBB block, returning true if uncertain. +bool MachineCSE::isPotentiallyReachableWithoutPassing( + const BasicBlock *From, const BasicBlock *To, const BasicBlock *ExclusionBB, + const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr) { + + SmallVector Worklist; + SmallPtrSet ExclusionSet; + Worklist.push_back(const_cast(From)); + if (ExclusionBB != nullptr) + ExclusionSet.insert(const_cast(ExclusionBB)); + + return llvm::isPotentiallyReachableFromMany( + Worklist, const_cast(To), &ExclusionSet, DT, LI); +} + bool MachineCSE::ProcessBlockPRE(MachineDominatorTree *DT, MachineBasicBlock *MBB) { bool Changed = false; @@ -802,13 +824,14 @@ if (!CMBB->isLegalToHoistInto()) continue; - // Two instrs are partial redundant if their basic blocks are reachable - // from one to another but one doesn't dominate another. + // Two equal instrs are partially redundant if their basic blocks are + // reachable from one to another but one doesn't dominate another. if (CMBB != MBB1) { - auto BB = MBB->getBasicBlock(), BB1 = MBB1->getBasicBlock(); + auto BB = MBB->getBasicBlock(), BB1 = MBB1->getBasicBlock(), + CBB = CMBB->getBasicBlock(); if (BB != nullptr && BB1 != nullptr && - (isPotentiallyReachable(BB1, BB) || - isPotentiallyReachable(BB, BB1))) { + (MachineCSE::isPotentiallyReachableWithoutPassing(BB1, BB, CBB) || + MachineCSE::isPotentiallyReachableWithoutPassing(BB, BB1, CBB))) { assert(MI->getOperand(0).isDef() && "First operand of instr with one explicit def must be this def");