1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

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

llvm-svn: 311048
This commit is contained in:
Eugene Zelenko 2017-08-16 22:07:40 +00:00
parent 6a4ddfbe1b
commit 4b30ec0e2d
10 changed files with 311 additions and 167 deletions

View File

@ -1,4 +1,4 @@
//===- llvm/Analysis/MemoryBuiltins.h- Calls to memory builtins -*- C++ -*-===// //==- llvm/Analysis/MemoryBuiltins.h - Calls to memory builtins --*- C++ -*-==//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -15,21 +15,42 @@
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H #ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
#define LLVM_ANALYSIS_MEMORYBUILTINS_H #define LLVM_ANALYSIS_MEMORYBUILTINS_H
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/TargetFolder.h" #include "llvm/Analysis/TargetFolder.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstVisitor.h" #include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueHandle.h"
#include "llvm/Support/DataTypes.h" #include <cstdint>
#include <utility>
namespace llvm { namespace llvm {
class AllocaInst;
class Argument;
class CallInst; class CallInst;
class PointerType; class ConstantInt;
class ConstantPointerNull;
class DataLayout; class DataLayout;
class ExtractElementInst;
class ExtractValueInst;
class GEPOperator;
class GlobalAlias;
class GlobalVariable;
class Instruction;
class IntegerType;
class IntrinsicInst;
class IntToPtrInst;
class LLVMContext;
class LoadInst;
class PHINode;
class PointerType;
class SelectInst;
class TargetLibraryInfo; class TargetLibraryInfo;
class Type; class Type;
class UndefValue;
class Value; class Value;
/// \brief Tests if a value is a call or invoke to a library function that /// \brief Tests if a value is a call or invoke to a library function that
@ -123,7 +144,6 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI)); return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI));
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Utility functions to compute size of objects. // Utility functions to compute size of objects.
// //
@ -169,13 +189,12 @@ ConstantInt *lowerObjectSizeCall(IntrinsicInst *ObjectSize,
const TargetLibraryInfo *TLI, const TargetLibraryInfo *TLI,
bool MustSucceed); bool MustSucceed);
typedef std::pair<APInt, APInt> SizeOffsetType; using SizeOffsetType = std::pair<APInt, APInt>;
/// \brief Evaluate the size and offset of an object pointed to by a Value* /// \brief Evaluate the size and offset of an object pointed to by a Value*
/// statically. Fails if size or offset are not known at compile time. /// statically. Fails if size or offset are not known at compile time.
class ObjectSizeOffsetVisitor class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> { : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
const DataLayout &DL; const DataLayout &DL;
const TargetLibraryInfo *TLI; const TargetLibraryInfo *TLI;
ObjectSizeOpts Options; ObjectSizeOpts Options;
@ -229,18 +248,16 @@ private:
bool CheckedZextOrTrunc(APInt &I); bool CheckedZextOrTrunc(APInt &I);
}; };
typedef std::pair<Value*, Value*> SizeOffsetEvalType; using SizeOffsetEvalType = std::pair<Value *, Value *>;
/// \brief Evaluate the size and offset of an object pointed to by a Value*. /// \brief Evaluate the size and offset of an object pointed to by a Value*.
/// May create code to compute the result at run-time. /// May create code to compute the result at run-time.
class ObjectSizeOffsetEvaluator class ObjectSizeOffsetEvaluator
: public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> { : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
using BuilderTy = IRBuilder<TargetFolder>;
typedef IRBuilder<TargetFolder> BuilderTy; using WeakEvalType = std::pair<WeakTrackingVH, WeakTrackingVH>;
typedef std::pair<WeakTrackingVH, WeakTrackingVH> WeakEvalType; using CacheMapTy = DenseMap<const Value *, WeakEvalType>;
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy; using PtrSetTy = SmallPtrSet<const Value *, 8>;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
const DataLayout &DL; const DataLayout &DL;
const TargetLibraryInfo *TLI; const TargetLibraryInfo *TLI;
@ -255,11 +272,13 @@ class ObjectSizeOffsetEvaluator
SizeOffsetEvalType unknown() { SizeOffsetEvalType unknown() {
return std::make_pair(nullptr, nullptr); return std::make_pair(nullptr, nullptr);
} }
SizeOffsetEvalType compute_(Value *V); SizeOffsetEvalType compute_(Value *V);
public: public:
ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI,
LLVMContext &Context, bool RoundToAlign = false); LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetEvalType compute(Value *V); SizeOffsetEvalType compute(Value *V);
bool knownSize(SizeOffsetEvalType SizeOffset) { bool knownSize(SizeOffsetEvalType SizeOffset) {
@ -291,6 +310,6 @@ public:
SizeOffsetEvalType visitInstruction(Instruction &I); SizeOffsetEvalType visitInstruction(Instruction &I);
}; };
} // End llvm namespace } // end namespace llvm
#endif #endif // LLVM_ANALYSIS_MEMORYBUILTINS_H

View File

@ -1,4 +1,4 @@
//===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps --*- C++ -*-===// //===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps ---*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -15,26 +15,35 @@
#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H #define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerEmbeddedInt.h" #include "llvm/ADT/PointerEmbeddedInt.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerSumType.h" #include "llvm/ADT/PointerSumType.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/BasicBlock.h" #include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include "llvm/IR/PredIteratorCache.h" #include "llvm/IR/PredIteratorCache.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <cstdint>
#include <utility>
#include <vector>
namespace llvm { namespace llvm {
class Function;
class FunctionPass;
class Instruction;
class CallSite;
class AssumptionCache; class AssumptionCache;
class MemoryDependenceResults; class CallSite;
class PredIteratorCache;
class DominatorTree; class DominatorTree;
class Function;
class Instruction;
class LoadInst;
class PHITransAddr; class PHITransAddr;
class TargetLibraryInfo;
class Value;
/// A memory dependence query can return one of three different answers. /// A memory dependence query can return one of three different answers.
class MemDepResult { class MemDepResult {
@ -105,17 +114,17 @@ class MemDepResult {
Unknown Unknown
}; };
typedef PointerSumType< using ValueTy = PointerSumType<
DepType, PointerSumTypeMember<Invalid, Instruction *>, DepType, PointerSumTypeMember<Invalid, Instruction *>,
PointerSumTypeMember<Clobber, Instruction *>, PointerSumTypeMember<Clobber, Instruction *>,
PointerSumTypeMember<Def, Instruction *>, PointerSumTypeMember<Def, Instruction *>,
PointerSumTypeMember<Other, PointerEmbeddedInt<OtherType, 3>>> PointerSumTypeMember<Other, PointerEmbeddedInt<OtherType, 3>>>;
ValueTy;
ValueTy Value; ValueTy Value;
explicit MemDepResult(ValueTy V) : Value(V) {} explicit MemDepResult(ValueTy V) : Value(V) {}
public: public:
MemDepResult() : Value() {} MemDepResult() = default;
/// get methods: These are static ctor methods for creating various /// get methods: These are static ctor methods for creating various
/// MemDepResult kinds. /// MemDepResult kinds.
@ -266,23 +275,23 @@ public:
/// internal caching mechanism. /// internal caching mechanism.
class MemoryDependenceResults { class MemoryDependenceResults {
// A map from instructions to their dependency. // A map from instructions to their dependency.
typedef DenseMap<Instruction *, MemDepResult> LocalDepMapType; using LocalDepMapType = DenseMap<Instruction *, MemDepResult>;
LocalDepMapType LocalDeps; LocalDepMapType LocalDeps;
public: public:
typedef std::vector<NonLocalDepEntry> NonLocalDepInfo; using NonLocalDepInfo = std::vector<NonLocalDepEntry>;
private: private:
/// A pair<Value*, bool> where the bool is true if the dependence is a read /// A pair<Value*, bool> where the bool is true if the dependence is a read
/// only dependence, false if read/write. /// only dependence, false if read/write.
typedef PointerIntPair<const Value *, 1, bool> ValueIsLoadPair; using ValueIsLoadPair = PointerIntPair<const Value *, 1, bool>;
/// This pair is used when caching information for a block. /// This pair is used when caching information for a block.
/// ///
/// If the pointer is null, the cache value is not a full query that starts /// If the pointer is null, the cache value is not a full query that starts
/// at the specified block. If non-null, the bool indicates whether or not /// at the specified block. If non-null, the bool indicates whether or not
/// the contents of the block was skipped. /// the contents of the block was skipped.
typedef PointerIntPair<BasicBlock *, 1, bool> BBSkipFirstBlockPair; using BBSkipFirstBlockPair = PointerIntPair<BasicBlock *, 1, bool>;
/// This record is the information kept for each (value, is load) pair. /// This record is the information kept for each (value, is load) pair.
struct NonLocalPointerInfo { struct NonLocalPointerInfo {
@ -293,31 +302,32 @@ private:
/// The maximum size of the dereferences of the pointer. /// The maximum size of the dereferences of the pointer.
/// ///
/// May be UnknownSize if the sizes are unknown. /// May be UnknownSize if the sizes are unknown.
uint64_t Size; uint64_t Size = MemoryLocation::UnknownSize;
/// The AA tags associated with dereferences of the pointer. /// The AA tags associated with dereferences of the pointer.
/// ///
/// The members may be null if there are no tags or conflicting tags. /// The members may be null if there are no tags or conflicting tags.
AAMDNodes AATags; AAMDNodes AATags;
NonLocalPointerInfo() : Size(MemoryLocation::UnknownSize) {} NonLocalPointerInfo() = default;
}; };
/// Cache storing single nonlocal def for the instruction. /// Cache storing single nonlocal def for the instruction.
/// It is set when nonlocal def would be found in function returning only /// It is set when nonlocal def would be found in function returning only
/// local dependencies. /// local dependencies.
DenseMap<Instruction *, NonLocalDepResult> NonLocalDefsCache; DenseMap<Instruction *, NonLocalDepResult> NonLocalDefsCache;
/// This map stores the cached results of doing a pointer lookup at the /// This map stores the cached results of doing a pointer lookup at the
/// bottom of a block. /// bottom of a block.
/// ///
/// The key of this map is the pointer+isload bit, the value is a list of /// The key of this map is the pointer+isload bit, the value is a list of
/// <bb->result> mappings. /// <bb->result> mappings.
typedef DenseMap<ValueIsLoadPair, NonLocalPointerInfo> using CachedNonLocalPointerInfo =
CachedNonLocalPointerInfo; DenseMap<ValueIsLoadPair, NonLocalPointerInfo>;
CachedNonLocalPointerInfo NonLocalPointerDeps; CachedNonLocalPointerInfo NonLocalPointerDeps;
// A map from instructions to their non-local pointer dependencies. // A map from instructions to their non-local pointer dependencies.
typedef DenseMap<Instruction *, SmallPtrSet<ValueIsLoadPair, 4>> using ReverseNonLocalPtrDepTy =
ReverseNonLocalPtrDepTy; DenseMap<Instruction *, SmallPtrSet<ValueIsLoadPair, 4>>;
ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps; ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
/// This is the instruction we keep for each cached access that we have for /// This is the instruction we keep for each cached access that we have for
@ -325,17 +335,17 @@ private:
/// ///
/// The pointer is an owning pointer and the bool indicates whether we have /// The pointer is an owning pointer and the bool indicates whether we have
/// any dirty bits in the set. /// any dirty bits in the set.
typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo; using PerInstNLInfo = std::pair<NonLocalDepInfo, bool>;
// A map from instructions to their non-local dependencies. // A map from instructions to their non-local dependencies.
typedef DenseMap<Instruction *, PerInstNLInfo> NonLocalDepMapType; using NonLocalDepMapType = DenseMap<Instruction *, PerInstNLInfo>;
NonLocalDepMapType NonLocalDeps; NonLocalDepMapType NonLocalDeps;
// A reverse mapping from dependencies to the dependees. This is // A reverse mapping from dependencies to the dependees. This is
// used when removing instructions to keep the cache coherent. // used when removing instructions to keep the cache coherent.
typedef DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> using ReverseDepMapType =
ReverseDepMapType; DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>>;
ReverseDepMapType ReverseLocalDeps; ReverseDepMapType ReverseLocalDeps;
// A reverse mapping from dependencies to the non-local dependees. // A reverse mapping from dependencies to the non-local dependees.
@ -493,10 +503,11 @@ private:
class MemoryDependenceAnalysis class MemoryDependenceAnalysis
: public AnalysisInfoMixin<MemoryDependenceAnalysis> { : public AnalysisInfoMixin<MemoryDependenceAnalysis> {
friend AnalysisInfoMixin<MemoryDependenceAnalysis>; friend AnalysisInfoMixin<MemoryDependenceAnalysis>;
static AnalysisKey Key; static AnalysisKey Key;
public: public:
typedef MemoryDependenceResults Result; using Result = MemoryDependenceResults;
MemoryDependenceResults run(Function &F, FunctionAnalysisManager &AM); MemoryDependenceResults run(Function &F, FunctionAnalysisManager &AM);
}; };
@ -505,10 +516,12 @@ public:
/// MemoryDepnedenceResults instance. /// MemoryDepnedenceResults instance.
class MemoryDependenceWrapperPass : public FunctionPass { class MemoryDependenceWrapperPass : public FunctionPass {
Optional<MemoryDependenceResults> MemDep; Optional<MemoryDependenceResults> MemDep;
public: public:
static char ID;
MemoryDependenceWrapperPass(); MemoryDependenceWrapperPass();
~MemoryDependenceWrapperPass() override; ~MemoryDependenceWrapperPass() override;
static char ID;
/// Pass Implementation stuff. This doesn't do any analysis eagerly. /// Pass Implementation stuff. This doesn't do any analysis eagerly.
bool runOnFunction(Function &) override; bool runOnFunction(Function &) override;
@ -522,6 +535,6 @@ public:
MemoryDependenceResults &getMemDep() { return *MemDep; } MemoryDependenceResults &getMemDep() { return *MemDep; }
}; };
} // End llvm namespace } // end namespace llvm
#endif #endif // LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H

View File

@ -6,7 +6,7 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// //
/// \file /// \file
/// \brief This file exposes an interface to building/using memory SSA to /// \brief This file exposes an interface to building/using memory SSA to
/// walk memory instructions using a use/def graph. /// walk memory instructions using a use/def graph.
@ -67,6 +67,7 @@
/// MemoryDefs are not disambiguated because it would require multiple reaching /// MemoryDefs are not disambiguated because it would require multiple reaching
/// definitions, which would require multiple phis, and multiple memoryaccesses /// definitions, which would require multiple phis, and multiple memoryaccesses
/// per instruction. /// per instruction.
//
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_MEMORYSSA_H #ifndef LLVM_ANALYSIS_MEMORYSSA_H
@ -80,6 +81,7 @@
#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/simple_ilist.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/PHITransAddr.h" #include "llvm/Analysis/PHITransAddr.h"
@ -87,14 +89,12 @@
#include "llvm/IR/DerivedUser.h" #include "llvm/IR/DerivedUser.h"
#include "llvm/IR/Dominators.h" #include "llvm/IR/Dominators.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Type.h" #include "llvm/IR/Type.h"
#include "llvm/IR/Use.h" #include "llvm/IR/Use.h"
#include "llvm/IR/User.h" #include "llvm/IR/User.h"
#include "llvm/IR/Value.h" #include "llvm/IR/Value.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
@ -107,12 +107,16 @@ namespace llvm {
class Function; class Function;
class Instruction; class Instruction;
class MemoryAccess; class MemoryAccess;
class MemorySSAWalker;
class LLVMContext; class LLVMContext;
class raw_ostream; class raw_ostream;
namespace MSSAHelpers { namespace MSSAHelpers {
struct AllAccessTag {}; struct AllAccessTag {};
struct DefsOnlyTag {}; struct DefsOnlyTag {};
}
} // end namespace MSSAHelpers
enum { enum {
// Used to signify what the default invalid ID is for MemoryAccess's // Used to signify what the default invalid ID is for MemoryAccess's
@ -137,6 +141,11 @@ public:
using DefsOnlyType = using DefsOnlyType =
ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>>; ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>>;
MemoryAccess(const MemoryAccess &) = delete;
MemoryAccess &operator=(const MemoryAccess &) = delete;
void *operator new(size_t) = delete;
// Methods for support type inquiry through isa, cast, and // Methods for support type inquiry through isa, cast, and
// dyn_cast // dyn_cast
static bool classof(const Value *V) { static bool classof(const Value *V) {
@ -144,19 +153,14 @@ public:
return ID == MemoryUseVal || ID == MemoryPhiVal || ID == MemoryDefVal; return ID == MemoryUseVal || ID == MemoryPhiVal || ID == MemoryDefVal;
} }
MemoryAccess(const MemoryAccess &) = delete;
MemoryAccess &operator=(const MemoryAccess &) = delete;
void *operator new(size_t) = delete;
BasicBlock *getBlock() const { return Block; } BasicBlock *getBlock() const { return Block; }
void print(raw_ostream &OS) const; void print(raw_ostream &OS) const;
void dump() const; void dump() const;
/// \brief The user iterators for a memory access /// \brief The user iterators for a memory access
typedef user_iterator iterator; using iterator = user_iterator;
typedef const_user_iterator const_iterator; using const_iterator = const_user_iterator;
/// \brief This iterator walks over all of the defs in a given /// \brief This iterator walks over all of the defs in a given
/// MemoryAccess. For MemoryPhi nodes, this walks arguments. For /// MemoryAccess. For MemoryPhi nodes, this walks arguments. For
@ -194,11 +198,11 @@ public:
} }
protected: protected:
friend class MemorySSA;
friend class MemoryUseOrDef;
friend class MemoryUse;
friend class MemoryDef; friend class MemoryDef;
friend class MemoryPhi; friend class MemoryPhi;
friend class MemorySSA;
friend class MemoryUse;
friend class MemoryUseOrDef;
/// \brief Used by MemorySSA to change the block of a MemoryAccess when it is /// \brief Used by MemorySSA to change the block of a MemoryAccess when it is
/// moved. /// moved.
@ -259,11 +263,13 @@ public:
protected: protected:
friend class MemorySSA; friend class MemorySSA;
friend class MemorySSAUpdater; friend class MemorySSAUpdater;
MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty, MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty,
DeleteValueTy DeleteValue, Instruction *MI, BasicBlock *BB) DeleteValueTy DeleteValue, Instruction *MI, BasicBlock *BB)
: MemoryAccess(C, Vty, DeleteValue, BB, 1), MemoryInst(MI) { : MemoryAccess(C, Vty, DeleteValue, BB, 1), MemoryInst(MI) {
setDefiningAccess(DMA); setDefiningAccess(DMA);
} }
void setDefiningAccess(MemoryAccess *DMA, bool Optimized = false) { void setDefiningAccess(MemoryAccess *DMA, bool Optimized = false) {
if (!Optimized) { if (!Optimized) {
setOperand(0, DMA); setOperand(0, DMA);
@ -291,8 +297,7 @@ public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB) MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB)
: MemoryUseOrDef(C, DMA, MemoryUseVal, deleteMe, MI, BB), : MemoryUseOrDef(C, DMA, MemoryUseVal, deleteMe, MI, BB) {}
OptimizedID(0) {}
// allocate space for exactly one operand // allocate space for exactly one operand
void *operator new(size_t s) { return User::operator new(s, 1); } void *operator new(size_t s) { return User::operator new(s, 1); }
@ -315,6 +320,7 @@ public:
MemoryAccess *getOptimized() const { MemoryAccess *getOptimized() const {
return getDefiningAccess(); return getDefiningAccess();
} }
void resetOptimized() { void resetOptimized() {
OptimizedID = INVALID_MEMORYACCESS_ID; OptimizedID = INVALID_MEMORYACCESS_ID;
} }
@ -325,7 +331,7 @@ protected:
private: private:
static void deleteMe(DerivedUser *Self); static void deleteMe(DerivedUser *Self);
unsigned int OptimizedID; unsigned int OptimizedID = 0;
}; };
template <> template <>
@ -343,12 +349,13 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryUse, MemoryAccess)
/// MemoryDef/MemoryPhi. /// MemoryDef/MemoryPhi.
class MemoryDef final : public MemoryUseOrDef { class MemoryDef final : public MemoryUseOrDef {
public: public:
friend class MemorySSA;
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB, MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB,
unsigned Ver) unsigned Ver)
: MemoryUseOrDef(C, DMA, MemoryDefVal, deleteMe, MI, BB), : MemoryUseOrDef(C, DMA, MemoryDefVal, deleteMe, MI, BB), ID(Ver) {}
ID(Ver), Optimized(nullptr), OptimizedID(INVALID_MEMORYACCESS_ID) {}
// allocate space for exactly one operand // allocate space for exactly one operand
void *operator new(size_t s) { return User::operator new(s, 1); } void *operator new(size_t s) { return User::operator new(s, 1); }
@ -361,27 +368,28 @@ public:
Optimized = MA; Optimized = MA;
OptimizedID = getDefiningAccess()->getID(); OptimizedID = getDefiningAccess()->getID();
} }
MemoryAccess *getOptimized() const { return Optimized; } MemoryAccess *getOptimized() const { return Optimized; }
bool isOptimized() const { bool isOptimized() const {
return getOptimized() && getDefiningAccess() && return getOptimized() && getDefiningAccess() &&
OptimizedID == getDefiningAccess()->getID(); OptimizedID == getDefiningAccess()->getID();
} }
void resetOptimized() { void resetOptimized() {
OptimizedID = INVALID_MEMORYACCESS_ID; OptimizedID = INVALID_MEMORYACCESS_ID;
} }
void print(raw_ostream &OS) const; void print(raw_ostream &OS) const;
friend class MemorySSA;
unsigned getID() const { return ID; } unsigned getID() const { return ID; }
private: private:
static void deleteMe(DerivedUser *Self); static void deleteMe(DerivedUser *Self);
const unsigned ID; const unsigned ID;
MemoryAccess *Optimized; MemoryAccess *Optimized = nullptr;
unsigned int OptimizedID; unsigned int OptimizedID = INVALID_MEMORYACCESS_ID;
}; };
template <> template <>
@ -436,8 +444,8 @@ public:
// Block iterator interface. This provides access to the list of incoming // Block iterator interface. This provides access to the list of incoming
// basic blocks, which parallels the list of incoming values. // basic blocks, which parallels the list of incoming values.
typedef BasicBlock **block_iterator; using block_iterator = BasicBlock **;
typedef BasicBlock *const *const_block_iterator; using const_block_iterator = BasicBlock *const *;
block_iterator block_begin() { block_iterator block_begin() {
auto *Ref = reinterpret_cast<Use::UserRef *>(op_begin() + ReservedSpace); auto *Ref = reinterpret_cast<Use::UserRef *>(op_begin() + ReservedSpace);
@ -477,6 +485,7 @@ public:
assert(V && "PHI node got a null value!"); assert(V && "PHI node got a null value!");
setOperand(I, V); setOperand(I, V);
} }
static unsigned getOperandNumForIncomingValue(unsigned I) { return I; } static unsigned getOperandNumForIncomingValue(unsigned I) { return I; }
static unsigned getIncomingValueNumForOperand(unsigned I) { return I; } static unsigned getIncomingValueNumForOperand(unsigned I) { return I; }
@ -595,12 +604,9 @@ inline void MemoryUseOrDef::resetOptimized() {
cast<MemoryUse>(this)->resetOptimized(); cast<MemoryUse>(this)->resetOptimized();
} }
template <> struct OperandTraits<MemoryPhi> : public HungoffOperandTraits<2> {}; template <> struct OperandTraits<MemoryPhi> : public HungoffOperandTraits<2> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryPhi, MemoryAccess) DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryPhi, MemoryAccess)
class MemorySSAWalker;
/// \brief Encapsulates MemorySSA, including all data associated with memory /// \brief Encapsulates MemorySSA, including all data associated with memory
/// accesses. /// accesses.
class MemorySSA { class MemorySSA {
@ -707,11 +713,13 @@ protected:
void moveTo(MemoryUseOrDef *What, BasicBlock *BB, AccessList::iterator Where); void moveTo(MemoryUseOrDef *What, BasicBlock *BB, AccessList::iterator Where);
void moveTo(MemoryUseOrDef *What, BasicBlock *BB, InsertionPlace Point); void moveTo(MemoryUseOrDef *What, BasicBlock *BB, InsertionPlace Point);
// Rename the dominator tree branch rooted at BB. // Rename the dominator tree branch rooted at BB.
void renamePass(BasicBlock *BB, MemoryAccess *IncomingVal, void renamePass(BasicBlock *BB, MemoryAccess *IncomingVal,
SmallPtrSetImpl<BasicBlock *> &Visited) { SmallPtrSetImpl<BasicBlock *> &Visited) {
renamePass(DT->getNode(BB), IncomingVal, Visited, true, true); renamePass(DT->getNode(BB), IncomingVal, Visited, true, true);
} }
void removeFromLookups(MemoryAccess *); void removeFromLookups(MemoryAccess *);
void removeFromLists(MemoryAccess *, bool ShouldDelete = true); void removeFromLists(MemoryAccess *, bool ShouldDelete = true);
void insertIntoListsForBlock(MemoryAccess *, const BasicBlock *, void insertIntoListsForBlock(MemoryAccess *, const BasicBlock *,
@ -729,6 +737,7 @@ private:
void optimizeUses(); void optimizeUses();
void verifyUseInDefs(MemoryAccess *, MemoryAccess *) const; void verifyUseInDefs(MemoryAccess *, MemoryAccess *) const;
using AccessMap = DenseMap<const BasicBlock *, std::unique_ptr<AccessList>>; using AccessMap = DenseMap<const BasicBlock *, std::unique_ptr<AccessList>>;
using DefsMap = DenseMap<const BasicBlock *, std::unique_ptr<DefsList>>; using DefsMap = DenseMap<const BasicBlock *, std::unique_ptr<DefsList>>;
@ -755,6 +764,7 @@ private:
// Memory SSA mappings // Memory SSA mappings
DenseMap<const Value *, MemoryAccess *> ValueToMemoryAccess; DenseMap<const Value *, MemoryAccess *> ValueToMemoryAccess;
// These two mappings contain the main block to access/def mappings for // These two mappings contain the main block to access/def mappings for
// MemorySSA. The list contained in PerBlockAccesses really owns all the // MemorySSA. The list contained in PerBlockAccesses really owns all the
// MemoryAccesses. // MemoryAccesses.
@ -779,8 +789,9 @@ private:
// Internal MemorySSA utils, for use by MemorySSA classes and walkers // Internal MemorySSA utils, for use by MemorySSA classes and walkers
class MemorySSAUtil { class MemorySSAUtil {
protected: protected:
friend class MemorySSAWalker;
friend class GVNHoist; friend class GVNHoist;
friend class MemorySSAWalker;
// This function should not be used by new passes. // This function should not be used by new passes.
static bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU, static bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU,
AliasAnalysis &AA); AliasAnalysis &AA);
@ -811,6 +822,7 @@ public:
// unique_ptr<MemorySSA> to avoid build breakage on MSVC. // unique_ptr<MemorySSA> to avoid build breakage on MSVC.
struct Result { struct Result {
Result(std::unique_ptr<MemorySSA> &&MSSA) : MSSA(std::move(MSSA)) {} Result(std::unique_ptr<MemorySSA> &&MSSA) : MSSA(std::move(MSSA)) {}
MemorySSA &getMSSA() { return *MSSA.get(); } MemorySSA &getMSSA() { return *MSSA.get(); }
std::unique_ptr<MemorySSA> MSSA; std::unique_ptr<MemorySSA> MSSA;
@ -978,6 +990,7 @@ public:
assert(MP && "Tried to get phi arg block when not iterating over a PHI"); assert(MP && "Tried to get phi arg block when not iterating over a PHI");
return MP->getIncomingBlock(ArgNo); return MP->getIncomingBlock(ArgNo);
} }
typename BaseT::iterator::pointer operator*() const { typename BaseT::iterator::pointer operator*() const {
assert(Access && "Tried to access past the end of our iterator"); assert(Access && "Tried to access past the end of our iterator");
// Go to the first argument for phis, and the defining access for everything // Go to the first argument for phis, and the defining access for everything
@ -986,6 +999,7 @@ public:
return MP->getIncomingValue(ArgNo); return MP->getIncomingValue(ArgNo);
return cast<MemoryUseOrDef>(Access)->getDefiningAccess(); return cast<MemoryUseOrDef>(Access)->getDefiningAccess();
} }
using BaseT::operator++; using BaseT::operator++;
memoryaccess_def_iterator &operator++() { memoryaccess_def_iterator &operator++() {
assert(Access && "Hit end of iterator"); assert(Access && "Hit end of iterator");

View File

@ -14,13 +14,17 @@
#ifndef LLVM_ANALYSIS_MODULESUMMARYANALYSIS_H #ifndef LLVM_ANALYSIS_MODULESUMMARYANALYSIS_H
#define LLVM_ANALYSIS_MODULESUMMARYANALYSIS_H #define LLVM_ANALYSIS_MODULESUMMARYANALYSIS_H
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Optional.h"
#include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include <functional>
namespace llvm { namespace llvm {
class BlockFrequencyInfo; class BlockFrequencyInfo;
class Function;
class Module;
class ProfileSummaryInfo; class ProfileSummaryInfo;
/// Direct function to compute a \c ModuleSummaryIndex from a given module. /// Direct function to compute a \c ModuleSummaryIndex from a given module.
@ -38,10 +42,11 @@ ModuleSummaryIndex buildModuleSummaryIndex(
class ModuleSummaryIndexAnalysis class ModuleSummaryIndexAnalysis
: public AnalysisInfoMixin<ModuleSummaryIndexAnalysis> { : public AnalysisInfoMixin<ModuleSummaryIndexAnalysis> {
friend AnalysisInfoMixin<ModuleSummaryIndexAnalysis>; friend AnalysisInfoMixin<ModuleSummaryIndexAnalysis>;
static AnalysisKey Key; static AnalysisKey Key;
public: public:
typedef ModuleSummaryIndex Result; using Result = ModuleSummaryIndex;
Result run(Module &M, ModuleAnalysisManager &AM); Result run(Module &M, ModuleAnalysisManager &AM);
}; };
@ -70,6 +75,7 @@ public:
// object for the module, to be written to bitcode or LLVM assembly. // object for the module, to be written to bitcode or LLVM assembly.
// //
ModulePass *createModuleSummaryIndexWrapperPass(); ModulePass *createModuleSummaryIndexWrapperPass();
}
#endif } // end namespace llvm
#endif // LLVM_ANALYSIS_MODULESUMMARYANALYSIS_H

View File

@ -1,4 +1,4 @@
//=- llvm/Analysis/PostDominators.h - Post Dominator Calculation-*- C++ -*-===// //=- llvm/Analysis/PostDominators.h - Post Dominator Calculation --*- C++ -*-=//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -14,16 +14,20 @@
#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H #ifndef LLVM_ANALYSIS_POSTDOMINATORS_H
#define LLVM_ANALYSIS_POSTDOMINATORS_H #define LLVM_ANALYSIS_POSTDOMINATORS_H
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/IR/Dominators.h" #include "llvm/IR/Dominators.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm { namespace llvm {
class Function;
class raw_ostream;
/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to /// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
/// compute the post-dominator tree. /// compute the post-dominator tree.
///
struct PostDominatorTree : public PostDomTreeBase<BasicBlock> { struct PostDominatorTree : public PostDomTreeBase<BasicBlock> {
typedef PostDomTreeBase<BasicBlock> Base; using Base = PostDomTreeBase<BasicBlock>;
/// Handle invalidation explicitly. /// Handle invalidation explicitly.
bool invalidate(Function &F, const PreservedAnalyses &PA, bool invalidate(Function &F, const PreservedAnalyses &PA,
@ -34,11 +38,12 @@ struct PostDominatorTree : public PostDomTreeBase<BasicBlock> {
class PostDominatorTreeAnalysis class PostDominatorTreeAnalysis
: public AnalysisInfoMixin<PostDominatorTreeAnalysis> { : public AnalysisInfoMixin<PostDominatorTreeAnalysis> {
friend AnalysisInfoMixin<PostDominatorTreeAnalysis>; friend AnalysisInfoMixin<PostDominatorTreeAnalysis>;
static AnalysisKey Key; static AnalysisKey Key;
public: public:
/// \brief Provide the result typedef for this analysis pass. /// \brief Provide the result type for this analysis pass.
typedef PostDominatorTree Result; using Result = PostDominatorTree;
/// \brief Run the analysis pass over a function and produce a post dominator /// \brief Run the analysis pass over a function and produce a post dominator
/// tree. /// tree.
@ -52,11 +57,13 @@ class PostDominatorTreePrinterPass
public: public:
explicit PostDominatorTreePrinterPass(raw_ostream &OS); explicit PostDominatorTreePrinterPass(raw_ostream &OS);
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
}; };
struct PostDominatorTreeWrapperPass : public FunctionPass { struct PostDominatorTreeWrapperPass : public FunctionPass {
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
PostDominatorTree DT; PostDominatorTree DT;
PostDominatorTreeWrapperPass() : FunctionPass(ID) { PostDominatorTreeWrapperPass() : FunctionPass(ID) {
@ -99,6 +106,6 @@ template <> struct GraphTraits<PostDominatorTree*>
} }
}; };
} // End llvm namespace } // end namespace llvm
#endif #endif // LLVM_ANALYSIS_POSTDOMINATORS_H

View File

@ -1,4 +1,4 @@
//===------ MemoryBuiltins.cpp - Identify calls to memory builtins --------===// //===- MemoryBuiltins.cpp - Identify calls to memory builtins -------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,20 +13,39 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetFolder.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/Attributes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h" #include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Metadata.h" #include "llvm/IR/Operator.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <utility>
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "memory-builtins" #define DEBUG_TYPE "memory-builtins"
@ -187,7 +206,6 @@ static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
return CS && CS.hasRetAttr(Attribute::NoAlias); return CS && CS.hasRetAttr(Attribute::NoAlias);
} }
/// \brief Tests if a value is a call or invoke to a library function that /// \brief Tests if a value is a call or invoke to a library function that
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup /// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
/// like). /// like).
@ -323,7 +341,6 @@ Value *llvm::getMallocArraySize(CallInst *CI, const DataLayout &DL,
return computeArraySize(CI, DL, TLI, LookThroughSExt); return computeArraySize(CI, DL, TLI, LookThroughSExt);
} }
/// extractCallocCall - Returns the corresponding CallInst if the instruction /// extractCallocCall - Returns the corresponding CallInst if the instruction
/// is a calloc call. /// is a calloc call.
const CallInst *llvm::extractCallocCall(const Value *I, const CallInst *llvm::extractCallocCall(const Value *I,
@ -331,7 +348,6 @@ const CallInst *llvm::extractCallocCall(const Value *I,
return isCallocLikeFn(I, TLI) ? cast<CallInst>(I) : nullptr; return isCallocLikeFn(I, TLI) ? cast<CallInst>(I) : nullptr;
} }
/// isFreeCall - Returns non-null if the value is a call to the builtin free() /// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) { const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
const CallInst *CI = dyn_cast<CallInst>(I); const CallInst *CI = dyn_cast<CallInst>(I);
@ -387,8 +403,6 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
return CI; return CI;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Utility functions to compute size of objects. // Utility functions to compute size of objects.
// //
@ -452,7 +466,6 @@ STATISTIC(ObjectVisitorArgument,
STATISTIC(ObjectVisitorLoad, STATISTIC(ObjectVisitorLoad,
"Number of load instructions with unsolved size and offset"); "Number of load instructions with unsolved size and offset");
APInt ObjectSizeOffsetVisitor::align(APInt Size, uint64_t Align) { APInt ObjectSizeOffsetVisitor::align(APInt Size, uint64_t Align) {
if (Options.RoundToAlign && Align) if (Options.RoundToAlign && Align)
return APInt(IntTyBits, alignTo(Size.getZExtValue(), Align)); return APInt(IntTyBits, alignTo(Size.getZExtValue(), Align));

View File

@ -15,28 +15,40 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/OrderedBasicBlock.h" #include "llvm/Analysis/OrderedBasicBlock.h"
#include "llvm/Analysis/PHITransAddr.h" #include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h" #include "llvm/IR/CallSite.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/Function.h" #include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h" #include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PredIteratorCache.h" #include "llvm/IR/PredIteratorCache.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/AtomicOrdering.h" #include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
@ -45,7 +57,9 @@
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstdint>
#include <iterator> #include <iterator>
#include <utility>
using namespace llvm; using namespace llvm;
@ -322,7 +336,6 @@ static bool isVolatile(Instruction *Inst) {
MemDepResult MemoryDependenceResults::getPointerDependencyFrom( MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt, const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) { BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) {
MemDepResult InvariantGroupDependency = MemDepResult::getUnknown(); MemDepResult InvariantGroupDependency = MemDepResult::getUnknown();
if (QueryInst != nullptr) { if (QueryInst != nullptr) {
if (auto *LI = dyn_cast<LoadInst>(QueryInst)) { if (auto *LI = dyn_cast<LoadInst>(QueryInst)) {
@ -350,7 +363,6 @@ MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
MemDepResult MemDepResult
MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI, MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
BasicBlock *BB) { BasicBlock *BB) {
auto *InvariantGroupMD = LI->getMetadata(LLVMContext::MD_invariant_group); auto *InvariantGroupMD = LI->getMetadata(LLVMContext::MD_invariant_group);
if (!InvariantGroupMD) if (!InvariantGroupMD)
return MemDepResult::getUnknown(); return MemDepResult::getUnknown();
@ -380,7 +392,6 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
return Best; return Best;
}; };
// FIXME: This loop is O(N^2) because dominates can be O(n) and in worst case // FIXME: This loop is O(N^2) because dominates can be O(n) and in worst case
// we will see all the instructions. This should be fixed in MSSA. // we will see all the instructions. This should be fixed in MSSA.
while (!LoadOperandsQueue.empty()) { while (!LoadOperandsQueue.empty()) {
@ -541,7 +552,6 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
// it does not alias with when this atomic load indicates that another // it does not alias with when this atomic load indicates that another
// thread may be accessing the location. // thread may be accessing the location.
if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) { if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
// While volatile access cannot be eliminated, they do not have to clobber // While volatile access cannot be eliminated, they do not have to clobber
// non-aliasing locations, as normal accesses, for example, can be safely // non-aliasing locations, as normal accesses, for example, can be safely
// reordered with volatile accesses. // reordered with volatile accesses.
@ -1508,7 +1518,6 @@ void MemoryDependenceResults::removeInstruction(Instruction *RemInst) {
} }
// If we have a cached local dependence query for this instruction, remove it. // If we have a cached local dependence query for this instruction, remove it.
//
LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst); LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst);
if (LocalDepEntry != LocalDeps.end()) { if (LocalDepEntry != LocalDeps.end()) {
// Remove us from DepInst's reverse set now that the local dep info is gone. // Remove us from DepInst's reverse set now that the local dep info is gone.
@ -1531,7 +1540,6 @@ void MemoryDependenceResults::removeInstruction(Instruction *RemInst) {
} }
// Loop over all of the things that depend on the instruction we're removing. // Loop over all of the things that depend on the instruction we're removing.
//
SmallVector<std::pair<Instruction *, Instruction *>, 8> ReverseDepsToAdd; SmallVector<std::pair<Instruction *, Instruction *>, 8> ReverseDepsToAdd;
// If we find RemInst as a clobber or Def in any of the maps for other values, // If we find RemInst as a clobber or Def in any of the maps for other values,
@ -1726,7 +1734,7 @@ MemoryDependenceWrapperPass::MemoryDependenceWrapperPass() : FunctionPass(ID) {
initializeMemoryDependenceWrapperPassPass(*PassRegistry::getPassRegistry()); initializeMemoryDependenceWrapperPassPass(*PassRegistry::getPassRegistry());
} }
MemoryDependenceWrapperPass::~MemoryDependenceWrapperPass() {} MemoryDependenceWrapperPass::~MemoryDependenceWrapperPass() = default;
void MemoryDependenceWrapperPass::releaseMemory() { void MemoryDependenceWrapperPass::releaseMemory() {
MemDep.reset(); MemDep.reset();

View File

@ -1,48 +1,63 @@
//===-- MemorySSA.cpp - Memory SSA Builder---------------------------===// //===- MemorySSA.cpp - Memory SSA Builder ---------------------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file implements the MemorySSA class. // This file implements the MemorySSA class.
// //
//===----------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/MemorySSA.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/Hashing.h"
#include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallBitVector.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/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/IteratedDominanceFrontier.h" #include "llvm/Analysis/IteratedDominanceFrontier.h"
#include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/DataLayout.h" #include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Dominators.h" #include "llvm/IR/Dominators.h"
#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.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/PassManager.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Use.h"
#include "llvm/IR/PatternMatch.h" #include "llvm/Pass.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.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/FormattedStream.h" #include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm> #include <algorithm>
#include <cassert>
#include <iterator>
#include <memory>
#include <utility>
using namespace llvm;
#define DEBUG_TYPE "memoryssa" #define DEBUG_TYPE "memoryssa"
using namespace llvm;
INITIALIZE_PASS_BEGIN(MemorySSAWrapperPass, "memoryssa", "Memory SSA", false, INITIALIZE_PASS_BEGIN(MemorySSAWrapperPass, "memoryssa", "Memory SSA", false,
true) true)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
@ -66,30 +81,34 @@ static cl::opt<bool>
cl::desc("Verify MemorySSA in legacy printer pass.")); cl::desc("Verify MemorySSA in legacy printer pass."));
namespace llvm { namespace llvm {
/// \brief An assembly annotator class to print Memory SSA information in /// \brief An assembly annotator class to print Memory SSA information in
/// comments. /// comments.
class MemorySSAAnnotatedWriter : public AssemblyAnnotationWriter { class MemorySSAAnnotatedWriter : public AssemblyAnnotationWriter {
friend class MemorySSA; friend class MemorySSA;
const MemorySSA *MSSA; const MemorySSA *MSSA;
public: public:
MemorySSAAnnotatedWriter(const MemorySSA *M) : MSSA(M) {} MemorySSAAnnotatedWriter(const MemorySSA *M) : MSSA(M) {}
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, void emitBasicBlockStartAnnot(const BasicBlock *BB,
formatted_raw_ostream &OS) { formatted_raw_ostream &OS) override {
if (MemoryAccess *MA = MSSA->getMemoryAccess(BB)) if (MemoryAccess *MA = MSSA->getMemoryAccess(BB))
OS << "; " << *MA << "\n"; OS << "; " << *MA << "\n";
} }
virtual void emitInstructionAnnot(const Instruction *I, void emitInstructionAnnot(const Instruction *I,
formatted_raw_ostream &OS) { formatted_raw_ostream &OS) override {
if (MemoryAccess *MA = MSSA->getMemoryAccess(I)) if (MemoryAccess *MA = MSSA->getMemoryAccess(I))
OS << "; " << *MA << "\n"; OS << "; " << *MA << "\n";
} }
}; };
}
} // end namespace llvm
namespace { namespace {
/// Our current alias analysis API differentiates heavily between calls and /// Our current alias analysis API differentiates heavily between calls and
/// non-calls, and functions called on one usually assert on the other. /// non-calls, and functions called on one usually assert on the other.
/// This class encapsulates the distinction to simplify other code that wants /// This class encapsulates the distinction to simplify other code that wants
@ -97,7 +116,9 @@ namespace {
/// For example, this class is used as a densemap key in the use optimizer. /// For example, this class is used as a densemap key in the use optimizer.
class MemoryLocOrCall { class MemoryLocOrCall {
public: public:
MemoryLocOrCall() : IsCall(false) {} bool IsCall = false;
MemoryLocOrCall() = default;
MemoryLocOrCall(MemoryUseOrDef *MUD) MemoryLocOrCall(MemoryUseOrDef *MUD)
: MemoryLocOrCall(MUD->getMemoryInst()) {} : MemoryLocOrCall(MUD->getMemoryInst()) {}
MemoryLocOrCall(const MemoryUseOrDef *MUD) MemoryLocOrCall(const MemoryUseOrDef *MUD)
@ -116,14 +137,13 @@ public:
} }
} }
explicit MemoryLocOrCall(const MemoryLocation &Loc) explicit MemoryLocOrCall(const MemoryLocation &Loc) : Loc(Loc) {}
: IsCall(false), Loc(Loc) {}
bool IsCall;
ImmutableCallSite getCS() const { ImmutableCallSite getCS() const {
assert(IsCall); assert(IsCall);
return CS; return CS;
} }
MemoryLocation getLoc() const { MemoryLocation getLoc() const {
assert(!IsCall); assert(!IsCall);
return Loc; return Loc;
@ -144,16 +164,20 @@ private:
MemoryLocation Loc; MemoryLocation Loc;
}; };
}; };
}
} // end anonymous namespace
namespace llvm { namespace llvm {
template <> struct DenseMapInfo<MemoryLocOrCall> { template <> struct DenseMapInfo<MemoryLocOrCall> {
static inline MemoryLocOrCall getEmptyKey() { static inline MemoryLocOrCall getEmptyKey() {
return MemoryLocOrCall(DenseMapInfo<MemoryLocation>::getEmptyKey()); return MemoryLocOrCall(DenseMapInfo<MemoryLocation>::getEmptyKey());
} }
static inline MemoryLocOrCall getTombstoneKey() { static inline MemoryLocOrCall getTombstoneKey() {
return MemoryLocOrCall(DenseMapInfo<MemoryLocation>::getTombstoneKey()); return MemoryLocOrCall(DenseMapInfo<MemoryLocation>::getTombstoneKey());
} }
static unsigned getHashValue(const MemoryLocOrCall &MLOC) { static unsigned getHashValue(const MemoryLocOrCall &MLOC) {
if (MLOC.IsCall) if (MLOC.IsCall)
return hash_combine(MLOC.IsCall, return hash_combine(MLOC.IsCall,
@ -162,6 +186,7 @@ template <> struct DenseMapInfo<MemoryLocOrCall> {
return hash_combine( return hash_combine(
MLOC.IsCall, DenseMapInfo<MemoryLocation>::getHashValue(MLOC.getLoc())); MLOC.IsCall, DenseMapInfo<MemoryLocation>::getHashValue(MLOC.getLoc()));
} }
static bool isEqual(const MemoryLocOrCall &LHS, const MemoryLocOrCall &RHS) { static bool isEqual(const MemoryLocOrCall &LHS, const MemoryLocOrCall &RHS) {
return LHS == RHS; return LHS == RHS;
} }
@ -169,6 +194,8 @@ template <> struct DenseMapInfo<MemoryLocOrCall> {
enum class Reorderability { Always, IfNoAlias, Never }; enum class Reorderability { Always, IfNoAlias, Never };
} // end namespace llvm
/// This does one-way checks to see if Use could theoretically be hoisted above /// This does one-way checks to see if Use could theoretically be hoisted above
/// MayClobber. This will not check the other way around. /// MayClobber. This will not check the other way around.
/// ///
@ -271,22 +298,21 @@ bool MemorySSAUtil::defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU,
AliasAnalysis &AA) { AliasAnalysis &AA) {
return instructionClobbersQuery(MD, MU, MemoryLocOrCall(MU), AA); return instructionClobbersQuery(MD, MU, MemoryLocOrCall(MU), AA);
} }
}
namespace { namespace {
struct UpwardsMemoryQuery { struct UpwardsMemoryQuery {
// True if our original query started off as a call // True if our original query started off as a call
bool IsCall; bool IsCall = false;
// The pointer location we started the query with. This will be empty if // The pointer location we started the query with. This will be empty if
// IsCall is true. // IsCall is true.
MemoryLocation StartingLoc; MemoryLocation StartingLoc;
// This is the instruction we were querying about. // This is the instruction we were querying about.
const Instruction *Inst; const Instruction *Inst = nullptr;
// The MemoryAccess we actually got called with, used to test local domination // The MemoryAccess we actually got called with, used to test local domination
const MemoryAccess *OriginalAccess; const MemoryAccess *OriginalAccess = nullptr;
UpwardsMemoryQuery() UpwardsMemoryQuery() = default;
: IsCall(false), Inst(nullptr), OriginalAccess(nullptr) {}
UpwardsMemoryQuery(const Instruction *Inst, const MemoryAccess *Access) UpwardsMemoryQuery(const Instruction *Inst, const MemoryAccess *Access)
: IsCall(ImmutableCallSite(Inst)), Inst(Inst), OriginalAccess(Access) { : IsCall(ImmutableCallSite(Inst)), Inst(Inst), OriginalAccess(Access) {
@ -295,6 +321,8 @@ struct UpwardsMemoryQuery {
} }
}; };
} // end anonymous namespace
static bool lifetimeEndsAt(MemoryDef *MD, const MemoryLocation &Loc, static bool lifetimeEndsAt(MemoryDef *MD, const MemoryLocation &Loc,
AliasAnalysis &AA) { AliasAnalysis &AA) {
Instruction *Inst = MD->getMemoryInst(); Instruction *Inst = MD->getMemoryInst();
@ -394,6 +422,8 @@ checkClobberSanity(MemoryAccess *Start, MemoryAccess *ClobberAt,
"ClobberAt never acted as a clobber"); "ClobberAt never acted as a clobber");
} }
namespace {
/// Our algorithm for walking (and trying to optimize) clobbers, all wrapped up /// Our algorithm for walking (and trying to optimize) clobbers, all wrapped up
/// in one class. /// in one class.
class ClobberWalker { class ClobberWalker {
@ -569,7 +599,7 @@ class ClobberWalker {
struct generic_def_path_iterator struct generic_def_path_iterator
: public iterator_facade_base<generic_def_path_iterator<T, Walker>, : public iterator_facade_base<generic_def_path_iterator<T, Walker>,
std::forward_iterator_tag, T *> { std::forward_iterator_tag, T *> {
generic_def_path_iterator() : W(nullptr), N(None) {} generic_def_path_iterator() = default;
generic_def_path_iterator(Walker *W, ListIndex N) : W(W), N(N) {} generic_def_path_iterator(Walker *W, ListIndex N) : W(W), N(N) {}
T &operator*() const { return curNode(); } T &operator*() const { return curNode(); }
@ -588,8 +618,8 @@ class ClobberWalker {
private: private:
T &curNode() const { return W->Paths[*N]; } T &curNode() const { return W->Paths[*N]; }
Walker *W; Walker *W = nullptr;
Optional<ListIndex> N; Optional<ListIndex> N = None;
}; };
using def_path_iterator = generic_def_path_iterator<DefPath, ClobberWalker>; using def_path_iterator = generic_def_path_iterator<DefPath, ClobberWalker>;
@ -664,7 +694,7 @@ class ClobberWalker {
}; };
MemoryPhi *Current = Phi; MemoryPhi *Current = Phi;
while (1) { while (true) {
assert(!MSSA.isLiveOnEntryDef(Current) && assert(!MSSA.isLiveOnEntryDef(Current) &&
"liveOnEntry wasn't treated as a clobber?"); "liveOnEntry wasn't treated as a clobber?");
@ -842,30 +872,34 @@ struct RenamePassData {
RenamePassData(DomTreeNode *D, DomTreeNode::const_iterator It, RenamePassData(DomTreeNode *D, DomTreeNode::const_iterator It,
MemoryAccess *M) MemoryAccess *M)
: DTN(D), ChildIt(It), IncomingVal(M) {} : DTN(D), ChildIt(It), IncomingVal(M) {}
void swap(RenamePassData &RHS) { void swap(RenamePassData &RHS) {
std::swap(DTN, RHS.DTN); std::swap(DTN, RHS.DTN);
std::swap(ChildIt, RHS.ChildIt); std::swap(ChildIt, RHS.ChildIt);
std::swap(IncomingVal, RHS.IncomingVal); std::swap(IncomingVal, RHS.IncomingVal);
} }
}; };
} // anonymous namespace
} // end anonymous namespace
namespace llvm { namespace llvm {
/// \brief A MemorySSAWalker that does AA walks to disambiguate accesses. It no /// \brief A MemorySSAWalker that does AA walks to disambiguate accesses. It no
/// longer does caching on its own, /// longer does caching on its own,
/// but the name has been retained for the moment. /// but the name has been retained for the moment.
class MemorySSA::CachingWalker final : public MemorySSAWalker { class MemorySSA::CachingWalker final : public MemorySSAWalker {
ClobberWalker Walker; ClobberWalker Walker;
bool AutoResetWalker; bool AutoResetWalker = true;
MemoryAccess *getClobberingMemoryAccess(MemoryAccess *, UpwardsMemoryQuery &); MemoryAccess *getClobberingMemoryAccess(MemoryAccess *, UpwardsMemoryQuery &);
void verifyRemoved(MemoryAccess *); void verifyRemoved(MemoryAccess *);
public: public:
CachingWalker(MemorySSA *, AliasAnalysis *, DominatorTree *); CachingWalker(MemorySSA *, AliasAnalysis *, DominatorTree *);
~CachingWalker() override; ~CachingWalker() override = default;
using MemorySSAWalker::getClobberingMemoryAccess; using MemorySSAWalker::getClobberingMemoryAccess;
MemoryAccess *getClobberingMemoryAccess(MemoryAccess *) override; MemoryAccess *getClobberingMemoryAccess(MemoryAccess *) override;
MemoryAccess *getClobberingMemoryAccess(MemoryAccess *, MemoryAccess *getClobberingMemoryAccess(MemoryAccess *,
const MemoryLocation &) override; const MemoryLocation &) override;
@ -884,6 +918,8 @@ public:
} }
}; };
} // end namespace llvm
void MemorySSA::renameSuccessorPhis(BasicBlock *BB, MemoryAccess *IncomingVal, void MemorySSA::renameSuccessorPhis(BasicBlock *BB, MemoryAccess *IncomingVal,
bool RenameAllUses) { bool RenameAllUses) {
// Pass through values to our successors // Pass through values to our successors
@ -1032,17 +1068,20 @@ MemorySSA::AccessList *MemorySSA::getOrCreateAccessList(const BasicBlock *BB) {
auto Res = PerBlockAccesses.insert(std::make_pair(BB, nullptr)); auto Res = PerBlockAccesses.insert(std::make_pair(BB, nullptr));
if (Res.second) if (Res.second)
Res.first->second = make_unique<AccessList>(); Res.first->second = llvm::make_unique<AccessList>();
return Res.first->second.get(); return Res.first->second.get();
} }
MemorySSA::DefsList *MemorySSA::getOrCreateDefsList(const BasicBlock *BB) { MemorySSA::DefsList *MemorySSA::getOrCreateDefsList(const BasicBlock *BB) {
auto Res = PerBlockDefs.insert(std::make_pair(BB, nullptr)); auto Res = PerBlockDefs.insert(std::make_pair(BB, nullptr));
if (Res.second) if (Res.second)
Res.first->second = make_unique<DefsList>(); Res.first->second = llvm::make_unique<DefsList>();
return Res.first->second.get(); return Res.first->second.get();
} }
namespace llvm {
/// This class is a batch walker of all MemoryUse's in the program, and points /// This class is a batch walker of all MemoryUse's in the program, and points
/// their defining access at the thing that actually clobbers them. Because it /// their defining access at the thing that actually clobbers them. Because it
/// is a batch walker that touches everything, it does not operate like the /// is a batch walker that touches everything, it does not operate like the
@ -1077,15 +1116,19 @@ private:
unsigned long LastKill; unsigned long LastKill;
bool LastKillValid; bool LastKillValid;
}; };
void optimizeUsesInBlock(const BasicBlock *, unsigned long &, unsigned long &, void optimizeUsesInBlock(const BasicBlock *, unsigned long &, unsigned long &,
SmallVectorImpl<MemoryAccess *> &, SmallVectorImpl<MemoryAccess *> &,
DenseMap<MemoryLocOrCall, MemlocStackInfo> &); DenseMap<MemoryLocOrCall, MemlocStackInfo> &);
MemorySSA *MSSA; MemorySSA *MSSA;
MemorySSAWalker *Walker; MemorySSAWalker *Walker;
AliasAnalysis *AA; AliasAnalysis *AA;
DominatorTree *DT; DominatorTree *DT;
}; };
} // end namespace llvm
/// Optimize the uses in a given block This is basically the SSA renaming /// Optimize the uses in a given block This is basically the SSA renaming
/// algorithm, with one caveat: We are able to use a single stack for all /// algorithm, with one caveat: We are able to use a single stack for all
/// MemoryUses. This is because the set of *possible* reaching MemoryDefs is /// MemoryUses. This is because the set of *possible* reaching MemoryDefs is
@ -1281,8 +1324,9 @@ void MemorySSA::buildMemorySSA() {
// semantics do *not* imply that something with no immediate uses can simply // semantics do *not* imply that something with no immediate uses can simply
// be removed. // be removed.
BasicBlock &StartingPoint = F.getEntryBlock(); BasicBlock &StartingPoint = F.getEntryBlock();
LiveOnEntryDef = make_unique<MemoryDef>(F.getContext(), nullptr, nullptr, LiveOnEntryDef =
&StartingPoint, NextID++); llvm::make_unique<MemoryDef>(F.getContext(), nullptr, nullptr,
&StartingPoint, NextID++);
DenseMap<const BasicBlock *, unsigned int> BBNumbers; DenseMap<const BasicBlock *, unsigned int> BBNumbers;
unsigned NextBBNum = 0; unsigned NextBBNum = 0;
@ -1343,7 +1387,7 @@ MemorySSA::CachingWalker *MemorySSA::getWalkerImpl() {
if (Walker) if (Walker)
return Walker.get(); return Walker.get();
Walker = make_unique<CachingWalker>(this, AA, DT); Walker = llvm::make_unique<CachingWalker>(this, AA, DT);
return Walker.get(); return Walker.get();
} }
@ -1462,6 +1506,7 @@ static inline bool isOrdered(const Instruction *I) {
} }
return false; return false;
} }
/// \brief Helper function to create new memory accesses /// \brief Helper function to create new memory accesses
MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I) { MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I) {
// The assume intrinsic has a control dependency which we model by claiming // The assume intrinsic has a control dependency which we model by claiming
@ -1675,7 +1720,6 @@ void MemorySSA::verifyDomination(Function &F) const {
/// \brief Verify the def-use lists in MemorySSA, by verifying that \p Use /// \brief Verify the def-use lists in MemorySSA, by verifying that \p Use
/// appears in the use list of \p Def. /// appears in the use list of \p Def.
void MemorySSA::verifyUseInDefs(MemoryAccess *Def, MemoryAccess *Use) const { void MemorySSA::verifyUseInDefs(MemoryAccess *Def, MemoryAccess *Use) const {
#ifndef NDEBUG #ifndef NDEBUG
// The live on entry use may cause us to get a NULL def here // The live on entry use may cause us to get a NULL def here
@ -1739,7 +1783,6 @@ void MemorySSA::renumberBlock(const BasicBlock *B) const {
/// \returns True if \p Dominator dominates \p Dominatee. /// \returns True if \p Dominator dominates \p Dominatee.
bool MemorySSA::locallyDominates(const MemoryAccess *Dominator, bool MemorySSA::locallyDominates(const MemoryAccess *Dominator,
const MemoryAccess *Dominatee) const { const MemoryAccess *Dominatee) const {
const BasicBlock *DominatorBlock = Dominator->getBlock(); const BasicBlock *DominatorBlock = Dominator->getBlock();
assert((DominatorBlock == Dominatee->getBlock()) && assert((DominatorBlock == Dominatee->getBlock()) &&
@ -1887,7 +1930,7 @@ MemorySSAAnalysis::Result MemorySSAAnalysis::run(Function &F,
FunctionAnalysisManager &AM) { FunctionAnalysisManager &AM) {
auto &DT = AM.getResult<DominatorTreeAnalysis>(F); auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &AA = AM.getResult<AAManager>(F); auto &AA = AM.getResult<AAManager>(F);
return MemorySSAAnalysis::Result(make_unique<MemorySSA>(F, &AA, &DT)); return MemorySSAAnalysis::Result(llvm::make_unique<MemorySSA>(F, &AA, &DT));
} }
PreservedAnalyses MemorySSAPrinterPass::run(Function &F, PreservedAnalyses MemorySSAPrinterPass::run(Function &F,
@ -1936,9 +1979,7 @@ MemorySSAWalker::MemorySSAWalker(MemorySSA *M) : MSSA(M) {}
MemorySSA::CachingWalker::CachingWalker(MemorySSA *M, AliasAnalysis *A, MemorySSA::CachingWalker::CachingWalker(MemorySSA *M, AliasAnalysis *A,
DominatorTree *D) DominatorTree *D)
: MemorySSAWalker(M), Walker(*M, *A, *D), AutoResetWalker(true) {} : MemorySSAWalker(M), Walker(*M, *A, *D) {}
MemorySSA::CachingWalker::~CachingWalker() {}
void MemorySSA::CachingWalker::invalidateInfo(MemoryAccess *MA) { void MemorySSA::CachingWalker::invalidateInfo(MemoryAccess *MA) {
if (auto *MUD = dyn_cast<MemoryUseOrDef>(MA)) if (auto *MUD = dyn_cast<MemoryUseOrDef>(MA))
@ -2059,7 +2100,6 @@ MemoryAccess *DoNothingMemorySSAWalker::getClobberingMemoryAccess(
return Use->getDefiningAccess(); return Use->getDefiningAccess();
return StartingAccess; return StartingAccess;
} }
} // namespace llvm
void MemoryPhi::deleteMe(DerivedUser *Self) { void MemoryPhi::deleteMe(DerivedUser *Self) {
delete static_cast<MemoryPhi *>(Self); delete static_cast<MemoryPhi *>(Self);

View File

@ -13,23 +13,47 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/ModuleSummaryAnalysis.h" #include "llvm/Analysis/ModuleSummaryAnalysis.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h" #include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Triple.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/IndirectCallPromotionAnalysis.h" #include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/TypeMetadataUtils.h" #include "llvm/Analysis/TypeMetadataUtils.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h" #include "llvm/IR/CallSite.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h" #include "llvm/IR/Dominators.h"
#include "llvm/IR/InstIterator.h" #include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/ValueSymbolTable.h" #include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Object/ModuleSymbolTable.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <vector>
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "module-summary-analysis" #define DEBUG_TYPE "module-summary-analysis"
@ -514,6 +538,7 @@ ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
} }
char ModuleSummaryIndexWrapperPass::ID = 0; char ModuleSummaryIndexWrapperPass::ID = 0;
INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis", INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
"Module Summary Analysis", false, true) "Module Summary Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)

View File

@ -12,13 +12,11 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/PostDominators.h"
#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/IR/Function.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include "llvm/Support/Debug.h" #include "llvm/Pass.h"
#include "llvm/Support/GenericDomTreeConstruction.h" #include "llvm/Support/raw_ostream.h"
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "postdomtree" #define DEBUG_TYPE "postdomtree"
@ -30,6 +28,7 @@ template class llvm::DominatorTreeBase<BasicBlock, true>; // PostDomTreeBase
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
char PostDominatorTreeWrapperPass::ID = 0; char PostDominatorTreeWrapperPass::ID = 0;
INITIALIZE_PASS(PostDominatorTreeWrapperPass, "postdomtree", INITIALIZE_PASS(PostDominatorTreeWrapperPass, "postdomtree",
"Post-Dominator Tree Construction", true, true) "Post-Dominator Tree Construction", true, true)