1c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===- llvm/Analysis/ScalarEvolution.h - Scalar Evolution -------*- C++ -*-===// 2c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 3c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// The LLVM Compiler Infrastructure 4c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 5c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file is distributed under the University of Illinois Open Source 6c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// License. See LICENSE.TXT for details. 7c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 8c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===// 9c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 10c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// The ScalarEvolution class is an LLVM pass which can be used to analyze and 11c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// categorize scalar expressions in loops. It specializes in recognizing 12c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// general induction variables, representing them with the abstract and opaque 13c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// SCEV class. Given this analysis, trip counts of loops and other important 14c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// properties can be obtained. 15c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 16c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This analysis is primarily useful for induction variable substitution and 17c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// strength reduction. 18c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 19c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===// 20c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 21c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H 22c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#define LLVM_ANALYSIS_SCALAREVOLUTION_H 23c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 24c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/APInt.h" 25c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/ArrayRef.h" 26c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/DenseMap.h" 27c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/DenseMapInfo.h" 28c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/FoldingSet.h" 29c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/Hashing.h" 30c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/Optional.h" 31c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/PointerIntPair.h" 32c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/SetVector.h" 33c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/SmallPtrSet.h" 34c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/SmallVector.h" 35c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Analysis/LoopInfo.h" 36c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/ConstantRange.h" 37c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/Function.h" 38c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/InstrTypes.h" 39c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/Instructions.h" 40c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/Operator.h" 41c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/PassManager.h" 42c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/ValueHandle.h" 43c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/ValueMap.h" 44c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Pass.h" 45c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/Allocator.h" 46c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/Casting.h" 47c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/Compiler.h" 48c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <algorithm> 49c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cassert> 50c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cstdint> 51c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <memory> 52c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <utility> 53c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 54c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotnamespace llvm { 55c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 56c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass AssumptionCache; 57c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass BasicBlock; 58c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass Constant; 59c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ConstantInt; 60c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass DataLayout; 61c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass DominatorTree; 62c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass GEPOperator; 63c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass Instruction; 64c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass LLVMContext; 65c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass raw_ostream; 66c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScalarEvolution; 67c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass SCEVAddRecExpr; 68c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass SCEVUnknown; 69c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass StructType; 70c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass TargetLibraryInfo; 71c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass Type; 72c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass Value; 73c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 74c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This class represents an analyzed expression in the program. These are 75c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// opaque objects that the client is not allowed to do much with directly. 76c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// 77c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass SCEV : public FoldingSetNode { 78c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot friend struct FoldingSetTrait<SCEV>; 79c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 80c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A reference to an Interned FoldingSetNodeID for this node. The 81c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ScalarEvolution's BumpPtrAllocator holds the data. 82c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FoldingSetNodeIDRef FastID; 83c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 84c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // The SCEV baseclass this node corresponds to 85c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const unsigned short SCEVType; 86c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 87c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprotected: 88c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This field is initialized to zero and may be used in subclasses to store 89c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// miscellaneous information. 90c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned short SubclassData = 0; 91c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 92c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 93c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// NoWrapFlags are bitfield indices into SubclassData. 94c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 95c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Add and Mul expressions may have no-unsigned-wrap <NUW> or 96c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// no-signed-wrap <NSW> properties, which are derived from the IR 97c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// operator. NSW is a misnomer that we use to mean no signed overflow or 98c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// underflow. 99c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 100c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// AddRec expressions may have a no-self-wraparound <NW> property if, in 101c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the integer domain, abs(step) * max-iteration(loop) <= 102c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// unsigned-max(bitwidth). This means that the recurrence will never reach 103c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// its start value if the step is non-zero. Computing the same value on 104c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// each iteration is not considered wrapping, and recurrences with step = 0 105c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// are trivially <NW>. <NW> is independent of the sign of step and the 106c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value the add recurrence starts with. 107c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 108c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Note that NUW and NSW are also valid properties of a recurrence, and 109c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// either implies NW. For convenience, NW will be set for a recurrence 110c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whenever either NUW or NSW are set. 111c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot enum NoWrapFlags { 112c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FlagAnyWrap = 0, // No guarantee. 113c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FlagNW = (1 << 0), // No self-wrap. 114c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FlagNUW = (1 << 1), // No unsigned wrap. 115c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FlagNSW = (1 << 2), // No signed wrap. 116c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot NoWrapMask = (1 << 3) - 1 117c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 118c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 119c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) 120c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot : FastID(ID), SCEVType(SCEVTy) {} 121c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV(const SCEV &) = delete; 122c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV &operator=(const SCEV &) = delete; 123c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 124c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned getSCEVType() const { return SCEVType; } 125c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 126c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the LLVM type of this SCEV expression. 127c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Type *getType() const; 128c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 129c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the expression is a constant zero. 130c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isZero() const; 131c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 132c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the expression is a constant one. 133c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isOne() const; 134c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 135c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the expression is a constant all-ones value. 136c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isAllOnesValue() const; 137c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 138c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the specified scev is negated, but not a constant. 139c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isNonConstantNegative() const; 140c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 141c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Print out the internal representation of this scalar to the specified 142c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// stream. This should really only be used for debugging purposes. 143c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void print(raw_ostream &OS) const; 144c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 145c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This method is used for debugging. 146c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void dump() const; 147c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 148c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 149c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// Specialize FoldingSetTrait for SCEV to avoid needing to compute 150c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// temporary FoldingSetNodeID values. 151c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <> struct FoldingSetTrait<SCEV> : DefaultFoldingSetTrait<SCEV> { 152c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static void Profile(const SCEV &X, FoldingSetNodeID &ID) { ID = X.FastID; } 153c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 154c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static bool Equals(const SCEV &X, const FoldingSetNodeID &ID, unsigned IDHash, 155c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FoldingSetNodeID &TempID) { 156c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return ID == X.FastID; 157c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 158c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 159c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) { 160c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return X.FastID.ComputeHash(); 161c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 162c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 163c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 164c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotinline raw_ostream &operator<<(raw_ostream &OS, const SCEV &S) { 165c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot S.print(OS); 166c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return OS; 167c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} 168c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 169c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// An object of this class is returned by queries that could not be answered. 170c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// For example, if you ask for the number of iterations of a linked-list 171c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// traversal loop, you will get one of these. None of the standard SCEV 172c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// operations are valid on this class, it is just a marker. 173c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotstruct SCEVCouldNotCompute : public SCEV { 174c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVCouldNotCompute(); 175c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 176c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Methods for support type inquiry through isa, cast, and dyn_cast: 177c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static bool classof(const SCEV *S); 178c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 179c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 180c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This class represents an assumption made using SCEV expressions which can 181c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// be checked at run-time. 182c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass SCEVPredicate : public FoldingSetNode { 183c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot friend struct FoldingSetTrait<SCEVPredicate>; 184c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 185c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A reference to an Interned FoldingSetNodeID for this node. The 186c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ScalarEvolution's BumpPtrAllocator holds the data. 187c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FoldingSetNodeIDRef FastID; 188c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 189c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 190c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot enum SCEVPredicateKind { P_Union, P_Equal, P_Wrap }; 191c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 192c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprotected: 193c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVPredicateKind Kind; 194c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ~SCEVPredicate() = default; 195c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVPredicate(const SCEVPredicate &) = default; 196c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVPredicate &operator=(const SCEVPredicate &) = default; 197c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 198c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 199c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVPredicate(const FoldingSetNodeIDRef ID, SCEVPredicateKind Kind); 200c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 201c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVPredicateKind getKind() const { return Kind; } 202c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 203c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the estimated complexity of this predicate. This is roughly 204c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// measured in the number of run-time checks required. 205c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot virtual unsigned getComplexity() const { return 1; } 206c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 207c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns true if the predicate is always true. This means that no 208c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// assumptions were made and nothing needs to be checked at run-time. 209c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot virtual bool isAlwaysTrue() const = 0; 210c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 211c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns true if this predicate implies \p N. 212c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot virtual bool implies(const SCEVPredicate *N) const = 0; 213c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 214c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Prints a textual representation of this predicate with an indentation of 215c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \p Depth. 216c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot virtual void print(raw_ostream &OS, unsigned Depth = 0) const = 0; 217c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 218c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the SCEV to which this predicate applies, or nullptr if this is 219c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// a SCEVUnionPredicate. 220c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot virtual const SCEV *getExpr() const = 0; 221c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 222c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 223c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotinline raw_ostream &operator<<(raw_ostream &OS, const SCEVPredicate &P) { 224c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot P.print(OS); 225c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return OS; 226c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} 227c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 228c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// Specialize FoldingSetTrait for SCEVPredicate to avoid needing to compute 229c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// temporary FoldingSetNodeID values. 230c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <> 231c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotstruct FoldingSetTrait<SCEVPredicate> : DefaultFoldingSetTrait<SCEVPredicate> { 232c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static void Profile(const SCEVPredicate &X, FoldingSetNodeID &ID) { 233c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ID = X.FastID; 234c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 235c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 236c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static bool Equals(const SCEVPredicate &X, const FoldingSetNodeID &ID, 237c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned IDHash, FoldingSetNodeID &TempID) { 238c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return ID == X.FastID; 239c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 240c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 241c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static unsigned ComputeHash(const SCEVPredicate &X, 242c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FoldingSetNodeID &TempID) { 243c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return X.FastID.ComputeHash(); 244c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 245c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 246c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 247c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This class represents an assumption that two SCEV expressions are equal, 248c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// and this can be checked at run-time. 249c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass SCEVEqualPredicate final : public SCEVPredicate { 250c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// We assume that LHS == RHS. 251c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *LHS; 252c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS; 253c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 254c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 255c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVEqualPredicate(const FoldingSetNodeIDRef ID, const SCEV *LHS, 256c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS); 257c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 258c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Implementation of the SCEVPredicate interface 259c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool implies(const SCEVPredicate *N) const override; 260c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void print(raw_ostream &OS, unsigned Depth = 0) const override; 261c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isAlwaysTrue() const override; 262c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getExpr() const override; 263c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 264c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the left hand side of the equality. 265c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getLHS() const { return LHS; } 266c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 267c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the right hand side of the equality. 268c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getRHS() const { return RHS; } 269c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 270c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Methods for support type inquiry through isa, cast, and dyn_cast: 271c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static bool classof(const SCEVPredicate *P) { 272c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return P->getKind() == P_Equal; 273c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 274c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 275c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 276c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This class represents an assumption made on an AddRec expression. Given an 277c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// affine AddRec expression {a,+,b}, we assume that it has the nssw or nusw 278c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// flags (defined below) in the first X iterations of the loop, where X is a 279c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// SCEV expression returned by getPredicatedBackedgeTakenCount). 280c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// 281c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Note that this does not imply that X is equal to the backedge taken 282c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// count. This means that if we have a nusw predicate for i32 {0,+,1} with a 283c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// predicated backedge taken count of X, we only guarantee that {0,+,1} has 284c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// nusw in the first X iterations. {0,+,1} may still wrap in the loop if we 285c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// have more than X iterations. 286c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass SCEVWrapPredicate final : public SCEVPredicate { 287c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 288c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Similar to SCEV::NoWrapFlags, but with slightly different semantics 289c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// for FlagNUSW. The increment is considered to be signed, and a + b 290c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// (where b is the increment) is considered to wrap if: 291c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// zext(a + b) != zext(a) + sext(b) 292c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 293c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If Signed is a function that takes an n-bit tuple and maps to the 294c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// integer domain as the tuples value interpreted as twos complement, 295c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// and Unsigned a function that takes an n-bit tuple and maps to the 296c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// integer domain as as the base two value of input tuple, then a + b 297c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// has IncrementNUSW iff: 298c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 299c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 0 <= Unsigned(a) + Signed(b) < 2^n 300c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 301c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The IncrementNSSW flag has identical semantics with SCEV::FlagNSW. 302c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 303c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Note that the IncrementNUSW flag is not commutative: if base + inc 304c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// has IncrementNUSW, then inc + base doesn't neccessarily have this 305c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// property. The reason for this is that this is used for sign/zero 306c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// extending affine AddRec SCEV expressions when a SCEVWrapPredicate is 307c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// assumed. A {base,+,inc} expression is already non-commutative with 308c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// regards to base and inc, since it is interpreted as: 309c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// (((base + inc) + inc) + inc) ... 310c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot enum IncrementWrapFlags { 311c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot IncrementAnyWrap = 0, // No guarantee. 312c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot IncrementNUSW = (1 << 0), // No unsigned with signed increment wrap. 313c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot IncrementNSSW = (1 << 1), // No signed with signed increment wrap 314c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // (equivalent with SCEV::NSW) 315c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot IncrementNoWrapMask = (1 << 2) - 1 316c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 317c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 318c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Convenient IncrementWrapFlags manipulation methods. 319c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LLVM_NODISCARD static SCEVWrapPredicate::IncrementWrapFlags 320c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot clearFlags(SCEVWrapPredicate::IncrementWrapFlags Flags, 321c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVWrapPredicate::IncrementWrapFlags OffFlags) { 322c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert((Flags & IncrementNoWrapMask) == Flags && "Invalid flags value!"); 323c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert((OffFlags & IncrementNoWrapMask) == OffFlags && 324c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot "Invalid flags value!"); 325c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return (SCEVWrapPredicate::IncrementWrapFlags)(Flags & ~OffFlags); 326c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 327c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 328c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LLVM_NODISCARD static SCEVWrapPredicate::IncrementWrapFlags 329c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot maskFlags(SCEVWrapPredicate::IncrementWrapFlags Flags, int Mask) { 330c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert((Flags & IncrementNoWrapMask) == Flags && "Invalid flags value!"); 331c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert((Mask & IncrementNoWrapMask) == Mask && "Invalid mask value!"); 332c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 333c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return (SCEVWrapPredicate::IncrementWrapFlags)(Flags & Mask); 334c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 335c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 336c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LLVM_NODISCARD static SCEVWrapPredicate::IncrementWrapFlags 337c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot setFlags(SCEVWrapPredicate::IncrementWrapFlags Flags, 338c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVWrapPredicate::IncrementWrapFlags OnFlags) { 339c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert((Flags & IncrementNoWrapMask) == Flags && "Invalid flags value!"); 340c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert((OnFlags & IncrementNoWrapMask) == OnFlags && 341c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot "Invalid flags value!"); 342c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 343c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return (SCEVWrapPredicate::IncrementWrapFlags)(Flags | OnFlags); 344c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 345c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 346c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the set of SCEVWrapPredicate no wrap flags implied by a 347c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEVAddRecExpr. 348c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LLVM_NODISCARD static SCEVWrapPredicate::IncrementWrapFlags 349c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot getImpliedFlags(const SCEVAddRecExpr *AR, ScalarEvolution &SE); 350c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 351c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate: 352c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEVAddRecExpr *AR; 353c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot IncrementWrapFlags Flags; 354c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 355c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 356c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot explicit SCEVWrapPredicate(const FoldingSetNodeIDRef ID, 357c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEVAddRecExpr *AR, 358c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot IncrementWrapFlags Flags); 359c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 360c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the set assumed no overflow flags. 361c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot IncrementWrapFlags getFlags() const { return Flags; } 362c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 363c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Implementation of the SCEVPredicate interface 364c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getExpr() const override; 365c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool implies(const SCEVPredicate *N) const override; 366c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void print(raw_ostream &OS, unsigned Depth = 0) const override; 367c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isAlwaysTrue() const override; 368c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 369c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Methods for support type inquiry through isa, cast, and dyn_cast: 370c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static bool classof(const SCEVPredicate *P) { 371c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return P->getKind() == P_Wrap; 372c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 373c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 374c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 375c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This class represents a composition of other SCEV predicates, and is the 376c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// class that most clients will interact with. This is equivalent to a 377c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// logical "AND" of all the predicates in the union. 378c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// 379c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// NB! Unlike other SCEVPredicate sub-classes this class does not live in the 380c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// ScalarEvolution::Preds folding set. This is why the \c add function is sound. 381c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass SCEVUnionPredicate final : public SCEVPredicate { 382c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate: 383c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using PredicateMap = 384c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const SCEV *, SmallVector<const SCEVPredicate *, 4>>; 385c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 386c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Vector with references to all predicates in this union. 387c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<const SCEVPredicate *, 16> Preds; 388c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 389c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Maps SCEVs to predicates for quick look-ups. 390c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot PredicateMap SCEVToPreds; 391c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 392c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 393c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVUnionPredicate(); 394c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 395c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SmallVectorImpl<const SCEVPredicate *> &getPredicates() const { 396c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return Preds; 397c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 398c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 399c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Adds a predicate to this union. 400c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void add(const SCEVPredicate *N); 401c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 402c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns a reference to a vector containing all predicates which apply to 403c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \p Expr. 404c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ArrayRef<const SCEVPredicate *> getPredicatesForExpr(const SCEV *Expr); 405c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 406c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Implementation of the SCEVPredicate interface 407c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isAlwaysTrue() const override; 408c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool implies(const SCEVPredicate *N) const override; 409c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void print(raw_ostream &OS, unsigned Depth) const override; 410c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getExpr() const override; 411c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 412c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// We estimate the complexity of a union predicate as the size number of 413c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// predicates in the union. 414c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned getComplexity() const override { return Preds.size(); } 415c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 416c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Methods for support type inquiry through isa, cast, and dyn_cast: 417c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static bool classof(const SCEVPredicate *P) { 418c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return P->getKind() == P_Union; 419c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 420c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 421c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 422c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotstruct ExitLimitQuery { 423c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimitQuery(const Loop *L, BasicBlock *ExitingBlock, bool AllowPredicates) 424c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot : L(L), ExitingBlock(ExitingBlock), AllowPredicates(AllowPredicates) {} 425c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 426c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop *L; 427c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *ExitingBlock; 428c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates; 429c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 430c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 431c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robottemplate <> struct DenseMapInfo<ExitLimitQuery> { 432c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static inline ExitLimitQuery getEmptyKey() { 433c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return ExitLimitQuery(nullptr, nullptr, true); 434c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 435c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 436c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static inline ExitLimitQuery getTombstoneKey() { 437c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return ExitLimitQuery(nullptr, nullptr, false); 438c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 439c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 440c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static unsigned getHashValue(ExitLimitQuery Val) { 441c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return hash_combine(hash_combine(Val.L, Val.ExitingBlock), 442c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Val.AllowPredicates); 443c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 444c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 445c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static bool isEqual(ExitLimitQuery LHS, ExitLimitQuery RHS) { 446c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return LHS.L == RHS.L && LHS.ExitingBlock == RHS.ExitingBlock && 447c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LHS.AllowPredicates == RHS.AllowPredicates; 448c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 449c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 450c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 451c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// The main scalar evolution driver. Because client code (intentionally) 452c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// can't do much with the SCEV objects directly, they must ask this class 453c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// for services. 454c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScalarEvolution { 455c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 456c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// An enum describing the relationship between a SCEV and a loop. 457c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot enum LoopDisposition { 458c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LoopVariant, ///< The SCEV is loop-variant (unknown). 459c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LoopInvariant, ///< The SCEV is loop-invariant. 460c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LoopComputable ///< The SCEV varies predictably with the loop. 461c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 462c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 463c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// An enum describing the relationship between a SCEV and a basic block. 464c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot enum BlockDisposition { 465c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DoesNotDominateBlock, ///< The SCEV does not dominate the block. 466c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DominatesBlock, ///< The SCEV dominates the block. 467c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ProperlyDominatesBlock ///< The SCEV properly dominates the block. 468c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 469c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 470c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Convenient NoWrapFlags manipulation that hides enum casts and is 471c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// visible in the ScalarEvolution name space. 472c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LLVM_NODISCARD static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags, 473c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot int Mask) { 474c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return (SCEV::NoWrapFlags)(Flags & Mask); 475c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 476c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LLVM_NODISCARD static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags, 477c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags OnFlags) { 478c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return (SCEV::NoWrapFlags)(Flags | OnFlags); 479c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 480c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LLVM_NODISCARD static SCEV::NoWrapFlags 481c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot clearFlags(SCEV::NoWrapFlags Flags, SCEV::NoWrapFlags OffFlags) { 482c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return (SCEV::NoWrapFlags)(Flags & ~OffFlags); 483c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 484c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 485c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScalarEvolution(Function &F, TargetLibraryInfo &TLI, AssumptionCache &AC, 486c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DominatorTree &DT, LoopInfo &LI); 487c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScalarEvolution(ScalarEvolution &&Arg); 488c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ~ScalarEvolution(); 489c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 490c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LLVMContext &getContext() const { return F.getContext(); } 491c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 492c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test if values of the given type are analyzable within the SCEV 493c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// framework. This primarily includes integer types, and it can optionally 494c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// include pointer types if the ScalarEvolution class has access to 495c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// target-specific information. 496c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isSCEVable(Type *Ty) const; 497c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 498c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the size in bits of the specified type, for which isSCEVable must 499c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// return true. 500c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot uint64_t getTypeSizeInBits(Type *Ty) const; 501c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 502c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a type with the same bitwidth as the given type and which 503c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// represents how SCEV will treat the given type, for which isSCEVable must 504c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// return true. For pointer types, this is the pointer-sized integer type. 505c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Type *getEffectiveSCEVType(Type *Ty) const; 506c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 507c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Returns a wider type among {Ty1, Ty2}. 508c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Type *getWiderType(Type *Ty1, Type *Ty2) const; 509c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 510c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the SCEV is a scAddRecExpr or it contains 511c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// scAddRecExpr. The result will be cached in HasRecMap. 512c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool containsAddRecurrence(const SCEV *S); 513c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 514c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Erase Value from ValueExprMap and ExprValueMap. 515c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void eraseValueFromMap(Value *V); 516c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 517c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV expression for the full generality of the specified 518c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// expression. 519c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSCEV(Value *V); 520c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 521c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getConstant(ConstantInt *V); 522c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getConstant(const APInt &Val); 523c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false); 524c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty); 525c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); 526c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); 527c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty); 528c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops, 529c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, 530c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Depth = 0); 531c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS, 532c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, 533c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Depth = 0) { 534c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<const SCEV *, 2> Ops = {LHS, RHS}; 535c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getAddExpr(Ops, Flags, Depth); 536c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 537c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, 538c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, 539c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Depth = 0) { 540c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2}; 541c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getAddExpr(Ops, Flags, Depth); 542c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 543c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops, 544c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, 545c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Depth = 0); 546c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS, 547c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, 548c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Depth = 0) { 549c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<const SCEV *, 2> Ops = {LHS, RHS}; 550c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getMulExpr(Ops, Flags, Depth); 551c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 552c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, 553c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, 554c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Depth = 0) { 555c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2}; 556c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getMulExpr(Ops, Flags, Depth); 557c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 558c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS); 559c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getUDivExactExpr(const SCEV *LHS, const SCEV *RHS); 560c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getURemExpr(const SCEV *LHS, const SCEV *RHS); 561c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step, const Loop *L, 562c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags); 563c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands, 564c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop *L, SCEV::NoWrapFlags Flags); 565c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getAddRecExpr(const SmallVectorImpl<const SCEV *> &Operands, 566c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop *L, SCEV::NoWrapFlags Flags) { 567c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end()); 568c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getAddRecExpr(NewOp, L, Flags); 569c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 570c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 571c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Checks if \p SymbolicPHI can be rewritten as an AddRecExpr under some 572c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Predicates. If successful return these <AddRecExpr, Predicates>; 573c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The function is intended to be called from PSCEV (the caller will decide 574c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whether to actually add the predicates and carry out the rewrites). 575c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Optional<std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>> 576c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot createAddRecFromPHIWithCasts(const SCEVUnknown *SymbolicPHI); 577c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 578c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns an expression for a GEP 579c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 580c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \p GEP The GEP. The indices contained in the GEP itself are ignored, 581c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// instead we use IndexExprs. 582c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \p IndexExprs The expressions for the indices. 583c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getGEPExpr(GEPOperator *GEP, 584c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SmallVectorImpl<const SCEV *> &IndexExprs); 585c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS); 586c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands); 587c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getUMaxExpr(const SCEV *LHS, const SCEV *RHS); 588c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getUMaxExpr(SmallVectorImpl<const SCEV *> &Operands); 589c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS); 590c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS); 591c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getUnknown(Value *V); 592c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getCouldNotCompute(); 593c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 594c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV for the constant 0 of a specific type. 595c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getZero(Type *Ty) { return getConstant(Ty, 0); } 596c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 597c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV for the constant 1 of a specific type. 598c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getOne(Type *Ty) { return getConstant(Ty, 1); } 599c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 600c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return an expression for sizeof AllocTy that is type IntTy 601c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSizeOfExpr(Type *IntTy, Type *AllocTy); 602c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 603c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return an expression for offsetof on the given field with type IntTy 604c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getOffsetOfExpr(Type *IntTy, StructType *STy, unsigned FieldNo); 605c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 606c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the SCEV object corresponding to -V. 607c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getNegativeSCEV(const SCEV *V, 608c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); 609c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 610c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the SCEV object corresponding to ~V. 611c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getNotSCEV(const SCEV *V); 612c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 613c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return LHS-RHS. Minus is represented in SCEV as A+B*-1. 614c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS, 615c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, 616c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Depth = 0); 617c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 618c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV corresponding to a conversion of the input value to the 619c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified type. If the type must be extended, it is zero extended. 620c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty); 621c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 622c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV corresponding to a conversion of the input value to the 623c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified type. If the type must be extended, it is sign extended. 624c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty); 625c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 626c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV corresponding to a conversion of the input value to the 627c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified type. If the type must be extended, it is zero extended. The 628c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// conversion must not be narrowing. 629c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getNoopOrZeroExtend(const SCEV *V, Type *Ty); 630c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 631c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV corresponding to a conversion of the input value to the 632c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified type. If the type must be extended, it is sign extended. The 633c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// conversion must not be narrowing. 634c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getNoopOrSignExtend(const SCEV *V, Type *Ty); 635c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 636c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV corresponding to a conversion of the input value to the 637c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified type. If the type must be extended, it is extended with 638c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// unspecified bits. The conversion must not be narrowing. 639c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getNoopOrAnyExtend(const SCEV *V, Type *Ty); 640c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 641c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV corresponding to a conversion of the input value to the 642c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified type. The conversion must not be widening. 643c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getTruncateOrNoop(const SCEV *V, Type *Ty); 644c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 645c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Promote the operands to the wider of the types using zero-extension, and 646c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// then perform a umax operation with them. 647c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getUMaxFromMismatchedTypes(const SCEV *LHS, const SCEV *RHS); 648c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 649c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Promote the operands to the wider of the types using zero-extension, and 650c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// then perform a umin operation with them. 651c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS, const SCEV *RHS); 652c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 653c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Transitively follow the chain of pointer-type operands until reaching a 654c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV that does not have a single pointer operand. This returns a 655c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEVUnknown pointer for well-formed pointer-type expressions, but corner 656c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// cases do exist. 657c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getPointerBase(const SCEV *V); 658c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 659c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a SCEV expression for the specified value at the specified scope 660c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// in the program. The L value specifies a loop nest to evaluate the 661c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// expression at, where null is the top-level or a specified loop is 662c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// immediately inside of the loop. 663c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 664c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This method can be used to compute the exit value for a variable defined 665c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// in a loop by querying what the value will hold in the parent loop. 666c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 667c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// In the case that a relevant loop exit value cannot be computed, the 668c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// original value V is returned. 669c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSCEVAtScope(const SCEV *S, const Loop *L); 670c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 671c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This is a convenience function which does getSCEVAtScope(getSCEV(V), L). 672c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSCEVAtScope(Value *V, const Loop *L); 673c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 674c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether entry to the loop is protected by a conditional between LHS 675c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// and RHS. This is used to help avoid max expressions in loop trip 676c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// counts, and to eliminate casts. 677c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, 678c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *LHS, const SCEV *RHS); 679c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 680c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the backedge of the loop is protected by a conditional 681c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// between LHS and RHS. This is used to to eliminate casts. 682c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, 683c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *LHS, const SCEV *RHS); 684c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 685c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the maximum trip count of the loop if it is a single-exit 686c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop and we can compute a small maximum for that loop. 687c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 688c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Implemented in terms of the \c getSmallConstantTripCount overload with 689c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the single exiting block passed to it. See that routine for details. 690c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned getSmallConstantTripCount(const Loop *L); 691c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 692c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the maximum trip count of this loop as a normal unsigned 693c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value. Returns 0 if the trip count is unknown or not constant. This 694c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// "trip count" assumes that control exits via ExitingBlock. More 695c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// precisely, it is the number of times that control may reach ExitingBlock 696c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// before taking the branch. For loops with multiple exits, it may not be 697c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the number times that the loop header executes if the loop exits 698c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// prematurely via another branch. 699c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned getSmallConstantTripCount(const Loop *L, BasicBlock *ExitingBlock); 700c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 701c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the upper bound of the loop trip count as a normal unsigned 702c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value. 703c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns 0 if the trip count is unknown or not constant. 704c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned getSmallConstantMaxTripCount(const Loop *L); 705c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 706c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the largest constant divisor of the trip count of the 707c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop if it is a single-exit loop and we can compute a small maximum for 708c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// that loop. 709c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 710c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Implemented in terms of the \c getSmallConstantTripMultiple overload with 711c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the single exiting block passed to it. See that routine for details. 712c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned getSmallConstantTripMultiple(const Loop *L); 713c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 714c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the largest constant divisor of the trip count of this loop as a 715c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// normal unsigned value, if possible. This means that the actual trip 716c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// count is always a multiple of the returned value (don't forget the trip 717c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// count could very well be zero as well!). As explained in the comments 718c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// for getSmallConstantTripCount, this assumes that control exits the loop 719c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// via ExitingBlock. 720c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned getSmallConstantTripMultiple(const Loop *L, 721c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *ExitingBlock); 722c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 723c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Get the expression for the number of loop iterations for which this loop 724c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// is guaranteed not to exit via ExitingBlock. Otherwise return 725c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEVCouldNotCompute. 726c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getExitCount(const Loop *L, BasicBlock *ExitingBlock); 727c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 728c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If the specified loop has a predictable backedge-taken count, return it, 729c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// otherwise return a SCEVCouldNotCompute object. The backedge-taken count is 730c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the number of times the loop header will be branched to from within the 731c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop, assuming there are no abnormal exists like exception throws. This is 732c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// one less than the trip count of the loop, since it doesn't count the first 733c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// iteration, when the header is branched to from outside the loop. 734c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 735c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Note that it is not valid to call this method on a loop without a 736c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop-invariant backedge-taken count (see 737c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// hasLoopInvariantBackedgeTakenCount). 738c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getBackedgeTakenCount(const Loop *L); 739c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 740c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Similar to getBackedgeTakenCount, except it will add a set of 741c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV predicates to Predicates that are required to be true in order for 742c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the answer to be correct. Predicates can be checked with run-time 743c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// checks and can be used to perform loop versioning. 744c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getPredicatedBackedgeTakenCount(const Loop *L, 745c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVUnionPredicate &Predicates); 746c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 747c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// When successful, this returns a SCEVConstant that is greater than or equal 748c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// to (i.e. a "conservative over-approximation") of the value returend by 749c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// getBackedgeTakenCount. If such a value cannot be computed, it returns the 750c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEVCouldNotCompute object. 751c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getMaxBackedgeTakenCount(const Loop *L); 752c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 753c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the backedge taken count is either the value returned by 754c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// getMaxBackedgeTakenCount or zero. 755c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isBackedgeTakenCountMaxOrZero(const Loop *L); 756c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 757c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the specified loop has an analyzable loop-invariant 758c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// backedge-taken count. 759c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasLoopInvariantBackedgeTakenCount(const Loop *L); 760c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 761c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This method should be called by the client when it has changed a loop in 762c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// a way that may effect ScalarEvolution's ability to compute a trip count, 763c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// or if the loop is deleted. This call is potentially expensive for large 764c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop bodies. 765c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void forgetLoop(const Loop *L); 766c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 767c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This method should be called by the client when it has changed a value 768c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// in a way that may effect its value, or which may disconnect it from a 769c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// def-use chain linking it to a loop. 770c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void forgetValue(Value *V); 771c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 772c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Called when the client has changed the disposition of values in 773c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// this loop. 774c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 775c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// We don't have a way to invalidate per-loop dispositions. Clear and 776c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// recompute is simpler. 777c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void forgetLoopDispositions(const Loop *L) { LoopDispositions.clear(); } 778c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 779c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine the minimum number of zero bits that S is guaranteed to end in 780c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// (at every loop iteration). It is, at the same time, the minimum number 781c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// of times S is divisible by 2. For example, given {4,+,8} it returns 2. 782c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If S is guaranteed to be 0, it returns the bitwidth of S. 783c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot uint32_t GetMinTrailingZeros(const SCEV *S); 784c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 785c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine the unsigned range for a particular SCEV. 786c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// NOTE: This returns a copy of the reference returned by getRangeRef. 787c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange getUnsignedRange(const SCEV *S) { 788c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getRangeRef(S, HINT_RANGE_UNSIGNED); 789c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 790c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 791c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine the min of the unsigned range for a particular SCEV. 792c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getUnsignedRangeMin(const SCEV *S) { 793c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getRangeRef(S, HINT_RANGE_UNSIGNED).getUnsignedMin(); 794c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 795c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 796c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine the max of the unsigned range for a particular SCEV. 797c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getUnsignedRangeMax(const SCEV *S) { 798c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getRangeRef(S, HINT_RANGE_UNSIGNED).getUnsignedMax(); 799c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 800c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 801c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine the signed range for a particular SCEV. 802c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// NOTE: This returns a copy of the reference returned by getRangeRef. 803c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange getSignedRange(const SCEV *S) { 804c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getRangeRef(S, HINT_RANGE_SIGNED); 805c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 806c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 807c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine the min of the signed range for a particular SCEV. 808c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getSignedRangeMin(const SCEV *S) { 809c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getRangeRef(S, HINT_RANGE_SIGNED).getSignedMin(); 810c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 811c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 812c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine the max of the signed range for a particular SCEV. 813c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getSignedRangeMax(const SCEV *S) { 814c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getRangeRef(S, HINT_RANGE_SIGNED).getSignedMax(); 815c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 816c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 817c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test if the given expression is known to be negative. 818c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownNegative(const SCEV *S); 819c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 820c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test if the given expression is known to be positive. 821c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownPositive(const SCEV *S); 822c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 823c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test if the given expression is known to be non-negative. 824c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownNonNegative(const SCEV *S); 825c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 826c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test if the given expression is known to be non-positive. 827c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownNonPositive(const SCEV *S); 828c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 829c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test if the given expression is known to be non-zero. 830c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownNonZero(const SCEV *S); 831c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 832c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test if the given expression is known to satisfy the condition described 833c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// by Pred, LHS, and RHS. 834c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, 835c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS); 836c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 837c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if, for all loop invariant X, the predicate "LHS `Pred` X" 838c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// is monotonically increasing or decreasing. In the former case set 839c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// `Increasing` to true and in the latter case set `Increasing` to false. 840c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 841c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A predicate is said to be monotonically increasing if may go from being 842c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// false to being true as the loop iterates, but never the other way 843c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// around. A predicate is said to be monotonically decreasing if may go 844c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from being true to being false as the loop iterates, but never the other 845c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// way around. 846c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isMonotonicPredicate(const SCEVAddRecExpr *LHS, ICmpInst::Predicate Pred, 847c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool &Increasing); 848c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 849c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the result of the predicate LHS `Pred` RHS is loop 850c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// invariant with respect to L. Set InvariantPred, InvariantLHS and 851c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// InvariantLHS so that InvariantLHS `InvariantPred` InvariantRHS is the 852c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop invariant form of LHS `Pred` RHS. 853c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isLoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, 854c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS, const Loop *L, 855c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ICmpInst::Predicate &InvariantPred, 856c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *&InvariantLHS, 857c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *&InvariantRHS); 858c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 859c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Simplify LHS and RHS in a comparison with predicate Pred. Return true 860c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// iff any changes were made. If the operands are provably equal or 861c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// unequal, LHS and RHS are set to the same value and Pred is set to either 862c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ICMP_EQ or ICMP_NE. 863c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, const SCEV *&LHS, 864c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *&RHS, unsigned Depth = 0); 865c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 866c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the "disposition" of the given SCEV with respect to the given 867c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop. 868c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L); 869c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 870c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the value of the given SCEV is unchanging in the 871c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified loop. 872c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isLoopInvariant(const SCEV *S, const Loop *L); 873c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 874c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine if the SCEV can be evaluated at loop's entry. It is true if it 875c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// doesn't depend on a SCEVUnknown of an instruction which is dominated by 876c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the header of loop L. 877c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isAvailableAtLoopEntry(const SCEV *S, const Loop *L); 878c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 879c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the given SCEV changes value in a known way in the 880c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified loop. This property being true implies that the value is 881c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// variant in the loop AND that we can emit an expression to compute the 882c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value of the expression at any particular loop iteration. 883c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasComputableLoopEvolution(const SCEV *S, const Loop *L); 884c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 885c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the "disposition" of the given SCEV with respect to the given 886c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// block. 887c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BlockDisposition getBlockDisposition(const SCEV *S, const BasicBlock *BB); 888c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 889c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if elements that makes up the given SCEV dominate the 890c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// specified basic block. 891c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool dominates(const SCEV *S, const BasicBlock *BB); 892c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 893c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if elements that makes up the given SCEV properly dominate 894c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the specified basic block. 895c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool properlyDominates(const SCEV *S, const BasicBlock *BB); 896c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 897c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the given SCEV has Op as a direct or indirect operand. 898c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasOperand(const SCEV *S, const SCEV *Op) const; 899c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 900c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the size of an element read or written by Inst. 901c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getElementSize(Instruction *Inst); 902c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 903c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the array dimensions Sizes from the set of Terms extracted from 904c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the memory access function of this SCEVAddRecExpr (second step of 905c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// delinearization). 906c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void findArrayDimensions(SmallVectorImpl<const SCEV *> &Terms, 907c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVectorImpl<const SCEV *> &Sizes, 908c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *ElementSize); 909c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 910c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void print(raw_ostream &OS) const; 911c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void verify() const; 912c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool invalidate(Function &F, const PreservedAnalyses &PA, 913c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FunctionAnalysisManager::Invalidator &Inv); 914c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 915c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Collect parametric terms occurring in step expressions (first step of 916c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// delinearization). 917c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void collectParametricTerms(const SCEV *Expr, 918c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVectorImpl<const SCEV *> &Terms); 919c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 920c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return in Subscripts the access functions for each dimension in Sizes 921c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// (third step of delinearization). 922c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void computeAccessFunctions(const SCEV *Expr, 923c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVectorImpl<const SCEV *> &Subscripts, 924c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVectorImpl<const SCEV *> &Sizes); 925c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 926c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Split this SCEVAddRecExpr into two vectors of SCEVs representing the 927c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// subscripts and sizes of an array access. 928c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 929c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The delinearization is a 3 step process: the first two steps compute the 930c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// sizes of each subscript and the third step computes the access functions 931c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// for the delinearized array: 932c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 933c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1. Find the terms in the step functions 934c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 2. Compute the array size 935c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 3. Compute the access function: divide the SCEV by the array size 936c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// starting with the innermost dimensions found in step 2. The Quotient 937c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// is the SCEV to be divided in the next step of the recursion. The 938c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Remainder is the subscript of the innermost dimension. Loop over all 939c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// array dimensions computed in step 2. 940c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 941c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// To compute a uniform array size for several memory accesses to the same 942c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// object, one can collect in step 1 all the step terms for all the memory 943c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// accesses, and compute in step 2 a unique array shape. This guarantees 944c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// that the array shape will be the same across all memory accesses. 945c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 946c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// FIXME: We could derive the result of steps 1 and 2 from a description of 947c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the array shape given in metadata. 948c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 949c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Example: 950c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 951c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A[][n][m] 952c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 953c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// for i 954c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// for j 955c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// for k 956c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A[j+k][2i][5i] = 957c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 958c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The initial SCEV: 959c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 960c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A[{{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k] 961c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 962c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1. Find the different terms in the step functions: 963c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// -> [2*m, 5, n*m, n*m] 964c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 965c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 2. Compute the array size: sort and unique them 966c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// -> [n*m, 2*m, 5] 967c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// find the GCD of all the terms = 1 968c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// divide by the GCD and erase constant terms 969c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// -> [n*m, 2*m] 970c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// GCD = m 971c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// divide by GCD -> [n, 2] 972c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// remove constant terms 973c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// -> [n] 974c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// size of the array is A[unknown][n][m] 975c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 976c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 3. Compute the access function 977c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// a. Divide {{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k by the innermost size m 978c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k 979c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Remainder: {{{0,+,5}_i, +, 0}_j, +, 0}_k 980c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The remainder is the subscript of the innermost array dimension: [5i]. 981c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 982c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// b. Divide Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k by next outer size n 983c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Quotient: {{{0,+,0}_i, +, 1}_j, +, 1}_k 984c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Remainder: {{{0,+,2}_i, +, 0}_j, +, 0}_k 985c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The Remainder is the subscript of the next array dimension: [2i]. 986c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 987c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The subscript of the outermost dimension is the Quotient: [j+k]. 988c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 989c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Overall, we have: A[][n][m], and the access function: A[j+k][2i][5i]. 990c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void delinearize(const SCEV *Expr, SmallVectorImpl<const SCEV *> &Subscripts, 991c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVectorImpl<const SCEV *> &Sizes, 992c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *ElementSize); 993c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 994c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the DataLayout associated with the module this SCEV instance is 995c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// operating on. 996c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const DataLayout &getDataLayout() const { 997c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return F.getParent()->getDataLayout(); 998c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 999c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1000c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEVPredicate *getEqualPredicate(const SCEV *LHS, const SCEV *RHS); 1001c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1002c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEVPredicate * 1003c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot getWrapPredicate(const SCEVAddRecExpr *AR, 1004c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVWrapPredicate::IncrementWrapFlags AddedFlags); 1005c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1006c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Re-writes the SCEV according to the Predicates in \p A. 1007c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *rewriteUsingPredicate(const SCEV *S, const Loop *L, 1008c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVUnionPredicate &A); 1009c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Tries to convert the \p S expression to an AddRec expression, 1010c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// adding additional predicates to \p Preds as required. 1011c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEVAddRecExpr *convertSCEVToAddRecWithPredicates( 1012c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *S, const Loop *L, 1013c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallPtrSetImpl<const SCEVPredicate *> &Preds); 1014c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1015c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate: 1016c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A CallbackVH to arrange for ScalarEvolution to be notified whenever a 1017c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Value is deleted. 1018c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot class SCEVCallbackVH final : public CallbackVH { 1019c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScalarEvolution *SE; 1020c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1021c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void deleted() override; 1022c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void allUsesReplacedWith(Value *New) override; 1023c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1024c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot public: 1025c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVCallbackVH(Value *V, ScalarEvolution *SE = nullptr); 1026c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 1027c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1028c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot friend class SCEVCallbackVH; 1029c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot friend class SCEVExpander; 1030c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot friend class SCEVUnknown; 1031c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1032c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The function we are analyzing. 1033c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Function &F; 1034c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1035c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Does the module have any calls to the llvm.experimental.guard intrinsic 1036c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// at all? If this is false, we avoid doing work that will only help if 1037c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// thare are guards present in the IR. 1038c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool HasGuards; 1039c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1040c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The target library information for the target we are targeting. 1041c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot TargetLibraryInfo &TLI; 1042c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1043c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The tracker for @llvm.assume intrinsics in this function. 1044c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot AssumptionCache &AC; 1045c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1046c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The dominator tree. 1047c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DominatorTree &DT; 1048c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1049c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The loop information for the function we are currently analyzing. 1050c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LoopInfo &LI; 1051c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1052c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This SCEV is used to represent unknown trip counts and things. 1053c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot std::unique_ptr<SCEVCouldNotCompute> CouldNotCompute; 1054c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1055c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The type for HasRecMap. 1056c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using HasRecMapType = DenseMap<const SCEV *, bool>; 1057c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1058c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This is a cache to record whether a SCEV contains any scAddRecExpr. 1059c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot HasRecMapType HasRecMap; 1060c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1061c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The type for ExprValueMap. 1062c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using ValueOffsetPair = std::pair<Value *, ConstantInt *>; 1063c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using ExprValueMapType = DenseMap<const SCEV *, SetVector<ValueOffsetPair>>; 1064c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1065c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ExprValueMap -- This map records the original values from which 1066c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the SCEV expr is generated from. 1067c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1068c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// We want to represent the mapping as SCEV -> ValueOffsetPair instead 1069c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// of SCEV -> Value: 1070c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Suppose we know S1 expands to V1, and 1071c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// S1 = S2 + C_a 1072c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// S3 = S2 + C_b 1073c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// where C_a and C_b are different SCEVConstants. Then we'd like to 1074c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// expand S3 as V1 - C_a + C_b instead of expanding S2 literally. 1075c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// It is helpful when S2 is a complex SCEV expr. 1076c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1077c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// In order to do that, we represent ExprValueMap as a mapping from 1078c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV to ValueOffsetPair. We will save both S1->{V1, 0} and 1079c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// S2->{V1, C_a} into the map when we create SCEV for V1. When S3 1080c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// is expanded, it will first expand S2 to V1 - C_a because of 1081c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// S2->{V1, C_a} in the map, then expand S3 to V1 - C_a + C_b. 1082c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1083c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Note: S->{V, Offset} in the ExprValueMap means S can be expanded 1084c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// to V - Offset. 1085c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExprValueMapType ExprValueMap; 1086c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1087c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The type for ValueExprMap. 1088c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using ValueExprMapType = 1089c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *>>; 1090c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1091c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This is a cache of the values we have analyzed so far. 1092c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ValueExprMapType ValueExprMap; 1093c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1094c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Mark predicate values currently being processed by isImpliedCond. 1095c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallPtrSet<Value *, 6> PendingLoopPredicates; 1096c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1097c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Set to true by isLoopBackedgeGuardedByCond when we're walking the set of 1098c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// conditions dominating the backedge of a loop. 1099c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool WalkingBEDominatingConds = false; 1100c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1101c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Set to true by isKnownPredicateViaSplitting when we're trying to prove a 1102c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// predicate by splitting it into a set of independent predicates. 1103c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool ProvingSplitPredicate = false; 1104c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1105c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Memoized values for the GetMinTrailingZeros 1106c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const SCEV *, uint32_t> MinTrailingZerosCache; 1107c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1108c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the Value set from which the SCEV expr is generated. 1109c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SetVector<ValueOffsetPair> *getSCEVValues(const SCEV *S); 1110c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1111c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Private helper method for the GetMinTrailingZeros method 1112c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot uint32_t GetMinTrailingZerosImpl(const SCEV *S); 1113c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1114c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Information about the number of loop iterations for which a loop exit's 1115c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// branch condition evaluates to the not-taken path. This is a temporary 1116c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// pair of exact and max expressions that are eventually summarized in 1117c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ExitNotTakenInfo and BackedgeTakenInfo. 1118c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot struct ExitLimit { 1119c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *ExactNotTaken; // The exit is not taken exactly this many times 1120c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *MaxNotTaken; // The exit is not taken at most this many times 1121c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1122c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Not taken either exactly MaxNotTaken or zero times 1123c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool MaxOrZero = false; 1124c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1125c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A set of predicate guards for this ExitLimit. The result is only valid 1126c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// if all of the predicates in \c Predicates evaluate to 'true' at 1127c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// run-time. 1128c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallPtrSet<const SCEVPredicate *, 4> Predicates; 1129c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1130c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void addPredicate(const SCEVPredicate *P) { 1131c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot assert(!isa<SCEVUnionPredicate>(P) && "Only add leaf predicates here!"); 1132c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Predicates.insert(P); 1133c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 1134c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1135c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /*implicit*/ ExitLimit(const SCEV *E); 1136c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1137c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit( 1138c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *E, const SCEV *M, bool MaxOrZero, 1139c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ArrayRef<const SmallPtrSetImpl<const SCEVPredicate *> *> PredSetList); 1140c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1141c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero, 1142c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SmallPtrSetImpl<const SCEVPredicate *> &PredSet); 1143c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1144c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero); 1145c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1146c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether this ExitLimit contains any computed information, or 1147c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whether it's all SCEVCouldNotCompute values. 1148c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasAnyInfo() const { 1149c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return !isa<SCEVCouldNotCompute>(ExactNotTaken) || 1150c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot !isa<SCEVCouldNotCompute>(MaxNotTaken); 1151c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 1152c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1153c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasOperand(const SCEV *S) const; 1154c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1155c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether this ExitLimit contains all information. 1156c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasFullInfo() const { 1157c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return !isa<SCEVCouldNotCompute>(ExactNotTaken); 1158c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 1159c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 1160c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1161c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Information about the number of times a particular loop exit may be 1162c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// reached before exiting the loop. 1163c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot struct ExitNotTakenInfo { 1164c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot PoisoningVH<BasicBlock> ExitingBlock; 1165c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *ExactNotTaken; 1166c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot std::unique_ptr<SCEVUnionPredicate> Predicate; 1167c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1168c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot explicit ExitNotTakenInfo(PoisoningVH<BasicBlock> ExitingBlock, 1169c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *ExactNotTaken, 1170c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot std::unique_ptr<SCEVUnionPredicate> Predicate) 1171c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot : ExitingBlock(ExitingBlock), ExactNotTaken(ExactNotTaken), 1172c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Predicate(std::move(Predicate)) {} 1173c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1174c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasAlwaysTruePredicate() const { 1175c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return !Predicate || Predicate->isAlwaysTrue(); 1176c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 1177c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 1178c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1179c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Information about the backedge-taken count of a loop. This currently 1180c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// includes an exact count and a maximum count. 1181c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1182c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot class BackedgeTakenInfo { 1183c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A list of computable exits and their not-taken counts. Loops almost 1184c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// never have more than one computable exit. 1185c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<ExitNotTakenInfo, 1> ExitNotTaken; 1186c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1187c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The pointer part of \c MaxAndComplete is an expression indicating the 1188c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// least maximum backedge-taken count of the loop that is known, or a 1189c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEVCouldNotCompute. This expression is only valid if the predicates 1190c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// associated with all loop exits are true. 1191c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1192c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The integer part of \c MaxAndComplete is a boolean indicating if \c 1193c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ExitNotTaken has an element for every exiting block in the loop. 1194c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot PointerIntPair<const SCEV *, 1> MaxAndComplete; 1195c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1196c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// True iff the backedge is taken either exactly Max or zero times. 1197c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool MaxOrZero = false; 1198c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1199c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \name Helper projection functions on \c MaxAndComplete. 1200c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// @{ 1201c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isComplete() const { return MaxAndComplete.getInt(); } 1202c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getMax() const { return MaxAndComplete.getPointer(); } 1203c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// @} 1204c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1205c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot public: 1206c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BackedgeTakenInfo() : MaxAndComplete(nullptr, 0) {} 1207c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BackedgeTakenInfo(BackedgeTakenInfo &&) = default; 1208c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BackedgeTakenInfo &operator=(BackedgeTakenInfo &&) = default; 1209c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1210c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using EdgeExitInfo = std::pair<BasicBlock *, ExitLimit>; 1211c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1212c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Initialize BackedgeTakenInfo from a list of exact exit counts. 1213c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BackedgeTakenInfo(SmallVectorImpl<EdgeExitInfo> &&ExitCounts, bool Complete, 1214c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *MaxCount, bool MaxOrZero); 1215c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1216c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether this BackedgeTakenInfo contains any computed information, 1217c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// or whether it's all SCEVCouldNotCompute values. 1218c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasAnyInfo() const { 1219c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return !ExitNotTaken.empty() || !isa<SCEVCouldNotCompute>(getMax()); 1220c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 1221c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1222c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether this BackedgeTakenInfo contains complete information. 1223c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasFullInfo() const { return isComplete(); } 1224c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1225c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return an expression indicating the exact *backedge-taken* 1226c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// count of the loop if it is known or SCEVCouldNotCompute 1227c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// otherwise. If execution makes it to the backedge on every 1228c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// iteration (i.e. there are no abnormal exists like exception 1229c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// throws and thread exits) then this is the number of times the 1230c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop header will execute minus one. 1231c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1232c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If the SCEV predicate associated with the answer can be different 1233c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from AlwaysTrue, we must add a (non null) Predicates argument. 1234c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The SCEV predicate associated with the answer will be added to 1235c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Predicates. A run-time check needs to be emitted for the SCEV 1236c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// predicate in order for the answer to be valid. 1237c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1238c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Note that we should always know if we need to pass a predicate 1239c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// argument or not from the way the ExitCounts vector was computed. 1240c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If we allowed SCEV predicates to be generated when populating this 1241c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// vector, this information can contain them and therefore a 1242c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEVPredicate argument should be added to getExact. 1243c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getExact(ScalarEvolution *SE, 1244c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVUnionPredicate *Predicates = nullptr) const; 1245c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1246c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the number of times this loop exit may fall through to the back 1247c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// edge, or SCEVCouldNotCompute. The loop is guaranteed not to exit via 1248c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// this block before this number of iterations, but may exit via another 1249c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// block. 1250c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) const; 1251c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1252c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Get the max backedge taken count for the loop. 1253c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getMax(ScalarEvolution *SE) const; 1254c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1255c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the number of times this backedge is taken is either the 1256c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value returned by getMax or zero. 1257c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isMaxOrZero(ScalarEvolution *SE) const; 1258c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1259c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if any backedge taken count expressions refer to the given 1260c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// subexpression. 1261c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasOperand(const SCEV *S, ScalarEvolution *SE) const; 1262c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1263c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Invalidate this result and free associated memory. 1264c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void clear(); 1265c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 1266c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1267c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Cache the backedge-taken count of the loops for this function as they 1268c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// are computed. 1269c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const Loop *, BackedgeTakenInfo> BackedgeTakenCounts; 1270c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1271c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Cache the predicated backedge-taken count of the loops for this 1272c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// function as they are computed. 1273c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const Loop *, BackedgeTakenInfo> PredicatedBackedgeTakenCounts; 1274c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1275c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Cache the calculated exit limits for the loops. 1276c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<ExitLimitQuery, ExitLimit> ExitLimits; 1277c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1278c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This map contains entries for all of the PHI instructions that we 1279c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// attempt to compute constant evolutions for. This allows us to avoid 1280c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// potentially expensive recomputation of these properties. An instruction 1281c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// maps to null if we are unable to compute its exit value. 1282c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<PHINode *, Constant *> ConstantEvolutionLoopExitValue; 1283c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1284c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This map contains entries for all the expressions that we attempt to 1285c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// compute getSCEVAtScope information for, which can be expensive in 1286c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// extreme cases. 1287c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const SCEV *, SmallVector<std::pair<const Loop *, const SCEV *>, 2>> 1288c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ValuesAtScopes; 1289c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1290c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Memoized computeLoopDisposition results. 1291c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const SCEV *, 1292c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<PointerIntPair<const Loop *, 2, LoopDisposition>, 2>> 1293c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LoopDispositions; 1294c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1295c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot struct LoopProperties { 1296c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Set to true if the loop contains no instruction that can have side 1297c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// effects (i.e. via throwing an exception, volatile or atomic access). 1298c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool HasNoAbnormalExits; 1299c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1300c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Set to true if the loop contains no instruction that can abnormally exit 1301c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the loop (i.e. via throwing an exception, by terminating the thread 1302c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// cleanly or by infinite looping in a called function). Strictly 1303c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// speaking, the last one is not leaving the loop, but is identical to 1304c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// leaving the loop for reasoning about undefined behavior. 1305c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool HasNoSideEffects; 1306c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 1307c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1308c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Cache for \c getLoopProperties. 1309c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const Loop *, LoopProperties> LoopPropertiesCache; 1310c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1311c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a \c LoopProperties instance for \p L, creating one if necessary. 1312c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LoopProperties getLoopProperties(const Loop *L); 1313c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1314c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool loopHasNoSideEffects(const Loop *L) { 1315c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getLoopProperties(L).HasNoSideEffects; 1316c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 1317c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1318c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool loopHasNoAbnormalExits(const Loop *L) { 1319c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return getLoopProperties(L).HasNoAbnormalExits; 1320c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 1321c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1322c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute a LoopDisposition value. 1323c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L); 1324c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1325c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Memoized computeBlockDisposition results. 1326c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap< 1327c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *, 1328c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallVector<PointerIntPair<const BasicBlock *, 2, BlockDisposition>, 2>> 1329c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BlockDispositions; 1330c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1331c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute a BlockDisposition value. 1332c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB); 1333c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1334c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Memoized results from getRange 1335c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const SCEV *, ConstantRange> UnsignedRanges; 1336c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1337c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Memoized results from getRange 1338c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const SCEV *, ConstantRange> SignedRanges; 1339c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1340c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Used to parameterize getRange 1341c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot enum RangeSignHint { HINT_RANGE_UNSIGNED, HINT_RANGE_SIGNED }; 1342c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1343c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Set the memoized range for the given SCEV. 1344c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint, 1345c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange CR) { 1346c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const SCEV *, ConstantRange> &Cache = 1347c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges; 1348c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1349c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot auto Pair = Cache.try_emplace(S, std::move(CR)); 1350c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (!Pair.second) 1351c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Pair.first->second = std::move(CR); 1352c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return Pair.first->second; 1353c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 1354c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1355c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determine the range for a particular SCEV. 1356c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// NOTE: This returns a reference to an entry in a cache. It must be 1357c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// copied if its needed for longer. 1358c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ConstantRange &getRangeRef(const SCEV *S, RangeSignHint Hint); 1359c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1360c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Determines the range for the affine SCEVAddRecExpr {\p Start,+,\p Stop}. 1361c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Helper for \c getRange. 1362c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange getRangeForAffineAR(const SCEV *Start, const SCEV *Stop, 1363c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *MaxBECount, unsigned BitWidth); 1364c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1365c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Try to compute a range for the affine SCEVAddRecExpr {\p Start,+,\p 1366c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Stop} by "factoring out" a ternary expression from the add recurrence. 1367c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Helper called by \c getRange. 1368c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange getRangeViaFactoring(const SCEV *Start, const SCEV *Stop, 1369c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *MaxBECount, unsigned BitWidth); 1370c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1371c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// We know that there is no SCEV for the specified value. Analyze the 1372c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// expression. 1373c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *createSCEV(Value *V); 1374c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1375c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Provide the special handling we need to analyze PHI SCEVs. 1376c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *createNodeForPHI(PHINode *PN); 1377c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1378c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Helper function called from createNodeForPHI. 1379c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *createAddRecFromPHI(PHINode *PN); 1380c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1381c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// A helper function for createAddRecFromPHI to handle simple cases. 1382c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *createSimpleAffineAddRec(PHINode *PN, Value *BEValueV, 1383c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Value *StartValueV); 1384c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1385c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Helper function called from createNodeForPHI. 1386c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *createNodeFromSelectLikePHI(PHINode *PN); 1387c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1388c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Provide special handling for a select-like instruction (currently this 1389c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// is either a select instruction or a phi node). \p I is the instruction 1390c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// being processed, and it is assumed equivalent to "Cond ? TrueVal : 1391c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// FalseVal". 1392c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *createNodeForSelectOrPHI(Instruction *I, Value *Cond, 1393c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Value *TrueVal, Value *FalseVal); 1394c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1395c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Provide the special handling we need to analyze GEP SCEVs. 1396c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *createNodeForGEP(GEPOperator *GEP); 1397c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1398c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Implementation code for getSCEVAtScope; called at most once for each 1399c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV+Loop pair. 1400c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *computeSCEVAtScope(const SCEV *S, const Loop *L); 1401c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1402c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This looks up computed SCEV values for all instructions that depend on 1403c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the given instruction and removes them from the ValueExprMap map if they 1404c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// reference SymName. This is used during PHI resolution. 1405c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void forgetSymbolicName(Instruction *I, const SCEV *SymName); 1406c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1407c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the BackedgeTakenInfo for the given loop, lazily computing new 1408c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// values if the loop hasn't been analyzed yet. The returned result is 1409c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// guaranteed not to be predicated. 1410c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L); 1411c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1412c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Similar to getBackedgeTakenInfo, but will add predicates as required 1413c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// with the purpose of returning complete information. 1414c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const BackedgeTakenInfo &getPredicatedBackedgeTakenInfo(const Loop *L); 1415c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1416c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the number of times the specified loop will iterate. 1417c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If AllowPredicates is set, we will create new SCEV predicates as 1418c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// necessary in order to return an exact answer. 1419c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BackedgeTakenInfo computeBackedgeTakenCount(const Loop *L, 1420c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates = false); 1421c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1422c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the number of times the backedge of the specified loop will 1423c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// execute if it exits via the specified block. If AllowPredicates is set, 1424c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// this call will try to use a minimal set of SCEV predicates in order to 1425c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// return an exact answer. 1426c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeExitLimit(const Loop *L, BasicBlock *ExitingBlock, 1427c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates = false); 1428c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1429c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeExitLimitImpl(const Loop *L, BasicBlock *ExitingBlock, 1430c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates = false); 1431c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1432c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the number of times the backedge of the specified loop will 1433c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// execute if its exit condition were a conditional branch of ExitCond, 1434c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// TBB, and FBB. 1435c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1436c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \p ControlsExit is true if ExitCond directly controls the exit 1437c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// branch. In this case, we can assume that the loop exits only if the 1438c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// condition is true and can infer that failing to meet the condition prior 1439c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// to integer wraparound results in undefined behavior. 1440c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1441c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If \p AllowPredicates is set, this call will try to use a minimal set of 1442c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV predicates in order to return an exact answer. 1443c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeExitLimitFromCond(const Loop *L, Value *ExitCond, 1444c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *TBB, BasicBlock *FBB, 1445c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool ControlsExit, 1446c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates = false); 1447c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1448c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Helper functions for computeExitLimitFromCond to avoid exponential time 1449c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // complexity. 1450c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1451c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot class ExitLimitCache { 1452c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // It may look like we need key on the whole (L, TBB, FBB, ControlsExit, 1453c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // AllowPredicates) tuple, but recursive calls to 1454c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // computeExitLimitFromCondCached from computeExitLimitFromCondImpl only 1455c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // vary the in \c ExitCond and \c ControlsExit parameters. We remember the 1456c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // initial values of the other values to assert our assumption. 1457c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SmallDenseMap<PointerIntPair<Value *, 1>, ExitLimit> TripCountMap; 1458c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1459c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop *L; 1460c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *TBB; 1461c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *FBB; 1462c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates; 1463c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1464c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot public: 1465c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimitCache(const Loop *L, BasicBlock *TBB, BasicBlock *FBB, 1466c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates) 1467c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot : L(L), TBB(TBB), FBB(FBB), AllowPredicates(AllowPredicates) {} 1468c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1469c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Optional<ExitLimit> find(const Loop *L, Value *ExitCond, BasicBlock *TBB, 1470c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *FBB, bool ControlsExit, 1471c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates); 1472c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1473c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void insert(const Loop *L, Value *ExitCond, BasicBlock *TBB, 1474c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *FBB, bool ControlsExit, bool AllowPredicates, 1475c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ExitLimit &EL); 1476c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot }; 1477c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1478c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using ExitLimitCacheTy = ExitLimitCache; 1479c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1480c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeExitLimitFromCondCached(ExitLimitCacheTy &Cache, 1481c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop *L, Value *ExitCond, 1482c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *TBB, BasicBlock *FBB, 1483c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool ControlsExit, 1484c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates); 1485c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeExitLimitFromCondImpl(ExitLimitCacheTy &Cache, const Loop *L, 1486c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Value *ExitCond, BasicBlock *TBB, 1487c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *FBB, bool ControlsExit, 1488c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates); 1489c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1490c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the number of times the backedge of the specified loop will 1491c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// execute if its exit condition were a conditional branch of the ICmpInst 1492c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ExitCond, TBB, and FBB. If AllowPredicates is set, this call will try 1493c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// to use a minimal set of SCEV predicates in order to return an exact 1494c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// answer. 1495c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeExitLimitFromICmp(const Loop *L, ICmpInst *ExitCond, 1496c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *TBB, BasicBlock *FBB, 1497c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool IsSubExpr, 1498c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates = false); 1499c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1500c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the number of times the backedge of the specified loop will 1501c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// execute if its exit condition were a switch with a single exiting case 1502c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// to ExitingBB. 1503c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeExitLimitFromSingleExitSwitch(const Loop *L, 1504c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SwitchInst *Switch, 1505c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BasicBlock *ExitingBB, 1506c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool IsSubExpr); 1507c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1508c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Given an exit condition of 'icmp op load X, cst', try to see if we can 1509c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// compute the backedge-taken count. 1510c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeLoadConstantCompareExitLimit(LoadInst *LI, Constant *RHS, 1511c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop *L, 1512c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ICmpInst::Predicate p); 1513c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1514c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the exit limit of a loop that is controlled by a 1515c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// "(IV >> 1) != 0" type comparison. We cannot compute the exact trip 1516c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// count in these cases (since SCEV has no way of expressing them), but we 1517c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// can still sometimes compute an upper bound. 1518c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1519c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return an ExitLimit for a loop whose backedge is guarded by `LHS Pred 1520c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// RHS`. 1521c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit computeShiftCompareExitLimit(Value *LHS, Value *RHS, const Loop *L, 1522c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ICmpInst::Predicate Pred); 1523c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1524c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If the loop is known to execute a constant number of times (the 1525c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// condition evolves only from constants), try to evaluate a few iterations 1526c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// of the loop until we get the exit condition gets a value of ExitWhen 1527c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// (true or false). If we cannot evaluate the exit count of the loop, 1528c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// return CouldNotCompute. 1529c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *computeExitCountExhaustively(const Loop *L, Value *Cond, 1530c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool ExitWhen); 1531c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1532c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the number of times an exit condition comparing the specified 1533c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value to zero will execute. If not computable, return CouldNotCompute. 1534c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If AllowPredicates is set, this call will try to use a minimal set of 1535c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV predicates in order to return an exact answer. 1536c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit howFarToZero(const SCEV *V, const Loop *L, bool IsSubExpr, 1537c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates = false); 1538c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1539c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the number of times an exit condition checking the specified 1540c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value for nonzero will execute. If not computable, return 1541c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// CouldNotCompute. 1542c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit howFarToNonZero(const SCEV *V, const Loop *L); 1543c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1544c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the number of times an exit condition containing the specified 1545c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// less-than comparison will execute. If not computable, return 1546c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// CouldNotCompute. 1547c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1548c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \p isSigned specifies whether the less-than is signed. 1549c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1550c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \p ControlsExit is true when the LHS < RHS condition directly controls 1551c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the branch (loops exits only if condition is true). In this case, we can 1552c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// use NoWrapFlags to skip overflow checks. 1553c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1554c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If \p AllowPredicates is set, this call will try to use a minimal set of 1555c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV predicates in order to return an exact answer. 1556c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit howManyLessThans(const SCEV *LHS, const SCEV *RHS, const Loop *L, 1557c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isSigned, bool ControlsExit, 1558c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates = false); 1559c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1560c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ExitLimit howManyGreaterThans(const SCEV *LHS, const SCEV *RHS, const Loop *L, 1561c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isSigned, bool IsSubExpr, 1562c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool AllowPredicates = false); 1563c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1564c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a predecessor of BB (which may not be an immediate predecessor) 1565c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// which has exactly one successor from which BB is reachable, or null if 1566c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// no such block is found. 1567c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot std::pair<BasicBlock *, BasicBlock *> 1568c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB); 1569c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1570c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the condition described by Pred, LHS, and RHS is true 1571c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whenever the given FoundCondValue value evaluates to true. 1572c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, 1573c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Value *FoundCondValue, bool Inverse); 1574c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1575c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the condition described by Pred, LHS, and RHS is true 1576c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whenever the condition described by FoundPred, FoundLHS, FoundRHS is 1577c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// true. 1578c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, 1579c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ICmpInst::Predicate FoundPred, const SCEV *FoundLHS, 1580c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *FoundRHS); 1581c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1582c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the condition described by Pred, LHS, and RHS is true 1583c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whenever the condition described by Pred, FoundLHS, and FoundRHS is 1584c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// true. 1585c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isImpliedCondOperands(ICmpInst::Predicate Pred, const SCEV *LHS, 1586c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS, const SCEV *FoundLHS, 1587c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *FoundRHS); 1588c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1589c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the condition described by Pred, LHS, and RHS is true 1590c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whenever the condition described by Pred, FoundLHS, and FoundRHS is 1591c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// true. Here LHS is an operation that includes FoundLHS as one of its 1592c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// arguments. 1593c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isImpliedViaOperations(ICmpInst::Predicate Pred, 1594c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *LHS, const SCEV *RHS, 1595c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *FoundLHS, const SCEV *FoundRHS, 1596c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Depth = 0); 1597c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1598c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the condition described by Pred, LHS, and RHS is true. 1599c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Use only simple non-recursive types of checks, such as range analysis etc. 1600c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownViaSimpleReasoning(ICmpInst::Predicate Pred, 1601c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *LHS, const SCEV *RHS); 1602c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1603c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the condition described by Pred, LHS, and RHS is true 1604c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whenever the condition described by Pred, FoundLHS, and FoundRHS is 1605c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// true. 1606c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, const SCEV *LHS, 1607c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS, const SCEV *FoundLHS, 1608c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *FoundRHS); 1609c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1610c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the condition described by Pred, LHS, and RHS is true 1611c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whenever the condition described by Pred, FoundLHS, and FoundRHS is 1612c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// true. Utility function used by isImpliedCondOperands. Tries to get 1613c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// cases like "X `sgt` 0 => X - 1 `sgt` -1". 1614c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred, const SCEV *LHS, 1615c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS, const SCEV *FoundLHS, 1616c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *FoundRHS); 1617c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1618c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the condition denoted by \p LHS \p Pred \p RHS is implied 1619c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// by a call to \c @llvm.experimental.guard in \p BB. 1620c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isImpliedViaGuard(BasicBlock *BB, ICmpInst::Predicate Pred, 1621c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *LHS, const SCEV *RHS); 1622c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1623c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test whether the condition described by Pred, LHS, and RHS is true 1624c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// whenever the condition described by Pred, FoundLHS, and FoundRHS is 1625c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// true. 1626c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1627c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This routine tries to rule out certain kinds of integer overflow, and 1628c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// then tries to reason about arithmetic properties of the predicates. 1629c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isImpliedCondOperandsViaNoOverflow(ICmpInst::Predicate Pred, 1630c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *LHS, const SCEV *RHS, 1631c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *FoundLHS, 1632c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *FoundRHS); 1633c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1634c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If we know that the specified Phi is in the header of its containing 1635c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop, we know the loop executes a constant number of times, and the PHI 1636c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// node is just a recurrence involving constants, fold it. 1637c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt &BEs, 1638c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop *L); 1639c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1640c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Test if the given expression is known to satisfy the condition described 1641c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// by Pred and the known constant ranges of LHS and RHS. 1642c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownPredicateViaConstantRanges(ICmpInst::Predicate Pred, 1643c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *LHS, const SCEV *RHS); 1644c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1645c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Try to prove the condition described by "LHS Pred RHS" by ruling out 1646c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// integer overflow. 1647c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1648c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// For instance, this will return true for "A s< (A + C)<nsw>" if C is 1649c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// positive. 1650c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred, const SCEV *LHS, 1651c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS); 1652c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1653c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Try to split Pred LHS RHS into logical conjunctions (and's) and try to 1654c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// prove them individually. 1655c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isKnownPredicateViaSplitting(ICmpInst::Predicate Pred, const SCEV *LHS, 1656c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *RHS); 1657c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1658c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Try to match the Expr as "(L + R)<Flags>". 1659c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool splitBinaryAdd(const SCEV *Expr, const SCEV *&L, const SCEV *&R, 1660c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags &Flags); 1661c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1662c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute \p LHS - \p RHS and returns the result as an APInt if it is a 1663c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// constant, and None if it isn't. 1664c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1665c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This is intended to be a cheaper version of getMinusSCEV. We can be 1666c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// frugal here since we just bail out of actually constructing and 1667c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// canonicalizing an expression in the cases where the result isn't going 1668c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// to be a constant. 1669c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Optional<APInt> computeConstantDifference(const SCEV *LHS, const SCEV *RHS); 1670c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1671c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Drop memoized information computed for S. Only erase Exit Limits info if 1672c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// we expect that the operation we have made is going to change it. 1673c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void forgetMemoizedResults(const SCEV *S, bool EraseExitLimit = true); 1674c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1675c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return an existing SCEV for V if there is one, otherwise return nullptr. 1676c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getExistingSCEV(Value *V); 1677c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1678c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return false iff given SCEV contains a SCEVUnknown with NULL value- 1679c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// pointer. 1680c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool checkValidity(const SCEV *S) const; 1681c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1682c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if `ExtendOpTy`({`Start`,+,`Step`}) can be proved to be 1683c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// equal to {`ExtendOpTy`(`Start`),+,`ExtendOpTy`(`Step`)}. This is 1684c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// equivalent to proving no signed (resp. unsigned) wrap in 1685c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// {`Start`,+,`Step`} if `ExtendOpTy` is `SCEVSignExtendExpr` 1686c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// (resp. `SCEVZeroExtendExpr`). 1687c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot template <typename ExtendOpTy> 1688c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool proveNoWrapByVaryingStart(const SCEV *Start, const SCEV *Step, 1689c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop *L); 1690c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1691c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Try to prove NSW or NUW on \p AR relying on ConstantRange manipulation. 1692c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags proveNoWrapViaConstantRanges(const SCEVAddRecExpr *AR); 1693c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1694c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isMonotonicPredicateImpl(const SCEVAddRecExpr *LHS, 1695c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ICmpInst::Predicate Pred, bool &Increasing); 1696c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1697c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return SCEV no-wrap flags that can be proven based on reasoning about 1698c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// how poison produced from no-wrap flags on this value (e.g. a nuw add) 1699c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// would trigger undefined behavior on overflow. 1700c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags getNoWrapFlagsFromUB(const Value *V); 1701c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1702c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the SCEV corresponding to \p I is never poison. Proving 1703c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// this is more complex than proving that just \p I is never poison, since 1704c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV commons expressions across control flow, and you can have cases 1705c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// like: 1706c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1707c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// idx0 = a + b; 1708c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ptr[idx0] = 100; 1709c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// if (<condition>) { 1710c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// idx1 = a +nsw b; 1711c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ptr[idx1] = 200; 1712c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// } 1713c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 1714c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// where the SCEV expression (+ a b) is guaranteed to not be poison (and 1715c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// hence not sign-overflow) only if "<condition>" is true. Since both 1716c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// `idx0` and `idx1` will be mapped to the same SCEV expression, (+ a b), 1717c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// it is not okay to annotate (+ a b) with <nsw> in the above example. 1718c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isSCEVExprNeverPoison(const Instruction *I); 1719c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1720c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This is like \c isSCEVExprNeverPoison but it specifically works for 1721c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// instructions that will get mapped to SCEV add recurrences. Return true 1722c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// if \p I will never generate poison under the assumption that \p I is an 1723c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// add recurrence on the loop \p L. 1724c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isAddRecNeverPoison(const Instruction *I, const Loop *L); 1725c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1726c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Similar to createAddRecFromPHI, but with the additional flexibility of 1727c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// suggesting runtime overflow checks in case casts are encountered. 1728c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If successful, the analysis records that for this loop, \p SymbolicPHI, 1729c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// which is the UnknownSCEV currently representing the PHI, can be rewritten 1730c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// into an AddRec, assuming some predicates; The function then returns the 1731c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// AddRec and the predicates as a pair, and caches this pair in 1732c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// PredicatedSCEVRewrites. 1733c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If the analysis is not successful, a mapping from the \p SymbolicPHI to 1734c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// itself (with no predicates) is recorded, and a nullptr with an empty 1735c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// predicates vector is returned as a pair. 1736c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot Optional<std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>> 1737c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI); 1738c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1739c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the backedge taken count knowing the interval difference, the 1740c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// stride and presence of the equality in the comparison. 1741c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *computeBECount(const SCEV *Delta, const SCEV *Stride, 1742c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool Equality); 1743c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1744c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compute the maximum backedge count based on the range of values 1745c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// permitted by Start, End, and Stride. This is for loops of the form 1746c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// {Start, +, Stride} LT End. 1747c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *computeMaxBECountForLT(const SCEV *Start, const SCEV *Stride, 1748c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *End, unsigned BitWidth, 1749c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool IsSigned); 1750c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1751c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Verify if an linear IV with positive stride can overflow when in a 1752c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// less-than comparison, knowing the invariant term of the comparison, 1753c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the stride and the knowledge of NSW/NUW flags on the recurrence. 1754c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool doesIVOverflowOnLT(const SCEV *RHS, const SCEV *Stride, bool IsSigned, 1755c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool NoWrap); 1756c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1757c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Verify if an linear IV with negative stride can overflow when in a 1758c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// greater-than comparison, knowing the invariant term of the comparison, 1759c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the stride and the knowledge of NSW/NUW flags on the recurrence. 1760c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool doesIVOverflowOnGT(const SCEV *RHS, const SCEV *Stride, bool IsSigned, 1761c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool NoWrap); 1762c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1763c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Get add expr already created or create a new one. 1764c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getOrCreateAddExpr(SmallVectorImpl<const SCEV *> &Ops, 1765c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags); 1766c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1767c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Get mul expr already created or create a new one. 1768c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getOrCreateMulExpr(SmallVectorImpl<const SCEV *> &Ops, 1769c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEV::NoWrapFlags Flags); 1770c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1771c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Find all of the loops transitively used in \p S, and update \c LoopUsers 1772c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// accordingly. 1773c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void addToLoopUseLists(const SCEV *S); 1774c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1775c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FoldingSet<SCEV> UniqueSCEVs; 1776c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot FoldingSet<SCEVPredicate> UniquePreds; 1777c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot BumpPtrAllocator SCEVAllocator; 1778c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1779c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// This maps loops to a list of SCEV expressions that (transitively) use said 1780c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// loop. 1781c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const Loop *, SmallVector<const SCEV *, 4>> LoopUsers; 1782c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1783c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Cache tentative mappings from UnknownSCEVs in a Loop, to a SCEV expression 1784c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// they can be rewritten into under certain predicates. 1785c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<std::pair<const SCEVUnknown *, const Loop *>, 1786c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>> 1787c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot PredicatedSCEVRewrites; 1788c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1789c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The head of a linked list of all SCEVUnknown values that have been 1790c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// allocated. This is used by releaseMemory to locate them all and call 1791c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// their destructors. 1792c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVUnknown *FirstUnknown = nullptr; 1793c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 1794c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1795c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Analysis pass that exposes the \c ScalarEvolution for a function. 1796c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScalarEvolutionAnalysis 1797c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot : public AnalysisInfoMixin<ScalarEvolutionAnalysis> { 1798c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot friend AnalysisInfoMixin<ScalarEvolutionAnalysis>; 1799c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1800c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static AnalysisKey Key; 1801c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1802c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 1803c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using Result = ScalarEvolution; 1804c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1805c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScalarEvolution run(Function &F, FunctionAnalysisManager &AM); 1806c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 1807c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1808c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Printer pass for the \c ScalarEvolutionAnalysis results. 1809c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScalarEvolutionPrinterPass 1810c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot : public PassInfoMixin<ScalarEvolutionPrinterPass> { 1811c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot raw_ostream &OS; 1812c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1813c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 1814c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot explicit ScalarEvolutionPrinterPass(raw_ostream &OS) : OS(OS) {} 1815c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1816c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 1817c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 1818c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1819c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass ScalarEvolutionWrapperPass : public FunctionPass { 1820c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot std::unique_ptr<ScalarEvolution> SE; 1821c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1822c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 1823c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static char ID; 1824c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1825c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScalarEvolutionWrapperPass(); 1826c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1827c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScalarEvolution &getSE() { return *SE; } 1828c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ScalarEvolution &getSE() const { return *SE; } 1829c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1830c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool runOnFunction(Function &F) override; 1831c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void releaseMemory() override; 1832c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void getAnalysisUsage(AnalysisUsage &AU) const override; 1833c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void print(raw_ostream &OS, const Module * = nullptr) const override; 1834c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void verifyAnalysis() const override; 1835c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 1836c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1837c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// An interface layer with SCEV used to manage how we see SCEV expressions 1838c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// for values in the context of existing predicates. We can add new 1839c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// predicates, but we cannot remove them. 1840c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// 1841c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This layer has multiple purposes: 1842c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// - provides a simple interface for SCEV versioning. 1843c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// - guarantees that the order of transformations applied on a SCEV 1844c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// expression for a single Value is consistent across two different 1845c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// getSCEV calls. This means that, for example, once we've obtained 1846c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// an AddRec expression for a certain value through expression 1847c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// rewriting, we will continue to get an AddRec expression for that 1848c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Value. 1849c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// - lowers the number of expression rewrites. 1850c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass PredicatedScalarEvolution { 1851c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 1852c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot PredicatedScalarEvolution(ScalarEvolution &SE, Loop &L); 1853c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1854c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEVUnionPredicate &getUnionPredicate() const; 1855c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1856c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the SCEV expression of V, in the context of the current SCEV 1857c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// predicate. The order of transformations applied on the expression of V 1858c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// returned by ScalarEvolution is guaranteed to be preserved, even when 1859c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// adding new predicates. 1860c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getSCEV(Value *V); 1861c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1862c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Get the (predicated) backedge count for the analyzed loop. 1863c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *getBackedgeTakenCount(); 1864c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1865c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Adds a new predicate. 1866c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void addPredicate(const SCEVPredicate &Pred); 1867c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1868c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Attempts to produce an AddRecExpr for V by adding additional SCEV 1869c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// predicates. If we can't transform the expression into an AddRecExpr we 1870c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// return nullptr and not add additional SCEV predicates to the current 1871c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// context. 1872c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEVAddRecExpr *getAsAddRec(Value *V); 1873c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1874c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Proves that V doesn't overflow by adding SCEV predicate. 1875c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void setNoOverflow(Value *V, SCEVWrapPredicate::IncrementWrapFlags Flags); 1876c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1877c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns true if we've proved that V doesn't wrap by means of a SCEV 1878c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// predicate. 1879c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool hasNoOverflow(Value *V, SCEVWrapPredicate::IncrementWrapFlags Flags); 1880c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1881c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Returns the ScalarEvolution analysis used. 1882c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScalarEvolution *getSE() const { return &SE; } 1883c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1884c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// We need to explicitly define the copy constructor because of FlagsMap. 1885c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot PredicatedScalarEvolution(const PredicatedScalarEvolution &); 1886c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1887c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Print the SCEV mappings done by the Predicated Scalar Evolution. 1888c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The printed text is indented by \p Depth. 1889c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void print(raw_ostream &OS, unsigned Depth) const; 1890c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1891c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate: 1892c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Increments the version number of the predicate. This needs to be called 1893c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// every time the SCEV predicate changes. 1894c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void updateGeneration(); 1895c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1896c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Holds a SCEV and the version number of the SCEV predicate used to 1897c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// perform the rewrite of the expression. 1898c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot using RewriteEntry = std::pair<unsigned, const SCEV *>; 1899c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1900c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Maps a SCEV to the rewrite result of that SCEV at a certain version 1901c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// number. If this number doesn't match the current Generation, we will 1902c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// need to do a rewrite. To preserve the transformation order of previous 1903c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// rewrites, we will rewrite the previous result instead of the original 1904c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV. 1905c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot DenseMap<const SCEV *, RewriteEntry> RewriteMap; 1906c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1907c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Records what NoWrap flags we've added to a Value *. 1908c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ValueMap<Value *, SCEVWrapPredicate::IncrementWrapFlags> FlagsMap; 1909c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1910c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The ScalarEvolution analysis. 1911c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ScalarEvolution &SE; 1912c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1913c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The analyzed Loop. 1914c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const Loop &L; 1915c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1916c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The SCEVPredicate that forms our context. We will rewrite all 1917c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// expressions assuming that this predicate true. 1918c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot SCEVUnionPredicate Preds; 1919c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1920c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Marks the version of the SCEV predicate used. When rewriting a SCEV 1921c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// expression we mark it with the version of the predicate. We use this to 1922c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// figure out if the predicate has changed from the last rewrite of the 1923c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// SCEV. If so, we need to perform a new rewrite. 1924c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned Generation = 0; 1925c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1926c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// The backedge taken count. 1927c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const SCEV *BackedgeCount = nullptr; 1928c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 1929c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1930c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} // end namespace llvm 1931c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 1932c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#endif // LLVM_ANALYSIS_SCALAREVOLUTION_H 1933