ObjCARCAPElim.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. //===- ObjCARCAPElim.cpp - ObjC ARC Optimization --------------------------===//
  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. /// \file
  9. ///
  10. /// This file defines ObjC ARC optimizations. ARC stands for Automatic
  11. /// Reference Counting and is a system for managing reference counts for objects
  12. /// in Objective C.
  13. ///
  14. /// This specific file implements optimizations which remove extraneous
  15. /// autorelease pools.
  16. ///
  17. /// WARNING: This file knows about certain library functions. It recognizes them
  18. /// by name, and hardwires knowledge of their semantics.
  19. ///
  20. /// WARNING: This file knows about how certain Objective-C library functions are
  21. /// used. Naive LLVM IR transformations which would otherwise be
  22. /// behavior-preserving may break these assumptions.
  23. ///
  24. //===----------------------------------------------------------------------===//
  25. #include "llvm/ADT/STLExtras.h"
  26. #include "llvm/Analysis/ObjCARCAnalysisUtils.h"
  27. #include "llvm/Analysis/ObjCARCInstKind.h"
  28. #include "llvm/IR/Constants.h"
  29. #include "llvm/IR/InstrTypes.h"
  30. #include "llvm/IR/PassManager.h"
  31. #include "llvm/Support/Debug.h"
  32. #include "llvm/Support/raw_ostream.h"
  33. #include "llvm/Transforms/ObjCARC.h"
  34. using namespace llvm;
  35. using namespace llvm::objcarc;
  36. #define DEBUG_TYPE "objc-arc-ap-elim"
  37. namespace {
  38. /// Interprocedurally determine if calls made by the given call site can
  39. /// possibly produce autoreleases.
  40. bool MayAutorelease(const CallBase &CB, unsigned Depth = 0) {
  41. if (const Function *Callee = CB.getCalledFunction()) {
  42. if (!Callee->hasExactDefinition())
  43. return true;
  44. for (const BasicBlock &BB : *Callee) {
  45. for (const Instruction &I : BB)
  46. if (const CallBase *JCB = dyn_cast<CallBase>(&I))
  47. // This recursion depth limit is arbitrary. It's just great
  48. // enough to cover known interesting testcases.
  49. if (Depth < 3 && !JCB->onlyReadsMemory() &&
  50. MayAutorelease(*JCB, Depth + 1))
  51. return true;
  52. }
  53. return false;
  54. }
  55. return true;
  56. }
  57. bool OptimizeBB(BasicBlock *BB) {
  58. bool Changed = false;
  59. Instruction *Push = nullptr;
  60. for (Instruction &Inst : llvm::make_early_inc_range(*BB)) {
  61. switch (GetBasicARCInstKind(&Inst)) {
  62. case ARCInstKind::AutoreleasepoolPush:
  63. Push = &Inst;
  64. break;
  65. case ARCInstKind::AutoreleasepoolPop:
  66. // If this pop matches a push and nothing in between can autorelease,
  67. // zap the pair.
  68. if (Push && cast<CallInst>(&Inst)->getArgOperand(0) == Push) {
  69. Changed = true;
  70. LLVM_DEBUG(dbgs() << "ObjCARCAPElim::OptimizeBB: Zapping push pop "
  71. "autorelease pair:\n"
  72. " Pop: "
  73. << Inst << "\n"
  74. << " Push: " << *Push
  75. << "\n");
  76. Inst.eraseFromParent();
  77. Push->eraseFromParent();
  78. }
  79. Push = nullptr;
  80. break;
  81. case ARCInstKind::CallOrUser:
  82. if (MayAutorelease(cast<CallBase>(Inst)))
  83. Push = nullptr;
  84. break;
  85. default:
  86. break;
  87. }
  88. }
  89. return Changed;
  90. }
  91. bool runImpl(Module &M) {
  92. if (!EnableARCOpts)
  93. return false;
  94. // If nothing in the Module uses ARC, don't do anything.
  95. if (!ModuleHasARC(M))
  96. return false;
  97. // Find the llvm.global_ctors variable, as the first step in
  98. // identifying the global constructors. In theory, unnecessary autorelease
  99. // pools could occur anywhere, but in practice it's pretty rare. Global
  100. // ctors are a place where autorelease pools get inserted automatically,
  101. // so it's pretty common for them to be unnecessary, and it's pretty
  102. // profitable to eliminate them.
  103. GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors");
  104. if (!GV)
  105. return false;
  106. assert(GV->hasDefinitiveInitializer() &&
  107. "llvm.global_ctors is uncooperative!");
  108. bool Changed = false;
  109. // Dig the constructor functions out of GV's initializer.
  110. ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
  111. for (User::op_iterator OI = Init->op_begin(), OE = Init->op_end();
  112. OI != OE; ++OI) {
  113. Value *Op = *OI;
  114. // llvm.global_ctors is an array of three-field structs where the second
  115. // members are constructor functions.
  116. Function *F = dyn_cast<Function>(cast<ConstantStruct>(Op)->getOperand(1));
  117. // If the user used a constructor function with the wrong signature and
  118. // it got bitcasted or whatever, look the other way.
  119. if (!F)
  120. continue;
  121. // Only look at function definitions.
  122. if (F->isDeclaration())
  123. continue;
  124. // Only look at functions with one basic block.
  125. if (std::next(F->begin()) != F->end())
  126. continue;
  127. // Ok, a single-block constructor function definition. Try to optimize it.
  128. Changed |= OptimizeBB(&F->front());
  129. }
  130. return Changed;
  131. }
  132. } // namespace
  133. PreservedAnalyses ObjCARCAPElimPass::run(Module &M, ModuleAnalysisManager &AM) {
  134. if (!runImpl(M))
  135. return PreservedAnalyses::all();
  136. PreservedAnalyses PA;
  137. PA.preserveSet<CFGAnalyses>();
  138. return PA;
  139. }