summaryrefslogtreecommitdiffstats
path: root/include/llvm/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Analysis')
-rw-r--r--include/llvm/Analysis/AliasSetTracker.h8
-rw-r--r--include/llvm/Analysis/DebugInfo.h41
-rw-r--r--include/llvm/Analysis/IVUsers.h2
-rw-r--r--include/llvm/Analysis/LoopDependenceAnalysis.h14
-rw-r--r--include/llvm/Analysis/LoopInfo.h9
-rw-r--r--include/llvm/Analysis/LoopPass.h4
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h73
-rw-r--r--include/llvm/Analysis/PHITransAddr.h121
-rw-r--r--include/llvm/Analysis/Passes.h1
-rw-r--r--include/llvm/Analysis/ProfileInfo.h180
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
OpenPOWER on IntegriCloud