Index: llvm/lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- llvm/lib/CodeGen/CodeGenPrepare.cpp +++ llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -304,7 +304,7 @@ const TargetTransformInfo *TTI = nullptr; const BasicBlockSectionsProfileReader *BBSectionsProfileReader = nullptr; const TargetLibraryInfo *TLInfo = nullptr; - const LoopInfo *LI = nullptr; + LoopInfo *LI = nullptr; std::unique_ptr BFI; std::unique_ptr BPI; ProfileSummaryInfo *PSI = nullptr; @@ -417,7 +417,7 @@ void removeAllAssertingVHReferences(Value *V); bool eliminateAssumptions(Function &F); - bool eliminateFallThrough(Function &F); + bool eliminateFallThrough(Function &F, DominatorTree *DT = nullptr); bool eliminateMostlyEmptyBlocks(Function &F); BasicBlock *findDestBlockOfMergeableEmptyBlock(BasicBlock *BB); bool canMergeBlocks(const BasicBlock *BB, const BasicBlock *DestBB) const; @@ -578,11 +578,15 @@ // Because the basic algorithm's complex is near O(N!). IsHugeFunc = F.size() > HugeFuncThresholdInCGPP; + // Transformations above may invalidate dominator tree and/or loop info. + DT.reset(); + LI->releaseMemory(); + LI->analyze(getDT(F)); + bool MadeChange = true; bool FuncIterated = false; while (MadeChange) { MadeChange = false; - DT.reset(); for (BasicBlock &BB : llvm::make_early_inc_range(F)) { if (FuncIterated && !FreshBBs.contains(&BB)) @@ -591,6 +595,9 @@ ModifyDT ModifiedDTOnIteration = ModifyDT::NotModifyDT; bool Changed = optimizeBlock(BB, ModifiedDTOnIteration); + if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT) + DT.reset(); + MadeChange |= Changed; if (IsHugeFunc) { // If the BB is updated, it may still has chance to be optimized. @@ -606,9 +613,6 @@ FreshBBs.insert(&BB); else if (FuncIterated) FreshBBs.erase(&BB); - - if (ModifiedDTOnIteration == ModifyDT::ModifyBBDT) - DT.reset(); } else { // For small/normal functions, we restart BB iteration if the dominator // tree of the Function was changed. @@ -626,7 +630,12 @@ MadeChange |= optimizePhiTypes(F); if (MadeChange) - eliminateFallThrough(F); + eliminateFallThrough(F, DT.get()); + +#ifndef NDEBUG + if (MadeChange && VerifyLoopInfo) + LI->verify(getDT(F)); +#endif // Really free removed instructions during promotion. for (Instruction *I : RemovedInsts) @@ -759,7 +768,7 @@ /// Merge basic blocks which are connected by a single edge, where one of the /// basic blocks has a single successor pointing to the other basic block, /// which has a single predecessor. -bool CodeGenPrepare::eliminateFallThrough(Function &F) { +bool CodeGenPrepare::eliminateFallThrough(Function &F, DominatorTree *DT) { bool Changed = false; // Scan all of the blocks in the function, except for the entry block. // Use a temporary array to avoid iterator being invalidated when @@ -781,13 +790,19 @@ if (!SinglePred || SinglePred == BB || BB->hasAddressTaken()) continue; + // Make an effort to skip unreachable blocks. + if (DT && !DT->isReachableFromEntry(BB)) + continue; + BranchInst *Term = dyn_cast(SinglePred->getTerminator()); if (Term && !Term->isConditional()) { Changed = true; LLVM_DEBUG(dbgs() << "To merge:\n" << *BB << "\n\n\n"); // Merge BB into SinglePred and delete it. - MergeBlockIntoPredecessor(BB); + MergeBlockIntoPredecessor(BB, /* DTU */ nullptr, LI, /* MSSAU */ nullptr, + /* MemDep */ nullptr, + /* PredecessorWithTwoSuccessors */ false, DT); Preds.insert(SinglePred); if (IsHugeFunc) { @@ -2135,6 +2150,7 @@ /// /// If the transform is performed, return true and set ModifiedDT to true. static bool despeculateCountZeros(IntrinsicInst *CountZeros, + LoopInfo &LI, const TargetLowering *TLI, const DataLayout *DL, ModifyDT &ModifiedDT, SmallSet &FreshBBs, @@ -2174,6 +2190,13 @@ if (IsHugeFunc) FreshBBs.insert(EndBlock); + // Update the LoopInfo. The new blocks are in the same loop as the start + // block. + if (Loop *L = LI.getLoopFor(StartBlock)) { + L->addBasicBlockToLoop(CallBlock, LI); + L->addBasicBlockToLoop(EndBlock, LI); + } + // Set up a builder to create a compare, conditional branch, and PHI. IRBuilder<> Builder(CountZeros->getContext()); Builder.SetInsertPoint(StartBlock->getTerminator()); @@ -2348,7 +2371,7 @@ case Intrinsic::cttz: case Intrinsic::ctlz: // If counting zeros is expensive, try to avoid it. - return despeculateCountZeros(II, TLI, DL, ModifiedDT, FreshBBs, + return despeculateCountZeros(II, *LI, TLI, DL, ModifiedDT, FreshBBs, IsHugeFunc); case Intrinsic::fshl: case Intrinsic::fshr: @@ -2431,6 +2454,8 @@ if (!RetI) return false; + assert(LI->getLoopFor(BB) == nullptr && "A return block cannot be in a loop"); + PHINode *PN = nullptr; ExtractValueInst *EVI = nullptr; BitCastInst *BCI = nullptr; @@ -6082,7 +6107,7 @@ NewBaseInsertPt = NewBaseInsertBB->getFirstInsertionPt(); else if (InvokeInst *Invoke = dyn_cast(BaseI)) { NewBaseInsertBB = - SplitEdge(NewBaseInsertBB, Invoke->getNormalDest()); + SplitEdge(NewBaseInsertBB, Invoke->getNormalDest(), DT.get(), LI); NewBaseInsertPt = NewBaseInsertBB->getFirstInsertionPt(); } else NewBaseInsertPt = std::next(BaseI->getIterator()); @@ -6939,8 +6964,10 @@ BasicBlock *EndBlock = StartBlock->splitBasicBlock(SplitPt, "select.end"); if (IsHugeFunc) FreshBBs.insert(EndBlock); + Loop *L = LI->getLoopFor(StartBlock); + if (L) + L->addBasicBlockToLoop(EndBlock, *LI); BFI->setBlockFreq(EndBlock, BFI->getBlockFreq(StartBlock).getFrequency()); - // Delete the unconditional branch that was just created by the split. StartBlock->getTerminator()->eraseFromParent(); @@ -6961,6 +6988,8 @@ TrueBranch = BranchInst::Create(EndBlock, TrueBlock); if (IsHugeFunc) FreshBBs.insert(TrueBlock); + if (L) + L->addBasicBlockToLoop(TrueBlock, *LI); TrueBranch->setDebugLoc(SI->getDebugLoc()); } auto *TrueInst = cast(SI->getTrueValue()); @@ -6972,6 +7001,8 @@ EndBlock->getParent(), EndBlock); if (IsHugeFunc) FreshBBs.insert(FalseBlock); + if (L) + L->addBasicBlockToLoop(FalseBlock, *LI); FalseBranch = BranchInst::Create(EndBlock, FalseBlock); FalseBranch->setDebugLoc(SI->getDebugLoc()); } @@ -6990,6 +7021,8 @@ EndBlock->getParent(), EndBlock); if (IsHugeFunc) FreshBBs.insert(FalseBlock); + if (L) + L->addBasicBlockToLoop(FalseBlock, *LI); auto *FalseBranch = BranchInst::Create(EndBlock, FalseBlock); FalseBranch->setDebugLoc(SI->getDebugLoc()); }