TypeFinder.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. //===- TypeFinder.cpp - Implement the TypeFinder class --------------------===//
  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 the TypeFinder class for the IR library.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/IR/TypeFinder.h"
  13. #include "llvm/ADT/SmallVector.h"
  14. #include "llvm/IR/BasicBlock.h"
  15. #include "llvm/IR/Constant.h"
  16. #include "llvm/IR/DerivedTypes.h"
  17. #include "llvm/IR/Function.h"
  18. #include "llvm/IR/Instruction.h"
  19. #include "llvm/IR/Metadata.h"
  20. #include "llvm/IR/Module.h"
  21. #include "llvm/IR/Type.h"
  22. #include "llvm/IR/Use.h"
  23. #include "llvm/IR/User.h"
  24. #include "llvm/IR/Value.h"
  25. #include "llvm/Support/Casting.h"
  26. #include <utility>
  27. using namespace llvm;
  28. void TypeFinder::run(const Module &M, bool onlyNamed) {
  29. OnlyNamed = onlyNamed;
  30. // Get types from global variables.
  31. for (const auto &G : M.globals()) {
  32. incorporateType(G.getType());
  33. if (G.hasInitializer())
  34. incorporateValue(G.getInitializer());
  35. }
  36. // Get types from aliases.
  37. for (const auto &A : M.aliases()) {
  38. incorporateType(A.getType());
  39. if (const Value *Aliasee = A.getAliasee())
  40. incorporateValue(Aliasee);
  41. }
  42. // Get types from functions.
  43. SmallVector<std::pair<unsigned, MDNode *>, 4> MDForInst;
  44. for (const Function &FI : M) {
  45. incorporateType(FI.getType());
  46. for (const Use &U : FI.operands())
  47. incorporateValue(U.get());
  48. // First incorporate the arguments.
  49. for (const auto &A : FI.args())
  50. incorporateValue(&A);
  51. for (const BasicBlock &BB : FI)
  52. for (const Instruction &I : BB) {
  53. // Incorporate the type of the instruction.
  54. incorporateType(I.getType());
  55. // Incorporate non-instruction operand types. (We are incorporating all
  56. // instructions with this loop.)
  57. for (const auto &O : I.operands())
  58. if (&*O && !isa<Instruction>(&*O))
  59. incorporateValue(&*O);
  60. // Incorporate types hiding in metadata.
  61. I.getAllMetadataOtherThanDebugLoc(MDForInst);
  62. for (const auto &MD : MDForInst)
  63. incorporateMDNode(MD.second);
  64. MDForInst.clear();
  65. }
  66. }
  67. for (const auto &NMD : M.named_metadata())
  68. for (const auto &MDOp : NMD.operands())
  69. incorporateMDNode(MDOp);
  70. }
  71. void TypeFinder::clear() {
  72. VisitedConstants.clear();
  73. VisitedTypes.clear();
  74. StructTypes.clear();
  75. }
  76. /// incorporateType - This method adds the type to the list of used structures
  77. /// if it's not in there already.
  78. void TypeFinder::incorporateType(Type *Ty) {
  79. // Check to see if we've already visited this type.
  80. if (!VisitedTypes.insert(Ty).second)
  81. return;
  82. SmallVector<Type *, 4> TypeWorklist;
  83. TypeWorklist.push_back(Ty);
  84. do {
  85. Ty = TypeWorklist.pop_back_val();
  86. // If this is a structure or opaque type, add a name for the type.
  87. if (StructType *STy = dyn_cast<StructType>(Ty))
  88. if (!OnlyNamed || STy->hasName())
  89. StructTypes.push_back(STy);
  90. // Add all unvisited subtypes to worklist for processing
  91. for (Type::subtype_reverse_iterator I = Ty->subtype_rbegin(),
  92. E = Ty->subtype_rend();
  93. I != E; ++I)
  94. if (VisitedTypes.insert(*I).second)
  95. TypeWorklist.push_back(*I);
  96. } while (!TypeWorklist.empty());
  97. }
  98. /// incorporateValue - This method is used to walk operand lists finding types
  99. /// hiding in constant expressions and other operands that won't be walked in
  100. /// other ways. GlobalValues, basic blocks, instructions, and inst operands are
  101. /// all explicitly enumerated.
  102. void TypeFinder::incorporateValue(const Value *V) {
  103. if (const auto *M = dyn_cast<MetadataAsValue>(V)) {
  104. if (const auto *N = dyn_cast<MDNode>(M->getMetadata()))
  105. return incorporateMDNode(N);
  106. if (const auto *MDV = dyn_cast<ValueAsMetadata>(M->getMetadata()))
  107. return incorporateValue(MDV->getValue());
  108. return;
  109. }
  110. if (!isa<Constant>(V) || isa<GlobalValue>(V)) return;
  111. // Already visited?
  112. if (!VisitedConstants.insert(V).second)
  113. return;
  114. // Check this type.
  115. incorporateType(V->getType());
  116. // If this is an instruction, we incorporate it separately.
  117. if (isa<Instruction>(V))
  118. return;
  119. // Look in operands for types.
  120. const User *U = cast<User>(V);
  121. for (const auto &I : U->operands())
  122. incorporateValue(&*I);
  123. }
  124. /// incorporateMDNode - This method is used to walk the operands of an MDNode to
  125. /// find types hiding within.
  126. void TypeFinder::incorporateMDNode(const MDNode *V) {
  127. // Already visited?
  128. if (!VisitedMetadata.insert(V).second)
  129. return;
  130. // Look in operands for types.
  131. for (Metadata *Op : V->operands()) {
  132. if (!Op)
  133. continue;
  134. if (auto *N = dyn_cast<MDNode>(Op)) {
  135. incorporateMDNode(N);
  136. continue;
  137. }
  138. if (auto *C = dyn_cast<ConstantAsMetadata>(Op)) {
  139. incorporateValue(C->getValue());
  140. continue;
  141. }
  142. }
  143. }