1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[Analysis] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).

llvm-svn: 311212
This commit is contained in:
Eugene Zelenko 2017-08-18 23:51:26 +00:00
parent cfb9a3b007
commit 626e76b0a7
11 changed files with 334 additions and 250 deletions

View File

@ -6,6 +6,7 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//
/// \file /// \file
/// This file provides a collection of visitors which walk the (instruction) /// This file provides a collection of visitors which walk the (instruction)
/// uses of a pointer. These visitors all provide the same essential behavior /// uses of a pointer. These visitors all provide the same essential behavior
@ -16,23 +17,36 @@
/// global variable, or function argument. /// global variable, or function argument.
/// ///
/// FIXME: Provide a variant which doesn't track offsets and is cheaper. /// FIXME: Provide a variant which doesn't track offsets and is cheaper.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H #ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H
#define LLVM_ANALYSIS_PTRUSEVISITOR_H #define LLVM_ANALYSIS_PTRUSEVISITOR_H
#include "llvm/ADT/APInt.h" #include "llvm/ADT/APInt.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h" #include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InstVisitor.h" #include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/Support/Compiler.h" #include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/Support/Casting.h"
#include <algorithm>
#include <cassert>
#include <type_traits>
namespace llvm { namespace llvm {
namespace detail { namespace detail {
/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor. /// \brief Implementation of non-dependent functionality for \c PtrUseVisitor.
/// ///
/// See \c PtrUseVisitor for the public interface and detailed comments about /// See \c PtrUseVisitor for the public interface and detailed comments about
@ -115,7 +129,8 @@ protected:
/// This is used to maintain a worklist fo to-visit uses. This is used to /// This is used to maintain a worklist fo to-visit uses. This is used to
/// make the visit be iterative rather than recursive. /// make the visit be iterative rather than recursive.
struct UseToVisit { struct UseToVisit {
typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair; using UseAndIsOffsetKnownPair = PointerIntPair<Use *, 1, bool>;
UseAndIsOffsetKnownPair UseAndIsOffsetKnown; UseAndIsOffsetKnownPair UseAndIsOffsetKnown;
APInt Offset; APInt Offset;
}; };
@ -128,7 +143,6 @@ protected:
/// @} /// @}
/// \name Per-visit state /// \name Per-visit state
/// This state is reset for each instruction visited. /// This state is reset for each instruction visited.
/// @{ /// @{
@ -145,7 +159,6 @@ protected:
/// @} /// @}
/// Note that the constructor is protected because this class must be a base /// Note that the constructor is protected because this class must be a base
/// class, we can't create instances directly of this class. /// class, we can't create instances directly of this class.
PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {} PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {}
@ -162,6 +175,7 @@ protected:
/// offsets and looking through GEPs. /// offsets and looking through GEPs.
bool adjustOffsetForGEP(GetElementPtrInst &GEPI); bool adjustOffsetForGEP(GetElementPtrInst &GEPI);
}; };
} // end namespace detail } // end namespace detail
/// \brief A base class for visitors over the uses of a pointer value. /// \brief A base class for visitors over the uses of a pointer value.
@ -193,7 +207,8 @@ template <typename DerivedT>
class PtrUseVisitor : protected InstVisitor<DerivedT>, class PtrUseVisitor : protected InstVisitor<DerivedT>,
public detail::PtrUseVisitorBase { public detail::PtrUseVisitorBase {
friend class InstVisitor<DerivedT>; friend class InstVisitor<DerivedT>;
typedef InstVisitor<DerivedT> Base;
using Base = InstVisitor<DerivedT>;
public: public:
PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) { PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {
@ -283,6 +298,6 @@ protected:
} }
}; };
} } // end namespace llvm
#endif #endif // LLVM_ANALYSIS_PTRUSEVISITOR_H

View File

@ -21,11 +21,21 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_H #define LLVM_ANALYSIS_SCALAREVOLUTION_H
#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/ConstantRange.h" #include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h" #include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
@ -33,30 +43,33 @@
#include "llvm/IR/ValueMap.h" #include "llvm/IR/ValueMap.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
#include <utility>
namespace llvm { namespace llvm {
class APInt;
class AssumptionCache; class AssumptionCache;
class BasicBlock;
class Constant; class Constant;
class ConstantInt; class ConstantInt;
class DominatorTree;
class Type;
class ScalarEvolution;
class DataLayout; class DataLayout;
class TargetLibraryInfo; class DominatorTree;
class GEPOperator;
class Instruction;
class LLVMContext; class LLVMContext;
class Operator; class raw_ostream;
class SCEV; class ScalarEvolution;
class SCEVAddRecExpr; class SCEVAddRecExpr;
class SCEVConstant;
class SCEVExpander;
class SCEVPredicate;
class SCEVUnknown; class SCEVUnknown;
class Function; class StructType;
class TargetLibraryInfo;
template <> struct FoldingSetTrait<SCEV>; class Type;
template <> struct FoldingSetTrait<SCEVPredicate>; class Value;
/// This class represents an analyzed expression in the program. These are /// This class represents an analyzed expression in the program. These are
/// opaque objects that the client is not allowed to do much with directly. /// opaque objects that the client is not allowed to do much with directly.
@ -74,11 +87,7 @@ class SCEV : public FoldingSetNode {
protected: protected:
/// This field is initialized to zero and may be used in subclasses to store /// This field is initialized to zero and may be used in subclasses to store
/// miscellaneous information. /// miscellaneous information.
unsigned short SubclassData; unsigned short SubclassData = 0;
private:
SCEV(const SCEV &) = delete;
void operator=(const SCEV &) = delete;
public: public:
/// NoWrapFlags are bitfield indices into SubclassData. /// NoWrapFlags are bitfield indices into SubclassData.
@ -108,24 +117,22 @@ public:
}; };
explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy)
: FastID(ID), SCEVType(SCEVTy), SubclassData(0) {} : FastID(ID), SCEVType(SCEVTy) {}
SCEV(const SCEV &) = delete;
SCEV &operator=(const SCEV &) = delete;
unsigned getSCEVType() const { return SCEVType; } unsigned getSCEVType() const { return SCEVType; }
/// Return the LLVM type of this SCEV expression. /// Return the LLVM type of this SCEV expression.
///
Type *getType() const; Type *getType() const;
/// Return true if the expression is a constant zero. /// Return true if the expression is a constant zero.
///
bool isZero() const; bool isZero() const;
/// Return true if the expression is a constant one. /// Return true if the expression is a constant one.
///
bool isOne() const; bool isOne() const;
/// Return true if the expression is a constant all-ones value. /// Return true if the expression is a constant all-ones value.
///
bool isAllOnesValue() const; bool isAllOnesValue() const;
/// Return true if the specified scev is negated, but not a constant. /// Return true if the specified scev is negated, but not a constant.
@ -136,7 +143,6 @@ public:
void print(raw_ostream &OS) const; void print(raw_ostream &OS) const;
/// This method is used for debugging. /// This method is used for debugging.
///
void dump() const; void dump() const;
}; };
@ -144,10 +150,12 @@ public:
// temporary FoldingSetNodeID values. // temporary FoldingSetNodeID values.
template <> struct FoldingSetTrait<SCEV> : DefaultFoldingSetTrait<SCEV> { template <> struct FoldingSetTrait<SCEV> : DefaultFoldingSetTrait<SCEV> {
static void Profile(const SCEV &X, FoldingSetNodeID &ID) { ID = X.FastID; } static void Profile(const SCEV &X, FoldingSetNodeID &ID) { ID = X.FastID; }
static bool Equals(const SCEV &X, const FoldingSetNodeID &ID, unsigned IDHash, static bool Equals(const SCEV &X, const FoldingSetNodeID &ID, unsigned IDHash,
FoldingSetNodeID &TempID) { FoldingSetNodeID &TempID) {
return ID == X.FastID; return ID == X.FastID;
} }
static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) { static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) {
return X.FastID.ComputeHash(); return X.FastID.ComputeHash();
} }
@ -221,7 +229,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const SCEVPredicate &P) {
// temporary FoldingSetNodeID values. // temporary FoldingSetNodeID values.
template <> template <>
struct FoldingSetTrait<SCEVPredicate> : DefaultFoldingSetTrait<SCEVPredicate> { struct FoldingSetTrait<SCEVPredicate> : DefaultFoldingSetTrait<SCEVPredicate> {
static void Profile(const SCEVPredicate &X, FoldingSetNodeID &ID) { static void Profile(const SCEVPredicate &X, FoldingSetNodeID &ID) {
ID = X.FastID; ID = X.FastID;
} }
@ -230,6 +237,7 @@ struct FoldingSetTrait<SCEVPredicate> : DefaultFoldingSetTrait<SCEVPredicate> {
unsigned IDHash, FoldingSetNodeID &TempID) { unsigned IDHash, FoldingSetNodeID &TempID) {
return ID == X.FastID; return ID == X.FastID;
} }
static unsigned ComputeHash(const SCEVPredicate &X, static unsigned ComputeHash(const SCEVPredicate &X,
FoldingSetNodeID &TempID) { FoldingSetNodeID &TempID) {
return X.FastID.ComputeHash(); return X.FastID.ComputeHash();
@ -351,6 +359,7 @@ public:
/// Returns the set assumed no overflow flags. /// Returns the set assumed no overflow flags.
IncrementWrapFlags getFlags() const { return Flags; } IncrementWrapFlags getFlags() const { return Flags; }
/// Implementation of the SCEVPredicate interface /// Implementation of the SCEVPredicate interface
const SCEV *getExpr() const override; const SCEV *getExpr() const override;
bool implies(const SCEVPredicate *N) const override; bool implies(const SCEVPredicate *N) const override;
@ -371,11 +380,12 @@ public:
/// ScalarEvolution::Preds folding set. This is why the \c add function is sound. /// ScalarEvolution::Preds folding set. This is why the \c add function is sound.
class SCEVUnionPredicate final : public SCEVPredicate { class SCEVUnionPredicate final : public SCEVPredicate {
private: private:
typedef DenseMap<const SCEV *, SmallVector<const SCEVPredicate *, 4>> using PredicateMap =
PredicateMap; DenseMap<const SCEV *, SmallVector<const SCEVPredicate *, 4>>;
/// Vector with references to all predicates in this union. /// Vector with references to all predicates in this union.
SmallVector<const SCEVPredicate *, 16> Preds; SmallVector<const SCEVPredicate *, 16> Preds;
/// Maps SCEVs to predicates for quick look-ups. /// Maps SCEVs to predicates for quick look-ups.
PredicateMap SCEVToPreds; PredicateMap SCEVToPreds;
@ -422,13 +432,16 @@ template <> struct DenseMapInfo<ExitLimitQuery> {
static inline ExitLimitQuery getEmptyKey() { static inline ExitLimitQuery getEmptyKey() {
return ExitLimitQuery(nullptr, nullptr, true); return ExitLimitQuery(nullptr, nullptr, true);
} }
static inline ExitLimitQuery getTombstoneKey() { static inline ExitLimitQuery getTombstoneKey() {
return ExitLimitQuery(nullptr, nullptr, false); return ExitLimitQuery(nullptr, nullptr, false);
} }
static unsigned getHashValue(ExitLimitQuery Val) { static unsigned getHashValue(ExitLimitQuery Val) {
return hash_combine(hash_combine(Val.L, Val.ExitingBlock), return hash_combine(hash_combine(Val.L, Val.ExitingBlock),
Val.AllowPredicates); Val.AllowPredicates);
} }
static bool isEqual(ExitLimitQuery LHS, ExitLimitQuery RHS) { static bool isEqual(ExitLimitQuery LHS, ExitLimitQuery RHS) {
return LHS.L == RHS.L && LHS.ExitingBlock == RHS.ExitingBlock && return LHS.L == RHS.L && LHS.ExitingBlock == RHS.ExitingBlock &&
LHS.AllowPredicates == RHS.AllowPredicates; LHS.AllowPredicates == RHS.AllowPredicates;
@ -474,6 +487,7 @@ private:
/// Value is deleted. /// Value is deleted.
class SCEVCallbackVH final : public CallbackVH { class SCEVCallbackVH final : public CallbackVH {
ScalarEvolution *SE; ScalarEvolution *SE;
void deleted() override; void deleted() override;
void allUsesReplacedWith(Value *New) override; void allUsesReplacedWith(Value *New) override;
@ -486,44 +500,37 @@ private:
friend class SCEVUnknown; friend class SCEVUnknown;
/// The function we are analyzing. /// The function we are analyzing.
///
Function &F; Function &F;
/// Does the module have any calls to the llvm.experimental.guard intrinsic /// Does the module have any calls to the llvm.experimental.guard intrinsic
/// at all? If this is false, we avoid doing work that will only help if /// at all? If this is false, we avoid doing work that will only help if
/// thare are guards present in the IR. /// thare are guards present in the IR.
///
bool HasGuards; bool HasGuards;
/// The target library information for the target we are targeting. /// The target library information for the target we are targeting.
///
TargetLibraryInfo &TLI; TargetLibraryInfo &TLI;
/// The tracker for @llvm.assume intrinsics in this function. /// The tracker for @llvm.assume intrinsics in this function.
AssumptionCache &AC; AssumptionCache &AC;
/// The dominator tree. /// The dominator tree.
///
DominatorTree &DT; DominatorTree &DT;
/// The loop information for the function we are currently analyzing. /// The loop information for the function we are currently analyzing.
///
LoopInfo &LI; LoopInfo &LI;
/// This SCEV is used to represent unknown trip counts and things. /// This SCEV is used to represent unknown trip counts and things.
std::unique_ptr<SCEVCouldNotCompute> CouldNotCompute; std::unique_ptr<SCEVCouldNotCompute> CouldNotCompute;
/// The typedef for HasRecMap. /// The type for HasRecMap.
/// using HasRecMapType = DenseMap<const SCEV *, bool>;
typedef DenseMap<const SCEV *, bool> HasRecMapType;
/// This is a cache to record whether a SCEV contains any scAddRecExpr. /// This is a cache to record whether a SCEV contains any scAddRecExpr.
HasRecMapType HasRecMap; HasRecMapType HasRecMap;
/// The typedef for ExprValueMap. /// The type for ExprValueMap.
/// using ValueOffsetPair = std::pair<Value *, ConstantInt *>;
typedef std::pair<Value *, ConstantInt *> ValueOffsetPair; using ExprValueMapType = DenseMap<const SCEV *, SetVector<ValueOffsetPair>>;
typedef DenseMap<const SCEV *, SetVector<ValueOffsetPair>> ExprValueMapType;
/// ExprValueMap -- This map records the original values from which /// ExprValueMap -- This map records the original values from which
/// the SCEV expr is generated from. /// the SCEV expr is generated from.
@ -547,13 +554,11 @@ private:
/// to V - Offset. /// to V - Offset.
ExprValueMapType ExprValueMap; ExprValueMapType ExprValueMap;
/// The typedef for ValueExprMap. /// The type for ValueExprMap.
/// using ValueExprMapType =
typedef DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *>> DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *>>;
ValueExprMapType;
/// This is a cache of the values we have analyzed so far. /// This is a cache of the values we have analyzed so far.
///
ValueExprMapType ValueExprMap; ValueExprMapType ValueExprMap;
/// Mark predicate values currently being processed by isImpliedCond. /// Mark predicate values currently being processed by isImpliedCond.
@ -561,11 +566,11 @@ private:
/// Set to true by isLoopBackedgeGuardedByCond when we're walking the set of /// Set to true by isLoopBackedgeGuardedByCond when we're walking the set of
/// conditions dominating the backedge of a loop. /// conditions dominating the backedge of a loop.
bool WalkingBEDominatingConds; bool WalkingBEDominatingConds = false;
/// Set to true by isKnownPredicateViaSplitting when we're trying to prove a /// Set to true by isKnownPredicateViaSplitting when we're trying to prove a
/// predicate by splitting it into a set of independent predicates. /// predicate by splitting it into a set of independent predicates.
bool ProvingSplitPredicate; bool ProvingSplitPredicate = false;
/// Memoized values for the GetMinTrailingZeros /// Memoized values for the GetMinTrailingZeros
DenseMap<const SCEV *, uint32_t> MinTrailingZerosCache; DenseMap<const SCEV *, uint32_t> MinTrailingZerosCache;
@ -580,7 +585,9 @@ private:
struct ExitLimit { struct ExitLimit {
const SCEV *ExactNotTaken; // The exit is not taken exactly this many times const SCEV *ExactNotTaken; // The exit is not taken exactly this many times
const SCEV *MaxNotTaken; // The exit is not taken at most this many times const SCEV *MaxNotTaken; // The exit is not taken at most this many times
bool MaxOrZero; // Not taken either exactly MaxNotTaken or zero times
// Not taken either exactly MaxNotTaken or zero times
bool MaxOrZero = false;
/// A set of predicate guards for this ExitLimit. The result is only valid /// A set of predicate guards for this ExitLimit. The result is only valid
/// if all of the predicates in \c Predicates evaluate to 'true' at /// if all of the predicates in \c Predicates evaluate to 'true' at
@ -624,15 +631,16 @@ private:
PoisoningVH<BasicBlock> ExitingBlock; PoisoningVH<BasicBlock> ExitingBlock;
const SCEV *ExactNotTaken; const SCEV *ExactNotTaken;
std::unique_ptr<SCEVUnionPredicate> Predicate; std::unique_ptr<SCEVUnionPredicate> Predicate;
bool hasAlwaysTruePredicate() const {
return !Predicate || Predicate->isAlwaysTrue();
}
explicit ExitNotTakenInfo(PoisoningVH<BasicBlock> ExitingBlock, explicit ExitNotTakenInfo(PoisoningVH<BasicBlock> ExitingBlock,
const SCEV *ExactNotTaken, const SCEV *ExactNotTaken,
std::unique_ptr<SCEVUnionPredicate> Predicate) std::unique_ptr<SCEVUnionPredicate> Predicate)
: ExitingBlock(ExitingBlock), ExactNotTaken(ExactNotTaken), : ExitingBlock(ExitingBlock), ExactNotTaken(ExactNotTaken),
Predicate(std::move(Predicate)) {} Predicate(std::move(Predicate)) {}
bool hasAlwaysTruePredicate() const {
return !Predicate || Predicate->isAlwaysTrue();
}
}; };
/// Information about the backedge-taken count of a loop. This currently /// Information about the backedge-taken count of a loop. This currently
@ -662,12 +670,11 @@ private:
/// @} /// @}
public: public:
BackedgeTakenInfo() : MaxAndComplete(nullptr, 0), MaxOrZero(false) {} BackedgeTakenInfo() : MaxAndComplete(nullptr, 0) {}
BackedgeTakenInfo(BackedgeTakenInfo &&) = default; BackedgeTakenInfo(BackedgeTakenInfo &&) = default;
BackedgeTakenInfo &operator=(BackedgeTakenInfo &&) = default; BackedgeTakenInfo &operator=(BackedgeTakenInfo &&) = default;
typedef std::pair<BasicBlock *, ExitLimit> EdgeExitInfo; using EdgeExitInfo = std::pair<BasicBlock *, ExitLimit>;
/// Initialize BackedgeTakenInfo from a list of exact exit counts. /// Initialize BackedgeTakenInfo from a list of exact exit counts.
BackedgeTakenInfo(SmallVectorImpl<EdgeExitInfo> &&ExitCounts, bool Complete, BackedgeTakenInfo(SmallVectorImpl<EdgeExitInfo> &&ExitCounts, bool Complete,
@ -857,7 +864,6 @@ private:
/// Implementation code for getSCEVAtScope; called at most once for each /// Implementation code for getSCEVAtScope; called at most once for each
/// SCEV+Loop pair. /// SCEV+Loop pair.
///
const SCEV *computeSCEVAtScope(const SCEV *S, const Loop *L); const SCEV *computeSCEVAtScope(const SCEV *S, const Loop *L);
/// This looks up computed SCEV values for all instructions that depend on /// This looks up computed SCEV values for all instructions that depend on
@ -936,7 +942,8 @@ private:
const ExitLimit &EL); const ExitLimit &EL);
}; };
typedef ExitLimitCache ExitLimitCacheTy; using ExitLimitCacheTy = ExitLimitCache;
ExitLimit computeExitLimitFromCondCached(ExitLimitCacheTy &Cache, ExitLimit computeExitLimitFromCondCached(ExitLimitCacheTy &Cache,
const Loop *L, Value *ExitCond, const Loop *L, Value *ExitCond,
BasicBlock *TBB, BasicBlock *FBB, BasicBlock *TBB, BasicBlock *FBB,
@ -1099,7 +1106,6 @@ private:
/// Test if the given expression is known to satisfy the condition described /// Test if the given expression is known to satisfy the condition described
/// by Pred and the known constant ranges of LHS and RHS. /// by Pred and the known constant ranges of LHS and RHS.
///
bool isKnownPredicateViaConstantRanges(ICmpInst::Predicate Pred, bool isKnownPredicateViaConstantRanges(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS); const SCEV *LHS, const SCEV *RHS);
@ -1145,7 +1151,6 @@ private:
/// equivalent to proving no signed (resp. unsigned) wrap in /// equivalent to proving no signed (resp. unsigned) wrap in
/// {`Start`,+,`Step`} if `ExtendOpTy` is `SCEVSignExtendExpr` /// {`Start`,+,`Step`} if `ExtendOpTy` is `SCEVSignExtendExpr`
/// (resp. `SCEVZeroExtendExpr`). /// (resp. `SCEVZeroExtendExpr`).
///
template <typename ExtendOpTy> template <typename ExtendOpTy>
bool proveNoWrapByVaryingStart(const SCEV *Start, const SCEV *Step, bool proveNoWrapByVaryingStart(const SCEV *Start, const SCEV *Step,
const Loop *L); const Loop *L);
@ -1188,8 +1193,8 @@ private:
public: public:
ScalarEvolution(Function &F, TargetLibraryInfo &TLI, AssumptionCache &AC, ScalarEvolution(Function &F, TargetLibraryInfo &TLI, AssumptionCache &AC,
DominatorTree &DT, LoopInfo &LI); DominatorTree &DT, LoopInfo &LI);
~ScalarEvolution();
ScalarEvolution(ScalarEvolution &&Arg); ScalarEvolution(ScalarEvolution &&Arg);
~ScalarEvolution();
LLVMContext &getContext() const { return F.getContext(); } LLVMContext &getContext() const { return F.getContext(); }
@ -1213,7 +1218,6 @@ public:
/// Return true if the SCEV is a scAddRecExpr or it contains /// Return true if the SCEV is a scAddRecExpr or it contains
/// scAddRecExpr. The result will be cached in HasRecMap. /// scAddRecExpr. The result will be cached in HasRecMap.
///
bool containsAddRecurrence(const SCEV *S); bool containsAddRecurrence(const SCEV *S);
/// Return the Value set from which the SCEV expr is generated. /// Return the Value set from which the SCEV expr is generated.
@ -1305,20 +1309,16 @@ public:
const SCEV *getOne(Type *Ty) { return getConstant(Ty, 1); } const SCEV *getOne(Type *Ty) { return getConstant(Ty, 1); }
/// Return an expression for sizeof AllocTy that is type IntTy /// Return an expression for sizeof AllocTy that is type IntTy
///
const SCEV *getSizeOfExpr(Type *IntTy, Type *AllocTy); const SCEV *getSizeOfExpr(Type *IntTy, Type *AllocTy);
/// Return an expression for offsetof on the given field with type IntTy /// Return an expression for offsetof on the given field with type IntTy
///
const SCEV *getOffsetOfExpr(Type *IntTy, StructType *STy, unsigned FieldNo); const SCEV *getOffsetOfExpr(Type *IntTy, StructType *STy, unsigned FieldNo);
/// Return the SCEV object corresponding to -V. /// Return the SCEV object corresponding to -V.
///
const SCEV *getNegativeSCEV(const SCEV *V, const SCEV *getNegativeSCEV(const SCEV *V,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
/// Return the SCEV object corresponding to ~V. /// Return the SCEV object corresponding to ~V.
///
const SCEV *getNotSCEV(const SCEV *V); const SCEV *getNotSCEV(const SCEV *V);
/// Return LHS-RHS. Minus is represented in SCEV as A+B*-1. /// Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
@ -1446,7 +1446,6 @@ public:
/// Note that it is not valid to call this method on a loop without a /// Note that it is not valid to call this method on a loop without a
/// loop-invariant backedge-taken count (see /// loop-invariant backedge-taken count (see
/// hasLoopInvariantBackedgeTakenCount). /// hasLoopInvariantBackedgeTakenCount).
///
const SCEV *getBackedgeTakenCount(const Loop *L); const SCEV *getBackedgeTakenCount(const Loop *L);
/// Similar to getBackedgeTakenCount, except it will add a set of /// Similar to getBackedgeTakenCount, except it will add a set of
@ -1527,28 +1526,22 @@ public:
} }
/// Test if the given expression is known to be negative. /// Test if the given expression is known to be negative.
///
bool isKnownNegative(const SCEV *S); bool isKnownNegative(const SCEV *S);
/// Test if the given expression is known to be positive. /// Test if the given expression is known to be positive.
///
bool isKnownPositive(const SCEV *S); bool isKnownPositive(const SCEV *S);
/// Test if the given expression is known to be non-negative. /// Test if the given expression is known to be non-negative.
///
bool isKnownNonNegative(const SCEV *S); bool isKnownNonNegative(const SCEV *S);
/// Test if the given expression is known to be non-positive. /// Test if the given expression is known to be non-positive.
///
bool isKnownNonPositive(const SCEV *S); bool isKnownNonPositive(const SCEV *S);
/// Test if the given expression is known to be non-zero. /// Test if the given expression is known to be non-zero.
///
bool isKnownNonZero(const SCEV *S); bool isKnownNonZero(const SCEV *S);
/// Test if the given expression is known to satisfy the condition described /// Test if the given expression is known to satisfy the condition described
/// by Pred, LHS, and RHS. /// by Pred, LHS, and RHS.
///
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *RHS); const SCEV *RHS);
@ -1578,7 +1571,6 @@ public:
/// iff any changes were made. If the operands are provably equal or /// iff any changes were made. If the operands are provably equal or
/// unequal, LHS and RHS are set to the same value and Pred is set to either /// unequal, LHS and RHS are set to the same value and Pred is set to either
/// ICMP_EQ or ICMP_NE. /// ICMP_EQ or ICMP_NE.
///
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, const SCEV *&LHS, bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, const SCEV *&LHS,
const SCEV *&RHS, unsigned Depth = 0); const SCEV *&RHS, unsigned Depth = 0);
@ -1784,17 +1776,18 @@ private:
/// The head of a linked list of all SCEVUnknown values that have been /// The head of a linked list of all SCEVUnknown values that have been
/// allocated. This is used by releaseMemory to locate them all and call /// allocated. This is used by releaseMemory to locate them all and call
/// their destructors. /// their destructors.
SCEVUnknown *FirstUnknown; SCEVUnknown *FirstUnknown = nullptr;
}; };
/// Analysis pass that exposes the \c ScalarEvolution for a function. /// Analysis pass that exposes the \c ScalarEvolution for a function.
class ScalarEvolutionAnalysis class ScalarEvolutionAnalysis
: public AnalysisInfoMixin<ScalarEvolutionAnalysis> { : public AnalysisInfoMixin<ScalarEvolutionAnalysis> {
friend AnalysisInfoMixin<ScalarEvolutionAnalysis>; friend AnalysisInfoMixin<ScalarEvolutionAnalysis>;
static AnalysisKey Key; static AnalysisKey Key;
public: public:
typedef ScalarEvolution Result; using Result = ScalarEvolution;
ScalarEvolution run(Function &F, FunctionAnalysisManager &AM); ScalarEvolution run(Function &F, FunctionAnalysisManager &AM);
}; };
@ -1806,6 +1799,7 @@ class ScalarEvolutionPrinterPass
public: public:
explicit ScalarEvolutionPrinterPass(raw_ostream &OS) : OS(OS) {} explicit ScalarEvolutionPrinterPass(raw_ostream &OS) : OS(OS) {}
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
}; };
@ -1843,6 +1837,7 @@ public:
class PredicatedScalarEvolution { class PredicatedScalarEvolution {
public: public:
PredicatedScalarEvolution(ScalarEvolution &SE, Loop &L); PredicatedScalarEvolution(ScalarEvolution &SE, Loop &L);
const SCEVUnionPredicate &getUnionPredicate() const; const SCEVUnionPredicate &getUnionPredicate() const;
/// Returns the SCEV expression of V, in the context of the current SCEV /// Returns the SCEV expression of V, in the context of the current SCEV
@ -1887,7 +1882,7 @@ private:
/// Holds a SCEV and the version number of the SCEV predicate used to /// Holds a SCEV and the version number of the SCEV predicate used to
/// perform the rewrite of the expression. /// perform the rewrite of the expression.
typedef std::pair<unsigned, const SCEV *> RewriteEntry; using RewriteEntry = std::pair<unsigned, const SCEV *>;
/// Maps a SCEV to the rewrite result of that SCEV at a certain version /// Maps a SCEV to the rewrite result of that SCEV at a certain version
/// number. If this number doesn't match the current Generation, we will /// number. If this number doesn't match the current Generation, we will
@ -1913,11 +1908,12 @@ private:
/// expression we mark it with the version of the predicate. We use this to /// expression we mark it with the version of the predicate. We use this to
/// figure out if the predicate has changed from the last rewrite of the /// figure out if the predicate has changed from the last rewrite of the
/// SCEV. If so, we need to perform a new rewrite. /// SCEV. If so, we need to perform a new rewrite.
unsigned Generation; unsigned Generation = 0;
/// The backedge taken count. /// The backedge taken count.
const SCEV *BackedgeCount; const SCEV *BackedgeCount = nullptr;
}; };
}
#endif } // end namespace llvm
#endif // LLVM_ANALYSIS_SCALAREVOLUTION_H

View File

@ -14,15 +14,27 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H #ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H #define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstddef>
namespace llvm { namespace llvm {
class ConstantInt;
class ConstantRange; class APInt;
class DominatorTree; class Constant;
class ConstantRange;
class Loop;
class Type;
enum SCEVTypes { enum SCEVTypes {
// These should be ordered in terms of increasing complexity to make the // These should be ordered in terms of increasing complexity to make the
@ -37,8 +49,10 @@ namespace llvm {
friend class ScalarEvolution; friend class ScalarEvolution;
ConstantInt *V; ConstantInt *V;
SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v) : SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v) :
SCEV(ID, scConstant), V(v) {} SCEV(ID, scConstant), V(v) {}
public: public:
ConstantInt *getValue() const { return V; } ConstantInt *getValue() const { return V; }
const APInt &getAPInt() const { return getValue()->getValue(); } const APInt &getAPInt() const { return getValue()->getValue(); }
@ -117,7 +131,6 @@ namespace llvm {
} }
}; };
/// This node is a base class providing common functionality for /// This node is a base class providing common functionality for
/// n'ary operators. /// n'ary operators.
class SCEVNAryExpr : public SCEV { class SCEVNAryExpr : public SCEV {
@ -135,13 +148,15 @@ namespace llvm {
public: public:
size_t getNumOperands() const { return NumOperands; } size_t getNumOperands() const { return NumOperands; }
const SCEV *getOperand(unsigned i) const { const SCEV *getOperand(unsigned i) const {
assert(i < NumOperands && "Operand index out of range!"); assert(i < NumOperands && "Operand index out of range!");
return Operands[i]; return Operands[i];
} }
typedef const SCEV *const *op_iterator; using op_iterator = const SCEV *const *;
typedef iterator_range<op_iterator> op_range; using op_range = iterator_range<op_iterator>;
op_iterator op_begin() const { return Operands; } op_iterator op_begin() const { return Operands; }
op_iterator op_end() const { return Operands + NumOperands; } op_iterator op_end() const { return Operands + NumOperands; }
op_range operands() const { op_range operands() const {
@ -198,15 +213,13 @@ namespace llvm {
} }
}; };
/// This node represents an addition of some number of SCEVs. /// This node represents an addition of some number of SCEVs.
class SCEVAddExpr : public SCEVCommutativeExpr { class SCEVAddExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution; friend class ScalarEvolution;
SCEVAddExpr(const FoldingSetNodeIDRef ID, SCEVAddExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N) const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scAddExpr, O, N) { : SCEVCommutativeExpr(ID, scAddExpr, O, N) {}
}
public: public:
Type *getType() const { Type *getType() const {
@ -222,15 +235,13 @@ namespace llvm {
} }
}; };
/// This node represents multiplication of some number of SCEVs. /// This node represents multiplication of some number of SCEVs.
class SCEVMulExpr : public SCEVCommutativeExpr { class SCEVMulExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution; friend class ScalarEvolution;
SCEVMulExpr(const FoldingSetNodeIDRef ID, SCEVMulExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N) const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scMulExpr, O, N) { : SCEVCommutativeExpr(ID, scMulExpr, O, N) {}
}
public: public:
/// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -239,13 +250,13 @@ namespace llvm {
} }
}; };
/// This class represents a binary unsigned division operation. /// This class represents a binary unsigned division operation.
class SCEVUDivExpr : public SCEV { class SCEVUDivExpr : public SCEV {
friend class ScalarEvolution; friend class ScalarEvolution;
const SCEV *LHS; const SCEV *LHS;
const SCEV *RHS; const SCEV *RHS;
SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs) SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs)
: SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {} : SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {}
@ -268,7 +279,6 @@ namespace llvm {
} }
}; };
/// This node represents a polynomial recurrence on the trip count /// This node represents a polynomial recurrence on the trip count
/// of the specified loop. This is the primary focus of the /// of the specified loop. This is the primary focus of the
/// ScalarEvolution framework; all the other SCEV subclasses are /// ScalarEvolution framework; all the other SCEV subclasses are
@ -368,7 +378,6 @@ namespace llvm {
} }
}; };
/// This class represents an unsigned maximum selection. /// This class represents an unsigned maximum selection.
class SCEVUMaxExpr : public SCEVCommutativeExpr { class SCEVUMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution; friend class ScalarEvolution;
@ -393,10 +402,6 @@ namespace llvm {
class SCEVUnknown final : public SCEV, private CallbackVH { class SCEVUnknown final : public SCEV, private CallbackVH {
friend class ScalarEvolution; friend class ScalarEvolution;
// Implement CallbackVH.
void deleted() override;
void allUsesReplacedWith(Value *New) override;
/// The parent ScalarEvolution value. This is used to update the /// The parent ScalarEvolution value. This is used to update the
/// parent's maps when the value associated with a SCEVUnknown is /// parent's maps when the value associated with a SCEVUnknown is
/// deleted or RAUW'd. /// deleted or RAUW'd.
@ -410,6 +415,10 @@ namespace llvm {
ScalarEvolution *se, SCEVUnknown *next) : ScalarEvolution *se, SCEVUnknown *next) :
SCEV(ID, scUnknown), CallbackVH(V), SE(se), Next(next) {} SCEV(ID, scUnknown), CallbackVH(V), SE(se), Next(next) {}
// Implement CallbackVH.
void deleted() override;
void allUsesReplacedWith(Value *New) override;
public: public:
Value *getValue() const { return getValPtr(); } Value *getValue() const { return getValPtr(); }
@ -490,6 +499,7 @@ namespace llvm {
if (Visited.insert(S).second && Visitor.follow(S)) if (Visited.insert(S).second && Visitor.follow(S))
Worklist.push_back(S); Worklist.push_back(S);
} }
public: public:
SCEVTraversal(SV& V): Visitor(V) {} SCEVTraversal(SV& V): Visitor(V) {}
@ -682,7 +692,7 @@ namespace llvm {
} }
}; };
typedef DenseMap<const Value*, Value*> ValueToValueMap; using ValueToValueMap = DenseMap<const Value *, Value *>;
/// The SCEVParameterRewriter takes a scalar evolution expression and updates /// The SCEVParameterRewriter takes a scalar evolution expression and updates
/// the SCEVUnknown components following the Map (Value -> Value). /// the SCEVUnknown components following the Map (Value -> Value).
@ -714,22 +724,22 @@ namespace llvm {
bool InterpretConsts; bool InterpretConsts;
}; };
typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT; using LoopToScevMapT = DenseMap<const Loop *, const SCEV *>;
/// The SCEVLoopAddRecRewriter takes a scalar evolution expression and applies /// The SCEVLoopAddRecRewriter takes a scalar evolution expression and applies
/// the Map (Loop -> SCEV) to all AddRecExprs. /// the Map (Loop -> SCEV) to all AddRecExprs.
class SCEVLoopAddRecRewriter class SCEVLoopAddRecRewriter
: public SCEVRewriteVisitor<SCEVLoopAddRecRewriter> { : public SCEVRewriteVisitor<SCEVLoopAddRecRewriter> {
public: public:
SCEVLoopAddRecRewriter(ScalarEvolution &SE, LoopToScevMapT &M)
: SCEVRewriteVisitor(SE), Map(M) {}
static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map, static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
ScalarEvolution &SE) { ScalarEvolution &SE) {
SCEVLoopAddRecRewriter Rewriter(SE, Map); SCEVLoopAddRecRewriter Rewriter(SE, Map);
return Rewriter.visit(Scev); return Rewriter.visit(Scev);
} }
SCEVLoopAddRecRewriter(ScalarEvolution &SE, LoopToScevMapT &M)
: SCEVRewriteVisitor(SE), Map(M) {}
const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
SmallVector<const SCEV *, 2> Operands; SmallVector<const SCEV *, 2> Operands;
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
@ -748,6 +758,7 @@ namespace llvm {
private: private:
LoopToScevMapT &Map; LoopToScevMapT &Map;
}; };
}
#endif } // end namespace llvm
#endif // LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H

View File

@ -6,22 +6,27 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//
/// \file /// \file
/// This is the interface for a metadata-based scoped no-alias analysis. /// This is the interface for a metadata-based scoped no-alias analysis.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_SCOPEDNOALIASAA_H #ifndef LLVM_ANALYSIS_SCOPEDNOALIASAA_H
#define LLVM_ANALYSIS_SCOPEDNOALIASAA_H #define LLVM_ANALYSIS_SCOPEDNOALIASAA_H
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/Function.h" #include "llvm/IR/CallSite.h"
#include "llvm/IR/Metadata.h" #include "llvm/IR/PassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include <memory>
namespace llvm { namespace llvm {
class Function;
class MDNode;
class MemoryLocation;
/// A simple AA result which uses scoped-noalias metadata to answer queries. /// A simple AA result which uses scoped-noalias metadata to answer queries.
class ScopedNoAliasAAResult : public AAResultBase<ScopedNoAliasAAResult> { class ScopedNoAliasAAResult : public AAResultBase<ScopedNoAliasAAResult> {
friend AAResultBase<ScopedNoAliasAAResult>; friend AAResultBase<ScopedNoAliasAAResult>;
@ -46,10 +51,11 @@ private:
/// Analysis pass providing a never-invalidated alias analysis result. /// Analysis pass providing a never-invalidated alias analysis result.
class ScopedNoAliasAA : public AnalysisInfoMixin<ScopedNoAliasAA> { class ScopedNoAliasAA : public AnalysisInfoMixin<ScopedNoAliasAA> {
friend AnalysisInfoMixin<ScopedNoAliasAA>; friend AnalysisInfoMixin<ScopedNoAliasAA>;
static AnalysisKey Key; static AnalysisKey Key;
public: public:
typedef ScopedNoAliasAAResult Result; using Result = ScopedNoAliasAAResult;
ScopedNoAliasAAResult run(Function &F, FunctionAnalysisManager &AM); ScopedNoAliasAAResult run(Function &F, FunctionAnalysisManager &AM);
}; };
@ -77,6 +83,7 @@ public:
// scoped noalias analysis. // scoped noalias analysis.
// //
ImmutablePass *createScopedNoAliasAAWrapperPass(); ImmutablePass *createScopedNoAliasAAWrapperPass();
}
#endif } // end namespace llvm
#endif // LLVM_ANALYSIS_SCOPEDNOALIASAA_H

View File

@ -17,22 +17,22 @@
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/BasicBlock.h"
#include <set> #include <set>
#include <utility>
#include <vector> #include <vector>
namespace llvm { namespace llvm {
class Value;
class Constant;
class Argument; class Argument;
class BasicBlock;
class Constant;
class Function;
class Instruction; class Instruction;
class PHINode; class PHINode;
class TerminatorInst;
class BasicBlock;
class Function;
class SparseSolver;
class raw_ostream; class raw_ostream;
class SparseSolver;
class TerminatorInst;
class Value;
template <typename T> class SmallVectorImpl; template <typename T> class SmallVectorImpl;
/// AbstractLatticeFunction - This class is implemented by the dataflow instance /// AbstractLatticeFunction - This class is implemented by the dataflow instance
@ -44,7 +44,7 @@ template <typename T> class SmallVectorImpl;
/// ///
class AbstractLatticeFunction { class AbstractLatticeFunction {
public: public:
typedef void *LatticeVal; using LatticeVal = void *;
private: private:
LatticeVal UndefVal, OverdefinedVal, UntrackedVal; LatticeVal UndefVal, OverdefinedVal, UntrackedVal;
@ -56,6 +56,7 @@ public:
OverdefinedVal = overdefinedVal; OverdefinedVal = overdefinedVal;
UntrackedVal = untrackedVal; UntrackedVal = untrackedVal;
} }
virtual ~AbstractLatticeFunction(); virtual ~AbstractLatticeFunction();
LatticeVal getUndefVal() const { return UndefVal; } LatticeVal getUndefVal() const { return UndefVal; }
@ -109,9 +110,8 @@ public:
/// SparseSolver - This class is a general purpose solver for Sparse Conditional /// SparseSolver - This class is a general purpose solver for Sparse Conditional
/// Propagation with a programmable lattice function. /// Propagation with a programmable lattice function.
///
class SparseSolver { class SparseSolver {
typedef AbstractLatticeFunction::LatticeVal LatticeVal; using LatticeVal = AbstractLatticeFunction::LatticeVal;
/// LatticeFunc - This is the object that knows the lattice and how to do /// LatticeFunc - This is the object that knows the lattice and how to do
/// compute transfer functions. /// compute transfer functions.
@ -126,19 +126,17 @@ class SparseSolver {
/// KnownFeasibleEdges - Entries in this set are edges which have already had /// KnownFeasibleEdges - Entries in this set are edges which have already had
/// PHI nodes retriggered. /// PHI nodes retriggered.
typedef std::pair<BasicBlock*,BasicBlock*> Edge; using Edge = std::pair<BasicBlock *, BasicBlock *>;
std::set<Edge> KnownFeasibleEdges; std::set<Edge> KnownFeasibleEdges;
SparseSolver(const SparseSolver&) = delete;
void operator=(const SparseSolver&) = delete;
public: public:
explicit SparseSolver(AbstractLatticeFunction *Lattice) explicit SparseSolver(AbstractLatticeFunction *Lattice)
: LatticeFunc(Lattice) {} : LatticeFunc(Lattice) {}
SparseSolver(const SparseSolver &) = delete;
SparseSolver &operator=(const SparseSolver &) = delete;
~SparseSolver() { delete LatticeFunc; } ~SparseSolver() { delete LatticeFunc; }
/// Solve - Solve for constants and executable blocks. /// Solve - Solve for constants and executable blocks.
///
void Solve(Function &F); void Solve(Function &F);
void Print(Function &F, raw_ostream &OS) const; void Print(Function &F, raw_ostream &OS) const;
@ -156,7 +154,6 @@ public:
/// map yet. This function is necessary because not all values should start /// map yet. This function is necessary because not all values should start
/// out in the underdefined state... Arguments should be overdefined, and /// out in the underdefined state... Arguments should be overdefined, and
/// constants should be marked as constants. /// constants should be marked as constants.
///
LatticeVal getOrInitValueState(Value *V); LatticeVal getOrInitValueState(Value *V);
/// isEdgeFeasible - Return true if the control flow edge from the 'From' /// isEdgeFeasible - Return true if the control flow edge from the 'From'

View File

@ -6,22 +6,28 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//
/// \file /// \file
/// This is the interface for a metadata-based TBAA. See the source file for /// This is the interface for a metadata-based TBAA. See the source file for
/// details on the algorithm. /// details on the algorithm.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_TYPEBASEDALIASANALYSIS_H #ifndef LLVM_ANALYSIS_TYPEBASEDALIASANALYSIS_H
#define LLVM_ANALYSIS_TYPEBASEDALIASANALYSIS_H #define LLVM_ANALYSIS_TYPEBASEDALIASANALYSIS_H
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/Function.h" #include "llvm/IR/CallSite.h"
#include "llvm/IR/Metadata.h" #include "llvm/IR/PassManager.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include <memory>
namespace llvm { namespace llvm {
class Function;
class MDNode;
class MemoryLocation;
/// A simple AA result that uses TBAA metadata to answer queries. /// A simple AA result that uses TBAA metadata to answer queries.
class TypeBasedAAResult : public AAResultBase<TypeBasedAAResult> { class TypeBasedAAResult : public AAResultBase<TypeBasedAAResult> {
friend AAResultBase<TypeBasedAAResult>; friend AAResultBase<TypeBasedAAResult>;
@ -50,10 +56,11 @@ private:
/// Analysis pass providing a never-invalidated alias analysis result. /// Analysis pass providing a never-invalidated alias analysis result.
class TypeBasedAA : public AnalysisInfoMixin<TypeBasedAA> { class TypeBasedAA : public AnalysisInfoMixin<TypeBasedAA> {
friend AnalysisInfoMixin<TypeBasedAA>; friend AnalysisInfoMixin<TypeBasedAA>;
static AnalysisKey Key; static AnalysisKey Key;
public: public:
typedef TypeBasedAAResult Result; using Result = TypeBasedAAResult;
TypeBasedAAResult run(Function &F, FunctionAnalysisManager &AM); TypeBasedAAResult run(Function &F, FunctionAnalysisManager &AM);
}; };
@ -81,6 +88,7 @@ public:
// type-based alias analysis. // type-based alias analysis.
// //
ImmutablePass *createTypeBasedAAWrapperPass(); ImmutablePass *createTypeBasedAAWrapperPass();
}
#endif } // end namespace llvm
#endif // LLVM_ANALYSIS_TYPEBASEDALIASANALYSIS_H

View File

@ -6,12 +6,16 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//
/// \file /// \file
/// Implementation of the pointer use visitors. /// Implementation of the pointer use visitors.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/PtrUseVisitor.h" #include "llvm/Analysis/PtrUseVisitor.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include <algorithm>
using namespace llvm; using namespace llvm;

View File

@ -59,12 +59,22 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/Sequence.h" #include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/InstructionSimplify.h"
@ -72,28 +82,55 @@
#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantRange.h" #include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h" #include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h" #include "llvm/IR/Dominators.h"
#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstIterator.h" #include "llvm/IR/InstIterator.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h" #include "llvm/IR/Metadata.h"
#include "llvm/IR/Operator.h" #include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h" #include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h" #include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <algorithm> #include <algorithm>
#include <cassert>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <map>
#include <memory>
#include <tuple>
#include <utility>
#include <vector>
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "scalar-evolution" #define DEBUG_TYPE "scalar-evolution"
@ -736,7 +773,6 @@ static int CompareSCEVComplexity(
/// results from this routine. In other words, we don't want the results of /// results from this routine. In other words, we don't want the results of
/// this to depend on where the addresses of various SCEV objects happened to /// this to depend on where the addresses of various SCEV objects happened to
/// land in memory. /// land in memory.
///
static void GroupByComplexity(SmallVectorImpl<const SCEV *> &Ops, static void GroupByComplexity(SmallVectorImpl<const SCEV *> &Ops,
LoopInfo *LI, DominatorTree &DT) { LoopInfo *LI, DominatorTree &DT) {
if (Ops.size() < 2) return; // Noop if (Ops.size() < 2) return; // Noop
@ -782,14 +818,16 @@ static void GroupByComplexity(SmallVectorImpl<const SCEV *> &Ops,
// Returns the size of the SCEV S. // Returns the size of the SCEV S.
static inline int sizeOfSCEV(const SCEV *S) { static inline int sizeOfSCEV(const SCEV *S) {
struct FindSCEVSize { struct FindSCEVSize {
int Size; int Size = 0;
FindSCEVSize() : Size(0) {}
FindSCEVSize() = default;
bool follow(const SCEV *S) { bool follow(const SCEV *S) {
++Size; ++Size;
// Keep looking at all operands of S. // Keep looking at all operands of S.
return true; return true;
} }
bool isDone() const { bool isDone() const {
return false; return false;
} }
@ -1029,7 +1067,7 @@ private:
const SCEV *Denominator, *Quotient, *Remainder, *Zero, *One; const SCEV *Denominator, *Quotient, *Remainder, *Zero, *One;
}; };
} } // end anonymous namespace
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Simple SCEV method implementations // Simple SCEV method implementations
@ -1154,7 +1192,6 @@ static const SCEV *BinomialCoefficient(const SCEV *It, unsigned K,
/// A*BC(It, 0) + B*BC(It, 1) + C*BC(It, 2) + D*BC(It, 3) /// A*BC(It, 0) + B*BC(It, 1) + C*BC(It, 2) + D*BC(It, 3)
/// ///
/// where BC(It, k) stands for binomial coefficient. /// where BC(It, k) stands for binomial coefficient.
///
const SCEV *SCEVAddRecExpr::evaluateAtIteration(const SCEV *It, const SCEV *SCEVAddRecExpr::evaluateAtIteration(const SCEV *It,
ScalarEvolution &SE) const { ScalarEvolution &SE) const {
const SCEV *Result = getStart(); const SCEV *Result = getStart();
@ -1340,7 +1377,8 @@ struct ExtendOpTraits<SCEVZeroExtendExpr> : public ExtendOpTraitsBase {
const ExtendOpTraitsBase::GetExtendExprTy ExtendOpTraits< const ExtendOpTraitsBase::GetExtendExprTy ExtendOpTraits<
SCEVZeroExtendExpr>::GetExtendExpr = &ScalarEvolution::getZeroExtendExpr; SCEVZeroExtendExpr>::GetExtendExpr = &ScalarEvolution::getZeroExtendExpr;
}
} // end anonymous namespace
// The recurrence AR has been shown to have no signed/unsigned wrap or something // The recurrence AR has been shown to have no signed/unsigned wrap or something
// close to it. Typically, if we can prove NSW/NUW for AR, then we can just as // close to it. Typically, if we can prove NSW/NUW for AR, then we can just as
@ -1470,7 +1508,6 @@ static const SCEV *getExtendAddRecStart(const SCEVAddRecExpr *AR, Type *Ty,
// //
// In the current context, S is `Start`, X is `Step`, Ext is `ExtendOpTy` and T // In the current context, S is `Start`, X is `Step`, Ext is `ExtendOpTy` and T
// is `Delta` (defined below). // is `Delta` (defined below).
//
template <typename ExtendOpTy> template <typename ExtendOpTy>
bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start, bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start,
const SCEV *Step, const SCEV *Step,
@ -1481,7 +1518,6 @@ bool ScalarEvolution::proveNoWrapByVaryingStart(const SCEV *Start,
// time here. It is correct (but more expensive) to continue with a // time here. It is correct (but more expensive) to continue with a
// non-constant `Start` and do a general SCEV subtraction to compute // non-constant `Start` and do a general SCEV subtraction to compute
// `PreStart` below. // `PreStart` below.
//
const SCEVConstant *StartC = dyn_cast<SCEVConstant>(Start); const SCEVConstant *StartC = dyn_cast<SCEVConstant>(Start);
if (!StartC) if (!StartC)
return false; return false;
@ -1983,7 +2019,6 @@ ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
/// getAnyExtendExpr - Return a SCEV for the given operand extended with /// getAnyExtendExpr - Return a SCEV for the given operand extended with
/// unspecified bits out to the given type. /// unspecified bits out to the given type.
///
const SCEV *ScalarEvolution::getAnyExtendExpr(const SCEV *Op, const SCEV *ScalarEvolution::getAnyExtendExpr(const SCEV *Op,
Type *Ty) { Type *Ty) {
assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) && assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) &&
@ -2054,7 +2089,6 @@ const SCEV *ScalarEvolution::getAnyExtendExpr(const SCEV *Op,
/// may be exposed. This helps getAddRecExpr short-circuit extra work in /// may be exposed. This helps getAddRecExpr short-circuit extra work in
/// the common case where no interesting opportunities are present, and /// the common case where no interesting opportunities are present, and
/// is also used as a check to avoid infinite recursion. /// is also used as a check to avoid infinite recursion.
///
static bool static bool
CollectAddOperandsWithScales(DenseMap<const SCEV *, APInt> &M, CollectAddOperandsWithScales(DenseMap<const SCEV *, APInt> &M,
SmallVectorImpl<const SCEV *> &NewOps, SmallVectorImpl<const SCEV *> &NewOps,
@ -2129,7 +2163,8 @@ StrengthenNoWrapFlags(ScalarEvolution *SE, SCEVTypes Type,
const SmallVectorImpl<const SCEV *> &Ops, const SmallVectorImpl<const SCEV *> &Ops,
SCEV::NoWrapFlags Flags) { SCEV::NoWrapFlags Flags) {
using namespace std::placeholders; using namespace std::placeholders;
typedef OverflowingBinaryOperator OBO;
using OBO = OverflowingBinaryOperator;
bool CanAnalyze = bool CanAnalyze =
Type == scAddExpr || Type == scAddRecExpr || Type == scMulExpr; Type == scAddExpr || Type == scAddRecExpr || Type == scMulExpr;
@ -2684,6 +2719,7 @@ static bool containsConstantInAddMulChain(const SCEV *StartExpr) {
FoundConstant |= isa<SCEVConstant>(S); FoundConstant |= isa<SCEVConstant>(S);
return isa<SCEVAddExpr>(S) || isa<SCEVMulExpr>(S); return isa<SCEVAddExpr>(S) || isa<SCEVMulExpr>(S);
} }
bool isDone() const { bool isDone() const {
return FoundConstant; return FoundConstant;
} }
@ -3718,7 +3754,6 @@ const SCEV *ScalarEvolution::getExistingSCEV(Value *V) {
} }
/// Return a SCEV corresponding to -V = -1*V /// Return a SCEV corresponding to -V = -1*V
///
const SCEV *ScalarEvolution::getNegativeSCEV(const SCEV *V, const SCEV *ScalarEvolution::getNegativeSCEV(const SCEV *V,
SCEV::NoWrapFlags Flags) { SCEV::NoWrapFlags Flags) {
if (const SCEVConstant *VC = dyn_cast<SCEVConstant>(V)) if (const SCEVConstant *VC = dyn_cast<SCEVConstant>(V))
@ -3961,8 +3996,12 @@ void ScalarEvolution::forgetSymbolicName(Instruction *PN, const SCEV *SymName) {
} }
namespace { namespace {
class SCEVInitRewriter : public SCEVRewriteVisitor<SCEVInitRewriter> { class SCEVInitRewriter : public SCEVRewriteVisitor<SCEVInitRewriter> {
public: public:
SCEVInitRewriter(const Loop *L, ScalarEvolution &SE)
: SCEVRewriteVisitor(SE), L(L) {}
static const SCEV *rewrite(const SCEV *S, const Loop *L, static const SCEV *rewrite(const SCEV *S, const Loop *L,
ScalarEvolution &SE) { ScalarEvolution &SE) {
SCEVInitRewriter Rewriter(L, SE); SCEVInitRewriter Rewriter(L, SE);
@ -3970,9 +4009,6 @@ public:
return Rewriter.isValid() ? Result : SE.getCouldNotCompute(); return Rewriter.isValid() ? Result : SE.getCouldNotCompute();
} }
SCEVInitRewriter(const Loop *L, ScalarEvolution &SE)
: SCEVRewriteVisitor(SE), L(L), Valid(true) {}
const SCEV *visitUnknown(const SCEVUnknown *Expr) { const SCEV *visitUnknown(const SCEVUnknown *Expr) {
if (!SE.isLoopInvariant(Expr, L)) if (!SE.isLoopInvariant(Expr, L))
Valid = false; Valid = false;
@ -3991,11 +4027,14 @@ public:
private: private:
const Loop *L; const Loop *L;
bool Valid; bool Valid = true;
}; };
class SCEVShiftRewriter : public SCEVRewriteVisitor<SCEVShiftRewriter> { class SCEVShiftRewriter : public SCEVRewriteVisitor<SCEVShiftRewriter> {
public: public:
SCEVShiftRewriter(const Loop *L, ScalarEvolution &SE)
: SCEVRewriteVisitor(SE), L(L) {}
static const SCEV *rewrite(const SCEV *S, const Loop *L, static const SCEV *rewrite(const SCEV *S, const Loop *L,
ScalarEvolution &SE) { ScalarEvolution &SE) {
SCEVShiftRewriter Rewriter(L, SE); SCEVShiftRewriter Rewriter(L, SE);
@ -4003,9 +4042,6 @@ public:
return Rewriter.isValid() ? Result : SE.getCouldNotCompute(); return Rewriter.isValid() ? Result : SE.getCouldNotCompute();
} }
SCEVShiftRewriter(const Loop *L, ScalarEvolution &SE)
: SCEVRewriteVisitor(SE), L(L), Valid(true) {}
const SCEV *visitUnknown(const SCEVUnknown *Expr) { const SCEV *visitUnknown(const SCEVUnknown *Expr) {
// Only allow AddRecExprs for this loop. // Only allow AddRecExprs for this loop.
if (!SE.isLoopInvariant(Expr, L)) if (!SE.isLoopInvariant(Expr, L))
@ -4019,12 +4055,14 @@ public:
Valid = false; Valid = false;
return Expr; return Expr;
} }
bool isValid() { return Valid; } bool isValid() { return Valid; }
private: private:
const Loop *L; const Loop *L;
bool Valid; bool Valid = true;
}; };
} // end anonymous namespace } // end anonymous namespace
SCEV::NoWrapFlags SCEV::NoWrapFlags
@ -4032,7 +4070,8 @@ ScalarEvolution::proveNoWrapViaConstantRanges(const SCEVAddRecExpr *AR) {
if (!AR->isAffine()) if (!AR->isAffine())
return SCEV::FlagAnyWrap; return SCEV::FlagAnyWrap;
typedef OverflowingBinaryOperator OBO; using OBO = OverflowingBinaryOperator;
SCEV::NoWrapFlags Result = SCEV::FlagAnyWrap; SCEV::NoWrapFlags Result = SCEV::FlagAnyWrap;
if (!AR->hasNoSignedWrap()) { if (!AR->hasNoSignedWrap()) {
@ -4059,6 +4098,7 @@ ScalarEvolution::proveNoWrapViaConstantRanges(const SCEVAddRecExpr *AR) {
} }
namespace { namespace {
/// Represents an abstract binary operation. This may exist as a /// Represents an abstract binary operation. This may exist as a
/// normal instruction or constant expression, or may have been /// normal instruction or constant expression, or may have been
/// derived from an expression tree. /// derived from an expression tree.
@ -4066,16 +4106,16 @@ struct BinaryOp {
unsigned Opcode; unsigned Opcode;
Value *LHS; Value *LHS;
Value *RHS; Value *RHS;
bool IsNSW; bool IsNSW = false;
bool IsNUW; bool IsNUW = false;
/// Op is set if this BinaryOp corresponds to a concrete LLVM instruction or /// Op is set if this BinaryOp corresponds to a concrete LLVM instruction or
/// constant expression. /// constant expression.
Operator *Op; Operator *Op = nullptr;
explicit BinaryOp(Operator *Op) explicit BinaryOp(Operator *Op)
: Opcode(Op->getOpcode()), LHS(Op->getOperand(0)), RHS(Op->getOperand(1)), : Opcode(Op->getOpcode()), LHS(Op->getOperand(0)), RHS(Op->getOperand(1)),
IsNSW(false), IsNUW(false), Op(Op) { Op(Op) {
if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(Op)) { if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(Op)) {
IsNSW = OBO->hasNoSignedWrap(); IsNSW = OBO->hasNoSignedWrap();
IsNUW = OBO->hasNoUnsignedWrap(); IsNUW = OBO->hasNoUnsignedWrap();
@ -4084,11 +4124,10 @@ struct BinaryOp {
explicit BinaryOp(unsigned Opcode, Value *LHS, Value *RHS, bool IsNSW = false, explicit BinaryOp(unsigned Opcode, Value *LHS, Value *RHS, bool IsNSW = false,
bool IsNUW = false) bool IsNUW = false)
: Opcode(Opcode), LHS(LHS), RHS(RHS), IsNSW(IsNSW), IsNUW(IsNUW), : Opcode(Opcode), LHS(LHS), RHS(RHS), IsNSW(IsNSW), IsNUW(IsNUW) {}
Op(nullptr) {}
}; };
}
} // end anonymous namespace
/// Try to map \p V into a BinaryOp, and return \c None on failure. /// Try to map \p V into a BinaryOp, and return \c None on failure.
static Optional<BinaryOp> MatchBinaryOp(Value *V, DominatorTree &DT) { static Optional<BinaryOp> MatchBinaryOp(Value *V, DominatorTree &DT) {
@ -4149,7 +4188,7 @@ static Optional<BinaryOp> MatchBinaryOp(Value *V, DominatorTree &DT) {
if (auto *F = CI->getCalledFunction()) if (auto *F = CI->getCalledFunction())
switch (F->getIntrinsicID()) { switch (F->getIntrinsicID()) {
case Intrinsic::sadd_with_overflow: case Intrinsic::sadd_with_overflow:
case Intrinsic::uadd_with_overflow: { case Intrinsic::uadd_with_overflow:
if (!isOverflowIntrinsicNoWrap(cast<IntrinsicInst>(CI), DT)) if (!isOverflowIntrinsicNoWrap(cast<IntrinsicInst>(CI), DT))
return BinaryOp(Instruction::Add, CI->getArgOperand(0), return BinaryOp(Instruction::Add, CI->getArgOperand(0),
CI->getArgOperand(1)); CI->getArgOperand(1));
@ -4165,10 +4204,8 @@ static Optional<BinaryOp> MatchBinaryOp(Value *V, DominatorTree &DT) {
return BinaryOp(Instruction::Add, CI->getArgOperand(0), return BinaryOp(Instruction::Add, CI->getArgOperand(0),
CI->getArgOperand(1), /* IsNSW = */ false, CI->getArgOperand(1), /* IsNSW = */ false,
/* IsNUW*/ true); /* IsNUW*/ true);
}
case Intrinsic::ssub_with_overflow: case Intrinsic::ssub_with_overflow:
case Intrinsic::usub_with_overflow: { case Intrinsic::usub_with_overflow:
if (!isOverflowIntrinsicNoWrap(cast<IntrinsicInst>(CI), DT)) if (!isOverflowIntrinsicNoWrap(cast<IntrinsicInst>(CI), DT))
return BinaryOp(Instruction::Sub, CI->getArgOperand(0), return BinaryOp(Instruction::Sub, CI->getArgOperand(0),
CI->getArgOperand(1)); CI->getArgOperand(1));
@ -4182,7 +4219,6 @@ static Optional<BinaryOp> MatchBinaryOp(Value *V, DominatorTree &DT) {
return BinaryOp(Instruction::Sub, CI->getArgOperand(0), return BinaryOp(Instruction::Sub, CI->getArgOperand(0),
CI->getArgOperand(1), /* IsNSW = */ false, CI->getArgOperand(1), /* IsNSW = */ false,
/* IsNUW = */ true); /* IsNUW = */ true);
}
case Intrinsic::smul_with_overflow: case Intrinsic::smul_with_overflow:
case Intrinsic::umul_with_overflow: case Intrinsic::umul_with_overflow:
return BinaryOp(Instruction::Mul, CI->getArgOperand(0), return BinaryOp(Instruction::Mul, CI->getArgOperand(0),
@ -4212,7 +4248,6 @@ static Optional<BinaryOp> MatchBinaryOp(Value *V, DominatorTree &DT) {
/// \p Signed to true/false, respectively. /// \p Signed to true/false, respectively.
static Type *isSimpleCastedPHI(const SCEV *Op, const SCEVUnknown *SymbolicPHI, static Type *isSimpleCastedPHI(const SCEV *Op, const SCEVUnknown *SymbolicPHI,
bool &Signed, ScalarEvolution &SE) { bool &Signed, ScalarEvolution &SE) {
// The case where Op == SymbolicPHI (that is, with no type conversions on // The case where Op == SymbolicPHI (that is, with no type conversions on
// the way) is handled by the regular add recurrence creating logic and // the way) is handled by the regular add recurrence creating logic and
// would have already been triggered in createAddRecForPHI. Reaching it here // would have already been triggered in createAddRecForPHI. Reaching it here
@ -4243,7 +4278,7 @@ static Type *isSimpleCastedPHI(const SCEV *Op, const SCEVUnknown *SymbolicPHI,
const SCEV *X = Trunc->getOperand(); const SCEV *X = Trunc->getOperand();
if (X != SymbolicPHI) if (X != SymbolicPHI)
return nullptr; return nullptr;
Signed = SExt ? true : false; Signed = SExt != nullptr;
return Trunc->getType(); return Trunc->getType();
} }
@ -4309,7 +4344,6 @@ static const Loop *isIntegerLoopHeaderPHI(const PHINode *PN, LoopInfo &LI) {
// which correspond to a phi->trunc->add->sext/zext->phi update chain. // which correspond to a phi->trunc->add->sext/zext->phi update chain.
// //
// 3) Outline common code with createAddRecFromPHI to avoid duplication. // 3) Outline common code with createAddRecFromPHI to avoid duplication.
//
Optional<std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>> Optional<std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>>
ScalarEvolution::createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI) { ScalarEvolution::createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI) {
SmallVector<const SCEVPredicate *, 3> Predicates; SmallVector<const SCEVPredicate *, 3> Predicates;
@ -4319,7 +4353,7 @@ ScalarEvolution::createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI
auto *PN = cast<PHINode>(SymbolicPHI->getValue()); auto *PN = cast<PHINode>(SymbolicPHI->getValue());
const Loop *L = isIntegerLoopHeaderPHI(PN, LI); const Loop *L = isIntegerLoopHeaderPHI(PN, LI);
assert (L && "Expecting an integer loop header phi"); assert(L && "Expecting an integer loop header phi");
// The loop may have multiple entrances or multiple exits; we can analyze // The loop may have multiple entrances or multiple exits; we can analyze
// this phi as an addrec if it has a unique entry value and a unique // this phi as an addrec if it has a unique entry value and a unique
@ -4380,7 +4414,6 @@ ScalarEvolution::createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI
// varying inside the loop. // varying inside the loop.
if (!isLoopInvariant(Accum, L)) if (!isLoopInvariant(Accum, L))
return None; return None;
// *** Part2: Create the predicates // *** Part2: Create the predicates
@ -4447,7 +4480,7 @@ ScalarEvolution::createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI
// Create the Equal Predicates P2,P3: // Create the Equal Predicates P2,P3:
auto AppendPredicate = [&](const SCEV *Expr) -> void { auto AppendPredicate = [&](const SCEV *Expr) -> void {
assert (isLoopInvariant(Expr, L) && "Expr is expected to be invariant"); assert(isLoopInvariant(Expr, L) && "Expr is expected to be invariant");
const SCEV *TruncatedExpr = getTruncateExpr(Expr, TruncTy); const SCEV *TruncatedExpr = getTruncateExpr(Expr, TruncTy);
const SCEV *ExtendedExpr = const SCEV *ExtendedExpr =
Signed ? getSignExtendExpr(TruncatedExpr, Expr->getType()) Signed ? getSignExtendExpr(TruncatedExpr, Expr->getType())
@ -4478,7 +4511,6 @@ ScalarEvolution::createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI
Optional<std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>> Optional<std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>>>
ScalarEvolution::createAddRecFromPHIWithCasts(const SCEVUnknown *SymbolicPHI) { ScalarEvolution::createAddRecFromPHIWithCasts(const SCEVUnknown *SymbolicPHI) {
auto *PN = cast<PHINode>(SymbolicPHI->getValue()); auto *PN = cast<PHINode>(SymbolicPHI->getValue());
const Loop *L = isIntegerLoopHeaderPHI(PN, LI); const Loop *L = isIntegerLoopHeaderPHI(PN, LI);
if (!L) if (!L)
@ -5614,7 +5646,7 @@ bool ScalarEvolution::isAddRecNeverPoison(const Instruction *I, const Loop *L) {
ScalarEvolution::LoopProperties ScalarEvolution::LoopProperties
ScalarEvolution::getLoopProperties(const Loop *L) { ScalarEvolution::getLoopProperties(const Loop *L) {
typedef ScalarEvolution::LoopProperties LoopProperties; using LoopProperties = ScalarEvolution::LoopProperties;
auto Itr = LoopPropertiesCache.find(L); auto Itr = LoopPropertiesCache.find(L);
if (Itr == LoopPropertiesCache.end()) { if (Itr == LoopPropertiesCache.end()) {
@ -5901,7 +5933,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
} }
break; break;
case Instruction::AShr: case Instruction::AShr: {
// AShr X, C, where C is a constant. // AShr X, C, where C is a constant.
ConstantInt *CI = dyn_cast<ConstantInt>(BO->RHS); ConstantInt *CI = dyn_cast<ConstantInt>(BO->RHS);
if (!CI) if (!CI)
@ -5953,6 +5985,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
} }
break; break;
} }
}
} }
switch (U->getOpcode()) { switch (U->getOpcode()) {
@ -6017,8 +6050,6 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
return getUnknown(V); return getUnknown(V);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Iteration Count Computation Code // Iteration Count Computation Code
// //
@ -6413,7 +6444,7 @@ bool ScalarEvolution::BackedgeTakenInfo::hasOperand(const SCEV *S,
} }
ScalarEvolution::ExitLimit::ExitLimit(const SCEV *E) ScalarEvolution::ExitLimit::ExitLimit(const SCEV *E)
: ExactNotTaken(E), MaxNotTaken(E), MaxOrZero(false) { : ExactNotTaken(E), MaxNotTaken(E) {
assert((isa<SCEVCouldNotCompute>(MaxNotTaken) || assert((isa<SCEVCouldNotCompute>(MaxNotTaken) ||
isa<SCEVConstant>(MaxNotTaken)) && isa<SCEVConstant>(MaxNotTaken)) &&
"No point in having a non-constant max backedge taken count!"); "No point in having a non-constant max backedge taken count!");
@ -6458,7 +6489,8 @@ ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
&&ExitCounts, &&ExitCounts,
bool Complete, const SCEV *MaxCount, bool MaxOrZero) bool Complete, const SCEV *MaxCount, bool MaxOrZero)
: MaxAndComplete(MaxCount, Complete), MaxOrZero(MaxOrZero) { : MaxAndComplete(MaxCount, Complete), MaxOrZero(MaxOrZero) {
typedef ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo EdgeExitInfo; using EdgeExitInfo = ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo;
ExitNotTaken.reserve(ExitCounts.size()); ExitNotTaken.reserve(ExitCounts.size());
std::transform( std::transform(
ExitCounts.begin(), ExitCounts.end(), std::back_inserter(ExitNotTaken), ExitCounts.begin(), ExitCounts.end(), std::back_inserter(ExitNotTaken),
@ -6490,7 +6522,7 @@ ScalarEvolution::computeBackedgeTakenCount(const Loop *L,
SmallVector<BasicBlock *, 8> ExitingBlocks; SmallVector<BasicBlock *, 8> ExitingBlocks;
L->getExitingBlocks(ExitingBlocks); L->getExitingBlocks(ExitingBlocks);
typedef ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo EdgeExitInfo; using EdgeExitInfo = ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo;
SmallVector<EdgeExitInfo, 4> ExitCounts; SmallVector<EdgeExitInfo, 4> ExitCounts;
bool CouldComputeBECount = true; bool CouldComputeBECount = true;
@ -6570,7 +6602,6 @@ ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
ScalarEvolution::ExitLimit ScalarEvolution::ExitLimit
ScalarEvolution::computeExitLimitImpl(const Loop *L, BasicBlock *ExitingBlock, ScalarEvolution::computeExitLimitImpl(const Loop *L, BasicBlock *ExitingBlock,
bool AllowPredicates) { bool AllowPredicates) {
// Okay, we've chosen an exiting block. See what condition causes us to exit // Okay, we've chosen an exiting block. See what condition causes us to exit
// at this block and remember the exit block and whether all other targets // at this block and remember the exit block and whether all other targets
// lead to the loop header. // lead to the loop header.
@ -6833,7 +6864,6 @@ ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
BasicBlock *FBB, BasicBlock *FBB,
bool ControlsExit, bool ControlsExit,
bool AllowPredicates) { bool AllowPredicates) {
// If the condition was exit on true, convert the condition to exit on false // If the condition was exit on true, convert the condition to exit on false
ICmpInst::Predicate Cond; ICmpInst::Predicate Cond;
if (!L->contains(FBB)) if (!L->contains(FBB))
@ -6968,7 +6998,6 @@ ScalarEvolution::computeLoadConstantCompareExitLimit(
Constant *RHS, Constant *RHS,
const Loop *L, const Loop *L,
ICmpInst::Predicate predicate) { ICmpInst::Predicate predicate) {
if (LI->isVolatile()) return getCouldNotCompute(); if (LI->isVolatile()) return getCouldNotCompute();
// Check to see if the loaded pointer is a getelementptr of a global. // Check to see if the loaded pointer is a getelementptr of a global.
@ -7887,7 +7916,6 @@ static const SCEV *SolveLinEquationWithOverflow(const APInt &A, const SCEV *B,
/// Find the roots of the quadratic equation for the given quadratic chrec /// Find the roots of the quadratic equation for the given quadratic chrec
/// {L,+,M,+,N}. This returns either the two roots (which might be the same) or /// {L,+,M,+,N}. This returns either the two roots (which might be the same) or
/// two SCEVCouldNotCompute objects. /// two SCEVCouldNotCompute objects.
///
static Optional<std::pair<const SCEVConstant *,const SCEVConstant *>> static Optional<std::pair<const SCEVConstant *,const SCEVConstant *>>
SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) { SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) {
assert(AddRec->getNumOperands() == 3 && "This is not a quadratic chrec!"); assert(AddRec->getNumOperands() == 3 && "This is not a quadratic chrec!");
@ -8128,7 +8156,6 @@ ScalarEvolution::getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB) {
/// expressions are equal, however for the purposes of looking for a condition /// expressions are equal, however for the purposes of looking for a condition
/// guarding a loop, it can be useful to be a little more general, since a /// guarding a loop, it can be useful to be a little more general, since a
/// front-end may have replicated the controlling expression. /// front-end may have replicated the controlling expression.
///
static bool HasSameValue(const SCEV *A, const SCEV *B) { static bool HasSameValue(const SCEV *A, const SCEV *B) {
// Quick check to see if they are the same SCEV. // Quick check to see if they are the same SCEV.
if (A == B) return true; if (A == B) return true;
@ -8575,7 +8602,6 @@ bool ScalarEvolution::isKnownPredicateViaConstantRanges(
bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred, bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *LHS,
const SCEV *RHS) { const SCEV *RHS) {
// Match Result to (X + Y)<ExpectedFlags> where Y is a constant integer. // Match Result to (X + Y)<ExpectedFlags> where Y is a constant integer.
// Return Y via OutY. // Return Y via OutY.
auto MatchBinaryAddToConst = auto MatchBinaryAddToConst =
@ -8741,7 +8767,6 @@ ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,
for (DomTreeNode *DTN = DT[Latch], *HeaderDTN = DT[L->getHeader()]; for (DomTreeNode *DTN = DT[Latch], *HeaderDTN = DT[L->getHeader()];
DTN != HeaderDTN; DTN = DTN->getIDom()) { DTN != HeaderDTN; DTN = DTN->getIDom()) {
assert(DTN && "should reach the loop header before reaching the root!"); assert(DTN && "should reach the loop header before reaching the root!");
BasicBlock *BB = DTN->getBlock(); BasicBlock *BB = DTN->getBlock();
@ -9164,7 +9189,6 @@ bool ScalarEvolution::isImpliedCondOperands(ICmpInst::Predicate Pred,
getNotSCEV(FoundLHS)); getNotSCEV(FoundLHS));
} }
/// If Expr computes ~A, return A else return nullptr /// If Expr computes ~A, return A else return nullptr
static const SCEV *MatchNotExpr(const SCEV *Expr) { static const SCEV *MatchNotExpr(const SCEV *Expr) {
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Expr); const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Expr);
@ -9180,7 +9204,6 @@ static const SCEV *MatchNotExpr(const SCEV *Expr) {
return AddRHS->getOperand(1); return AddRHS->getOperand(1);
} }
/// Is MaybeMaxExpr an SMax or UMax of Candidate and some other values? /// Is MaybeMaxExpr an SMax or UMax of Candidate and some other values?
template<typename MaxExprType> template<typename MaxExprType>
static bool IsMaxConsistingOf(const SCEV *MaybeMaxExpr, static bool IsMaxConsistingOf(const SCEV *MaybeMaxExpr,
@ -9191,7 +9214,6 @@ static bool IsMaxConsistingOf(const SCEV *MaybeMaxExpr,
return find(MaxExpr->operands(), Candidate) != MaxExpr->op_end(); return find(MaxExpr->operands(), Candidate) != MaxExpr->op_end();
} }
/// Is MaybeMinExpr an SMin or UMin of Candidate and some other values? /// Is MaybeMinExpr an SMin or UMin of Candidate and some other values?
template<typename MaxExprType> template<typename MaxExprType>
static bool IsMinConsistingOf(ScalarEvolution &SE, static bool IsMinConsistingOf(ScalarEvolution &SE,
@ -9207,7 +9229,6 @@ static bool IsMinConsistingOf(ScalarEvolution &SE,
static bool IsKnownPredicateViaAddRecStart(ScalarEvolution &SE, static bool IsKnownPredicateViaAddRecStart(ScalarEvolution &SE,
ICmpInst::Predicate Pred, ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS) { const SCEV *LHS, const SCEV *RHS) {
// If both sides are affine addrecs for the same loop, with equal // If both sides are affine addrecs for the same loop, with equal
// steps, and we know the recurrences don't wrap, then we only // steps, and we know the recurrences don't wrap, then we only
// need to check the predicate on the starting values. // need to check the predicate on the starting values.
@ -9343,7 +9364,9 @@ bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
} else if (auto *LHSUnknownExpr = dyn_cast<SCEVUnknown>(LHS)) { } else if (auto *LHSUnknownExpr = dyn_cast<SCEVUnknown>(LHS)) {
Value *LL, *LR; Value *LL, *LR;
// FIXME: Once we have SDiv implemented, we can get rid of this matching. // FIXME: Once we have SDiv implemented, we can get rid of this matching.
using namespace llvm::PatternMatch; using namespace llvm::PatternMatch;
if (match(LHSUnknownExpr->getValue(), m_SDiv(m_Value(LL), m_Value(LR)))) { if (match(LHSUnknownExpr->getValue(), m_SDiv(m_Value(LL), m_Value(LR)))) {
// Rules for division. // Rules for division.
// We are going to perform some comparisons with Denominator and its // We are going to perform some comparisons with Denominator and its
@ -9636,7 +9659,6 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
if (PredicatedIV || !NoWrap || isKnownNonPositive(Stride) || if (PredicatedIV || !NoWrap || isKnownNonPositive(Stride) ||
!loopHasNoSideEffects(L)) !loopHasNoSideEffects(L))
return getCouldNotCompute(); return getCouldNotCompute();
} else if (!Stride->isOne() && } else if (!Stride->isOne() &&
doesIVOverflowOnLT(RHS, Stride, IsSigned, NoWrap)) doesIVOverflowOnLT(RHS, Stride, IsSigned, NoWrap))
// Avoid proven overflow cases: this will ensure that the backedge taken // Avoid proven overflow cases: this will ensure that the backedge taken
@ -9922,6 +9944,7 @@ static inline bool containsUndefs(const SCEV *S) {
} }
namespace { namespace {
// Collect all steps of SCEV expressions. // Collect all steps of SCEV expressions.
struct SCEVCollectStrides { struct SCEVCollectStrides {
ScalarEvolution &SE; ScalarEvolution &SE;
@ -9935,6 +9958,7 @@ struct SCEVCollectStrides {
Strides.push_back(AR->getStepRecurrence(SE)); Strides.push_back(AR->getStepRecurrence(SE));
return true; return true;
} }
bool isDone() const { return false; } bool isDone() const { return false; }
}; };
@ -9942,8 +9966,7 @@ struct SCEVCollectStrides {
struct SCEVCollectTerms { struct SCEVCollectTerms {
SmallVectorImpl<const SCEV *> &Terms; SmallVectorImpl<const SCEV *> &Terms;
SCEVCollectTerms(SmallVectorImpl<const SCEV *> &T) SCEVCollectTerms(SmallVectorImpl<const SCEV *> &T) : Terms(T) {}
: Terms(T) {}
bool follow(const SCEV *S) { bool follow(const SCEV *S) {
if (isa<SCEVUnknown>(S) || isa<SCEVMulExpr>(S) || if (isa<SCEVUnknown>(S) || isa<SCEVMulExpr>(S) ||
@ -9958,6 +9981,7 @@ struct SCEVCollectTerms {
// Keep looking. // Keep looking.
return true; return true;
} }
bool isDone() const { return false; } bool isDone() const { return false; }
}; };
@ -9966,7 +9990,7 @@ struct SCEVHasAddRec {
bool &ContainsAddRec; bool &ContainsAddRec;
SCEVHasAddRec(bool &ContainsAddRec) : ContainsAddRec(ContainsAddRec) { SCEVHasAddRec(bool &ContainsAddRec) : ContainsAddRec(ContainsAddRec) {
ContainsAddRec = false; ContainsAddRec = false;
} }
bool follow(const SCEV *S) { bool follow(const SCEV *S) {
@ -9980,6 +10004,7 @@ struct SCEVHasAddRec {
// Keep looking. // Keep looking.
return true; return true;
} }
bool isDone() const { return false; } bool isDone() const { return false; }
}; };
@ -10033,9 +10058,11 @@ struct SCEVCollectAddRecMultiplies {
// Keep looking. // Keep looking.
return true; return true;
} }
bool isDone() const { return false; } bool isDone() const { return false; }
}; };
}
} // end anonymous namespace
/// Find parametric terms in this SCEVAddRecExpr. We first for parameters in /// Find parametric terms in this SCEVAddRecExpr. We first for parameters in
/// two places: /// two places:
@ -10114,7 +10141,6 @@ static bool findArrayDimensionsRec(ScalarEvolution &SE,
return true; return true;
} }
// Returns true when one of the SCEVs of Terms contains a SCEVUnknown parameter. // Returns true when one of the SCEVs of Terms contains a SCEVUnknown parameter.
static inline bool containsParameters(SmallVectorImpl<const SCEV *> &Terms) { static inline bool containsParameters(SmallVectorImpl<const SCEV *> &Terms) {
for (const SCEV *T : Terms) for (const SCEV *T : Terms)
@ -10229,7 +10255,6 @@ void ScalarEvolution::findArrayDimensions(SmallVectorImpl<const SCEV *> &Terms,
void ScalarEvolution::computeAccessFunctions( void ScalarEvolution::computeAccessFunctions(
const SCEV *Expr, SmallVectorImpl<const SCEV *> &Subscripts, const SCEV *Expr, SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes) { SmallVectorImpl<const SCEV *> &Sizes) {
// Early exit in case this SCEV is not an affine multivariate function. // Early exit in case this SCEV is not an affine multivariate function.
if (Sizes.empty()) if (Sizes.empty())
return; return;
@ -10333,7 +10358,6 @@ void ScalarEvolution::computeAccessFunctions(
/// DelinearizationPass that walks through all loads and stores of a function /// DelinearizationPass that walks through all loads and stores of a function
/// asking for the SCEV of the memory access with respect to all enclosing /// asking for the SCEV of the memory access with respect to all enclosing
/// loops, calling SCEV->delinearize on that and printing the results. /// loops, calling SCEV->delinearize on that and printing the results.
void ScalarEvolution::delinearize(const SCEV *Expr, void ScalarEvolution::delinearize(const SCEV *Expr,
SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes, SmallVectorImpl<const SCEV *> &Sizes,
@ -10422,11 +10446,8 @@ ScalarEvolution::ScalarEvolution(Function &F, TargetLibraryInfo &TLI,
AssumptionCache &AC, DominatorTree &DT, AssumptionCache &AC, DominatorTree &DT,
LoopInfo &LI) LoopInfo &LI)
: F(F), TLI(TLI), AC(AC), DT(DT), LI(LI), : F(F), TLI(TLI), AC(AC), DT(DT), LI(LI),
CouldNotCompute(new SCEVCouldNotCompute()), CouldNotCompute(new SCEVCouldNotCompute()), ValuesAtScopes(64),
WalkingBEDominatingConds(false), ProvingSplitPredicate(false), LoopDispositions(64), BlockDispositions(64) {
ValuesAtScopes(64), LoopDispositions(64), BlockDispositions(64),
FirstUnknown(nullptr) {
// To use guards for proving predicates, we need to scan every instruction in // To use guards for proving predicates, we need to scan every instruction in
// relevant basic blocks, and not just terminators. Doing this is a waste of // relevant basic blocks, and not just terminators. Doing this is a waste of
// time if the IR does not actually contain any calls to // time if the IR does not actually contain any calls to
@ -10447,7 +10468,6 @@ ScalarEvolution::ScalarEvolution(ScalarEvolution &&Arg)
LI(Arg.LI), CouldNotCompute(std::move(Arg.CouldNotCompute)), LI(Arg.LI), CouldNotCompute(std::move(Arg.CouldNotCompute)),
ValueExprMap(std::move(Arg.ValueExprMap)), ValueExprMap(std::move(Arg.ValueExprMap)),
PendingLoopPredicates(std::move(Arg.PendingLoopPredicates)), PendingLoopPredicates(std::move(Arg.PendingLoopPredicates)),
WalkingBEDominatingConds(false), ProvingSplitPredicate(false),
MinTrailingZerosCache(std::move(Arg.MinTrailingZerosCache)), MinTrailingZerosCache(std::move(Arg.MinTrailingZerosCache)),
BackedgeTakenCounts(std::move(Arg.BackedgeTakenCounts)), BackedgeTakenCounts(std::move(Arg.BackedgeTakenCounts)),
PredicatedBackedgeTakenCounts( PredicatedBackedgeTakenCounts(
@ -10914,9 +10934,12 @@ void ScalarEvolution::verify() const {
// Map's SCEV expressions from one ScalarEvolution "universe" to another. // Map's SCEV expressions from one ScalarEvolution "universe" to another.
struct SCEVMapper : public SCEVRewriteVisitor<SCEVMapper> { struct SCEVMapper : public SCEVRewriteVisitor<SCEVMapper> {
SCEVMapper(ScalarEvolution &SE) : SCEVRewriteVisitor<SCEVMapper>(SE) {}
const SCEV *visitConstant(const SCEVConstant *Constant) { const SCEV *visitConstant(const SCEVConstant *Constant) {
return SE.getConstant(Constant->getAPInt()); return SE.getConstant(Constant->getAPInt());
} }
const SCEV *visitUnknown(const SCEVUnknown *Expr) { const SCEV *visitUnknown(const SCEVUnknown *Expr) {
return SE.getUnknown(Expr->getValue()); return SE.getUnknown(Expr->getValue());
} }
@ -10924,7 +10947,6 @@ void ScalarEvolution::verify() const {
const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) { const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
return SE.getCouldNotCompute(); return SE.getCouldNotCompute();
} }
SCEVMapper(ScalarEvolution &SE) : SCEVRewriteVisitor<SCEVMapper>(SE) {}
}; };
SCEVMapper SCM(SE2); SCEVMapper SCM(SE2);
@ -11013,6 +11035,7 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(ScalarEvolutionWrapperPass, "scalar-evolution", INITIALIZE_PASS_END(ScalarEvolutionWrapperPass, "scalar-evolution",
"Scalar Evolution Analysis", false, true) "Scalar Evolution Analysis", false, true)
char ScalarEvolutionWrapperPass::ID = 0; char ScalarEvolutionWrapperPass::ID = 0;
ScalarEvolutionWrapperPass::ScalarEvolutionWrapperPass() : FunctionPass(ID) { ScalarEvolutionWrapperPass::ScalarEvolutionWrapperPass() : FunctionPass(ID) {
@ -11088,6 +11111,11 @@ namespace {
class SCEVPredicateRewriter : public SCEVRewriteVisitor<SCEVPredicateRewriter> { class SCEVPredicateRewriter : public SCEVRewriteVisitor<SCEVPredicateRewriter> {
public: public:
SCEVPredicateRewriter(const Loop *L, ScalarEvolution &SE,
SmallPtrSetImpl<const SCEVPredicate *> *NewPreds,
SCEVUnionPredicate *Pred)
: SCEVRewriteVisitor(SE), NewPreds(NewPreds), Pred(Pred), L(L) {}
/// Rewrites \p S in the context of a loop L and the SCEV predication /// Rewrites \p S in the context of a loop L and the SCEV predication
/// infrastructure. /// infrastructure.
/// ///
@ -11103,11 +11131,6 @@ public:
return Rewriter.visit(S); return Rewriter.visit(S);
} }
SCEVPredicateRewriter(const Loop *L, ScalarEvolution &SE,
SmallPtrSetImpl<const SCEVPredicate *> *NewPreds,
SCEVUnionPredicate *Pred)
: SCEVRewriteVisitor(SE), NewPreds(NewPreds), Pred(Pred), L(L) {}
const SCEV *visitUnknown(const SCEVUnknown *Expr) { const SCEV *visitUnknown(const SCEVUnknown *Expr) {
if (Pred) { if (Pred) {
auto ExprPreds = Pred->getPredicatesForExpr(Expr); auto ExprPreds = Pred->getPredicatesForExpr(Expr);
@ -11191,6 +11214,7 @@ private:
SCEVUnionPredicate *Pred; SCEVUnionPredicate *Pred;
const Loop *L; const Loop *L;
}; };
} // end anonymous namespace } // end anonymous namespace
const SCEV *ScalarEvolution::rewriteUsingPredicate(const SCEV *S, const Loop *L, const SCEV *ScalarEvolution::rewriteUsingPredicate(const SCEV *S, const Loop *L,
@ -11201,7 +11225,6 @@ const SCEV *ScalarEvolution::rewriteUsingPredicate(const SCEV *S, const Loop *L,
const SCEVAddRecExpr *ScalarEvolution::convertSCEVToAddRecWithPredicates( const SCEVAddRecExpr *ScalarEvolution::convertSCEVToAddRecWithPredicates(
const SCEV *S, const Loop *L, const SCEV *S, const Loop *L,
SmallPtrSetImpl<const SCEVPredicate *> &Preds) { SmallPtrSetImpl<const SCEVPredicate *> &Preds) {
SmallPtrSet<const SCEVPredicate *, 4> TransformPreds; SmallPtrSet<const SCEVPredicate *, 4> TransformPreds;
S = SCEVPredicateRewriter::rewrite(S, L, *this, &TransformPreds, nullptr); S = SCEVPredicateRewriter::rewrite(S, L, *this, &TransformPreds, nullptr);
auto *AddRec = dyn_cast<SCEVAddRecExpr>(S); auto *AddRec = dyn_cast<SCEVAddRecExpr>(S);
@ -11357,7 +11380,7 @@ void SCEVUnionPredicate::add(const SCEVPredicate *N) {
PredicatedScalarEvolution::PredicatedScalarEvolution(ScalarEvolution &SE, PredicatedScalarEvolution::PredicatedScalarEvolution(ScalarEvolution &SE,
Loop &L) Loop &L)
: SE(SE), L(L), Generation(0), BackedgeCount(nullptr) {} : SE(SE), L(L) {}
const SCEV *PredicatedScalarEvolution::getSCEV(Value *V) { const SCEV *PredicatedScalarEvolution::getSCEV(Value *V) {
const SCEV *Expr = SE.getSCEV(V); const SCEV *Expr = SE.getSCEV(V);

View File

@ -34,11 +34,12 @@
#include "llvm/Analysis/ScopedNoAliasAA.h" #include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h" #include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h" #include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
using namespace llvm; using namespace llvm;
@ -50,14 +51,15 @@ static cl::opt<bool> EnableScopedNoAlias("enable-scoped-noalias",
cl::init(true)); cl::init(true));
namespace { namespace {
/// This is a simple wrapper around an MDNode which provides a higher-level /// This is a simple wrapper around an MDNode which provides a higher-level
/// interface by hiding the details of how alias analysis information is encoded /// interface by hiding the details of how alias analysis information is encoded
/// in its operands. /// in its operands.
class AliasScopeNode { class AliasScopeNode {
const MDNode *Node; const MDNode *Node = nullptr;
public: public:
AliasScopeNode() : Node(nullptr) {} AliasScopeNode() = default;
explicit AliasScopeNode(const MDNode *N) : Node(N) {} explicit AliasScopeNode(const MDNode *N) : Node(N) {}
/// Get the MDNode for this AliasScopeNode. /// Get the MDNode for this AliasScopeNode.
@ -70,7 +72,8 @@ public:
return dyn_cast_or_null<MDNode>(Node->getOperand(1)); return dyn_cast_or_null<MDNode>(Node->getOperand(1));
} }
}; };
} // end of anonymous namespace
} // end anonymous namespace
AliasResult ScopedNoAliasAAResult::alias(const MemoryLocation &LocA, AliasResult ScopedNoAliasAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB) { const MemoryLocation &LocB) {
@ -181,6 +184,7 @@ ScopedNoAliasAAResult ScopedNoAliasAA::run(Function &F,
} }
char ScopedNoAliasAAWrapperPass::ID = 0; char ScopedNoAliasAAWrapperPass::ID = 0;
INITIALIZE_PASS(ScopedNoAliasAAWrapperPass, "scoped-noalias", INITIALIZE_PASS(ScopedNoAliasAAWrapperPass, "scoped-noalias",
"Scoped NoAlias Alias Analysis", false, true) "Scoped NoAlias Alias Analysis", false, true)

View File

@ -13,11 +13,21 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/SparsePropagation.h" #include "llvm/Analysis/SparsePropagation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/User.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "sparseprop" #define DEBUG_TYPE "sparseprop"
@ -26,7 +36,7 @@ using namespace llvm;
// AbstractLatticeFunction Implementation // AbstractLatticeFunction Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
AbstractLatticeFunction::~AbstractLatticeFunction() {} AbstractLatticeFunction::~AbstractLatticeFunction() = default;
/// PrintValue - Render the specified lattice value to the specified stream. /// PrintValue - Render the specified lattice value to the specified stream.
void AbstractLatticeFunction::PrintValue(LatticeVal V, raw_ostream &OS) { void AbstractLatticeFunction::PrintValue(LatticeVal V, raw_ostream &OS) {
@ -49,7 +59,6 @@ void AbstractLatticeFunction::PrintValue(LatticeVal V, raw_ostream &OS) {
/// map yet. This function is necessary because not all values should start /// map yet. This function is necessary because not all values should start
/// out in the underdefined state... Arguments should be overdefined, and /// out in the underdefined state... Arguments should be overdefined, and
/// constants should be marked as constants. /// constants should be marked as constants.
///
SparseSolver::LatticeVal SparseSolver::getOrInitValueState(Value *V) { SparseSolver::LatticeVal SparseSolver::getOrInitValueState(Value *V) {
DenseMap<Value*, LatticeVal>::iterator I = ValueState.find(V); DenseMap<Value*, LatticeVal>::iterator I = ValueState.find(V);
if (I != ValueState.end()) return I->second; // Common case, in the map if (I != ValueState.end()) return I->second; // Common case, in the map
@ -109,13 +118,11 @@ void SparseSolver::markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
// because they have potentially new operands. // because they have potentially new operands.
for (BasicBlock::iterator I = Dest->begin(); isa<PHINode>(I); ++I) for (BasicBlock::iterator I = Dest->begin(); isa<PHINode>(I); ++I)
visitPHINode(*cast<PHINode>(I)); visitPHINode(*cast<PHINode>(I));
} else { } else {
MarkBlockExecutable(Dest); MarkBlockExecutable(Dest);
} }
} }
/// getFeasibleSuccessors - Return a vector of booleans to indicate which /// getFeasibleSuccessors - Return a vector of booleans to indicate which
/// successors are reachable from a given terminator instruction. /// successors are reachable from a given terminator instruction.
void SparseSolver::getFeasibleSuccessors(TerminatorInst &TI, void SparseSolver::getFeasibleSuccessors(TerminatorInst &TI,
@ -199,7 +206,6 @@ void SparseSolver::getFeasibleSuccessors(TerminatorInst &TI,
Succs[Case.getSuccessorIndex()] = true; Succs[Case.getSuccessorIndex()] = true;
} }
/// isEdgeFeasible - Return true if the control flow edge from the 'From' /// isEdgeFeasible - Return true if the control flow edge from the 'From'
/// basic block to the 'To' basic block is currently feasible... /// basic block to the 'To' basic block is currently feasible...
bool SparseSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To, bool SparseSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To,
@ -273,7 +279,6 @@ void SparseSolver::visitPHINode(PHINode &PN) {
UpdateState(PN, PNIV); UpdateState(PN, PNIV);
} }
void SparseSolver::visitInst(Instruction &I) { void SparseSolver::visitInst(Instruction &I) {
// PHIs are handled by the propagation logic, they are never passed into the // PHIs are handled by the propagation logic, they are never passed into the
// transfer functions. // transfer functions.
@ -344,4 +349,3 @@ void SparseSolver::Print(Function &F, raw_ostream &OS) const {
OS << "\n"; OS << "\n";
} }
} }

View File

@ -123,10 +123,20 @@
#include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Metadata.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
using namespace llvm; using namespace llvm;
// A handy option for disabling TBAA functionality. The same effect can also be // A handy option for disabling TBAA functionality. The same effect can also be
@ -135,15 +145,16 @@ using namespace llvm;
static cl::opt<bool> EnableTBAA("enable-tbaa", cl::init(true)); static cl::opt<bool> EnableTBAA("enable-tbaa", cl::init(true));
namespace { namespace {
/// This is a simple wrapper around an MDNode which provides a higher-level /// This is a simple wrapper around an MDNode which provides a higher-level
/// interface by hiding the details of how alias analysis information is encoded /// interface by hiding the details of how alias analysis information is encoded
/// in its operands. /// in its operands.
template<typename MDNodeTy> template<typename MDNodeTy>
class TBAANodeImpl { class TBAANodeImpl {
MDNodeTy *Node; MDNodeTy *Node = nullptr;
public: public:
TBAANodeImpl() : Node(nullptr) {} TBAANodeImpl() = default;
explicit TBAANodeImpl(MDNodeTy *N) : Node(N) {} explicit TBAANodeImpl(MDNodeTy *N) : Node(N) {}
/// getNode - Get the MDNode for this TBAANode. /// getNode - Get the MDNode for this TBAANode.
@ -176,8 +187,8 @@ public:
/// \name Specializations of \c TBAANodeImpl for const and non const qualified /// \name Specializations of \c TBAANodeImpl for const and non const qualified
/// \c MDNode. /// \c MDNode.
/// @{ /// @{
typedef TBAANodeImpl<const MDNode> TBAANode; using TBAANode = TBAANodeImpl<const MDNode>;
typedef TBAANodeImpl<MDNode> MutableTBAANode; using MutableTBAANode = TBAANodeImpl<MDNode>;
/// @} /// @}
/// This is a simple wrapper around an MDNode which provides a /// This is a simple wrapper around an MDNode which provides a
@ -197,12 +208,15 @@ public:
MDNodeTy *getBaseType() const { MDNodeTy *getBaseType() const {
return dyn_cast_or_null<MDNode>(Node->getOperand(0)); return dyn_cast_or_null<MDNode>(Node->getOperand(0));
} }
MDNodeTy *getAccessType() const { MDNodeTy *getAccessType() const {
return dyn_cast_or_null<MDNode>(Node->getOperand(1)); return dyn_cast_or_null<MDNode>(Node->getOperand(1));
} }
uint64_t getOffset() const { uint64_t getOffset() const {
return mdconst::extract<ConstantInt>(Node->getOperand(2))->getZExtValue(); return mdconst::extract<ConstantInt>(Node->getOperand(2))->getZExtValue();
} }
/// Test if this TBAAStructTagNode represents a type for objects /// Test if this TBAAStructTagNode represents a type for objects
/// which are not modified (by any means) in the context where this /// which are not modified (by any means) in the context where this
/// AliasAnalysis is relevant. /// AliasAnalysis is relevant.
@ -219,8 +233,8 @@ public:
/// \name Specializations of \c TBAAStructTagNodeImpl for const and non const /// \name Specializations of \c TBAAStructTagNodeImpl for const and non const
/// qualified \c MDNods. /// qualified \c MDNods.
/// @{ /// @{
typedef TBAAStructTagNodeImpl<const MDNode> TBAAStructTagNode; using TBAAStructTagNode = TBAAStructTagNodeImpl<const MDNode>;
typedef TBAAStructTagNodeImpl<MDNode> MutableTBAAStructTagNode; using MutableTBAAStructTagNode = TBAAStructTagNodeImpl<MDNode>;
/// @} /// @}
/// This is a simple wrapper around an MDNode which provides a /// This is a simple wrapper around an MDNode which provides a
@ -228,10 +242,10 @@ typedef TBAAStructTagNodeImpl<MDNode> MutableTBAAStructTagNode;
/// information is encoded in its operands. /// information is encoded in its operands.
class TBAAStructTypeNode { class TBAAStructTypeNode {
/// This node should be created with createTBAAStructTypeNode. /// This node should be created with createTBAAStructTypeNode.
const MDNode *Node; const MDNode *Node = nullptr;
public: public:
TBAAStructTypeNode() : Node(nullptr) {} TBAAStructTypeNode() = default;
explicit TBAAStructTypeNode(const MDNode *N) : Node(N) {} explicit TBAAStructTypeNode(const MDNode *N) : Node(N) {}
/// Get the MDNode for this TBAAStructTypeNode. /// Get the MDNode for this TBAAStructTypeNode.
@ -283,7 +297,8 @@ public:
return TBAAStructTypeNode(P); return TBAAStructTypeNode(P);
} }
}; };
}
} // end anonymous namespace
/// Check the first operand of the tbaa tag node, if it is a MDNode, we treat /// Check the first operand of the tbaa tag node, if it is a MDNode, we treat
/// it as struct-path aware TBAA format, otherwise, we treat it as scalar TBAA /// it as struct-path aware TBAA format, otherwise, we treat it as scalar TBAA