Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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