Enzyme main
Loading...
Searching...
No Matches
TBAA.h
Go to the documentation of this file.
1//===- TBAA.h - Helpers for llvm::Type-based alias analysis ------------===//
2//
3// Enzyme Project and The LLVM Project
4// First section modified from: TypeBasedAliasAnalysis.cpp in LLVM
5//
6// Part of the Enzyme Project, under the Apache License v2.0 with LLVM
7// Exceptions. See https://llvm.org/LICENSE.txt for license information.
8// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9//
10// If using this code in an academic setting, please cite the following:
11// @incollection{enzymeNeurips,
12// title = {Instead of Rewriting Foreign Code for Machine Learning,
13// Automatically Synthesize Fast Gradients},
14// author = {Moses, William S. and Churavy, Valentin},
15// booktitle = {Advances in Neural Information Processing Systems 33},
16// year = {2020},
17// note = {To appear in},
18// }
19//
20//===----------------------------------------------------------------------===//
21//
22// This file contains the implementation of several utilities for understanding
23// TBAA metadata and converting that metadata into corresponding TypeAnalysis
24// representations.
25//
26//===----------------------------------------------------------------------===//
27#ifndef ENZYME_TYPE_ANALYSIS_TBAA_H
28#define ENZYME_TYPE_ANALYSIS_TBAA_H 1
29
30#include "BaseType.h"
31#include "ConcreteType.h"
32#include "TypeTree.h"
33
34/// isNewFormatTypeNode - Return true iff the given type node is in the new
35/// size-aware format.
36static bool isNewFormatTypeNode(const llvm::MDNode *N) {
37 if (N->getNumOperands() < 3)
38 return false;
39 // In the old format the first operand is a string.
40 if (!llvm::isa<llvm::MDNode>(N->getOperand(0)))
41 return false;
42 return true;
43}
44
45/// This is a simple wrapper around an llvm::MDNode which provides a
46/// higher-level interface by hiding the details of how alias analysis
47/// information is encoded in its operands.
48template <typename MDNodeTy> class TBAANodeImpl {
49 MDNodeTy *Node = nullptr;
50
51public:
52 TBAANodeImpl() = default;
53 explicit TBAANodeImpl(MDNodeTy *N) : Node(N) {}
54
55 /// getNode - Get the llvm::MDNode for this TBAANode.
56 MDNodeTy *getNode() const { return Node; }
57
58 /// isNewFormat - Return true iff the wrapped type node is in the new
59 /// size-aware format.
60 bool isNewFormat() const { return isNewFormatTypeNode(Node); }
61
62 /// getParent - Get this TBAANode's Alias tree parent.
64 if (isNewFormat())
65 return TBAANodeImpl(llvm::cast<MDNodeTy>(Node->getOperand(0)));
66
67 if (Node->getNumOperands() < 2)
69 MDNodeTy *P = llvm::dyn_cast_or_null<MDNodeTy>(Node->getOperand(1));
70 if (!P)
72 // Ok, this node has a valid parent. Return it.
73 return TBAANodeImpl<MDNodeTy>(P);
74 }
75
76 /// Test if this TBAANode represents a type for objects which are
77 /// not modified (by any means) in the context where this
78 /// AliasAnalysis is relevant.
79 bool isTypeImmutable() const {
80 if (Node->getNumOperands() < 3)
81 return false;
82 llvm::ConstantInt *CI =
83 llvm::mdconst::dyn_extract<llvm::ConstantInt>(Node->getOperand(2));
84 if (!CI)
85 return false;
86 return CI->getValue()[0];
87 }
88};
89
90/// \name Specializations of \c TBAANodeImpl for const and non const qualified
91/// \c MDNode.
92/// @{
95/// @}
96
97/// This is a simple wrapper around an llvm::MDNode which provides a
98/// higher-level interface by hiding the details of how alias analysis
99/// information is encoded in its operands.
100template <typename MDNodeTy> class TBAAStructTagNodeImpl {
101 /// This node should be created with createTBAAAccessTag().
102 MDNodeTy *Node;
103
104public:
105 explicit TBAAStructTagNodeImpl(MDNodeTy *N) : Node(N) {}
106
107 /// Get the llvm::MDNode for this TBAAStructTagNode.
108 MDNodeTy *getNode() const { return Node; }
109
110 /// isNewFormat - Return true iff the wrapped access tag is in the new
111 /// size-aware format.
112 bool isNewFormat() const {
113 if (Node->getNumOperands() < 4)
114 return false;
115 if (MDNodeTy *AccessType = getAccessType())
116 if (!TBAANodeImpl<MDNodeTy>(AccessType).isNewFormat())
117 return false;
118 return true;
119 }
120
121 MDNodeTy *getBaseType() const {
122 return llvm::dyn_cast_or_null<llvm::MDNode>(Node->getOperand(0));
123 }
124
125 MDNodeTy *getAccessType() const {
126 return llvm::dyn_cast_or_null<llvm::MDNode>(Node->getOperand(1));
127 }
128
129 uint64_t getOffset() const {
130 return llvm::mdconst::extract<llvm::ConstantInt>(Node->getOperand(2))
131 ->getZExtValue();
132 }
133
134 uint64_t getSize() const {
135 if (!isNewFormat())
136 return UINT64_MAX;
137 return llvm::mdconst::extract<llvm::ConstantInt>(Node->getOperand(3))
138 ->getZExtValue();
139 }
140
141 /// Test if this TBAAStructTagNode represents a type for objects
142 /// which are not modified (by any means) in the context where this
143 /// AliasAnalysis is relevant.
144 bool isTypeImmutable() const {
145 unsigned OpNo = isNewFormat() ? 4 : 3;
146 if (Node->getNumOperands() < OpNo + 1)
147 return false;
148 llvm::ConstantInt *CI =
149 llvm::mdconst::dyn_extract<llvm::ConstantInt>(Node->getOperand(OpNo));
150 if (!CI)
151 return false;
152 return CI->getValue()[0];
153 }
154};
155
156/// \name Specializations of \c TBAAStructTagNodeImpl for const and non const
157/// qualified \c MDNods.
158/// @{
161/// @}
162
163/// This is a simple wrapper around an llvm::MDNode which provides a
164/// higher-level interface by hiding the details of how alias analysis
165/// information is encoded in its operands.
167 /// This node should be created with createTBAATypeNode().
168 const llvm::MDNode *Node = nullptr;
169
170public:
172 explicit TBAAStructTypeNode(const llvm::MDNode *N) : Node(N) {}
173
174 /// Get the llvm::MDNode for this TBAAStructTypeNode.
175 const llvm::MDNode *getNode() const { return Node; }
176
177 /// isNewFormat - Return true iff the wrapped type node is in the new
178 /// size-aware format.
179 bool isNewFormat() const { return isNewFormatTypeNode(Node); }
180
181 bool operator==(const TBAAStructTypeNode &Other) const {
182 return getNode() == Other.getNode();
183 }
184
185 /// getId - Return type identifier.
186 llvm::Metadata *getId() const {
187 return Node->getOperand(isNewFormat() ? 2 : 0);
188 }
189
190 unsigned getNumFields() const {
191 unsigned FirstFieldOpNo = isNewFormat() ? 3 : 1;
192 unsigned NumOpsPerField = isNewFormat() ? 3 : 2;
193 return (getNode()->getNumOperands() - FirstFieldOpNo) / NumOpsPerField;
194 }
195
196 uint64_t getFieldOffset(unsigned FieldIndex) const {
197 unsigned FirstFieldOpNo = isNewFormat() ? 3 : 1;
198 unsigned NumOpsPerField = isNewFormat() ? 3 : 2;
199 unsigned OpIndex = FirstFieldOpNo + FieldIndex * NumOpsPerField;
200
201 uint64_t Cur =
202 llvm::mdconst::extract<llvm::ConstantInt>(Node->getOperand(OpIndex + 1))
203 ->getZExtValue();
204 return Cur;
205 }
206
207 TBAAStructTypeNode getFieldType(unsigned FieldIndex) const {
208 unsigned FirstFieldOpNo = isNewFormat() ? 3 : 1;
209 unsigned NumOpsPerField = isNewFormat() ? 3 : 2;
210 unsigned OpIndex = FirstFieldOpNo + FieldIndex * NumOpsPerField;
211 auto *TypeNode = llvm::cast<llvm::MDNode>(getNode()->getOperand(OpIndex));
212 return TBAAStructTypeNode(TypeNode);
213 }
214
215 /// Get this TBAAStructTypeNode's field in the type DAG with
216 /// given offset. Update the offset to be relative to the field type.
217 TBAAStructTypeNode getField(uint64_t &Offset) const {
218 bool NewFormat = isNewFormat();
219 if (NewFormat) {
220 // New-format root and scalar type nodes have no fields.
221 if (Node->getNumOperands() < 6)
222 return TBAAStructTypeNode();
223 } else {
224 // Parent can be omitted for the root node.
225 if (Node->getNumOperands() < 2)
226 return TBAAStructTypeNode();
227
228 // Fast path for a scalar type node and a struct type node with a single
229 // field.
230 if (Node->getNumOperands() <= 3) {
231 uint64_t Cur =
232 Node->getNumOperands() == 2
233 ? 0
234 : llvm::mdconst::extract<llvm::ConstantInt>(Node->getOperand(2))
235 ->getZExtValue();
236 Offset -= Cur;
237 llvm::MDNode *P =
238 llvm::dyn_cast_or_null<llvm::MDNode>(Node->getOperand(1));
239 if (!P)
240 return TBAAStructTypeNode();
241 return TBAAStructTypeNode(P);
242 }
243 }
244
245 // Assume the offsets are in order. We return the previous field if
246 // the current offset is bigger than the given offset.
247 unsigned FirstFieldOpNo = NewFormat ? 3 : 1;
248 unsigned NumOpsPerField = NewFormat ? 3 : 2;
249 unsigned TheIdx = 0;
250 for (unsigned Idx = FirstFieldOpNo; Idx < Node->getNumOperands();
251 Idx += NumOpsPerField) {
252 uint64_t Cur =
253 llvm::mdconst::extract<llvm::ConstantInt>(Node->getOperand(Idx + 1))
254 ->getZExtValue();
255 if (Cur > Offset) {
256 assert(Idx >= FirstFieldOpNo + NumOpsPerField &&
257 "TBAAStructTypeNode::getField should have an offset match!");
258 TheIdx = Idx - NumOpsPerField;
259 break;
260 }
261 }
262 // Move along the last field.
263 if (TheIdx == 0)
264 TheIdx = Node->getNumOperands() - NumOpsPerField;
265 uint64_t Cur =
266 llvm::mdconst::extract<llvm::ConstantInt>(Node->getOperand(TheIdx + 1))
267 ->getZExtValue();
268 Offset -= Cur;
269 llvm::MDNode *P =
270 llvm::dyn_cast_or_null<llvm::MDNode>(Node->getOperand(TheIdx));
271 if (!P)
272 return TBAAStructTypeNode();
273 return TBAAStructTypeNode(P);
274 }
275};
276
277/// Check the first operand of the tbaa tag node, if it is a llvm::MDNode, we
278/// treat it as struct-path aware TBAA format, otherwise, we treat it as scalar
279/// TBAA format.
280static inline bool isStructPathTBAA(const llvm::MDNode *MD) {
281 // Anonymous TBAA root starts with a llvm::MDNode and dragonegg uses it as
282 // a TBAA tag.
283 return llvm::isa<llvm::MDNode>(MD->getOperand(0)) &&
284 MD->getNumOperands() >= 3;
285}
286
287static inline const llvm::MDNode *
288createAccessTag(const llvm::MDNode *AccessType) {
289 // If there is no access type or the access type is the root node, then
290 // we don't have any useful access tag to return.
291 if (!AccessType || AccessType->getNumOperands() < 2)
292 return nullptr;
293
294 llvm::Type *Int64 = llvm::IntegerType::get(AccessType->getContext(), 64);
295 auto *OffsetNode =
296 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int64, 0));
297
298 if (TBAAStructTypeNode(AccessType).isNewFormat()) {
299 // TODO: Take access ranges into account when matching access tags and
300 // fix this code to generate actual access sizes for generic tags.
301 uint64_t AccessSize = UINT64_MAX;
302 auto *SizeNode = llvm::ConstantAsMetadata::get(
303 llvm::ConstantInt::get(Int64, AccessSize));
304 llvm::Metadata *Ops[] = {const_cast<llvm::MDNode *>(AccessType),
305 const_cast<llvm::MDNode *>(AccessType), OffsetNode,
306 SizeNode};
307 return llvm::MDNode::get(AccessType->getContext(), Ops);
308 }
309
310 llvm::Metadata *Ops[] = {const_cast<llvm::MDNode *>(AccessType),
311 const_cast<llvm::MDNode *>(AccessType), OffsetNode};
312 return llvm::MDNode::get(AccessType->getContext(), Ops);
313}
314
315// Modified from llvm::MDNode::isTBAAVtableAccess()
316
317static inline std::string
318getAccessNameTBAA(const llvm::MDNode *M,
319 const std::set<std::string> &legalnames) {
320 if (!isStructPathTBAA(M)) {
321 if (M->getNumOperands() < 1)
322 return "";
323 if (const llvm::MDString *Tag1 =
324 llvm::dyn_cast<llvm::MDString>(M->getOperand(0))) {
325 return Tag1->getString().str();
326 }
327 return "";
328 }
329
330 // For struct-path aware TBAA, we use the access type of the tag.
331 // llvm::errs() << "M: " << *M << "\n";
333 // llvm::errs() << "AT: " << *Tag.getAccessType() << "\n";
334 TBAAStructTypeNode AccessType(Tag.getAccessType());
335
336 // llvm::errs() << "numfields: " << AccessType.getNumFields() << "\n";
337 while (AccessType.getNumFields() > 0) {
338
339 if (auto *Id = llvm::dyn_cast<llvm::MDString>(AccessType.getId())) {
340 // llvm::errs() << "cur access type: " << Id->getString() << "\n";
341 if (legalnames.count(Id->getString().str())) {
342 return Id->getString().str();
343 }
344 }
345
346 AccessType = AccessType.getFieldType(0);
347 // llvm::errs() << "numfields: " << AccessType.getNumFields() << "\n";
348 }
349
350 if (auto *Id = llvm::dyn_cast<llvm::MDString>(AccessType.getId())) {
351 // llvm::errs() << "access type: " << Id->getString() << "\n";
352 return Id->getString().str();
353 }
354 return "";
355}
356
357static inline std::string
358getAccessNameTBAA(llvm::Instruction *Inst,
359 const std::set<std::string> &legalnames) {
360 if (const llvm::MDNode *M =
361 Inst->getMetadata(llvm::LLVMContext::MD_tbaa_struct)) {
362 for (unsigned i = 2; i < M->getNumOperands(); i += 3) {
363 if (const llvm::MDNode *M2 =
364 llvm::dyn_cast<llvm::MDNode>(M->getOperand(i))) {
365 auto res = getAccessNameTBAA(M2, legalnames);
366 if (res != "")
367 return res;
368 }
369 }
370 }
371 if (const llvm::MDNode *M = Inst->getMetadata(llvm::LLVMContext::MD_tbaa)) {
372 return getAccessNameTBAA(M, legalnames);
373 }
374 return "";
375}
376
377//! The following is not taken from LLVM
378
379extern "C" {
380/// Flag to print llvm::Type Analysis results as they are derived
381extern llvm::cl::opt<bool> EnzymePrintType;
382}
383
384/// Derive the ConcreteType corresponding to the string TypeName
385/// The llvm::Instruction I denotes the context in which this was found
386static inline ConcreteType
387getTypeFromTBAAString(std::string TypeName, llvm::Instruction &I,
388 std::shared_ptr<llvm::ModuleSlotTracker> MST) {
389 if (TypeName == "long long" || TypeName == "long" || TypeName == "int" ||
390 TypeName == "bool" || TypeName == "jtbaa_arraysize" ||
391 TypeName == "jtbaa_arraylen") {
392 if (EnzymePrintType) {
393 llvm::errs() << "known tbaa ";
394 if (MST)
395 I.print(llvm::errs(), *MST);
396 else
397 llvm::errs() << I;
398 llvm::errs() << " " << TypeName << "\n";
399 }
401 } else if (TypeName == "any pointer" || TypeName == "vtable pointer" ||
402 TypeName == "jtbaa_tag") {
403 if (EnzymePrintType) {
404 llvm::errs() << "known tbaa ";
405 if (MST)
406 I.print(llvm::errs(), *MST);
407 else
408 llvm::errs() << I;
409 llvm::errs() << " " << TypeName << "\n";
410 }
412 } else if (TypeName == "float") {
413 if (EnzymePrintType) {
414 llvm::errs() << "known tbaa ";
415 if (MST)
416 I.print(llvm::errs(), *MST);
417 else
418 llvm::errs() << I;
419 llvm::errs() << " " << TypeName << "\n";
420 }
421 return llvm::Type::getFloatTy(I.getContext());
422 } else if (TypeName == "double") {
423 if (EnzymePrintType) {
424 llvm::errs() << "known tbaa ";
425 if (MST)
426 I.print(llvm::errs(), *MST);
427 else
428 llvm::errs() << I;
429 llvm::errs() << " " << TypeName << "\n";
430 }
431 return llvm::Type::getDoubleTy(I.getContext());
432 }
434}
435
436/// Given a TBAA access node return the corresponding TypeTree
437/// This includes recursively parsing the access nodes, with
438/// corresponding offsets in the result
439static inline TypeTree parseTBAA(TBAAStructTypeNode AccessType,
440 llvm::Instruction &I,
441 const llvm::DataLayout &DL,
442 std::shared_ptr<llvm::ModuleSlotTracker> MST) {
443
444 if (auto *Id = llvm::dyn_cast<llvm::MDString>(AccessType.getId())) {
445 auto CT = getTypeFromTBAAString(Id->getString().str(), I, MST);
446 if (CT.isKnown()) {
447 return TypeTree(CT).Only(-1, &I);
448 }
449 }
450
452 for (unsigned i = 0, size = AccessType.getNumFields(); i < size; ++i) {
453 auto SubAccess = AccessType.getFieldType(i);
454 auto Offset = AccessType.getFieldOffset(i);
455 auto SubResult = parseTBAA(SubAccess, I, DL, MST);
456 Result |= SubResult.ShiftIndices(DL, /*init offset*/ 0, /*max size*/ -1,
457 /*addOffset*/ Offset);
458 }
459
460 return Result;
461}
462
463/// Given a TBAA metadata node return the corresponding TypeTree
464/// Modified from llvm::MDNode::isTBAAVtableAccess()
465static inline TypeTree parseTBAA(const llvm::MDNode *M, llvm::Instruction &I,
466 const llvm::DataLayout &DL,
467 std::shared_ptr<llvm::ModuleSlotTracker> MST) {
468 if (!isStructPathTBAA(M)) {
469 if (M->getNumOperands() < 1)
470 return TypeTree();
471 if (const llvm::MDString *Tag1 =
472 llvm::dyn_cast<llvm::MDString>(M->getOperand(0))) {
473 return TypeTree(getTypeFromTBAAString(Tag1->getString().str(), I, MST))
474 .Only(0, &I);
475 }
476 return TypeTree();
477 }
478
479 // For struct-path aware TBAA, we use the access type of the tag.
481 TBAAStructTypeNode AccessType(Tag.getAccessType());
482 return parseTBAA(AccessType, I, DL, MST);
483}
484
485/// Given an llvm::Instruction, return a TypeTree representing any
486/// types that can be derived from TBAA metadata attached
487static inline TypeTree parseTBAA(llvm::Instruction &I,
488 const llvm::DataLayout &DL,
489 std::shared_ptr<llvm::ModuleSlotTracker> MST) {
490 TypeTree Result;
491 if (const llvm::MDNode *M =
492 I.getMetadata(llvm::LLVMContext::MD_tbaa_struct)) {
493 for (unsigned i = 0, size = M->getNumOperands(); i < size; i += 3) {
494 if (const llvm::MDNode *M2 =
495 llvm::dyn_cast<llvm::MDNode>(M->getOperand(i + 2))) {
496 auto SubResult = parseTBAA(M2, I, DL, MST);
497 auto Start = llvm::cast<llvm::ConstantInt>(
498 llvm::cast<llvm::ConstantAsMetadata>(M->getOperand(i))
499 ->getValue())
500 ->getLimitedValue();
501 auto Len =
502 llvm::cast<llvm::ConstantInt>(
503 llvm::cast<llvm::ConstantAsMetadata>(M->getOperand(i + 1))
504 ->getValue())
505 ->getLimitedValue();
506 Result |=
507 SubResult.ShiftIndices(DL, /*init offset*/ 0, /*max size*/ Len,
508 /*add offset*/ Start);
509 }
510 }
511 }
512 if (const llvm::MDNode *M = I.getMetadata(llvm::LLVMContext::MD_tbaa)) {
513 Result |= parseTBAA(M, I, DL, MST);
514 }
515 Result |= TypeTree(BaseType::Pointer);
516 return Result;
517}
518
519#endif
llvm::PointerUnion< Operation *, Value > Node
static std::string getAccessNameTBAA(const llvm::MDNode *M, const std::set< std::string > &legalnames)
Definition TBAA.h:318
static const llvm::MDNode * createAccessTag(const llvm::MDNode *AccessType)
Definition TBAA.h:288
static ConcreteType getTypeFromTBAAString(std::string TypeName, llvm::Instruction &I, std::shared_ptr< llvm::ModuleSlotTracker > MST)
Derive the ConcreteType corresponding to the string TypeName The llvm::Instruction I denotes the cont...
Definition TBAA.h:387
llvm::cl::opt< bool > EnzymePrintType
The following is not taken from LLVM.
static bool isStructPathTBAA(const llvm::MDNode *MD)
Check the first operand of the tbaa tag node, if it is a llvm::MDNode, we treat it as struct-path awa...
Definition TBAA.h:280
static bool isNewFormatTypeNode(const llvm::MDNode *N)
isNewFormatTypeNode - Return true iff the given type node is in the new size-aware format.
Definition TBAA.h:36
static TypeTree parseTBAA(TBAAStructTypeNode AccessType, llvm::Instruction &I, const llvm::DataLayout &DL, std::shared_ptr< llvm::ModuleSlotTracker > MST)
Given a TBAA access node return the corresponding TypeTree This includes recursively parsing the acce...
Definition TBAA.h:439
Concrete SubType of a given value.
This is a simple wrapper around an llvm::MDNode which provides a higher-level interface by hiding the...
Definition TBAA.h:48
bool isNewFormat() const
isNewFormat - Return true iff the wrapped type node is in the new size-aware format.
Definition TBAA.h:60
TBAANodeImpl< MDNodeTy > getParent() const
getParent - Get this TBAANode's Alias tree parent.
Definition TBAA.h:63
TBAANodeImpl(MDNodeTy *N)
Definition TBAA.h:53
TBAANodeImpl()=default
MDNodeTy * getNode() const
getNode - Get the llvm::MDNode for this TBAANode.
Definition TBAA.h:56
bool isTypeImmutable() const
Test if this TBAANode represents a type for objects which are not modified (by any means) in the cont...
Definition TBAA.h:79
This is a simple wrapper around an llvm::MDNode which provides a higher-level interface by hiding the...
Definition TBAA.h:100
bool isNewFormat() const
isNewFormat - Return true iff the wrapped access tag is in the new size-aware format.
Definition TBAA.h:112
MDNodeTy * getBaseType() const
Definition TBAA.h:121
MDNodeTy * getNode() const
Get the llvm::MDNode for this TBAAStructTagNode.
Definition TBAA.h:108
TBAAStructTagNodeImpl(MDNodeTy *N)
Definition TBAA.h:105
MDNodeTy * getAccessType() const
Definition TBAA.h:125
uint64_t getSize() const
Definition TBAA.h:134
uint64_t getOffset() const
Definition TBAA.h:129
bool isTypeImmutable() const
Test if this TBAAStructTagNode represents a type for objects which are not modified (by any means) in...
Definition TBAA.h:144
This is a simple wrapper around an llvm::MDNode which provides a higher-level interface by hiding the...
Definition TBAA.h:166
const llvm::MDNode * getNode() const
Get the llvm::MDNode for this TBAAStructTypeNode.
Definition TBAA.h:175
TBAAStructTypeNode getField(uint64_t &Offset) const
Get this TBAAStructTypeNode's field in the type DAG with given offset.
Definition TBAA.h:217
TBAAStructTypeNode getFieldType(unsigned FieldIndex) const
Definition TBAA.h:207
bool isNewFormat() const
isNewFormat - Return true iff the wrapped type node is in the new size-aware format.
Definition TBAA.h:179
TBAAStructTypeNode()=default
llvm::Metadata * getId() const
getId - Return type identifier.
Definition TBAA.h:186
TBAAStructTypeNode(const llvm::MDNode *N)
Definition TBAA.h:172
bool operator==(const TBAAStructTypeNode &Other) const
Definition TBAA.h:181
unsigned getNumFields() const
Definition TBAA.h:190
uint64_t getFieldOffset(unsigned FieldIndex) const
Definition TBAA.h:196
Class representing the underlying types of values as sequences of offsets to a ConcreteType.
Definition TypeTree.h:72
TypeTree Only(int Off, llvm::Instruction *orig) const
Prepend an offset to all mappings.
Definition TypeTree.h:471
TypeTree ShiftIndices(const llvm::DataLayout &dl, const int offset, const int maxSize, size_t addOffset=0) const
Replace mappings in the range in [offset, offset+maxSize] with those in.
Definition TypeTree.h:840