LLVM  14.0.0git
ValueLattice.h
Go to the documentation of this file.
1 //===- ValueLattice.h - Value constraint analysis ---------------*- 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 #ifndef LLVM_ANALYSIS_VALUELATTICE_H
10 #define LLVM_ANALYSIS_VALUELATTICE_H
11 
12 #include "llvm/IR/ConstantRange.h"
13 #include "llvm/IR/Constants.h"
14 #include "llvm/IR/Instructions.h"
15 //
16 //===----------------------------------------------------------------------===//
17 // ValueLatticeElement
18 //===----------------------------------------------------------------------===//
19 
20 namespace llvm {
21 
22 /// This class represents lattice values for constants.
23 ///
24 /// FIXME: This is basically just for bringup, this can be made a lot more rich
25 /// in the future.
26 ///
28  enum ValueLatticeElementTy {
29  /// This Value has no known value yet. As a result, this implies the
30  /// producing instruction is dead. Caution: We use this as the starting
31  /// state in our local meet rules. In this usage, it's taken to mean
32  /// "nothing known yet".
33  /// Transition to any other state allowed.
34  unknown,
35 
36  /// This Value is an UndefValue constant or produces undef. Undefined values
37  /// can be merged with constants (or single element constant ranges),
38  /// assuming all uses of the result will be replaced.
39  /// Transition allowed to the following states:
40  /// constant
41  /// constantrange_including_undef
42  /// overdefined
43  undef,
44 
45  /// This Value has a specific constant value. The constant cannot be undef.
46  /// (For constant integers, constantrange is used instead. Integer typed
47  /// constantexprs can appear as constant.) Note that the constant state
48  /// can be reached by merging undef & constant states.
49  /// Transition allowed to the following states:
50  /// overdefined
51  constant,
52 
53  /// This Value is known to not have the specified value. (For constant
54  /// integers, constantrange is used instead. As above, integer typed
55  /// constantexprs can appear here.)
56  /// Transition allowed to the following states:
57  /// overdefined
58  notconstant,
59 
60  /// The Value falls within this range. (Used only for integer typed values.)
61  /// Transition allowed to the following states:
62  /// constantrange (new range must be a superset of the existing range)
63  /// constantrange_including_undef
64  /// overdefined
65  constantrange,
66 
67  /// This Value falls within this range, but also may be undef.
68  /// Merging it with other constant ranges results in
69  /// constantrange_including_undef.
70  /// Transition allowed to the following states:
71  /// overdefined
72  constantrange_including_undef,
73 
74  /// We can not precisely model the dynamic values this value might take.
75  /// No transitions are allowed after reaching overdefined.
76  overdefined,
77  };
78 
79  ValueLatticeElementTy Tag : 8;
80  /// Number of times a constant range has been extended with widening enabled.
81  unsigned NumRangeExtensions : 8;
82 
83  /// The union either stores a pointer to a constant or a constant range,
84  /// associated to the lattice element. We have to ensure that Range is
85  /// initialized or destroyed when changing state to or from constantrange.
86  union {
89  };
90 
91  /// Destroy contents of lattice value, without destructing the object.
92  void destroy() {
93  switch (Tag) {
94  case overdefined:
95  case unknown:
96  case undef:
97  case constant:
98  case notconstant:
99  break;
100  case constantrange_including_undef:
101  case constantrange:
102  Range.~ConstantRange();
103  break;
104  };
105  }
106 
107 public:
108  /// Struct to control some aspects related to merging constant ranges.
109  struct MergeOptions {
110  /// The merge value may include undef.
112 
113  /// Handle repeatedly extending a range by going to overdefined after a
114  /// number of steps.
116 
117  /// The number of allowed widening steps (including setting the range
118  /// initially).
119  unsigned MaxWidenSteps;
120 
122 
124  unsigned MaxWidenSteps = 1)
127 
129  MayIncludeUndef = V;
130  return *this;
131  }
132 
133  MergeOptions &setCheckWiden(bool V = true) {
134  CheckWiden = V;
135  return *this;
136  }
137 
138  MergeOptions &setMaxWidenSteps(unsigned Steps = 1) {
139  CheckWiden = true;
140  MaxWidenSteps = Steps;
141  return *this;
142  }
143  };
144 
145  // ConstVal and Range are initialized on-demand.
146  ValueLatticeElement() : Tag(unknown), NumRangeExtensions(0) {}
147 
148  ~ValueLatticeElement() { destroy(); }
149 
151  : Tag(Other.Tag), NumRangeExtensions(0) {
152  switch (Other.Tag) {
153  case constantrange:
154  case constantrange_including_undef:
155  new (&Range) ConstantRange(Other.Range);
156  NumRangeExtensions = Other.NumRangeExtensions;
157  break;
158  case constant:
159  case notconstant:
160  ConstVal = Other.ConstVal;
161  break;
162  case overdefined:
163  case unknown:
164  case undef:
165  break;
166  }
167  }
168 
170  : Tag(Other.Tag), NumRangeExtensions(0) {
171  switch (Other.Tag) {
172  case constantrange:
173  case constantrange_including_undef:
174  new (&Range) ConstantRange(std::move(Other.Range));
175  NumRangeExtensions = Other.NumRangeExtensions;
176  break;
177  case constant:
178  case notconstant:
179  ConstVal = Other.ConstVal;
180  break;
181  case overdefined:
182  case unknown:
183  case undef:
184  break;
185  }
186  Other.Tag = unknown;
187  }
188 
190  destroy();
191  new (this) ValueLatticeElement(Other);
192  return *this;
193  }
194 
196  destroy();
197  new (this) ValueLatticeElement(std::move(Other));
198  return *this;
199  }
200 
203  if (isa<UndefValue>(C))
204  Res.markUndef();
205  else
206  Res.markConstant(C);
207  return Res;
208  }
211  assert(!isa<UndefValue>(C) && "!= undef is not supported");
212  Res.markNotConstant(C);
213  return Res;
214  }
216  bool MayIncludeUndef = false) {
217  if (CR.isFullSet())
218  return getOverdefined();
219 
220  if (CR.isEmptySet()) {
222  if (MayIncludeUndef)
223  Res.markUndef();
224  return Res;
225  }
226 
229  MergeOptions().setMayIncludeUndef(MayIncludeUndef));
230  return Res;
231  }
234  Res.markOverdefined();
235  return Res;
236  }
237 
238  bool isUndef() const { return Tag == undef; }
239  bool isUnknown() const { return Tag == unknown; }
240  bool isUnknownOrUndef() const { return Tag == unknown || Tag == undef; }
241  bool isConstant() const { return Tag == constant; }
242  bool isNotConstant() const { return Tag == notconstant; }
244  return Tag == constantrange_including_undef;
245  }
246  /// Returns true if this value is a constant range. Use \p UndefAllowed to
247  /// exclude non-singleton constant ranges that may also be undef. Note that
248  /// this function also returns true if the range may include undef, but only
249  /// contains a single element. In that case, it can be replaced by a constant.
250  bool isConstantRange(bool UndefAllowed = true) const {
251  return Tag == constantrange || (Tag == constantrange_including_undef &&
252  (UndefAllowed || Range.isSingleElement()));
253  }
254  bool isOverdefined() const { return Tag == overdefined; }
255 
257  assert(isConstant() && "Cannot get the constant of a non-constant!");
258  return ConstVal;
259  }
260 
262  assert(isNotConstant() && "Cannot get the constant of a non-notconstant!");
263  return ConstVal;
264  }
265 
266  /// Returns the constant range for this value. Use \p UndefAllowed to exclude
267  /// non-singleton constant ranges that may also be undef. Note that this
268  /// function also returns a range if the range may include undef, but only
269  /// contains a single element. In that case, it can be replaced by a constant.
270  const ConstantRange &getConstantRange(bool UndefAllowed = true) const {
271  assert(isConstantRange(UndefAllowed) &&
272  "Cannot get the constant-range of a non-constant-range!");
273  return Range;
274  }
275 
277  if (isConstant() && isa<ConstantInt>(getConstant())) {
278  return cast<ConstantInt>(getConstant())->getValue();
279  } else if (isConstantRange() && getConstantRange().isSingleElement()) {
281  }
282  return None;
283  }
284 
286  if (isOverdefined())
287  return false;
288  destroy();
289  Tag = overdefined;
290  return true;
291  }
292 
293  bool markUndef() {
294  if (isUndef())
295  return false;
296 
297  assert(isUnknown());
298  Tag = undef;
299  return true;
300  }
301 
302  bool markConstant(Constant *V, bool MayIncludeUndef = false) {
303  if (isa<UndefValue>(V))
304  return markUndef();
305 
306  if (isConstant()) {
307  assert(getConstant() == V && "Marking constant with different value");
308  return false;
309  }
310 
311  if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
312  return markConstantRange(
313  ConstantRange(CI->getValue()),
314  MergeOptions().setMayIncludeUndef(MayIncludeUndef));
315 
316  assert(isUnknown() || isUndef());
317  Tag = constant;
318  ConstVal = V;
319  return true;
320  }
321 
323  assert(V && "Marking constant with NULL");
324  if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
325  return markConstantRange(
326  ConstantRange(CI->getValue() + 1, CI->getValue()));
327 
328  if (isa<UndefValue>(V))
329  return false;
330 
331  if (isNotConstant()) {
332  assert(getNotConstant() == V && "Marking !constant with different value");
333  return false;
334  }
335 
336  assert(isUnknown());
337  Tag = notconstant;
338  ConstVal = V;
339  return true;
340  }
341 
342  /// Mark the object as constant range with \p NewR. If the object is already a
343  /// constant range, nothing changes if the existing range is equal to \p
344  /// NewR and the tag. Otherwise \p NewR must be a superset of the existing
345  /// range or the object must be undef. The tag is set to
346  /// constant_range_including_undef if either the existing value or the new
347  /// range may include undef.
349  MergeOptions Opts = MergeOptions()) {
350  assert(!NewR.isEmptySet() && "should only be called for non-empty sets");
351 
352  if (NewR.isFullSet())
353  return markOverdefined();
354 
355  ValueLatticeElementTy OldTag = Tag;
356  ValueLatticeElementTy NewTag =
357  (isUndef() || isConstantRangeIncludingUndef() || Opts.MayIncludeUndef)
358  ? constantrange_including_undef
359  : constantrange;
360  if (isConstantRange()) {
361  Tag = NewTag;
362  if (getConstantRange() == NewR)
363  return Tag != OldTag;
364 
365  // Simple form of widening. If a range is extended multiple times, go to
366  // overdefined.
367  if (Opts.CheckWiden && ++NumRangeExtensions > Opts.MaxWidenSteps)
368  return markOverdefined();
369 
370  assert(NewR.contains(getConstantRange()) &&
371  "Existing range must be a subset of NewR");
372  Range = std::move(NewR);
373  return true;
374  }
375 
376  assert(isUnknown() || isUndef());
377 
378  NumRangeExtensions = 0;
379  Tag = NewTag;
380  new (&Range) ConstantRange(std::move(NewR));
381  return true;
382  }
383 
384  /// Updates this object to approximate both this object and RHS. Returns
385  /// true if this object has been changed.
386  bool mergeIn(const ValueLatticeElement &RHS,
387  MergeOptions Opts = MergeOptions()) {
388  if (RHS.isUnknown() || isOverdefined())
389  return false;
390  if (RHS.isOverdefined()) {
391  markOverdefined();
392  return true;
393  }
394 
395  if (isUndef()) {
396  assert(!RHS.isUnknown());
397  if (RHS.isUndef())
398  return false;
399  if (RHS.isConstant())
400  return markConstant(RHS.getConstant(), true);
401  if (RHS.isConstantRange())
402  return markConstantRange(RHS.getConstantRange(true),
403  Opts.setMayIncludeUndef());
404  return markOverdefined();
405  }
406 
407  if (isUnknown()) {
408  assert(!RHS.isUnknown() && "Unknow RHS should be handled earlier");
409  *this = RHS;
410  return true;
411  }
412 
413  if (isConstant()) {
414  if (RHS.isConstant() && getConstant() == RHS.getConstant())
415  return false;
416  if (RHS.isUndef())
417  return false;
418  markOverdefined();
419  return true;
420  }
421 
422  if (isNotConstant()) {
423  if (RHS.isNotConstant() && getNotConstant() == RHS.getNotConstant())
424  return false;
425  markOverdefined();
426  return true;
427  }
428 
429  auto OldTag = Tag;
430  assert(isConstantRange() && "New ValueLattice type?");
431  if (RHS.isUndef()) {
432  Tag = constantrange_including_undef;
433  return OldTag != Tag;
434  }
435 
436  if (!RHS.isConstantRange()) {
437  // We can get here if we've encountered a constantexpr of integer type
438  // and merge it with a constantrange.
439  markOverdefined();
440  return true;
441  }
442 
444  return markConstantRange(
445  std::move(NewR),
446  Opts.setMayIncludeUndef(RHS.isConstantRangeIncludingUndef()));
447  }
448 
449  // Compares this symbolic value with Other using Pred and returns either
450  /// true, false or undef constants, or nullptr if the comparison cannot be
451  /// evaluated.
453  const ValueLatticeElement &Other) const {
454  if (isUnknownOrUndef() || Other.isUnknownOrUndef())
455  return UndefValue::get(Ty);
456 
457  if (isConstant() && Other.isConstant())
458  return ConstantExpr::getCompare(Pred, getConstant(), Other.getConstant());
459 
460  if (ICmpInst::isEquality(Pred)) {
461  // not(C) != C => true, not(C) == C => false.
462  if ((isNotConstant() && Other.isConstant() &&
463  getNotConstant() == Other.getConstant()) ||
464  (isConstant() && Other.isNotConstant() &&
465  getConstant() == Other.getNotConstant()))
466  return Pred == ICmpInst::ICMP_NE
468  }
469 
470  // Integer constants are represented as ConstantRanges with single
471  // elements.
472  if (!isConstantRange() || !Other.isConstantRange())
473  return nullptr;
474 
475  const auto &CR = getConstantRange();
476  const auto &OtherCR = Other.getConstantRange();
477  if (CR.icmp(Pred, OtherCR))
478  return ConstantInt::getTrue(Ty);
479  if (CR.icmp(CmpInst::getInversePredicate(Pred), OtherCR))
480  return ConstantInt::getFalse(Ty);
481 
482  return nullptr;
483  }
484 
485  unsigned getNumRangeExtensions() const { return NumRangeExtensions; }
486  void setNumRangeExtensions(unsigned N) { NumRangeExtensions = N; }
487 };
488 
489 static_assert(sizeof(ValueLatticeElement) <= 40,
490  "size of ValueLatticeElement changed unexpectedly");
491 
492 raw_ostream &operator<<(raw_ostream &OS, const ValueLatticeElement &Val);
493 } // end namespace llvm
494 #endif
llvm::ConstantRange::isFullSet
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
Definition: ConstantRange.cpp:309
llvm::ValueLatticeElement::getNot
static ValueLatticeElement getNot(Constant *C)
Definition: ValueLattice.h:209
llvm::ValueLatticeElement::MergeOptions::setMaxWidenSteps
MergeOptions & setMaxWidenSteps(unsigned Steps=1)
Definition: ValueLattice.h:138
llvm::ValueLatticeElement::~ValueLatticeElement
~ValueLatticeElement()
Definition: ValueLattice.h:148
llvm::ValueLatticeElement::getConstantRange
const ConstantRange & getConstantRange(bool UndefAllowed=true) const
Returns the constant range for this value.
Definition: ValueLattice.h:270
llvm::ValueLatticeElement::isConstant
bool isConstant() const
Definition: ValueLattice.h:241
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::ValueLatticeElement::MergeOptions::MaxWidenSteps
unsigned MaxWidenSteps
The number of allowed widening steps (including setting the range initially).
Definition: ValueLattice.h:119
llvm::CmpInst::Predicate
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:720
llvm::ValueLatticeElement::getConstant
Constant * getConstant() const
Definition: ValueLattice.h:256
llvm::ValueLatticeElement::asConstantInteger
Optional< APInt > asConstantInteger() const
Definition: ValueLattice.h:276
llvm::ValueLatticeElement::getNotConstant
Constant * getNotConstant() const
Definition: ValueLattice.h:261
llvm::CmpInst::ICMP_NE
@ ICMP_NE
not equal
Definition: InstrTypes.h:742
llvm::CmpInst::getInversePredicate
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition: InstrTypes.h:820
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::ICmpInst::isEquality
bool isEquality() const
Return true if this predicate is either EQ or NE.
Definition: Instructions.h:1298
llvm::ValueLatticeElement::getOverdefined
static ValueLatticeElement getOverdefined()
Definition: ValueLattice.h:232
llvm::Optional
Definition: APInt.h:33
llvm::ValueLatticeElement::markNotConstant
bool markNotConstant(Constant *V)
Definition: ValueLattice.h:322
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::ValueLatticeElement::MergeOptions
Struct to control some aspects related to merging constant ranges.
Definition: ValueLattice.h:109
llvm::ValueLatticeElement::isUnknownOrUndef
bool isUnknownOrUndef() const
Definition: ValueLattice.h:240
Constants.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ValueLatticeElement::operator=
ValueLatticeElement & operator=(ValueLatticeElement &&Other)
Definition: ValueLattice.h:195
llvm::ValueLatticeElement::isConstantRangeIncludingUndef
bool isConstantRangeIncludingUndef() const
Definition: ValueLattice.h:243
llvm::ConstantRange::isSingleElement
bool isSingleElement() const
Return true if this set contains exactly one member.
Definition: ConstantRange.h:234
false
Definition: StackSlotColoring.cpp:142
llvm::ConstantRange::unionWith
ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
Definition: ConstantRange.cpp:573
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:230
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1796
llvm::ValueLatticeElement::markConstantRange
bool markConstantRange(ConstantRange NewR, MergeOptions Opts=MergeOptions())
Mark the object as constant range with NewR.
Definition: ValueLattice.h:348
llvm::ValueLatticeElement::ValueLatticeElement
ValueLatticeElement(ValueLatticeElement &&Other)
Definition: ValueLattice.h:169
llvm::None
const NoneType None
Definition: None.h:23
llvm::ValueLatticeElement::markOverdefined
bool markOverdefined()
Definition: ValueLattice.h:285
llvm::ValueLatticeElement::markConstant
bool markConstant(Constant *V, bool MayIncludeUndef=false)
Definition: ValueLattice.h:302
llvm::ConstantExpr::getCompare
static Constant * getCompare(unsigned short pred, Constant *C1, Constant *C2, bool OnlyIfReduced=false)
Return an ICmp or FCmp comparison operator constant expression.
Definition: Constants.cpp:2398
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::ValueLatticeElement::ValueLatticeElement
ValueLatticeElement(const ValueLatticeElement &Other)
Definition: ValueLattice.h:150
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::ValueLatticeElement::MergeOptions::MayIncludeUndef
bool MayIncludeUndef
The merge value may include undef.
Definition: ValueLattice.h:111
llvm::ValueLatticeElement::operator=
ValueLatticeElement & operator=(const ValueLatticeElement &Other)
Definition: ValueLattice.h:189
llvm::ValueLatticeElement::getCompare
Constant * getCompare(CmpInst::Predicate Pred, Type *Ty, const ValueLatticeElement &Other) const
true, false or undef constants, or nullptr if the comparison cannot be evaluated.
Definition: ValueLattice.h:452
llvm::ValueLatticeElement::getNumRangeExtensions
unsigned getNumRangeExtensions() const
Definition: ValueLattice.h:485
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ConstantRange::getSingleElement
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
Definition: ConstantRange.h:219
llvm::ValueLatticeElement::Range
ConstantRange Range
Definition: ValueLattice.h:88
ConstantRange.h
llvm::ValueLatticeElement
This class represents lattice values for constants.
Definition: ValueLattice.h:27
llvm::ValueLatticeElement::isOverdefined
bool isOverdefined() const
Definition: ValueLattice.h:254
llvm::ConstantInt::getFalse
static ConstantInt * getFalse(LLVMContext &Context)
Definition: Constants.cpp:880
llvm::ValueLatticeElement::isUndef
bool isUndef() const
Definition: ValueLattice.h:238
llvm::ConstantInt::getTrue
static ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:873
llvm::ValueLatticeElement::MergeOptions::setMayIncludeUndef
MergeOptions & setMayIncludeUndef(bool V=true)
Definition: ValueLattice.h:128
llvm::ValueLatticeElement::MergeOptions::MergeOptions
MergeOptions(bool MayIncludeUndef, bool CheckWiden, unsigned MaxWidenSteps=1)
Definition: ValueLattice.h:123
llvm::ValueLatticeElement::getRange
static ValueLatticeElement getRange(ConstantRange CR, bool MayIncludeUndef=false)
Definition: ValueLattice.h:215
llvm::ValueLatticeElement::isNotConstant
bool isNotConstant() const
Definition: ValueLattice.h:242
llvm::ConstantRange::contains
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
Definition: ConstantRange.cpp:393
llvm::ValueLatticeElement::MergeOptions::CheckWiden
bool CheckWiden
Handle repeatedly extending a range by going to overdefined after a number of steps.
Definition: ValueLattice.h:115
llvm::ConstantRange
This class represents a range of values.
Definition: ConstantRange.h:47
llvm::ValueLatticeElement::mergeIn
bool mergeIn(const ValueLatticeElement &RHS, MergeOptions Opts=MergeOptions())
Updates this object to approximate both this object and RHS.
Definition: ValueLattice.h:386
Instructions.h
llvm::ValueLatticeElement::get
static ValueLatticeElement get(Constant *C)
Definition: ValueLattice.h:201
N
#define N
llvm::ValueLatticeElement::isConstantRange
bool isConstantRange(bool UndefAllowed=true) const
Returns true if this value is a constant range.
Definition: ValueLattice.h:250
llvm::ValueLatticeElement::isUnknown
bool isUnknown() const
Definition: ValueLattice.h:239
llvm::ValueLatticeElement::markUndef
bool markUndef()
Definition: ValueLattice.h:293
llvm::ConstantRange::isEmptySet
bool isEmptySet() const
Return true if this set contains no members.
Definition: ConstantRange.cpp:313
llvm::ValueLatticeElement::MergeOptions::MergeOptions
MergeOptions()
Definition: ValueLattice.h:121
llvm::ValueLatticeElement::MergeOptions::setCheckWiden
MergeOptions & setCheckWiden(bool V=true)
Definition: ValueLattice.h:133
llvm::ValueLatticeElement::ValueLatticeElement
ValueLatticeElement()
Definition: ValueLattice.h:146
llvm::ValueLatticeElement::setNumRangeExtensions
void setNumRangeExtensions(unsigned N)
Definition: ValueLattice.h:486
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1184
llvm::ValueLatticeElement::ConstVal
Constant * ConstVal
Definition: ValueLattice.h:87