LLVM 19.0.0git
TypeFinder.cpp
Go to the documentation of this file.
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
13#include "llvm/IR/TypeFinder.h"
15#include "llvm/IR/BasicBlock.h"
16#include "llvm/IR/Constant.h"
19#include "llvm/IR/Function.h"
20#include "llvm/IR/Instruction.h"
22#include "llvm/IR/Metadata.h"
23#include "llvm/IR/Module.h"
24#include "llvm/IR/Operator.h"
25#include "llvm/IR/Type.h"
26#include "llvm/IR/Use.h"
27#include "llvm/IR/User.h"
28#include "llvm/IR/Value.h"
30#include <utility>
31
32using namespace llvm;
33
34void TypeFinder::run(const Module &M, bool onlyNamed) {
35 OnlyNamed = onlyNamed;
36
37 // Get types from global variables.
38 for (const auto &G : M.globals()) {
39 incorporateType(G.getValueType());
40 if (G.hasInitializer())
41 incorporateValue(G.getInitializer());
42 }
43
44 // Get types from aliases.
45 for (const auto &A : M.aliases()) {
46 incorporateType(A.getValueType());
47 if (const Value *Aliasee = A.getAliasee())
48 incorporateValue(Aliasee);
49 }
50
51 // Get types from ifuncs.
52 for (const auto &GI : M.ifuncs())
53 incorporateType(GI.getValueType());
54
55 // Get types from functions.
57 for (const Function &FI : M) {
58 incorporateType(FI.getFunctionType());
59 incorporateAttributes(FI.getAttributes());
60
61 for (const Use &U : FI.operands())
62 incorporateValue(U.get());
63
64 // First incorporate the arguments.
65 for (const auto &A : FI.args())
66 incorporateValue(&A);
67
68 for (const BasicBlock &BB : FI)
69 for (const Instruction &I : BB) {
70 // Incorporate the type of the instruction.
71 incorporateType(I.getType());
72
73 // Incorporate non-instruction operand types. (We are incorporating all
74 // instructions with this loop.)
75 for (const auto &O : I.operands())
76 if (&*O && !isa<Instruction>(&*O))
77 incorporateValue(&*O);
78
79 if (auto *GEP = dyn_cast<GetElementPtrInst>(&I))
80 incorporateType(GEP->getSourceElementType());
81 if (auto *AI = dyn_cast<AllocaInst>(&I))
82 incorporateType(AI->getAllocatedType());
83 if (const auto *CB = dyn_cast<CallBase>(&I))
84 incorporateAttributes(CB->getAttributes());
85
86 // Incorporate types hiding in metadata.
87 I.getAllMetadataOtherThanDebugLoc(MDForInst);
88 for (const auto &MD : MDForInst)
89 incorporateMDNode(MD.second);
90 MDForInst.clear();
91 }
92 }
93
94 for (const auto &NMD : M.named_metadata())
95 for (const auto *MDOp : NMD.operands())
96 incorporateMDNode(MDOp);
97}
98
100 VisitedConstants.clear();
101 VisitedTypes.clear();
102 StructTypes.clear();
103}
104
105/// incorporateType - This method adds the type to the list of used structures
106/// if it's not in there already.
107void TypeFinder::incorporateType(Type *Ty) {
108 // Check to see if we've already visited this type.
109 if (!VisitedTypes.insert(Ty).second)
110 return;
111
112 SmallVector<Type *, 4> TypeWorklist;
113 TypeWorklist.push_back(Ty);
114 do {
115 Ty = TypeWorklist.pop_back_val();
116
117 // If this is a structure or opaque type, add a name for the type.
118 if (StructType *STy = dyn_cast<StructType>(Ty))
119 if (!OnlyNamed || STy->hasName())
120 StructTypes.push_back(STy);
121
122 // Add all unvisited subtypes to worklist for processing
123 for (Type *SubTy : llvm::reverse(Ty->subtypes()))
124 if (VisitedTypes.insert(SubTy).second)
125 TypeWorklist.push_back(SubTy);
126 } while (!TypeWorklist.empty());
127}
128
129/// incorporateValue - This method is used to walk operand lists finding types
130/// hiding in constant expressions and other operands that won't be walked in
131/// other ways. GlobalValues, basic blocks, instructions, and inst operands are
132/// all explicitly enumerated.
133void TypeFinder::incorporateValue(const Value *V) {
134 if (const auto *M = dyn_cast<MetadataAsValue>(V)) {
135 if (const auto *N = dyn_cast<MDNode>(M->getMetadata()))
136 return incorporateMDNode(N);
137 if (const auto *MDV = dyn_cast<ValueAsMetadata>(M->getMetadata()))
138 return incorporateValue(MDV->getValue());
139 if (const auto *AL = dyn_cast<DIArgList>(M->getMetadata())) {
140 for (auto *Arg : AL->getArgs())
141 incorporateValue(Arg->getValue());
142 return;
143 }
144 return;
145 }
146
147 if (!isa<Constant>(V) || isa<GlobalValue>(V)) return;
148
149 // Already visited?
150 if (!VisitedConstants.insert(V).second)
151 return;
152
153 // Check this type.
154 incorporateType(V->getType());
155
156 // If this is an instruction, we incorporate it separately.
157 if (isa<Instruction>(V))
158 return;
159
160 if (auto *GEP = dyn_cast<GEPOperator>(V))
161 incorporateType(GEP->getSourceElementType());
162
163 // Look in operands for types.
164 const User *U = cast<User>(V);
165 for (const auto &I : U->operands())
166 incorporateValue(&*I);
167}
168
169/// incorporateMDNode - This method is used to walk the operands of an MDNode to
170/// find types hiding within.
171void TypeFinder::incorporateMDNode(const MDNode *V) {
172 // Already visited?
173 if (!VisitedMetadata.insert(V).second)
174 return;
175
176 // Look in operands for types.
177 for (Metadata *Op : V->operands()) {
178 if (!Op)
179 continue;
180 if (auto *N = dyn_cast<MDNode>(Op)) {
181 incorporateMDNode(N);
182 continue;
183 }
184 if (auto *C = dyn_cast<ConstantAsMetadata>(Op)) {
185 incorporateValue(C->getValue());
186 continue;
187 }
188 }
189}
190
191void TypeFinder::incorporateAttributes(AttributeList AL) {
192 if (!VisitedAttributes.insert(AL).second)
193 return;
194
195 for (AttributeSet AS : AL)
196 for (Attribute A : AS)
197 if (A.isTypeAttribute())
198 incorporateType(A.getValueAsType());
199}
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Hexagon Common GEP
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
This file contains the declarations for metadata subclasses.
Module.h This file contains the declarations for the Module class.
This file defines the SmallVector class.
This defines the Use class.
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
This class represents an Operation in the Expression.
Metadata node.
Definition: Metadata.h:1067
Root of the metadata hierarchy.
Definition: Metadata.h:62
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
bool empty() const
Definition: SmallVector.h:94
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
Class to represent struct types.
Definition: DerivedTypes.h:216
void run(const Module &M, bool onlyNamed)
Definition: TypeFinder.cpp:34
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
ArrayRef< Type * > subtypes() const
Definition: Type.h:361
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
LLVM Value Representation.
Definition: Value.h:74
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
#define N