llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
cfg.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/Support/DOTGraphTraits.h>
9 
10 #include "core/block.h"
11 #include "core/func.h"
12 #include "core/insts.h"
13 #include "core/cast.h"
14 
15 
16 
18 template <>
19 struct llvm::GraphTraits<Block *> {
20  using NodeRef = Block *;
21  using ChildIteratorType = Block::succ_iterator;
22 
23  static NodeRef getEntryNode(Block *BB) { return BB; }
24  static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
25  static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
26 };
27 
28 template <>
29 struct llvm::GraphTraits<const Block *> {
30  using NodeRef = const Block *;
31  using ChildIteratorType = Block::const_succ_iterator;
32 
33  static NodeRef getEntryNode(const Block *BB) { return BB; }
34  static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
35  static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
36 };
37 
38 
40 template <>
41 struct llvm::GraphTraits<llvm::Inverse<Block*>> {
42  using NodeRef = Block *;
44 
45  static NodeRef getEntryNode(llvm::Inverse<Block *> G) { return G.Graph; }
46  static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
47  static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
48 };
49 
50 template <>
51 struct llvm::GraphTraits<llvm::Inverse<const Block*>> {
52  using NodeRef = const Block *;
54 
55  static NodeRef getEntryNode(llvm::Inverse<const Block *> G) { return G.Graph; }
56  static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
57  static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
58 };
59 
61 template <>
62 struct llvm::GraphTraits<Func *> : public llvm::GraphTraits<Block *> {
63  using nodes_iterator = pointer_iterator<Func::iterator>;
64 
65  static NodeRef getEntryNode(Func *F) { return &F->getEntryBlock(); }
66  static nodes_iterator nodes_begin(Func *F) {
67  return nodes_iterator(F->begin());
68  }
69 
70  static nodes_iterator nodes_end(Func *F) {
71  return nodes_iterator(F->end());
72  }
73 
74  static size_t size(Func *F) { return F->size(); }
75 };
76 
77 template<>
78 struct llvm::DOTGraphTraits<Func*> : public llvm::DefaultDOTGraphTraits {
79  DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
80 
81  static std::string getNodeLabel(const Block *block, const Func *f)
82  {
83  return std::string(block->getName());
84  }
85 
86  static std::string getNodeDescription(const Block *block, const Func *f)
87  {
88  std::string str;
89  llvm::raw_string_ostream os(str);
90  auto *term = block->GetTerminator();
91  if (auto *call = ::cast_or_null<const CallSite>(term)) {
92  if (auto *func = call->GetDirectCallee()) {
93  os << "call: " << func->getName();
94  } else {
95  os << "indirect call";
96  }
97  }
98  return str;
99  }
100 
101  static std::string getNodeAttributes(const Block *block, const Func *f)
102  {
103  std::string str;
104  llvm::raw_string_ostream os(str);
105  auto *term = block->GetTerminator();
106  if (auto *call = ::cast_or_null<const CallSite>(term)) {
107  if (auto *func = call->GetDirectCallee()) {
108  os << "color=purple";
109  } else {
110  os << "color=orange";
111  }
112  } else if (term->Is(Inst::Kind::TRAP) || term->Is(Inst::Kind::DEBUG_TRAP)) {
113  os << "color=red";
114  } else if (term->IsReturn()) {
115  os << "color=blue";
116  }
117  return str;
118  }
119 };
120 
121 template <>
122 struct llvm::GraphTraits<const Func *> : public llvm::GraphTraits<const Block *> {
123  using nodes_iterator = pointer_iterator<Func::const_iterator>;
124 
125  static NodeRef getEntryNode(const Func *F) { return &F->getEntryBlock(); }
126  static nodes_iterator nodes_begin(const Func *F) {
127  return nodes_iterator(F->begin());
128  }
129 
130  static nodes_iterator nodes_end(const Func *F) {
131  return nodes_iterator(F->end());
132  }
133 
134  static size_t size(const Func *F) { return F->size(); }
135 };
136 
138 template <>
139 struct llvm::GraphTraits<llvm::Inverse<Func*>> : public llvm::GraphTraits<llvm::Inverse<Block*>> {
140  static NodeRef getEntryNode(llvm::Inverse<Func *> G) {
141  return &G.Graph->getEntryBlock();
142  }
143 };
144 
145 template <>
146 struct llvm::GraphTraits<llvm::Inverse<const Func*>> : public llvm::GraphTraits<llvm::Inverse<const Block*>> {
147  static NodeRef getEntryNode(llvm::Inverse<const Func *> G) {
148  return &G.Graph->getEntryBlock();
149  }
150 };
llvm
Graph traits for call graph nodes.
Definition: call_graph.h:129
Func
Definition: func.h:30
Func::size
size_t size() const
Returns the size of the function.
Definition: func.h:175
Global::getName
llvm::StringRef getName() const
Returns the name of the basic block for LLVM.
Definition: global.h:54
Func::getEntryBlock
Block & getEntryBlock()
Returns the entry block.
Definition: func.cpp:175
llvm::GraphTraits< const Block * >
Definition: cfg.h:29
Block::GetTerminator
TerminatorInst * GetTerminator()
Returns the terminator of the block.
Definition: block.cpp:119
Block
Definition: block.h:29
Block::PredIterator
Iterator over the predecessors of a block.
Definition: block.h:50
llvm::GraphTraits< Block * >
Traits for blocks.
Definition: cfg.h:19