llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
forwarder.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 "core/adt/bitset.h"
8 #include "core/prog.h"
9 #include "core/func.h"
10 #include "core/dag.h"
11 #include "core/inst_visitor.h"
12 #include "passes/global_forward/nodes.h"
13 
14 class MovInst;
15 
16 
17 
21 class GlobalForwarder final {
22 public:
24  GlobalForwarder(Prog &prog, Func &entry);
25 
27  bool Forward();
29  bool Reverse();
30 
31 private:
33  struct FuncState {
35  DAGFunc &DAG;
37  unsigned Active;
39  unsigned Accurate;
41  std::unordered_map<unsigned, std::unique_ptr<NodeState>> States;
42 
43  FuncState(DAGFunc &dag)
44  : DAG(dag)
45  , Active(dag.rbegin()->Index)
46  , Accurate(Active)
47  {
48  }
49 
50  NodeState &GetState(unsigned index)
51  {
52  auto it = States.emplace(index, nullptr);
53  if (it.second) {
54  it.first->second.reset(new NodeState());
55  }
56  return *it.first->second;
57  }
58  };
59 
61  class Approximator : public InstVisitor<void> {
62  public:
63  Approximator(GlobalForwarder &state) : state_(state) {}
64 
65  void VisitInst(Inst &inst) override { }
66 
67  void VisitMovInst(MovInst &mov) override;
68  void VisitMemoryStoreInst(MemoryStoreInst &store) override;
69  void VisitMemoryLoadInst(MemoryLoadInst &load) override;
70  void VisitCallSite(CallSite &site) override;
71  void VisitTrapInst(TrapInst &) override { }
72  void VisitRaiseInst(RaiseInst &raise) override { Raises = true; }
73 
74  public:
76  bool Raises = false;
78  bool Indirect = false;
80  BitSet<Func> Funcs;
82  BitSet<Object> Escaped;
84  BitSet<Object> Loaded;
86  BitSet<Object> Stored;
87 
88  private:
90  GlobalForwarder &state_;
91  };
92 
94  class Simplifier final : public InstVisitor<bool> {
95  public:
96  Simplifier(
97  GlobalForwarder &state,
98  NodeState &node,
99  ReverseNodeState &reverse)
100  : state_(state)
101  , node_(node)
102  , reverse_(reverse)
103  {
104  }
105 
106  bool VisitInst(Inst &inst) override { return false; }
107 
108  bool VisitAddInst(AddInst &add) override;
109  bool VisitMovInst(MovInst &mov) override;
110  bool VisitMemoryStoreInst(MemoryStoreInst &store) override;
111  bool VisitMemoryLoadInst(MemoryLoadInst &load) override;
112  bool VisitMemoryExchangeInst(MemoryExchangeInst &xchg) override;
113 
114  bool VisitTerminatorInst(TerminatorInst &) override
115  {
116  llvm_unreachable("cannot evaluate terminator");
117  }
118 
119  protected:
121  GlobalForwarder &state_;
123  NodeState &node_;
125  ReverseNodeState &reverse_;
126  };
127 
128 
129 private:
131  void Escape(BitSet<Func> &funcs, BitSet<Object> &escaped, MovInst &mov);
133  void Indirect(
134  BitSet<Func> &funcs,
135  BitSet<Object> &escaped,
136  BitSet<Object> &storedImprecise,
137  BitSet<Object> &loadedImprecise,
138  bool &raises
139  );
141  void Raise(NodeState &node, ReverseNodeState &reverse);
142 
144  ID<Func> GetFuncID(Func &func)
145  {
146  auto it = funcToID_.find(&func);
147  assert(it != funcToID_.end() && "missing function");
148  return it->second;
149  }
150 
152  ID<Object> GetObjectID(Object *object)
153  {
154  auto it = objectToID_.find(object);
155  assert(it != objectToID_.end() && "missing object");
156  return it->second;
157  }
158 
160  DAGFunc &GetDAG(Func &func)
161  {
162  auto &dag = funcs_[GetFuncID(func)]->DAG;
163  if (!dag) {
164  dag.reset(new DAGFunc(func));
165  }
166  return *dag;
167  }
168 
170  ReverseNodeState &GetReverseNode(Func &func, unsigned index)
171  {
172  std::pair<Func *, unsigned> key(&func, index);
173  auto it = reverse_.emplace(key, nullptr);
174  if (it.second) {
175  it.first->second.reset(new ReverseNodeState(*(GetDAG(func)[index])));
176  }
177  return *it.first->second;
178  }
179 
180 private:
182  Prog &prog_;
184  Func &entry_;
185 
187  std::unordered_map<Object *, ID<Object>> objectToID_;
189  std::vector<std::unique_ptr<ObjectClosure>> objects_;
191  std::vector<Object *> idToObject_;
192 
194  std::unordered_map<Func *, ID<Func>> funcToID_;
196  std::vector<std::unique_ptr<FuncClosure>> funcs_;
197 
199  std::unordered_map
200  < std::pair<Func *, unsigned>
201  , std::unique_ptr<ReverseNodeState>
202  > reverse_;
203 
205  std::vector<FuncState> stack_;
206 };
Inst
Definition: inst.h:53
Func
Definition: func.h:30
GlobalForwarder::Forward
bool Forward()
Simplify loads and build the graph for the reverse transformations.
Definition: forwarder.cpp:186
ID< Func >
DAGFunc
Definition: dag.h:75
Object
Definition: object.h:43
MovInst
Definition: mov.h:17
BitSet< Func >
GlobalForwarder
Definition: forwarder.h:21
Prog
Definition: prog.h:33
InstVisitor
Definition: inst_visitor.h:15
DAGBlock::Index
const unsigned Index
Index of the DAG block (higher is closer to entry).
Definition: dag.h:22
GlobalForwarder::Reverse
bool Reverse()
Hoist stores.
Definition: reverse.cpp:17
ReverseNodeState
Definition: nodes.h:81
NodeState
Evaluation state of a node.
Definition: nodes.h:51
GlobalForwarder::GlobalForwarder
GlobalForwarder(Prog &prog, Func &entry)
Initialise the analysis.
Definition: forwarder.cpp:47