aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Analysis/DataStructure/EquivClassGraphs.h
blob: 9ae8c8955dbeadc52147d98d2636f76489d7dcdc (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
//===-- EquivClassGraphs.h - Merge equiv-class graphs -----------*- C++ -*-===//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This pass is the same as the complete bottom-up graphs, but with functions
// partitioned into equivalence classes and a single merged DS graph for all
// functions in an equivalence class.  After this merging, graphs are inlined
// bottom-up on the SCCs of the final (CBU) call graph.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure/DataStructure.h"
#include "llvm/Analysis/DataStructure/DSGraph.h"
#include "llvm/ADT/EquivalenceClasses.h"
#include "llvm/ADT/STLExtras.h"
#include <vector>
#include <map>
#include <ext/hash_map>

namespace llvm {
  class Module;
  class Function;

  /// EquivClassGraphs - This is the same as the complete bottom-up graphs, but
  /// with functions partitioned into equivalence classes and a single merged
  /// DS graph for all functions in an equivalence class.  After this merging,
  /// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
  ///
  struct EquivClassGraphs : public ModulePass {
    CompleteBUDataStructures *CBU;

    DSGraph *GlobalsGraph;

    // DSInfo - one graph for each function.
    hash_map<const Function*, DSGraph*> DSInfo;

    /// ActualCallees - The actual functions callable from indirect call sites.
    ///
    hash_multimap<Instruction*, Function*> ActualCallees;
  
    // Equivalence class where functions that can potentially be called via the
    // same function pointer are in the same class.
    EquivalenceClasses<Function*> FuncECs;

    /// OneCalledFunction - For each indirect call, we keep track of one
    /// target of the call.  This is used to find equivalence class called by
    /// a call site.
    std::map<DSNode*, Function *> OneCalledFunction;

  public:
    /// EquivClassGraphs - Computes the equivalence classes and then the
    /// folded DS graphs for each class.
    /// 
    virtual bool runOnModule(Module &M);

    /// getDSGraph - Return the data structure graph for the specified function.
    /// This returns the folded graph.  The folded graph is the same as the CBU
    /// graph iff the function is in a singleton equivalence class AND all its 
    /// callees also have the same folded graph as the CBU graph.
    /// 
    DSGraph &getDSGraph(const Function &F) const {
      hash_map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
      assert(I != DSInfo.end() && "No graph computed for that function!");
      return *I->second;
    }

    /// ContainsDSGraphFor - Return true if we have a graph for the specified
    /// function.
    bool ContainsDSGraphFor(const Function &F) const {
      return DSInfo.find(&F) != DSInfo.end();
    }

    /// getSomeCalleeForCallSite - Return any one callee function at
    /// a call site.
    /// 
    Function *getSomeCalleeForCallSite(const CallSite &CS) const;

    DSGraph &getGlobalsGraph() const {
      return *GlobalsGraph;
    }
    
    typedef hash_multimap<Instruction*, Function*> ActualCalleesTy;
    const ActualCalleesTy &getActualCallees() const {
      return ActualCallees;
    }

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
      AU.addRequired<CompleteBUDataStructures>();
    }

  private:
    void buildIndirectFunctionSets(Module &M);

    unsigned processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack,
                        unsigned &NextID, 
                        std::map<DSGraph*, unsigned> &ValMap);
    void processGraph(DSGraph &FG);

    DSGraph &getOrCreateGraph(Function &F);
  };
}; // end llvm namespace