Enzyme main
Loading...
Searching...
No Matches
TypeAnalysis.h
Go to the documentation of this file.
1//===- TypeAnalysis.h - Declaration of Type Analysis ------------===//
2//
3// Enzyme Project
4//
5// Part of the Enzyme Project, under the Apache License v2.0 with LLVM
6// Exceptions. See https://llvm.org/LICENSE.txt for license information.
7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8//
9// If using this code in an academic setting, please cite the following:
10// @incollection{enzymeNeurips,
11// title = {Instead of Rewriting Foreign Code for Machine Learning,
12// Automatically Synthesize Fast Gradients},
13// author = {Moses, William S. and Churavy, Valentin},
14// booktitle = {Advances in Neural Information Processing Systems 33},
15// year = {2020},
16// note = {To appear in},
17// }
18//
19//===----------------------------------------------------------------------===//
20//
21// This file contains the declaration of Type Analysis, a utility for
22// computing the underlying data type of LLVM values.
23//
24//===----------------------------------------------------------------------===//
25#ifndef ENZYME_TYPE_ANALYSIS_H
26#define ENZYME_TYPE_ANALYSIS_H 1
27
28#include <cstdint>
29#include <deque>
30
31#include <llvm/Config/llvm-config.h>
32
33#include "llvm/ADT/SetVector.h"
34#include "llvm/ADT/StringMap.h"
35
36#include "llvm/Analysis/TargetLibraryInfo.h"
37
38#if LLVM_VERSION_MAJOR >= 16
39#include "llvm/Analysis/ScalarEvolution.h"
40#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
41#else
42#include "SCEV/ScalarEvolution.h"
43#include "SCEV/ScalarEvolutionExpander.h"
44#endif
45
46#include "llvm/IR/Constants.h"
47#include "llvm/IR/InstVisitor.h"
48#include "llvm/IR/ModuleSlotTracker.h"
49#include "llvm/IR/Type.h"
50#include "llvm/IR/Value.h"
51
52#include "llvm/Analysis/LoopInfo.h"
53#include "llvm/Analysis/PostDominators.h"
54#include "llvm/IR/Dominators.h"
55
56#include "../Utils.h"
57#include "TypeTree.h"
58
59extern const llvm::StringMap<llvm::Intrinsic::ID> LIBM_FUNCTIONS;
60
61static inline bool isMemFreeLibMFunction(llvm::StringRef str,
62 llvm::Intrinsic::ID *ID = nullptr) {
63 llvm::StringRef ogstr = str;
64 if (ID) {
65 if (str == "llvm.enzyme.lifetime_start") {
66 *ID = llvm::Intrinsic::lifetime_start;
67 return false;
68 }
69 if (str == "llvm.enzyme.lifetime_end") {
70 *ID = llvm::Intrinsic::lifetime_end;
71 return false;
72 }
73 }
74 if (startsWith(str, "__") && endsWith(str, "_finite")) {
75 str = str.substr(2, str.size() - 2 - 7);
76 } else if (startsWith(str, "__fd_") && endsWith(str, "_1")) {
77 str = str.substr(5, str.size() - 5 - 2);
78 } else if (startsWith(str, "__nv_")) {
79 str = str.substr(5, str.size() - 5);
80 } else if (startsWith(str, "__ocml_")) {
81 str = str.substr(7, str.size() - 7);
82 } else if (startsWith(str, "air.")) {
83 // Metal AIR math intrinsics, e.g. air.cos.f32, air.fast_tanh.f32.
84 // Defense-in-depth alongside PreserveNVVM.cpp's Implements map: this
85 // raw-name check works even in pipelines that don't run preserve-nvvm,
86 // exactly as __nv_/__ocml_ above already do for CUDA/ROCm.
87 str = str.substr(4, str.size() - 4);
88 if (endsWith(str, ".f16") || endsWith(str, ".f32") || endsWith(str, ".f64"))
89 str = str.substr(0, str.size() - 4);
90 if (startsWith(str, "fast_"))
91 str = str.substr(5, str.size() - 5);
92 }
93 if (LIBM_FUNCTIONS.find(str.str()) != LIBM_FUNCTIONS.end()) {
94 if (ID)
95 *ID = LIBM_FUNCTIONS.find(str.str())->second;
96 return true;
97 }
98 if (endsWith(str, "f") || endsWith(str, "l") ||
99 (startsWith(ogstr, "__nv_") && endsWith(str, "d"))) {
100 if (LIBM_FUNCTIONS.find(str.substr(0, str.size() - 1).str()) !=
101 LIBM_FUNCTIONS.end()) {
102 if (ID)
103 *ID = LIBM_FUNCTIONS.find(str.substr(0, str.size() - 1).str())->second;
104 return true;
105 }
106 }
107 if ((startsWith(ogstr, "__ocml_") &&
108 (endsWith(str, "_f64") || endsWith(str, "_f32")))) {
109 if (LIBM_FUNCTIONS.find(str.substr(0, str.size() - 4).str()) !=
110 LIBM_FUNCTIONS.end()) {
111 if (ID)
112 *ID = LIBM_FUNCTIONS.find(str.substr(0, str.size() - 4).str())->second;
113 return true;
114 }
115 }
116 return false;
117}
118
119/// Struct containing all contextual type information for a
120/// particular function call
122 /// Function being analyzed
123 llvm::Function *Function;
124
125 FnTypeInfo(llvm::Function *fn) : Function(fn) {}
126 FnTypeInfo(const FnTypeInfo &) = default;
129
130 /// Types of arguments
131 std::map<llvm::Argument *, TypeTree> Arguments;
132
133 /// Type of return
135
136 /// The specific constant(s) known to represented by an argument, if constant
137 std::map<llvm::Argument *, std::set<int64_t>> KnownValues;
138
139 /// The set of known values val will take
140 std::set<int64_t>
141 knownIntegralValues(llvm::Value *val, const llvm::DominatorTree &DT,
142 std::map<llvm::Value *, std::set<int64_t>> &intseen,
143 llvm::ScalarEvolution &SE) const;
144};
145
146static inline bool operator<(const FnTypeInfo &lhs, const FnTypeInfo &rhs) {
147
148 if (lhs.Function < rhs.Function)
149 return true;
150 if (rhs.Function < lhs.Function)
151 return false;
152
153 if (lhs.Return < rhs.Return)
154 return true;
155 if (rhs.Return < lhs.Return)
156 return false;
157
158 for (auto &arg : lhs.Function->args()) {
159 {
160 auto foundLHS = lhs.Arguments.find(&arg);
161 assert(foundLHS != lhs.Arguments.end());
162 auto foundRHS = rhs.Arguments.find(&arg);
163 assert(foundRHS != rhs.Arguments.end());
164 if (foundLHS->second < foundRHS->second)
165 return true;
166 if (foundRHS->second < foundLHS->second)
167 return false;
168 }
169
170 {
171 auto foundLHS = lhs.KnownValues.find(&arg);
172 assert(foundLHS != lhs.KnownValues.end());
173 auto foundRHS = rhs.KnownValues.find(&arg);
174 assert(foundRHS != rhs.KnownValues.end());
175 if (foundLHS->second < foundRHS->second)
176 return true;
177 if (foundRHS->second < foundLHS->second)
178 return false;
179 }
180 }
181 // equal;
182 return false;
183}
184
185class TypeAnalyzer;
186class TypeAnalysis;
187class EnzymeLogic;
188
189/// A holder class representing the results of running TypeAnalysis
190/// on a given function
192public:
194
195public:
196 TypeResults(std::nullptr_t);
198 ConcreteType intType(size_t num, llvm::Value *val, llvm::Instruction *I,
199 GradientUtils *gutils = nullptr,
200 llvm::IRBuilder<> *BuilderIfShouldErr = nullptr,
201 bool pointerIntSame = false) const;
202 llvm::Type *addingType(size_t num, llvm::Value *val, size_t start = 0) const;
203
204 /// Returns whether in the first num bytes there is pointer, int, float, or
205 /// none If pointerIntSame is set to true, then consider either as the same
206 /// (and thus mergable)
207 ConcreteType firstPointer(size_t num, llvm::Value *val, llvm::Instruction *I,
208 GradientUtils *gutils = nullptr,
209 llvm::IRBuilder<> *BuilderIfShouldErr = nullptr,
210 bool pointerIntSame = false) const;
211
212 /// The TypeTree of a particular Value
213 const TypeTree &query(llvm::Value *val) const;
214
215 /// Whether any part of the top level register can contain a float
216 /// e.g. { i64, float } can contain a float, but { i64, i8* } would not.
217 // Of course, here we compute with type analysis rather than llvm type
218 // The flag `anythingIsFloat` specifies whether an anything should
219 // be considered a float.
220 bool anyFloat(llvm::Value *val, bool anythingIsFloat = true) const;
221
222 /// Whether all of the top level register is known to contain float data
223 bool allFloat(llvm::Value *val) const;
224
225 /// Whether any part of the top level register can contain a pointer
226 /// e.g. { i64, i8* } can contain a pointer, but { i64, float } would not.
227 // Of course, here we compute with type analysis rather than llvm type
228 bool anyPointer(llvm::Value *val) const;
229
230 /// The TypeInfo calling convention
232
233 /// The Type of the return
235
236 /// Prints all known information
237 void dump(llvm::raw_ostream &ss = llvm::errs()) const;
238
239 /// The set of values val will take on during this program
240 std::set<int64_t> knownIntegralValues(llvm::Value *val) const;
241
242 FnTypeInfo getCallInfo(llvm::CallBase &CI, llvm::Function &fn) const;
243
244 llvm::Function *getFunction() const;
245};
246
247/// Helper class that computes the fixed-point type results of a given function
248class TypeAnalyzer : public llvm::InstVisitor<TypeAnalyzer> {
249public:
250 /// Cache of metadata indices, for faster printing.
251 /// Only initialized if EnzymePrintType is true
252 std::shared_ptr<llvm::ModuleSlotTracker> MST;
253
254 /// List of value's which should be re-analyzed now with new information
255 llvm::SetVector<llvm::Value *, std::deque<llvm::Value *>> workList;
256
257 const llvm::SmallPtrSet<llvm::BasicBlock *, 4> notForAnalysis;
258
259private:
260 /// Tell TypeAnalyzer to reanalyze this value
261 void addToWorkList(llvm::Value *val);
262
263 /// Map of Value to known integer constants that it will take on
264 std::map<llvm::Value *, std::set<int64_t>> intseen;
265
266 std::map<llvm::Value *, std::pair<bool, bool>> mriseen;
267 bool mustRemainInteger(llvm::Value *val, bool *returned = nullptr);
268
269public:
270 /// Calling context
272
273 /// Calling TypeAnalysis to be used in the case of calls to other
274 /// functions
276
277 /// Directionality of checks
278 uint8_t direction;
279
280 /// Whether an inconsistent update has been found
281 /// This will only be set when direction != Both, erring otherwise
283
285
286 // propagate from instruction to operand
287 static constexpr uint8_t UP = 1;
288 // propagate from operand to instruction
289 static constexpr uint8_t DOWN = 2;
290 static constexpr uint8_t BOTH = UP | DOWN;
291
292 /// Intermediate conservative, but correct Type analysis results
293 std::map<llvm::Value *, TypeTree> analysis;
294
295 llvm::TargetLibraryInfo &TLI;
296 llvm::DominatorTree &DT;
297 llvm::PostDominatorTree &PDT;
298
299 llvm::LoopInfo &LI;
300 llvm::ScalarEvolution &SE;
301
302 FnTypeInfo getCallInfo(llvm::CallBase &CI, llvm::Function &fn);
303
305
306 TypeAnalyzer(const FnTypeInfo &fn, TypeAnalysis &TA,
307 uint8_t direction = BOTH);
308
309 TypeAnalyzer(const FnTypeInfo &fn, TypeAnalysis &TA,
310 const llvm::SmallPtrSetImpl<llvm::BasicBlock *> &notForAnalysis,
311 const TypeAnalyzer &Prev, uint8_t direction = BOTH,
312 bool PHIRecur = false);
313
314 /// Get the current results for a given value
315 const TypeTree &getAnalysis(llvm::Value *Val);
316
317 /// Add additional information to the Type info of val, readding it to the
318 /// work queue as necessary
319 void updateAnalysis(llvm::Value *val, BaseType data, llvm::Value *origin);
320 void updateAnalysis(llvm::Value *val, ConcreteType data, llvm::Value *origin);
321 void updateAnalysis(llvm::Value *val, TypeTree data, llvm::Value *origin);
322
323 /// Analyze type info given by the arguments, possibly adding to work queue
324 void prepareArgs();
325
326 /// Analyze type info given by the TBAA, possibly adding to work queue
327 void considerTBAA();
328
329 /// Run the interprocedural type analysis starting from this function
330 void run();
331
332 /// Hypothesize that undefined phi's are integers and try to prove
333 /// that they are really integral
334 void runPHIHypotheses();
335
336 void visitValue(llvm::Value &val);
337
338 void visitConstantExpr(llvm::ConstantExpr &CE);
339
340 void visitCmpInst(llvm::CmpInst &I);
341
342 void visitAllocaInst(llvm::AllocaInst &I);
343
344 void visitLoadInst(llvm::LoadInst &I);
345
346 void visitStoreInst(llvm::StoreInst &I);
347
348 void visitGetElementPtrInst(llvm::GetElementPtrInst &gep);
349
350 void visitGEPOperator(llvm::GEPOperator &gep);
351
352 void visitPHINode(llvm::PHINode &phi);
353
354 void visitTruncInst(llvm::TruncInst &I);
355
356 void visitZExtInst(llvm::ZExtInst &I);
357
358 void visitSExtInst(llvm::SExtInst &I);
359
360 void visitAddrSpaceCastInst(llvm::AddrSpaceCastInst &I);
361
362 void visitFPExtInst(llvm::FPExtInst &I);
363
364 void visitFPTruncInst(llvm::FPTruncInst &I);
365
366 void visitFPToUIInst(llvm::FPToUIInst &I);
367
368 void visitFPToSIInst(llvm::FPToSIInst &I);
369
370 void visitUIToFPInst(llvm::UIToFPInst &I);
371
372 void visitSIToFPInst(llvm::SIToFPInst &I);
373
374 void visitPtrToIntInst(llvm::PtrToIntInst &I);
375
376 void visitIntToPtrInst(llvm::IntToPtrInst &I);
377
378 void visitBitCastInst(llvm::BitCastInst &I);
379
380#if LLVM_VERSION_MAJOR >= 10
381 void visitFreezeInst(llvm::FreezeInst &I);
382#endif
383
384 void visitSelectInst(llvm::SelectInst &I);
385
386 void visitExtractElementInst(llvm::ExtractElementInst &I);
387
388 void visitInsertElementInst(llvm::InsertElementInst &I);
389
390 void visitShuffleVectorInst(llvm::ShuffleVectorInst &I);
391
392 void visitExtractValueInst(llvm::ExtractValueInst &I);
393
394 void visitInsertValueInst(llvm::InsertValueInst &I);
395
396 void visitAtomicRMWInst(llvm::AtomicRMWInst &I);
397
398 void visitBinaryOperator(llvm::BinaryOperator &I);
399 void visitBinaryOperation(const llvm::DataLayout &DL, llvm::Type *T,
400 llvm::Instruction::BinaryOps, llvm::Value *Args[2],
401 TypeTree &Ret, TypeTree &LHS, TypeTree &RHS,
402 llvm::Instruction *I);
403
404 void visitIPOCall(llvm::CallBase &call, llvm::Function &fn);
405
406 void visitCallBase(llvm::CallBase &call);
407
408 void visitMemTransferInst(llvm::MemTransferInst &MTI);
409 void visitMemTransferCommon(llvm::CallBase &MTI);
410
411 void visitIntrinsicInst(llvm::IntrinsicInst &II);
412
414
415 void dump(llvm::raw_ostream &ss = llvm::errs());
416
417 std::set<int64_t> knownIntegralValues(llvm::Value *val);
418
419 // TODO handle fneg on LLVM 10+
420};
421
422/// Full interprocedural TypeAnalysis
424public:
427 /// Map of custom function call handlers
428 llvm::StringMap<
429 std::function<bool(int /*direction*/, TypeTree & /*returnTree*/,
430 llvm::ArrayRef<TypeTree> /*argTrees*/,
431 llvm::ArrayRef<std::set<int64_t>> /*knownValues*/,
432 llvm::CallBase * /*call*/, TypeAnalyzer *)>>
434
435 /// Map of possible query states to TypeAnalyzer intermediate results
436 std::map<FnTypeInfo, std::shared_ptr<TypeAnalyzer>> analyzedFunctions;
437
438 /// Analyze a particular function, returning the results
440
441 /// Clear existing analyses
442 void clear();
443};
444
445TypeTree defaultTypeTreeForLLVM(llvm::Type *ET, llvm::Instruction *I,
446 bool intIsPointer = true);
448 llvm::Function *todiff);
449#endif
BaseType
Categories of potential types.
Definition BaseType.h:32
static std::string str(AugmentedStruct c)
Definition EnzymeLogic.h:62
FnTypeInfo preventTypeAnalysisLoops(const FnTypeInfo &oldTypeInfo_, llvm::Function *todiff)
TypeTree defaultTypeTreeForLLVM(llvm::Type *ET, llvm::Instruction *I, bool intIsPointer=true)
const llvm::StringMap< llvm::Intrinsic::ID > LIBM_FUNCTIONS
static bool isMemFreeLibMFunction(llvm::StringRef str, llvm::Intrinsic::ID *ID=nullptr)
static bool operator<(const FnTypeInfo &lhs, const FnTypeInfo &rhs)
@ Args
Return is a struct of all args.
static bool startsWith(llvm::StringRef string, llvm::StringRef prefix)
Definition Utils.h:847
static bool endsWith(llvm::StringRef string, llvm::StringRef suffix)
Definition Utils.h:855
Concrete SubType of a given value.
Full interprocedural TypeAnalysis.
llvm::StringMap< std::function< bool(int, TypeTree &, llvm::ArrayRef< TypeTree >, llvm::ArrayRef< std::set< int64_t > >, llvm::CallBase *, TypeAnalyzer *)> > CustomRules
Map of custom function call handlers.
std::map< FnTypeInfo, std::shared_ptr< TypeAnalyzer > > analyzedFunctions
Map of possible query states to TypeAnalyzer intermediate results.
void clear()
Clear existing analyses.
TypeAnalysis(EnzymeLogic &Logic)
TypeResults analyzeFunction(const FnTypeInfo &fn)
Analyze a particular function, returning the results.
EnzymeLogic & Logic
Helper class that computes the fixed-point type results of a given function.
void visitMemTransferInst(llvm::MemTransferInst &MTI)
void visitFPToSIInst(llvm::FPToSIInst &I)
llvm::PostDominatorTree & PDT
FnTypeInfo getCallInfo(llvm::CallBase &CI, llvm::Function &fn)
void visitAllocaInst(llvm::AllocaInst &I)
const FnTypeInfo fntypeinfo
Calling context.
void visitExtractValueInst(llvm::ExtractValueInst &I)
void visitSIToFPInst(llvm::SIToFPInst &I)
const llvm::SmallPtrSet< llvm::BasicBlock *, 4 > notForAnalysis
llvm::DominatorTree & DT
std::set< int64_t > knownIntegralValues(llvm::Value *val)
void visitFPExtInst(llvm::FPExtInst &I)
void visitConstantExpr(llvm::ConstantExpr &CE)
TypeAnalysis & interprocedural
Calling TypeAnalysis to be used in the case of calls to other functions.
void visitGetElementPtrInst(llvm::GetElementPtrInst &gep)
void visitIntToPtrInst(llvm::IntToPtrInst &I)
void prepareArgs()
Analyze type info given by the arguments, possibly adding to work queue.
void visitShuffleVectorInst(llvm::ShuffleVectorInst &I)
llvm::TargetLibraryInfo & TLI
void visitUIToFPInst(llvm::UIToFPInst &I)
static constexpr uint8_t UP
void visitInsertValueInst(llvm::InsertValueInst &I)
void visitPHINode(llvm::PHINode &phi)
void visitValue(llvm::Value &val)
void visitSelectInst(llvm::SelectInst &I)
void visitIPOCall(llvm::CallBase &call, llvm::Function &fn)
std::shared_ptr< llvm::ModuleSlotTracker > MST
Cache of metadata indices, for faster printing.
llvm::SetVector< llvm::Value *, std::deque< llvm::Value * > > workList
List of value's which should be re-analyzed now with new information.
static constexpr uint8_t DOWN
const TypeTree & getAnalysis(llvm::Value *Val)
Get the current results for a given value.
void updateAnalysis(llvm::Value *val, BaseType data, llvm::Value *origin)
Add additional information to the Type info of val, readding it to the work queue as necessary.
void visitAddrSpaceCastInst(llvm::AddrSpaceCastInst &I)
bool Invalid
Whether an inconsistent update has been found This will only be set when direction !...
static constexpr uint8_t BOTH
void visitExtractElementInst(llvm::ExtractElementInst &I)
void visitLoadInst(llvm::LoadInst &I)
void visitCmpInst(llvm::CmpInst &I)
uint8_t direction
Directionality of checks.
std::map< llvm::Value *, TypeTree > analysis
Intermediate conservative, but correct Type analysis results.
void visitIntrinsicInst(llvm::IntrinsicInst &II)
void visitSExtInst(llvm::SExtInst &I)
void visitGEPOperator(llvm::GEPOperator &gep)
void updateAnalysis(llvm::Value *val, ConcreteType data, llvm::Value *origin)
void considerTBAA()
Analyze type info given by the TBAA, possibly adding to work queue.
void visitCallBase(llvm::CallBase &call)
void visitFPTruncInst(llvm::FPTruncInst &I)
void visitStoreInst(llvm::StoreInst &I)
void visitAtomicRMWInst(llvm::AtomicRMWInst &I)
TypeAnalyzer(TypeAnalysis &TA)
void visitZExtInst(llvm::ZExtInst &I)
void runPHIHypotheses()
Hypothesize that undefined phi's are integers and try to prove that they are really integral.
void visitBinaryOperator(llvm::BinaryOperator &I)
void visitMemTransferCommon(llvm::CallBase &MTI)
void visitBinaryOperation(const llvm::DataLayout &DL, llvm::Type *T, llvm::Instruction::BinaryOps, llvm::Value *Args[2], TypeTree &Ret, TypeTree &LHS, TypeTree &RHS, llvm::Instruction *I)
void visitFPToUIInst(llvm::FPToUIInst &I)
void visitBitCastInst(llvm::BitCastInst &I)
void updateAnalysis(llvm::Value *val, TypeTree data, llvm::Value *origin)
llvm::LoopInfo & LI
void dump(llvm::raw_ostream &ss=llvm::errs())
void visitTruncInst(llvm::TruncInst &I)
void visitPtrToIntInst(llvm::PtrToIntInst &I)
llvm::ScalarEvolution & SE
void run()
Run the interprocedural type analysis starting from this function.
TypeTree getReturnAnalysis()
void visitInsertElementInst(llvm::InsertElementInst &I)
A holder class representing the results of running TypeAnalysis on a given function.
TypeResults(std::nullptr_t)
llvm::Type * addingType(size_t num, llvm::Value *val, size_t start=0) const
ConcreteType firstPointer(size_t num, llvm::Value *val, llvm::Instruction *I, GradientUtils *gutils=nullptr, llvm::IRBuilder<> *BuilderIfShouldErr=nullptr, bool pointerIntSame=false) const
Returns whether in the first num bytes there is pointer, int, float, or none If pointerIntSame is set...
void dump(llvm::raw_ostream &ss=llvm::errs()) const
Prints all known information.
bool anyFloat(llvm::Value *val, bool anythingIsFloat=true) const
Whether any part of the top level register can contain a float e.g.
TypeAnalyzer * analyzer
FnTypeInfo getAnalyzedTypeInfo() const
The TypeInfo calling convention.
bool anyPointer(llvm::Value *val) const
Whether any part of the top level register can contain a pointer e.g.
std::set< int64_t > knownIntegralValues(llvm::Value *val) const
The set of values val will take on during this program.
TypeTree getReturnAnalysis() const
The Type of the return.
const TypeTree & query(llvm::Value *val) const
The TypeTree of a particular Value.
ConcreteType intType(size_t num, llvm::Value *val, llvm::Instruction *I, GradientUtils *gutils=nullptr, llvm::IRBuilder<> *BuilderIfShouldErr=nullptr, bool pointerIntSame=false) const
bool allFloat(llvm::Value *val) const
Whether all of the top level register is known to contain float data.
llvm::Function * getFunction() const
FnTypeInfo getCallInfo(llvm::CallBase &CI, llvm::Function &fn) const
Class representing the underlying types of values as sequences of offsets to a ConcreteType.
Definition TypeTree.h:72
Struct containing all contextual type information for a particular function call.
FnTypeInfo(llvm::Function *fn)
std::map< llvm::Argument *, TypeTree > Arguments
Types of arguments.
llvm::Function * Function
Function being analyzed.
TypeTree Return
Type of return.
std::set< int64_t > knownIntegralValues(llvm::Value *val, const llvm::DominatorTree &DT, std::map< llvm::Value *, std::set< int64_t > > &intseen, llvm::ScalarEvolution &SE) const
The set of known values val will take.
FnTypeInfo & operator=(FnTypeInfo &)=default
FnTypeInfo(const FnTypeInfo &)=default
std::map< llvm::Argument *, std::set< int64_t > > KnownValues
The specific constant(s) known to represented by an argument, if constant.
FnTypeInfo & operator=(FnTypeInfo &&)=default