diff options
Diffstat (limited to 'include/llvm/Analysis')
-rw-r--r-- | include/llvm/Analysis/AliasSetTracker.h | 8 | ||||
-rw-r--r-- | include/llvm/Analysis/DebugInfo.h | 41 | ||||
-rw-r--r-- | include/llvm/Analysis/IVUsers.h | 2 | ||||
-rw-r--r-- | include/llvm/Analysis/LoopDependenceAnalysis.h | 14 | ||||
-rw-r--r-- | include/llvm/Analysis/LoopInfo.h | 9 | ||||
-rw-r--r-- | include/llvm/Analysis/LoopPass.h | 4 | ||||
-rw-r--r-- | include/llvm/Analysis/MemoryDependenceAnalysis.h | 73 | ||||
-rw-r--r-- | include/llvm/Analysis/PHITransAddr.h | 121 | ||||
-rw-r--r-- | include/llvm/Analysis/Passes.h | 1 | ||||
-rw-r--r-- | include/llvm/Analysis/ProfileInfo.h | 180 |
10 files changed, 366 insertions, 87 deletions
diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 42a377e..09f12ad 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -259,11 +259,9 @@ class AliasSetTracker { ASTCallbackVH(Value *V, AliasSetTracker *AST = 0); ASTCallbackVH &operator=(Value *V); }; - /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that ASTCallbackVH - /// is not a POD (it needs its destructor called). - struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> { - static bool isPod() { return false; } - }; + /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to + /// compare and hash the value handle. + struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {}; AliasAnalysis &AA; ilist<AliasSet> AliasSets; diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index 866ed8a..232804e 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -197,7 +197,8 @@ namespace llvm { FlagProtected = 1 << 1, FlagFwdDecl = 1 << 2, FlagAppleBlock = 1 << 3, - FlagBlockByrefStruct = 1 << 4 + FlagBlockByrefStruct = 1 << 4, + FlagVirtual = 1 << 5 }; protected: @@ -242,6 +243,9 @@ namespace llvm { bool isBlockByrefStruct() const { return (getFlags() & FlagBlockByrefStruct) != 0; } + bool isVirtual() const { + return (getFlags() & FlagVirtual) != 0; + } /// dump - print type. void dump() const; @@ -366,6 +370,24 @@ namespace llvm { /// compile unit, like 'static' in C. unsigned isLocalToUnit() const { return getUnsignedField(9); } unsigned isDefinition() const { return getUnsignedField(10); } + + unsigned getVirtuality() const { + if (DbgNode->getNumElements() < 14) + return 0; + return getUnsignedField(11); + } + + unsigned getVirtualIndex() const { + if (DbgNode->getNumElements() < 14) + return 0; + return getUnsignedField(12); + } + + DICompositeType getContainingType() const { + assert (DbgNode->getNumElements() >= 14 && "Invalid type!"); + return getFieldAs<DICompositeType>(13); + } + StringRef getFilename() const { return getCompileUnit().getFilename();} StringRef getDirectory() const { return getCompileUnit().getDirectory();} @@ -470,6 +492,7 @@ namespace llvm { const Type *EmptyStructPtr; // "{}*". Function *DeclareFn; // llvm.dbg.declare + Function *ValueFn; // llvm.dbg.value DIFactory(const DIFactory &); // DO NOT IMPLEMENT void operator=(const DIFactory&); // DO NOT IMPLEMENT @@ -565,7 +588,14 @@ namespace llvm { StringRef LinkageName, DICompileUnit CompileUnit, unsigned LineNo, DIType Type, bool isLocalToUnit, - bool isDefinition); + bool isDefinition, + unsigned VK = 0, + unsigned VIndex = 0, + DIType = DIType()); + + /// CreateSubprogramDefinition - Create new subprogram descriptor for the + /// given declaration. + DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration); /// CreateGlobalVariable - Create a new descriptor for the specified global. DIGlobalVariable @@ -610,6 +640,13 @@ namespace llvm { Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, Instruction *InsertBefore); + /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. + Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset, + DIVariable D, BasicBlock *InsertAtEnd); + + /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. + Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset, + DIVariable D, Instruction *InsertBefore); private: Constant *GetTagConstant(unsigned TAG); }; diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 22fbb35..fcd9caa 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -175,11 +175,11 @@ class IVUsers : public LoopPass { ScalarEvolution *SE; SmallPtrSet<Instruction*,16> Processed; -public: /// IVUses - A list of all tracked IV uses of induction variable expressions /// we are interested in. ilist<IVUsersOfOneStride> IVUses; +public: /// IVUsesByStride - A mapping from the strides in StrideOrder to the /// uses in IVUses. std::map<const SCEV *, IVUsersOfOneStride*> IVUsesByStride; diff --git a/include/llvm/Analysis/LoopDependenceAnalysis.h b/include/llvm/Analysis/LoopDependenceAnalysis.h index 1d386ba..a1a5637 100644 --- a/include/llvm/Analysis/LoopDependenceAnalysis.h +++ b/include/llvm/Analysis/LoopDependenceAnalysis.h @@ -67,17 +67,17 @@ class LoopDependenceAnalysis : public LoopPass { /// created. The third argument is set to the pair found or created. bool findOrInsertDependencePair(Value*, Value*, DependencePair*&); - /// getLoops - Collect all loops of the loop-nest L a given SCEV is variant - /// in. + /// getLoops - Collect all loops of the loop nest L in which + /// a given SCEV is variant. void getLoops(const SCEV*, DenseSet<const Loop*>*) const; /// isLoopInvariant - True if a given SCEV is invariant in all loops of the - /// loop-nest starting at the innermost loop L. + /// loop nest starting at the innermost loop L. bool isLoopInvariant(const SCEV*) const; - /// isAffine - An SCEV is affine with respect to the loop-nest starting at + /// isAffine - An SCEV is affine with respect to the loop nest starting at /// the innermost loop L if it is of the form A+B*X where A, B are invariant - /// in the loop-nest and X is a induction variable in the loop-nest. + /// in the loop nest and X is a induction variable in the loop nest. bool isAffine(const SCEV*) const; /// TODO: doc @@ -93,8 +93,8 @@ public: static char ID; // Class identification, replacement for typeinfo LoopDependenceAnalysis() : LoopPass(&ID) {} - /// isDependencePair - Check wether two values can possibly give rise to a - /// data dependence: that is the case if both are instructions accessing + /// isDependencePair - Check whether two values can possibly give rise to + /// a data dependence: that is the case if both are instructions accessing /// memory and at least one of those accesses is a write. bool isDependencePair(const Value*, const Value*) const; diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 9969d99..2294e53 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -568,7 +568,7 @@ public: /// getUniqueExitBlocks - Return all unique successor blocks of this loop. /// These are the blocks _outside of the current loop_ which are branched to. - /// This assumes that loop is in canonical form. + /// This assumes that loop exits are in canonical form. /// void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const; @@ -976,13 +976,6 @@ public: void removeBlock(BasicBlock *BB) { LI.removeBlock(BB); } - - static bool isNotAlreadyContainedIn(const Loop *SubLoop, - const Loop *ParentLoop) { - return - LoopInfoBase<BasicBlock, Loop>::isNotAlreadyContainedIn(SubLoop, - ParentLoop); - } }; diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h index 2eb329f..2dceccb 100644 --- a/include/llvm/Analysis/LoopPass.h +++ b/include/llvm/Analysis/LoopPass.h @@ -52,7 +52,7 @@ public: // LPPassManger as expected. void preparePassManager(PMStack &PMS); - /// Assign pass manager to manager this pass + /// Assign pass manager to manage this pass virtual void assignPassManager(PMStack &PMS, PassManagerType PMT = PMT_LoopPassManager); @@ -73,7 +73,7 @@ public: /// cloneBasicBlockAnalysis - Clone analysis info associated with basic block. virtual void cloneBasicBlockAnalysis(BasicBlock *F, BasicBlock *T, Loop *L) {} - /// deletekAnalysisValue - Delete analysis info associated with value V. + /// deleteAnalysisValue - Delete analysis info associated with value V. virtual void deleteAnalysisValue(Value *V, Loop *L) {} }; diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 6b300fd..c04631b 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -16,6 +16,7 @@ #include "llvm/BasicBlock.h" #include "llvm/Pass.h" +#include "llvm/Support/ValueHandle.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" @@ -31,6 +32,7 @@ namespace llvm { class MemoryDependenceAnalysis; class PredIteratorCache; class DominatorTree; + class PHITransAddr; /// MemDepResult - A memory dependence query can return one of three different /// answers, described below. @@ -60,9 +62,9 @@ namespace llvm { /// this case, the load is loading an undef value or a store is the /// first store to (that part of) the allocation. /// 3. Dependence queries on calls return Def only when they are - /// readonly calls with identical callees and no intervening - /// clobbers. No validation is done that the operands to the calls - /// are the same. + /// readonly calls or memory use intrinsics with identical callees + /// and no intervening clobbers. No validation is done that the + /// operands to the calls are the same. Def, /// NonLocal - This marker indicates that the query has no dependency in @@ -130,6 +132,45 @@ namespace llvm { } }; + /// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache, and an + /// entry in the results set for a non-local query. For each BasicBlock (the + /// BB entry) it keeps a MemDepResult and the (potentially phi translated) + /// address that was live in the block. + class NonLocalDepEntry { + BasicBlock *BB; + MemDepResult Result; + WeakVH Address; + public: + NonLocalDepEntry(BasicBlock *bb, MemDepResult result, Value *address) + : BB(bb), Result(result), Address(address) {} + + // This is used for searches. + NonLocalDepEntry(BasicBlock *bb) : BB(bb) {} + + // BB is the sort key, it can't be changed. + BasicBlock *getBB() const { return BB; } + + void setResult(const MemDepResult &R, Value *Addr) { + Result = R; + Address = Addr; + } + + const MemDepResult &getResult() const { return Result; } + + /// getAddress - Return the address of this pointer in this block. This can + /// be different than the address queried for the non-local result because + /// of phi translation. This returns null if the address was not available + /// in a block (i.e. because phi translation failed) or if this is a cached + /// result and that address was deleted. + /// + /// The address is always null for a non-local 'call' dependence. + Value *getAddress() const { return Address; } + + bool operator<(const NonLocalDepEntry &RHS) const { + return BB < RHS.BB; + } + }; + /// MemoryDependenceAnalysis - This is an analysis that determines, for a /// given memory operation, what preceding memory operations it depends on. /// It builds on alias analysis information, and tries to provide a lazy, @@ -151,7 +192,6 @@ namespace llvm { LocalDepMapType LocalDeps; public: - typedef std::pair<BasicBlock*, MemDepResult> NonLocalDepEntry; typedef std::vector<NonLocalDepEntry> NonLocalDepInfo; private: /// ValueIsLoadPair - This is a pair<Value*, bool> where the bool is true if @@ -245,29 +285,6 @@ namespace llvm { BasicBlock *BB, SmallVectorImpl<NonLocalDepEntry> &Result); - /// GetPHITranslatedValue - Find an available version of the specified value - /// PHI translated across the specified edge. If MemDep isn't able to - /// satisfy this request, it returns null. - Value *GetPHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD) const; - - /// GetAvailablePHITranslatedValue - Return the value computed by - /// PHITranslatePointer if it dominates PredBB, otherwise return null. - Value *GetAvailablePHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT) const; - - /// InsertPHITranslatedPointer - Insert a computation of the PHI translated - /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB - /// block. All newly created instructions are added to the NewInsts list. - Value *InsertPHITranslatedPointer(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT, - SmallVectorImpl<Instruction*> &NewInsts) const; - /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. void removeInstruction(Instruction *InstToRemove); @@ -288,7 +305,7 @@ namespace llvm { MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall, BasicBlock::iterator ScanIt, BasicBlock *BB); - bool getNonLocalPointerDepFromBB(Value *Pointer, uint64_t Size, + bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t Size, bool isLoad, BasicBlock *BB, SmallVectorImpl<NonLocalDepEntry> &Result, DenseMap<BasicBlock*, Value*> &Visited, diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h new file mode 100644 index 0000000..b612316 --- /dev/null +++ b/include/llvm/Analysis/PHITransAddr.h @@ -0,0 +1,121 @@ +//===- PHITransAddr.h - PHI Translation for Addresses -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the PHITransAddr class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_PHITRANSADDR_H +#define LLVM_ANALYSIS_PHITRANSADDR_H + +#include "llvm/Instruction.h" +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + class DominatorTree; + class TargetData; + +/// PHITransAddr - An address value which tracks and handles phi translation. +/// As we walk "up" the CFG through predecessors, we need to ensure that the +/// address we're tracking is kept up to date. For example, if we're analyzing +/// an address of "&A[i]" and walk through the definition of 'i' which is a PHI +/// node, we *must* phi translate i to get "&A[j]" or else we will analyze an +/// incorrect pointer in the predecessor block. +/// +/// This is designed to be a relatively small object that lives on the stack and +/// is copyable. +/// +class PHITransAddr { + /// Addr - The actual address we're analyzing. + Value *Addr; + + /// TD - The target data we are playing with if known, otherwise null. + const TargetData *TD; + + /// InstInputs - The inputs for our symbolic address. + SmallVector<Instruction*, 4> InstInputs; +public: + PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td) { + // If the address is an instruction, the whole thing is considered an input. + if (Instruction *I = dyn_cast<Instruction>(Addr)) + InstInputs.push_back(I); + } + + Value *getAddr() const { return Addr; } + + /// NeedsPHITranslationFromBlock - Return true if moving from the specified + /// BasicBlock to its predecessors requires PHI translation. + bool NeedsPHITranslationFromBlock(BasicBlock *BB) const { + // We do need translation if one of our input instructions is defined in + // this block. + for (unsigned i = 0, e = InstInputs.size(); i != e; ++i) + if (InstInputs[i]->getParent() == BB) + return true; + return false; + } + + /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true + /// if we have some hope of doing it. This should be used as a filter to + /// avoid calling PHITranslateValue in hopeless situations. + bool IsPotentiallyPHITranslatable() const; + + /// PHITranslateValue - PHI translate the current address up the CFG from + /// CurBB to Pred, updating our state the reflect any needed changes. This + /// returns true on failure and sets Addr to null. + bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB); + + /// PHITranslateWithInsertion - PHI translate this value into the specified + /// predecessor block, inserting a computation of the value if it is + /// unavailable. + /// + /// All newly created instructions are added to the NewInsts list. This + /// returns null on failure. + /// + Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT, + SmallVectorImpl<Instruction*> &NewInsts); + + void dump() const; + + /// Verify - Check internal consistency of this data structure. If the + /// structure is valid, it returns true. If invalid, it prints errors and + /// returns false. + bool Verify() const; +private: + Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB); + + + /// GetAvailablePHITranslatedSubExpr - Return the value computed by + /// PHITranslateSubExpr if it dominates PredBB, otherwise return null. + Value *GetAvailablePHITranslatedSubExpr(Value *V, + BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT) const; + + /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated + /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB + /// block. All newly created instructions are added to the NewInsts list. + /// This returns null on failure. + /// + Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, + BasicBlock *PredBB, const DominatorTree &DT, + SmallVectorImpl<Instruction*> &NewInsts); + + /// AddAsInput - If the specified value is an instruction, add it as an input. + Value *AddAsInput(Value *V) { + // If V is an instruction, it is now an input. + if (Instruction *VI = dyn_cast<Instruction>(V)) + InstInputs.push_back(VI); + return V; + } + +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index b222321..2f39c6a 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -92,6 +92,7 @@ namespace llvm { // file. // ModulePass *createProfileLoaderPass(); + extern const PassInfo *ProfileLoaderPassID; //===--------------------------------------------------------------------===// // diff --git a/include/llvm/Analysis/ProfileInfo.h b/include/llvm/Analysis/ProfileInfo.h index 2a80f3d..80ba6d8 100644 --- a/include/llvm/Analysis/ProfileInfo.h +++ b/include/llvm/Analysis/ProfileInfo.h @@ -21,116 +21,228 @@ #ifndef LLVM_ANALYSIS_PROFILEINFO_H #define LLVM_ANALYSIS_PROFILEINFO_H -#include "llvm/BasicBlock.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" #include <cassert> #include <string> #include <map> +#include <set> namespace llvm { - class Function; class Pass; class raw_ostream; + class BasicBlock; + class Function; + class MachineBasicBlock; + class MachineFunction; + + // Helper for dumping edges to errs(). + raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, const BasicBlock *> E); + raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E); + + raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB); + raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB); + + raw_ostream& operator<<(raw_ostream &O, const Function *F); + raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF); + /// ProfileInfo Class - This class holds and maintains profiling /// information for some unit of code. - class ProfileInfo { + template<class FType, class BType> + class ProfileInfoT { public: // Types for handling profiling information. - typedef std::pair<const BasicBlock*, const BasicBlock*> Edge; + typedef std::pair<const BType*, const BType*> Edge; typedef std::pair<Edge, double> EdgeWeight; typedef std::map<Edge, double> EdgeWeights; - typedef std::map<const BasicBlock*, double> BlockCounts; + typedef std::map<const BType*, double> BlockCounts; + typedef std::map<const BType*, const BType*> Path; protected: // EdgeInformation - 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. - std::map<const Function*, EdgeWeights> EdgeInformation; + std::map<const FType*, EdgeWeights> EdgeInformation; // BlockInformation - Count the number of times a block is executed. - std::map<const Function*, BlockCounts> BlockInformation; + std::map<const FType*, BlockCounts> BlockInformation; // FunctionInformation - Count the number of times a function is executed. - std::map<const Function*, double> FunctionInformation; + std::map<const FType*, double> FunctionInformation; + + ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile; public: static char ID; // Class identification, replacement for typeinfo - virtual ~ProfileInfo(); // We want to be subclassed + ProfileInfoT(); + ~ProfileInfoT(); // We want to be subclassed // MissingValue - The value that is returned for execution counts in case // no value is available. static const double MissingValue; // getFunction() - Returns the Function for an Edge, checking for validity. - static const Function* getFunction(Edge e) { + static const FType* getFunction(Edge e) { if (e.first) { return e.first->getParent(); } else if (e.second) { return e.second->getParent(); } assert(0 && "Invalid ProfileInfo::Edge"); - return (const Function*)0; + return (const FType*)0; } // getEdge() - Creates an Edge from two BasicBlocks. - static Edge getEdge(const BasicBlock *Src, const BasicBlock *Dest) { + static Edge getEdge(const BType *Src, const BType *Dest) { return std::make_pair(Src, Dest); } //===------------------------------------------------------------------===// /// Profile Information Queries /// - double getExecutionCount(const Function *F); + double getExecutionCount(const FType *F); + + double getExecutionCount(const BType *BB); - double getExecutionCount(const BasicBlock *BB); + void setExecutionCount(const BType *BB, double w); + + void addExecutionCount(const BType *BB, double w); double getEdgeWeight(Edge e) const { - std::map<const Function*, EdgeWeights>::const_iterator J = + typename std::map<const FType*, EdgeWeights>::const_iterator J = EdgeInformation.find(getFunction(e)); if (J == EdgeInformation.end()) return MissingValue; - EdgeWeights::const_iterator I = J->second.find(e); + typename EdgeWeights::const_iterator I = J->second.find(e); if (I == J->second.end()) return MissingValue; return I->second; } - EdgeWeights &getEdgeWeights (const Function *F) { + void setEdgeWeight(Edge e, double w) { + DEBUG_WITH_TYPE("profile-info", + errs() << "Creating Edge " << e + << " (weight: " << format("%.20g",w) << ")\n"); + EdgeInformation[getFunction(e)][e] = w; + } + + void addEdgeWeight(Edge e, double w); + + EdgeWeights &getEdgeWeights (const FType *F) { return EdgeInformation[F]; } //===------------------------------------------------------------------===// /// Analysis Update Methods /// - void removeBlock(const BasicBlock *BB) { - std::map<const Function*, BlockCounts>::iterator J = - BlockInformation.find(BB->getParent()); - if (J == BlockInformation.end()) return; - - J->second.erase(BB); + void removeBlock(const BType *BB); + + void removeEdge(Edge e); + + void replaceEdge(const Edge &, const Edge &); + + enum GetPathMode { + GetPathToExit = 1, + GetPathToValue = 2, + GetPathToDest = 4, + GetPathWithNewEdges = 8 + }; + + const BType *GetPath(const BType *Src, const BType *Dest, + Path &P, unsigned Mode); + + void divertFlow(const Edge &, const Edge &); + + void splitEdge(const BType *FirstBB, const BType *SecondBB, + const BType *NewBB, bool MergeIdenticalEdges = false); + + void splitBlock(const BType *Old, const BType* New); + + void splitBlock(const BType *BB, const BType* NewBB, + BType *const *Preds, unsigned NumPreds); + + void replaceAllUses(const BType *RmBB, const BType *DestBB); + + void transfer(const FType *Old, const FType *New); + + void repair(const FType *F); + + void dump(FType *F = 0, bool real = true) { + errs() << "**** This is ProfileInfo " << this << " speaking:\n"; + if (!real) { + typename std::set<const FType*> Functions; + + errs() << "Functions: \n"; + if (F) { + errs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; + Functions.insert(F); + } else { + for (typename std::map<const FType*, double>::iterator fi = FunctionInformation.begin(), + fe = FunctionInformation.end(); fi != fe; ++fi) { + errs() << fi->first << "@" << format("%p",fi->first) << ": " << format("%.20g",fi->second) << "\n"; + Functions.insert(fi->first); + } + } + + for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end(); + FI != FE; ++FI) { + const FType *F = *FI; + typename std::map<const FType*, BlockCounts>::iterator bwi = BlockInformation.find(F); + errs() << "BasicBlocks for Function " << F << ":\n"; + for (typename BlockCounts::const_iterator bi = bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) { + errs() << bi->first << "@" << format("%p", bi->first) << ": " << format("%.20g",bi->second) << "\n"; + } + } + + for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end(); + FI != FE; ++FI) { + typename std::map<const FType*, EdgeWeights>::iterator ei = EdgeInformation.find(*FI); + errs() << "Edges for Function " << ei->first << ":\n"; + for (typename EdgeWeights::iterator ewi = ei->second.begin(), ewe = ei->second.end(); + ewi != ewe; ++ewi) { + errs() << ewi->first << ": " << format("%.20g",ewi->second) << "\n"; + } + } + } else { + assert(F && "No function given, this is not supported!"); + errs() << "Functions: \n"; + errs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; + + errs() << "BasicBlocks for Function " << F << ":\n"; + for (typename FType::const_iterator BI = F->begin(), BE = F->end(); + BI != BE; ++BI) { + const BType *BB = &(*BI); + errs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n"; + } + } + errs() << "**** ProfileInfo " << this << ", over and out.\n"; } - void removeEdge(Edge e) { - std::map<const Function*, EdgeWeights>::iterator J = - EdgeInformation.find(getFunction(e)); - if (J == EdgeInformation.end()) return; + bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false); - J->second.erase(e); - } + bool EstimateMissingEdges(const BType *BB); - void splitEdge(const BasicBlock *FirstBB, const BasicBlock *SecondBB, - const BasicBlock *NewBB, bool MergeIdenticalEdges = false); + ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() { + if (MachineProfile == 0) + MachineProfile = new ProfileInfoT<MachineFunction, MachineBasicBlock>(); + return MachineProfile; + } - void replaceAllUses(const BasicBlock *RmBB, const BasicBlock *DestBB); + bool hasMI() const { + return (MachineProfile != 0); + } }; + typedef ProfileInfoT<Function, BasicBlock> ProfileInfo; + typedef ProfileInfoT<MachineFunction, MachineBasicBlock> MachineProfileInfo; + /// createProfileLoaderPass - This function returns a Pass that loads the /// profiling information for the module from the specified filename, making /// it available to the optimizers. Pass *createProfileLoaderPass(const std::string &Filename); - raw_ostream& operator<<(raw_ostream &O, ProfileInfo::Edge E); - } // End llvm namespace #endif |