1 //===- ADCE.cpp - Code to perform dead code elimination -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Aggressive Dead Code Elimination pass. This pass 11 // optimistically assumes that all instructions are dead until proven otherwise, 12 // allowing it to eliminate dead computations that other DCE passes do not 13 // catch, particularly involving loop computations. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "llvm/Transforms/Scalar/ADCE.h" 18 19 #include "llvm/ADT/DepthFirstIterator.h" 20 #include "llvm/ADT/PostOrderIterator.h" 21 #include "llvm/ADT/SmallPtrSet.h" 22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/Statistic.h" 24 #include "llvm/Analysis/GlobalsModRef.h" 25 #include "llvm/Analysis/IteratedDominanceFrontier.h" 26 #include "llvm/Analysis/PostDominators.h" 27 #include "llvm/IR/BasicBlock.h" 28 #include "llvm/IR/CFG.h" 29 #include "llvm/IR/DebugInfoMetadata.h" 30 #include "llvm/IR/Dominators.h" 31 #include "llvm/IR/IRBuilder.h" 32 #include "llvm/IR/InstIterator.h" 33 #include "llvm/IR/Instructions.h" 34 #include "llvm/IR/IntrinsicInst.h" 35 #include "llvm/Pass.h" 36 #include "llvm/ProfileData/InstrProf.h" 37 #include "llvm/Transforms/Scalar.h" 38 using namespace llvm; 39 40 #define DEBUG_TYPE "adce" 41 42 STATISTIC(NumRemoved, "Number of instructions removed"); 43 STATISTIC(NumBranchesRemoved, "Number of branch instructions removed"); 44 45 // This is a temporary option until we change the interface to this pass based 46 // on optimization level. 47 static cl::opt<bool> RemoveControlFlowFlag("adce-remove-control-flow", 48 cl::init(true), cl::Hidden); 49 50 // This option enables removing of may-be-infinite loops which have no other 51 // effect. 52 static cl::opt<bool> RemoveLoops("adce-remove-loops", cl::init(false), 53 cl::Hidden); 54 55 namespace { 56 /// Information about Instructions 57 struct InstInfoType { 58 /// True if the associated instruction is live. 59 bool Live = false; 60 /// Quick access to information for block containing associated Instruction. 61 struct BlockInfoType *Block = nullptr; 62 }; 63 64 /// Information about basic blocks relevant to dead code elimination. 65 struct BlockInfoType { 66 /// True when this block contains a live instructions. 67 bool Live = false; 68 /// True when this block ends in an unconditional branch. 69 bool UnconditionalBranch = false; 70 /// True when this block is known to have live PHI nodes. 71 bool HasLivePhiNodes = false; 72 /// Control dependence sources need to be live for this block. 73 bool CFLive = false; 74 75 /// Quick access to the LiveInfo for the terminator, 76 /// holds the value &InstInfo[Terminator] 77 InstInfoType *TerminatorLiveInfo = nullptr; 78 79 bool terminatorIsLive() const { return TerminatorLiveInfo->Live; } 80 81 /// Corresponding BasicBlock. 82 BasicBlock *BB = nullptr; 83 84 /// Cache of BB->getTerminator(). 85 TerminatorInst *Terminator = nullptr; 86 87 /// Post-order numbering of reverse control flow graph. 88 unsigned PostOrder; 89 }; 90 91 class AggressiveDeadCodeElimination { 92 Function &F; 93 94 // ADCE does not use DominatorTree per se, but it updates it to preserve the 95 // analysis. 96 DominatorTree &DT; 97 PostDominatorTree &PDT; 98 99 /// Mapping of blocks to associated information, an element in BlockInfoVec. 100 DenseMap<BasicBlock *, BlockInfoType> BlockInfo; 101 bool isLive(BasicBlock *BB) { return BlockInfo[BB].Live; } 102 103 /// Mapping of instructions to associated information. 104 DenseMap<Instruction *, InstInfoType> InstInfo; 105 bool isLive(Instruction *I) { return InstInfo[I].Live; } 106 107 /// Instructions known to be live where we need to mark 108 /// reaching definitions as live. 109 SmallVector<Instruction *, 128> Worklist; 110 /// Debug info scopes around a live instruction. 111 SmallPtrSet<const Metadata *, 32> AliveScopes; 112 113 /// Set of blocks with not known to have live terminators. 114 SmallPtrSet<BasicBlock *, 16> BlocksWithDeadTerminators; 115 116 /// The set of blocks which we have determined whose control 117 /// dependence sources must be live and which have not had 118 /// those dependences analyzed. 119 SmallPtrSet<BasicBlock *, 16> NewLiveBlocks; 120 121 /// Set up auxiliary data structures for Instructions and BasicBlocks and 122 /// initialize the Worklist to the set of must-be-live Instruscions. 123 void initialize(); 124 /// Return true for operations which are always treated as live. 125 bool isAlwaysLive(Instruction &I); 126 /// Return true for instrumentation instructions for value profiling. 127 bool isInstrumentsConstant(Instruction &I); 128 129 /// Propagate liveness to reaching definitions. 130 void markLiveInstructions(); 131 /// Mark an instruction as live. 132 void markLive(Instruction *I); 133 /// Mark a block as live. 134 void markLive(BlockInfoType &BB); 135 void markLive(BasicBlock *BB) { markLive(BlockInfo[BB]); } 136 137 /// Mark terminators of control predecessors of a PHI node live. 138 void markPhiLive(PHINode *PN); 139 140 /// Record the Debug Scopes which surround live debug information. 141 void collectLiveScopes(const DILocalScope &LS); 142 void collectLiveScopes(const DILocation &DL); 143 144 /// Analyze dead branches to find those whose branches are the sources 145 /// of control dependences impacting a live block. Those branches are 146 /// marked live. 147 void markLiveBranchesFromControlDependences(); 148 149 /// Remove instructions not marked live, return if any any instruction 150 /// was removed. 151 bool removeDeadInstructions(); 152 153 /// Identify connected sections of the control flow graph which have 154 /// dead terminators and rewrite the control flow graph to remove them. 155 void updateDeadRegions(); 156 157 /// Set the BlockInfo::PostOrder field based on a post-order 158 /// numbering of the reverse control flow graph. 159 void computeReversePostOrder(); 160 161 /// Make the terminator of this block an unconditional branch to \p Target. 162 void makeUnconditional(BasicBlock *BB, BasicBlock *Target); 163 164 public: 165 AggressiveDeadCodeElimination(Function &F, DominatorTree &DT, 166 PostDominatorTree &PDT) 167 : F(F), DT(DT), PDT(PDT) {} 168 bool performDeadCodeElimination(); 169 }; 170 } 171 172 bool AggressiveDeadCodeElimination::performDeadCodeElimination() { 173 initialize(); 174 markLiveInstructions(); 175 return removeDeadInstructions(); 176 } 177 178 static bool isUnconditionalBranch(TerminatorInst *Term) { 179 auto *BR = dyn_cast<BranchInst>(Term); 180 return BR && BR->isUnconditional(); 181 } 182 183 void AggressiveDeadCodeElimination::initialize() { 184 185 auto NumBlocks = F.size(); 186 187 // We will have an entry in the map for each block so we grow the 188 // structure to twice that size to keep the load factor low in the hash table. 189 BlockInfo.reserve(NumBlocks); 190 size_t NumInsts = 0; 191 192 // Iterate over blocks and initialize BlockInfoVec entries, count 193 // instructions to size the InstInfo hash table. 194 for (auto &BB : F) { 195 NumInsts += BB.size(); 196 auto &Info = BlockInfo[&BB]; 197 Info.BB = &BB; 198 Info.Terminator = BB.getTerminator(); 199 Info.UnconditionalBranch = isUnconditionalBranch(Info.Terminator); 200 } 201 202 // Initialize instruction map and set pointers to block info. 203 InstInfo.reserve(NumInsts); 204 for (auto &BBInfo : BlockInfo) 205 for (Instruction &I : *BBInfo.second.BB) 206 InstInfo[&I].Block = &BBInfo.second; 207 208 // Since BlockInfoVec holds pointers into InstInfo and vice-versa, we may not 209 // add any more elements to either after this point. 210 for (auto &BBInfo : BlockInfo) 211 BBInfo.second.TerminatorLiveInfo = &InstInfo[BBInfo.second.Terminator]; 212 213 // Collect the set of "root" instructions that are known live. 214 for (Instruction &I : instructions(F)) 215 if (isAlwaysLive(I)) 216 markLive(&I); 217 218 if (!RemoveControlFlowFlag) 219 return; 220 221 if (!RemoveLoops) { 222 // This stores state for the depth-first iterator. In addition 223 // to recording which nodes have been visited we also record whether 224 // a node is currently on the "stack" of active ancestors of the current 225 // node. 226 typedef DenseMap<BasicBlock *, bool> StatusMap ; 227 class DFState : public StatusMap { 228 public: 229 std::pair<StatusMap::iterator, bool> insert(BasicBlock *BB) { 230 return StatusMap::insert(std::make_pair(BB, true)); 231 } 232 233 // Invoked after we have visited all children of a node. 234 void completed(BasicBlock *BB) { (*this)[BB] = false; } 235 236 // Return true if \p BB is currently on the active stack 237 // of ancestors. 238 bool onStack(BasicBlock *BB) { 239 auto Iter = find(BB); 240 return Iter != end() && Iter->second; 241 } 242 } State; 243 244 State.reserve(F.size()); 245 // Iterate over blocks in depth-first pre-order and 246 // treat all edges to a block already seen as loop back edges 247 // and mark the branch live it if there is a back edge. 248 for (auto *BB: depth_first_ext(&F.getEntryBlock(), State)) { 249 TerminatorInst *Term = BB->getTerminator(); 250 if (isLive(Term)) 251 continue; 252 253 for (auto *Succ : successors(BB)) 254 if (State.onStack(Succ)) { 255 // back edge.... 256 markLive(Term); 257 break; 258 } 259 } 260 } 261 262 // Mark blocks live if there is no path from the block to a 263 // return of the function. 264 // We do this by seeing which of the postdomtree root children exit the 265 // program, and for all others, mark the subtree live. 266 for (auto &PDTChild : children<DomTreeNode *>(PDT.getRootNode())) { 267 auto *BB = PDTChild->getBlock(); 268 auto &Info = BlockInfo[BB]; 269 // Real function return 270 if (isa<ReturnInst>(Info.Terminator)) { 271 DEBUG(dbgs() << "post-dom root child is a return: " << BB->getName() 272 << '\n';); 273 continue; 274 } 275 276 // This child is something else, like an infinite loop. 277 for (auto DFNode : depth_first(PDTChild)) 278 markLive(BlockInfo[DFNode->getBlock()].Terminator); 279 } 280 281 // Treat the entry block as always live 282 auto *BB = &F.getEntryBlock(); 283 auto &EntryInfo = BlockInfo[BB]; 284 EntryInfo.Live = true; 285 if (EntryInfo.UnconditionalBranch) 286 markLive(EntryInfo.Terminator); 287 288 // Build initial collection of blocks with dead terminators 289 for (auto &BBInfo : BlockInfo) 290 if (!BBInfo.second.terminatorIsLive()) 291 BlocksWithDeadTerminators.insert(BBInfo.second.BB); 292 } 293 294 bool AggressiveDeadCodeElimination::isAlwaysLive(Instruction &I) { 295 // TODO -- use llvm::isInstructionTriviallyDead 296 if (I.isEHPad() || I.mayHaveSideEffects()) { 297 // Skip any value profile instrumentation calls if they are 298 // instrumenting constants. 299 if (isInstrumentsConstant(I)) 300 return false; 301 return true; 302 } 303 if (!isa<TerminatorInst>(I)) 304 return false; 305 if (RemoveControlFlowFlag && (isa<BranchInst>(I) || isa<SwitchInst>(I))) 306 return false; 307 return true; 308 } 309 310 // Check if this instruction is a runtime call for value profiling and 311 // if it's instrumenting a constant. 312 bool AggressiveDeadCodeElimination::isInstrumentsConstant(Instruction &I) { 313 // TODO -- move this test into llvm::isInstructionTriviallyDead 314 if (CallInst *CI = dyn_cast<CallInst>(&I)) 315 if (Function *Callee = CI->getCalledFunction()) 316 if (Callee->getName().equals(getInstrProfValueProfFuncName())) 317 if (isa<Constant>(CI->getArgOperand(0))) 318 return true; 319 return false; 320 } 321 322 void AggressiveDeadCodeElimination::markLiveInstructions() { 323 324 // Propagate liveness backwards to operands. 325 do { 326 // Worklist holds newly discovered live instructions 327 // where we need to mark the inputs as live. 328 while (!Worklist.empty()) { 329 Instruction *LiveInst = Worklist.pop_back_val(); 330 DEBUG(dbgs() << "work live: "; LiveInst->dump();); 331 332 for (Use &OI : LiveInst->operands()) 333 if (Instruction *Inst = dyn_cast<Instruction>(OI)) 334 markLive(Inst); 335 336 if (auto *PN = dyn_cast<PHINode>(LiveInst)) 337 markPhiLive(PN); 338 } 339 340 // After data flow liveness has been identified, examine which branch 341 // decisions are required to determine live instructions are executed. 342 markLiveBranchesFromControlDependences(); 343 344 } while (!Worklist.empty()); 345 } 346 347 void AggressiveDeadCodeElimination::markLive(Instruction *I) { 348 349 auto &Info = InstInfo[I]; 350 if (Info.Live) 351 return; 352 353 DEBUG(dbgs() << "mark live: "; I->dump()); 354 Info.Live = true; 355 Worklist.push_back(I); 356 357 // Collect the live debug info scopes attached to this instruction. 358 if (const DILocation *DL = I->getDebugLoc()) 359 collectLiveScopes(*DL); 360 361 // Mark the containing block live 362 auto &BBInfo = *Info.Block; 363 if (BBInfo.Terminator == I) { 364 BlocksWithDeadTerminators.erase(BBInfo.BB); 365 // For live terminators, mark destination blocks 366 // live to preserve this control flow edges. 367 if (!BBInfo.UnconditionalBranch) 368 for (auto *BB : successors(I->getParent())) 369 markLive(BB); 370 } 371 markLive(BBInfo); 372 } 373 374 void AggressiveDeadCodeElimination::markLive(BlockInfoType &BBInfo) { 375 if (BBInfo.Live) 376 return; 377 DEBUG(dbgs() << "mark block live: " << BBInfo.BB->getName() << '\n'); 378 BBInfo.Live = true; 379 if (!BBInfo.CFLive) { 380 BBInfo.CFLive = true; 381 NewLiveBlocks.insert(BBInfo.BB); 382 } 383 384 // Mark unconditional branches at the end of live 385 // blocks as live since there is no work to do for them later 386 if (BBInfo.UnconditionalBranch) 387 markLive(BBInfo.Terminator); 388 } 389 390 void AggressiveDeadCodeElimination::collectLiveScopes(const DILocalScope &LS) { 391 if (!AliveScopes.insert(&LS).second) 392 return; 393 394 if (isa<DISubprogram>(LS)) 395 return; 396 397 // Tail-recurse through the scope chain. 398 collectLiveScopes(cast<DILocalScope>(*LS.getScope())); 399 } 400 401 void AggressiveDeadCodeElimination::collectLiveScopes(const DILocation &DL) { 402 // Even though DILocations are not scopes, shove them into AliveScopes so we 403 // don't revisit them. 404 if (!AliveScopes.insert(&DL).second) 405 return; 406 407 // Collect live scopes from the scope chain. 408 collectLiveScopes(*DL.getScope()); 409 410 // Tail-recurse through the inlined-at chain. 411 if (const DILocation *IA = DL.getInlinedAt()) 412 collectLiveScopes(*IA); 413 } 414 415 void AggressiveDeadCodeElimination::markPhiLive(PHINode *PN) { 416 auto &Info = BlockInfo[PN->getParent()]; 417 // Only need to check this once per block. 418 if (Info.HasLivePhiNodes) 419 return; 420 Info.HasLivePhiNodes = true; 421 422 // If a predecessor block is not live, mark it as control-flow live 423 // which will trigger marking live branches upon which 424 // that block is control dependent. 425 for (auto *PredBB : predecessors(Info.BB)) { 426 auto &Info = BlockInfo[PredBB]; 427 if (!Info.CFLive) { 428 Info.CFLive = true; 429 NewLiveBlocks.insert(PredBB); 430 } 431 } 432 } 433 434 void AggressiveDeadCodeElimination::markLiveBranchesFromControlDependences() { 435 436 if (BlocksWithDeadTerminators.empty()) 437 return; 438 439 DEBUG({ 440 dbgs() << "new live blocks:\n"; 441 for (auto *BB : NewLiveBlocks) 442 dbgs() << "\t" << BB->getName() << '\n'; 443 dbgs() << "dead terminator blocks:\n"; 444 for (auto *BB : BlocksWithDeadTerminators) 445 dbgs() << "\t" << BB->getName() << '\n'; 446 }); 447 448 // The dominance frontier of a live block X in the reverse 449 // control graph is the set of blocks upon which X is control 450 // dependent. The following sequence computes the set of blocks 451 // which currently have dead terminators that are control 452 // dependence sources of a block which is in NewLiveBlocks. 453 454 SmallVector<BasicBlock *, 32> IDFBlocks; 455 ReverseIDFCalculator IDFs(PDT); 456 IDFs.setDefiningBlocks(NewLiveBlocks); 457 IDFs.setLiveInBlocks(BlocksWithDeadTerminators); 458 IDFs.calculate(IDFBlocks); 459 NewLiveBlocks.clear(); 460 461 // Dead terminators which control live blocks are now marked live. 462 for (auto *BB : IDFBlocks) { 463 DEBUG(dbgs() << "live control in: " << BB->getName() << '\n'); 464 markLive(BB->getTerminator()); 465 } 466 } 467 468 //===----------------------------------------------------------------------===// 469 // 470 // Routines to update the CFG and SSA information before removing dead code. 471 // 472 //===----------------------------------------------------------------------===// 473 bool AggressiveDeadCodeElimination::removeDeadInstructions() { 474 475 // Updates control and dataflow around dead blocks 476 updateDeadRegions(); 477 478 DEBUG({ 479 for (Instruction &I : instructions(F)) { 480 // Check if the instruction is alive. 481 if (isLive(&I)) 482 continue; 483 484 if (auto *DII = dyn_cast<DbgInfoIntrinsic>(&I)) { 485 // Check if the scope of this variable location is alive. 486 if (AliveScopes.count(DII->getDebugLoc()->getScope())) 487 continue; 488 489 // If intrinsic is pointing at a live SSA value, there may be an 490 // earlier optimization bug: if we know the location of the variable, 491 // why isn't the scope of the location alive? 492 if (Value *V = DII->getVariableLocation()) 493 if (Instruction *II = dyn_cast<Instruction>(V)) 494 if (isLive(II)) 495 dbgs() << "Dropping debug info for " << *DII << "\n"; 496 } 497 } 498 }); 499 500 // The inverse of the live set is the dead set. These are those instructions 501 // that have no side effects and do not influence the control flow or return 502 // value of the function, and may therefore be deleted safely. 503 // NOTE: We reuse the Worklist vector here for memory efficiency. 504 for (Instruction &I : instructions(F)) { 505 // Check if the instruction is alive. 506 if (isLive(&I)) 507 continue; 508 509 if (auto *DII = dyn_cast<DbgInfoIntrinsic>(&I)) { 510 // Check if the scope of this variable location is alive. 511 if (AliveScopes.count(DII->getDebugLoc()->getScope())) 512 continue; 513 514 // Fallthrough and drop the intrinsic. 515 } 516 517 // Prepare to delete. 518 Worklist.push_back(&I); 519 I.dropAllReferences(); 520 } 521 522 for (Instruction *&I : Worklist) { 523 ++NumRemoved; 524 I->eraseFromParent(); 525 } 526 527 return !Worklist.empty(); 528 } 529 530 // A dead region is the set of dead blocks with a common live post-dominator. 531 void AggressiveDeadCodeElimination::updateDeadRegions() { 532 533 DEBUG({ 534 dbgs() << "final dead terminator blocks: " << '\n'; 535 for (auto *BB : BlocksWithDeadTerminators) 536 dbgs() << '\t' << BB->getName() 537 << (BlockInfo[BB].Live ? " LIVE\n" : "\n"); 538 }); 539 540 // Don't compute the post ordering unless we needed it. 541 bool HavePostOrder = false; 542 543 for (auto *BB : BlocksWithDeadTerminators) { 544 auto &Info = BlockInfo[BB]; 545 if (Info.UnconditionalBranch) { 546 InstInfo[Info.Terminator].Live = true; 547 continue; 548 } 549 550 if (!HavePostOrder) { 551 computeReversePostOrder(); 552 HavePostOrder = true; 553 } 554 555 // Add an unconditional branch to the successor closest to the 556 // end of the function which insures a path to the exit for each 557 // live edge. 558 BlockInfoType *PreferredSucc = nullptr; 559 for (auto *Succ : successors(BB)) { 560 auto *Info = &BlockInfo[Succ]; 561 if (!PreferredSucc || PreferredSucc->PostOrder < Info->PostOrder) 562 PreferredSucc = Info; 563 } 564 assert((PreferredSucc && PreferredSucc->PostOrder > 0) && 565 "Failed to find safe successor for dead branch"); 566 567 // Collect removed successors to update the (Post)DominatorTrees. 568 SmallPtrSet<BasicBlock *, 4> RemovedSuccessors; 569 bool First = true; 570 for (auto *Succ : successors(BB)) { 571 if (!First || Succ != PreferredSucc->BB) { 572 Succ->removePredecessor(BB); 573 RemovedSuccessors.insert(Succ); 574 } else 575 First = false; 576 } 577 makeUnconditional(BB, PreferredSucc->BB); 578 579 // Inform the dominators about the deleted CFG edges. 580 SmallVector<DominatorTree::UpdateType, 4> DeletedEdges; 581 for (auto *Succ : RemovedSuccessors) { 582 // It might have happened that the same successor appeared multiple times 583 // and the CFG edge wasn't really removed. 584 if (Succ != PreferredSucc->BB) { 585 DEBUG(dbgs() << "ADCE: (Post)DomTree edge enqueued for deletion" 586 << BB->getName() << " -> " << Succ->getName() << "\n"); 587 DeletedEdges.push_back({DominatorTree::Delete, BB, Succ}); 588 } 589 } 590 591 DT.applyUpdates(DeletedEdges); 592 PDT.applyUpdates(DeletedEdges); 593 594 NumBranchesRemoved += 1; 595 } 596 } 597 598 // reverse top-sort order 599 void AggressiveDeadCodeElimination::computeReversePostOrder() { 600 601 // This provides a post-order numbering of the reverse control flow graph 602 // Note that it is incomplete in the presence of infinite loops but we don't 603 // need numbers blocks which don't reach the end of the functions since 604 // all branches in those blocks are forced live. 605 606 // For each block without successors, extend the DFS from the block 607 // backward through the graph 608 SmallPtrSet<BasicBlock*, 16> Visited; 609 unsigned PostOrder = 0; 610 for (auto &BB : F) { 611 if (succ_begin(&BB) != succ_end(&BB)) 612 continue; 613 for (BasicBlock *Block : inverse_post_order_ext(&BB,Visited)) 614 BlockInfo[Block].PostOrder = PostOrder++; 615 } 616 } 617 618 void AggressiveDeadCodeElimination::makeUnconditional(BasicBlock *BB, 619 BasicBlock *Target) { 620 TerminatorInst *PredTerm = BB->getTerminator(); 621 // Collect the live debug info scopes attached to this instruction. 622 if (const DILocation *DL = PredTerm->getDebugLoc()) 623 collectLiveScopes(*DL); 624 625 // Just mark live an existing unconditional branch 626 if (isUnconditionalBranch(PredTerm)) { 627 PredTerm->setSuccessor(0, Target); 628 InstInfo[PredTerm].Live = true; 629 return; 630 } 631 DEBUG(dbgs() << "making unconditional " << BB->getName() << '\n'); 632 NumBranchesRemoved += 1; 633 IRBuilder<> Builder(PredTerm); 634 auto *NewTerm = Builder.CreateBr(Target); 635 InstInfo[NewTerm].Live = true; 636 if (const DILocation *DL = PredTerm->getDebugLoc()) 637 NewTerm->setDebugLoc(DL); 638 639 InstInfo.erase(PredTerm); 640 PredTerm->eraseFromParent(); 641 } 642 643 //===----------------------------------------------------------------------===// 644 // 645 // Pass Manager integration code 646 // 647 //===----------------------------------------------------------------------===// 648 PreservedAnalyses ADCEPass::run(Function &F, FunctionAnalysisManager &FAM) { 649 auto &DT = FAM.getResult<DominatorTreeAnalysis>(F); 650 auto &PDT = FAM.getResult<PostDominatorTreeAnalysis>(F); 651 if (!AggressiveDeadCodeElimination(F, DT, PDT).performDeadCodeElimination()) 652 return PreservedAnalyses::all(); 653 654 PreservedAnalyses PA; 655 PA.preserveSet<CFGAnalyses>(); 656 PA.preserve<GlobalsAA>(); 657 PA.preserve<DominatorTreeAnalysis>(); 658 PA.preserve<PostDominatorTreeAnalysis>(); 659 return PA; 660 } 661 662 namespace { 663 struct ADCELegacyPass : public FunctionPass { 664 static char ID; // Pass identification, replacement for typeid 665 ADCELegacyPass() : FunctionPass(ID) { 666 initializeADCELegacyPassPass(*PassRegistry::getPassRegistry()); 667 } 668 669 bool runOnFunction(Function &F) override { 670 if (skipFunction(F)) 671 return false; 672 673 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 674 auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree(); 675 return AggressiveDeadCodeElimination(F, DT, PDT) 676 .performDeadCodeElimination(); 677 } 678 679 void getAnalysisUsage(AnalysisUsage &AU) const override { 680 // We require DominatorTree here only to update and thus preserve it. 681 AU.addRequired<DominatorTreeWrapperPass>(); 682 AU.addRequired<PostDominatorTreeWrapperPass>(); 683 if (!RemoveControlFlowFlag) 684 AU.setPreservesCFG(); 685 else { 686 AU.addPreserved<DominatorTreeWrapperPass>(); 687 AU.addPreserved<PostDominatorTreeWrapperPass>(); 688 } 689 AU.addPreserved<GlobalsAAWrapperPass>(); 690 } 691 }; 692 } 693 694 char ADCELegacyPass::ID = 0; 695 INITIALIZE_PASS_BEGIN(ADCELegacyPass, "adce", 696 "Aggressive Dead Code Elimination", false, false) 697 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 698 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) 699 INITIALIZE_PASS_END(ADCELegacyPass, "adce", "Aggressive Dead Code Elimination", 700 false, false) 701 702 FunctionPass *llvm::createAggressiveDCEPass() { return new ADCELegacyPass(); } 703