ValueLattice.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  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. #ifndef LLVM_ANALYSIS_VALUELATTICE_H
  9. #define LLVM_ANALYSIS_VALUELATTICE_H
  10. #include "llvm/IR/ConstantRange.h"
  11. #include "llvm/IR/Constants.h"
  12. #include "llvm/IR/Instructions.h"
  13. //
  14. //===----------------------------------------------------------------------===//
  15. // ValueLatticeElement
  16. //===----------------------------------------------------------------------===//
  17. namespace llvm {
  18. /// This class represents lattice values for constants.
  19. ///
  20. /// FIXME: This is basically just for bringup, this can be made a lot more rich
  21. /// in the future.
  22. ///
  23. class ValueLatticeElement {
  24. enum ValueLatticeElementTy {
  25. /// This Value has no known value yet. As a result, this implies the
  26. /// producing instruction is dead. Caution: We use this as the starting
  27. /// state in our local meet rules. In this usage, it's taken to mean
  28. /// "nothing known yet".
  29. /// Transition to any other state allowed.
  30. unknown,
  31. /// This Value is an UndefValue constant or produces undef. Undefined values
  32. /// can be merged with constants (or single element constant ranges),
  33. /// assuming all uses of the result will be replaced.
  34. /// Transition allowed to the following states:
  35. /// constant
  36. /// constantrange_including_undef
  37. /// overdefined
  38. undef,
  39. /// This Value has a specific constant value. The constant cannot be undef.
  40. /// (For constant integers, constantrange is used instead. Integer typed
  41. /// constantexprs can appear as constant.) Note that the constant state
  42. /// can be reached by merging undef & constant states.
  43. /// Transition allowed to the following states:
  44. /// overdefined
  45. constant,
  46. /// This Value is known to not have the specified value. (For constant
  47. /// integers, constantrange is used instead. As above, integer typed
  48. /// constantexprs can appear here.)
  49. /// Transition allowed to the following states:
  50. /// overdefined
  51. notconstant,
  52. /// The Value falls within this range. (Used only for integer typed values.)
  53. /// Transition allowed to the following states:
  54. /// constantrange (new range must be a superset of the existing range)
  55. /// constantrange_including_undef
  56. /// overdefined
  57. constantrange,
  58. /// This Value falls within this range, but also may be undef.
  59. /// Merging it with other constant ranges results in
  60. /// constantrange_including_undef.
  61. /// Transition allowed to the following states:
  62. /// overdefined
  63. constantrange_including_undef,
  64. /// We can not precisely model the dynamic values this value might take.
  65. /// No transitions are allowed after reaching overdefined.
  66. overdefined,
  67. };
  68. ValueLatticeElementTy Tag : 8;
  69. /// Number of times a constant range has been extended with widening enabled.
  70. unsigned NumRangeExtensions : 8;
  71. /// The union either stores a pointer to a constant or a constant range,
  72. /// associated to the lattice element. We have to ensure that Range is
  73. /// initialized or destroyed when changing state to or from constantrange.
  74. union {
  75. Constant *ConstVal;
  76. ConstantRange Range;
  77. };
  78. /// Destroy contents of lattice value, without destructing the object.
  79. void destroy() {
  80. switch (Tag) {
  81. case overdefined:
  82. case unknown:
  83. case undef:
  84. case constant:
  85. case notconstant:
  86. break;
  87. case constantrange_including_undef:
  88. case constantrange:
  89. Range.~ConstantRange();
  90. break;
  91. };
  92. }
  93. public:
  94. /// Struct to control some aspects related to merging constant ranges.
  95. struct MergeOptions {
  96. /// The merge value may include undef.
  97. bool MayIncludeUndef;
  98. /// Handle repeatedly extending a range by going to overdefined after a
  99. /// number of steps.
  100. bool CheckWiden;
  101. /// The number of allowed widening steps (including setting the range
  102. /// initially).
  103. unsigned MaxWidenSteps;
  104. MergeOptions() : MergeOptions(false, false) {}
  105. MergeOptions(bool MayIncludeUndef, bool CheckWiden,
  106. unsigned MaxWidenSteps = 1)
  107. : MayIncludeUndef(MayIncludeUndef), CheckWiden(CheckWiden),
  108. MaxWidenSteps(MaxWidenSteps) {}
  109. MergeOptions &setMayIncludeUndef(bool V = true) {
  110. MayIncludeUndef = V;
  111. return *this;
  112. }
  113. MergeOptions &setCheckWiden(bool V = true) {
  114. CheckWiden = V;
  115. return *this;
  116. }
  117. MergeOptions &setMaxWidenSteps(unsigned Steps = 1) {
  118. CheckWiden = true;
  119. MaxWidenSteps = Steps;
  120. return *this;
  121. }
  122. };
  123. // ConstVal and Range are initialized on-demand.
  124. ValueLatticeElement() : Tag(unknown), NumRangeExtensions(0) {}
  125. ~ValueLatticeElement() { destroy(); }
  126. ValueLatticeElement(const ValueLatticeElement &Other)
  127. : Tag(Other.Tag), NumRangeExtensions(0) {
  128. switch (Other.Tag) {
  129. case constantrange:
  130. case constantrange_including_undef:
  131. new (&Range) ConstantRange(Other.Range);
  132. NumRangeExtensions = Other.NumRangeExtensions;
  133. break;
  134. case constant:
  135. case notconstant:
  136. ConstVal = Other.ConstVal;
  137. break;
  138. case overdefined:
  139. case unknown:
  140. case undef:
  141. break;
  142. }
  143. }
  144. ValueLatticeElement(ValueLatticeElement &&Other)
  145. : Tag(Other.Tag), NumRangeExtensions(0) {
  146. switch (Other.Tag) {
  147. case constantrange:
  148. case constantrange_including_undef:
  149. new (&Range) ConstantRange(std::move(Other.Range));
  150. NumRangeExtensions = Other.NumRangeExtensions;
  151. break;
  152. case constant:
  153. case notconstant:
  154. ConstVal = Other.ConstVal;
  155. break;
  156. case overdefined:
  157. case unknown:
  158. case undef:
  159. break;
  160. }
  161. Other.Tag = unknown;
  162. }
  163. ValueLatticeElement &operator=(const ValueLatticeElement &Other) {
  164. destroy();
  165. new (this) ValueLatticeElement(Other);
  166. return *this;
  167. }
  168. ValueLatticeElement &operator=(ValueLatticeElement &&Other) {
  169. destroy();
  170. new (this) ValueLatticeElement(std::move(Other));
  171. return *this;
  172. }
  173. static ValueLatticeElement get(Constant *C) {
  174. ValueLatticeElement Res;
  175. if (isa<UndefValue>(C))
  176. Res.markUndef();
  177. else
  178. Res.markConstant(C);
  179. return Res;
  180. }
  181. static ValueLatticeElement getNot(Constant *C) {
  182. ValueLatticeElement Res;
  183. assert(!isa<UndefValue>(C) && "!= undef is not supported");
  184. Res.markNotConstant(C);
  185. return Res;
  186. }
  187. static ValueLatticeElement getRange(ConstantRange CR,
  188. bool MayIncludeUndef = false) {
  189. if (CR.isFullSet())
  190. return getOverdefined();
  191. if (CR.isEmptySet()) {
  192. ValueLatticeElement Res;
  193. if (MayIncludeUndef)
  194. Res.markUndef();
  195. return Res;
  196. }
  197. ValueLatticeElement Res;
  198. Res.markConstantRange(std::move(CR),
  199. MergeOptions().setMayIncludeUndef(MayIncludeUndef));
  200. return Res;
  201. }
  202. static ValueLatticeElement getOverdefined() {
  203. ValueLatticeElement Res;
  204. Res.markOverdefined();
  205. return Res;
  206. }
  207. bool isUndef() const { return Tag == undef; }
  208. bool isUnknown() const { return Tag == unknown; }
  209. bool isUnknownOrUndef() const { return Tag == unknown || Tag == undef; }
  210. bool isConstant() const { return Tag == constant; }
  211. bool isNotConstant() const { return Tag == notconstant; }
  212. bool isConstantRangeIncludingUndef() const {
  213. return Tag == constantrange_including_undef;
  214. }
  215. /// Returns true if this value is a constant range. Use \p UndefAllowed to
  216. /// exclude non-singleton constant ranges that may also be undef. Note that
  217. /// this function also returns true if the range may include undef, but only
  218. /// contains a single element. In that case, it can be replaced by a constant.
  219. bool isConstantRange(bool UndefAllowed = true) const {
  220. return Tag == constantrange || (Tag == constantrange_including_undef &&
  221. (UndefAllowed || Range.isSingleElement()));
  222. }
  223. bool isOverdefined() const { return Tag == overdefined; }
  224. Constant *getConstant() const {
  225. assert(isConstant() && "Cannot get the constant of a non-constant!");
  226. return ConstVal;
  227. }
  228. Constant *getNotConstant() const {
  229. assert(isNotConstant() && "Cannot get the constant of a non-notconstant!");
  230. return ConstVal;
  231. }
  232. /// Returns the constant range for this value. Use \p UndefAllowed to exclude
  233. /// non-singleton constant ranges that may also be undef. Note that this
  234. /// function also returns a range if the range may include undef, but only
  235. /// contains a single element. In that case, it can be replaced by a constant.
  236. const ConstantRange &getConstantRange(bool UndefAllowed = true) const {
  237. assert(isConstantRange(UndefAllowed) &&
  238. "Cannot get the constant-range of a non-constant-range!");
  239. return Range;
  240. }
  241. Optional<APInt> asConstantInteger() const {
  242. if (isConstant() && isa<ConstantInt>(getConstant())) {
  243. return cast<ConstantInt>(getConstant())->getValue();
  244. } else if (isConstantRange() && getConstantRange().isSingleElement()) {
  245. return *getConstantRange().getSingleElement();
  246. }
  247. return None;
  248. }
  249. bool markOverdefined() {
  250. if (isOverdefined())
  251. return false;
  252. destroy();
  253. Tag = overdefined;
  254. return true;
  255. }
  256. bool markUndef() {
  257. if (isUndef())
  258. return false;
  259. assert(isUnknown());
  260. Tag = undef;
  261. return true;
  262. }
  263. bool markConstant(Constant *V, bool MayIncludeUndef = false) {
  264. if (isa<UndefValue>(V))
  265. return markUndef();
  266. if (isConstant()) {
  267. assert(getConstant() == V && "Marking constant with different value");
  268. return false;
  269. }
  270. if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
  271. return markConstantRange(
  272. ConstantRange(CI->getValue()),
  273. MergeOptions().setMayIncludeUndef(MayIncludeUndef));
  274. assert(isUnknown() || isUndef());
  275. Tag = constant;
  276. ConstVal = V;
  277. return true;
  278. }
  279. bool markNotConstant(Constant *V) {
  280. assert(V && "Marking constant with NULL");
  281. if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
  282. return markConstantRange(
  283. ConstantRange(CI->getValue() + 1, CI->getValue()));
  284. if (isa<UndefValue>(V))
  285. return false;
  286. if (isNotConstant()) {
  287. assert(getNotConstant() == V && "Marking !constant with different value");
  288. return false;
  289. }
  290. assert(isUnknown());
  291. Tag = notconstant;
  292. ConstVal = V;
  293. return true;
  294. }
  295. /// Mark the object as constant range with \p NewR. If the object is already a
  296. /// constant range, nothing changes if the existing range is equal to \p
  297. /// NewR and the tag. Otherwise \p NewR must be a superset of the existing
  298. /// range or the object must be undef. The tag is set to
  299. /// constant_range_including_undef if either the existing value or the new
  300. /// range may include undef.
  301. bool markConstantRange(ConstantRange NewR,
  302. MergeOptions Opts = MergeOptions()) {
  303. assert(!NewR.isEmptySet() && "should only be called for non-empty sets");
  304. if (NewR.isFullSet())
  305. return markOverdefined();
  306. ValueLatticeElementTy OldTag = Tag;
  307. ValueLatticeElementTy NewTag =
  308. (isUndef() || isConstantRangeIncludingUndef() || Opts.MayIncludeUndef)
  309. ? constantrange_including_undef
  310. : constantrange;
  311. if (isConstantRange()) {
  312. Tag = NewTag;
  313. if (getConstantRange() == NewR)
  314. return Tag != OldTag;
  315. // Simple form of widening. If a range is extended multiple times, go to
  316. // overdefined.
  317. if (Opts.CheckWiden && ++NumRangeExtensions > Opts.MaxWidenSteps)
  318. return markOverdefined();
  319. assert(NewR.contains(getConstantRange()) &&
  320. "Existing range must be a subset of NewR");
  321. Range = std::move(NewR);
  322. return true;
  323. }
  324. assert(isUnknown() || isUndef());
  325. NumRangeExtensions = 0;
  326. Tag = NewTag;
  327. new (&Range) ConstantRange(std::move(NewR));
  328. return true;
  329. }
  330. /// Updates this object to approximate both this object and RHS. Returns
  331. /// true if this object has been changed.
  332. bool mergeIn(const ValueLatticeElement &RHS,
  333. MergeOptions Opts = MergeOptions()) {
  334. if (RHS.isUnknown() || isOverdefined())
  335. return false;
  336. if (RHS.isOverdefined()) {
  337. markOverdefined();
  338. return true;
  339. }
  340. if (isUndef()) {
  341. assert(!RHS.isUnknown());
  342. if (RHS.isUndef())
  343. return false;
  344. if (RHS.isConstant())
  345. return markConstant(RHS.getConstant(), true);
  346. if (RHS.isConstantRange())
  347. return markConstantRange(RHS.getConstantRange(true),
  348. Opts.setMayIncludeUndef());
  349. return markOverdefined();
  350. }
  351. if (isUnknown()) {
  352. assert(!RHS.isUnknown() && "Unknow RHS should be handled earlier");
  353. *this = RHS;
  354. return true;
  355. }
  356. if (isConstant()) {
  357. if (RHS.isConstant() && getConstant() == RHS.getConstant())
  358. return false;
  359. if (RHS.isUndef())
  360. return false;
  361. markOverdefined();
  362. return true;
  363. }
  364. if (isNotConstant()) {
  365. if (RHS.isNotConstant() && getNotConstant() == RHS.getNotConstant())
  366. return false;
  367. markOverdefined();
  368. return true;
  369. }
  370. auto OldTag = Tag;
  371. assert(isConstantRange() && "New ValueLattice type?");
  372. if (RHS.isUndef()) {
  373. Tag = constantrange_including_undef;
  374. return OldTag != Tag;
  375. }
  376. if (!RHS.isConstantRange()) {
  377. // We can get here if we've encountered a constantexpr of integer type
  378. // and merge it with a constantrange.
  379. markOverdefined();
  380. return true;
  381. }
  382. ConstantRange NewR = getConstantRange().unionWith(RHS.getConstantRange());
  383. return markConstantRange(
  384. std::move(NewR),
  385. Opts.setMayIncludeUndef(RHS.isConstantRangeIncludingUndef()));
  386. }
  387. // Compares this symbolic value with Other using Pred and returns either
  388. /// true, false or undef constants, or nullptr if the comparison cannot be
  389. /// evaluated.
  390. Constant *getCompare(CmpInst::Predicate Pred, Type *Ty,
  391. const ValueLatticeElement &Other) const {
  392. if (isUnknownOrUndef() || Other.isUnknownOrUndef())
  393. return UndefValue::get(Ty);
  394. if (isConstant() && Other.isConstant())
  395. return ConstantExpr::getCompare(Pred, getConstant(), Other.getConstant());
  396. if (ICmpInst::isEquality(Pred)) {
  397. // not(C) != C => true, not(C) == C => false.
  398. if ((isNotConstant() && Other.isConstant() &&
  399. getNotConstant() == Other.getConstant()) ||
  400. (isConstant() && Other.isNotConstant() &&
  401. getConstant() == Other.getNotConstant()))
  402. return Pred == ICmpInst::ICMP_NE
  403. ? ConstantInt::getTrue(Ty) : ConstantInt::getFalse(Ty);
  404. }
  405. // Integer constants are represented as ConstantRanges with single
  406. // elements.
  407. if (!isConstantRange() || !Other.isConstantRange())
  408. return nullptr;
  409. const auto &CR = getConstantRange();
  410. const auto &OtherCR = Other.getConstantRange();
  411. if (CR.icmp(Pred, OtherCR))
  412. return ConstantInt::getTrue(Ty);
  413. if (CR.icmp(CmpInst::getInversePredicate(Pred), OtherCR))
  414. return ConstantInt::getFalse(Ty);
  415. return nullptr;
  416. }
  417. unsigned getNumRangeExtensions() const { return NumRangeExtensions; }
  418. void setNumRangeExtensions(unsigned N) { NumRangeExtensions = N; }
  419. };
  420. static_assert(sizeof(ValueLatticeElement) <= 40,
  421. "size of ValueLatticeElement changed unexpectedly");
  422. raw_ostream &operator<<(raw_ostream &OS, const ValueLatticeElement &Val);
  423. } // end namespace llvm
  424. #endif