Index: lib/Transforms/Scalar/ADCE.cpp =================================================================== --- lib/Transforms/Scalar/ADCE.cpp +++ lib/Transforms/Scalar/ADCE.cpp @@ -58,6 +58,10 @@ bool Live = false; /// True when this block ends in an unconditional branch. bool UnconditionalBranch = false; + /// True when this block is known to have live PHI nodes. + bool HasLivePhiNodes = false; + /// Control dependence sources need to be live for this block. + bool CFLive = false; /// Quick access to the LiveInfo for the terminator, /// holds the value &InstInfo[Terminator] @@ -109,6 +113,9 @@ void markLiveInstructions(); /// Mark an instruction as live. void markLive(Instruction *I); + + /// Mark terminators of control predecessors of a PHI node live. + void markPhiLive(PHINode *PN); /// Record the Debug Scopes which surround live debug information. void collectLiveScopes(const DILocalScope &LS); @@ -269,15 +276,18 @@ // where we need to mark the inputs as live. while (!Worklist.empty()) { Instruction *LiveInst = Worklist.pop_back_val(); + DEBUG(dbgs() << "work live: "; LiveInst->dump();); // Collect the live debug info scopes attached to this instruction. if (const DILocation *DL = LiveInst->getDebugLoc()) collectLiveScopes(*DL); - DEBUG(dbgs() << "work live: "; LiveInst->dump();); for (Use &OI : LiveInst->operands()) if (Instruction *Inst = dyn_cast(OI)) markLive(Inst); + + if (auto *PN = dyn_cast(LiveInst)) + markPhiLive(PN); } markLiveBranchesFromControlDependences(); @@ -315,7 +325,10 @@ DEBUG(dbgs() << "mark block live: " << BBInfo.BB->getName() << '\n'); BBInfo.Live = true; - NewLiveBlocks.insert(BBInfo.BB); + if (!BBInfo.CFLive) { + BBInfo.CFLive = true; + NewLiveBlocks.insert(BBInfo.BB); + } // Mark unconditional branches at the end of live // blocks as live since there is no work to do for them later @@ -348,6 +361,25 @@ collectLiveScopes(*IA); } +void AggressiveDeadCodeElimination::markPhiLive(PHINode *PN) { + auto &Info = BlockInfo[PN->getParent()]; + // Only need to check this once per block. + if (Info.HasLivePhiNodes) + return; + Info.HasLivePhiNodes = true; + + // If a predecessor block is not live, mark it as control-flow live + // which will trigger marking live branches upon which + // that block is control dependent. + for (auto *PredBB : predecessors(Info.BB)) { + auto &Info = BlockInfo[PredBB]; + if (!Info.CFLive) { + Info.CFLive = true; + NewLiveBlocks.insert(PredBB); + } + } +} + void AggressiveDeadCodeElimination::markLiveBranchesFromControlDependences() { if (BlocksWithDeadTerminators.empty()) @@ -382,6 +414,11 @@ } } +//===----------------------------------------------------------------------===// +// +// Routines to update the CFG and SSA information before removing dead code. +// +//===----------------------------------------------------------------------===// bool AggressiveDeadCodeElimination::removeDeadInstructions() { // The inverse of the live set is the dead set. These are those instructions