summaryrefslogtreecommitdiffstats
path: root/include/llvm/Analysis/ProfileInfo.h
blob: 2a80f3d4c43a9b88d0e3f41a6355a3f642de0aff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//===- 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/BasicBlock.h"
#include <cassert>
#include <string>
#include <map>

namespace llvm {
  class Function;
  class Pass;
  class raw_ostream;

  /// ProfileInfo Class - This class holds and maintains profiling
  /// information for some unit of code.
  class ProfileInfo {
  public:
    // Types for handling profiling information.
    typedef std::pair<const BasicBlock*, const BasicBlock*> Edge;
    typedef std::pair<Edge, double> EdgeWeight;
    typedef std::map<Edge, double> EdgeWeights;
    typedef std::map<const BasicBlock*, double> BlockCounts;

  protected:
    // EdgeInformation - Count the number of times a transition between two
    // blocks is executed. As a special case, we also hold an edge from the
    // null BasicBlock to the entry block to indicate how many times the
    // function was entered.
    std::map<const Function*, EdgeWeights> EdgeInformation;

    // BlockInformation - Count the number of times a block is executed.
    std::map<const Function*, BlockCounts> BlockInformation;

    // FunctionInformation - Count the number of times a function is executed.
    std::map<const Function*, double> FunctionInformation;
  public:
    static char ID; // Class identification, replacement for typeinfo
    virtual ~ProfileInfo();  // We want to be subclassed

    // MissingValue - The value that is returned for execution counts in case
    // no value is available.
    static const double MissingValue;

    // getFunction() - Returns the Function for an Edge, checking for validity.
    static const Function* getFunction(Edge e) {
      if (e.first) {
        return e.first->getParent();
      } else if (e.second) {
        return e.second->getParent();
      }
      assert(0 && "Invalid ProfileInfo::Edge");
      return (const Function*)0;
    }

    // getEdge() - Creates an Edge from two BasicBlocks.
    static Edge getEdge(const BasicBlock *Src, const BasicBlock *Dest) {
      return std::make_pair(Src, Dest);
    }

    //===------------------------------------------------------------------===//
    /// Profile Information Queries
    ///
    double getExecutionCount(const Function *F);

    double getExecutionCount(const BasicBlock *BB);

    double getEdgeWeight(Edge e) const {
      std::map<const Function*, EdgeWeights>::const_iterator J =
        EdgeInformation.find(getFunction(e));
      if (J == EdgeInformation.end()) return MissingValue;

      EdgeWeights::const_iterator I = J->second.find(e);
      if (I == J->second.end()) return MissingValue;

      return I->second;
    }

    EdgeWeights &getEdgeWeights (const Function *F) {
      return EdgeInformation[F];
    }

    //===------------------------------------------------------------------===//
    /// Analysis Update Methods
    ///
    void removeBlock(const BasicBlock *BB) {
      std::map<const Function*, BlockCounts>::iterator J =
        BlockInformation.find(BB->getParent());
      if (J == BlockInformation.end()) return;

      J->second.erase(BB);
    }

    void removeEdge(Edge e) {
      std::map<const Function*, EdgeWeights>::iterator J =
        EdgeInformation.find(getFunction(e));
      if (J == EdgeInformation.end()) return;

      J->second.erase(e);
    }

    void splitEdge(const BasicBlock *FirstBB, const BasicBlock *SecondBB,
                   const BasicBlock *NewBB, bool MergeIdenticalEdges = false);

    void replaceAllUses(const BasicBlock *RmBB, const BasicBlock *DestBB);
  };

  /// createProfileLoaderPass - This function returns a Pass that loads the
  /// profiling information for the module from the specified filename, making
  /// it available to the optimizers.
  Pass *createProfileLoaderPass(const std::string &Filename);

  raw_ostream& operator<<(raw_ostream &O, ProfileInfo::Edge E);

} // End llvm namespace

#endif
OpenPOWER on IntegriCloud