[llvm] r191835 - Remove the very substantial, largely unmaintained legacy PGO
Alexey Samsonov
samsonov at google.com
Fri Oct 4 03:45:41 PDT 2013
FYI, I've restored LLVM_BUILD_RUNTIME CMake option in r191948 - otherwise
this change silently discarded building compiler-rt and libcxx :)
On Wed, Oct 2, 2013 at 7:57 PM, Rafael EspĂndola <rafael.espindola at gmail.com
> wrote:
> 61 files changed, 12 insertions(+), 8640 deletions(-)
>
> Nice!
>
> On 2 October 2013 11:42, Chandler Carruth <chandlerc at gmail.com> wrote:
> > Author: chandlerc
> > Date: Wed Oct 2 10:42:23 2013
> > New Revision: 191835
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=191835&view=rev
> > Log:
> > Remove the very substantial, largely unmaintained legacy PGO
> > infrastructure.
> >
> > This was essentially work toward PGO based on a design that had several
> > flaws, partially dating from a time when LLVM had a different
> > architecture, and with an effort to modernize it abandoned without being
> > completed. Since then, it has bitrotted for several years further. The
> > result is nearly unusable, and isn't helping any of the modern PGO
> > efforts. Instead, it is getting in the way, adding confusion about PGO
> > in LLVM and distracting everyone with maintenance on essentially dead
> > code. Removing it paves the way for modern efforts around PGO.
> >
> > Among other effects, this removes the last of the runtime libraries from
> > LLVM. Those are being developed in the separate 'compiler-rt' project
> > now, with somewhat different licensing specifically more approriate for
> > runtimes.
> >
> > Removed:
> > llvm/trunk/include/llvm/Analysis/PathNumbering.h
> > llvm/trunk/include/llvm/Analysis/PathProfileInfo.h
> > llvm/trunk/include/llvm/Analysis/ProfileDataLoader.h
> > llvm/trunk/include/llvm/Analysis/ProfileDataTypes.h
> > llvm/trunk/include/llvm/Analysis/ProfileInfo.h
> > llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h
> > llvm/trunk/include/llvm/Analysis/ProfileInfoTypes.h
> > llvm/trunk/lib/Analysis/PathNumbering.cpp
> > llvm/trunk/lib/Analysis/PathProfileInfo.cpp
> > llvm/trunk/lib/Analysis/PathProfileVerifier.cpp
> > llvm/trunk/lib/Analysis/ProfileDataLoader.cpp
> > llvm/trunk/lib/Analysis/ProfileDataLoaderPass.cpp
> > llvm/trunk/lib/Analysis/ProfileEstimatorPass.cpp
> > llvm/trunk/lib/Analysis/ProfileInfo.cpp
> > llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp
> > llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp
> > llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp
> > llvm/trunk/lib/Transforms/Instrumentation/EdgeProfiling.cpp
> > llvm/trunk/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp
> > llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp
> > llvm/trunk/runtime/
> > llvm/trunk/test/Analysis/Profiling/
> > llvm/trunk/tools/llvm-prof/
> > Modified:
> > llvm/trunk/CMakeLists.txt
> > llvm/trunk/LLVMBuild.txt
> > llvm/trunk/Makefile
> > llvm/trunk/include/llvm/Analysis/Passes.h
> > llvm/trunk/include/llvm/InitializePasses.h
> > llvm/trunk/include/llvm/LinkAllPasses.h
> > llvm/trunk/include/llvm/Transforms/Instrumentation.h
> > llvm/trunk/lib/Analysis/Analysis.cpp
> > llvm/trunk/lib/Analysis/CMakeLists.txt
> > llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp
> > llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt
> > llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
> > llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp
> > llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp
> > llvm/trunk/lib/Transforms/Utils/Local.cpp
> > llvm/trunk/test/lit.cfg
> > llvm/trunk/tools/CMakeLists.txt
> > llvm/trunk/tools/LLVMBuild.txt
> > llvm/trunk/tools/Makefile
> >
> > Modified: llvm/trunk/CMakeLists.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/CMakeLists.txt (original)
> > +++ llvm/trunk/CMakeLists.txt Wed Oct 2 10:42:23 2013
> > @@ -246,18 +246,13 @@ if( WIN32 AND NOT CYGWIN )
> > endif()
> >
> > # Define options to control the inclusion and default build behavior for
> > -# components which may not strictly be necessary (tools, runtime,
> examples, and
> > -# tests).
> > +# components which may not strictly be necessary (tools, examples, and
> tests).
> > #
> > # This is primarily to support building smaller or faster project files.
> > option(LLVM_INCLUDE_TOOLS "Generate build targets for the LLVM tools."
> ON)
> > option(LLVM_BUILD_TOOLS
> > "Build the LLVM tools. If OFF, just generate build targets." ON)
> >
> > -option(LLVM_INCLUDE_RUNTIME "Generate build targets for the LLVM
> runtimes" ON)
> > -option(LLVM_BUILD_RUNTIME
> > - "Build the LLVM runtime libraries. If OFF, just generate build
> targets." ON)
> > -
> > option(LLVM_BUILD_EXAMPLES
> > "Build the LLVM example programs. If OFF, just generate build
> targets." OFF)
> > option(LLVM_INCLUDE_EXAMPLES "Generate build targets for the LLVM
> examples" ON)
> > @@ -471,10 +466,6 @@ if( LLVM_INCLUDE_TOOLS )
> > add_subdirectory(tools)
> > endif()
> >
> > -if( LLVM_INCLUDE_RUNTIME )
> > - add_subdirectory(runtime)
> > -endif()
> > -
> > if( LLVM_INCLUDE_EXAMPLES )
> > add_subdirectory(examples)
> > endif()
> >
> > Modified: llvm/trunk/LLVMBuild.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/LLVMBuild.txt?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/LLVMBuild.txt (original)
> > +++ llvm/trunk/LLVMBuild.txt Wed Oct 2 10:42:23 2013
> > @@ -16,7 +16,7 @@
> >
> ;===------------------------------------------------------------------------===;
> >
> > [common]
> > -subdirectories = bindings docs examples lib projects runtime tools utils
> > +subdirectories = bindings docs examples lib projects tools utils
> >
> > [component_0]
> > type = Group
> >
> > Modified: llvm/trunk/Makefile
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/Makefile?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/Makefile (original)
> > +++ llvm/trunk/Makefile Wed Oct 2 10:42:23 2013
> > @@ -15,7 +15,7 @@ LEVEL := .
> > # 3. Build IR, which builds the Intrinsics.inc file used by libs.
> > # 4. Build libs, which are needed by llvm-config.
> > # 5. Build llvm-config, which determines inter-lib dependencies for
> tools.
> > -# 6. Build tools, runtime, docs.
> > +# 6. Build tools and docs.
> > #
> > # When cross-compiling, there are some things (tablegen) that need to
> > # be build for the build system first.
> > @@ -31,7 +31,7 @@ ifeq ($(BUILD_DIRS_ONLY),1)
> > OPTIONAL_DIRS := tools/clang/utils/TableGen
> > else
> > DIRS := lib/Support lib/TableGen utils lib/IR lib tools/llvm-shlib \
> > - tools/llvm-config tools runtime docs unittests
> > + tools/llvm-config tools docs unittests
> > OPTIONAL_DIRS := projects bindings
> > endif
> >
> > @@ -52,17 +52,17 @@ ifneq ($(ENABLE_DOCS),1)
> > endif
> >
> > ifeq ($(MAKECMDGOALS),libs-only)
> > - DIRS := $(filter-out tools runtime docs, $(DIRS))
> > + DIRS := $(filter-out tools docs, $(DIRS))
> > OPTIONAL_DIRS :=
> > endif
> >
> > ifeq ($(MAKECMDGOALS),install-libs)
> > - DIRS := $(filter-out tools runtime docs, $(DIRS))
> > + DIRS := $(filter-out tools docs, $(DIRS))
> > OPTIONAL_DIRS := $(filter bindings, $(OPTIONAL_DIRS))
> > endif
> >
> > ifeq ($(MAKECMDGOALS),tools-only)
> > - DIRS := $(filter-out runtime docs, $(DIRS))
> > + DIRS := $(filter-out docs, $(DIRS))
> > OPTIONAL_DIRS :=
> > endif
> >
> > @@ -72,7 +72,7 @@ ifeq ($(MAKECMDGOALS),install-clang)
> > tools/clang/tools/c-index-test \
> > tools/clang/include/clang-c \
> > tools/clang/runtime tools/clang/docs \
> > - tools/lto runtime
> > + tools/lto
> > OPTIONAL_DIRS :=
> > NO_INSTALL = 1
> > endif
> > @@ -84,7 +84,7 @@ ifeq ($(MAKECMDGOALS),clang-only)
> > endif
> >
> > ifeq ($(MAKECMDGOALS),unittests)
> > - DIRS := $(filter-out tools runtime docs, $(DIRS)) utils unittests
> > + DIRS := $(filter-out tools docs, $(DIRS)) utils unittests
> > OPTIONAL_DIRS :=
> > endif
> >
> >
> > Modified: llvm/trunk/include/llvm/Analysis/Passes.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Passes.h?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/Passes.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/Passes.h Wed Oct 2 10:42:23 2013
> > @@ -95,64 +95,6 @@ namespace llvm {
> >
> >
> //===--------------------------------------------------------------------===//
> > //
> > - // createProfileLoaderPass - This pass loads information from a
> profile dump
> > - // file.
> > - //
> > - ModulePass *createProfileLoaderPass();
> > - extern char &ProfileLoaderPassID;
> > -
> > -
> //===--------------------------------------------------------------------===//
> > - //
> > - // createProfileMetadataLoaderPass - This pass loads information from
> a
> > - // profile dump file and sets branch weight metadata.
> > - //
> > - ModulePass *createProfileMetadataLoaderPass();
> > - extern char &ProfileMetadataLoaderPassID;
> > -
> > -
> //===--------------------------------------------------------------------===//
> > - //
> > - // createNoProfileInfoPass - This pass implements the default "no
> profile".
> > - //
> > - ImmutablePass *createNoProfileInfoPass();
> > -
> > -
> //===--------------------------------------------------------------------===//
> > - //
> > - // createProfileEstimatorPass - This pass estimates profiling
> information
> > - // instead of loading it from a previous run.
> > - //
> > - FunctionPass *createProfileEstimatorPass();
> > - extern char &ProfileEstimatorPassID;
> > -
> > -
> //===--------------------------------------------------------------------===//
> > - //
> > - // createProfileVerifierPass - This pass verifies profiling
> information.
> > - //
> > - FunctionPass *createProfileVerifierPass();
> > -
> > -
> //===--------------------------------------------------------------------===//
> > - //
> > - // createPathProfileLoaderPass - This pass loads information from a
> path
> > - // profile dump file.
> > - //
> > - ModulePass *createPathProfileLoaderPass();
> > - extern char &PathProfileLoaderPassID;
> > -
> > -
> //===--------------------------------------------------------------------===//
> > - //
> > - // createNoPathProfileInfoPass - This pass implements the default
> > - // "no path profile".
> > - //
> > - ImmutablePass *createNoPathProfileInfoPass();
> > -
> > -
> //===--------------------------------------------------------------------===//
> > - //
> > - // createPathProfileVerifierPass - This pass verifies path profiling
> > - // information.
> > - //
> > - ModulePass *createPathProfileVerifierPass();
> > -
> > -
> //===--------------------------------------------------------------------===//
> > - //
> > // createDSAAPass - This pass implements simple context sensitive
> alias
> > // analysis.
> > //
> >
> > Removed: llvm/trunk/include/llvm/Analysis/PathNumbering.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PathNumbering.h?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/PathNumbering.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/PathNumbering.h (removed)
> > @@ -1,304 +0,0 @@
> > -//===- PathNumbering.h ----------------------------------------*- 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
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -
> > -#ifndef LLVM_ANALYSIS_PATHNUMBERING_H
> > -#define LLVM_ANALYSIS_PATHNUMBERING_H
> > -
> > -#include "llvm/Analysis/ProfileInfoTypes.h"
> > -#include "llvm/IR/BasicBlock.h"
> > -#include "llvm/IR/Instructions.h"
> > -#include "llvm/Pass.h"
> > -#include "llvm/Support/CFG.h"
> > -#include <map>
> > -#include <stack>
> > -#include <vector>
> > -
> > -namespace llvm {
> > -class BallLarusNode;
> > -class BallLarusEdge;
> > -class BallLarusDag;
> > -
> > -// typedefs for storage/ interators of various DAG components
> > -typedef std::vector<BallLarusNode*> BLNodeVector;
> > -typedef std::vector<BallLarusNode*>::iterator BLNodeIterator;
> > -typedef std::vector<BallLarusEdge*> BLEdgeVector;
> > -typedef std::vector<BallLarusEdge*>::iterator BLEdgeIterator;
> > -typedef std::map<BasicBlock*, BallLarusNode*> BLBlockNodeMap;
> > -typedef std::stack<BallLarusNode*> BLNodeStack;
> > -
> > -// Represents a basic block with information necessary for the BallLarus
> > -// algorithms.
> > -class BallLarusNode {
> > -public:
> > - enum NodeColor { WHITE, GRAY, BLACK };
> > -
> > - // Constructor: Initializes a new Node for the given BasicBlock
> > - BallLarusNode(BasicBlock* BB) :
> > - _basicBlock(BB), _numberPaths(0), _color(WHITE) {
> > - static unsigned nextUID = 0;
> > - _uid = nextUID++;
> > - }
> > -
> > - // Returns the basic block for the BallLarusNode
> > - BasicBlock* getBlock();
> > -
> > - // Get/set the number of paths to the exit starting at the node.
> > - unsigned getNumberPaths();
> > - void setNumberPaths(unsigned numberPaths);
> > -
> > - // Get/set the NodeColor used in graph algorithms.
> > - NodeColor getColor();
> > - void setColor(NodeColor color);
> > -
> > - // Iterator information for predecessor edges. Includes phony and
> > - // backedges.
> > - BLEdgeIterator predBegin();
> > - BLEdgeIterator predEnd();
> > - unsigned getNumberPredEdges();
> > -
> > - // Iterator information for successor edges. Includes phony and
> > - // backedges.
> > - BLEdgeIterator succBegin();
> > - BLEdgeIterator succEnd();
> > - unsigned getNumberSuccEdges();
> > -
> > - // Add an edge to the predecessor list.
> > - void addPredEdge(BallLarusEdge* edge);
> > -
> > - // Remove an edge from the predecessor list.
> > - void removePredEdge(BallLarusEdge* edge);
> > -
> > - // Add an edge to the successor list.
> > - void addSuccEdge(BallLarusEdge* edge);
> > -
> > - // Remove an edge from the successor list.
> > - void removeSuccEdge(BallLarusEdge* 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 getName();
> > -
> > -private:
> > - // The corresponding underlying BB.
> > - BasicBlock* _basicBlock;
> > -
> > - // Holds the predecessor edges of this node.
> > - BLEdgeVector _predEdges;
> > -
> > - // Holds the successor edges of this node.
> > - BLEdgeVector _succEdges;
> > -
> > - // The number of paths from the node to the exit.
> > - unsigned _numberPaths;
> > -
> > - // 'Color' used by graph algorithms to mark the node.
> > - NodeColor _color;
> > -
> > - // Unique ID to ensure naming difference with dotgraphs
> > - unsigned _uid;
> > -
> > - // Removes an edge from an edgeVector. Used by removePredEdge and
> > - // removeSuccEdge.
> > - void removeEdge(BLEdgeVector& v, BallLarusEdge* e);
> > -};
> > -
> > -// Represents an edge in the Dag. For an edge, v -> w, v is the
> source, and
> > -// w is the target.
> > -class BallLarusEdge {
> > -public:
> > - enum EdgeType { NORMAL, BACKEDGE, SPLITEDGE,
> > - BACKEDGE_PHONY, SPLITEDGE_PHONY, CALLEDGE_PHONY };
> > -
> > - // Constructor: Initializes an BallLarusEdge with a source and target.
> > - BallLarusEdge(BallLarusNode* source, BallLarusNode* target,
> > - unsigned duplicateNumber)
> > - : _source(source), _target(target), _weight(0), _edgeType(NORMAL),
> > - _realEdge(NULL), _duplicateNumber(duplicateNumber) {}
> > -
> > - // Returns the source/ target node of this edge.
> > - BallLarusNode* getSource() const;
> > - BallLarusNode* getTarget() const;
> > -
> > - // Sets the type of the edge.
> > - EdgeType getType() const;
> > -
> > - // Gets the type of the edge.
> > - void setType(EdgeType type);
> > -
> > - // Returns the weight of this edge. Used to decode path numbers to
> > - // sequences of basic blocks.
> > - unsigned getWeight();
> > -
> > - // Sets the weight of the edge. Used during path numbering.
> > - void setWeight(unsigned weight);
> > -
> > - // Gets/sets the phony edge originating at the root.
> > - BallLarusEdge* getPhonyRoot();
> > - void setPhonyRoot(BallLarusEdge* phonyRoot);
> > -
> > - // Gets/sets the phony edge terminating at the exit.
> > - BallLarusEdge* getPhonyExit();
> > - void setPhonyExit(BallLarusEdge* phonyExit);
> > -
> > - // Gets/sets the associated real edge if this is a phony edge.
> > - BallLarusEdge* getRealEdge();
> > - void setRealEdge(BallLarusEdge* realEdge);
> > -
> > - // Returns the duplicate number of the edge.
> > - unsigned getDuplicateNumber();
> > -
> > -protected:
> > - // Source node for this edge.
> > - BallLarusNode* _source;
> > -
> > - // Target node for this edge.
> > - BallLarusNode* _target;
> > -
> > -private:
> > - // Edge weight cooresponding to path number increments before removing
> > - // increments along a spanning tree. The sum over the edge weights
> gives
> > - // the path number.
> > - unsigned _weight;
> > -
> > - // Type to represent for what this edge is intended
> > - EdgeType _edgeType;
> > -
> > - // For backedges and split-edges, the phony edge which is linked to
> the
> > - // root node of the DAG. This contains a path number initialization.
> > - BallLarusEdge* _phonyRoot;
> > -
> > - // For backedges and split-edges, the phony edge which is linked to
> the
> > - // exit node of the DAG. This contains a path counter increment, and
> > - // potentially a path number increment.
> > - BallLarusEdge* _phonyExit;
> > -
> > - // If this is a phony edge, _realEdge is a link to the back or split
> > - // edge. Otherwise, this is null.
> > - BallLarusEdge* _realEdge;
> > -
> > - // An ID to differentiate between those edges which have the same
> source
> > - // and destination blocks.
> > - unsigned _duplicateNumber;
> > -};
> > -
> > -// Represents the Ball Larus DAG for a given Function. Can calculate
> > -// various properties required for instrumentation or analysis. E.g.
> the
> > -// edge weights that determine the path number.
> > -class BallLarusDag {
> > -public:
> > - // Initializes a BallLarusDag from the CFG of a given function. Must
> > - // call init() after creation, since some initialization requires
> > - // virtual functions.
> > - BallLarusDag(Function &F)
> > - : _root(NULL), _exit(NULL), _function(F) {}
> > -
> > - // Initialization that requires virtual functions which are not fully
> > - // functional in the constructor.
> > - void init();
> > -
> > - // Frees all memory associated with the DAG.
> > - virtual ~BallLarusDag();
> > -
> > - // Calculate the path numbers by assigning edge increments as
> prescribed
> > - // in Ball-Larus path profiling.
> > - void calculatePathNumbers();
> > -
> > - // Returns the number of paths for the DAG.
> > - unsigned getNumberOfPaths();
> > -
> > - // Returns the root (i.e. entry) node for the DAG.
> > - BallLarusNode* getRoot();
> > -
> > - // Returns the exit node for the DAG.
> > - BallLarusNode* getExit();
> > -
> > - // Returns the function for the DAG.
> > - Function& getFunction();
> > -
> > - // Clears the node colors.
> > - void clearColors(BallLarusNode::NodeColor color);
> > -
> > -protected:
> > - // All nodes in the DAG.
> > - BLNodeVector _nodes;
> > -
> > - // All edges in the DAG.
> > - BLEdgeVector _edges;
> > -
> > - // All backedges in the DAG.
> > - BLEdgeVector _backEdges;
> > -
> > - // 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.
> > - virtual BallLarusNode* createNode(BasicBlock* BB);
> > -
> > - // Allows subclasses to determine which type of Edge is created.
> > - // Override this method to produce subclasses of BallLarusEdge if
> > - // necessary. Parameters source and target will have been created by
> > - // createNode and can be cast to the subclass of BallLarusNode*
> > - // returned by createNode. The destructor of BallLarusDag will call
> free
> > - // on each pointer created.
> > - virtual BallLarusEdge* createEdge(BallLarusNode* source,
> BallLarusNode*
> > - target, unsigned duplicateNumber);
> > -
> > - // Proxy to node's constructor. Updates the DAG state.
> > - BallLarusNode* addNode(BasicBlock* BB);
> > -
> > - // Proxy to edge's constructor. Updates the DAG state.
> > - BallLarusEdge* addEdge(BallLarusNode* source, BallLarusNode* target,
> > - unsigned duplicateNumber);
> > -
> > -private:
> > - // The root (i.e. entry) node for this DAG.
> > - BallLarusNode* _root;
> > -
> > - // The exit node for this DAG.
> > - BallLarusNode* _exit;
> > -
> > - // The function represented by this DAG.
> > - Function& _function;
> > -
> > - // Processes one node and its imediate edges for building the DAG.
> > - void buildNode(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>&
> dfsStack);
> > -
> > - // Process an edge in the CFG for DAG building.
> > - void buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>&
> dfsStack,
> > - BallLarusNode* currentNode, BasicBlock* succBB,
> > - unsigned duplicateNumber);
> > -
> > - // The weight on each edge is the increment required along any path
> that
> > - // contains that edge.
> > - void calculatePathNumbersFrom(BallLarusNode* node);
> > -
> > - // Adds a backedge with its phony edges. Updates the DAG state.
> > - void addBackedge(BallLarusNode* source, BallLarusNode* target,
> > - unsigned duplicateCount);
> > -};
> > -} // end namespace llvm
> > -
> > -#endif
> >
> > Removed: llvm/trunk/include/llvm/Analysis/PathProfileInfo.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PathProfileInfo.h?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/PathProfileInfo.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/PathProfileInfo.h (removed)
> > @@ -1,112 +0,0 @@
> > -//===- PathProfileInfo.h --------------------------------------*- C++
> -*---===//
> > -//
> > -// The LLVM Compiler Infrastructure
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -//
> > -// This file outlines the interface used by optimizers to load path
> profiles.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -
> > -#ifndef LLVM_ANALYSIS_PATHPROFILEINFO_H
> > -#define LLVM_ANALYSIS_PATHPROFILEINFO_H
> > -
> > -#include "llvm/Analysis/PathNumbering.h"
> > -#include "llvm/IR/BasicBlock.h"
> > -
> > -namespace llvm {
> > -
> > -class ProfilePath;
> > -class ProfilePathEdge;
> > -class PathProfileInfo;
> > -
> > -typedef std::vector<ProfilePathEdge> ProfilePathEdgeVector;
> > -typedef std::vector<ProfilePathEdge>::iterator ProfilePathEdgeIterator;
> > -
> > -typedef std::vector<BasicBlock*> ProfilePathBlockVector;
> > -typedef std::vector<BasicBlock*>::iterator ProfilePathBlockIterator;
> > -
> > -typedef std::map<unsigned int,ProfilePath*> ProfilePathMap;
> > -typedef std::map<unsigned int,ProfilePath*>::iterator
> ProfilePathIterator;
> > -
> > -typedef std::map<Function*,unsigned int> FunctionPathCountMap;
> > -typedef std::map<Function*,ProfilePathMap> FunctionPathMap;
> > -typedef std::map<Function*,ProfilePathMap>::iterator
> FunctionPathIterator;
> > -
> > -class ProfilePathEdge {
> > -public:
> > - ProfilePathEdge(BasicBlock* source, BasicBlock* target,
> > - unsigned duplicateNumber);
> > -
> > - inline unsigned getDuplicateNumber() { return _duplicateNumber; }
> > - inline BasicBlock* getSource() { return _source; }
> > - inline BasicBlock* getTarget() { return _target; }
> > -
> > -protected:
> > - BasicBlock* _source;
> > - BasicBlock* _target;
> > - unsigned _duplicateNumber;
> > -};
> > -
> > -class ProfilePath {
> > -public:
> > - ProfilePath(unsigned int number, unsigned int count,
> > - double countStdDev, PathProfileInfo* ppi);
> > -
> > - double getFrequency() const;
> > -
> > - inline unsigned int getNumber() const { return _number; }
> > - inline unsigned int getCount() const { return _count; }
> > - inline double getCountStdDev() const { return _countStdDev; }
> > -
> > - ProfilePathEdgeVector* getPathEdges() const;
> > - ProfilePathBlockVector* getPathBlocks() const;
> > -
> > - BasicBlock* getFirstBlockInPath() const;
> > -
> > -private:
> > - unsigned int _number;
> > - unsigned int _count;
> > - double _countStdDev;
> > -
> > - // double pointer back to the profiling info
> > - PathProfileInfo* _ppi;
> > -};
> > -
> > -// TODO: overload [] operator for getting path
> > -// Add: getFunctionCallCount()
> > -class PathProfileInfo {
> > - public:
> > - PathProfileInfo();
> > - ~PathProfileInfo();
> > -
> > - void setCurrentFunction(Function* F);
> > - Function* getCurrentFunction() const;
> > - BasicBlock* getCurrentFunctionEntry();
> > -
> > - ProfilePath* getPath(unsigned int number);
> > - unsigned int getPotentialPathCount();
> > -
> > - ProfilePathIterator pathBegin();
> > - ProfilePathIterator pathEnd();
> > - unsigned int pathsRun();
> > -
> > - static char ID; // Pass identification
> > - std::string argList;
> > -
> > -protected:
> > - FunctionPathMap _functionPaths;
> > - FunctionPathCountMap _functionPathCounts;
> > -
> > -private:
> > - BallLarusDag* _currentDag;
> > - Function* _currentFunction;
> > -
> > - friend class ProfilePath;
> > -};
> > -} // end namespace llvm
> > -
> > -#endif
> >
> > Removed: llvm/trunk/include/llvm/Analysis/ProfileDataLoader.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ProfileDataLoader.h?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/ProfileDataLoader.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/ProfileDataLoader.h (removed)
> > @@ -1,140 +0,0 @@
> > -//===- ProfileDataLoader.h - Load & convert profile info ----*- C++
> -*-===//
> > -//
> > -// The LLVM Compiler Infrastructure
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -//
> > -// The ProfileDataLoader class is used to load profiling data from a
> dump file.
> > -// The ProfileDataT<FType, BType> class is used to store the mapping of
> this
> > -// data to control flow edges.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -
> > -#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
> > -#define LLVM_ANALYSIS_PROFILEDATALOADER_H
> > -
> > -#include "llvm/ADT/ArrayRef.h"
> > -#include "llvm/ADT/DenseMap.h"
> > -#include "llvm/ADT/SmallVector.h"
> > -#include "llvm/Support/Debug.h"
> > -#include "llvm/Support/ErrorHandling.h"
> > -#include <string>
> > -
> > -namespace llvm {
> > -
> > -class ModulePass;
> > -class Function;
> > -class BasicBlock;
> > -
> > -// Helper for dumping edges to dbgs().
> > -raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *,
> > - const BasicBlock *>
> E);
> > -
> > -/// \brief The ProfileDataT<FType, BType> class is used to store the
> mapping of
> > -/// profiling data to control flow edges.
> > -///
> > -/// An edge is defined by its source and sink basic blocks.
> > -template<class FType, class BType>
> > -class ProfileDataT {
> > -public:
> > - // The profiling information defines an Edge by its source and sink
> basic
> > - // blocks.
> > - typedef std::pair<const BType*, const BType*> Edge;
> > -
> > -private:
> > - typedef DenseMap<Edge, unsigned> EdgeWeights;
> > -
> > - /// \brief Count the number of times a transition between two blocks
> is
> > - /// executed.
> > - ///
> > - /// As a special case, we also hold an edge from the null BasicBlock
> to the
> > - /// entry block to indicate how many times the function was entered.
> > - DenseMap<const FType*, EdgeWeights> EdgeInformation;
> > -
> > -public:
> > - /// getFunction() - Returns the Function for an Edge.
> > - static const FType *getFunction(Edge e) {
> > - // e.first may be NULL
> > - assert(((!e.first) || (e.first->getParent() ==
> e.second->getParent()))
> > - && "A ProfileData::Edge can not be between two functions");
> > - assert(e.second && "A ProfileData::Edge must have a real sink");
> > - return e.second->getParent();
> > - }
> > -
> > - /// getEdge() - Creates an Edge between two BasicBlocks.
> > - static Edge getEdge(const BType *Src, const BType *Dest) {
> > - return Edge(Src, Dest);
> > - }
> > -
> > - /// getEdgeWeight - Return the number of times that a given edge was
> > - /// executed.
> > - unsigned getEdgeWeight(Edge e) const {
> > - const FType *f = getFunction(e);
> > - assert((EdgeInformation.find(f) != EdgeInformation.end())
> > - && "No profiling information for function");
> > - EdgeWeights weights = EdgeInformation.find(f)->second;
> > -
> > - assert((weights.find(e) != weights.end())
> > - && "No profiling information for edge");
> > - return weights.find(e)->second;
> > - }
> > -
> > - /// addEdgeWeight - Add 'weight' to the already stored execution
> count for
> > - /// this edge.
> > - void addEdgeWeight(Edge e, unsigned weight) {
> > - EdgeInformation[getFunction(e)][e] += weight;
> > - }
> > -};
> > -
> > -typedef ProfileDataT<Function, BasicBlock> ProfileData;
> > -//typedef ProfileDataT<MachineFunction, MachineBasicBlock>
> MachineProfileData;
> > -
> > -/// The ProfileDataLoader class is used to load raw profiling data from
> the
> > -/// dump file.
> > -class ProfileDataLoader {
> > -private:
> > - /// The name of the file where the raw profiling data is stored.
> > - const std::string &Filename;
> > -
> > - /// A vector of the command line arguments used when the target
> program was
> > - /// run to generate profiling data. One entry per program run.
> > - SmallVector<std::string, 1> CommandLines;
> > -
> > - /// The raw values for how many times each edge was traversed, values
> from
> > - /// multiple program runs are accumulated.
> > - SmallVector<unsigned, 32> EdgeCounts;
> > -
> > -public:
> > - /// ProfileDataLoader ctor - Read the specified profiling data file,
> exiting
> > - /// the program if the file is invalid or broken.
> > - ProfileDataLoader(const char *ToolName, const std::string &Filename);
> > -
> > - /// A special value used to represent the weight of an edge which has
> not
> > - /// been counted yet.
> > - static const unsigned Uncounted;
> > -
> > - /// getNumExecutions - Return the number of times the target program
> was run
> > - /// to generate this profiling data.
> > - unsigned getNumExecutions() const { return CommandLines.size(); }
> > -
> > - /// getExecution - Return the command line parameters used to
> generate the
> > - /// i'th set of profiling data.
> > - const std::string &getExecution(unsigned i) const { return
> CommandLines[i]; }
> > -
> > - const std::string &getFileName() const { return Filename; }
> > -
> > - /// getRawEdgeCounts - Return the raw profiling data, this is just a
> list of
> > - /// numbers with no mappings to edges.
> > - ArrayRef<unsigned> getRawEdgeCounts() const { return EdgeCounts; }
> > -};
> > -
> > -/// createProfileMetadataLoaderPass - This function returns a Pass that
> loads
> > -/// the profiling information for the module from the specified
> filename.
> > -ModulePass *createProfileMetadataLoaderPass(const std::string
> &Filename);
> > -
> > -} // End llvm namespace
> > -
> > -#endif
> >
> > Removed: llvm/trunk/include/llvm/Analysis/ProfileDataTypes.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ProfileDataTypes.h?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/ProfileDataTypes.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/ProfileDataTypes.h (removed)
> > @@ -1,39 +0,0 @@
> > -/*===-- ProfileDataTypes.h - Profiling info shared constants
> --------------===*\
> > -|*
> > -|* The LLVM Compiler Infrastructure
> > -|*
> > -|* This file is distributed under the University of Illinois Open Source
> > -|* License. See LICENSE.TXT for details.
> > -|*
> >
> -|*===----------------------------------------------------------------------===*|
> > -|*
> > -|* This file defines constants shared by the various different profiling
> > -|* runtime libraries and the LLVM C++ profile metadata loader. It must
> be a
> > -|* C header because, at present, the profiling runtimes are written in
> C.
> > -|*
> >
> -\*===----------------------------------------------------------------------===*/
> > -
> > -#ifndef LLVM_ANALYSIS_PROFILEDATATYPES_H
> > -#define LLVM_ANALYSIS_PROFILEDATATYPES_H
> > -
> > -/* Included by libprofile. */
> > -#if defined(__cplusplus)
> > -extern "C" {
> > -#endif
> > -
> > -/* TODO: Strip out unused entries once ProfileInfo etc has been
> removed. */
> > -enum ProfilingType {
> > - ArgumentInfo = 1, /* The command line argument block */
> > - FunctionInfo = 2, /* Function profiling information */
> > - BlockInfo = 3, /* Block profiling information */
> > - EdgeInfo = 4, /* Edge profiling information */
> > - PathInfo = 5, /* Path profiling information */
> > - BBTraceInfo = 6, /* Basic block trace information */
> > - OptEdgeInfo = 7 /* Edge profiling information, optimal version */
> > -};
> > -
> > -#if defined(__cplusplus)
> > -}
> > -#endif
> > -
> > -#endif /* LLVM_ANALYSIS_PROFILEDATATYPES_H */
> >
> > Removed: llvm/trunk/include/llvm/Analysis/ProfileInfo.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ProfileInfo.h?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/ProfileInfo.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/ProfileInfo.h (removed)
> > @@ -1,247 +0,0 @@
> > -//===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- 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 generic ProfileInfo interface, which is used
> as the
> > -// common interface used by all clients of profiling information, and
> > -// implemented either by making static guestimations, or by actually
> reading in
> > -// profiling information gathered by running the program.
> > -//
> > -// Note that to be useful, all profile-based optimizations should
> preserve
> > -// ProfileInfo, which requires that they notify it when changes to the
> CFG are
> > -// made. (This is not implemented yet.)
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -
> > -#ifndef LLVM_ANALYSIS_PROFILEINFO_H
> > -#define LLVM_ANALYSIS_PROFILEINFO_H
> > -
> > -#include "llvm/Support/Debug.h"
> > -#include "llvm/Support/ErrorHandling.h"
> > -#include "llvm/Support/Format.h"
> > -#include "llvm/Support/raw_ostream.h"
> > -#include <cassert>
> > -#include <map>
> > -#include <set>
> > -#include <string>
> > -
> > -namespace llvm {
> > - class Pass;
> > - class raw_ostream;
> > -
> > - class BasicBlock;
> > - class Function;
> > - class MachineBasicBlock;
> > - class MachineFunction;
> > -
> > - // Helper for dumping edges to dbgs().
> > - raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *,
> const BasicBlock *> E);
> > - raw_ostream& operator<<(raw_ostream &O, std::pair<const
> MachineBasicBlock *, const MachineBasicBlock *> E);
> > -
> > - raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB);
> > - raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB);
> > -
> > - raw_ostream& operator<<(raw_ostream &O, const Function *F);
> > - raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF);
> > -
> > - /// ProfileInfo Class - This class holds and maintains profiling
> > - /// information for some unit of code.
> > - template<class FType, class BType>
> > - class ProfileInfoT {
> > - public:
> > - // Types for handling profiling information.
> > - typedef std::pair<const BType*, const BType*> Edge;
> > - typedef std::pair<Edge, double> EdgeWeight;
> > - typedef std::map<Edge, double> EdgeWeights;
> > - typedef std::map<const BType*, double> BlockCounts;
> > - typedef std::map<const BType*, const BType*> Path;
> > -
> > - protected:
> > - // EdgeInformation - Count the number of times a transition between
> two
> > - // blocks is executed. As a special case, we also hold an edge from
> the
> > - // null BasicBlock to the entry block to indicate how many times the
> > - // function was entered.
> > - std::map<const FType*, EdgeWeights> EdgeInformation;
> > -
> > - // BlockInformation - Count the number of times a block is executed.
> > - std::map<const FType*, BlockCounts> BlockInformation;
> > -
> > - // FunctionInformation - Count the number of times a function is
> executed.
> > - std::map<const FType*, double> FunctionInformation;
> > -
> > - ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile;
> > - public:
> > - static char ID; // Class identification, replacement for typeinfo
> > - ProfileInfoT();
> > - ~ProfileInfoT(); // We want to be subclassed
> > -
> > - // MissingValue - The value that is returned for execution counts
> in case
> > - // no value is available.
> > - static const double MissingValue;
> > -
> > - // getFunction() - Returns the Function for an Edge, checking for
> validity.
> > - static const FType* getFunction(Edge e) {
> > - if (e.first)
> > - return e.first->getParent();
> > - if (e.second)
> > - return e.second->getParent();
> > - llvm_unreachable("Invalid ProfileInfo::Edge");
> > - }
> > -
> > - // getEdge() - Creates an Edge from two BasicBlocks.
> > - static Edge getEdge(const BType *Src, const BType *Dest) {
> > - return std::make_pair(Src, Dest);
> > - }
> > -
> > -
> //===------------------------------------------------------------------===//
> > - /// Profile Information Queries
> > - ///
> > - double getExecutionCount(const FType *F);
> > -
> > - double getExecutionCount(const BType *BB);
> > -
> > - void setExecutionCount(const BType *BB, double w);
> > -
> > - void addExecutionCount(const BType *BB, double w);
> > -
> > - double getEdgeWeight(Edge e) const {
> > - typename std::map<const FType*, EdgeWeights>::const_iterator J =
> > - EdgeInformation.find(getFunction(e));
> > - if (J == EdgeInformation.end()) return MissingValue;
> > -
> > - typename EdgeWeights::const_iterator I = J->second.find(e);
> > - if (I == J->second.end()) return MissingValue;
> > -
> > - return I->second;
> > - }
> > -
> > - void setEdgeWeight(Edge e, double w) {
> > - DEBUG_WITH_TYPE("profile-info",
> > - dbgs() << "Creating Edge " << e
> > - << " (weight: " << format("%.20g",w) << ")\n");
> > - EdgeInformation[getFunction(e)][e] = w;
> > - }
> > -
> > - void addEdgeWeight(Edge e, double w);
> > -
> > - EdgeWeights &getEdgeWeights (const FType *F) {
> > - return EdgeInformation[F];
> > - }
> > -
> > -
> //===------------------------------------------------------------------===//
> > - /// Analysis Update Methods
> > - ///
> > - void removeBlock(const BType *BB);
> > -
> > - void removeEdge(Edge e);
> > -
> > - void replaceEdge(const Edge &, const Edge &);
> > -
> > - enum GetPathMode {
> > - GetPathToExit = 1,
> > - GetPathToValue = 2,
> > - GetPathToDest = 4,
> > - GetPathWithNewEdges = 8
> > - };
> > -
> > - const BType *GetPath(const BType *Src, const BType *Dest,
> > - Path &P, unsigned Mode);
> > -
> > - void divertFlow(const Edge &, const Edge &);
> > -
> > - void splitEdge(const BType *FirstBB, const BType *SecondBB,
> > - const BType *NewBB, bool MergeIdenticalEdges =
> false);
> > -
> > - void splitBlock(const BType *Old, const BType* New);
> > -
> > - void splitBlock(const BType *BB, const BType* NewBB,
> > - BType *const *Preds, unsigned NumPreds);
> > -
> > - void replaceAllUses(const BType *RmBB, const BType *DestBB);
> > -
> > - void transfer(const FType *Old, const FType *New);
> > -
> > - void repair(const FType *F);
> > -
> > - void dump(FType *F = 0, bool real = true) {
> > - dbgs() << "**** This is ProfileInfo " << this << " speaking:\n";
> > - if (!real) {
> > - typename std::set<const FType*> Functions;
> > -
> > - dbgs() << "Functions: \n";
> > - if (F) {
> > - dbgs() << F << "@" << format("%p", F) << ": " <<
> format("%.20g",getExecutionCount(F)) << "\n";
> > - Functions.insert(F);
> > - } else {
> > - for (typename std::map<const FType*, double>::iterator fi =
> FunctionInformation.begin(),
> > - fe = FunctionInformation.end(); fi != fe; ++fi) {
> > - dbgs() << fi->first << "@" << format("%p",fi->first) << ":
> " << format("%.20g",fi->second) << "\n";
> > - Functions.insert(fi->first);
> > - }
> > - }
> > -
> > - for (typename std::set<const FType*>::iterator FI =
> Functions.begin(), FE = Functions.end();
> > - FI != FE; ++FI) {
> > - const FType *F = *FI;
> > - typename std::map<const FType*, BlockCounts>::iterator bwi =
> BlockInformation.find(F);
> > - dbgs() << "BasicBlocks for Function " << F << ":\n";
> > - for (typename BlockCounts::const_iterator bi =
> bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) {
> > - dbgs() << bi->first << "@" << format("%p", bi->first) << ":
> " << format("%.20g",bi->second) << "\n";
> > - }
> > - }
> > -
> > - for (typename std::set<const FType*>::iterator FI =
> Functions.begin(), FE = Functions.end();
> > - FI != FE; ++FI) {
> > - typename std::map<const FType*, EdgeWeights>::iterator ei =
> EdgeInformation.find(*FI);
> > - dbgs() << "Edges for Function " << ei->first << ":\n";
> > - for (typename EdgeWeights::iterator ewi = ei->second.begin(),
> ewe = ei->second.end();
> > - ewi != ewe; ++ewi) {
> > - dbgs() << ewi->first << ": " << format("%.20g",ewi->second)
> << "\n";
> > - }
> > - }
> > - } else {
> > - assert(F && "No function given, this is not supported!");
> > - dbgs() << "Functions: \n";
> > - dbgs() << F << "@" << format("%p", F) << ": " <<
> format("%.20g",getExecutionCount(F)) << "\n";
> > -
> > - dbgs() << "BasicBlocks for Function " << F << ":\n";
> > - for (typename FType::const_iterator BI = F->begin(), BE =
> F->end();
> > - BI != BE; ++BI) {
> > - const BType *BB = &(*BI);
> > - dbgs() << BB << "@" << format("%p", BB) << ": " <<
> format("%.20g",getExecutionCount(BB)) << "\n";
> > - }
> > - }
> > - dbgs() << "**** ProfileInfo " << this << ", over and out.\n";
> > - }
> > -
> > - bool CalculateMissingEdge(const BType *BB, Edge &removed, bool
> assumeEmptyExit = false);
> > -
> > - bool EstimateMissingEdges(const BType *BB);
> > -
> > - ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() {
> > - if (MachineProfile == 0)
> > - MachineProfile = new ProfileInfoT<MachineFunction,
> MachineBasicBlock>();
> > - return MachineProfile;
> > - }
> > -
> > - bool hasMI() const {
> > - return (MachineProfile != 0);
> > - }
> > - };
> > -
> > - typedef ProfileInfoT<Function, BasicBlock> ProfileInfo;
> > - typedef ProfileInfoT<MachineFunction, MachineBasicBlock>
> MachineProfileInfo;
> > -
> > - /// createProfileLoaderPass - This function returns a Pass that loads
> the
> > - /// profiling information for the module from the specified filename,
> making
> > - /// it available to the optimizers.
> > - Pass *createProfileLoaderPass(const std::string &Filename);
> > -
> > -} // End llvm namespace
> > -
> > -#endif
> >
> > Removed: llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/ProfileInfoLoader.h (removed)
> > @@ -1,81 +0,0 @@
> > -//===- ProfileInfoLoader.h - Load & convert profile information -*- C++
> -*-===//
> > -//
> > -// 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. If conversions between
> formats are
> > -// needed, it can also do this.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -
> > -#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
> > -#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
> > -
> > -#include <string>
> > -#include <utility>
> > -#include <vector>
> > -
> > -namespace llvm {
> > -
> > -class Module;
> > -class Function;
> > -class BasicBlock;
> > -
> > -class ProfileInfoLoader {
> > - const std::string &Filename;
> > - std::vector<std::string> CommandLines;
> > - std::vector<unsigned> FunctionCounts;
> > - std::vector<unsigned> BlockCounts;
> > - std::vector<unsigned> EdgeCounts;
> > - std::vector<unsigned> OptimalEdgeCounts;
> > - std::vector<unsigned> BBTrace;
> > -public:
> > - // ProfileInfoLoader ctor - Read the specified profiling data file,
> exiting
> > - // the program if the file is invalid or broken.
> > - ProfileInfoLoader(const char *ToolName, const std::string &Filename);
> > -
> > - static const unsigned Uncounted;
> > -
> > - unsigned getNumExecutions() const { return CommandLines.size(); }
> > - const std::string &getExecution(unsigned i) const { return
> CommandLines[i]; }
> > -
> > - const std::string &getFileName() const { return Filename; }
> > -
> > - // getRawFunctionCounts - This method is used by consumers of function
> > - // counting information.
> > - //
> > - const std::vector<unsigned> &getRawFunctionCounts() const {
> > - return FunctionCounts;
> > - }
> > -
> > - // getRawBlockCounts - This method is used by consumers of block
> counting
> > - // information.
> > - //
> > - const std::vector<unsigned> &getRawBlockCounts() const {
> > - return BlockCounts;
> > - }
> > -
> > - // getEdgeCounts - This method is used by consumers of edge counting
> > - // information.
> > - //
> > - const std::vector<unsigned> &getRawEdgeCounts() const {
> > - return EdgeCounts;
> > - }
> > -
> > - // getEdgeOptimalCounts - This method is used by consumers of optimal
> edge
> > - // counting information.
> > - //
> > - const std::vector<unsigned> &getRawOptimalEdgeCounts() const {
> > - return OptimalEdgeCounts;
> > - }
> > -
> > -};
> > -
> > -} // End llvm namespace
> > -
> > -#endif
> >
> > Removed: llvm/trunk/include/llvm/Analysis/ProfileInfoTypes.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ProfileInfoTypes.h?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/ProfileInfoTypes.h (original)
> > +++ llvm/trunk/include/llvm/Analysis/ProfileInfoTypes.h (removed)
> > @@ -1,52 +0,0 @@
> > -/*===-- ProfileInfoTypes.h - Profiling info shared constants
> --------------===*\
> > -|*
> > -|* The LLVM Compiler Infrastructure
> > -|*
> > -|* This file is distributed under the University of Illinois Open Source
> > -|* License. See LICENSE.TXT for details.
> > -|*
> >
> -|*===----------------------------------------------------------------------===*|
> > -|*
> > -|* This file defines constants shared by the various different profiling
> > -|* runtime libraries and the LLVM C++ profile info loader. It must be a
> > -|* C header because, at present, the profiling runtimes are written in
> C.
> > -|*
> >
> -\*===----------------------------------------------------------------------===*/
> > -
> > -#ifndef LLVM_ANALYSIS_PROFILEINFOTYPES_H
> > -#define LLVM_ANALYSIS_PROFILEINFOTYPES_H
> > -
> > -/* Included by libprofile. */
> > -#if defined(__cplusplus)
> > -extern "C" {
> > -#endif
> > -
> > -/* IDs to distinguish between those path counters stored in hashses vs
> arrays */
> > -enum ProfilingStorageType {
> > - ProfilingArray = 1,
> > - ProfilingHash = 2
> > -};
> > -
> > -#include "llvm/Analysis/ProfileDataTypes.h"
> > -
> > -/*
> > - * The header for tables that map path numbers to path counters.
> > - */
> > -typedef struct {
> > - unsigned fnNumber; /* function number for these counters */
> > - unsigned numEntries; /* number of entries stored */
> > -} PathProfileHeader;
> > -
> > -/*
> > - * Describes an entry in a tagged table for path counters.
> > - */
> > -typedef struct {
> > - unsigned pathNumber;
> > - unsigned pathCounter;
> > -} PathProfileTableEntry;
> > -
> > -#if defined(__cplusplus)
> > -}
> > -#endif
> > -
> > -#endif /* LLVM_ANALYSIS_PROFILEINFOTYPES_H */
> >
> > Modified: llvm/trunk/include/llvm/InitializePasses.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/InitializePasses.h (original)
> > +++ llvm/trunk/include/llvm/InitializePasses.h Wed Oct 2 10:42:23 2013
> > @@ -113,9 +113,7 @@ void initializeDominanceFrontierPass(Pas
> > void initializeDominatorTreePass(PassRegistry&);
> > void initializeEarlyIfConverterPass(PassRegistry&);
> > void initializeEdgeBundlesPass(PassRegistry&);
> > -void initializeEdgeProfilerPass(PassRegistry&);
> > void initializeExpandPostRAPass(PassRegistry&);
> > -void initializePathProfilerPass(PassRegistry&);
> > void initializeGCOVProfilerPass(PassRegistry&);
> > void initializeAddressSanitizerPass(PassRegistry&);
> > void initializeAddressSanitizerModulePass(PassRegistry&);
> > @@ -155,8 +153,6 @@ void initializeLiveRegMatrixPass(PassReg
> > void initializeLiveStacksPass(PassRegistry&);
> > void initializeLiveVariablesPass(PassRegistry&);
> > void initializeLoaderPassPass(PassRegistry&);
> > -void initializeProfileMetadataLoaderPassPass(PassRegistry&);
> > -void initializePathProfileLoaderPassPass(PassRegistry&);
> > void initializeLocalStackSlotPassPass(PassRegistry&);
> > void initializeLoopDeletionPass(PassRegistry&);
> > void initializeLoopExtractorPass(PassRegistry&);
> > @@ -195,14 +191,11 @@ void initializeMetaRenamerPass(PassRegis
> > void initializeMergeFunctionsPass(PassRegistry&);
> > void initializeModuleDebugInfoPrinterPass(PassRegistry&);
> > void initializeNoAAPass(PassRegistry&);
> > -void initializeNoProfileInfoPass(PassRegistry&);
> > -void initializeNoPathProfileInfoPass(PassRegistry&);
> > void initializeObjCARCAliasAnalysisPass(PassRegistry&);
> > void initializeObjCARCAPElimPass(PassRegistry&);
> > void initializeObjCARCExpandPass(PassRegistry&);
> > void initializeObjCARCContractPass(PassRegistry&);
> > void initializeObjCARCOptPass(PassRegistry&);
> > -void initializeOptimalEdgeProfilerPass(PassRegistry&);
> > void initializeOptimizePHIsPass(PassRegistry&);
> > void initializePartiallyInlineLibCallsPass(PassRegistry&);
> > void initializePEIPass(PassRegistry&);
> > @@ -220,11 +213,6 @@ void initializePrintFunctionPassPass(Pas
> > void initializePrintModulePassPass(PassRegistry&);
> > void initializePrintBasicBlockPassPass(PassRegistry&);
> > void initializeProcessImplicitDefsPass(PassRegistry&);
> > -void initializeProfileEstimatorPassPass(PassRegistry&);
> > -void initializeProfileInfoAnalysisGroup(PassRegistry&);
> > -void initializePathProfileInfoAnalysisGroup(PassRegistry&);
> > -void initializePathProfileVerifierPass(PassRegistry&);
> > -void initializeProfileVerifierPassPass(PassRegistry&);
> > void initializePromotePassPass(PassRegistry&);
> > void initializePruneEHPass(PassRegistry&);
> > void initializeReassociatePass(PassRegistry&);
> >
> > Modified: llvm/trunk/include/llvm/LinkAllPasses.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/LinkAllPasses.h (original)
> > +++ llvm/trunk/include/llvm/LinkAllPasses.h Wed Oct 2 10:42:23 2013
> > @@ -74,9 +74,6 @@ namespace {
> > (void) llvm::createDomPrinterPass();
> > (void) llvm::createDomOnlyViewerPass();
> > (void) llvm::createDomViewerPass();
> > - (void) llvm::createEdgeProfilerPass();
> > - (void) llvm::createOptimalEdgeProfilerPass();
> > - (void) llvm::createPathProfilerPass();
> > (void) llvm::createGCOVProfilerPass();
> > (void) llvm::createFunctionInliningPass();
> > (void) llvm::createAlwaysInlinerPass();
> > @@ -102,18 +99,11 @@ namespace {
> > (void) llvm::createLowerInvokePass();
> > (void) llvm::createLowerSwitchPass();
> > (void) llvm::createNoAAPass();
> > - (void) llvm::createNoProfileInfoPass();
> > (void) llvm::createObjCARCAliasAnalysisPass();
> > (void) llvm::createObjCARCAPElimPass();
> > (void) llvm::createObjCARCExpandPass();
> > (void) llvm::createObjCARCContractPass();
> > (void) llvm::createObjCARCOptPass();
> > - (void) llvm::createProfileEstimatorPass();
> > - (void) llvm::createProfileVerifierPass();
> > - (void) llvm::createPathProfileVerifierPass();
> > - (void) llvm::createProfileLoaderPass();
> > - (void) llvm::createProfileMetadataLoaderPass();
> > - (void) llvm::createPathProfileLoaderPass();
> > (void) llvm::createPromoteMemoryToRegisterPass();
> > (void) llvm::createDemoteRegisterToMemoryPass();
> > (void) llvm::createPruneEHPass();
> >
> > Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)
> > +++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Wed Oct 2
> 10:42:23 2013
> > @@ -35,15 +35,6 @@ namespace llvm {
> > class ModulePass;
> > class FunctionPass;
> >
> > -// Insert edge profiling instrumentation
> > -ModulePass *createEdgeProfilerPass();
> > -
> > -// Insert optimal edge profiling instrumentation
> > -ModulePass *createOptimalEdgeProfilerPass();
> > -
> > -// Insert path profiling instrumentation
> > -ModulePass *createPathProfilerPass();
> > -
> > // Insert GCOV profiling instrumentation
> > struct GCOVOptions {
> > static GCOVOptions getDefault();
> >
> > Modified: llvm/trunk/lib/Analysis/Analysis.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Analysis.cpp?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/Analysis.cpp (original)
> > +++ llvm/trunk/lib/Analysis/Analysis.cpp Wed Oct 2 10:42:23 2013
> > @@ -54,16 +54,6 @@ void llvm::initializeAnalysis(PassRegist
> > 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);
> >
> > Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
> > +++ llvm/trunk/lib/Analysis/CMakeLists.txt Wed Oct 2 10:42:23 2013
> > @@ -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
> >
> > Removed: llvm/trunk/lib/Analysis/PathNumbering.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PathNumbering.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/PathNumbering.cpp (original)
> > +++ llvm/trunk/lib/Analysis/PathNumbering.cpp (removed)
> > @@ -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);
> > -}
> >
> > Removed: llvm/trunk/lib/Analysis/PathProfileInfo.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PathProfileInfo.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/PathProfileInfo.cpp (original)
> > +++ llvm/trunk/lib/Analysis/PathProfileInfo.cpp (removed)
> > @@ -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(); }
> >
> > Removed: llvm/trunk/lib/Analysis/PathProfileVerifier.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PathProfileVerifier.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/PathProfileVerifier.cpp (original)
> > +++ llvm/trunk/lib/Analysis/PathProfileVerifier.cpp (removed)
> > @@ -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;
> > -}
> >
> > Removed: llvm/trunk/lib/Analysis/ProfileDataLoader.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileDataLoader.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/ProfileDataLoader.cpp (original)
> > +++ llvm/trunk/lib/Analysis/ProfileDataLoader.cpp (removed)
> > @@ -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);
> > -}
> >
> > Removed: llvm/trunk/lib/Analysis/ProfileDataLoaderPass.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileDataLoaderPass.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/ProfileDataLoaderPass.cpp (original)
> > +++ llvm/trunk/lib/Analysis/ProfileDataLoaderPass.cpp (removed)
> > @@ -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;
> > -}
> >
> > Removed: llvm/trunk/lib/Analysis/ProfileEstimatorPass.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileEstimatorPass.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/ProfileEstimatorPass.cpp (original)
> > +++ llvm/trunk/lib/Analysis/ProfileEstimatorPass.cpp (removed)
> > @@ -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;
> > -}
> >
> > Removed: llvm/trunk/lib/Analysis/ProfileInfo.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileInfo.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/ProfileInfo.cpp (original)
> > +++ llvm/trunk/lib/Analysis/ProfileInfo.cpp (removed)
> > @@ -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(); }
> >
> > Removed: llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp (original)
> > +++ llvm/trunk/lib/Analysis/ProfileInfoLoader.cpp (removed)
> > @@ -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);
> > -}
> > -
> >
> > Removed: llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp (original)
> > +++ llvm/trunk/lib/Analysis/ProfileInfoLoaderPass.cpp (removed)
> > @@ -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;
> > -}
> >
> > Removed: llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp (original)
> > +++ llvm/trunk/lib/Analysis/ProfileVerifierPass.cpp (removed)
> > @@ -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);
> > - }
> > -}
> > -
> >
> > Modified: llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp (original)
> > +++ llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp Wed Oct 2 10:42:23
> 2013
> > @@ -24,7 +24,6 @@
> > #include "llvm/ADT/DepthFirstIterator.h"
> > #include "llvm/ADT/SmallPtrSet.h"
> > #include "llvm/Analysis/Dominators.h"
> > -#include "llvm/Analysis/ProfileInfo.h"
> > #include "llvm/CodeGen/MachineDominators.h"
> > #include "llvm/CodeGen/MachineFunctionPass.h"
> > #include "llvm/CodeGen/MachineLoopInfo.h"
> > @@ -50,7 +49,6 @@ namespace {
> >
> > virtual void getAnalysisUsage(AnalysisUsage &AU) const {
> > AU.addPreserved<DominatorTree>();
> > - AU.addPreserved<ProfileInfo>();
> > }
> > };
> > }
> > @@ -87,9 +85,7 @@ bool UnreachableBlockElim::runOnFunction
> > }
> >
> > // Actually remove the blocks now.
> > - ProfileInfo *PI = getAnalysisIfAvailable<ProfileInfo>();
> > for (unsigned i = 0, e = DeadBlocks.size(); i != e; ++i) {
> > - if (PI) PI->removeBlock(DeadBlocks[i]);
> > DeadBlocks[i]->eraseFromParent();
> > }
> >
> >
> > Modified: llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt (original)
> > +++ llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt Wed Oct 2
> 10:42:23 2013
> > @@ -3,12 +3,9 @@ add_llvm_library(LLVMInstrumentation
> > BoundsChecking.cpp
> > DataFlowSanitizer.cpp
> > DebugIR.cpp
> > - EdgeProfiling.cpp
> > GCOVProfiling.cpp
> > MemorySanitizer.cpp
> > Instrumentation.cpp
> > - OptimalEdgeProfiling.cpp
> > - PathProfiling.cpp
> > ProfilingUtils.cpp
> > ThreadSanitizer.cpp
> > )
> >
> > Removed: llvm/trunk/lib/Transforms/Instrumentation/EdgeProfiling.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/EdgeProfiling.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Instrumentation/EdgeProfiling.cpp
> (original)
> > +++ llvm/trunk/lib/Transforms/Instrumentation/EdgeProfiling.cpp (removed)
> > @@ -1,117 +0,0 @@
> > -//===- EdgeProfiling.cpp - Insert counters for edge profiling
> -------------===//
> > -//
> > -// The LLVM Compiler Infrastructure
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -//
> > -// This pass instruments the specified program with counters for edge
> profiling.
> > -// Edge profiling can give a reasonable approximation of the hot paths
> through a
> > -// program, and is used for a wide variety of program transformations.
> > -//
> > -// Note that this implementation is very naive. We insert a counter
> for *every*
> > -// edge in the program, instead of using control flow information to
> prune the
> > -// number of counters inserted.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -#define DEBUG_TYPE "insert-edge-profiling"
> > -
> > -#include "llvm/Transforms/Instrumentation.h"
> > -#include "ProfilingUtils.h"
> > -#include "llvm/ADT/Statistic.h"
> > -#include "llvm/IR/Module.h"
> > -#include "llvm/Pass.h"
> > -#include "llvm/Support/raw_ostream.h"
> > -#include "llvm/Transforms/Utils/BasicBlockUtils.h"
> > -#include <set>
> > -using namespace llvm;
> > -
> > -STATISTIC(NumEdgesInserted, "The # of edges inserted.");
> > -
> > -namespace {
> > - class EdgeProfiler : public ModulePass {
> > - bool runOnModule(Module &M);
> > - public:
> > - static char ID; // Pass identification, replacement for typeid
> > - EdgeProfiler() : ModulePass(ID) {
> > - initializeEdgeProfilerPass(*PassRegistry::getPassRegistry());
> > - }
> > -
> > - virtual const char *getPassName() const {
> > - return "Edge Profiler";
> > - }
> > - };
> > -}
> > -
> > -char EdgeProfiler::ID = 0;
> > -INITIALIZE_PASS(EdgeProfiler, "insert-edge-profiling",
> > - "Insert instrumentation for edge profiling", false,
> false)
> > -
> > -ModulePass *llvm::createEdgeProfilerPass() { return new EdgeProfiler();
> }
> > -
> > -bool EdgeProfiler::runOnModule(Module &M) {
> > - Function *Main = M.getFunction("main");
> > - if (Main == 0) {
> > - errs() << "WARNING: cannot insert edge profiling into a module"
> > - << " with no main function!\n";
> > - return false; // No main, no instrumentation!
> > - }
> > -
> > - std::set<BasicBlock*> BlocksToInstrument;
> > - unsigned NumEdges = 0;
> > - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
> > - if (F->isDeclaration()) continue;
> > - // Reserve space for (0,entry) edge.
> > - ++NumEdges;
> > - for (Function::iterator BB = F->begin(), E = F->end(); BB != E;
> ++BB) {
> > - // Keep track of which blocks need to be instrumented. We don't
> want to
> > - // instrument blocks that are added as the result of breaking
> critical
> > - // edges!
> > - BlocksToInstrument.insert(BB);
> > - NumEdges += BB->getTerminator()->getNumSuccessors();
> > - }
> > - }
> > -
> > - Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()),
> NumEdges);
> > - GlobalVariable *Counters =
> > - new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
> > - Constant::getNullValue(ATy), "EdgeProfCounters");
> > - NumEdgesInserted = NumEdges;
> > -
> > - // Instrument all of the edges...
> > - unsigned i = 0;
> > - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
> > - if (F->isDeclaration()) continue;
> > - // Create counter for (0,entry) edge.
> > - IncrementCounterInBlock(&F->getEntryBlock(), i++, Counters);
> > - for (Function::iterator BB = F->begin(), E = F->end(); BB != E;
> ++BB)
> > - if (BlocksToInstrument.count(BB)) { // Don't instrument inserted
> blocks
> > - // Okay, we have to add a counter of each outgoing edge. If the
> > - // outgoing edge is not critical don't split it, just insert
> the counter
> > - // in the source or destination of the edge.
> > - TerminatorInst *TI = BB->getTerminator();
> > - for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
> > - // If the edge is critical, split it.
> > - SplitCriticalEdge(TI, s, this);
> > -
> > - // Okay, we are guaranteed that the edge is no longer
> critical. If we
> > - // only have a single successor, insert the counter in this
> block,
> > - // otherwise insert it in the successor block.
> > - if (TI->getNumSuccessors() == 1) {
> > - // Insert counter at the start of the block
> > - IncrementCounterInBlock(BB, i++, Counters, false);
> > - } else {
> > - // Insert counter at the start of the block
> > - IncrementCounterInBlock(TI->getSuccessor(s), i++, Counters);
> > - }
> > - }
> > - }
> > - }
> > -
> > - // Add the initialization call to main.
> > - InsertProfilingInitCall(Main, "llvm_start_edge_profiling", Counters);
> > - return true;
> > -}
> > -
> >
> > Modified: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
> (original)
> > +++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp Wed
> Oct 2 10:42:23 2013
> > @@ -24,10 +24,7 @@ void llvm::initializeInstrumentation(Pas
> > initializeAddressSanitizerPass(Registry);
> > initializeAddressSanitizerModulePass(Registry);
> > initializeBoundsCheckingPass(Registry);
> > - initializeEdgeProfilerPass(Registry);
> > initializeGCOVProfilerPass(Registry);
> > - initializeOptimalEdgeProfilerPass(Registry);
> > - initializePathProfilerPass(Registry);
> > initializeMemorySanitizerPass(Registry);
> > initializeThreadSanitizerPass(Registry);
> > initializeDataFlowSanitizerPass(Registry);
> >
> > Removed:
> llvm/trunk/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp
> (original)
> > +++ llvm/trunk/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp
> (removed)
> > @@ -1,225 +0,0 @@
> > -//===- OptimalEdgeProfiling.cpp - Insert counters for opt. edge
> profiling -===//
> > -//
> > -// The LLVM Compiler Infrastructure
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -//
> > -// This pass instruments the specified program with counters for edge
> profiling.
> > -// Edge profiling can give a reasonable approximation of the hot paths
> through a
> > -// program, and is used for a wide variety of program transformations.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -#define DEBUG_TYPE "insert-optimal-edge-profiling"
> > -#include "llvm/Transforms/Instrumentation.h"
> > -#include "MaximumSpanningTree.h"
> > -#include "ProfilingUtils.h"
> > -#include "llvm/ADT/DenseSet.h"
> > -#include "llvm/ADT/Statistic.h"
> > -#include "llvm/Analysis/Passes.h"
> > -#include "llvm/Analysis/ProfileInfo.h"
> > -#include "llvm/Analysis/ProfileInfoLoader.h"
> > -#include "llvm/IR/Constants.h"
> > -#include "llvm/IR/Module.h"
> > -#include "llvm/Pass.h"
> > -#include "llvm/Support/Debug.h"
> > -#include "llvm/Support/raw_ostream.h"
> > -#include "llvm/Transforms/Utils/BasicBlockUtils.h"
> > -using namespace llvm;
> > -
> > -STATISTIC(NumEdgesInserted, "The # of edges inserted.");
> > -
> > -namespace {
> > - class OptimalEdgeProfiler : public ModulePass {
> > - bool runOnModule(Module &M);
> > - public:
> > - static char ID; // Pass identification, replacement for typeid
> > - OptimalEdgeProfiler() : ModulePass(ID) {
> > -
> initializeOptimalEdgeProfilerPass(*PassRegistry::getPassRegistry());
> > - }
> > -
> > - void getAnalysisUsage(AnalysisUsage &AU) const {
> > - AU.addRequiredID(ProfileEstimatorPassID);
> > - AU.addRequired<ProfileInfo>();
> > - }
> > -
> > - virtual const char *getPassName() const {
> > - return "Optimal Edge Profiler";
> > - }
> > - };
> > -}
> > -
> > -char OptimalEdgeProfiler::ID = 0;
> > -INITIALIZE_PASS_BEGIN(OptimalEdgeProfiler,
> "insert-optimal-edge-profiling",
> > - "Insert optimal instrumentation for edge profiling",
> > - false, false)
> > -INITIALIZE_PASS_DEPENDENCY(ProfileEstimatorPass)
> > -INITIALIZE_AG_DEPENDENCY(ProfileInfo)
> > -INITIALIZE_PASS_END(OptimalEdgeProfiler,
> "insert-optimal-edge-profiling",
> > - "Insert optimal instrumentation for edge profiling",
> > - false, false)
> > -
> > -ModulePass *llvm::createOptimalEdgeProfilerPass() {
> > - return new OptimalEdgeProfiler();
> > -}
> > -
> > -inline static void printEdgeCounter(ProfileInfo::Edge e,
> > - BasicBlock* b,
> > - unsigned i) {
> > - DEBUG(dbgs() << "--Edge Counter for " << (e) << " in " \
> > - << ((b)?(b)->getName():"0") << " (# " << (i) << ")\n");
> > -}
> > -
> > -bool OptimalEdgeProfiler::runOnModule(Module &M) {
> > - Function *Main = M.getFunction("main");
> > - if (Main == 0) {
> > - errs() << "WARNING: cannot insert edge profiling into a module"
> > - << " with no main function!\n";
> > - return false; // No main, no instrumentation!
> > - }
> > -
> > - // NumEdges counts all the edges that may be instrumented. Later on
> its
> > - // decided which edges to actually instrument, to achieve optimal
> profiling.
> > - // For the entry block a virtual edge (0,entry) is reserved, for each
> block
> > - // with no successors an edge (BB,0) is reserved. These edges are
> necessary
> > - // to calculate a truly optimal maximum spanning tree and thus an
> optimal
> > - // instrumentation.
> > - unsigned NumEdges = 0;
> > -
> > - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
> > - if (F->isDeclaration()) continue;
> > - // Reserve space for (0,entry) edge.
> > - ++NumEdges;
> > - for (Function::iterator BB = F->begin(), E = F->end(); BB != E;
> ++BB) {
> > - // Keep track of which blocks need to be instrumented. We don't
> want to
> > - // instrument blocks that are added as the result of breaking
> critical
> > - // edges!
> > - if (BB->getTerminator()->getNumSuccessors() == 0) {
> > - // Reserve space for (BB,0) edge.
> > - ++NumEdges;
> > - } else {
> > - NumEdges += BB->getTerminator()->getNumSuccessors();
> > - }
> > - }
> > - }
> > -
> > - // In the profiling output a counter for each edge is reserved, but
> only few
> > - // are used. This is done to be able to read back in the profile
> without
> > - // calulating the maximum spanning tree again, instead each edge
> counter that
> > - // is not used is initialised with -1 to signal that this edge
> counter has to
> > - // be calculated from other edge counters on reading the profile info
> back
> > - // in.
> > -
> > - Type *Int32 = Type::getInt32Ty(M.getContext());
> > - ArrayType *ATy = ArrayType::get(Int32, NumEdges);
> > - GlobalVariable *Counters =
> > - new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
> > - Constant::getNullValue(ATy),
> "OptEdgeProfCounters");
> > - NumEdgesInserted = 0;
> > -
> > - std::vector<Constant*> Initializer(NumEdges);
> > - Constant *Zero = ConstantInt::get(Int32, 0);
> > - Constant *Uncounted = ConstantInt::get(Int32,
> ProfileInfoLoader::Uncounted);
> > -
> > - // Instrument all of the edges not in MST...
> > - unsigned i = 0;
> > - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
> > - if (F->isDeclaration()) continue;
> > - DEBUG(dbgs() << "Working on " << F->getName() << "\n");
> > -
> > - // Calculate a Maximum Spanning Tree with the edge weights
> determined by
> > - // ProfileEstimator. ProfileEstimator also assign weights to the
> virtual
> > - // edges (0,entry) and (BB,0) (for blocks with no successors) and
> this
> > - // edges also participate in the maximum spanning tree calculation.
> > - // The third parameter of MaximumSpanningTree() has the effect that
> not the
> > - // actual MST is returned but the edges _not_ in the MST.
> > -
> > - ProfileInfo::EdgeWeights ECs =
> > - getAnalysis<ProfileInfo>(*F).getEdgeWeights(F);
> > - std::vector<ProfileInfo::EdgeWeight> EdgeVector(ECs.begin(),
> ECs.end());
> > - MaximumSpanningTree<BasicBlock> MST(EdgeVector);
> > - std::stable_sort(MST.begin(), MST.end());
> > -
> > - // Check if (0,entry) not in the MST. If not, instrument edge
> > - // (IncrementCounterInBlock()) and set the counter initially to
> zero, if
> > - // the edge is in the MST the counter is initialised to -1.
> > -
> > - BasicBlock *entry = &(F->getEntryBlock());
> > - ProfileInfo::Edge edge = ProfileInfo::getEdge(0, entry);
> > - if (!std::binary_search(MST.begin(), MST.end(), edge)) {
> > - printEdgeCounter(edge, entry, i);
> > - IncrementCounterInBlock(entry, i, Counters); ++NumEdgesInserted;
> > - Initializer[i++] = (Zero);
> > - } else{
> > - Initializer[i++] = (Uncounted);
> > - }
> > -
> > - // InsertedBlocks contains all blocks that were inserted for
> splitting an
> > - // edge, this blocks do not have to be instrumented.
> > - DenseSet<BasicBlock*> InsertedBlocks;
> > - for (Function::iterator BB = F->begin(), E = F->end(); BB != E;
> ++BB) {
> > - // Check if block was not inserted and thus does not have to be
> > - // instrumented.
> > - if (InsertedBlocks.count(BB)) continue;
> > -
> > - // Okay, we have to add a counter of each outgoing edge not in
> MST. If
> > - // the outgoing edge is not critical don't split it, just insert
> the
> > - // counter in the source or destination of the edge. Also, if the
> block
> > - // has no successors, the virtual edge (BB,0) is processed.
> > - TerminatorInst *TI = BB->getTerminator();
> > - if (TI->getNumSuccessors() == 0) {
> > - ProfileInfo::Edge edge = ProfileInfo::getEdge(BB, 0);
> > - if (!std::binary_search(MST.begin(), MST.end(), edge)) {
> > - printEdgeCounter(edge, BB, i);
> > - IncrementCounterInBlock(BB, i, Counters); ++NumEdgesInserted;
> > - Initializer[i++] = (Zero);
> > - } else{
> > - Initializer[i++] = (Uncounted);
> > - }
> > - }
> > - for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
> > - BasicBlock *Succ = TI->getSuccessor(s);
> > - ProfileInfo::Edge edge = ProfileInfo::getEdge(BB,Succ);
> > - if (!std::binary_search(MST.begin(), MST.end(), edge)) {
> > -
> > - // If the edge is critical, split it.
> > - bool wasInserted = SplitCriticalEdge(TI, s, this);
> > - Succ = TI->getSuccessor(s);
> > - if (wasInserted)
> > - InsertedBlocks.insert(Succ);
> > -
> > - // Okay, we are guaranteed that the edge is no longer
> critical. If
> > - // we only have a single successor, insert the counter in
> this block,
> > - // otherwise insert it in the successor block.
> > - if (TI->getNumSuccessors() == 1) {
> > - // Insert counter at the start of the block
> > - printEdgeCounter(edge, BB, i);
> > - IncrementCounterInBlock(BB, i, Counters);
> ++NumEdgesInserted;
> > - } else {
> > - // Insert counter at the start of the block
> > - printEdgeCounter(edge, Succ, i);
> > - IncrementCounterInBlock(Succ, i, Counters);
> ++NumEdgesInserted;
> > - }
> > - Initializer[i++] = (Zero);
> > - } else {
> > - Initializer[i++] = (Uncounted);
> > - }
> > - }
> > - }
> > - }
> > -
> > - // Check if the number of edges counted at first was the number of
> edges we
> > - // considered for instrumentation.
> > - assert(i == NumEdges && "the number of edges in counting array is
> wrong");
> > -
> > - // Assign the now completely defined initialiser to the array.
> > - Constant *init = ConstantArray::get(ATy, Initializer);
> > - Counters->setInitializer(init);
> > -
> > - // Add the initialization call to main.
> > - InsertProfilingInitCall(Main, "llvm_start_opt_edge_profiling",
> Counters);
> > - return true;
> > -}
> > -
> >
> > Removed: llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp?rev=191834&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp
> (original)
> > +++ llvm/trunk/lib/Transforms/Instrumentation/PathProfiling.cpp (removed)
> > @@ -1,1424 +0,0 @@
> > -//===- PathProfiling.cpp - Inserts counters for path profiling
> ------------===//
> > -//
> > -// The LLVM Compiler Infrastructure
> > -//
> > -// This file is distributed under the University of Illinois Open Source
> > -// License. See LICENSE.TXT for details.
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -//
> > -// This pass instruments functions for Ball-Larus path profiling.
> Ball-Larus
> > -// profiling converts the CFG into a DAG by replacing backedges with
> edges
> > -// from entry to the start block and from the end block to exit. The
> paths
> > -// along the new DAG are enumrated, i.e. each path is given a path
> number.
> > -// Edges are instrumented to increment the path number register, such
> that the
> > -// path number register will equal the path number of the path taken at
> the
> > -// exit.
> > -//
> > -// This file defines classes for building a CFG for use with different
> stages
> > -// in the Ball-Larus path profiling instrumentation [Ball96]. The
> > -// requirements are formatting the llvm CFG into the Ball-Larus DAG,
> path
> > -// numbering, finding a spanning tree, moving increments from the
> spanning
> > -// tree to chords.
> > -//
> > -// Terms:
> > -// DAG - Directed Acyclic Graph.
> > -// Ball-Larus DAG - A CFG with an entry node, an exit node, and
> backedges
> > -// removed in the following manner. For every backedge
> > -// v->w, insert edge ENTRY->w and edge v->EXIT.
> > -// Path Number - The number corresponding to a specific path through
> a
> > -// Ball-Larus DAG.
> > -// Spanning Tree - A subgraph, S, is a spanning tree if S covers all
> > -// vertices and is a tree.
> > -// Chord - An edge not in the spanning tree.
> > -//
> > -// [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
> > -//
> > -// [Ball94]
> > -// Thomas Ball. "Efficiently Counting Program Events with Support for
> > -// On-line queries."
> > -// ACM Transactions on Programmmg Languages and Systems, Vol 16, No 5,
> > -// September 1994, Pages 1399-1410.
> >
> -//===----------------------------------------------------------------------===//
> > -#define DEBUG_TYPE "insert-path-profiling"
> > -
> > -#include "llvm/Transforms/Instrumentation.h"
> > -#include "ProfilingUtils.h"
> > -#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/LLVMContext.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 "llvm/Transforms/Utils/BasicBlockUtils.h"
> > -#include <vector>
> > -
> > -#define HASH_THRESHHOLD 100000
> > -
> > -using namespace llvm;
> > -
> > -namespace {
> > -class BLInstrumentationNode;
> > -class BLInstrumentationEdge;
> > -class BLInstrumentationDag;
> > -
> > -//
> ---------------------------------------------------------------------------
> > -// BLInstrumentationNode extends BallLarusNode with member used by the
> > -// instrumentation algortihms.
> > -//
> ---------------------------------------------------------------------------
> > -class BLInstrumentationNode : public BallLarusNode {
> > -public:
> > - // Creates a new BLInstrumentationNode from a BasicBlock.
> > - BLInstrumentationNode(BasicBlock* BB);
> > -
> > - // Get/sets the Value corresponding to the pathNumber register,
> > - // constant or phinode. Used by the instrumentation code to remember
> > - // path number Values.
> > - Value* getStartingPathNumber();
> > - void setStartingPathNumber(Value* pathNumber);
> > -
> > - Value* getEndingPathNumber();
> > - void setEndingPathNumber(Value* pathNumber);
> > -
> > - // Get/set the PHINode Instruction for this node.
> > - PHINode* getPathPHI();
> > - void setPathPHI(PHINode* pathPHI);
> > -
> > -private:
> > -
> > - Value* _startingPathNumber; // The Value for the current pathNumber.
> > - Value* _endingPathNumber; // The Value for the current pathNumber.
> > - PHINode* _pathPHI; // The PHINode for current pathNumber.
> > -};
> > -
> > -//
> --------------------------------------------------------------------------
> > -// BLInstrumentationEdge extends BallLarusEdge with data about the
> > -// instrumentation that will end up on each edge.
> > -//
> --------------------------------------------------------------------------
> > -class BLInstrumentationEdge : public BallLarusEdge {
> > -public:
> > - BLInstrumentationEdge(BLInstrumentationNode* source,
> > - BLInstrumentationNode* target);
> > -
> > - // Sets the target node of this edge. Required to split edges.
> > - void setTarget(BallLarusNode* node);
> > -
> > - // Get/set whether edge is in the spanning tree.
> > - bool isInSpanningTree() const;
> > - void setIsInSpanningTree(bool isInSpanningTree);
> > -
> > - // Get/ set whether this edge will be instrumented with a path number
> > - // initialization.
> > - bool isInitialization() const;
> > - void setIsInitialization(bool isInitialization);
> > -
> > - // Get/set whether this edge will be instrumented with a path counter
> > - // increment. Notice this is incrementing the path counter
> > - // corresponding to the path number register. The path number
> > - // increment is determined by getIncrement().
> > - bool isCounterIncrement() const;
> > - void setIsCounterIncrement(bool isCounterIncrement);
> > -
> > - // Get/set the path number increment that this edge will be
> instrumented
> > - // with. This is distinct from the path counter increment and the
> > - // weight. The counter increment counts the number of executions of
> > - // some path, whereas the path number keeps track of which path number
> > - // the program is on.
> > - long getIncrement() const;
> > - void setIncrement(long increment);
> > -
> > - // Get/set whether the edge has been instrumented.
> > - bool hasInstrumentation();
> > - void setHasInstrumentation(bool hasInstrumentation);
> > -
> > - // Returns the successor number of this edge in the source.
> > - unsigned getSuccessorNumber();
> > -
> > -private:
> > - // The increment that the code will be instrumented with.
> > - long long _increment;
> > -
> > - // Whether this edge is in the spanning tree.
> > - bool _isInSpanningTree;
> > -
> > - // Whether this edge is an initialiation of the path number.
> > - bool _isInitialization;
> > -
> > - // Whether this edge is a path counter increment.
> > - bool _isCounterIncrement;
> > -
> > - // Whether this edge has been instrumented.
> > - bool _hasInstrumentation;
> > -};
> > -
> > -//
> ---------------------------------------------------------------------------
> > -// BLInstrumentationDag extends BallLarusDag with algorithms that
> > -// determine where instrumentation should be placed.
> > -//
> ---------------------------------------------------------------------------
> > -class BLInstrumentationDag : public BallLarusDag {
> > -public:
> > - BLInstrumentationDag(Function &F);
> > -
> > - // Returns the Exit->Root edge. This edge is required for creating
> > - // directed cycles in the algorithm for moving instrumentation off of
> > - // the spanning tree
> > - BallLarusEdge* getExitRootEdge();
> > -
> > - // Returns an array of phony edges which mark those nodes
> > - // with function calls
> > - BLEdgeVector getCallPhonyEdges();
> > -
> > - // Gets/sets the path counter array
> > - GlobalVariable* getCounterArray();
> > - void setCounterArray(GlobalVariable* c);
> > -
> > - // Calculates the increments for the chords, thereby removing
> > - // instrumentation from the spanning tree edges. Implementation is
> based
> > - // on the algorithm in Figure 4 of [Ball94]
> > - void calculateChordIncrements();
> > -
> > - // Updates the state when an edge has been split
> > - void splitUpdate(BLInstrumentationEdge* formerEdge, BasicBlock*
> newBlock);
> > -
> > - // Calculates a spanning tree of the DAG ignoring cycles. Whichever
> > - // edges are in the spanning tree will not be instrumented, but this
> > - // implementation does not try to minimize the instrumentation
> overhead
> > - // by trying to find hot edges.
> > - void calculateSpanningTree();
> > -
> > - // Pushes initialization further down in order to group the first
> > - // increment and initialization.
> > - void pushInitialization();
> > -
> > - // Pushes the path counter increments up in order to group the last
> path
> > - // number increment.
> > - void pushCounters();
> > -
> > - // Removes phony edges from the successor list of the source, and the
> > - // predecessor list of the target.
> > - void unlinkPhony();
> > -
> > - // Generate dot graph for the function
> > - void generateDotGraph();
> > -
> > -protected:
> > - // BLInstrumentationDag creates BLInstrumentationNode objects in this
> > - // method overriding the creation of BallLarusNode objects.
> > - //
> > - // Allows subclasses to determine which type of Node is created.
> > - // Override this method to produce subclasses of BallLarusNode if
> > - // necessary.
> > - virtual BallLarusNode* createNode(BasicBlock* BB);
> > -
> > - // BLInstrumentationDag create BLInstrumentationEdges.
> > - //
> > - // Allows subclasses to determine which type of Edge is created.
> > - // Override this method to produce subclasses of BallLarusEdge if
> > - // necessary. Parameters source and target will have been created by
> > - // createNode and can be cast to the subclass of BallLarusNode*
> > - // returned by createNode.
> > - virtual BallLarusEdge* createEdge(
> > - BallLarusNode* source, BallLarusNode* target, unsigned edgeNumber);
> > -
> > -private:
> > - BLEdgeVector _treeEdges; // All edges in the spanning tree.
> > - BLEdgeVector _chordEdges; // All edges not in the spanning tree.
> > - GlobalVariable* _counterArray; // Array to store path counters
> > -
> > - // Removes the edge from the appropriate predecessor and successor
> lists.
> > - void unlinkEdge(BallLarusEdge* edge);
> > -
> > - // Makes an edge part of the spanning tree.
> > - void makeEdgeSpanning(BLInstrumentationEdge* edge);
> > -
> > - // Pushes initialization and calls itself recursively.
> > - void pushInitializationFromEdge(BLInstrumentationEdge* edge);
> > -
> > - // Pushes path counter increments up recursively.
> > - void pushCountersFromEdge(BLInstrumentationEdge* edge);
> > -
> > - // Depth first algorithm for determining the chord increments.f
> > - void calculateChordIncrementsDfs(
> > - long weight, BallLarusNode* v, BallLarusEdge* e);
> > -
> > - // Determines the relative direction of two edges.
> > - int calculateChordIncrementsDir(BallLarusEdge* e, BallLarusEdge* f);
> > -};
> > -
> > -//
> ---------------------------------------------------------------------------
> > -// PathProfiler is a module pass which instruments path profiling
> instructions
> > -//
> ---------------------------------------------------------------------------
> > -class PathProfiler : public ModulePass {
> > -private:
> > - // Current context for multi threading support.
> > - LLVMContext* Context;
> > -
> > - // Which function are we currently instrumenting
> > - unsigned currentFunctionNumber;
> > -
> > - // The function prototype in the profiling runtime for incrementing a
> > - // single path counter in a hash table.
> > - Constant* llvmIncrementHashFunction;
> > - Constant* llvmDecrementHashFunction;
> > -
> > - // Instruments each function with path profiling. 'main' is
> instrumented
> > - // with code to save the profile to disk.
> > - bool runOnModule(Module &M);
> > -
> > - // Analyzes the function for Ball-Larus path profiling, and inserts
> code.
> > - void runOnFunction(std::vector<Constant*> &ftInit, Function &F,
> Module &M);
> > -
> > - // Creates an increment constant representing incr.
> > - ConstantInt* createIncrementConstant(long incr, int bitsize);
> > -
> > - // Creates an increment constant representing the value in
> > - // edge->getIncrement().
> > - ConstantInt* createIncrementConstant(BLInstrumentationEdge* edge);
> > -
> > - // Finds the insertion point after pathNumber in block. PathNumber
> may
> > - // be NULL.
> > - BasicBlock::iterator getInsertionPoint(
> > - BasicBlock* block, Value* pathNumber);
> > -
> > - // Inserts source's pathNumber Value* into target. Target may or may
> not
> > - // have multiple predecessors, and may or may not have its phiNode
> > - // initalized.
> > - void pushValueIntoNode(
> > - BLInstrumentationNode* source, BLInstrumentationNode* target);
> > -
> > - // Inserts source's pathNumber Value* into the appropriate slot of
> > - // target's phiNode.
> > - void pushValueIntoPHI(
> > - BLInstrumentationNode* target, BLInstrumentationNode* source);
> > -
> > - // The Value* in node, oldVal, is updated with a Value*
> correspodning to
> > - // oldVal + addition.
> > - void insertNumberIncrement(BLInstrumentationNode* node, Value*
> addition,
> > - bool atBeginning);
> > -
> > - // Creates a counter increment in the given node. The Value* in node
> is
> > - // taken as the index into a hash table.
> > - void insertCounterIncrement(
> > - Value* incValue,
> > - BasicBlock::iterator insertPoint,
> > - BLInstrumentationDag* dag,
> > - bool increment = true);
> > -
> > - // A PHINode is created in the node, and its values initialized to
> -1U.
> > - void preparePHI(BLInstrumentationNode* node);
> > -
> > - // Inserts instrumentation for the given edge
> > - //
> > - // Pre: The edge's source node has pathNumber set if edge is non zero
> > - // path number increment.
> > - //
> > - // Post: Edge's target node has a pathNumber set to the path number
> Value
> > - // corresponding to the value of the path register after edge's
> > - // execution.
> > - void insertInstrumentationStartingAt(
> > - BLInstrumentationEdge* edge,
> > - BLInstrumentationDag* dag);
> > -
> > - // If this edge is a critical edge, then inserts a node at this edge.
> > - // This edge becomes the first edge, and a new BallLarusEdge is
> created.
> > - bool splitCritical(BLInstrumentationEdge* edge, BLInstrumentationDag*
> dag);
> > -
> > - // Inserts instrumentation according to the marked edges in dag.
> Phony
> > - // edges must be unlinked from the DAG, but accessible from the
> > - // backedges. Dag must have initializations, path number increments,
> and
> > - // counter increments present.
> > - //
> > - // Counter storage is created here.
> > - void insertInstrumentation( BLInstrumentationDag& dag, Module &M);
> > -
> > -public:
> > - static char ID; // Pass identification, replacement for typeid
> > - PathProfiler() : ModulePass(ID) {
> > - initializePathProfilerPass(*PassRegistry::getPassRegistry());
> > - }
> > -
> > - virtual const char *getPassName() const {
> > - return "Path Profiler";
> > - }
> > -};
> > -} // end anonymous namespace
> > -
> > -// Should we print the dot-graphs
> > -static cl::opt<bool> DotPathDag("path-profile-pathdag", cl::Hidden,
> > - cl::desc("Output the path profiling DAG for each function."));
> > -
> > -// Register the path profiler as a pass
> > -char PathProfiler::ID = 0;
> > -INITIALIZE_PASS(PathProfiler, "insert-path-profiling",
> > - "Insert instrumentation for Ball-Larus path profiling",
> > - false, false)
> > -
> > -ModulePass *llvm::createPathProfilerPass() { return new PathProfiler();
> }
> > -
> > -namespace llvm {
> > - class PathProfilingFunctionTable {};
> > -
> > - // Type for global array storing references to hashes or arrays
> > - template<bool xcompile> class TypeBuilder<PathProfilingFunctionTable,
> > - xcompile> {
> > - public:
> > - static StructType *get(LLVMContext& C) {
> > - return( StructType::get(
> > - TypeBuilder<types::i<32>, xcompile>::get(C), // type
> > - TypeBuilder<types::i<32>, xcompile>::get(C), // array
> size
> > - TypeBuilder<types::i<8>*, xcompile>::get(C), //
> array/hash ptr
> > - NULL));
> > - }
> > - };
> > -
> > - typedef TypeBuilder<PathProfilingFunctionTable, true>
> > - ftEntryTypeBuilder;
> > -
> > - // BallLarusEdge << operator overloading
> > - raw_ostream& operator<<(raw_ostream& os,
> > - const BLInstrumentationEdge& edge)
> > - LLVM_ATTRIBUTE_USED;
> > - raw_ostream& operator<<(raw_ostream& os,
> > - const BLInstrumentationEdge& edge) {
> > - os << "[" << edge.getSource()->getName() << " -> "
> > - << edge.getTarget()->getName() << "] init: "
> > - << (edge.isInitialization() ? "yes" : "no")
> > - << " incr:" << edge.getIncrement() << " cinc: "
> > - << (edge.isCounterIncrement() ? "yes" : "no");
> > - return(os);
> > - }
> > -}
> > -
> > -// Creates a new BLInstrumentationNode from a BasicBlock.
> > -BLInstrumentationNode::BLInstrumentationNode(BasicBlock* BB) :
> > - BallLarusNode(BB),
> > - _startingPathNumber(NULL), _endingPathNumber(NULL), _pathPHI(NULL) {}
> > -
> > -// Constructor for BLInstrumentationEdge.
> > -BLInstrumentationEdge::BLInstrumentationEdge(BLInstrumentationNode*
> source,
> > - BLInstrumentationNode*
> target)
> > - : BallLarusEdge(source, target, 0),
> > - _increment(0), _isInSpanningTree(false), _isInitialization(false),
> > - _isCounterIncrement(false), _hasInstrumentation(false) {}
> > -
> > -// Sets the target node of this edge. Required to split edges.
> > -void BLInstrumentationEdge::setTarget(BallLarusNode* node) {
> > - _target = node;
> > -}
> > -
> > -// Returns whether this edge is in the spanning tree.
> > -bool BLInstrumentationEdge::isInSpanningTree() const {
> > - return(_isInSpanningTree);
> > -}
> > -
> > -// Sets whether this edge is in the spanning tree.
> > -void BLInstrumentationEdge::setIsInSpanningTree(bool isInSpanningTree) {
> > - _isInSpanningTree = isInSpanningTree;
> > -}
> > -
> > -// Returns whether this edge will be instrumented with a path number
> > -// initialization.
> > -bool BLInstrumentationEdge::isInitialization() const {
> > - return(_isInitialization);
> > -}
> > -
> > -// Sets whether this edge will be instrumented with a path number
> > -// initialization.
> > -void BLInstrumentationEdge::setIsInitialization(bool isInitialization) {
> > - _isInitialization = isInitialization;
> > -}
> > -
> > -// Returns whether this edge will be instrumented with a path counter
> > -// increment. Notice this is incrementing the path counter
> > -// corresponding to the path number register. The path number
> > -// increment is determined by getIncrement().
> > -bool BLInstrumentationEdge::isCounterIncrement() const {
> > - return(_isCounterIncrement);
> > -}
> > -
> > -// Sets whether this edge will be instrumented with a path counter
> > -// increment.
> > -void BLInstrumentationEdge::setIsCounterIncrement(bool
> isCounterIncrement) {
> > - _isCounterIncrement = isCounterIncrement;
> > -}
> > -
> > -// Gets the path number increment that this edge will be instrumented
> > -// with. This is distinct from the path counter increment and the
> > -// weight. The counter increment is counts the number of executions of
> > -// some path, whereas the path number keeps track of which path number
> > -// the program is on.
> > -long BLInstrumentationEdge::getIncrement() const {
> > - return(_increment);
> > -}
> > -
> > -// Set whether this edge will be instrumented with a path number
> > -// increment.
> > -void BLInstrumentationEdge::setIncrement(long increment) {
> > - _increment = increment;
> > -}
> > -
> > -// True iff the edge has already been instrumented.
> > -bool BLInstrumentationEdge::hasInstrumentation() {
> > - return(_hasInstrumentation);
> > -}
> > -
> > -// Set whether this edge has been instrumented.
> > -void BLInstrumentationEdge::setHasInstrumentation(bool
> hasInstrumentation) {
> > - _hasInstrumentation = hasInstrumentation;
> > -}
> > -
> > -// Returns the successor number of this edge in the source.
> > -unsigned BLInstrumentationEdge::getSuccessorNumber() {
> > - BallLarusNode* sourceNode = getSource();
> > - BallLarusNode* targetNode = getTarget();
> > - BasicBlock* source = sourceNode->getBlock();
> > - BasicBlock* target = targetNode->getBlock();
> > -
> > - if(source == NULL || target == NULL)
> > - return(0);
> > -
> > - TerminatorInst* terminator = source->getTerminator();
> > -
> > - unsigned i;
> > - for(i=0; i < terminator->getNumSuccessors(); i++) {
> > - if(terminator->getSuccessor(i) == target)
> > - break;
> > - }
> > -
> > - return(i);
> > -}
> > -
> > -// BLInstrumentationDag constructor initializes a DAG for the given
> Function.
> > -BLInstrumentationDag::BLInstrumentationDag(Function &F) :
> BallLarusDag(F),
> > -
> _counterArray(0) {
> > -}
> > -
> > -// Returns the Exit->Root edge. This edge is required for creating
> > -// directed cycles in the algorithm for moving instrumentation off of
> > -// the spanning tree
> > -BallLarusEdge* BLInstrumentationDag::getExitRootEdge() {
> > - BLEdgeIterator erEdge = getExit()->succBegin();
> > - return(*erEdge);
> > -}
> > -
> > -BLEdgeVector BLInstrumentationDag::getCallPhonyEdges () {
> > - BLEdgeVector callEdges;
> > -
> > - for( BLEdgeIterator edge = _edges.begin(), end = _edges.end();
> > - edge != end; edge++ ) {
> > - if( (*edge)->getType() == BallLarusEdge::CALLEDGE_PHONY )
> > - callEdges.push_back(*edge);
> > - }
> > -
> > - return callEdges;
> > -}
> > -
> > -// Gets the path counter array
> > -GlobalVariable* BLInstrumentationDag::getCounterArray() {
> > - return _counterArray;
> > -}
> > -
> > -void BLInstrumentationDag::setCounterArray(GlobalVariable* c) {
> > - _counterArray = c;
> > -}
> > -
> > -// Calculates the increment for the chords, thereby removing
> > -// instrumentation from the spanning tree edges. Implementation is
> based on
> > -// the algorithm in Figure 4 of [Ball94]
> > -void BLInstrumentationDag::calculateChordIncrements() {
> > - calculateChordIncrementsDfs(0, getRoot(), NULL);
> > -
> > - BLInstrumentationEdge* chord;
> > - for(BLEdgeIterator chordEdge = _chordEdges.begin(),
> > - end = _chordEdges.end(); chordEdge != end; chordEdge++) {
> > - chord = (BLInstrumentationEdge*) *chordEdge;
> > - chord->setIncrement(chord->getIncrement() + chord->getWeight());
> > - }
> > -}
> > -
> > -// Updates the state when an edge has been split
> > -void BLInstrumentationDag::splitUpdate(BLInstrumentationEdge*
> formerEdge,
> > - BasicBlock* newBlock) {
> > - BallLarusNode* oldTarget = formerEdge->getTarget();
> > - BallLarusNode* newNode = addNode(newBlock);
> > - formerEdge->setTarget(newNode);
> > - newNode->addPredEdge(formerEdge);
> > -
> > - DEBUG(dbgs() << " Edge split: " << *formerEdge << "\n");
> > -
> > - oldTarget->removePredEdge(formerEdge);
> > - BallLarusEdge* newEdge = addEdge(newNode, oldTarget,0);
> > -
> > - if( formerEdge->getType() == BallLarusEdge::BACKEDGE ||
> > - formerEdge->getType() ==
> BallLarusEdge::SPLITEDGE) {
> > - newEdge->setType(formerEdge->getType());
> > - newEdge->setPhonyRoot(formerEdge->getPhonyRoot());
> > - newEdge->setPhonyExit(formerEdge->getPhonyExit());
> > - formerEdge->setType(BallLarusEdge::NORMAL);
> > - formerEdge->setPhonyRoot(NULL);
> > - formerEdge->setPhonyExit(NULL);
> > - }
> > -}
> > -
> > -// Calculates a spanning tree of the DAG ignoring cycles. Whichever
> > -// edges are in the spanning tree will not be instrumented, but this
> > -// implementation does not try to minimize the instrumentation overhead
> > -// by trying to find hot edges.
> > -void BLInstrumentationDag::calculateSpanningTree() {
> > - std::stack<BallLarusNode*> dfsStack;
> > -
> > - for(BLNodeIterator nodeIt = _nodes.begin(), end = _nodes.end();
> > - nodeIt != end; nodeIt++) {
> > - (*nodeIt)->setColor(BallLarusNode::WHITE);
> > - }
> > -
> > - dfsStack.push(getRoot());
> > - while(dfsStack.size() > 0) {
> > - BallLarusNode* node = dfsStack.top();
> > - dfsStack.pop();
> > -
> > - if(node->getColor() == BallLarusNode::WHITE)
> > - continue;
> > -
> > - BallLarusNode* nextNode;
> > - bool forward = true;
> > - BLEdgeIterator succEnd = node->succEnd();
> > -
> > - node->setColor(BallLarusNode::WHITE);
> > - // first iterate over successors then predecessors
> > - for(BLEdgeIterator edge = node->succBegin(), predEnd =
> node->predEnd();
> > - edge != predEnd; edge++) {
> > - if(edge == succEnd) {
> > - edge = node->predBegin();
> > - forward = false;
> > - }
> > -
> > - // Ignore split edges
> > - if ((*edge)->getType() == BallLarusEdge::SPLITEDGE)
> > - continue;
> > -
> > - nextNode = forward? (*edge)->getTarget(): (*edge)->getSource();
> > - if(nextNode->getColor() != BallLarusNode::WHITE) {
> > - nextNode->setColor(BallLarusNode::WHITE);
> > - makeEdgeSpanning((BLInstrumentationEdge*)(*edge));
> > - }
> > - }
> > - }
> > -
> > - for(BLEdgeIterator edge = _edges.begin(), end = _edges.end();
> > - edge != end; edge++) {
> > - BLInstrumentationEdge* instEdge = (BLInstrumentationEdge*) (*edge);
> > - // safe since createEdge is overriden
> > - if(!instEdge->isInSpanningTree() && (*edge)->getType()
> > - != BallLarusEdge::SPLITEDGE)
> > - _chordEdges.push_back(instEdge);
> > - }
> > -}
> > -
> > -// Pushes initialization further down in order to group the first
> > -// increment and initialization.
> > -void BLInstrumentationDag::pushInitialization() {
> > - BLInstrumentationEdge* exitRootEdge =
> > - (BLInstrumentationEdge*) getExitRootEdge();
> > - exitRootEdge->setIsInitialization(true);
> > - pushInitializationFromEdge(exitRootEdge);
> > -}
> > -
> > -// Pushes the path counter increments up in order to group the last path
> > -// number increment.
> > -void BLInstrumentationDag::pushCounters() {
> > - BLInstrumentationEdge* exitRootEdge =
> > - (BLInstrumentationEdge*) getExitRootEdge();
> > - exitRootEdge->setIsCounterIncrement(true);
> > - pushCountersFromEdge(exitRootEdge);
> > -}
> > -
> > -// Removes phony edges from the successor list of the source, and the
> > -// predecessor list of the target.
> > -void BLInstrumentationDag::unlinkPhony() {
> > - BallLarusEdge* edge;
> > -
> > - for(BLEdgeIterator next = _edges.begin(),
> > - end = _edges.end(); next != end; next++) {
> > - edge = (*next);
> > -
> > - if( edge->getType() == BallLarusEdge::BACKEDGE_PHONY ||
> > - edge->getType() == BallLarusEdge::SPLITEDGE_PHONY ||
> > - edge->getType() == BallLarusEdge::CALLEDGE_PHONY ) {
> > - unlinkEdge(edge);
> > - }
> > - }
> > -}
> > -
> > -// Generate a .dot graph to represent the DAG and pathNumbers
> > -void BLInstrumentationDag::generateDotGraph() {
> > - std::string errorInfo;
> > - std::string functionName = getFunction().getName().str();
> > - std::string filename = "pathdag." + functionName + ".dot";
> > -
> > - DEBUG (dbgs() << "Writing '" << filename << "'...\n");
> > - raw_fd_ostream dotFile(filename.c_str(), errorInfo);
> > -
> > - if (!errorInfo.empty()) {
> > - errs() << "Error opening '" << filename.c_str() <<"' for writing!";
> > - errs() << "\n";
> > - return;
> > - }
> > -
> > - dotFile << "digraph " << functionName << " {\n";
> > -
> > - for( BLEdgeIterator edge = _edges.begin(), end = _edges.end();
> > - edge != end; edge++) {
> > - std::string sourceName = (*edge)->getSource()->getName();
> > - std::string targetName = (*edge)->getTarget()->getName();
> > -
> > - dotFile << "\t\"" << sourceName.c_str() << "\" -> \""
> > - << targetName.c_str() << "\" ";
> > -
> > - long inc = ((BLInstrumentationEdge*)(*edge))->getIncrement();
> > -
> > - switch( (*edge)->getType() ) {
> > - case BallLarusEdge::NORMAL:
> > - dotFile << "[label=" << inc << "] [color=black];\n";
> > - break;
> > -
> > - case BallLarusEdge::BACKEDGE:
> > - dotFile << "[color=cyan];\n";
> > - break;
> > -
> > - case BallLarusEdge::BACKEDGE_PHONY:
> > - dotFile << "[label=" << inc
> > - << "] [color=blue];\n";
> > - break;
> > -
> > - case BallLarusEdge::SPLITEDGE:
> > - dotFile << "[color=violet];\n";
> > - break;
> > -
> > - case BallLarusEdge::SPLITEDGE_PHONY:
> > - dotFile << "[label=" << inc << "] [color=red];\n";
> > - break;
> > -
> > - case BallLarusEdge::CALLEDGE_PHONY:
> > - dotFile << "[label=" << inc << "] [color=green];\n";
> > - break;
> > - }
> > - }
> > -
> > - dotFile << "}\n";
> > -}
> > -
> > -// 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* BLInstrumentationDag::createNode(BasicBlock* BB) {
> > - return( new BLInstrumentationNode(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* BLInstrumentationDag::createEdge(BallLarusNode* source,
> > - BallLarusNode* target,
> unsigned edgeNumber) {
> > - // One can cast from BallLarusNode to BLInstrumentationNode since
> createNode
> > - // is overriden to produce BLInstrumentationNode.
> > - return( new BLInstrumentationEdge((BLInstrumentationNode*)source,
> > - (BLInstrumentationNode*)target) );
> > -}
> > -
> > -// Sets the Value corresponding to the pathNumber register, constant,
> > -// or phinode. Used by the instrumentation code to remember path
> > -// number Values.
> > -Value* BLInstrumentationNode::getStartingPathNumber(){
> > - return(_startingPathNumber);
> > -}
> > -
> > -// Sets the Value of the pathNumber. Used by the instrumentation code.
> > -void BLInstrumentationNode::setStartingPathNumber(Value* pathNumber) {
> > - DEBUG(dbgs() << " SPN-" << getName() << " <-- " << (pathNumber ?
> > -
> pathNumber->getName() :
> > - "unused") <<
> "\n");
> > - _startingPathNumber = pathNumber;
> > -}
> > -
> > -Value* BLInstrumentationNode::getEndingPathNumber(){
> > - return(_endingPathNumber);
> > -}
> > -
> > -void BLInstrumentationNode::setEndingPathNumber(Value* pathNumber) {
> > - DEBUG(dbgs() << " EPN-" << getName() << " <-- "
> > - << (pathNumber ? pathNumber->getName() : "unused") <<
> "\n");
> > - _endingPathNumber = pathNumber;
> > -}
> > -
> > -// Get the PHINode Instruction for this node. Used by instrumentation
> > -// code.
> > -PHINode* BLInstrumentationNode::getPathPHI() {
> > - return(_pathPHI);
> > -}
> > -
> > -// Set the PHINode Instruction for this node. Used by instrumentation
> > -// code.
> > -void BLInstrumentationNode::setPathPHI(PHINode* pathPHI) {
> > - _pathPHI = pathPHI;
> > -}
> > -
> > -// Removes the edge from the appropriate predecessor and successor
> > -// lists.
> > -void BLInstrumentationDag::unlinkEdge(BallLarusEdge* edge) {
> > - if(edge == getExitRootEdge())
> > - DEBUG(dbgs() << " Removing exit->root edge\n");
> > -
> > - edge->getSource()->removeSuccEdge(edge);
> > - edge->getTarget()->removePredEdge(edge);
> > -}
> > -
> > -// Makes an edge part of the spanning tree.
> > -void BLInstrumentationDag::makeEdgeSpanning(BLInstrumentationEdge*
> edge) {
> > - edge->setIsInSpanningTree(true);
> > - _treeEdges.push_back(edge);
> > -}
> > -
> > -// Pushes initialization and calls itself recursively.
> > -void BLInstrumentationDag::pushInitializationFromEdge(
> > - BLInstrumentationEdge* edge) {
> > - BallLarusNode* target;
> > -
> > - target = edge->getTarget();
> > - if( target->getNumberPredEdges() > 1 || target == getExit() ) {
> > - return;
> > - } else {
> > - for(BLEdgeIterator next = target->succBegin(),
> > - end = target->succEnd(); next != end; next++) {
> > - BLInstrumentationEdge* intoEdge = (BLInstrumentationEdge*) *next;
> > -
> > - // Skip split edges
> > - if (intoEdge->getType() == BallLarusEdge::SPLITEDGE)
> > - continue;
> > -
> > - intoEdge->setIncrement(intoEdge->getIncrement() +
> > - edge->getIncrement());
> > - intoEdge->setIsInitialization(true);
> > - pushInitializationFromEdge(intoEdge);
> > - }
> > -
> > - edge->setIncrement(0);
> > - edge->setIsInitialization(false);
> > - }
> > -}
> > -
> > -// Pushes path counter increments up recursively.
> > -void BLInstrumentationDag::pushCountersFromEdge(BLInstrumentationEdge*
> edge) {
> > - BallLarusNode* source;
> > -
> > - source = edge->getSource();
> > - if(source->getNumberSuccEdges() > 1 || source == getRoot()
> > - || edge->isInitialization()) {
> > - return;
> > - } else {
> > - for(BLEdgeIterator previous = source->predBegin(),
> > - end = source->predEnd(); previous != end; previous++) {
> > - BLInstrumentationEdge* fromEdge = (BLInstrumentationEdge*)
> *previous;
> > -
> > - // Skip split edges
> > - if (fromEdge->getType() == BallLarusEdge::SPLITEDGE)
> > - continue;
> > -
> > - fromEdge->setIncrement(fromEdge->getIncrement() +
> > - edge->getIncrement());
> > - fromEdge->setIsCounterIncrement(true);
> > - pushCountersFromEdge(fromEdge);
> > - }
> > -
> > - edge->setIncrement(0);
> > - edge->setIsCounterIncrement(false);
> > - }
> > -}
> > -
> > -// Depth first algorithm for determining the chord increments.
> > -void BLInstrumentationDag::calculateChordIncrementsDfs(long weight,
> > - BallLarusNode*
> v, BallLarusEdge* e) {
> > - BLInstrumentationEdge* f;
> > -
> > - for(BLEdgeIterator treeEdge = _treeEdges.begin(),
> > - end = _treeEdges.end(); treeEdge != end; treeEdge++) {
> > - f = (BLInstrumentationEdge*) *treeEdge;
> > - if(e != f && v == f->getTarget()) {
> > - calculateChordIncrementsDfs(
> > - calculateChordIncrementsDir(e,f)*(weight) +
> > - f->getWeight(), f->getSource(), f);
> > - }
> > - if(e != f && v == f->getSource()) {
> > - calculateChordIncrementsDfs(
> > - calculateChordIncrementsDir(e,f)*(weight) +
> > - f->getWeight(), f->getTarget(), f);
> > - }
> > - }
> > -
> > - for(BLEdgeIterator chordEdge = _chordEdges.begin(),
> > - end = _chordEdges.end(); chordEdge != end; chordEdge++) {
> > - f = (BLInstrumentationEdge*) *chordEdge;
> > - if(v == f->getSource() || v == f->getTarget()) {
> > - f->setIncrement(f->getIncrement() +
> > - calculateChordIncrementsDir(e,f)*weight);
> > - }
> > - }
> > -}
> > -
> > -// Determines the relative direction of two edges.
> > -int BLInstrumentationDag::calculateChordIncrementsDir(BallLarusEdge* e,
> > - BallLarusEdge* f)
> {
> > - if( e == NULL)
> > - return(1);
> > - else if(e->getSource() == f->getTarget()
> > - || e->getTarget() == f->getSource())
> > - return(1);
> > -
> > - return(-1);
> > -}
> > -
> > -// Creates an increment constant representing incr.
> > -ConstantInt* PathProfiler::createIncrementConstant(long incr,
> > - int bitsize) {
> > - return(ConstantInt::get(IntegerType::get(*Context, 32), incr));
> > -}
> > -
> > -// Creates an increment constant representing the value in
> > -// edge->getIncrement().
> > -ConstantInt* PathProfiler::createIncrementConstant(
> > - BLInstrumentationEdge* edge) {
> > - return(createIncrementConstant(edge->getIncrement(), 32));
> > -}
> > -
> > -// Finds the insertion point after pathNumber in block. PathNumber may
> > -// be NULL.
> > -BasicBlock::iterator PathProfiler::getInsertionPoint(BasicBlock* block,
> Value*
> > - pathNumber) {
> > - if(pathNumber == NULL || isa<ConstantInt>(pathNumber)
> > - || (((Instruction*)(pathNumber))->getParent()) != block) {
> > - return(block->getFirstInsertionPt());
> > - } else {
> > - Instruction* pathNumberInst = (Instruction*) (pathNumber);
> > - BasicBlock::iterator insertPoint;
> > - BasicBlock::iterator end = block->end();
> > -
> > - for(insertPoint = block->begin();
> > - insertPoint != end; insertPoint++) {
> > - Instruction* insertInst = &(*insertPoint);
> > -
> > - if(insertInst == pathNumberInst)
> > - return(++insertPoint);
> > - }
> > -
> > - return(insertPoint);
> > - }
> > -}
> > -
> > -// A PHINode is created in the node, and its values initialized to -1U.
> > -void PathProfiler::preparePHI(BLInstrumentationNode* node) {
> > - BasicBlock* block = node->getBlock();
> > - BasicBlock::iterator insertPoint = block->getFirstInsertionPt();
> > - pred_iterator PB = pred_begin(node->getBlock()),
> > - PE = pred_end(node->getBlock());
> > - PHINode* phi = PHINode::Create(Type::getInt32Ty(*Context),
> > - std::distance(PB, PE), "pathNumber",
> > - insertPoint );
> > - node->setPathPHI(phi);
> > - node->setStartingPathNumber(phi);
> > - node->setEndingPathNumber(phi);
> > -
> > - for(pred_iterator predIt = PB; predIt != PE; predIt++) {
> > - BasicBlock* pred = (*predIt);
> > -
> > - if(pred != NULL)
> > - phi->addIncoming(createIncrementConstant((long)-1, 32), pred);
> > - }
> > -}
> > -
> > -// Inserts source's pathNumber Value* into target. Target may or may
> not
> > -// have multiple predecessors, and may or may not have its phiNode
> > -// initalized.
> > -void PathProfiler::pushValueIntoNode(BLInstrumentationNode* source,
> > - BLInstrumentationNode* target) {
> > - if(target->getBlock() == NULL)
> > - return;
> > -
> > -
> > - if(target->getNumberPredEdges() <= 1) {
> > - assert(target->getStartingPathNumber() == NULL &&
> > - "Target already has path number");
> > - target->setStartingPathNumber(source->getEndingPathNumber());
> > - target->setEndingPathNumber(source->getEndingPathNumber());
> > - DEBUG(dbgs() << " Passing path number"
> > - << (source->getEndingPathNumber() ? "" : " (null)")
> > - << " value through.\n");
> > - } else {
> > - if(target->getPathPHI() == NULL) {
> > - DEBUG(dbgs() << " Initializing PHI node for block '"
> > - << target->getName() << "'\n");
> > - preparePHI(target);
> > - }
> > - pushValueIntoPHI(target, source);
> > - DEBUG(dbgs() << " Passing number value into PHI for block '"
> > - << target->getName() << "'\n");
> > - }
> > -}
> > -
> > -// Inserts source's pathNumber Value* into the appropriate slot of
> > -// target's phiNode.
> > -void PathProfiler::pushValueIntoPHI(BLInstrumentationNode* target,
> > - BLInstrumentationNode* source) {
> > - PHINode* phi = target->getPathPHI();
> > - assert(phi != NULL && " Tried to push value into node with PHI, but
> node"
> > - " actually had no PHI.");
> > - phi->removeIncomingValue(source->getBlock(), false);
> > - phi->addIncoming(source->getEndingPathNumber(), source->getBlock());
> > -}
> > -
> > -// The Value* in node, oldVal, is updated with a Value* correspodning
> to
> > -// oldVal + addition.
> > -void PathProfiler::insertNumberIncrement(BLInstrumentationNode* node,
> > - Value* addition, bool
> atBeginning) {
> > - BasicBlock* block = node->getBlock();
> > - assert(node->getStartingPathNumber() != NULL);
> > - assert(node->getEndingPathNumber() != NULL);
> > -
> > - BasicBlock::iterator insertPoint;
> > -
> > - if( atBeginning )
> > - insertPoint = block->getFirstInsertionPt();
> > - else
> > - insertPoint = block->getTerminator();
> > -
> > - DEBUG(errs() << " Creating addition instruction.\n");
> > - Value* newpn = BinaryOperator::Create(Instruction::Add,
> > - node->getStartingPathNumber(),
> > - addition, "pathNumber",
> insertPoint);
> > -
> > - node->setEndingPathNumber(newpn);
> > -
> > - if( atBeginning )
> > - node->setStartingPathNumber(newpn);
> > -}
> > -
> > -// Creates a counter increment in the given node. The Value* in node is
> > -// taken as the index into an array or hash table. The hash table
> access
> > -// is a call to the runtime.
> > -void PathProfiler::insertCounterIncrement(Value* incValue,
> > - BasicBlock::iterator
> insertPoint,
> > - BLInstrumentationDag* dag,
> > - bool increment) {
> > - // Counter increment for array
> > - if( dag->getNumberOfPaths() <= HASH_THRESHHOLD ) {
> > - // Get pointer to the array location
> > - std::vector<Value*> gepIndices(2);
> > - gepIndices[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
> > - gepIndices[1] = incValue;
> > -
> > - GetElementPtrInst* pcPointer =
> > - GetElementPtrInst::Create(dag->getCounterArray(), gepIndices,
> > - "counterInc", insertPoint);
> > -
> > - // Load from the array - call it oldPC
> > - LoadInst* oldPc = new LoadInst(pcPointer, "oldPC", insertPoint);
> > -
> > - // Test to see whether adding 1 will overflow the counter
> > - ICmpInst* isMax = new ICmpInst(insertPoint, CmpInst::ICMP_ULT,
> oldPc,
> > - createIncrementConstant(0xffffffff,
> 32),
> > - "isMax");
> > -
> > - // Select increment for the path counter based on overflow
> > - SelectInst* inc =
> > - SelectInst::Create( isMax,
> createIncrementConstant(increment?1:-1,32),
> > - createIncrementConstant(0,32),
> > - "pathInc", insertPoint);
> > -
> > - // newPc = oldPc + inc
> > - BinaryOperator* newPc = BinaryOperator::Create(Instruction::Add,
> > - oldPc, inc, "newPC",
> > - insertPoint);
> > -
> > - // Store back in to the array
> > - new StoreInst(newPc, pcPointer, insertPoint);
> > - } else { // Counter increment for hash
> > - std::vector<Value*> args(2);
> > - args[0] = ConstantInt::get(Type::getInt32Ty(*Context),
> > - currentFunctionNumber);
> > - args[1] = incValue;
> > -
> > - CallInst::Create(
> > - increment ? llvmIncrementHashFunction : llvmDecrementHashFunction,
> > - args, "", insertPoint);
> > - }
> > -}
> > -
> > -// Inserts instrumentation for the given edge
> > -//
> > -// Pre: The edge's source node has pathNumber set if edge is non zero
> > -// path number increment.
> > -//
> > -// Post: Edge's target node has a pathNumber set to the path number
> Value
> > -// corresponding to the value of the path register after edge's
> > -// execution.
> > -//
> > -// FIXME: This should be reworked so it's not recursive.
> > -void
> PathProfiler::insertInstrumentationStartingAt(BLInstrumentationEdge* edge,
> > -
> BLInstrumentationDag* dag) {
> > - // Mark the edge as instrumented
> > - edge->setHasInstrumentation(true);
> > - DEBUG(dbgs() << "\nInstrumenting edge: " << (*edge) << "\n");
> > -
> > - // create a new node for this edge's instrumentation
> > - splitCritical(edge, dag);
> > -
> > - BLInstrumentationNode* sourceNode =
> (BLInstrumentationNode*)edge->getSource();
> > - BLInstrumentationNode* targetNode =
> (BLInstrumentationNode*)edge->getTarget();
> > - BLInstrumentationNode* instrumentNode;
> > - BLInstrumentationNode* nextSourceNode;
> > -
> > - bool atBeginning = false;
> > -
> > - // Source node has only 1 successor so any information can be simply
> > - // inserted in to it without splitting
> > - if( sourceNode->getBlock() && sourceNode->getNumberSuccEdges() <= 1) {
> > - DEBUG(dbgs() << " Potential instructions to be placed in: "
> > - << sourceNode->getName() << " (at end)\n");
> > - instrumentNode = sourceNode;
> > - nextSourceNode = targetNode; // ... since we never made any new
> nodes
> > - }
> > -
> > - // The target node only has one predecessor, so we can safely insert
> edge
> > - // instrumentation into it. If there was splitting, it must have been
> > - // successful.
> > - else if( targetNode->getNumberPredEdges() == 1 ) {
> > - DEBUG(dbgs() << " Potential instructions to be placed in: "
> > - << targetNode->getName() << " (at beginning)\n");
> > - pushValueIntoNode(sourceNode, targetNode);
> > - instrumentNode = targetNode;
> > - nextSourceNode = NULL; // ... otherwise we'll just keep splitting
> > - atBeginning = true;
> > - }
> > -
> > - // Somehow, splitting must have failed.
> > - else {
> > - errs() << "Instrumenting could not split a critical edge.\n";
> > - DEBUG(dbgs() << " Couldn't split edge " << (*edge) << ".\n");
> > - return;
> > - }
> > -
> > - // Insert instrumentation if this is a back or split edge
> > - if( edge->getType() == BallLarusEdge::BACKEDGE ||
> > - edge->getType() == BallLarusEdge::SPLITEDGE ) {
> > - BLInstrumentationEdge* top =
> > - (BLInstrumentationEdge*) edge->getPhonyRoot();
> > - BLInstrumentationEdge* bottom =
> > - (BLInstrumentationEdge*) edge->getPhonyExit();
> > -
> > - assert( top->isInitialization() && " Top phony edge did not"
> > - " contain a path number initialization.");
> > - assert( bottom->isCounterIncrement() && " Bottom phony edge"
> > - " did not contain a path counter increment.");
> > -
> > - // split edge has yet to be initialized
> > - if( !instrumentNode->getEndingPathNumber() ) {
> > -
> instrumentNode->setStartingPathNumber(createIncrementConstant(0,32));
> > -
> instrumentNode->setEndingPathNumber(createIncrementConstant(0,32));
> > - }
> > -
> > - BasicBlock::iterator insertPoint = atBeginning ?
> > - instrumentNode->getBlock()->getFirstInsertionPt() :
> > - instrumentNode->getBlock()->getTerminator();
> > -
> > - // add information from the bottom edge, if it exists
> > - if( bottom->getIncrement() ) {
> > - Value* newpn =
> > - BinaryOperator::Create(Instruction::Add,
> > - instrumentNode->getStartingPathNumber(),
> > - createIncrementConstant(bottom),
> > - "pathNumber", insertPoint);
> > - instrumentNode->setEndingPathNumber(newpn);
> > - }
> > -
> > - insertCounterIncrement(instrumentNode->getEndingPathNumber(),
> > - insertPoint, dag);
> > -
> > - if( atBeginning )
> > -
> instrumentNode->setStartingPathNumber(createIncrementConstant(top));
> > -
> > - instrumentNode->setEndingPathNumber(createIncrementConstant(top));
> > -
> > - // Check for path counter increments
> > - if( top->isCounterIncrement() ) {
> > - insertCounterIncrement(instrumentNode->getEndingPathNumber(),
> > -
> instrumentNode->getBlock()->getTerminator(),dag);
> > - instrumentNode->setEndingPathNumber(0);
> > - }
> > - }
> > -
> > - // Insert instrumentation if this is a normal edge
> > - else {
> > - BasicBlock::iterator insertPoint = atBeginning ?
> > - instrumentNode->getBlock()->getFirstInsertionPt() :
> > - instrumentNode->getBlock()->getTerminator();
> > -
> > - if( edge->isInitialization() ) { // initialize path number
> > -
> instrumentNode->setEndingPathNumber(createIncrementConstant(edge));
> > - } else if( edge->getIncrement() ) {// increment path number
> > - Value* newpn =
> > - BinaryOperator::Create(Instruction::Add,
> > - instrumentNode->getStartingPathNumber(),
> > - createIncrementConstant(edge),
> > - "pathNumber", insertPoint);
> > - instrumentNode->setEndingPathNumber(newpn);
> > -
> > - if( atBeginning )
> > - instrumentNode->setStartingPathNumber(newpn);
> > - }
> > -
> > - // Check for path counter increments
> > - if( edge->isCounterIncrement() ) {
> > - insertCounterIncrement(instrumentNode->getEndingPathNumber(),
> > - insertPoint, dag);
> > - instrumentNode->setEndingPathNumber(0);
> > - }
> > - }
> > -
> > - // Push it along
> > - if (nextSourceNode && instrumentNode->getEndingPathNumber())
> > - pushValueIntoNode(instrumentNode, nextSourceNode);
> > -
> > - // Add all the successors
> > - for( BLEdgeIterator next = targetNode->succBegin(),
> > - end = targetNode->succEnd(); next != end; next++ ) {
> > - // So long as it is un-instrumented, add it to the list
> > - if( !((BLInstrumentationEdge*)(*next))->hasInstrumentation() )
> > -
> insertInstrumentationStartingAt((BLInstrumentationEdge*)*next,dag);
> > - else
> > - DEBUG(dbgs() << " Edge " << *(BLInstrumentationEdge*)(*next)
> > - << " already instrumented.\n");
> > - }
> > -}
> > -
> > -// Inserts instrumentation according to the marked edges in dag. Phony
> edges
> > -// must be unlinked from the DAG, but accessible from the backedges.
> Dag
> > -// must have initializations, path number increments, and counter
> increments
> > -// present.
> > -//
> > -// Counter storage is created here.
> > -void PathProfiler::insertInstrumentation(
> > - BLInstrumentationDag& dag, Module &M) {
> > -
> > - BLInstrumentationEdge* exitRootEdge =
> > - (BLInstrumentationEdge*) dag.getExitRootEdge();
> > - insertInstrumentationStartingAt(exitRootEdge, &dag);
> > -
> > - // Iterate through each call edge and apply the appropriate hash
> increment
> > - // and decrement functions
> > - BLEdgeVector callEdges = dag.getCallPhonyEdges();
> > - for( BLEdgeIterator edge = callEdges.begin(),
> > - end = callEdges.end(); edge != end; edge++ ) {
> > - BLInstrumentationNode* node =
> > - (BLInstrumentationNode*)(*edge)->getSource();
> > - BasicBlock::iterator insertPoint =
> node->getBlock()->getFirstInsertionPt();
> > -
> > - // Find the first function call
> > - while( ((Instruction&)(*insertPoint)).getOpcode() !=
> Instruction::Call )
> > - insertPoint++;
> > -
> > - DEBUG(dbgs() << "\nInstrumenting method call block '"
> > - << node->getBlock()->getName() << "'\n");
> > - DEBUG(dbgs() << " Path number initialized: "
> > - << ((node->getStartingPathNumber()) ? "yes" : "no") <<
> "\n");
> > -
> > - Value* newpn;
> > - if( node->getStartingPathNumber() ) {
> > - long inc = ((BLInstrumentationEdge*)(*edge))->getIncrement();
> > - if ( inc )
> > - newpn = BinaryOperator::Create(Instruction::Add,
> > - node->getStartingPathNumber(),
> > - createIncrementConstant(inc,32),
> > - "pathNumber", insertPoint);
> > - else
> > - newpn = node->getStartingPathNumber();
> > - } else {
> > - newpn = (Value*)createIncrementConstant(
> > - ((BLInstrumentationEdge*)(*edge))->getIncrement(), 32);
> > - }
> > -
> > - insertCounterIncrement(newpn, insertPoint, &dag);
> > - insertCounterIncrement(newpn, node->getBlock()->getTerminator(),
> > - &dag, false);
> > - }
> > -}
> > -
> > -// Entry point of the module
> > -void PathProfiler::runOnFunction(std::vector<Constant*> &ftInit,
> > - Function &F, Module &M) {
> > - // Build DAG from CFG
> > - BLInstrumentationDag dag = BLInstrumentationDag(F);
> > - dag.init();
> > -
> > - // give each path a unique integer value
> > - dag.calculatePathNumbers();
> > -
> > - // modify path increments to increase the efficiency
> > - // of instrumentation
> > - dag.calculateSpanningTree();
> > - dag.calculateChordIncrements();
> > - dag.pushInitialization();
> > - dag.pushCounters();
> > - dag.unlinkPhony();
> > -
> > - // potentially generate .dot graph for the dag
> > - if (DotPathDag)
> > - dag.generateDotGraph ();
> > -
> > - // Should we store the information in an array or hash
> > - if( dag.getNumberOfPaths() <= HASH_THRESHHOLD ) {
> > - Type* t = ArrayType::get(Type::getInt32Ty(*Context),
> > - dag.getNumberOfPaths());
> > -
> > - dag.setCounterArray(new GlobalVariable(M, t, false,
> > - GlobalValue::InternalLinkage,
> > - Constant::getNullValue(t),
> ""));
> > - }
> > -
> > - insertInstrumentation(dag, M);
> > -
> > - // Add to global function reference table
> > - unsigned type;
> > - Type* voidPtr = TypeBuilder<types::i<8>*, true>::get(*Context);
> > -
> > - if( dag.getNumberOfPaths() <= HASH_THRESHHOLD )
> > - type = ProfilingArray;
> > - else
> > - type = ProfilingHash;
> > -
> > - std::vector<Constant*> entryArray(3);
> > - entryArray[0] = createIncrementConstant(type,32);
> > - entryArray[1] = createIncrementConstant(dag.getNumberOfPaths(),32);
> > - entryArray[2] = dag.getCounterArray() ?
> > - ConstantExpr::getBitCast(dag.getCounterArray(), voidPtr) :
> > - Constant::getNullValue(voidPtr);
> > -
> > - StructType* at = ftEntryTypeBuilder::get(*Context);
> > - ConstantStruct* functionEntry =
> > - (ConstantStruct*)ConstantStruct::get(at, entryArray);
> > - ftInit.push_back(functionEntry);
> > -}
> > -
> > -// Output the bitcode if we want to observe instrumentation changess
> > -#define PRINT_MODULE dbgs() << \
> > - "\n\n============= MODULE BEGIN ===============\n" << M << \
> > - "\n============== MODULE END ================\n"
> > -
> > -bool PathProfiler::runOnModule(Module &M) {
> > - Context = &M.getContext();
> > -
> > - DEBUG(dbgs()
> > - << "****************************************\n"
> > - << "****************************************\n"
> > - << "** **\n"
> > - << "** PATH PROFILING INSTRUMENTATION **\n"
> > - << "** **\n"
> > - << "****************************************\n"
> > - << "****************************************\n");
> > -
> > - // No main, no instrumentation!
> > - Function *Main = M.getFunction("main");
> > -
> > - // Using fortran? ... this kind of works
> > - if (!Main)
> > - Main = M.getFunction("MAIN__");
> > -
> > - if (!Main) {
> > - errs() << "WARNING: cannot insert path profiling into a module"
> > - << " with no main function!\n";
> > - return false;
> > - }
> > -
> > - llvmIncrementHashFunction = M.getOrInsertFunction(
> > - "llvm_increment_path_count",
> > - Type::getVoidTy(*Context), // return type
> > - Type::getInt32Ty(*Context), // function number
> > - Type::getInt32Ty(*Context), // path number
> > - NULL );
> > -
> > - llvmDecrementHashFunction = M.getOrInsertFunction(
> > - "llvm_decrement_path_count",
> > - Type::getVoidTy(*Context), // return type
> > - Type::getInt32Ty(*Context), // function number
> > - Type::getInt32Ty(*Context), // path number
> > - NULL );
> > -
> > - std::vector<Constant*> ftInit;
> > - unsigned functionNumber = 0;
> > - for (Module::iterator F = M.begin(), E = M.end(); F != E; F++) {
> > - if (F->isDeclaration())
> > - continue;
> > -
> > - DEBUG(dbgs() << "Function: " << F->getName() << "\n");
> > - functionNumber++;
> > -
> > - // set function number
> > - currentFunctionNumber = functionNumber;
> > - runOnFunction(ftInit, *F, M);
> > - }
> > -
> > - Type *t = ftEntryTypeBuilder::get(*Context);
> > - ArrayType* ftArrayType = ArrayType::get(t, ftInit.size());
> > - Constant* ftInitConstant = ConstantArray::get(ftArrayType, ftInit);
> > -
> > - DEBUG(dbgs() << " ftArrayType:" << *ftArrayType << "\n");
> > -
> > - GlobalVariable* functionTable =
> > - new GlobalVariable(M, ftArrayType, false,
> GlobalValue::InternalLinkage,
> > - ftInitConstant, "functionPathTable");
> > - Type *eltType = ftArrayType->getTypeAtIndex((unsigned)0);
> > - InsertProfilingInitCall(Main, "llvm_start_path_profiling",
> functionTable,
> > - PointerType::getUnqual(eltType));
> > -
> > - DEBUG(PRINT_MODULE);
> > -
> > - return true;
> > -}
> > -
> > -// If this edge is a critical edge, then inserts a node at this edge.
> > -// This edge becomes the first edge, and a new BallLarusEdge is created.
> > -// Returns true if the edge was split
> > -bool PathProfiler::splitCritical(BLInstrumentationEdge* edge,
> > - BLInstrumentationDag* dag) {
> > - unsigned succNum = edge->getSuccessorNumber();
> > - BallLarusNode* sourceNode = edge->getSource();
> > - BallLarusNode* targetNode = edge->getTarget();
> > - BasicBlock* sourceBlock = sourceNode->getBlock();
> > - BasicBlock* targetBlock = targetNode->getBlock();
> > -
> > - if(sourceBlock == NULL || targetBlock == NULL
> > - || sourceNode->getNumberSuccEdges() <= 1
> > - || targetNode->getNumberPredEdges() == 1 ) {
> > - return(false);
> > - }
> > -
> > - TerminatorInst* terminator = sourceBlock->getTerminator();
> > -
> > - if( SplitCriticalEdge(terminator, succNum, this, false)) {
> > - BasicBlock* newBlock = terminator->getSuccessor(succNum);
> > - dag->splitUpdate(edge, newBlock);
> > - return(true);
> > - } else
> > - return(false);
> > -}
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Oct 2
> 10:42:23 2013
> > @@ -22,7 +22,6 @@
> > #include "llvm/Analysis/DominatorInternals.h"
> > #include "llvm/Analysis/Dominators.h"
> > #include "llvm/Analysis/InstructionSimplify.h"
> > -#include "llvm/Analysis/ProfileInfo.h"
> > #include "llvm/Assembly/Writer.h"
> > #include "llvm/IR/Constants.h"
> > #include "llvm/IR/DataLayout.h"
> > @@ -80,7 +79,6 @@ namespace {
> > const TargetLowering *TLI;
> > const TargetLibraryInfo *TLInfo;
> > DominatorTree *DT;
> > - ProfileInfo *PFI;
> >
> > /// CurInstIterator - As we scan instructions optimizing them, this
> is the
> > /// next instruction to optimize. Xforms that can invalidate this
> should
> > @@ -111,7 +109,6 @@ namespace {
> >
> > virtual void getAnalysisUsage(AnalysisUsage &AU) const {
> > AU.addPreserved<DominatorTree>();
> > - AU.addPreserved<ProfileInfo>();
> > AU.addRequired<TargetLibraryInfo>();
> > }
> >
> > @@ -151,7 +148,6 @@ bool CodeGenPrepare::runOnFunction(Funct
> > if (TM) TLI = TM->getTargetLowering();
> > TLInfo = &getAnalysis<TargetLibraryInfo>();
> > DT = getAnalysisIfAvailable<DominatorTree>();
> > - PFI = getAnalysisIfAvailable<ProfileInfo>();
> > OptSize = F.getAttributes().hasAttribute(AttributeSet::FunctionIndex,
> > Attribute::OptimizeForSize);
> >
> > @@ -442,10 +438,6 @@ void CodeGenPrepare::EliminateMostlyEmpt
> > DT->changeImmediateDominator(DestBB, NewIDom);
> > DT->eraseNode(BB);
> > }
> > - if (PFI) {
> > - PFI->replaceAllUses(BB, DestBB);
> > - PFI->removeEdge(ProfileInfo::getEdge(BB, DestBB));
> > - }
> > BB->eraseFromParent();
> > ++NumBlocksElim;
> >
> >
> > Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Wed Oct 2
> 10:42:23 2013
> > @@ -22,7 +22,6 @@
> > #include "llvm/Analysis/CFG.h"
> > #include "llvm/Analysis/Dominators.h"
> > #include "llvm/Analysis/LoopInfo.h"
> > -#include "llvm/Analysis/ProfileInfo.h"
> > #include "llvm/IR/Function.h"
> > #include "llvm/IR/Instructions.h"
> > #include "llvm/IR/Type.h"
> > @@ -45,7 +44,6 @@ namespace {
> > virtual void getAnalysisUsage(AnalysisUsage &AU) const {
> > AU.addPreserved<DominatorTree>();
> > AU.addPreserved<LoopInfo>();
> > - AU.addPreserved<ProfileInfo>();
> >
> > // No loop canonicalization guarantees are broken by this pass.
> > AU.addPreservedID(LoopSimplifyID);
> > @@ -213,10 +211,9 @@ BasicBlock *llvm::SplitCriticalEdge(Term
> >
> > DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>();
> > LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>();
> > - ProfileInfo *PI = P->getAnalysisIfAvailable<ProfileInfo>();
> >
> > // If we have nothing to update, just return.
> > - if (DT == 0 && LI == 0 && PI == 0)
> > + if (DT == 0 && LI == 0)
> > return NewBB;
> >
> > // Now update analysis information. Since the only predecessor of
> NewBB is
> > @@ -369,9 +366,5 @@ BasicBlock *llvm::SplitCriticalEdge(Term
> > }
> > }
> >
> > - // Update ProfileInfo if it is around.
> > - if (PI)
> > - PI->splitEdge(TIBB, DestBB, NewBB, MergeIdenticalEdges);
> > -
> > return NewBB;
> > }
> >
> > Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Wed Oct 2 10:42:23 2013
> > @@ -20,7 +20,6 @@
> > #include "llvm/Analysis/Dominators.h"
> > #include "llvm/Analysis/InstructionSimplify.h"
> > #include "llvm/Analysis/MemoryBuiltins.h"
> > -#include "llvm/Analysis/ProfileInfo.h"
> > #include "llvm/Analysis/ValueTracking.h"
> > #include "llvm/DIBuilder.h"
> > #include "llvm/DebugInfo.h"
> > @@ -513,11 +512,6 @@ void llvm::MergeBasicBlockIntoOnlyPred(B
> > DT->changeImmediateDominator(DestBB, PredBBIDom);
> > DT->eraseNode(PredBB);
> > }
> > - ProfileInfo *PI = P->getAnalysisIfAvailable<ProfileInfo>();
> > - if (PI) {
> > - PI->replaceAllUses(PredBB, DestBB);
> > - PI->removeEdge(ProfileInfo::getEdge(PredBB, DestBB));
> > - }
> > }
> > // Nuke BB.
> > PredBB->eraseFromParent();
> >
> > Modified: llvm/trunk/test/lit.cfg
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/test/lit.cfg (original)
> > +++ llvm/trunk/test/lit.cfg Wed Oct 2 10:42:23 2013
> > @@ -226,7 +226,6 @@ for pattern in [r"\bbugpoint\b(?!-)",
> > r"\bllvm-mc\b",
> > r"\bllvm-nm\b",
> > r"\bllvm-objdump\b",
> > - r"\bllvm-prof\b",
> > r"\bllvm-ranlib\b",
> > r"\bllvm-readobj\b",
> > r"\bllvm-rtdyld\b",
> >
> > Modified: llvm/trunk/tools/CMakeLists.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/CMakeLists.txt?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/tools/CMakeLists.txt (original)
> > +++ llvm/trunk/tools/CMakeLists.txt Wed Oct 2 10:42:23 2013
> > @@ -15,7 +15,6 @@ add_llvm_tool_subdirectory(llvm-nm)
> > add_llvm_tool_subdirectory(llvm-size)
> >
> > add_llvm_tool_subdirectory(llvm-cov)
> > -add_llvm_tool_subdirectory(llvm-prof)
> > add_llvm_tool_subdirectory(llvm-link)
> > add_llvm_tool_subdirectory(lli)
> >
> >
> > Modified: llvm/trunk/tools/LLVMBuild.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/LLVMBuild.txt?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/tools/LLVMBuild.txt (original)
> > +++ llvm/trunk/tools/LLVMBuild.txt Wed Oct 2 10:42:23 2013
> > @@ -16,7 +16,7 @@
> >
> ;===------------------------------------------------------------------------===;
> >
> > [common]
> > -subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer
> llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener
> llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-prof llvm-rtdyld
> llvm-size macho-dump opt llvm-mcmarkup
> > +subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer
> llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener
> llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-rtdyld llvm-size
> macho-dump opt llvm-mcmarkup
> >
> > [component_0]
> > type = Group
> >
> > Modified: llvm/trunk/tools/Makefile
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=191835&r1=191834&r2=191835&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/tools/Makefile (original)
> > +++ llvm/trunk/tools/Makefile Wed Oct 2 10:42:23 2013
> > @@ -27,7 +27,7 @@ OPTIONAL_DIRS := lldb
> > # large and three small executables. This is done to minimize memory
> load
> > # in parallel builds. Please retain this ordering.
> > DIRS := llvm-config
> > -PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-prof
> llvm-link \
> > +PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-link \
> > lli llvm-extract llvm-mc bugpoint llvm-bcanalyzer
> llvm-diff \
> > macho-dump llvm-objdump llvm-readobj llvm-rtdyld \
> > llvm-dwarfdump llvm-cov llvm-size llvm-stress
> llvm-mcmarkup \
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
Alexey Samsonov, MSK
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131004/e2adc7ed/attachment.html>
More information about the llvm-commits
mailing list