ReduceBasicBlocks.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //===- ReduceArguments.cpp - Specialized Delta Pass -----------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements a function which calls the Generic Delta pass in order
  10. // to reduce uninteresting Arguments from defined functions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "ReduceBasicBlocks.h"
  14. #include "llvm/ADT/DenseSet.h"
  15. #include "llvm/IR/BasicBlock.h"
  16. #include "llvm/IR/Instruction.h"
  17. #include "llvm/IR/Instructions.h"
  18. #include "llvm/IR/LLVMContext.h"
  19. #include "llvm/IR/Value.h"
  20. #include "llvm/Support/Casting.h"
  21. #include "llvm/Support/raw_ostream.h"
  22. #include <vector>
  23. using namespace llvm;
  24. /// Replaces BB Terminator with one that only contains Chunk BBs
  25. static void replaceBranchTerminator(BasicBlock &BB,
  26. const DenseSet<BasicBlock *> &BBsToKeep) {
  27. auto *Term = BB.getTerminator();
  28. std::vector<BasicBlock *> ChunkSucessors;
  29. for (auto *Succ : successors(&BB))
  30. if (BBsToKeep.count(Succ))
  31. ChunkSucessors.push_back(Succ);
  32. // BB only references Chunk BBs
  33. if (ChunkSucessors.size() == Term->getNumSuccessors())
  34. return;
  35. bool IsBranch = isa<BranchInst>(Term) || isa<InvokeInst>(Term);
  36. Value *Address = nullptr;
  37. if (auto *IndBI = dyn_cast<IndirectBrInst>(Term))
  38. Address = IndBI->getAddress();
  39. Term->replaceAllUsesWith(UndefValue::get(Term->getType()));
  40. Term->eraseFromParent();
  41. if (ChunkSucessors.empty()) {
  42. auto *FnRetTy = BB.getParent()->getReturnType();
  43. ReturnInst::Create(BB.getContext(),
  44. FnRetTy->isVoidTy() ? nullptr : UndefValue::get(FnRetTy),
  45. &BB);
  46. return;
  47. }
  48. if (IsBranch)
  49. BranchInst::Create(ChunkSucessors[0], &BB);
  50. if (Address) {
  51. auto *NewIndBI =
  52. IndirectBrInst::Create(Address, ChunkSucessors.size(), &BB);
  53. for (auto *Dest : ChunkSucessors)
  54. NewIndBI->addDestination(Dest);
  55. }
  56. }
  57. /// Removes uninteresting BBs from switch, if the default case ends up being
  58. /// uninteresting, the switch is replaced with a void return (since it has to be
  59. /// replace with something)
  60. static void
  61. removeUninterestingBBsFromSwitch(SwitchInst &SwInst,
  62. const DenseSet<BasicBlock *> &BBsToKeep) {
  63. if (!BBsToKeep.count(SwInst.getDefaultDest())) {
  64. auto *FnRetTy = SwInst.getParent()->getParent()->getReturnType();
  65. ReturnInst::Create(SwInst.getContext(),
  66. FnRetTy->isVoidTy() ? nullptr : UndefValue::get(FnRetTy),
  67. SwInst.getParent());
  68. SwInst.eraseFromParent();
  69. } else
  70. for (int I = 0, E = SwInst.getNumCases(); I != E; ++I) {
  71. auto Case = SwInst.case_begin() + I;
  72. if (!BBsToKeep.count(Case->getCaseSuccessor())) {
  73. SwInst.removeCase(Case);
  74. --I;
  75. --E;
  76. }
  77. }
  78. }
  79. /// Removes out-of-chunk arguments from functions, and modifies their calls
  80. /// accordingly. It also removes allocations of out-of-chunk arguments.
  81. static void extractBasicBlocksFromModule(Oracle &O, Module &Program) {
  82. DenseSet<BasicBlock *> BBsToKeep;
  83. SmallVector<BasicBlock *> BBsToDelete;
  84. for (auto &F : Program) {
  85. for (auto &BB : F) {
  86. if (O.shouldKeep())
  87. BBsToKeep.insert(&BB);
  88. else {
  89. BBsToDelete.push_back(&BB);
  90. // Remove out-of-chunk BB from successor phi nodes
  91. for (auto *Succ : successors(&BB))
  92. Succ->removePredecessor(&BB);
  93. }
  94. }
  95. }
  96. // Replace terminators that reference out-of-chunk BBs
  97. for (auto &F : Program)
  98. for (auto &BB : F) {
  99. if (auto *SwInst = dyn_cast<SwitchInst>(BB.getTerminator()))
  100. removeUninterestingBBsFromSwitch(*SwInst, BBsToKeep);
  101. else
  102. replaceBranchTerminator(BB, BBsToKeep);
  103. }
  104. // Replace out-of-chunk switch uses
  105. for (auto &BB : BBsToDelete) {
  106. // Instructions might be referenced in other BBs
  107. for (auto &I : *BB)
  108. I.replaceAllUsesWith(UndefValue::get(I.getType()));
  109. if (BB->getParent()->size() == 1) {
  110. // this is the last basic block of the function, thus we must also make
  111. // sure to remove comdat and set linkage to external
  112. auto F = BB->getParent();
  113. F->deleteBody();
  114. F->setComdat(nullptr);
  115. } else {
  116. BB->eraseFromParent();
  117. }
  118. }
  119. }
  120. void llvm::reduceBasicBlocksDeltaPass(TestRunner &Test) {
  121. outs() << "*** Reducing Basic Blocks...\n";
  122. runDeltaPass(Test, extractBasicBlocksFromModule);
  123. }