DataLayout is mandatory, update the API to reflect it with references.
[oota-llvm.git] / include / llvm / Analysis / ScalarEvolution.h
index 304eb3ab47906566af8f5fe6752a3dc1249aa01f..e1d1aa3bfac2c9d6d08f25b28b85d2a2daf8a83e 100644 (file)
@@ -71,8 +71,8 @@ namespace llvm {
     unsigned short SubclassData;
 
   private:
-    SCEV(const SCEV &) LLVM_DELETED_FUNCTION;
-    void operator=(const SCEV &) LLVM_DELETED_FUNCTION;
+    SCEV(const SCEV &) = delete;
+    void operator=(const SCEV &) = delete;
 
   public:
     /// NoWrapFlags are bitfield indices into SubclassData.
@@ -82,12 +82,13 @@ namespace llvm {
     /// operator. NSW is a misnomer that we use to mean no signed overflow or
     /// underflow.
     ///
-    /// AddRec expression may have a no-self-wraparound <NW> property if the
-    /// result can never reach the start value. This property is independent of
-    /// the actual start value and step direction. Self-wraparound is defined
-    /// purely in terms of the recurrence's loop, step size, and
-    /// bitwidth. Formally, a recurrence with no self-wraparound satisfies:
-    /// abs(step) * max-iteration(loop) <= unsigned-max(bitwidth).
+    /// AddRec expressions may have a no-self-wraparound <NW> property if, in
+    /// the integer domain, abs(step) * max-iteration(loop) <=
+    /// unsigned-max(bitwidth).  This means that the recurrence will never reach
+    /// its start value if the step is non-zero.  Computing the same value on
+    /// each iteration is not considered wrapping, and recurrences with step = 0
+    /// are trivially <NW>.  <NW> is independent of the sign of step and the
+    /// value the add recurrence starts with.
     ///
     /// Note that NUW and NSW are also valid properties of a recurrence, and
     /// either implies NW. For convenience, NW will be set for a recurrence
@@ -231,10 +232,6 @@ namespace llvm {
     ///
     LoopInfo *LI;
 
-    /// The DataLayout information for the target we are targeting.
-    ///
-    const DataLayout *DL;
-
     /// TLI - The target library information for the target we are targeting.
     ///
     TargetLibraryInfo *TLI;
@@ -387,32 +384,31 @@ namespace llvm {
     /// computeBlockDisposition - Compute a BlockDisposition value.
     BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB);
 
-    /// UnsignedRanges - Memoized results from getUnsignedRange
+    /// UnsignedRanges - Memoized results from getRange
     DenseMap<const SCEV *, ConstantRange> UnsignedRanges;
 
-    /// SignedRanges - Memoized results from getSignedRange
+    /// SignedRanges - Memoized results from getRange
     DenseMap<const SCEV *, ConstantRange> SignedRanges;
 
-    /// setUnsignedRange - Set the memoized unsigned range for the given SCEV.
-    const ConstantRange &setUnsignedRange(const SCEV *S,
-                                          const ConstantRange &CR) {
-      std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
-        UnsignedRanges.insert(std::make_pair(S, CR));
-      if (!Pair.second)
-        Pair.first->second = CR;
-      return Pair.first->second;
-    }
+    /// RangeSignHint - Used to parameterize getRange
+    enum RangeSignHint { HINT_RANGE_UNSIGNED, HINT_RANGE_SIGNED };
+
+    /// setRange - Set the memoized range for the given SCEV.
+    const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint,
+                                  const ConstantRange &CR) {
+      DenseMap<const SCEV *, ConstantRange> &Cache =
+          Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges;
 
-    /// setUnsignedRange - Set the memoized signed range for the given SCEV.
-    const ConstantRange &setSignedRange(const SCEV *S,
-                                        const ConstantRange &CR) {
       std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
-        SignedRanges.insert(std::make_pair(S, CR));
+          Cache.insert(std::make_pair(S, CR));
       if (!Pair.second)
         Pair.first->second = CR;
       return Pair.first->second;
     }
 
+    /// getRange - Determine the range for a particular SCEV.
+    ConstantRange getRange(const SCEV *S, RangeSignHint Hint);
+
     /// createSCEV - We know that there is no SCEV for the specified value.
     /// Analyze the expression.
     const SCEV *createSCEV(Value *V);
@@ -560,6 +556,15 @@ namespace llvm {
     /// pointer.
     bool checkValidity(const SCEV *S) const;
 
+    // Return true if `ExtendOpTy`({`Start`,+,`Step`}) can be proved to be equal
+    // to {`ExtendOpTy`(`Start`),+,`ExtendOpTy`(`Step`)}.  This is equivalent to
+    // proving no signed (resp. unsigned) wrap in {`Start`,+,`Step`} if
+    // `ExtendOpTy` is `SCEVSignExtendExpr` (resp. `SCEVZeroExtendExpr`).
+    //
+    template<typename ExtendOpTy>
+    bool proveNoWrapByVaryingStart(const SCEV *Start, const SCEV *Step,
+                                   const Loop *L);
+
   public:
     static char ID; // Pass identification, replacement for typeid
     ScalarEvolution();
@@ -833,11 +838,15 @@ namespace llvm {
 
     /// getUnsignedRange - Determine the unsigned range for a particular SCEV.
     ///
-    ConstantRange getUnsignedRange(const SCEV *S);
+    ConstantRange getUnsignedRange(const SCEV *S) {
+      return getRange(S, HINT_RANGE_UNSIGNED);
+    }
 
     /// getSignedRange - Determine the signed range for a particular SCEV.
     ///
-    ConstantRange getSignedRange(const SCEV *S);
+    ConstantRange getSignedRange(const SCEV *S) {
+      return getRange(S, HINT_RANGE_SIGNED);
+    }
 
     /// isKnownNegative - Test if the given expression is known to be negative.
     ///