CtorUtils.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //===- CtorUtils.cpp - Helpers for working with global_ctors ----*- C++ -*-===//
  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 defines functions that are used to process llvm.global_ctors.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Transforms/Utils/CtorUtils.h"
  13. #include "llvm/ADT/BitVector.h"
  14. #include "llvm/IR/Constants.h"
  15. #include "llvm/IR/Function.h"
  16. #include "llvm/IR/GlobalVariable.h"
  17. #include "llvm/IR/Module.h"
  18. #include "llvm/Support/Debug.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. #include <numeric>
  21. #define DEBUG_TYPE "ctor_utils"
  22. using namespace llvm;
  23. /// Given a specified llvm.global_ctors list, remove the listed elements.
  24. static void removeGlobalCtors(GlobalVariable *GCL, const BitVector &CtorsToRemove) {
  25. // Filter out the initializer elements to remove.
  26. ConstantArray *OldCA = cast<ConstantArray>(GCL->getInitializer());
  27. SmallVector<Constant *, 10> CAList;
  28. for (unsigned I = 0, E = OldCA->getNumOperands(); I < E; ++I)
  29. if (!CtorsToRemove.test(I))
  30. CAList.push_back(OldCA->getOperand(I));
  31. // Create the new array initializer.
  32. ArrayType *ATy =
  33. ArrayType::get(OldCA->getType()->getElementType(), CAList.size());
  34. Constant *CA = ConstantArray::get(ATy, CAList);
  35. // If we didn't change the number of elements, don't create a new GV.
  36. if (CA->getType() == OldCA->getType()) {
  37. GCL->setInitializer(CA);
  38. return;
  39. }
  40. // Create the new global and insert it next to the existing list.
  41. GlobalVariable *NGV =
  42. new GlobalVariable(CA->getType(), GCL->isConstant(), GCL->getLinkage(),
  43. CA, "", GCL->getThreadLocalMode());
  44. GCL->getParent()->getGlobalList().insert(GCL->getIterator(), NGV);
  45. NGV->takeName(GCL);
  46. // Nuke the old list, replacing any uses with the new one.
  47. if (!GCL->use_empty()) {
  48. Constant *V = NGV;
  49. if (V->getType() != GCL->getType())
  50. V = ConstantExpr::getBitCast(V, GCL->getType());
  51. GCL->replaceAllUsesWith(V);
  52. }
  53. GCL->eraseFromParent();
  54. }
  55. /// Given a llvm.global_ctors list that we can understand,
  56. /// return a list of the functions and null terminator as a vector.
  57. static std::vector<std::pair<uint32_t, Function *>>
  58. parseGlobalCtors(GlobalVariable *GV) {
  59. ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
  60. std::vector<std::pair<uint32_t, Function *>> Result;
  61. Result.reserve(CA->getNumOperands());
  62. for (auto &V : CA->operands()) {
  63. ConstantStruct *CS = cast<ConstantStruct>(V);
  64. Result.emplace_back(cast<ConstantInt>(CS->getOperand(0))->getZExtValue(),
  65. dyn_cast<Function>(CS->getOperand(1)));
  66. }
  67. return Result;
  68. }
  69. /// Find the llvm.global_ctors list.
  70. static GlobalVariable *findGlobalCtors(Module &M) {
  71. GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors");
  72. if (!GV)
  73. return nullptr;
  74. // Verify that the initializer is simple enough for us to handle. We are
  75. // only allowed to optimize the initializer if it is unique.
  76. if (!GV->hasUniqueInitializer())
  77. return nullptr;
  78. // If there are no ctors, then the initializer might be null/undef/poison.
  79. // Ignore anything but an array.
  80. ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer());
  81. if (!CA)
  82. return nullptr;
  83. for (auto &V : CA->operands()) {
  84. if (isa<ConstantAggregateZero>(V))
  85. continue;
  86. ConstantStruct *CS = cast<ConstantStruct>(V);
  87. if (isa<ConstantPointerNull>(CS->getOperand(1)))
  88. continue;
  89. // Can only handle global constructors with no arguments.
  90. Function *F = dyn_cast<Function>(CS->getOperand(1));
  91. if (!F || F->arg_size() != 0)
  92. return nullptr;
  93. }
  94. return GV;
  95. }
  96. /// Call "ShouldRemove" for every entry in M's global_ctor list and remove the
  97. /// entries for which it returns true. Return true if anything changed.
  98. bool llvm::optimizeGlobalCtorsList(
  99. Module &M, function_ref<bool(uint32_t, Function *)> ShouldRemove) {
  100. GlobalVariable *GlobalCtors = findGlobalCtors(M);
  101. if (!GlobalCtors)
  102. return false;
  103. std::vector<std::pair<uint32_t, Function *>> Ctors =
  104. parseGlobalCtors(GlobalCtors);
  105. if (Ctors.empty())
  106. return false;
  107. bool MadeChange = false;
  108. // Loop over global ctors, optimizing them when we can.
  109. BitVector CtorsToRemove(Ctors.size());
  110. std::vector<size_t> CtorsByPriority(Ctors.size());
  111. std::iota(CtorsByPriority.begin(), CtorsByPriority.end(), 0);
  112. stable_sort(CtorsByPriority, [&](size_t LHS, size_t RHS) {
  113. return Ctors[LHS].first < Ctors[RHS].first;
  114. });
  115. for (unsigned CtorIndex : CtorsByPriority) {
  116. const uint32_t Priority = Ctors[CtorIndex].first;
  117. Function *F = Ctors[CtorIndex].second;
  118. if (!F)
  119. continue;
  120. LLVM_DEBUG(dbgs() << "Optimizing Global Constructor: " << *F << "\n");
  121. // If we can evaluate the ctor at compile time, do.
  122. if (ShouldRemove(Priority, F)) {
  123. Ctors[CtorIndex].second = nullptr;
  124. CtorsToRemove.set(CtorIndex);
  125. MadeChange = true;
  126. continue;
  127. }
  128. }
  129. if (!MadeChange)
  130. return false;
  131. removeGlobalCtors(GlobalCtors, CtorsToRemove);
  132. return true;
  133. }