aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/Analysis.cpp10
-rw-r--r--lib/Analysis/CMakeLists.txt10
-rw-r--r--lib/Analysis/PathNumbering.cpp521
-rw-r--r--lib/Analysis/PathProfileInfo.cpp433
-rw-r--r--lib/Analysis/PathProfileVerifier.cpp205
-rw-r--r--lib/Analysis/ProfileDataLoader.cpp155
-rw-r--r--lib/Analysis/ProfileDataLoaderPass.cpp188
-rw-r--r--lib/Analysis/ProfileEstimatorPass.cpp426
-rw-r--r--lib/Analysis/ProfileInfo.cpp1079
-rw-r--r--lib/Analysis/ProfileInfoLoader.cpp155
-rw-r--r--lib/Analysis/ProfileInfoLoaderPass.cpp267
-rw-r--r--lib/Analysis/ProfileVerifierPass.cpp383
12 files changed, 0 insertions, 3832 deletions
diff --git a/lib/Analysis/Analysis.cpp b/lib/Analysis/Analysis.cpp
index 349c417..8062393 100644
--- a/lib/Analysis/Analysis.cpp
+++ b/lib/Analysis/Analysis.cpp
@@ -54,16 +54,6 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeMemoryDependenceAnalysisPass(Registry);
initializeModuleDebugInfoPrinterPass(Registry);
initializePostDominatorTreePass(Registry);
- initializeProfileEstimatorPassPass(Registry);
- initializeNoProfileInfoPass(Registry);
- initializeNoPathProfileInfoPass(Registry);
- initializeProfileInfoAnalysisGroup(Registry);
- initializePathProfileInfoAnalysisGroup(Registry);
- initializeLoaderPassPass(Registry);
- initializePathProfileLoaderPassPass(Registry);
- initializeProfileVerifierPassPass(Registry);
- initializePathProfileVerifierPass(Registry);
- initializeProfileMetadataLoaderPassPass(Registry);
initializeRegionInfoPass(Registry);
initializeRegionViewerPass(Registry);
initializeRegionPrinterPass(Registry);
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
index 94ded34..3d7c0ed 100644
--- a/lib/Analysis/CMakeLists.txt
+++ b/lib/Analysis/CMakeLists.txt
@@ -35,17 +35,7 @@ add_llvm_library(LLVMAnalysis
ModuleDebugInfoPrinter.cpp
NoAliasAnalysis.cpp
PHITransAddr.cpp
- PathNumbering.cpp
- PathProfileInfo.cpp
- PathProfileVerifier.cpp
PostDominators.cpp
- ProfileEstimatorPass.cpp
- ProfileInfo.cpp
- ProfileInfoLoader.cpp
- ProfileInfoLoaderPass.cpp
- ProfileVerifierPass.cpp
- ProfileDataLoader.cpp
- ProfileDataLoaderPass.cpp
PtrUseVisitor.cpp
RegionInfo.cpp
RegionPass.cpp
diff --git a/lib/Analysis/PathNumbering.cpp b/lib/Analysis/PathNumbering.cpp
deleted file mode 100644
index 30d213b..0000000
--- a/lib/Analysis/PathNumbering.cpp
+++ /dev/null
@@ -1,521 +0,0 @@
-//===- PathNumbering.cpp --------------------------------------*- C++ -*---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Ball-Larus path numbers uniquely identify paths through a directed acyclic
-// graph (DAG) [Ball96]. For a CFG backedges are removed and replaced by phony
-// edges to obtain a DAG, and thus the unique path numbers [Ball96].
-//
-// The purpose of this analysis is to enumerate the edges in a CFG in order
-// to obtain paths from path numbers in a convenient manner. As described in
-// [Ball96] edges can be enumerated such that given a path number by following
-// the CFG and updating the path number, the path is obtained.
-//
-// [Ball96]
-// T. Ball and J. R. Larus. "Efficient Path Profiling."
-// International Symposium on Microarchitecture, pages 46-57, 1996.
-// http://portal.acm.org/citation.cfm?id=243857
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "ball-larus-numbering"
-
-#include "llvm/Analysis/PathNumbering.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/TypeBuilder.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CFG.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include <queue>
-#include <sstream>
-#include <stack>
-#include <string>
-#include <utility>
-
-using namespace llvm;
-
-// Are we enabling early termination
-static cl::opt<bool> ProcessEarlyTermination(
- "path-profile-early-termination", cl::Hidden,
- cl::desc("In path profiling, insert extra instrumentation to account for "
- "unexpected function termination."));
-
-// Returns the basic block for the BallLarusNode
-BasicBlock* BallLarusNode::getBlock() {
- return(_basicBlock);
-}
-
-// Returns the number of paths to the exit starting at the node.
-unsigned BallLarusNode::getNumberPaths() {
- return(_numberPaths);
-}
-
-// Sets the number of paths to the exit starting at the node.
-void BallLarusNode::setNumberPaths(unsigned numberPaths) {
- _numberPaths = numberPaths;
-}
-
-// Gets the NodeColor used in graph algorithms.
-BallLarusNode::NodeColor BallLarusNode::getColor() {
- return(_color);
-}
-
-// Sets the NodeColor used in graph algorithms.
-void BallLarusNode::setColor(BallLarusNode::NodeColor color) {
- _color = color;
-}
-
-// Returns an iterator over predecessor edges. Includes phony and
-// backedges.
-BLEdgeIterator BallLarusNode::predBegin() {
- return(_predEdges.begin());
-}
-
-// Returns the end sentinel for the predecessor iterator.
-BLEdgeIterator BallLarusNode::predEnd() {
- return(_predEdges.end());
-}
-
-// Returns the number of predecessor edges. Includes phony and
-// backedges.
-unsigned BallLarusNode::getNumberPredEdges() {
- return(_predEdges.size());
-}
-
-// Returns an iterator over successor edges. Includes phony and
-// backedges.
-BLEdgeIterator BallLarusNode::succBegin() {
- return(_succEdges.begin());
-}
-
-// Returns the end sentinel for the successor iterator.
-BLEdgeIterator BallLarusNode::succEnd() {
- return(_succEdges.end());
-}
-
-// Returns the number of successor edges. Includes phony and
-// backedges.
-unsigned BallLarusNode::getNumberSuccEdges() {
- return(_succEdges.size());
-}
-
-// Add an edge to the predecessor list.
-void BallLarusNode::addPredEdge(BallLarusEdge* edge) {
- _predEdges.push_back(edge);
-}
-
-// Remove an edge from the predecessor list.
-void BallLarusNode::removePredEdge(BallLarusEdge* edge) {
- removeEdge(_predEdges, edge);
-}
-
-// Add an edge to the successor list.
-void BallLarusNode::addSuccEdge(BallLarusEdge* edge) {
- _succEdges.push_back(edge);
-}
-
-// Remove an edge from the successor list.
-void BallLarusNode::removeSuccEdge(BallLarusEdge* edge) {
- removeEdge(_succEdges, edge);
-}
-
-// Returns the name of the BasicBlock being represented. If BasicBlock
-// is null then returns "<null>". If BasicBlock has no name, then
-// "<unnamed>" is returned. Intended for use with debug output.
-std::string BallLarusNode::getName() {
- std::stringstream name;
-
- if(getBlock() != NULL) {
- if(getBlock()->hasName()) {
- std::string tempName(getBlock()->getName());
- name << tempName.c_str() << " (" << _uid << ")";
- } else
- name << "<unnamed> (" << _uid << ")";
- } else
- name << "<null> (" << _uid << ")";
-
- return name.str();
-}
-
-// Removes an edge from an edgeVector. Used by removePredEdge and
-// removeSuccEdge.
-void BallLarusNode::removeEdge(BLEdgeVector& v, BallLarusEdge* e) {
- // TODO: Avoid linear scan by using a set instead
- for(BLEdgeIterator i = v.begin(),
- end = v.end();
- i != end;
- ++i) {
- if((*i) == e) {
- v.erase(i);
- break;
- }
- }
-}
-
-// Returns the source node of this edge.
-BallLarusNode* BallLarusEdge::getSource() const {
- return(_source);
-}
-
-// Returns the target node of this edge.
-BallLarusNode* BallLarusEdge::getTarget() const {
- return(_target);
-}
-
-// Sets the type of the edge.
-BallLarusEdge::EdgeType BallLarusEdge::getType() const {
- return _edgeType;
-}
-
-// Gets the type of the edge.
-void BallLarusEdge::setType(EdgeType type) {
- _edgeType = type;
-}
-
-// Returns the weight of this edge. Used to decode path numbers to sequences
-// of basic blocks.
-unsigned BallLarusEdge::getWeight() {
- return(_weight);
-}
-
-// Sets the weight of the edge. Used during path numbering.
-void BallLarusEdge::setWeight(unsigned weight) {
- _weight = weight;
-}
-
-// Gets the phony edge originating at the root.
-BallLarusEdge* BallLarusEdge::getPhonyRoot() {
- return _phonyRoot;
-}
-
-// Sets the phony edge originating at the root.
-void BallLarusEdge::setPhonyRoot(BallLarusEdge* phonyRoot) {
- _phonyRoot = phonyRoot;
-}
-
-// Gets the phony edge terminating at the exit.
-BallLarusEdge* BallLarusEdge::getPhonyExit() {
- return _phonyExit;
-}
-
-// Sets the phony edge terminating at the exit.
-void BallLarusEdge::setPhonyExit(BallLarusEdge* phonyExit) {
- _phonyExit = phonyExit;
-}
-
-// Gets the associated real edge if this is a phony edge.
-BallLarusEdge* BallLarusEdge::getRealEdge() {
- return _realEdge;
-}
-
-// Sets the associated real edge if this is a phony edge.
-void BallLarusEdge::setRealEdge(BallLarusEdge* realEdge) {
- _realEdge = realEdge;
-}
-
-// Returns the duplicate number of the edge.
-unsigned BallLarusEdge::getDuplicateNumber() {
- return(_duplicateNumber);
-}
-
-// Initialization that requires virtual functions which are not fully
-// functional in the constructor.
-void BallLarusDag::init() {
- BLBlockNodeMap inDag;
- std::stack<BallLarusNode*> dfsStack;
-
- _root = addNode(&(_function.getEntryBlock()));
- _exit = addNode(NULL);
-
- // start search from root
- dfsStack.push(getRoot());
-
- // dfs to add each bb into the dag
- while(dfsStack.size())
- buildNode(inDag, dfsStack);
-
- // put in the final edge
- addEdge(getExit(),getRoot(),0);
-}
-
-// Frees all memory associated with the DAG.
-BallLarusDag::~BallLarusDag() {
- for(BLEdgeIterator edge = _edges.begin(), end = _edges.end(); edge != end;
- ++edge)
- delete (*edge);
-
- for(BLNodeIterator node = _nodes.begin(), end = _nodes.end(); node != end;
- ++node)
- delete (*node);
-}
-
-// Calculate the path numbers by assigning edge increments as prescribed
-// in Ball-Larus path profiling.
-void BallLarusDag::calculatePathNumbers() {
- BallLarusNode* node;
- std::queue<BallLarusNode*> bfsQueue;
- bfsQueue.push(getExit());
-
- while(bfsQueue.size() > 0) {
- node = bfsQueue.front();
-
- DEBUG(dbgs() << "calculatePathNumbers on " << node->getName() << "\n");
-
- bfsQueue.pop();
- unsigned prevPathNumber = node->getNumberPaths();
- calculatePathNumbersFrom(node);
-
- // Check for DAG splitting
- if( node->getNumberPaths() > 100000000 && node != getRoot() ) {
- // Add new phony edge from the split-node to the DAG's exit
- BallLarusEdge* exitEdge = addEdge(node, getExit(), 0);
- exitEdge->setType(BallLarusEdge::SPLITEDGE_PHONY);
-
- // Counters to handle the possibility of a multi-graph
- BasicBlock* oldTarget = 0;
- unsigned duplicateNumber = 0;
-
- // Iterate through each successor edge, adding phony edges
- for( BLEdgeIterator succ = node->succBegin(), end = node->succEnd();
- succ != end; oldTarget = (*succ)->getTarget()->getBlock(), succ++ ) {
-
- if( (*succ)->getType() == BallLarusEdge::NORMAL ) {
- // is this edge a duplicate?
- if( oldTarget != (*succ)->getTarget()->getBlock() )
- duplicateNumber = 0;
-
- // create the new phony edge: root -> succ
- BallLarusEdge* rootEdge =
- addEdge(getRoot(), (*succ)->getTarget(), duplicateNumber++);
- rootEdge->setType(BallLarusEdge::SPLITEDGE_PHONY);
- rootEdge->setRealEdge(*succ);
-
- // split on this edge and reference it's exit/root phony edges
- (*succ)->setType(BallLarusEdge::SPLITEDGE);
- (*succ)->setPhonyRoot(rootEdge);
- (*succ)->setPhonyExit(exitEdge);
- (*succ)->setWeight(0);
- }
- }
-
- calculatePathNumbersFrom(node);
- }
-
- DEBUG(dbgs() << "prev, new number paths " << prevPathNumber << ", "
- << node->getNumberPaths() << ".\n");
-
- if(prevPathNumber == 0 && node->getNumberPaths() != 0) {
- DEBUG(dbgs() << "node ready : " << node->getName() << "\n");
- for(BLEdgeIterator pred = node->predBegin(), end = node->predEnd();
- pred != end; pred++) {
- if( (*pred)->getType() == BallLarusEdge::BACKEDGE ||
- (*pred)->getType() == BallLarusEdge::SPLITEDGE )
- continue;
-
- BallLarusNode* nextNode = (*pred)->getSource();
- // not yet visited?
- if(nextNode->getNumberPaths() == 0)
- bfsQueue.push(nextNode);
- }
- }
- }
-
- DEBUG(dbgs() << "\tNumber of paths: " << getRoot()->getNumberPaths() << "\n");
-}
-
-// Returns the number of paths for the Dag.
-unsigned BallLarusDag::getNumberOfPaths() {
- return(getRoot()->getNumberPaths());
-}
-
-// Returns the root (i.e. entry) node for the DAG.
-BallLarusNode* BallLarusDag::getRoot() {
- return _root;
-}
-
-// Returns the exit node for the DAG.
-BallLarusNode* BallLarusDag::getExit() {
- return _exit;
-}
-
-// Returns the function for the DAG.
-Function& BallLarusDag::getFunction() {
- return(_function);
-}
-
-// Clears the node colors.
-void BallLarusDag::clearColors(BallLarusNode::NodeColor color) {
- for (BLNodeIterator nodeIt = _nodes.begin(); nodeIt != _nodes.end(); nodeIt++)
- (*nodeIt)->setColor(color);
-}
-
-// Processes one node and its imediate edges for building the DAG.
-void BallLarusDag::buildNode(BLBlockNodeMap& inDag, BLNodeStack& dfsStack) {
- BallLarusNode* currentNode = dfsStack.top();
- BasicBlock* currentBlock = currentNode->getBlock();
-
- if(currentNode->getColor() != BallLarusNode::WHITE) {
- // we have already visited this node
- dfsStack.pop();
- currentNode->setColor(BallLarusNode::BLACK);
- } else {
- // are there any external procedure calls?
- if( ProcessEarlyTermination ) {
- for( BasicBlock::iterator bbCurrent = currentNode->getBlock()->begin(),
- bbEnd = currentNode->getBlock()->end(); bbCurrent != bbEnd;
- bbCurrent++ ) {
- Instruction& instr = *bbCurrent;
- if( instr.getOpcode() == Instruction::Call ) {
- BallLarusEdge* callEdge = addEdge(currentNode, getExit(), 0);
- callEdge->setType(BallLarusEdge::CALLEDGE_PHONY);
- break;
- }
- }
- }
-
- TerminatorInst* terminator = currentNode->getBlock()->getTerminator();
- if(isa<ReturnInst>(terminator) || isa<UnreachableInst>(terminator) ||
- isa<ResumeInst>(terminator))
- addEdge(currentNode, getExit(),0);
-
- currentNode->setColor(BallLarusNode::GRAY);
- inDag[currentBlock] = currentNode;
-
- BasicBlock* oldSuccessor = 0;
- unsigned duplicateNumber = 0;
-
- // iterate through this node's successors
- for(succ_iterator successor = succ_begin(currentBlock),
- succEnd = succ_end(currentBlock); successor != succEnd;
- oldSuccessor = *successor, ++successor ) {
- BasicBlock* succBB = *successor;
-
- // is this edge a duplicate?
- if (oldSuccessor == succBB)
- duplicateNumber++;
- else
- duplicateNumber = 0;
-
- buildEdge(inDag, dfsStack, currentNode, succBB, duplicateNumber);
- }
- }
-}
-
-// Process an edge in the CFG for DAG building.
-void BallLarusDag::buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>&
- dfsStack, BallLarusNode* currentNode,
- BasicBlock* succBB, unsigned duplicateCount) {
- BallLarusNode* succNode = inDag[succBB];
-
- if(succNode && succNode->getColor() == BallLarusNode::BLACK) {
- // visited node and forward edge
- addEdge(currentNode, succNode, duplicateCount);
- } else if(succNode && succNode->getColor() == BallLarusNode::GRAY) {
- // visited node and back edge
- DEBUG(dbgs() << "Backedge detected.\n");
- addBackedge(currentNode, succNode, duplicateCount);
- } else {
- BallLarusNode* childNode;
- // not visited node and forward edge
- if(succNode) // an unvisited node that is child of a gray node
- childNode = succNode;
- else { // an unvisited node that is a child of a an unvisted node
- childNode = addNode(succBB);
- inDag[succBB] = childNode;
- }
- addEdge(currentNode, childNode, duplicateCount);
- dfsStack.push(childNode);
- }
-}
-
-// The weight on each edge is the increment required along any path that
-// contains that edge.
-void BallLarusDag::calculatePathNumbersFrom(BallLarusNode* node) {
- if(node == getExit())
- // The Exit node must be base case
- node->setNumberPaths(1);
- else {
- unsigned sumPaths = 0;
- BallLarusNode* succNode;
-
- for(BLEdgeIterator succ = node->succBegin(), end = node->succEnd();
- succ != end; succ++) {
- if( (*succ)->getType() == BallLarusEdge::BACKEDGE ||
- (*succ)->getType() == BallLarusEdge::SPLITEDGE )
- continue;
-
- (*succ)->setWeight(sumPaths);
- succNode = (*succ)->getTarget();
-
- if( !succNode->getNumberPaths() )
- return;
- sumPaths += succNode->getNumberPaths();
- }
-
- node->setNumberPaths(sumPaths);
- }
-}
-
-// Allows subclasses to determine which type of Node is created.
-// Override this method to produce subclasses of BallLarusNode if
-// necessary. The destructor of BallLarusDag will call free on each
-// pointer created.
-BallLarusNode* BallLarusDag::createNode(BasicBlock* BB) {
- return( new BallLarusNode(BB) );
-}
-
-// Allows subclasses to determine which type of Edge is created.
-// Override this method to produce subclasses of BallLarusEdge if
-// necessary. The destructor of BallLarusDag will call free on each
-// pointer created.
-BallLarusEdge* BallLarusDag::createEdge(BallLarusNode* source,
- BallLarusNode* target,
- unsigned duplicateCount) {
- return( new BallLarusEdge(source, target, duplicateCount) );
-}
-
-// Proxy to node's constructor. Updates the DAG state.
-BallLarusNode* BallLarusDag::addNode(BasicBlock* BB) {
- BallLarusNode* newNode = createNode(BB);
- _nodes.push_back(newNode);
- return( newNode );
-}
-
-// Proxy to edge's constructor. Updates the DAG state.
-BallLarusEdge* BallLarusDag::addEdge(BallLarusNode* source,
- BallLarusNode* target,
- unsigned duplicateCount) {
- BallLarusEdge* newEdge = createEdge(source, target, duplicateCount);
- _edges.push_back(newEdge);
- source->addSuccEdge(newEdge);
- target->addPredEdge(newEdge);
- return(newEdge);
-}
-
-// Adds a backedge with its phony edges. Updates the DAG state.
-void BallLarusDag::addBackedge(BallLarusNode* source, BallLarusNode* target,
- unsigned duplicateCount) {
- BallLarusEdge* childEdge = addEdge(source, target, duplicateCount);
- childEdge->setType(BallLarusEdge::BACKEDGE);
-
- childEdge->setPhonyRoot(addEdge(getRoot(), target,0));
- childEdge->setPhonyExit(addEdge(source, getExit(),0));
-
- childEdge->getPhonyRoot()->setRealEdge(childEdge);
- childEdge->getPhonyRoot()->setType(BallLarusEdge::BACKEDGE_PHONY);
-
- childEdge->getPhonyExit()->setRealEdge(childEdge);
- childEdge->getPhonyExit()->setType(BallLarusEdge::BACKEDGE_PHONY);
- _backEdges.push_back(childEdge);
-}
diff --git a/lib/Analysis/PathProfileInfo.cpp b/lib/Analysis/PathProfileInfo.cpp
deleted file mode 100644
index bc53221..0000000
--- a/lib/Analysis/PathProfileInfo.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-//===- PathProfileInfo.cpp ------------------------------------*- C++ -*---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface used by optimizers to load path profiles,
-// and provides a loader pass which reads a path profile file.
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "path-profile-info"
-
-#include "llvm/Analysis/PathProfileInfo.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Analysis/ProfileInfoTypes.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdio>
-
-using namespace llvm;
-
-// command line option for loading path profiles
-static cl::opt<std::string>
-PathProfileInfoFilename("path-profile-loader-file", cl::init("llvmprof.out"),
- cl::value_desc("filename"),
- cl::desc("Path profile file loaded by -path-profile-loader"), cl::Hidden);
-
-namespace {
- class PathProfileLoaderPass : public ModulePass, public PathProfileInfo {
- public:
- PathProfileLoaderPass() : ModulePass(ID) { }
- ~PathProfileLoaderPass();
-
- // this pass doesn't change anything (only loads information)
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
-
- // the full name of the loader pass
- virtual const char* getPassName() const {
- return "Path Profiling Information Loader";
- }
-
- // required since this pass implements multiple inheritance
- virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
- if (PI == &PathProfileInfo::ID)
- return (PathProfileInfo*)this;
- return this;
- }
-
- // entry point to run the pass
- bool runOnModule(Module &M);
-
- // pass identification
- static char ID;
-
- private:
- // make a reference table to refer to function by number
- void buildFunctionRefs(Module &M);
-
- // process argument info of a program from the input file
- void handleArgumentInfo();
-
- // process path number information from the input file
- void handlePathInfo();
-
- // array of references to the functions in the module
- std::vector<Function*> _functions;
-
- // path profile file handle
- FILE* _file;
-
- // path profile file name
- std::string _filename;
- };
-}
-
-// register PathLoader
-char PathProfileLoaderPass::ID = 0;
-
-INITIALIZE_ANALYSIS_GROUP(PathProfileInfo, "Path Profile Information",
- NoPathProfileInfo)
-INITIALIZE_AG_PASS(PathProfileLoaderPass, PathProfileInfo,
- "path-profile-loader",
- "Load path profile information from file",
- false, true, false)
-
-char &llvm::PathProfileLoaderPassID = PathProfileLoaderPass::ID;
-
-// link PathLoader as a pass, and make it available as an optimisation
-ModulePass *llvm::createPathProfileLoaderPass() {
- return new PathProfileLoaderPass;
-}
-
-// ----------------------------------------------------------------------------
-// PathEdge implementation
-//
-ProfilePathEdge::ProfilePathEdge (BasicBlock* source, BasicBlock* target,
- unsigned duplicateNumber)
- : _source(source), _target(target), _duplicateNumber(duplicateNumber) {}
-
-// ----------------------------------------------------------------------------
-// Path implementation
-//
-
-ProfilePath::ProfilePath (unsigned int number, unsigned int count,
- double countStdDev, PathProfileInfo* ppi)
- : _number(number) , _count(count), _countStdDev(countStdDev), _ppi(ppi) {}
-
-double ProfilePath::getFrequency() const {
- return 100 * double(_count) /
- double(_ppi->_functionPathCounts[_ppi->_currentFunction]);
-}
-
-static BallLarusEdge* getNextEdge (BallLarusNode* node,
- unsigned int pathNumber) {
- BallLarusEdge* best = 0;
-
- for( BLEdgeIterator next = node->succBegin(),
- end = node->succEnd(); next != end; next++ ) {
- if( (*next)->getType() != BallLarusEdge::BACKEDGE && // no backedges
- (*next)->getType() != BallLarusEdge::SPLITEDGE && // no split edges
- (*next)->getWeight() <= pathNumber && // weight must be <= pathNumber
- (!best || (best->getWeight() < (*next)->getWeight())) ) // best one?
- best = *next;
- }
-
- return best;
-}
-
-ProfilePathEdgeVector* ProfilePath::getPathEdges() const {
- BallLarusNode* currentNode = _ppi->_currentDag->getRoot ();
- unsigned int increment = _number;
- ProfilePathEdgeVector* pev = new ProfilePathEdgeVector;
-
- while (currentNode != _ppi->_currentDag->getExit()) {
- BallLarusEdge* next = getNextEdge(currentNode, increment);
-
- increment -= next->getWeight();
-
- if( next->getType() != BallLarusEdge::BACKEDGE_PHONY &&
- next->getType() != BallLarusEdge::SPLITEDGE_PHONY &&
- next->getTarget() != _ppi->_currentDag->getExit() )
- pev->push_back(ProfilePathEdge(
- next->getSource()->getBlock(),
- next->getTarget()->getBlock(),
- next->getDuplicateNumber()));
-
- if( next->getType() == BallLarusEdge::BACKEDGE_PHONY &&
- next->getTarget() == _ppi->_currentDag->getExit() )
- pev->push_back(ProfilePathEdge(
- next->getRealEdge()->getSource()->getBlock(),
- next->getRealEdge()->getTarget()->getBlock(),
- next->getDuplicateNumber()));
-
- if( next->getType() == BallLarusEdge::SPLITEDGE_PHONY &&
- next->getSource() == _ppi->_currentDag->getRoot() )
- pev->push_back(ProfilePathEdge(
- next->getRealEdge()->getSource()->getBlock(),
- next->getRealEdge()->getTarget()->getBlock(),
- next->getDuplicateNumber()));
-
- // set the new node
- currentNode = next->getTarget();
- }
-
- return pev;
-}
-
-ProfilePathBlockVector* ProfilePath::getPathBlocks() const {
- BallLarusNode* currentNode = _ppi->_currentDag->getRoot ();
- unsigned int increment = _number;
- ProfilePathBlockVector* pbv = new ProfilePathBlockVector;
-
- while (currentNode != _ppi->_currentDag->getExit()) {
- BallLarusEdge* next = getNextEdge(currentNode, increment);
- increment -= next->getWeight();
-
- // add block to the block list if it is a real edge
- if( next->getType() == BallLarusEdge::NORMAL)
- pbv->push_back (currentNode->getBlock());
- // make the back edge the last edge since we are at the end
- else if( next->getTarget() == _ppi->_currentDag->getExit() ) {
- pbv->push_back (currentNode->getBlock());
- pbv->push_back (next->getRealEdge()->getTarget()->getBlock());
- }
-
- // set the new node
- currentNode = next->getTarget();
- }
-
- return pbv;
-}
-
-BasicBlock* ProfilePath::getFirstBlockInPath() const {
- BallLarusNode* root = _ppi->_currentDag->getRoot();
- BallLarusEdge* edge = getNextEdge(root, _number);
-
- if( edge && (edge->getType() == BallLarusEdge::BACKEDGE_PHONY ||
- edge->getType() == BallLarusEdge::SPLITEDGE_PHONY) )
- return edge->getTarget()->getBlock();
-
- return root->getBlock();
-}
-
-// ----------------------------------------------------------------------------
-// PathProfileInfo implementation
-//
-
-// Pass identification
-char llvm::PathProfileInfo::ID = 0;
-
-PathProfileInfo::PathProfileInfo () : _currentDag(0) , _currentFunction(0) {
-}
-
-PathProfileInfo::~PathProfileInfo() {
- if (_currentDag)
- delete _currentDag;
-}
-
-// set the function for which paths are currently begin processed
-void PathProfileInfo::setCurrentFunction(Function* F) {
- // Make sure it exists
- if (!F) return;
-
- if (_currentDag)
- delete _currentDag;
-
- _currentFunction = F;
- _currentDag = new BallLarusDag(*F);
- _currentDag->init();
- _currentDag->calculatePathNumbers();
-}
-
-// get the function for which paths are currently being processed
-Function* PathProfileInfo::getCurrentFunction() const {
- return _currentFunction;
-}
-
-// get the entry block of the function
-BasicBlock* PathProfileInfo::getCurrentFunctionEntry() {
- return _currentDag->getRoot()->getBlock();
-}
-
-// return the path based on its number
-ProfilePath* PathProfileInfo::getPath(unsigned int number) {
- return _functionPaths[_currentFunction][number];
-}
-
-// return the number of paths which a function may potentially execute
-unsigned int PathProfileInfo::getPotentialPathCount() {
- return _currentDag ? _currentDag->getNumberOfPaths() : 0;
-}
-
-// return an iterator for the beginning of a functions executed paths
-ProfilePathIterator PathProfileInfo::pathBegin() {
- return _functionPaths[_currentFunction].begin();
-}
-
-// return an iterator for the end of a functions executed paths
-ProfilePathIterator PathProfileInfo::pathEnd() {
- return _functionPaths[_currentFunction].end();
-}
-
-// returns the total number of paths run in the function
-unsigned int PathProfileInfo::pathsRun() {
- return _currentFunction ? _functionPaths[_currentFunction].size() : 0;
-}
-
-// ----------------------------------------------------------------------------
-// PathLoader implementation
-//
-
-// remove all generated paths
-PathProfileLoaderPass::~PathProfileLoaderPass() {
- for( FunctionPathIterator funcNext = _functionPaths.begin(),
- funcEnd = _functionPaths.end(); funcNext != funcEnd; funcNext++)
- for( ProfilePathIterator pathNext = funcNext->second.begin(),
- pathEnd = funcNext->second.end(); pathNext != pathEnd; pathNext++)
- delete pathNext->second;
-}
-
-// entry point of the pass; this loads and parses a file
-bool PathProfileLoaderPass::runOnModule(Module &M) {
- // get the filename and setup the module's function references
- _filename = PathProfileInfoFilename;
- buildFunctionRefs (M);
-
- if (!(_file = fopen(_filename.c_str(), "rb"))) {
- errs () << "error: input '" << _filename << "' file does not exist.\n";
- return false;
- }
-
- ProfilingType profType;
-
- while( fread(&profType, sizeof(ProfilingType), 1, _file) ) {
- switch (profType) {
- case ArgumentInfo:
- handleArgumentInfo ();
- break;
- case PathInfo:
- handlePathInfo ();
- break;
- default:
- errs () << "error: bad path profiling file syntax, " << profType << "\n";
- fclose (_file);
- return false;
- }
- }
-
- fclose (_file);
-
- return true;
-}
-
-// create a reference table for functions defined in the path profile file
-void PathProfileLoaderPass::buildFunctionRefs (Module &M) {
- _functions.push_back(0); // make the 0 index a null pointer
-
- for (Module::iterator F = M.begin(), E = M.end(); F != E; F++) {
- if (F->isDeclaration())
- continue;
- _functions.push_back(F);
- }
-}
-
-// handle command like argument infor in the output file
-void PathProfileLoaderPass::handleArgumentInfo() {
- // get the argument list's length
- unsigned savedArgsLength;
- if( fread(&savedArgsLength, sizeof(unsigned), 1, _file) != 1 ) {
- errs() << "warning: argument info header/data mismatch\n";
- return;
- }
-
- // allocate a buffer, and get the arguments
- char* args = new char[savedArgsLength+1];
- if( fread(args, 1, savedArgsLength, _file) != savedArgsLength )
- errs() << "warning: argument info header/data mismatch\n";
-
- args[savedArgsLength] = '\0';
- argList = std::string(args);
- delete [] args; // cleanup dynamic string
-
- // byte alignment
- if (savedArgsLength & 3)
- fseek(_file, 4-(savedArgsLength&3), SEEK_CUR);
-}
-
-// Handle path profile information in the output file
-void PathProfileLoaderPass::handlePathInfo () {
- // get the number of functions in this profile
- unsigned functionCount;
- if( fread(&functionCount, sizeof(functionCount), 1, _file) != 1 ) {
- errs() << "warning: path info header/data mismatch\n";
- return;
- }
-
- // gather path information for each function
- for (unsigned i = 0; i < functionCount; i++) {
- PathProfileHeader pathHeader;
- if( fread(&pathHeader, sizeof(pathHeader), 1, _file) != 1 ) {
- errs() << "warning: bad header for path function info\n";
- break;
- }
-
- Function* f = _functions[pathHeader.fnNumber];
-
- // dynamically allocate a table to store path numbers
- PathProfileTableEntry* pathTable =
- new PathProfileTableEntry[pathHeader.numEntries];
-
- if( fread(pathTable, sizeof(PathProfileTableEntry),
- pathHeader.numEntries, _file) != pathHeader.numEntries) {
- delete [] pathTable;
- errs() << "warning: path function info header/data mismatch\n";
- return;
- }
-
- // Build a new path for the current function
- unsigned int totalPaths = 0;
- for (unsigned int j = 0; j < pathHeader.numEntries; j++) {
- totalPaths += pathTable[j].pathCounter;
- _functionPaths[f][pathTable[j].pathNumber]
- = new ProfilePath(pathTable[j].pathNumber, pathTable[j].pathCounter,
- 0, this);
- }
-
- _functionPathCounts[f] = totalPaths;
-
- delete [] pathTable;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// NoProfile PathProfileInfo implementation
-//
-
-namespace {
- struct NoPathProfileInfo : public ImmutablePass, public PathProfileInfo {
- static char ID; // Class identification, replacement for typeinfo
- NoPathProfileInfo() : ImmutablePass(ID) {
- initializeNoPathProfileInfoPass(*PassRegistry::getPassRegistry());
- }
-
- /// getAdjustedAnalysisPointer - This method is used when a pass implements
- /// an analysis interface through multiple inheritance. If needed, it
- /// should override this to adjust the this pointer as needed for the
- /// specified pass info.
- virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
- if (PI == &PathProfileInfo::ID)
- return (PathProfileInfo*)this;
- return this;
- }
-
- virtual const char *getPassName() const {
- return "NoPathProfileInfo";
- }
- };
-} // End of anonymous namespace
-
-char NoPathProfileInfo::ID = 0;
-// Register this pass...
-INITIALIZE_AG_PASS(NoPathProfileInfo, PathProfileInfo, "no-path-profile",
- "No Path Profile Information", false, true, true)
-
-ImmutablePass *llvm::createNoPathProfileInfoPass() { return new NoPathProfileInfo(); }
diff --git a/lib/Analysis/PathProfileVerifier.cpp b/lib/Analysis/PathProfileVerifier.cpp
deleted file mode 100644
index dabd347..0000000
--- a/lib/Analysis/PathProfileVerifier.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-//===- PathProfileVerifier.cpp --------------------------------*- C++ -*---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This verifier derives an edge profile file from current path profile
-// information
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "path-profile-verifier"
-
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Analysis/PathProfileInfo.h"
-#include "llvm/Analysis/ProfileInfoTypes.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include <stdio.h>
-
-using namespace llvm;
-
-namespace {
- class PathProfileVerifier : public ModulePass {
- private:
- bool runOnModule(Module &M);
-
- public:
- static char ID; // Pass identification, replacement for typeid
- PathProfileVerifier() : ModulePass(ID) {
- initializePathProfileVerifierPass(*PassRegistry::getPassRegistry());
- }
-
-
- virtual const char *getPassName() const {
- return "Path Profiler Verifier";
- }
-
- // The verifier requires the path profile and edge profile.
- virtual void getAnalysisUsage(AnalysisUsage& AU) const;
- };
-}
-
-static cl::opt<std::string>
-EdgeProfileFilename("path-profile-verifier-file",
- cl::init("edgefrompath.llvmprof.out"),
- cl::value_desc("filename"),
- cl::desc("Edge profile file generated by -path-profile-verifier"),
- cl::Hidden);
-
-char PathProfileVerifier::ID = 0;
-INITIALIZE_PASS(PathProfileVerifier, "path-profile-verifier",
- "Compare the path profile derived edge profile against the "
- "edge profile.", true, true)
-
-ModulePass *llvm::createPathProfileVerifierPass() {
- return new PathProfileVerifier();
-}
-
-// The verifier requires the path profile and edge profile.
-void PathProfileVerifier::getAnalysisUsage(AnalysisUsage& AU) const {
- AU.addRequired<PathProfileInfo>();
- AU.addPreserved<PathProfileInfo>();
-}
-
-typedef std::map<unsigned, unsigned> DuplicateToIndexMap;
-typedef std::map<BasicBlock*,DuplicateToIndexMap> BlockToDuplicateMap;
-typedef std::map<BasicBlock*,BlockToDuplicateMap> NestedBlockToIndexMap;
-
-// the verifier iterates through each path to gather the total
-// number of edge frequencies
-bool PathProfileVerifier::runOnModule (Module &M) {
- PathProfileInfo& pathProfileInfo = getAnalysis<PathProfileInfo>();
-
- // setup a data structure to map path edges which index an
- // array of edge counters
- NestedBlockToIndexMap arrayMap;
- unsigned i = 0;
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- if (F->isDeclaration()) continue;
-
- arrayMap[(BasicBlock*)0][F->begin()][0] = i++;
-
- for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
- TerminatorInst *TI = BB->getTerminator();
-
- unsigned duplicate = 0;
- BasicBlock* prev = 0;
- for (unsigned s = 0, e = TI->getNumSuccessors(); s != e;
- prev = TI->getSuccessor(s), ++s) {
- if (prev == TI->getSuccessor(s))
- duplicate++;
- else duplicate = 0;
-
- arrayMap[BB][TI->getSuccessor(s)][duplicate] = i++;
- }
- }
- }
-
- std::vector<unsigned> edgeArray(i);
-
- // iterate through each path and increment the edge counters as needed
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- if (F->isDeclaration()) continue;
-
- pathProfileInfo.setCurrentFunction(F);
-
- DEBUG(dbgs() << "function '" << F->getName() << "' ran "
- << pathProfileInfo.pathsRun()
- << "/" << pathProfileInfo.getPotentialPathCount()
- << " potential paths\n");
-
- for( ProfilePathIterator nextPath = pathProfileInfo.pathBegin(),
- endPath = pathProfileInfo.pathEnd();
- nextPath != endPath; nextPath++ ) {
- ProfilePath* currentPath = nextPath->second;
-
- ProfilePathEdgeVector* pev = currentPath->getPathEdges();
- DEBUG(dbgs () << "path #" << currentPath->getNumber() << ": "
- << currentPath->getCount() << "\n");
- // setup the entry edge (normally path profiling doesn't care about this)
- if (currentPath->getFirstBlockInPath() == &F->getEntryBlock())
- edgeArray[arrayMap[(BasicBlock*)0][currentPath->getFirstBlockInPath()][0]]
- += currentPath->getCount();
-
- for( ProfilePathEdgeIterator nextEdge = pev->begin(),
- endEdge = pev->end(); nextEdge != endEdge; nextEdge++ ) {
- if (nextEdge != pev->begin())
- DEBUG(dbgs() << " :: ");
-
- BasicBlock* source = nextEdge->getSource();
- BasicBlock* target = nextEdge->getTarget();
- unsigned duplicateNumber = nextEdge->getDuplicateNumber();
- DEBUG(dbgs() << source->getName() << " --{" << duplicateNumber
- << "}--> " << target->getName());
-
- // Ensure all the referenced edges exist
- // TODO: make this a separate function
- if( !arrayMap.count(source) ) {
- errs() << " error [" << F->getName() << "()]: source '"
- << source->getName()
- << "' does not exist in the array map.\n";
- } else if( !arrayMap[source].count(target) ) {
- errs() << " error [" << F->getName() << "()]: target '"
- << target->getName()
- << "' does not exist in the array map.\n";
- } else if( !arrayMap[source][target].count(duplicateNumber) ) {
- errs() << " error [" << F->getName() << "()]: edge "
- << source->getName() << " -> " << target->getName()
- << " duplicate number " << duplicateNumber
- << " does not exist in the array map.\n";
- } else {
- edgeArray[arrayMap[source][target][duplicateNumber]]
- += currentPath->getCount();
- }
- }
-
- DEBUG(errs() << "\n");
-
- delete pev;
- }
- }
-
- std::string filename = EdgeProfileFilename;
-
- // Open a handle to the file
- FILE* edgeFile = fopen(filename.c_str(),"wb");
-
- if (!edgeFile) {
- errs() << "error: unable to open file '" << filename << "' for output.\n";
- return false;
- }
-
- errs() << "Generating edge profile '" << filename << "' ...\n";
-
- // write argument info
- unsigned type = ArgumentInfo;
- unsigned num = pathProfileInfo.argList.size();
- int zeros = 0;
-
- fwrite(&type,sizeof(unsigned),1,edgeFile);
- fwrite(&num,sizeof(unsigned),1,edgeFile);
- fwrite(pathProfileInfo.argList.c_str(),1,num,edgeFile);
- if (num&3)
- fwrite(&zeros, 1, 4-(num&3), edgeFile);
-
- type = EdgeInfo;
- num = edgeArray.size();
- fwrite(&type,sizeof(unsigned),1,edgeFile);
- fwrite(&num,sizeof(unsigned),1,edgeFile);
-
- // write each edge to the file
- for( std::vector<unsigned>::iterator s = edgeArray.begin(),
- e = edgeArray.end(); s != e; s++)
- fwrite(&*s, sizeof (unsigned), 1, edgeFile);
-
- fclose (edgeFile);
-
- return true;
-}
diff --git a/lib/Analysis/ProfileDataLoader.cpp b/lib/Analysis/ProfileDataLoader.cpp
deleted file mode 100644
index 3d0a1e2..0000000
--- a/lib/Analysis/ProfileDataLoader.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-//===- ProfileDataLoader.cpp - Load profile information from disk ---------===//
-//
-// 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 raw profiling data from the dump
-// file.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/ProfileDataLoader.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Analysis/ProfileDataTypes.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
-#include <cstdio>
-#include <cstdlib>
-using namespace llvm;
-
-raw_ostream &llvm::operator<<(raw_ostream &O, std::pair<const BasicBlock *,
- const BasicBlock *> E) {
- O << "(";
-
- if (E.first)
- O << E.first->getName();
- else
- O << "0";
-
- O << ",";
-
- if (E.second)
- O << E.second->getName();
- else
- O << "0";
-
- return O << ")";
-}
-
-/// AddCounts - Add 'A' and 'B', accounting for the fact that the value of one
-/// (or both) may not be defined.
-static unsigned AddCounts(unsigned A, unsigned B) {
- // If either value is undefined, use the other.
- // Undefined + undefined = undefined.
- if (A == ProfileDataLoader::Uncounted) return B;
- if (B == ProfileDataLoader::Uncounted) return A;
-
- return A + B;
-}
-
-/// ReadProfilingData - Load 'NumEntries' items of type 'T' from file 'F'
-template <typename T>
-static void ReadProfilingData(const char *ToolName, FILE *F,
- T *Data, size_t NumEntries) {
- // Read in the block of data...
- if (fread(Data, sizeof(T), NumEntries, F) != NumEntries)
- report_fatal_error(Twine(ToolName) + ": Profiling data truncated");
-}
-
-/// ReadProfilingNumEntries - Read how many entries are in this profiling data
-/// packet.
-static unsigned ReadProfilingNumEntries(const char *ToolName, FILE *F,
- bool ShouldByteSwap) {
- unsigned Entry;
- ReadProfilingData<unsigned>(ToolName, F, &Entry, 1);
- return ShouldByteSwap ? ByteSwap_32(Entry) : Entry;
-}
-
-/// ReadProfilingBlock - Read the number of entries in the next profiling data
-/// packet and then accumulate the entries into 'Data'.
-static void ReadProfilingBlock(const char *ToolName, FILE *F,
- bool ShouldByteSwap,
- SmallVectorImpl<unsigned> &Data) {
- // Read the number of entries...
- unsigned NumEntries = ReadProfilingNumEntries(ToolName, F, ShouldByteSwap);
-
- // Read in the data.
- SmallVector<unsigned, 8> TempSpace(NumEntries);
- ReadProfilingData<unsigned>(ToolName, F, TempSpace.data(), NumEntries);
-
- // Make sure we have enough space ...
- if (Data.size() < NumEntries)
- Data.resize(NumEntries, ProfileDataLoader::Uncounted);
-
- // Accumulate the data we just read into the existing data.
- for (unsigned i = 0; i < NumEntries; ++i) {
- unsigned Entry = ShouldByteSwap ? ByteSwap_32(TempSpace[i]) : TempSpace[i];
- Data[i] = AddCounts(Entry, Data[i]);
- }
-}
-
-/// ReadProfilingArgBlock - Read the command line arguments that the progam was
-/// run with when the current profiling data packet(s) were generated.
-static void ReadProfilingArgBlock(const char *ToolName, FILE *F,
- bool ShouldByteSwap,
- SmallVectorImpl<std::string> &CommandLines) {
- // Read the number of bytes ...
- unsigned ArgLength = ReadProfilingNumEntries(ToolName, F, ShouldByteSwap);
-
- // Read in the arguments (if there are any to read). Round up the length to
- // the nearest 4-byte multiple.
- SmallVector<char, 8> Args(ArgLength+4);
- if (ArgLength)
- ReadProfilingData<char>(ToolName, F, Args.data(), (ArgLength+3) & ~3);
-
- // Store the arguments.
- CommandLines.push_back(std::string(&Args[0], &Args[ArgLength]));
-}
-
-const unsigned ProfileDataLoader::Uncounted = ~0U;
-
-/// ProfileDataLoader ctor - Read the specified profiling data file, reporting
-/// a fatal error if the file is invalid or broken.
-ProfileDataLoader::ProfileDataLoader(const char *ToolName,
- const std::string &Filename)
- : Filename(Filename) {
- FILE *F = fopen(Filename.c_str(), "rb");
- if (F == 0)
- report_fatal_error(Twine(ToolName) + ": Error opening '" +
- Filename + "': ");
-
- // Keep reading packets until we run out of them.
- unsigned PacketType;
- while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
- // If the low eight bits of the packet are zero, we must be dealing with an
- // endianness mismatch. Byteswap all words read from the profiling
- // information. This can happen when the compiler host and target have
- // different endianness.
- bool ShouldByteSwap = (char)PacketType == 0;
- PacketType = ShouldByteSwap ? ByteSwap_32(PacketType) : PacketType;
-
- switch (PacketType) {
- case ArgumentInfo:
- ReadProfilingArgBlock(ToolName, F, ShouldByteSwap, CommandLines);
- break;
-
- case EdgeInfo:
- ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts);
- break;
-
- default:
- report_fatal_error(std::string(ToolName)
- + ": Unknown profiling packet type");
- break;
- }
- }
-
- fclose(F);
-}
diff --git a/lib/Analysis/ProfileDataLoaderPass.cpp b/lib/Analysis/ProfileDataLoaderPass.cpp
deleted file mode 100644
index 2ee0093..0000000
--- a/lib/Analysis/ProfileDataLoaderPass.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-//===- ProfileDataLoaderPass.cpp - Set branch weight metadata from prof ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass loads profiling data from a dump file and sets branch weight
-// metadata.
-//
-// TODO: Replace all "profile-metadata-loader" strings with "profile-loader"
-// once ProfileInfo etc. has been removed.
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "profile-metadata-loader"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/ProfileDataLoader.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/MDBuilder.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CFG.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-STATISTIC(NumEdgesRead, "The # of edges read.");
-STATISTIC(NumTermsAnnotated, "The # of terminator instructions annotated.");
-
-static cl::opt<std::string>
-ProfileMetadataFilename("profile-file", cl::init("llvmprof.out"),
- cl::value_desc("filename"),
- cl::desc("Profile file loaded by -profile-metadata-loader"));
-
-namespace {
- /// This pass loads profiling data from a dump file and sets branch weight
- /// metadata.
- class ProfileMetadataLoaderPass : public ModulePass {
- std::string Filename;
- public:
- static char ID; // Class identification, replacement for typeinfo
- explicit ProfileMetadataLoaderPass(const std::string &filename = "")
- : ModulePass(ID), Filename(filename) {
- initializeProfileMetadataLoaderPassPass(*PassRegistry::getPassRegistry());
- if (filename.empty()) Filename = ProfileMetadataFilename;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
-
- virtual const char *getPassName() const {
- return "Profile loader";
- }
-
- virtual void readEdge(unsigned, ProfileData&, ProfileData::Edge,
- ArrayRef<unsigned>);
- virtual unsigned matchEdges(Module&, ProfileData&, ArrayRef<unsigned>);
- virtual void setBranchWeightMetadata(Module&, ProfileData&);
-
- virtual bool runOnModule(Module &M);
- };
-} // End of anonymous namespace
-
-char ProfileMetadataLoaderPass::ID = 0;
-INITIALIZE_PASS_BEGIN(ProfileMetadataLoaderPass, "profile-metadata-loader",
- "Load profile information from llvmprof.out", false, true)
-INITIALIZE_PASS_END(ProfileMetadataLoaderPass, "profile-metadata-loader",
- "Load profile information from llvmprof.out", false, true)
-
-char &llvm::ProfileMetadataLoaderPassID = ProfileMetadataLoaderPass::ID;
-
-/// createProfileMetadataLoaderPass - This function returns a Pass that loads
-/// the profiling information for the module from the specified filename,
-/// making it available to the optimizers.
-ModulePass *llvm::createProfileMetadataLoaderPass() {
- return new ProfileMetadataLoaderPass();
-}
-ModulePass *llvm::createProfileMetadataLoaderPass(const std::string &Filename) {
- return new ProfileMetadataLoaderPass(Filename);
-}
-
-/// readEdge - Take the value from a profile counter and assign it to an edge.
-void ProfileMetadataLoaderPass::readEdge(unsigned ReadCount,
- ProfileData &PB, ProfileData::Edge e,
- ArrayRef<unsigned> Counters) {
- if (ReadCount >= Counters.size()) return;
-
- unsigned weight = Counters[ReadCount];
- assert(weight != ProfileDataLoader::Uncounted);
- PB.addEdgeWeight(e, weight);
-
- DEBUG(dbgs() << "-- Read Edge Counter for " << e
- << " (# "<< (ReadCount) << "): "
- << PB.getEdgeWeight(e) << "\n");
-}
-
-/// matchEdges - Link every profile counter with an edge.
-unsigned ProfileMetadataLoaderPass::matchEdges(Module &M, ProfileData &PB,
- ArrayRef<unsigned> Counters) {
- if (Counters.size() == 0) return 0;
-
- unsigned ReadCount = 0;
-
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- if (F->isDeclaration()) continue;
- DEBUG(dbgs() << "Loading edges in '" << F->getName() << "'\n");
- readEdge(ReadCount++, PB, PB.getEdge(0, &F->getEntryBlock()), Counters);
- for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
- TerminatorInst *TI = BB->getTerminator();
- for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
- readEdge(ReadCount++, PB, PB.getEdge(BB,TI->getSuccessor(s)),
- Counters);
- }
- }
- }
-
- return ReadCount;
-}
-
-/// setBranchWeightMetadata - Translate the counter values associated with each
-/// edge into branch weights for each conditional branch (a branch with 2 or
-/// more desinations).
-void ProfileMetadataLoaderPass::setBranchWeightMetadata(Module &M,
- ProfileData &PB) {
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- if (F->isDeclaration()) continue;
- DEBUG(dbgs() << "Setting branch metadata in '" << F->getName() << "'\n");
-
- for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
- TerminatorInst *TI = BB->getTerminator();
- unsigned NumSuccessors = TI->getNumSuccessors();
-
- // If there is only one successor then we can not set a branch
- // probability as the target is certain.
- if (NumSuccessors < 2) continue;
-
- // Load the weights of all edges leading from this terminator.
- DEBUG(dbgs() << "-- Terminator with " << NumSuccessors
- << " successors:\n");
- SmallVector<uint32_t, 4> Weights(NumSuccessors);
- for (unsigned s = 0 ; s < NumSuccessors ; ++s) {
- ProfileData::Edge edge = PB.getEdge(BB, TI->getSuccessor(s));
- Weights[s] = (uint32_t)PB.getEdgeWeight(edge);
- DEBUG(dbgs() << "---- Edge '" << edge << "' has weight "
- << Weights[s] << "\n");
- }
-
- // Set branch weight metadata. This will set branch probabilities of
- // 100%/0% if that is true of the dynamic execution.
- // BranchProbabilityInfo can account for this when it loads this metadata
- // (it gives the unexectuted branch a weight of 1 for the purposes of
- // probability calculations).
- MDBuilder MDB(TI->getContext());
- MDNode *Node = MDB.createBranchWeights(Weights);
- TI->setMetadata(LLVMContext::MD_prof, Node);
- NumTermsAnnotated++;
- }
- }
-}
-
-bool ProfileMetadataLoaderPass::runOnModule(Module &M) {
- ProfileDataLoader PDL("profile-data-loader", Filename);
- ProfileData PB;
-
- ArrayRef<unsigned> Counters = PDL.getRawEdgeCounts();
-
- unsigned ReadCount = matchEdges(M, PB, Counters);
-
- if (ReadCount != Counters.size()) {
- errs() << "WARNING: profile information is inconsistent with "
- << "the current program!\n";
- }
- NumEdgesRead = ReadCount;
-
- setBranchWeightMetadata(M, PB);
-
- return ReadCount > 0;
-}
diff --git a/lib/Analysis/ProfileEstimatorPass.cpp b/lib/Analysis/ProfileEstimatorPass.cpp
deleted file mode 100644
index 365b64c..0000000
--- a/lib/Analysis/ProfileEstimatorPass.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-//===- ProfileEstimatorPass.cpp - LLVM Pass to estimate profile info ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a concrete implementation of profiling information that
-// estimates the profiling information in a very crude and unimaginative way.
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "profile-estimator"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/ProfileInfo.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-static cl::opt<double>
-LoopWeight(
- "profile-estimator-loop-weight", cl::init(10),
- cl::value_desc("loop-weight"),
- cl::desc("Number of loop executions used for profile-estimator")
-);
-
-namespace {
- class ProfileEstimatorPass : public FunctionPass, public ProfileInfo {
- double ExecCount;
- LoopInfo *LI;
- std::set<BasicBlock*> BBToVisit;
- std::map<Loop*,double> LoopExitWeights;
- std::map<Edge,double> MinimalWeight;
- public:
- static char ID; // Class identification, replacement for typeinfo
- explicit ProfileEstimatorPass(const double execcount = 0)
- : FunctionPass(ID), ExecCount(execcount) {
- initializeProfileEstimatorPassPass(*PassRegistry::getPassRegistry());
- if (execcount == 0) ExecCount = LoopWeight;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<LoopInfo>();
- }
-
- virtual const char *getPassName() const {
- return "Profiling information estimator";
- }
-
- /// run - Estimate the profile information from the specified file.
- virtual bool runOnFunction(Function &F);
-
- /// getAdjustedAnalysisPointer - This method is used when a pass implements
- /// an analysis interface through multiple inheritance. If needed, it
- /// should override this to adjust the this pointer as needed for the
- /// specified pass info.
- virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
- if (PI == &ProfileInfo::ID)
- return (ProfileInfo*)this;
- return this;
- }
-
- virtual void recurseBasicBlock(BasicBlock *BB);
-
- void inline printEdgeWeight(Edge);
- };
-} // End of anonymous namespace
-
-char ProfileEstimatorPass::ID = 0;
-INITIALIZE_AG_PASS_BEGIN(ProfileEstimatorPass, ProfileInfo, "profile-estimator",
- "Estimate profiling information", false, true, false)
-INITIALIZE_PASS_DEPENDENCY(LoopInfo)
-INITIALIZE_AG_PASS_END(ProfileEstimatorPass, ProfileInfo, "profile-estimator",
- "Estimate profiling information", false, true, false)
-
-namespace llvm {
- char &ProfileEstimatorPassID = ProfileEstimatorPass::ID;
-
- FunctionPass *createProfileEstimatorPass() {
- return new ProfileEstimatorPass();
- }
-
- /// createProfileEstimatorPass - This function returns a Pass that estimates
- /// profiling information using the given loop execution count.
- Pass *createProfileEstimatorPass(const unsigned execcount) {
- return new ProfileEstimatorPass(execcount);
- }
-}
-
-static double ignoreMissing(double w) {
- if (w == ProfileInfo::MissingValue) return 0;
- return w;
-}
-
-static void inline printEdgeError(ProfileInfo::Edge e, const char *M) {
- DEBUG(dbgs() << "-- Edge " << e << " is not calculated, " << M << "\n");
-}
-
-void inline ProfileEstimatorPass::printEdgeWeight(Edge E) {
- DEBUG(dbgs() << "-- Weight of Edge " << E << ":"
- << format("%20.20g", getEdgeWeight(E)) << "\n");
-}
-
-// recurseBasicBlock() - This calculates the ProfileInfo estimation for a
-// single block and then recurses into the successors.
-// The algorithm preserves the flow condition, meaning that the sum of the
-// weight of the incoming edges must be equal the block weight which must in
-// turn be equal to the sume of the weights of the outgoing edges.
-// Since the flow of an block is deterimined from the current state of the
-// flow, once an edge has a flow assigned this flow is never changed again,
-// otherwise it would be possible to violate the flow condition in another
-// block.
-void ProfileEstimatorPass::recurseBasicBlock(BasicBlock *BB) {
-
- // Break the recursion if this BasicBlock was already visited.
- if (BBToVisit.find(BB) == BBToVisit.end()) return;
-
- // Read the LoopInfo for this block.
- bool BBisHeader = LI->isLoopHeader(BB);
- Loop* BBLoop = LI->getLoopFor(BB);
-
- // To get the block weight, read all incoming edges.
- double BBWeight = 0;
- std::set<BasicBlock*> ProcessedPreds;
- for ( pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
- bbi != bbe; ++bbi ) {
- // If this block was not considered already, add weight.
- Edge edge = getEdge(*bbi,BB);
- double w = getEdgeWeight(edge);
- if (ProcessedPreds.insert(*bbi).second) {
- BBWeight += ignoreMissing(w);
- }
- // If this block is a loop header and the predecessor is contained in this
- // loop, thus the edge is a backedge, continue and do not check if the
- // value is valid.
- if (BBisHeader && BBLoop->contains(*bbi)) {
- printEdgeError(edge, "but is backedge, continuing");
- continue;
- }
- // If the edges value is missing (and this is no loop header, and this is
- // no backedge) return, this block is currently non estimatable.
- if (w == MissingValue) {
- printEdgeError(edge, "returning");
- return;
- }
- }
- if (getExecutionCount(BB) != MissingValue) {
- BBWeight = getExecutionCount(BB);
- }
-
- // Fetch all necessary information for current block.
- SmallVector<Edge, 8> ExitEdges;
- SmallVector<Edge, 8> Edges;
- if (BBLoop) {
- BBLoop->getExitEdges(ExitEdges);
- }
-
- // If this is a loop header, consider the following:
- // Exactly the flow that is entering this block, must exit this block too. So
- // do the following:
- // *) get all the exit edges, read the flow that is already leaving this
- // loop, remember the edges that do not have any flow on them right now.
- // (The edges that have already flow on them are most likely exiting edges of
- // other loops, do not touch those flows because the previously caclulated
- // loopheaders would not be exact anymore.)
- // *) In case there is not a single exiting edge left, create one at the loop
- // latch to prevent the flow from building up in the loop.
- // *) Take the flow that is not leaving the loop already and distribute it on
- // the remaining exiting edges.
- // (This ensures that all flow that enters the loop also leaves it.)
- // *) Increase the flow into the loop by increasing the weight of this block.
- // There is at least one incoming backedge that will bring us this flow later
- // on. (So that the flow condition in this node is valid again.)
- if (BBisHeader) {
- double incoming = BBWeight;
- // Subtract the flow leaving the loop.
- std::set<Edge> ProcessedExits;
- for (SmallVectorImpl<Edge>::iterator ei = ExitEdges.begin(),
- ee = ExitEdges.end(); ei != ee; ++ei) {
- if (ProcessedExits.insert(*ei).second) {
- double w = getEdgeWeight(*ei);
- if (w == MissingValue) {
- Edges.push_back(*ei);
- // Check if there is a necessary minimal weight, if yes, subtract it
- // from weight.
- if (MinimalWeight.find(*ei) != MinimalWeight.end()) {
- incoming -= MinimalWeight[*ei];
- DEBUG(dbgs() << "Reserving " << format("%.20g",MinimalWeight[*ei]) << " at " << (*ei) << "\n");
- }
- } else {
- incoming -= w;
- }
- }
- }
- // If no exit edges, create one:
- if (Edges.size() == 0) {
- BasicBlock *Latch = BBLoop->getLoopLatch();
- if (Latch) {
- Edge edge = getEdge(Latch,0);
- EdgeInformation[BB->getParent()][edge] = BBWeight;
- printEdgeWeight(edge);
- edge = getEdge(Latch, BB);
- EdgeInformation[BB->getParent()][edge] = BBWeight * ExecCount;
- printEdgeWeight(edge);
- }
- }
-
- // Distribute remaining weight to the exting edges. To prevent fractions
- // from building up and provoking precision problems the weight which is to
- // be distributed is split and the rounded, the last edge gets a somewhat
- // bigger value, but we are close enough for an estimation.
- double fraction = floor(incoming/Edges.size());
- for (SmallVectorImpl<Edge>::iterator ei = Edges.begin(), ee = Edges.end();
- ei != ee; ++ei) {
- double w = 0;
- if (ei != (ee-1)) {
- w = fraction;
- incoming -= fraction;
- } else {
- w = incoming;
- }
- EdgeInformation[BB->getParent()][*ei] += w;
- // Read necessary minimal weight.
- if (MinimalWeight.find(*ei) != MinimalWeight.end()) {
- EdgeInformation[BB->getParent()][*ei] += MinimalWeight[*ei];
- DEBUG(dbgs() << "Additionally " << format("%.20g",MinimalWeight[*ei]) << " at " << (*ei) << "\n");
- }
- printEdgeWeight(*ei);
-
- // Add minimal weight to paths to all exit edges, this is used to ensure
- // that enough flow is reaching this edges.
- Path p;
- const BasicBlock *Dest = GetPath(BB, (*ei).first, p, GetPathToDest);
- while (Dest != BB) {
- const BasicBlock *Parent = p.find(Dest)->second;
- Edge e = getEdge(Parent, Dest);
- if (MinimalWeight.find(e) == MinimalWeight.end()) {
- MinimalWeight[e] = 0;
- }
- MinimalWeight[e] += w;
- DEBUG(dbgs() << "Minimal Weight for " << e << ": " << format("%.20g",MinimalWeight[e]) << "\n");
- Dest = Parent;
- }
- }
- // Increase flow into the loop.
- BBWeight *= (ExecCount+1);
- }
-
- BlockInformation[BB->getParent()][BB] = BBWeight;
- // Up until now we considered only the loop exiting edges, now we have a
- // definite block weight and must distribute this onto the outgoing edges.
- // Since there may be already flow attached to some of the edges, read this
- // flow first and remember the edges that have still now flow attached.
- Edges.clear();
- std::set<BasicBlock*> ProcessedSuccs;
-
- succ_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
- // Also check for (BB,0) edges that may already contain some flow. (But only
- // in case there are no successors.)
- if (bbi == bbe) {
- Edge edge = getEdge(BB,0);
- EdgeInformation[BB->getParent()][edge] = BBWeight;
- printEdgeWeight(edge);
- }
- for ( ; bbi != bbe; ++bbi ) {
- if (ProcessedSuccs.insert(*bbi).second) {
- Edge edge = getEdge(BB,*bbi);
- double w = getEdgeWeight(edge);
- if (w != MissingValue) {
- BBWeight -= getEdgeWeight(edge);
- } else {
- Edges.push_back(edge);
- // If minimal weight is necessary, reserve weight by subtracting weight
- // from block weight, this is readded later on.
- if (MinimalWeight.find(edge) != MinimalWeight.end()) {
- BBWeight -= MinimalWeight[edge];
- DEBUG(dbgs() << "Reserving " << format("%.20g",MinimalWeight[edge]) << " at " << edge << "\n");
- }
- }
- }
- }
-
- double fraction = Edges.size() ? floor(BBWeight/Edges.size()) : 0.0;
- // Finally we know what flow is still not leaving the block, distribute this
- // flow onto the empty edges.
- for (SmallVectorImpl<Edge>::iterator ei = Edges.begin(), ee = Edges.end();
- ei != ee; ++ei) {
- if (ei != (ee-1)) {
- EdgeInformation[BB->getParent()][*ei] += fraction;
- BBWeight -= fraction;
- } else {
- EdgeInformation[BB->getParent()][*ei] += BBWeight;
- }
- // Readd minial necessary weight.
- if (MinimalWeight.find(*ei) != MinimalWeight.end()) {
- EdgeInformation[BB->getParent()][*ei] += MinimalWeight[*ei];
- DEBUG(dbgs() << "Additionally " << format("%.20g",MinimalWeight[*ei]) << " at " << (*ei) << "\n");
- }
- printEdgeWeight(*ei);
- }
-
- // This block is visited, mark this before the recursion.
- BBToVisit.erase(BB);
-
- // Recurse into successors.
- for (succ_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
- bbi != bbe; ++bbi) {
- recurseBasicBlock(*bbi);
- }
-}
-
-bool ProfileEstimatorPass::runOnFunction(Function &F) {
- if (F.isDeclaration()) return false;
-
- // Fetch LoopInfo and clear ProfileInfo for this function.
- LI = &getAnalysis<LoopInfo>();
- FunctionInformation.erase(&F);
- BlockInformation[&F].clear();
- EdgeInformation[&F].clear();
- BBToVisit.clear();
-
- // Mark all blocks as to visit.
- for (Function::iterator bi = F.begin(), be = F.end(); bi != be; ++bi)
- BBToVisit.insert(bi);
-
- // Clear Minimal Edges.
- MinimalWeight.clear();
-
- DEBUG(dbgs() << "Working on function " << F.getName() << "\n");
-
- // Since the entry block is the first one and has no predecessors, the edge
- // (0,entry) is inserted with the starting weight of 1.
- BasicBlock *entry = &F.getEntryBlock();
- BlockInformation[&F][entry] = pow(2.0, 32.0);
- Edge edge = getEdge(0,entry);
- EdgeInformation[&F][edge] = BlockInformation[&F][entry];
- printEdgeWeight(edge);
-
- // Since recurseBasicBlock() maybe returns with a block which was not fully
- // estimated, use recurseBasicBlock() until everything is calculated.
- bool cleanup = false;
- recurseBasicBlock(entry);
- while (BBToVisit.size() > 0 && !cleanup) {
- // Remember number of open blocks, this is later used to check if progress
- // was made.
- unsigned size = BBToVisit.size();
-
- // Try to calculate all blocks in turn.
- for (std::set<BasicBlock*>::iterator bi = BBToVisit.begin(),
- be = BBToVisit.end(); bi != be; ++bi) {
- recurseBasicBlock(*bi);
- // If at least one block was finished, break because iterator may be
- // invalid.
- if (BBToVisit.size() < size) break;
- }
-
- // If there was not a single block resolved, make some assumptions.
- if (BBToVisit.size() == size) {
- bool found = false;
- for (std::set<BasicBlock*>::iterator BBI = BBToVisit.begin(), BBE = BBToVisit.end();
- (BBI != BBE) && (!found); ++BBI) {
- BasicBlock *BB = *BBI;
- // Try each predecessor if it can be assumend.
- for (pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
- (bbi != bbe) && (!found); ++bbi) {
- Edge e = getEdge(*bbi,BB);
- double w = getEdgeWeight(e);
- // Check that edge from predecessor is still free.
- if (w == MissingValue) {
- // Check if there is a circle from this block to predecessor.
- Path P;
- const BasicBlock *Dest = GetPath(BB, *bbi, P, GetPathToDest);
- if (Dest != *bbi) {
- // If there is no circle, just set edge weight to 0
- EdgeInformation[&F][e] = 0;
- DEBUG(dbgs() << "Assuming edge weight: ");
- printEdgeWeight(e);
- found = true;
- }
- }
- }
- }
- if (!found) {
- cleanup = true;
- DEBUG(dbgs() << "No assumption possible in Fuction "<<F.getName()<<", setting all to zero\n");
- }
- }
- }
- // In case there was no safe way to assume edges, set as a last measure,
- // set _everything_ to zero.
- if (cleanup) {
- FunctionInformation[&F] = 0;
- BlockInformation[&F].clear();
- EdgeInformation[&F].clear();
- for (Function::const_iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
- const BasicBlock *BB = &(*FI);
- BlockInformation[&F][BB] = 0;
- const_pred_iterator predi = pred_begin(BB), prede = pred_end(BB);
- if (predi == prede) {
- Edge e = getEdge(0,BB);
- setEdgeWeight(e,0);
- }
- for (;predi != prede; ++predi) {
- Edge e = getEdge(*predi,BB);
- setEdgeWeight(e,0);
- }
- succ_const_iterator succi = succ_begin(BB), succe = succ_end(BB);
- if (succi == succe) {
- Edge e = getEdge(BB,0);
- setEdgeWeight(e,0);
- }
- for (;succi != succe; ++succi) {
- Edge e = getEdge(*succi,BB);
- setEdgeWeight(e,0);
- }
- }
- }
-
- return false;
-}
diff --git a/lib/Analysis/ProfileInfo.cpp b/lib/Analysis/ProfileInfo.cpp
deleted file mode 100644
index 9626a48..0000000
--- a/lib/Analysis/ProfileInfo.cpp
+++ /dev/null
@@ -1,1079 +0,0 @@
-//===- ProfileInfo.cpp - Profile Info Interface ---------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the abstract ProfileInfo interface, and the default
-// "no profile" implementation.
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "profile-info"
-#include "llvm/Analysis/ProfileInfo.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CFG.h"
-#include <limits>
-#include <queue>
-#include <set>
-using namespace llvm;
-
-namespace llvm {
- template<> char ProfileInfoT<Function,BasicBlock>::ID = 0;
-}
-
-// Register the ProfileInfo interface, providing a nice name to refer to.
-INITIALIZE_ANALYSIS_GROUP(ProfileInfo, "Profile Information", NoProfileInfo)
-
-namespace llvm {
-
-template <>
-ProfileInfoT<MachineFunction, MachineBasicBlock>::ProfileInfoT() {}
-template <>
-ProfileInfoT<MachineFunction, MachineBasicBlock>::~ProfileInfoT() {}
-
-template <>
-ProfileInfoT<Function, BasicBlock>::ProfileInfoT() {
- MachineProfile = 0;
-}
-template <>
-ProfileInfoT<Function, BasicBlock>::~ProfileInfoT() {
- if (MachineProfile) delete MachineProfile;
-}
-
-template<>
-char ProfileInfoT<MachineFunction, MachineBasicBlock>::ID = 0;
-
-template<>
-const double ProfileInfoT<Function,BasicBlock>::MissingValue = -1;
-
-template<> const
-double ProfileInfoT<MachineFunction, MachineBasicBlock>::MissingValue = -1;
-
-template<> double
-ProfileInfoT<Function,BasicBlock>::getExecutionCount(const BasicBlock *BB) {
- std::map<const Function*, BlockCounts>::iterator J =
- BlockInformation.find(BB->getParent());
- if (J != BlockInformation.end()) {
- BlockCounts::iterator I = J->second.find(BB);
- if (I != J->second.end())
- return I->second;
- }
-
- double Count = MissingValue;
-
- const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
-
- // Are there zero predecessors of this block?
- if (PI == PE) {
- Edge e = getEdge(0, BB);
- Count = getEdgeWeight(e);
- } else {
- // Otherwise, if there are predecessors, the execution count of this block is
- // the sum of the edge frequencies from the incoming edges.
- std::set<const BasicBlock*> ProcessedPreds;
- Count = 0;
- for (; PI != PE; ++PI) {
- const BasicBlock *P = *PI;
- if (ProcessedPreds.insert(P).second) {
- double w = getEdgeWeight(getEdge(P, BB));
- if (w == MissingValue) {
- Count = MissingValue;
- break;
- }
- Count += w;
- }
- }
- }
-
- // If the predecessors did not suffice to get block weight, try successors.
- if (Count == MissingValue) {
-
- succ_const_iterator SI = succ_begin(BB), SE = succ_end(BB);
-
- // Are there zero successors of this block?
- if (SI == SE) {
- Edge e = getEdge(BB,0);
- Count = getEdgeWeight(e);
- } else {
- std::set<const BasicBlock*> ProcessedSuccs;
- Count = 0;
- for (; SI != SE; ++SI)
- if (ProcessedSuccs.insert(*SI).second) {
- double w = getEdgeWeight(getEdge(BB, *SI));
- if (w == MissingValue) {
- Count = MissingValue;
- break;
- }
- Count += w;
- }
- }
- }
-
- if (Count != MissingValue) BlockInformation[BB->getParent()][BB] = Count;
- return Count;
-}
-
-template<>
-double ProfileInfoT<MachineFunction, MachineBasicBlock>::
- getExecutionCount(const MachineBasicBlock *MBB) {
- std::map<const MachineFunction*, BlockCounts>::iterator J =
- BlockInformation.find(MBB->getParent());
- if (J != BlockInformation.end()) {
- BlockCounts::iterator I = J->second.find(MBB);
- if (I != J->second.end())
- return I->second;
- }
-
- return MissingValue;
-}
-
-template<>
-double ProfileInfoT<Function,BasicBlock>::getExecutionCount(const Function *F) {
- std::map<const Function*, double>::iterator J =
- FunctionInformation.find(F);
- if (J != FunctionInformation.end())
- return J->second;
-
- // isDeclaration() is checked here and not at start of function to allow
- // functions without a body still to have a execution count.
- if (F->isDeclaration()) return MissingValue;
-
- double Count = getExecutionCount(&F->getEntryBlock());
- if (Count != MissingValue) FunctionInformation[F] = Count;
- return Count;
-}
-
-template<>
-double ProfileInfoT<MachineFunction, MachineBasicBlock>::
- getExecutionCount(const MachineFunction *MF) {
- std::map<const MachineFunction*, double>::iterator J =
- FunctionInformation.find(MF);
- if (J != FunctionInformation.end())
- return J->second;
-
- double Count = getExecutionCount(&MF->front());
- if (Count != MissingValue) FunctionInformation[MF] = Count;
- return Count;
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::
- setExecutionCount(const BasicBlock *BB, double w) {
- DEBUG(dbgs() << "Creating Block " << BB->getName()
- << " (weight: " << format("%.20g",w) << ")\n");
- BlockInformation[BB->getParent()][BB] = w;
-}
-
-template<>
-void ProfileInfoT<MachineFunction, MachineBasicBlock>::
- setExecutionCount(const MachineBasicBlock *MBB, double w) {
- DEBUG(dbgs() << "Creating Block " << MBB->getBasicBlock()->getName()
- << " (weight: " << format("%.20g",w) << ")\n");
- BlockInformation[MBB->getParent()][MBB] = w;
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::addEdgeWeight(Edge e, double w) {
- double oldw = getEdgeWeight(e);
- assert (oldw != MissingValue && "Adding weight to Edge with no previous weight");
- DEBUG(dbgs() << "Adding to Edge " << e
- << " (new weight: " << format("%.20g",oldw + w) << ")\n");
- EdgeInformation[getFunction(e)][e] = oldw + w;
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::
- addExecutionCount(const BasicBlock *BB, double w) {
- double oldw = getExecutionCount(BB);
- assert (oldw != MissingValue && "Adding weight to Block with no previous weight");
- DEBUG(dbgs() << "Adding to Block " << BB->getName()
- << " (new weight: " << format("%.20g",oldw + w) << ")\n");
- BlockInformation[BB->getParent()][BB] = oldw + w;
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::removeBlock(const BasicBlock *BB) {
- std::map<const Function*, BlockCounts>::iterator J =
- BlockInformation.find(BB->getParent());
- if (J == BlockInformation.end()) return;
-
- DEBUG(dbgs() << "Deleting " << BB->getName() << "\n");
- J->second.erase(BB);
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::removeEdge(Edge e) {
- std::map<const Function*, EdgeWeights>::iterator J =
- EdgeInformation.find(getFunction(e));
- if (J == EdgeInformation.end()) return;
-
- DEBUG(dbgs() << "Deleting" << e << "\n");
- J->second.erase(e);
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::
- replaceEdge(const Edge &oldedge, const Edge &newedge) {
- double w;
- if ((w = getEdgeWeight(newedge)) == MissingValue) {
- w = getEdgeWeight(oldedge);
- DEBUG(dbgs() << "Replacing " << oldedge << " with " << newedge << "\n");
- } else {
- w += getEdgeWeight(oldedge);
- DEBUG(dbgs() << "Adding " << oldedge << " to " << newedge << "\n");
- }
- setEdgeWeight(newedge,w);
- removeEdge(oldedge);
-}
-
-template<>
-const BasicBlock *ProfileInfoT<Function,BasicBlock>::
- GetPath(const BasicBlock *Src, const BasicBlock *Dest,
- Path &P, unsigned Mode) {
- const BasicBlock *BB = 0;
- bool hasFoundPath = false;
-
- std::queue<const BasicBlock *> BFS;
- BFS.push(Src);
-
- while(BFS.size() && !hasFoundPath) {
- BB = BFS.front();
- BFS.pop();
-
- succ_const_iterator Succ = succ_begin(BB), End = succ_end(BB);
- if (Succ == End) {
- P[(const BasicBlock*)0] = BB;
- if (Mode & GetPathToExit) {
- hasFoundPath = true;
- BB = 0;
- }
- }
- for(;Succ != End; ++Succ) {
- if (P.find(*Succ) != P.end()) continue;
- Edge e = getEdge(BB,*Succ);
- if ((Mode & GetPathWithNewEdges) && (getEdgeWeight(e) != MissingValue)) continue;
- P[*Succ] = BB;
- BFS.push(*Succ);
- if ((Mode & GetPathToDest) && *Succ == Dest) {
- hasFoundPath = true;
- BB = *Succ;
- break;
- }
- if ((Mode & GetPathToValue) && (getExecutionCount(*Succ) != MissingValue)) {
- hasFoundPath = true;
- BB = *Succ;
- break;
- }
- }
- }
-
- return BB;
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::
- divertFlow(const Edge &oldedge, const Edge &newedge) {
- DEBUG(dbgs() << "Diverting " << oldedge << " via " << newedge );
-
- // First check if the old edge was taken, if not, just delete it...
- if (getEdgeWeight(oldedge) == 0) {
- removeEdge(oldedge);
- return;
- }
-
- Path P;
- P[newedge.first] = 0;
- P[newedge.second] = newedge.first;
- const BasicBlock *BB = GetPath(newedge.second,oldedge.second,P,GetPathToExit | GetPathToDest);
-
- double w = getEdgeWeight (oldedge);
- DEBUG(dbgs() << ", Weight: " << format("%.20g",w) << "\n");
- do {
- const BasicBlock *Parent = P.find(BB)->second;
- Edge e = getEdge(Parent,BB);
- double oldw = getEdgeWeight(e);
- double oldc = getExecutionCount(e.first);
- setEdgeWeight(e, w+oldw);
- if (Parent != oldedge.first) {
- setExecutionCount(e.first, w+oldc);
- }
- BB = Parent;
- } while (BB != newedge.first);
- removeEdge(oldedge);
-}
-
-/// Replaces all occurrences of RmBB in the ProfilingInfo with DestBB.
-/// This checks all edges of the function the blocks reside in and replaces the
-/// occurrences of RmBB with DestBB.
-template<>
-void ProfileInfoT<Function,BasicBlock>::
- replaceAllUses(const BasicBlock *RmBB, const BasicBlock *DestBB) {
- DEBUG(dbgs() << "Replacing " << RmBB->getName()
- << " with " << DestBB->getName() << "\n");
- const Function *F = DestBB->getParent();
- std::map<const Function*, EdgeWeights>::iterator J =
- EdgeInformation.find(F);
- if (J == EdgeInformation.end()) return;
-
- Edge e, newedge;
- bool erasededge = false;
- EdgeWeights::iterator I = J->second.begin(), E = J->second.end();
- while(I != E) {
- e = (I++)->first;
- bool foundedge = false; bool eraseedge = false;
- if (e.first == RmBB) {
- if (e.second == DestBB) {
- eraseedge = true;
- } else {
- newedge = getEdge(DestBB, e.second);
- foundedge = true;
- }
- }
- if (e.second == RmBB) {
- if (e.first == DestBB) {
- eraseedge = true;
- } else {
- newedge = getEdge(e.first, DestBB);
- foundedge = true;
- }
- }
- if (foundedge) {
- replaceEdge(e, newedge);
- }
- if (eraseedge) {
- if (erasededge) {
- Edge newedge = getEdge(DestBB, DestBB);
- replaceEdge(e, newedge);
- } else {
- removeEdge(e);
- erasededge = true;
- }
- }
- }
-}
-
-/// Splits an edge in the ProfileInfo and redirects flow over NewBB.
-/// Since its possible that there is more than one edge in the CFG from FristBB
-/// to SecondBB its necessary to redirect the flow proporionally.
-template<>
-void ProfileInfoT<Function,BasicBlock>::splitEdge(const BasicBlock *FirstBB,
- const BasicBlock *SecondBB,
- const BasicBlock *NewBB,
- bool MergeIdenticalEdges) {
- const Function *F = FirstBB->getParent();
- std::map<const Function*, EdgeWeights>::iterator J =
- EdgeInformation.find(F);
- if (J == EdgeInformation.end()) return;
-
- // Generate edges and read current weight.
- Edge e = getEdge(FirstBB, SecondBB);
- Edge n1 = getEdge(FirstBB, NewBB);
- Edge n2 = getEdge(NewBB, SecondBB);
- EdgeWeights &ECs = J->second;
- double w = ECs[e];
-
- int succ_count = 0;
- if (!MergeIdenticalEdges) {
- // First count the edges from FristBB to SecondBB, if there is more than
- // one, only slice out a proporional part for NewBB.
- for(succ_const_iterator BBI = succ_begin(FirstBB), BBE = succ_end(FirstBB);
- BBI != BBE; ++BBI) {
- if (*BBI == SecondBB) succ_count++;
- }
- // When the NewBB is completely new, increment the count by one so that
- // the counts are properly distributed.
- if (getExecutionCount(NewBB) == ProfileInfo::MissingValue) succ_count++;
- } else {
- // When the edges are merged anyway, then redirect all flow.
- succ_count = 1;
- }
-
- // We know now how many edges there are from FirstBB to SecondBB, reroute a
- // proportional part of the edge weight over NewBB.
- double neww = floor(w / succ_count);
- ECs[n1] += neww;
- ECs[n2] += neww;
- BlockInformation[F][NewBB] += neww;
- if (succ_count == 1) {
- ECs.erase(e);
- } else {
- ECs[e] -= neww;
- }
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::splitBlock(const BasicBlock *Old,
- const BasicBlock* New) {
- const Function *F = Old->getParent();
- std::map<const Function*, EdgeWeights>::iterator J =
- EdgeInformation.find(F);
- if (J == EdgeInformation.end()) return;
-
- DEBUG(dbgs() << "Splitting " << Old->getName() << " to " << New->getName() << "\n");
-
- std::set<Edge> Edges;
- for (EdgeWeights::iterator ewi = J->second.begin(), ewe = J->second.end();
- ewi != ewe; ++ewi) {
- Edge old = ewi->first;
- if (old.first == Old) {
- Edges.insert(old);
- }
- }
- for (std::set<Edge>::iterator EI = Edges.begin(), EE = Edges.end();
- EI != EE; ++EI) {
- Edge newedge = getEdge(New, EI->second);
- replaceEdge(*EI, newedge);
- }
-
- double w = getExecutionCount(Old);
- setEdgeWeight(getEdge(Old, New), w);
- setExecutionCount(New, w);
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::splitBlock(const BasicBlock *BB,
- const BasicBlock* NewBB,
- BasicBlock *const *Preds,
- unsigned NumPreds) {
- const Function *F = BB->getParent();
- std::map<const Function*, EdgeWeights>::iterator J =
- EdgeInformation.find(F);
- if (J == EdgeInformation.end()) return;
-
- DEBUG(dbgs() << "Splitting " << NumPreds << " Edges from " << BB->getName()
- << " to " << NewBB->getName() << "\n");
-
- // Collect weight that was redirected over NewBB.
- double newweight = 0;
-
- std::set<const BasicBlock *> ProcessedPreds;
- // For all requestes Predecessors.
- for (unsigned pred = 0; pred < NumPreds; ++pred) {
- const BasicBlock * Pred = Preds[pred];
- if (ProcessedPreds.insert(Pred).second) {
- // Create edges and read old weight.
- Edge oldedge = getEdge(Pred, BB);
- Edge newedge = getEdge(Pred, NewBB);
-
- // Remember how much weight was redirected.
- newweight += getEdgeWeight(oldedge);
-
- replaceEdge(oldedge,newedge);
- }
- }
-
- Edge newedge = getEdge(NewBB,BB);
- setEdgeWeight(newedge, newweight);
- setExecutionCount(NewBB, newweight);
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::transfer(const Function *Old,
- const Function *New) {
- DEBUG(dbgs() << "Replacing Function " << Old->getName() << " with "
- << New->getName() << "\n");
- std::map<const Function*, EdgeWeights>::iterator J =
- EdgeInformation.find(Old);
- if(J != EdgeInformation.end()) {
- EdgeInformation[New] = J->second;
- }
- EdgeInformation.erase(Old);
- BlockInformation.erase(Old);
- FunctionInformation.erase(Old);
-}
-
-static double readEdgeOrRemember(ProfileInfo::Edge edge, double w,
- ProfileInfo::Edge &tocalc, unsigned &uncalc) {
- if (w == ProfileInfo::MissingValue) {
- tocalc = edge;
- uncalc++;
- return 0;
- } else {
- return w;
- }
-}
-
-template<>
-bool ProfileInfoT<Function,BasicBlock>::
- CalculateMissingEdge(const BasicBlock *BB, Edge &removed,
- bool assumeEmptySelf) {
- Edge edgetocalc;
- unsigned uncalculated = 0;
-
- // collect weights of all incoming and outgoing edges, rememer edges that
- // have no value
- double incount = 0;
- SmallSet<const BasicBlock*,8> pred_visited;
- const_pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
- if (bbi==bbe) {
- Edge e = getEdge(0,BB);
- incount += readEdgeOrRemember(e, getEdgeWeight(e) ,edgetocalc,uncalculated);
- }
- for (;bbi != bbe; ++bbi) {
- if (pred_visited.insert(*bbi)) {
- Edge e = getEdge(*bbi,BB);
- incount += readEdgeOrRemember(e, getEdgeWeight(e) ,edgetocalc,uncalculated);
- }
- }
-
- double outcount = 0;
- SmallSet<const BasicBlock*,8> succ_visited;
- succ_const_iterator sbbi = succ_begin(BB), sbbe = succ_end(BB);
- if (sbbi==sbbe) {
- Edge e = getEdge(BB,0);
- if (getEdgeWeight(e) == MissingValue) {
- double w = getExecutionCount(BB);
- if (w != MissingValue) {
- setEdgeWeight(e,w);
- removed = e;
- }
- }
- outcount += readEdgeOrRemember(e, getEdgeWeight(e), edgetocalc, uncalculated);
- }
- for (;sbbi != sbbe; ++sbbi) {
- if (succ_visited.insert(*sbbi)) {
- Edge e = getEdge(BB,*sbbi);
- outcount += readEdgeOrRemember(e, getEdgeWeight(e), edgetocalc, uncalculated);
- }
- }
-
- // if exactly one edge weight was missing, calculate it and remove it from
- // spanning tree
- if (uncalculated == 0 ) {
- return true;
- } else
- if (uncalculated == 1) {
- if (incount < outcount) {
- EdgeInformation[BB->getParent()][edgetocalc] = outcount-incount;
- } else {
- EdgeInformation[BB->getParent()][edgetocalc] = incount-outcount;
- }
- DEBUG(dbgs() << "--Calc Edge Counter for " << edgetocalc << ": "
- << format("%.20g", getEdgeWeight(edgetocalc)) << "\n");
- removed = edgetocalc;
- return true;
- } else
- if (uncalculated == 2 && assumeEmptySelf && edgetocalc.first == edgetocalc.second && incount == outcount) {
- setEdgeWeight(edgetocalc, incount * 10);
- removed = edgetocalc;
- return true;
- } else {
- return false;
- }
-}
-
-static void readEdge(ProfileInfo *PI, ProfileInfo::Edge e, double &calcw, std::set<ProfileInfo::Edge> &misscount) {
- double w = PI->getEdgeWeight(e);
- if (w != ProfileInfo::MissingValue) {
- calcw += w;
- } else {
- misscount.insert(e);
- }
-}
-
-template<>
-bool ProfileInfoT<Function,BasicBlock>::EstimateMissingEdges(const BasicBlock *BB) {
- double inWeight = 0;
- std::set<Edge> inMissing;
- std::set<const BasicBlock*> ProcessedPreds;
- const_pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
- if (bbi == bbe) {
- readEdge(this,getEdge(0,BB),inWeight,inMissing);
- }
- for( ; bbi != bbe; ++bbi ) {
- if (ProcessedPreds.insert(*bbi).second) {
- readEdge(this,getEdge(*bbi,BB),inWeight,inMissing);
- }
- }
-
- double outWeight = 0;
- std::set<Edge> outMissing;
- std::set<const BasicBlock*> ProcessedSuccs;
- succ_const_iterator sbbi = succ_begin(BB), sbbe = succ_end(BB);
- if (sbbi == sbbe)
- readEdge(this,getEdge(BB,0),outWeight,outMissing);
- for ( ; sbbi != sbbe; ++sbbi ) {
- if (ProcessedSuccs.insert(*sbbi).second) {
- readEdge(this,getEdge(BB,*sbbi),outWeight,outMissing);
- }
- }
-
- double share;
- std::set<Edge>::iterator ei,ee;
- if (inMissing.size() == 0 && outMissing.size() > 0) {
- ei = outMissing.begin();
- ee = outMissing.end();
- share = inWeight/outMissing.size();
- setExecutionCount(BB,inWeight);
- } else
- if (inMissing.size() > 0 && outMissing.size() == 0 && outWeight == 0) {
- ei = inMissing.begin();
- ee = inMissing.end();
- share = 0;
- setExecutionCount(BB,0);
- } else
- if (inMissing.size() == 0 && outMissing.size() == 0) {
- setExecutionCount(BB,outWeight);
- return true;
- } else {
- return false;
- }
- for ( ; ei != ee; ++ei ) {
- setEdgeWeight(*ei,share);
- }
- return true;
-}
-
-template<>
-void ProfileInfoT<Function,BasicBlock>::repair(const Function *F) {
-// if (getExecutionCount(&(F->getEntryBlock())) == 0) {
-// for (Function::const_iterator FI = F->begin(), FE = F->end();
-// FI != FE; ++FI) {
-// const BasicBlock* BB = &(*FI);
-// {
-// const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
-// if (NBB == End) {
-// setEdgeWeight(getEdge(0,BB),0);
-// }
-// for(;NBB != End; ++NBB) {
-// setEdgeWeight(getEdge(*NBB,BB),0);
-// }
-// }
-// {
-// succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
-// if (NBB == End) {
-// setEdgeWeight(getEdge(0,BB),0);
-// }
-// for(;NBB != End; ++NBB) {
-// setEdgeWeight(getEdge(*NBB,BB),0);
-// }
-// }
-// }
-// return;
-// }
- // The set of BasicBlocks that are still unvisited.
- std::set<const BasicBlock*> Unvisited;
-
- // The set of return edges (Edges with no successors).
- std::set<Edge> ReturnEdges;
- double ReturnWeight = 0;
-
- // First iterate over the whole function and collect:
- // 1) The blocks in this function in the Unvisited set.
- // 2) The return edges in the ReturnEdges set.
- // 3) The flow that is leaving the function already via return edges.
-
- // Data structure for searching the function.
- std::queue<const BasicBlock *> BFS;
- const BasicBlock *BB = &(F->getEntryBlock());
- BFS.push(BB);
- Unvisited.insert(BB);
-
- while (BFS.size()) {
- BB = BFS.front(); BFS.pop();
- succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
- if (NBB == End) {
- Edge e = getEdge(BB,0);
- double w = getEdgeWeight(e);
- if (w == MissingValue) {
- // If the return edge has no value, try to read value from block.
- double bw = getExecutionCount(BB);
- if (bw != MissingValue) {
- setEdgeWeight(e,bw);
- ReturnWeight += bw;
- } else {
- // If both return edge and block provide no value, collect edge.
- ReturnEdges.insert(e);
- }
- } else {
- // If the return edge has a proper value, collect it.
- ReturnWeight += w;
- }
- }
- for (;NBB != End; ++NBB) {
- if (Unvisited.insert(*NBB).second) {
- BFS.push(*NBB);
- }
- }
- }
-
- while (Unvisited.size() > 0) {
- unsigned oldUnvisitedCount = Unvisited.size();
- bool FoundPath = false;
-
- // If there is only one edge left, calculate it.
- if (ReturnEdges.size() == 1) {
- ReturnWeight = getExecutionCount(&(F->getEntryBlock())) - ReturnWeight;
-
- Edge e = *ReturnEdges.begin();
- setEdgeWeight(e,ReturnWeight);
- setExecutionCount(e.first,ReturnWeight);
-
- Unvisited.erase(e.first);
- ReturnEdges.erase(e);
- continue;
- }
-
- // Calculate all blocks where only one edge is missing, this may also
- // resolve furhter return edges.
- std::set<const BasicBlock *>::iterator FI = Unvisited.begin(), FE = Unvisited.end();
- while(FI != FE) {
- const BasicBlock *BB = *FI; ++FI;
- Edge e;
- if(CalculateMissingEdge(BB,e,true)) {
- if (BlockInformation[F].find(BB) == BlockInformation[F].end()) {
- setExecutionCount(BB,getExecutionCount(BB));
- }
- Unvisited.erase(BB);
- if (e.first != 0 && e.second == 0) {
- ReturnEdges.erase(e);
- ReturnWeight += getEdgeWeight(e);
- }
- }
- }
- if (oldUnvisitedCount > Unvisited.size()) continue;
-
- // Estimate edge weights by dividing the flow proportionally.
- FI = Unvisited.begin(), FE = Unvisited.end();
- while(FI != FE) {
- const BasicBlock *BB = *FI; ++FI;
- const BasicBlock *Dest = 0;
- bool AllEdgesHaveSameReturn = true;
- // Check each Successor, these must all end up in the same or an empty
- // return block otherwise its dangerous to do an estimation on them.
- for (succ_const_iterator Succ = succ_begin(BB), End = succ_end(BB);
- Succ != End; ++Succ) {
- Path P;
- GetPath(*Succ, 0, P, GetPathToExit);
- if (Dest && Dest != P[(const BasicBlock*)0]) {
- AllEdgesHaveSameReturn = false;
- }
- Dest = P[(const BasicBlock*)0];
- }
- if (AllEdgesHaveSameReturn) {
- if(EstimateMissingEdges(BB)) {
- Unvisited.erase(BB);
- break;
- }
- }
- }
- if (oldUnvisitedCount > Unvisited.size()) continue;
-
- // Check if there is a path to an block that has a known value and redirect
- // flow accordingly.
- FI = Unvisited.begin(), FE = Unvisited.end();
- while(FI != FE && !FoundPath) {
- // Fetch path.
- const BasicBlock *BB = *FI; ++FI;
- Path P;
- const BasicBlock *Dest = GetPath(BB, 0, P, GetPathToValue);
-
- // Calculate incoming flow.
- double iw = 0; unsigned inmissing = 0; unsigned incount = 0; unsigned invalid = 0;
- std::set<const BasicBlock *> Processed;
- for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
- NBB != End; ++NBB) {
- if (Processed.insert(*NBB).second) {
- Edge e = getEdge(*NBB, BB);
- double ew = getEdgeWeight(e);
- if (ew != MissingValue) {
- iw += ew;
- invalid++;
- } else {
- // If the path contains the successor, this means its a backedge,
- // do not count as missing.
- if (P.find(*NBB) == P.end())
- inmissing++;
- }
- incount++;
- }
- }
- if (inmissing == incount) continue;
- if (invalid == 0) continue;
-
- // Subtract (already) outgoing flow.
- Processed.clear();
- for (succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
- NBB != End; ++NBB) {
- if (Processed.insert(*NBB).second) {
- Edge e = getEdge(BB, *NBB);
- double ew = getEdgeWeight(e);
- if (ew != MissingValue) {
- iw -= ew;
- }
- }
- }
- if (iw < 0) continue;
-
- // Check the receiving end of the path if it can handle the flow.
- double ow = getExecutionCount(Dest);
- Processed.clear();
- for (succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
- NBB != End; ++NBB) {
- if (Processed.insert(*NBB).second) {
- Edge e = getEdge(BB, *NBB);
- double ew = getEdgeWeight(e);
- if (ew != MissingValue) {
- ow -= ew;
- }
- }
- }
- if (ow < 0) continue;
-
- // Determine how much flow shall be used.
- double ew = getEdgeWeight(getEdge(P[Dest],Dest));
- if (ew != MissingValue) {
- ew = ew<ow?ew:ow;
- ew = ew<iw?ew:iw;
- } else {
- if (inmissing == 0)
- ew = iw;
- }
-
- // Create flow.
- if (ew != MissingValue) {
- do {
- Edge e = getEdge(P[Dest],Dest);
- if (getEdgeWeight(e) == MissingValue) {
- setEdgeWeight(e,ew);
- FoundPath = true;
- }
- Dest = P[Dest];
- } while (Dest != BB);
- }
- }
- if (FoundPath) continue;
-
- // Calculate a block with self loop.
- FI = Unvisited.begin(), FE = Unvisited.end();
- while(FI != FE && !FoundPath) {
- const BasicBlock *BB = *FI; ++FI;
- bool SelfEdgeFound = false;
- for (succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
- NBB != End; ++NBB) {
- if (*NBB == BB) {
- SelfEdgeFound = true;
- break;
- }
- }
- if (SelfEdgeFound) {
- Edge e = getEdge(BB,BB);
- if (getEdgeWeight(e) == MissingValue) {
- double iw = 0;
- std::set<const BasicBlock *> Processed;
- for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
- NBB != End; ++NBB) {
- if (Processed.insert(*NBB).second) {
- Edge e = getEdge(*NBB, BB);
- double ew = getEdgeWeight(e);
- if (ew != MissingValue) {
- iw += ew;
- }
- }
- }
- setEdgeWeight(e,iw * 10);
- FoundPath = true;
- }
- }
- }
- if (FoundPath) continue;
-
- // Determine backedges, set them to zero.
- FI = Unvisited.begin(), FE = Unvisited.end();
- while(FI != FE && !FoundPath) {
- const BasicBlock *BB = *FI; ++FI;
- const BasicBlock *Dest = 0;
- Path P;
- bool BackEdgeFound = false;
- for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
- NBB != End; ++NBB) {
- Dest = GetPath(BB, *NBB, P, GetPathToDest | GetPathWithNewEdges);
- if (Dest == *NBB) {
- BackEdgeFound = true;
- break;
- }
- }
- if (BackEdgeFound) {
- Edge e = getEdge(Dest,BB);
- double w = getEdgeWeight(e);
- if (w == MissingValue) {
- setEdgeWeight(e,0);
- FoundPath = true;
- }
- do {
- Edge e = getEdge(P[Dest], Dest);
- double w = getEdgeWeight(e);
- if (w == MissingValue) {
- setEdgeWeight(e,0);
- FoundPath = true;
- }
- Dest = P[Dest];
- } while (Dest != BB);
- }
- }
- if (FoundPath) continue;
-
- // Channel flow to return block.
- FI = Unvisited.begin(), FE = Unvisited.end();
- while(FI != FE && !FoundPath) {
- const BasicBlock *BB = *FI; ++FI;
-
- Path P;
- const BasicBlock *Dest = GetPath(BB, 0, P, GetPathToExit | GetPathWithNewEdges);
- Dest = P[(const BasicBlock*)0];
- if (!Dest) continue;
-
- if (getEdgeWeight(getEdge(Dest,0)) == MissingValue) {
- // Calculate incoming flow.
- double iw = 0;
- std::set<const BasicBlock *> Processed;
- for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
- NBB != End; ++NBB) {
- if (Processed.insert(*NBB).second) {
- Edge e = getEdge(*NBB, BB);
- double ew = getEdgeWeight(e);
- if (ew != MissingValue) {
- iw += ew;
- }
- }
- }
- do {
- Edge e = getEdge(P[Dest], Dest);
- double w = getEdgeWeight(e);
- if (w == MissingValue) {
- setEdgeWeight(e,iw);
- FoundPath = true;
- } else {
- assert(0 && "Edge should not have value already!");
- }
- Dest = P[Dest];
- } while (Dest != BB);
- }
- }
- if (FoundPath) continue;
-
- // Speculatively set edges to zero.
- FI = Unvisited.begin(), FE = Unvisited.end();
- while(FI != FE && !FoundPath) {
- const BasicBlock *BB = *FI; ++FI;
-
- for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
- NBB != End; ++NBB) {
- Edge e = getEdge(*NBB,BB);
- double w = getEdgeWeight(e);
- if (w == MissingValue) {
- setEdgeWeight(e,0);
- FoundPath = true;
- break;
- }
- }
- }
- if (FoundPath) continue;
-
- errs() << "{";
- FI = Unvisited.begin(), FE = Unvisited.end();
- while(FI != FE) {
- const BasicBlock *BB = *FI; ++FI;
- dbgs() << BB->getName();
- if (FI != FE)
- dbgs() << ",";
- }
- errs() << "}";
-
- errs() << "ASSERT: could not repair function";
- assert(0 && "could not repair function");
- }
-
- EdgeWeights J = EdgeInformation[F];
- for (EdgeWeights::iterator EI = J.begin(), EE = J.end(); EI != EE; ++EI) {
- Edge e = EI->first;
-
- bool SuccFound = false;
- if (e.first != 0) {
- succ_const_iterator NBB = succ_begin(e.first), End = succ_end(e.first);
- if (NBB == End) {
- if (0 == e.second) {
- SuccFound = true;
- }
- }
- for (;NBB != End; ++NBB) {
- if (*NBB == e.second) {
- SuccFound = true;
- break;
- }
- }
- if (!SuccFound) {
- removeEdge(e);
- }
- }
- }
-}
-
-raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF) {
- return O << MF->getFunction()->getName() << "(MF)";
-}
-
-raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB) {
- return O << MBB->getBasicBlock()->getName() << "(MB)";
-}
-
-raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E) {
- O << "(";
-
- if (E.first)
- O << E.first;
- else
- O << "0";
-
- O << ",";
-
- if (E.second)
- O << E.second;
- else
- O << "0";
-
- return O << ")";
-}
-
-} // namespace llvm
-
-//===----------------------------------------------------------------------===//
-// NoProfile ProfileInfo implementation
-//
-
-namespace {
- struct NoProfileInfo : public ImmutablePass, public ProfileInfo {
- static char ID; // Class identification, replacement for typeinfo
- NoProfileInfo() : ImmutablePass(ID) {
- initializeNoProfileInfoPass(*PassRegistry::getPassRegistry());
- }
-
- /// getAdjustedAnalysisPointer - This method is used when a pass implements
- /// an analysis interface through multiple inheritance. If needed, it
- /// should override this to adjust the this pointer as needed for the
- /// specified pass info.
- virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
- if (PI == &ProfileInfo::ID)
- return (ProfileInfo*)this;
- return this;
- }
-
- virtual const char *getPassName() const {
- return "NoProfileInfo";
- }
- };
-} // End of anonymous namespace
-
-char NoProfileInfo::ID = 0;
-// Register this pass...
-INITIALIZE_AG_PASS(NoProfileInfo, ProfileInfo, "no-profile",
- "No Profile Information", false, true, true)
-
-ImmutablePass *llvm::createNoProfileInfoPass() { return new NoProfileInfo(); }
diff --git a/lib/Analysis/ProfileInfoLoader.cpp b/lib/Analysis/ProfileInfoLoader.cpp
deleted file mode 100644
index f1f3e94..0000000
--- a/lib/Analysis/ProfileInfoLoader.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-//===- ProfileInfoLoad.cpp - Load profile information from disk -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The ProfileInfoLoader class is used to load and represent profiling
-// information read in from the dump file.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/ProfileInfoLoader.h"
-#include "llvm/Analysis/ProfileInfoTypes.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdio>
-#include <cstdlib>
-using namespace llvm;
-
-// ByteSwap - Byteswap 'Var' if 'Really' is true.
-//
-static inline unsigned ByteSwap(unsigned Var, bool Really) {
- if (!Really) return Var;
- return ((Var & (255U<< 0U)) << 24U) |
- ((Var & (255U<< 8U)) << 8U) |
- ((Var & (255U<<16U)) >> 8U) |
- ((Var & (255U<<24U)) >> 24U);
-}
-
-static unsigned AddCounts(unsigned A, unsigned B) {
- // If either value is undefined, use the other.
- if (A == ProfileInfoLoader::Uncounted) return B;
- if (B == ProfileInfoLoader::Uncounted) return A;
- return A + B;
-}
-
-static void ReadProfilingBlock(const char *ToolName, FILE *F,
- bool ShouldByteSwap,
- std::vector<unsigned> &Data) {
- // Read the number of entries...
- unsigned NumEntries;
- if (fread(&NumEntries, sizeof(unsigned), 1, F) != 1) {
- errs() << ToolName << ": data packet truncated!\n";
- perror(0);
- exit(1);
- }
- NumEntries = ByteSwap(NumEntries, ShouldByteSwap);
-
- // Read the counts...
- std::vector<unsigned> TempSpace(NumEntries);
-
- // Read in the block of data...
- if (fread(&TempSpace[0], sizeof(unsigned)*NumEntries, 1, F) != 1) {
- errs() << ToolName << ": data packet truncated!\n";
- perror(0);
- exit(1);
- }
-
- // Make sure we have enough space... The space is initialised to -1 to
- // facitiltate the loading of missing values for OptimalEdgeProfiling.
- if (Data.size() < NumEntries)
- Data.resize(NumEntries, ProfileInfoLoader::Uncounted);
-
- // Accumulate the data we just read into the data.
- if (!ShouldByteSwap) {
- for (unsigned i = 0; i != NumEntries; ++i) {
- Data[i] = AddCounts(TempSpace[i], Data[i]);
- }
- } else {
- for (unsigned i = 0; i != NumEntries; ++i) {
- Data[i] = AddCounts(ByteSwap(TempSpace[i], true), Data[i]);
- }
- }
-}
-
-const unsigned ProfileInfoLoader::Uncounted = ~0U;
-
-// ProfileInfoLoader ctor - Read the specified profiling data file, exiting the
-// program if the file is invalid or broken.
-//
-ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
- const std::string &Filename)
- : Filename(Filename) {
- FILE *F = fopen(Filename.c_str(), "rb");
- if (F == 0) {
- errs() << ToolName << ": Error opening '" << Filename << "': ";
- perror(0);
- exit(1);
- }
-
- // Keep reading packets until we run out of them.
- unsigned PacketType;
- while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
- // If the low eight bits of the packet are zero, we must be dealing with an
- // endianness mismatch. Byteswap all words read from the profiling
- // information.
- bool ShouldByteSwap = (char)PacketType == 0;
- PacketType = ByteSwap(PacketType, ShouldByteSwap);
-
- switch (PacketType) {
- case ArgumentInfo: {
- unsigned ArgLength;
- if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) {
- errs() << ToolName << ": arguments packet truncated!\n";
- perror(0);
- exit(1);
- }
- ArgLength = ByteSwap(ArgLength, ShouldByteSwap);
-
- // Read in the arguments...
- std::vector<char> Chars(ArgLength+4);
-
- if (ArgLength)
- if (fread(&Chars[0], (ArgLength+3) & ~3, 1, F) != 1) {
- errs() << ToolName << ": arguments packet truncated!\n";
- perror(0);
- exit(1);
- }
- CommandLines.push_back(std::string(&Chars[0], &Chars[ArgLength]));
- break;
- }
-
- case FunctionInfo:
- ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts);
- break;
-
- case BlockInfo:
- ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts);
- break;
-
- case EdgeInfo:
- ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts);
- break;
-
- case OptEdgeInfo:
- ReadProfilingBlock(ToolName, F, ShouldByteSwap, OptimalEdgeCounts);
- break;
-
- case BBTraceInfo:
- ReadProfilingBlock(ToolName, F, ShouldByteSwap, BBTrace);
- break;
-
- default:
- errs() << ToolName << ": Unknown packet type #" << PacketType << "!\n";
- exit(1);
- }
- }
-
- fclose(F);
-}
-
diff --git a/lib/Analysis/ProfileInfoLoaderPass.cpp b/lib/Analysis/ProfileInfoLoaderPass.cpp
deleted file mode 100644
index 346f8d6..0000000
--- a/lib/Analysis/ProfileInfoLoaderPass.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-//===- ProfileInfoLoaderPass.cpp - LLVM Pass to load profile info ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a concrete implementation of profiling information that
-// loads the information from a profile dump file.
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "profile-loader"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/ProfileInfo.h"
-#include "llvm/Analysis/ProfileInfoLoader.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CFG.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <set>
-using namespace llvm;
-
-STATISTIC(NumEdgesRead, "The # of edges read.");
-
-static cl::opt<std::string>
-ProfileInfoFilename("profile-info-file", cl::init("llvmprof.out"),
- cl::value_desc("filename"),
- cl::desc("Profile file loaded by -profile-loader"));
-
-namespace {
- class LoaderPass : public ModulePass, public ProfileInfo {
- std::string Filename;
- std::set<Edge> SpanningTree;
- std::set<const BasicBlock*> BBisUnvisited;
- unsigned ReadCount;
- public:
- static char ID; // Class identification, replacement for typeinfo
- explicit LoaderPass(const std::string &filename = "")
- : ModulePass(ID), Filename(filename) {
- initializeLoaderPassPass(*PassRegistry::getPassRegistry());
- if (filename.empty()) Filename = ProfileInfoFilename;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
-
- virtual const char *getPassName() const {
- return "Profiling information loader";
- }
-
- // recurseBasicBlock() - Calculates the edge weights for as much basic
- // blocks as possbile.
- virtual void recurseBasicBlock(const BasicBlock *BB);
- virtual void readEdgeOrRemember(Edge, Edge&, unsigned &, double &);
- virtual void readEdge(ProfileInfo::Edge, std::vector<unsigned>&);
-
- /// getAdjustedAnalysisPointer - This method is used when a pass implements
- /// an analysis interface through multiple inheritance. If needed, it
- /// should override this to adjust the this pointer as needed for the
- /// specified pass info.
- virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
- if (PI == &ProfileInfo::ID)
- return (ProfileInfo*)this;
- return this;
- }
-
- /// run - Load the profile information from the specified file.
- virtual bool runOnModule(Module &M);
- };
-} // End of anonymous namespace
-
-char LoaderPass::ID = 0;
-INITIALIZE_AG_PASS(LoaderPass, ProfileInfo, "profile-loader",
- "Load profile information from llvmprof.out", false, true, false)
-
-char &llvm::ProfileLoaderPassID = LoaderPass::ID;
-
-ModulePass *llvm::createProfileLoaderPass() { return new LoaderPass(); }
-
-/// 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 *llvm::createProfileLoaderPass(const std::string &Filename) {
- return new LoaderPass(Filename);
-}
-
-void LoaderPass::readEdgeOrRemember(Edge edge, Edge &tocalc,
- unsigned &uncalc, double &count) {
- double w;
- if ((w = getEdgeWeight(edge)) == MissingValue) {
- tocalc = edge;
- uncalc++;
- } else {
- count+=w;
- }
-}
-
-// recurseBasicBlock - Visits all neighbours of a block and then tries to
-// calculate the missing edge values.
-void LoaderPass::recurseBasicBlock(const BasicBlock *BB) {
-
- // break recursion if already visited
- if (BBisUnvisited.find(BB) == BBisUnvisited.end()) return;
- BBisUnvisited.erase(BB);
- if (!BB) return;
-
- for (succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
- bbi != bbe; ++bbi) {
- recurseBasicBlock(*bbi);
- }
- for (const_pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
- bbi != bbe; ++bbi) {
- recurseBasicBlock(*bbi);
- }
-
- Edge tocalc;
- if (CalculateMissingEdge(BB, tocalc)) {
- SpanningTree.erase(tocalc);
- }
-}
-
-void LoaderPass::readEdge(ProfileInfo::Edge e,
- std::vector<unsigned> &ECs) {
- if (ReadCount < ECs.size()) {
- double weight = ECs[ReadCount++];
- if (weight != ProfileInfoLoader::Uncounted) {
- // Here the data realm changes from the unsigned of the file to the
- // double of the ProfileInfo. This conversion is save because we know
- // that everything thats representable in unsinged is also representable
- // in double.
- EdgeInformation[getFunction(e)][e] += (double)weight;
-
- DEBUG(dbgs() << "--Read Edge Counter for " << e
- << " (# "<< (ReadCount-1) << "): "
- << (unsigned)getEdgeWeight(e) << "\n");
- } else {
- // This happens only if reading optimal profiling information, not when
- // reading regular profiling information.
- SpanningTree.insert(e);
- }
- }
-}
-
-bool LoaderPass::runOnModule(Module &M) {
- ProfileInfoLoader PIL("profile-loader", Filename);
-
- EdgeInformation.clear();
- std::vector<unsigned> Counters = PIL.getRawEdgeCounts();
- if (Counters.size() > 0) {
- ReadCount = 0;
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- if (F->isDeclaration()) continue;
- DEBUG(dbgs() << "Working on " << F->getName() << "\n");
- readEdge(getEdge(0,&F->getEntryBlock()), Counters);
- for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
- TerminatorInst *TI = BB->getTerminator();
- for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
- readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
- }
- }
- }
- if (ReadCount != Counters.size()) {
- errs() << "WARNING: profile information is inconsistent with "
- << "the current program!\n";
- }
- NumEdgesRead = ReadCount;
- }
-
- Counters = PIL.getRawOptimalEdgeCounts();
- if (Counters.size() > 0) {
- ReadCount = 0;
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- if (F->isDeclaration()) continue;
- DEBUG(dbgs() << "Working on " << F->getName() << "\n");
- readEdge(getEdge(0,&F->getEntryBlock()), Counters);
- for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
- TerminatorInst *TI = BB->getTerminator();
- if (TI->getNumSuccessors() == 0) {
- readEdge(getEdge(BB,0), Counters);
- }
- for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
- readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
- }
- }
- while (SpanningTree.size() > 0) {
-
- unsigned size = SpanningTree.size();
-
- BBisUnvisited.clear();
- for (std::set<Edge>::iterator ei = SpanningTree.begin(),
- ee = SpanningTree.end(); ei != ee; ++ei) {
- BBisUnvisited.insert(ei->first);
- BBisUnvisited.insert(ei->second);
- }
- while (BBisUnvisited.size() > 0) {
- recurseBasicBlock(*BBisUnvisited.begin());
- }
-
- if (SpanningTree.size() == size) {
- DEBUG(dbgs()<<"{");
- for (std::set<Edge>::iterator ei = SpanningTree.begin(),
- ee = SpanningTree.end(); ei != ee; ++ei) {
- DEBUG(dbgs()<< *ei <<",");
- }
- assert(0 && "No edge calculated!");
- }
-
- }
- }
- if (ReadCount != Counters.size()) {
- errs() << "WARNING: profile information is inconsistent with "
- << "the current program!\n";
- }
- NumEdgesRead = ReadCount;
- }
-
- BlockInformation.clear();
- Counters = PIL.getRawBlockCounts();
- if (Counters.size() > 0) {
- ReadCount = 0;
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- if (F->isDeclaration()) continue;
- for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
- if (ReadCount < Counters.size())
- // Here the data realm changes from the unsigned of the file to the
- // double of the ProfileInfo. This conversion is save because we know
- // that everything thats representable in unsinged is also
- // representable in double.
- BlockInformation[F][BB] = (double)Counters[ReadCount++];
- }
- if (ReadCount != Counters.size()) {
- errs() << "WARNING: profile information is inconsistent with "
- << "the current program!\n";
- }
- }
-
- FunctionInformation.clear();
- Counters = PIL.getRawFunctionCounts();
- if (Counters.size() > 0) {
- ReadCount = 0;
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- if (F->isDeclaration()) continue;
- if (ReadCount < Counters.size())
- // Here the data realm changes from the unsigned of the file to the
- // double of the ProfileInfo. This conversion is save because we know
- // that everything thats representable in unsinged is also
- // representable in double.
- FunctionInformation[F] = (double)Counters[ReadCount++];
- }
- if (ReadCount != Counters.size()) {
- errs() << "WARNING: profile information is inconsistent with "
- << "the current program!\n";
- }
- }
-
- return false;
-}
diff --git a/lib/Analysis/ProfileVerifierPass.cpp b/lib/Analysis/ProfileVerifierPass.cpp
deleted file mode 100644
index c8896de..0000000
--- a/lib/Analysis/ProfileVerifierPass.cpp
+++ /dev/null
@@ -1,383 +0,0 @@
-//===- ProfileVerifierPass.cpp - LLVM Pass to estimate profile info -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a pass that checks profiling information for
-// plausibility.
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "profile-verifier"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Analysis/ProfileInfo.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CFG.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/InstIterator.h"
-#include "llvm/Support/raw_ostream.h"
-#include <set>
-using namespace llvm;
-
-static cl::opt<bool,false>
-ProfileVerifierDisableAssertions("profile-verifier-noassert",
- cl::desc("Disable assertions"));
-
-namespace {
- template<class FType, class BType>
- class ProfileVerifierPassT : public FunctionPass {
-
- struct DetailedBlockInfo {
- const BType *BB;
- double BBWeight;
- double inWeight;
- int inCount;
- double outWeight;
- int outCount;
- };
-
- ProfileInfoT<FType, BType> *PI;
- std::set<const BType*> BBisVisited;
- std::set<const FType*> FisVisited;
- bool DisableAssertions;
-
- // When debugging is enabled, the verifier prints a whole slew of debug
- // information, otherwise its just the assert. These are all the helper
- // functions.
- bool PrintedDebugTree;
- std::set<const BType*> BBisPrinted;
- void debugEntry(DetailedBlockInfo*);
- void printDebugInfo(const BType *BB);
-
- public:
- static char ID; // Class identification, replacement for typeinfo
-
- explicit ProfileVerifierPassT () : FunctionPass(ID) {
- initializeProfileVerifierPassPass(*PassRegistry::getPassRegistry());
- DisableAssertions = ProfileVerifierDisableAssertions;
- }
- explicit ProfileVerifierPassT (bool da) : FunctionPass(ID),
- DisableAssertions(da) {
- initializeProfileVerifierPassPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<ProfileInfoT<FType, BType> >();
- }
-
- const char *getPassName() const {
- return "Profiling information verifier";
- }
-
- /// run - Verify the profile information.
- bool runOnFunction(FType &F);
- void recurseBasicBlock(const BType*);
-
- bool exitReachable(const FType*);
- double ReadOrAssert(typename ProfileInfoT<FType, BType>::Edge);
- void CheckValue(bool, const char*, DetailedBlockInfo*);
- };
-
- typedef ProfileVerifierPassT<Function, BasicBlock> ProfileVerifierPass;
-
- template<class FType, class BType>
- void ProfileVerifierPassT<FType, BType>::printDebugInfo(const BType *BB) {
-
- if (BBisPrinted.find(BB) != BBisPrinted.end()) return;
-
- double BBWeight = PI->getExecutionCount(BB);
- if (BBWeight == ProfileInfoT<FType, BType>::MissingValue) { BBWeight = 0; }
- double inWeight = 0;
- int inCount = 0;
- std::set<const BType*> ProcessedPreds;
- for (const_pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
- bbi != bbe; ++bbi ) {
- if (ProcessedPreds.insert(*bbi).second) {
- typename ProfileInfoT<FType, BType>::Edge E = PI->getEdge(*bbi,BB);
- double EdgeWeight = PI->getEdgeWeight(E);
- if (EdgeWeight == ProfileInfoT<FType, BType>::MissingValue) { EdgeWeight = 0; }
- dbgs() << "calculated in-edge " << E << ": "
- << format("%20.20g",EdgeWeight) << "\n";
- inWeight += EdgeWeight;
- inCount++;
- }
- }
- double outWeight = 0;
- int outCount = 0;
- std::set<const BType*> ProcessedSuccs;
- for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
- bbi != bbe; ++bbi ) {
- if (ProcessedSuccs.insert(*bbi).second) {
- typename ProfileInfoT<FType, BType>::Edge E = PI->getEdge(BB,*bbi);
- double EdgeWeight = PI->getEdgeWeight(E);
- if (EdgeWeight == ProfileInfoT<FType, BType>::MissingValue) { EdgeWeight = 0; }
- dbgs() << "calculated out-edge " << E << ": "
- << format("%20.20g",EdgeWeight) << "\n";
- outWeight += EdgeWeight;
- outCount++;
- }
- }
- dbgs() << "Block " << BB->getName() << " in "
- << BB->getParent()->getName() << ":"
- << "BBWeight=" << format("%20.20g",BBWeight) << ","
- << "inWeight=" << format("%20.20g",inWeight) << ","
- << "inCount=" << inCount << ","
- << "outWeight=" << format("%20.20g",outWeight) << ","
- << "outCount" << outCount << "\n";
-
- // mark as visited and recurse into subnodes
- BBisPrinted.insert(BB);
- for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
- bbi != bbe; ++bbi ) {
- printDebugInfo(*bbi);
- }
- }
-
- template<class FType, class BType>
- void ProfileVerifierPassT<FType, BType>::debugEntry (DetailedBlockInfo *DI) {
- dbgs() << "TROUBLE: Block " << DI->BB->getName() << " in "
- << DI->BB->getParent()->getName() << ":"
- << "BBWeight=" << format("%20.20g",DI->BBWeight) << ","
- << "inWeight=" << format("%20.20g",DI->inWeight) << ","
- << "inCount=" << DI->inCount << ","
- << "outWeight=" << format("%20.20g",DI->outWeight) << ","
- << "outCount=" << DI->outCount << "\n";
- if (!PrintedDebugTree) {
- PrintedDebugTree = true;
- printDebugInfo(&(DI->BB->getParent()->getEntryBlock()));
- }
- }
-
- // This compares A and B for equality.
- static bool Equals(double A, double B) {
- return A == B;
- }
-
- // This checks if the function "exit" is reachable from an given function
- // via calls, this is necessary to check if a profile is valid despite the
- // counts not fitting exactly.
- template<class FType, class BType>
- bool ProfileVerifierPassT<FType, BType>::exitReachable(const FType *F) {
- if (!F) return false;
-
- if (FisVisited.count(F)) return false;
-
- FType *Exit = F->getParent()->getFunction("exit");
- if (Exit == F) {
- return true;
- }
-
- FisVisited.insert(F);
- bool exits = false;
- for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
- if (const CallInst *CI = dyn_cast<CallInst>(&*I)) {
- FType *F = CI->getCalledFunction();
- if (F) {
- exits |= exitReachable(F);
- } else {
- // This is a call to a pointer, all bets are off...
- exits = true;
- }
- if (exits) break;
- }
- }
- return exits;
- }
-
- #define ASSERTMESSAGE(M) \
- { dbgs() << "ASSERT:" << (M) << "\n"; \
- if (!DisableAssertions) assert(0 && (M)); }
-
- template<class FType, class BType>
- double ProfileVerifierPassT<FType, BType>::ReadOrAssert(typename ProfileInfoT<FType, BType>::Edge E) {
- double EdgeWeight = PI->getEdgeWeight(E);
- if (EdgeWeight == ProfileInfoT<FType, BType>::MissingValue) {
- dbgs() << "Edge " << E << " in Function "
- << ProfileInfoT<FType, BType>::getFunction(E)->getName() << ": ";
- ASSERTMESSAGE("Edge has missing value");
- return 0;
- } else {
- if (EdgeWeight < 0) {
- dbgs() << "Edge " << E << " in Function "
- << ProfileInfoT<FType, BType>::getFunction(E)->getName() << ": ";
- ASSERTMESSAGE("Edge has negative value");
- }
- return EdgeWeight;
- }
- }
-
- template<class FType, class BType>
- void ProfileVerifierPassT<FType, BType>::CheckValue(bool Error,
- const char *Message,
- DetailedBlockInfo *DI) {
- if (Error) {
- DEBUG(debugEntry(DI));
- dbgs() << "Block " << DI->BB->getName() << " in Function "
- << DI->BB->getParent()->getName() << ": ";
- ASSERTMESSAGE(Message);
- }
- return;
- }
-
- // This calculates the Information for a block and then recurses into the
- // successors.
- template<class FType, class BType>
- void ProfileVerifierPassT<FType, BType>::recurseBasicBlock(const BType *BB) {
-
- // Break the recursion by remembering all visited blocks.
- if (BBisVisited.find(BB) != BBisVisited.end()) return;
-
- // Use a data structure to store all the information, this can then be handed
- // to debug printers.
- DetailedBlockInfo DI;
- DI.BB = BB;
- DI.outCount = DI.inCount = 0;
- DI.inWeight = DI.outWeight = 0;
-
- // Read predecessors.
- std::set<const BType*> ProcessedPreds;
- const_pred_iterator bpi = pred_begin(BB), bpe = pred_end(BB);
- // If there are none, check for (0,BB) edge.
- if (bpi == bpe) {
- DI.inWeight += ReadOrAssert(PI->getEdge(0,BB));
- DI.inCount++;
- }
- for (;bpi != bpe; ++bpi) {
- if (ProcessedPreds.insert(*bpi).second) {
- DI.inWeight += ReadOrAssert(PI->getEdge(*bpi,BB));
- DI.inCount++;
- }
- }
-
- // Read successors.
- std::set<const BType*> ProcessedSuccs;
- succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
- // If there is an (0,BB) edge, consider it too. (This is done not only when
- // there are no successors, but every time; not every function contains
- // return blocks with no successors (think loop latch as return block)).
- double w = PI->getEdgeWeight(PI->getEdge(BB,0));
- if (w != ProfileInfoT<FType, BType>::MissingValue) {
- DI.outWeight += w;
- DI.outCount++;
- }
- for (;bbi != bbe; ++bbi) {
- if (ProcessedSuccs.insert(*bbi).second) {
- DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi));
- DI.outCount++;
- }
- }
-
- // Read block weight.
- DI.BBWeight = PI->getExecutionCount(BB);
- CheckValue(DI.BBWeight == ProfileInfoT<FType, BType>::MissingValue,
- "BasicBlock has missing value", &DI);
- CheckValue(DI.BBWeight < 0,
- "BasicBlock has negative value", &DI);
-
- // Check if this block is a setjmp target.
- bool isSetJmpTarget = false;
- if (DI.outWeight > DI.inWeight) {
- for (typename BType::const_iterator i = BB->begin(), ie = BB->end();
- i != ie; ++i) {
- if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
- FType *F = CI->getCalledFunction();
- if (F && (F->getName() == "_setjmp")) {
- isSetJmpTarget = true; break;
- }
- }
- }
- }
- // Check if this block is eventually reaching exit.
- bool isExitReachable = false;
- if (DI.inWeight > DI.outWeight) {
- for (typename BType::const_iterator i = BB->begin(), ie = BB->end();
- i != ie; ++i) {
- if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
- FType *F = CI->getCalledFunction();
- if (F) {
- FisVisited.clear();
- isExitReachable |= exitReachable(F);
- } else {
- // This is a call to a pointer, all bets are off...
- isExitReachable = true;
- }
- if (isExitReachable) break;
- }
- }
- }
-
- if (DI.inCount > 0 && DI.outCount == 0) {
- // If this is a block with no successors.
- if (!isSetJmpTarget) {
- CheckValue(!Equals(DI.inWeight,DI.BBWeight),
- "inWeight and BBWeight do not match", &DI);
- }
- } else if (DI.inCount == 0 && DI.outCount > 0) {
- // If this is a block with no predecessors.
- if (!isExitReachable)
- CheckValue(!Equals(DI.BBWeight,DI.outWeight),
- "BBWeight and outWeight do not match", &DI);
- } else {
- // If this block has successors and predecessors.
- if (DI.inWeight > DI.outWeight && !isExitReachable)
- CheckValue(!Equals(DI.inWeight,DI.outWeight),
- "inWeight and outWeight do not match", &DI);
- if (DI.inWeight < DI.outWeight && !isSetJmpTarget)
- CheckValue(!Equals(DI.inWeight,DI.outWeight),
- "inWeight and outWeight do not match", &DI);
- }
-
-
- // Mark this block as visited, rescurse into successors.
- BBisVisited.insert(BB);
- for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
- bbi != bbe; ++bbi ) {
- recurseBasicBlock(*bbi);
- }
- }
-
- template<class FType, class BType>
- bool ProfileVerifierPassT<FType, BType>::runOnFunction(FType &F) {
- PI = getAnalysisIfAvailable<ProfileInfoT<FType, BType> >();
- if (!PI)
- ASSERTMESSAGE("No ProfileInfo available");
-
- // Prepare global variables.
- PrintedDebugTree = false;
- BBisVisited.clear();
-
- // Fetch entry block and recurse into it.
- const BType *entry = &F.getEntryBlock();
- recurseBasicBlock(entry);
-
- if (PI->getExecutionCount(&F) != PI->getExecutionCount(entry))
- ASSERTMESSAGE("Function count and entry block count do not match");
-
- return false;
- }
-
- template<class FType, class BType>
- char ProfileVerifierPassT<FType, BType>::ID = 0;
-}
-
-INITIALIZE_PASS_BEGIN(ProfileVerifierPass, "profile-verifier",
- "Verify profiling information", false, true)
-INITIALIZE_AG_DEPENDENCY(ProfileInfo)
-INITIALIZE_PASS_END(ProfileVerifierPass, "profile-verifier",
- "Verify profiling information", false, true)
-
-namespace llvm {
- FunctionPass *createProfileVerifierPass() {
- return new ProfileVerifierPass(ProfileVerifierDisableAssertions);
- }
-}
-