diff options
Diffstat (limited to 'include/llvm/Analysis')
| -rw-r--r-- | include/llvm/Analysis/AliasAnalysis.h | 14 | ||||
| -rw-r--r-- | include/llvm/Analysis/BranchProbabilityInfo.h | 38 | ||||
| -rw-r--r-- | include/llvm/Analysis/LoopInfoImpl.h | 1 | ||||
| -rw-r--r-- | include/llvm/Analysis/MemoryBuiltins.h | 58 | ||||
| -rw-r--r-- | include/llvm/Analysis/Passes.h | 8 | ||||
| -rw-r--r-- | include/llvm/Analysis/ProfileDataLoader.h | 142 | ||||
| -rw-r--r-- | include/llvm/Analysis/ProfileDataTypes.h | 39 | ||||
| -rw-r--r-- | include/llvm/Analysis/ProfileInfoTypes.h | 10 | ||||
| -rw-r--r-- | include/llvm/Analysis/RegionInfo.h | 21 |
9 files changed, 267 insertions, 64 deletions
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 674868a..f587220 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -46,6 +46,7 @@ class LoadInst; class StoreInst; class VAArgInst; class TargetData; +class TargetLibraryInfo; class Pass; class AnalysisUsage; class MemTransferInst; @@ -55,6 +56,7 @@ class DominatorTree; class AliasAnalysis { protected: const TargetData *TD; + const TargetLibraryInfo *TLI; private: AliasAnalysis *AA; // Previous Alias Analysis to chain to. @@ -73,7 +75,7 @@ protected: public: static char ID; // Class identification, replacement for typeinfo - AliasAnalysis() : TD(0), AA(0) {} + AliasAnalysis() : TD(0), TLI(0), AA(0) {} virtual ~AliasAnalysis(); // We want to be subclassed /// UnknownSize - This is a special value which can be used with the @@ -86,6 +88,11 @@ public: /// const TargetData *getTargetData() const { return TD; } + /// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo + /// object, or null if no TargetLibraryInfo object is available. + /// + const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; } + /// getTypeStoreSize - Return the TargetData store size for the given type, /// if known, or a conservative value otherwise. /// @@ -187,6 +194,11 @@ public: return isNoAlias(Location(V1, V1Size), Location(V2, V2Size)); } + /// isNoAlias - A convenience wrapper. + bool isNoAlias(const Value *V1, const Value *V2) { + return isNoAlias(Location(V1), Location(V2)); + } + /// isMustAlias - A convenience wrapper. bool isMustAlias(const Location &LocA, const Location &LocB) { return alias(LocA, LocB) == MustAlias; diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index 006daa0..c0567da 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -28,11 +28,14 @@ class raw_ostream; /// /// This is a function analysis pass which provides information on the relative /// probabilities of each "edge" in the function's CFG where such an edge is -/// defined by a pair of basic blocks. The probability for a given block and -/// a successor block are always relative to the probabilities of the other -/// successor blocks. Another way of looking at it is that the probabilities -/// for a given block B and each of its successors should sum to exactly -/// one (100%). +/// defined by a pair (PredBlock and an index in the successors). The +/// probability of an edge from one block is always relative to the +/// probabilities of other edges from the block. The probabilites of all edges +/// from a block sum to exactly one (100%). +/// We use a pair (PredBlock and an index in the successors) to uniquely +/// identify an edge, since we can have multiple edges from Src to Dst. +/// As an example, we can have a switch which jumps to Dst with value 0 and +/// value 10. class BranchProbabilityInfo : public FunctionPass { public: static char ID; @@ -52,6 +55,12 @@ public: /// leaving the 'Src' block. The returned probability is never zero, and can /// only be one if the source block has only one successor. BranchProbability getEdgeProbability(const BasicBlock *Src, + unsigned IndexInSuccessors) const; + + /// \brief Get the probability of going from Src to Dst. + /// + /// It returns the sum of all probabilities for edges from Src to Dst. + BranchProbability getEdgeProbability(const BasicBlock *Src, const BasicBlock *Dst) const; /// \brief Test if an edge is hot relative to other out-edges of the Src. @@ -74,25 +83,34 @@ public: raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src, const BasicBlock *Dst) const; - /// \brief Get the raw edge weight calculated for the block pair. + /// \brief Get the raw edge weight calculated for the edge. /// /// This returns the raw edge weight. It is guaranteed to fall between 1 and /// UINT32_MAX. Note that the raw edge weight is not meaningful in isolation. /// This interface should be very carefully, and primarily by routines that /// are updating the analysis by later calling setEdgeWeight. + uint32_t getEdgeWeight(const BasicBlock *Src, + unsigned IndexInSuccessors) const; + + /// \brief Get the raw edge weight calculated for the block pair. + /// + /// This returns the sum of all raw edge weights from Src to Dst. + /// It is guaranteed to fall between 1 and UINT32_MAX. uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const; - /// \brief Set the raw edge weight for the block pair. + /// \brief Set the raw edge weight for a given edge. /// - /// This allows a pass to explicitly set the edge weight for a block. It can + /// This allows a pass to explicitly set the edge weight for an edge. It can /// be used when updating the CFG to update and preserve the branch /// probability information. Read the implementation of how these edge /// weights are calculated carefully before using! - void setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst, + void setEdgeWeight(const BasicBlock *Src, unsigned IndexInSuccessors, uint32_t Weight); private: - typedef std::pair<const BasicBlock *, const BasicBlock *> Edge; + // Since we allow duplicate edges from one basic block to another, we use + // a pair (PredBlock and an index in the successors) to specify an edge. + typedef std::pair<const BasicBlock *, unsigned> Edge; // Default weight value. Used when we don't have information about the edge. // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index c07fbf7..3bb96f9 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -145,7 +145,6 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const { // Loop over the predecessors of the header node... BlockT *Header = getHeader(); - typedef GraphTraits<BlockT*> BlockTraits; typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; for (typename InvBlockTraits::ChildIteratorType PI = InvBlockTraits::child_begin(Header), diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index e16f389..c3ae603 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -28,6 +28,7 @@ namespace llvm { class CallInst; class PointerType; class TargetData; +class TargetLibraryInfo; class Type; class Value; @@ -35,27 +36,33 @@ class Value; /// \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 /// like). -bool isAllocationFn(const Value *V, bool LookThroughBitCast = false); +bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI, + bool LookThroughBitCast = false); /// \brief Tests if a value is a call or invoke to a function that returns a /// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions). -bool isNoAliasFn(const Value *V, bool LookThroughBitCast = false); +bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI, + bool LookThroughBitCast = false); /// \brief Tests if a value is a call or invoke to a library function that /// allocates uninitialized memory (such as malloc). -bool isMallocLikeFn(const Value *V, bool LookThroughBitCast = false); +bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, + bool LookThroughBitCast = false); /// \brief Tests if a value is a call or invoke to a library function that /// allocates zero-filled memory (such as calloc). -bool isCallocLikeFn(const Value *V, bool LookThroughBitCast = false); +bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, + bool LookThroughBitCast = false); /// \brief Tests if a value is a call or invoke to a library function that /// allocates memory (either malloc, calloc, or strdup like). -bool isAllocLikeFn(const Value *V, bool LookThroughBitCast = false); +bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, + bool LookThroughBitCast = false); /// \brief Tests if a value is a call or invoke to a library function that /// reallocates memory (such as realloc). -bool isReallocLikeFn(const Value *V, bool LookThroughBitCast = false); +bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, + bool LookThroughBitCast = false); //===----------------------------------------------------------------------===// @@ -65,29 +72,31 @@ bool isReallocLikeFn(const Value *V, bool LookThroughBitCast = false); /// extractMallocCall - Returns the corresponding CallInst if the instruction /// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we /// ignore InvokeInst here. -const CallInst *extractMallocCall(const Value *I); -static inline CallInst *extractMallocCall(Value *I) { - return const_cast<CallInst*>(extractMallocCall((const Value*)I)); +const CallInst *extractMallocCall(const Value *I, const TargetLibraryInfo *TLI); +static inline CallInst *extractMallocCall(Value *I, + const TargetLibraryInfo *TLI) { + return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI)); } /// isArrayMalloc - Returns the corresponding CallInst if the instruction /// is a call to malloc whose array size can be determined and the array size /// is not constant 1. Otherwise, return NULL. -const CallInst *isArrayMalloc(const Value *I, const TargetData *TD); +const CallInst *isArrayMalloc(const Value *I, const TargetData *TD, + const TargetLibraryInfo *TLI); /// getMallocType - Returns the PointerType resulting from the malloc call. /// The PointerType depends on the number of bitcast uses of the malloc call: /// 0: PointerType is the malloc calls' return type. /// 1: PointerType is the bitcast's result type. /// >1: Unique PointerType cannot be determined, return NULL. -PointerType *getMallocType(const CallInst *CI); +PointerType *getMallocType(const CallInst *CI, const TargetLibraryInfo *TLI); /// getMallocAllocatedType - Returns the Type allocated by malloc call. /// The Type depends on the number of bitcast uses of the malloc call: /// 0: PointerType is the malloc calls' return type. /// 1: PointerType is the bitcast's result type. /// >1: Unique PointerType cannot be determined, return NULL. -Type *getMallocAllocatedType(const CallInst *CI); +Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI); /// getMallocArraySize - Returns the array size of a malloc call. If the /// argument passed to malloc is a multiple of the size of the malloced type, @@ -95,6 +104,7 @@ Type *getMallocAllocatedType(const CallInst *CI); /// constant 1. Otherwise, return NULL for mallocs whose array size cannot be /// determined. Value *getMallocArraySize(CallInst *CI, const TargetData *TD, + const TargetLibraryInfo *TLI, bool LookThroughSExt = false); @@ -104,9 +114,10 @@ Value *getMallocArraySize(CallInst *CI, const TargetData *TD, /// extractCallocCall - Returns the corresponding CallInst if the instruction /// is a calloc call. -const CallInst *extractCallocCall(const Value *I); -static inline CallInst *extractCallocCall(Value *I) { - return const_cast<CallInst*>(extractCallocCall((const Value*)I)); +const CallInst *extractCallocCall(const Value *I, const TargetLibraryInfo *TLI); +static inline CallInst *extractCallocCall(Value *I, + const TargetLibraryInfo *TLI) { + return const_cast<CallInst*>(extractCallocCall((const Value*)I, TLI)); } @@ -115,10 +126,10 @@ static inline CallInst *extractCallocCall(Value *I) { // /// isFreeCall - Returns non-null if the value is a call to the builtin free() -const CallInst *isFreeCall(const Value *I); +const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI); -static inline CallInst *isFreeCall(Value *I) { - return const_cast<CallInst*>(isFreeCall((const Value*)I)); +static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) { + return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI)); } @@ -131,7 +142,7 @@ static inline CallInst *isFreeCall(Value *I) { /// If RoundToAlign is true, then Size is rounded up to the aligment of allocas, /// byval arguments, and global variables. bool getObjectSize(const Value *Ptr, uint64_t &Size, const TargetData *TD, - bool RoundToAlign = false); + const TargetLibraryInfo *TLI, bool RoundToAlign = false); @@ -143,6 +154,7 @@ class ObjectSizeOffsetVisitor : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> { const TargetData *TD; + const TargetLibraryInfo *TLI; bool RoundToAlign; unsigned IntTyBits; APInt Zero; @@ -155,8 +167,8 @@ class ObjectSizeOffsetVisitor } public: - ObjectSizeOffsetVisitor(const TargetData *TD, LLVMContext &Context, - bool RoundToAlign = false); + ObjectSizeOffsetVisitor(const TargetData *TD, const TargetLibraryInfo *TLI, + LLVMContext &Context, bool RoundToAlign = false); SizeOffsetType compute(Value *V); @@ -202,6 +214,7 @@ class ObjectSizeOffsetEvaluator typedef SmallPtrSet<const Value*, 8> PtrSetTy; const TargetData *TD; + const TargetLibraryInfo *TLI; LLVMContext &Context; BuilderTy Builder; IntegerType *IntTy; @@ -215,7 +228,8 @@ class ObjectSizeOffsetEvaluator SizeOffsetEvalType compute_(Value *V); public: - ObjectSizeOffsetEvaluator(const TargetData *TD, LLVMContext &Context); + ObjectSizeOffsetEvaluator(const TargetData *TD, const TargetLibraryInfo *TLI, + LLVMContext &Context); SizeOffsetEvalType compute(Value *V); bool knownSize(SizeOffsetEvalType SizeOffset) { diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index a22bd12..c52f846 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -103,6 +103,14 @@ namespace llvm { //===--------------------------------------------------------------------===// // + // createProfileMetadataLoaderPass - This pass loads information from a + // profile dump file and sets branch weight metadata. + // + ModulePass *createProfileMetadataLoaderPass(); + extern char &ProfileMetadataLoaderPassID; + + //===--------------------------------------------------------------------===// + // // createNoProfileInfoPass - This pass implements the default "no profile". // ImmutablePass *createNoProfileInfoPass(); diff --git a/include/llvm/Analysis/ProfileDataLoader.h b/include/llvm/Analysis/ProfileDataLoader.h new file mode 100644 index 0000000..bec9fac --- /dev/null +++ b/include/llvm/Analysis/ProfileDataLoader.h @@ -0,0 +1,142 @@ +//===- ProfileDataLoader.h - Load & convert profile info ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The ProfileDataLoader class is used to load profiling data from a dump file. +// The ProfileDataT<FType, BType> class is used to store the mapping of this +// data to control flow edges. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H +#define LLVM_ANALYSIS_PROFILEDATALOADER_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include <string> + +namespace llvm { + +class ModulePass; +class Function; +class BasicBlock; + +// Helper for dumping edges to dbgs(). +raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, + const BasicBlock *> E); + +/// \brief The ProfileDataT<FType, BType> class is used to store the mapping of +/// profiling data to control flow edges. +/// +/// An edge is defined by its source and sink basic blocks. +template<class FType, class BType> +class ProfileDataT { +public: + // The profiling information defines an Edge by its source and sink basic + // blocks. + typedef std::pair<const BType*, const BType*> Edge; + +private: + typedef DenseMap<Edge, unsigned> EdgeWeights; + + /// \brief Count the number of times a transition between two blocks is + /// executed. + /// + /// As a special case, we also hold an edge from the null BasicBlock to the + /// entry block to indicate how many times the function was entered. + DenseMap<const FType*, EdgeWeights> EdgeInformation; + +public: + /// getFunction() - Returns the Function for an Edge. + static const FType *getFunction(Edge e) { + // e.first may be NULL + assert(((!e.first) || (e.first->getParent() == e.second->getParent())) + && "A ProfileData::Edge can not be between two functions"); + assert(e.second && "A ProfileData::Edge must have a real sink"); + return e.second->getParent(); + } + + /// getEdge() - Creates an Edge between two BasicBlocks. + static Edge getEdge(const BType *Src, const BType *Dest) { + return Edge(Src, Dest); + } + + /// getEdgeWeight - Return the number of times that a given edge was + /// executed. + unsigned getEdgeWeight(Edge e) const { + const FType *f = getFunction(e); + assert((EdgeInformation.find(f) != EdgeInformation.end()) + && "No profiling information for function"); + EdgeWeights weights = EdgeInformation.find(f)->second; + + assert((weights.find(e) != weights.end()) + && "No profiling information for edge"); + return weights.find(e)->second; + } + + /// addEdgeWeight - Add 'weight' to the already stored execution count for + /// this edge. + void addEdgeWeight(Edge e, unsigned weight) { + EdgeInformation[getFunction(e)][e] += weight; + } +}; + +typedef ProfileDataT<Function, BasicBlock> ProfileData; +//typedef ProfileDataT<MachineFunction, MachineBasicBlock> MachineProfileData; + +/// The ProfileDataLoader class is used to load raw profiling data from the +/// dump file. +class ProfileDataLoader { +private: + /// The name of the file where the raw profiling data is stored. + const std::string &Filename; + + /// A vector of the command line arguments used when the target program was + /// run to generate profiling data. One entry per program run. + SmallVector<std::string, 1> CommandLines; + + /// The raw values for how many times each edge was traversed, values from + /// multiple program runs are accumulated. + SmallVector<unsigned, 32> EdgeCounts; + +public: + /// ProfileDataLoader ctor - Read the specified profiling data file, exiting + /// the program if the file is invalid or broken. + ProfileDataLoader(const char *ToolName, const std::string &Filename); + + /// A special value used to represent the weight of an edge which has not + /// been counted yet. + static const unsigned Uncounted; + + /// The maximum value that can be stored in a profiling counter. + static const unsigned MaxCount; + + /// getNumExecutions - Return the number of times the target program was run + /// to generate this profiling data. + unsigned getNumExecutions() const { return CommandLines.size(); } + + /// getExecution - Return the command line parameters used to generate the + /// i'th set of profiling data. + const std::string &getExecution(unsigned i) const { return CommandLines[i]; } + + const std::string &getFileName() const { return Filename; } + + /// getRawEdgeCounts - Return the raw profiling data, this is just a list of + /// numbers with no mappings to edges. + ArrayRef<unsigned> getRawEdgeCounts() const { return EdgeCounts; } +}; + +/// createProfileMetadataLoaderPass - This function returns a Pass that loads +/// the profiling information for the module from the specified filename. +ModulePass *createProfileMetadataLoaderPass(const std::string &Filename); + +} // End llvm namespace + +#endif diff --git a/include/llvm/Analysis/ProfileDataTypes.h b/include/llvm/Analysis/ProfileDataTypes.h new file mode 100644 index 0000000..1be15e0 --- /dev/null +++ b/include/llvm/Analysis/ProfileDataTypes.h @@ -0,0 +1,39 @@ +/*===-- ProfileDataTypes.h - Profiling info shared constants --------------===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file is distributed under the University of Illinois Open Source +|* License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This file defines constants shared by the various different profiling +|* runtime libraries and the LLVM C++ profile metadata loader. It must be a +|* C header because, at present, the profiling runtimes are written in C. +|* +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_ANALYSIS_PROFILEDATATYPES_H +#define LLVM_ANALYSIS_PROFILEDATATYPES_H + +/* Included by libprofile. */ +#if defined(__cplusplus) +extern "C" { +#endif + +/* TODO: Strip out unused entries once ProfileInfo etc has been removed. */ +enum ProfilingType { + ArgumentInfo = 1, /* The command line argument block */ + FunctionInfo = 2, /* Function profiling information */ + BlockInfo = 3, /* Block profiling information */ + EdgeInfo = 4, /* Edge profiling information */ + PathInfo = 5, /* Path profiling information */ + BBTraceInfo = 6, /* Basic block trace information */ + OptEdgeInfo = 7 /* Edge profiling information, optimal version */ +}; + +#if defined(__cplusplus) +} +#endif + +#endif /* LLVM_ANALYSIS_PROFILEDATATYPES_H */ diff --git a/include/llvm/Analysis/ProfileInfoTypes.h b/include/llvm/Analysis/ProfileInfoTypes.h index 6b4ac85..45aab5b 100644 --- a/include/llvm/Analysis/ProfileInfoTypes.h +++ b/include/llvm/Analysis/ProfileInfoTypes.h @@ -27,15 +27,7 @@ enum ProfilingStorageType { ProfilingHash = 2 }; -enum ProfilingType { - ArgumentInfo = 1, /* The command line argument block */ - FunctionInfo = 2, /* Function profiling information */ - BlockInfo = 3, /* Block profiling information */ - EdgeInfo = 4, /* Edge profiling information */ - PathInfo = 5, /* Path profiling information */ - BBTraceInfo = 6, /* Basic block trace information */ - OptEdgeInfo = 7 /* Edge profiling information, optimal version */ -}; +#include "llvm/Analysis/ProfileDataTypes.h" /* * The header for tables that map path numbers to path counters. diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index 188d11c..e62040e 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -473,27 +473,6 @@ public: const_iterator end() const { return children.end(); } //@} - /// @name BasicBlock Node Iterators - /// - /// These iterators iterate over all BasicBlock RegionNodes that are - /// contained in this Region. The iterator also iterates over BasicBlock - /// RegionNodes that are elements of a subregion of this Region. It is - /// therefore called a flat iterator. - //@{ - typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false, - GraphTraits<FlatIt<RegionNode*> > > block_node_iterator; - - typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>, - false, GraphTraits<FlatIt<const RegionNode*> > > - const_block_node_iterator; - - block_node_iterator block_node_begin(); - block_node_iterator block_node_end(); - - const_block_node_iterator block_node_begin() const; - const_block_node_iterator block_node_end() const; - //@} - /// @name BasicBlock Iterators /// /// These iterators iterate over all BasicBlocks that are contained in this |
