llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
call_graph.h
1 // This file if part of the llir-opt project.
2 // Licensing information can be found in the LICENSE file.
3 // (C) 2018 Nandor Licker. All rights reserved.
4 
5 #pragma once
6 
7 #include <llvm/ADT/GraphTraits.h>
8 #include <llvm/ADT/PointerUnion.h>
9 #include <llvm/Support/DOTGraphTraits.h>
10 
11 #include "core/func.h"
12 #include "core/inst.h"
13 #include "core/prog.h"
14 
15 
16 
20 class CallGraph final {
21 public:
25  class Node {
26  public:
28  class iterator : public std::iterator<std::forward_iterator_tag, const Node *> {
29  public:
31  iterator(const Node *node, Inst *start);
33  iterator(const Node *node, Func *func);
35  iterator() : it_(static_cast<Inst *>(nullptr)) {}
36 
37  bool operator!=(const iterator &that) const { return !(*this == that); }
38  bool operator==(const iterator &that) const;
39 
40  iterator &operator++();
41 
42  iterator operator++(int)
43  {
44  iterator it(*this);
45  ++*this;
46  return it;
47  }
48 
49  const Node *operator*() const;
50 
51  private:
53  const Node *node_;
55  llvm::PointerUnion<Inst *, Func *> it_;
56  };
57 
58  public:
59 
61  Node(const CallGraph *graph, Prog *prog);
63  Node(const CallGraph *graph, Func *caller);
64 
66  iterator begin() const;
67  iterator end() const { return iterator(); }
68 
70  Func *GetCaller() const;
71 
73  bool IsRecursive() const;
74 
75  private:
76  friend class iterator;
78  const CallGraph *graph_;
80  llvm::PointerUnion<Func *, Prog *> node_;
81  };
82 
83 private:
84  using NodeMap = std::unordered_map<const Func *, std::unique_ptr<Node>>;
85 
86 public:
88  struct const_node_iterator : llvm::iterator_adaptor_base
89  < const_node_iterator
90  , NodeMap::const_iterator
91  , std::random_access_iterator_tag
92  , const Node *
93  >
94  {
95  explicit const_node_iterator(NodeMap::const_iterator it)
96  : iterator_adaptor_base(it)
97  {
98  }
99 
100  const Node *operator*() const { return I->second.get(); }
101  const Node *operator->() const { return I->second.get(); }
102  };
103 
104 public:
106  CallGraph(Prog &p);
107 
109  ~CallGraph();
110 
112  const Node *Entry() const { return &entry_; }
114  const Node *operator[](Func *f) const;
115 
117  const_node_iterator begin() const { return const_node_iterator(nodes_.begin()); }
118  const_node_iterator end() const { return const_node_iterator(nodes_.end()); }
119 
120 private:
121  friend class Node::iterator;
123  Node entry_;
125  mutable NodeMap nodes_;
126 };
127 
129 namespace llvm {
130 
131 template <>
132 struct GraphTraits<CallGraph::Node *> {
133  using NodeRef = const CallGraph::Node *;
134 
136  static ChildIteratorType child_begin(NodeRef n) { return n->begin(); }
137  static ChildIteratorType child_end(NodeRef n) { return n->end(); }
138 };
139 
141 template <>
142 struct GraphTraits<CallGraph *> : public GraphTraits<CallGraph::Node *> {
143  static NodeRef getEntryNode(const CallGraph *g) { return g->Entry(); }
144 
146  static nodes_iterator nodes_begin(CallGraph *g) { return g->begin(); }
147  static nodes_iterator nodes_end(CallGraph *g) { return g->end(); }
148 };
149 
150 template<>
151 struct DOTGraphTraits<CallGraph*> : public DefaultDOTGraphTraits {
152  DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
153 
154  static std::string getNodeLabel(
155  const CallGraph::Node *n,
156  const CallGraph *g)
157  {
158  if (auto *f = n->GetCaller()) {
159  return std::string(f->GetName());
160  } else {
161  return "root";
162  }
163  }
164 };
165 
166 }
CallGraph::Node::IsRecursive
bool IsRecursive() const
Checks if the node is a tail-recursive function.
Definition: call_graph.cpp:129
llvm
Graph traits for call graph nodes.
Definition: call_graph.h:129
Inst
Definition: inst.h:53
Func
Definition: func.h:30
CallGraph::const_node_iterator
Iterator over the nodes of the call graph.
Definition: call_graph.h:88
CallGraph::Node::Node
Node(const CallGraph *graph, Prog *prog)
Entry node.
Definition: call_graph.cpp:95
CallGraph::Node
Definition: call_graph.h:25
CallGraph
Definition: call_graph.h:20
CallGraph::Entry
const Node * Entry() const
Returns the virtual the entry node.
Definition: call_graph.h:112
CallGraph::Node::iterator::iterator
iterator()
End iterator.
Definition: call_graph.h:35
CallGraph::operator[]
const Node * operator[](Func *f) const
Returns the node for a function.
Definition: call_graph.cpp:156
CallGraph::Node::begin
iterator begin() const
Return iterators over the callees.
Definition: call_graph.cpp:107
Prog
Definition: prog.h:33
Node
Definition: node.h:43
CallGraph::begin
const_node_iterator begin() const
Iterator over nodes.
Definition: call_graph.h:117
CallGraph::CallGraph
CallGraph(Prog &p)
Creates a call graph for a program.
Definition: call_graph.cpp:142
CallGraph::~CallGraph
~CallGraph()
Cleanup.
Definition: call_graph.cpp:151
CallGraph::Node::iterator
Iterator over call site targets.
Definition: call_graph.h:28
CallGraph::Node::GetCaller
Func * GetCaller() const
Returns the function, null for entry.
Definition: call_graph.cpp:123
llvm::GraphTraits< CallGraph::Node * >
Definition: call_graph.h:132