llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
pass_manager.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/ArrayRef.h>
8 
9 #include <type_traits>
10 #include <unordered_map>
11 #include <vector>
12 #include <string>
13 #include <memory>
14 #include <set>
15 
16 #include "core/pass.h"
17 #include "core/analysis.h"
18 
19 class Pass;
20 class Target;
21 
22 
23 
27 enum class OptLevel {
29  O0,
31  O1,
33  O2,
35  O3,
37  O4,
39  Os,
40 };
41 
45 struct PassConfig {
47  OptLevel Opt = OptLevel::O0;
49  bool Static = false;
51  bool Shared = false;
53  std::string Entry;
54 
55  PassConfig() {}
56 
57  PassConfig(
58  OptLevel opt,
59  bool isStatic,
60  bool isShared,
61  std::string entry)
62  : Opt(opt)
63  , Static(isStatic)
64  , Shared(isShared)
65  , Entry(entry)
66  {
67  }
68 };
69 
70 
74 class PassManager final {
75 public:
77  const PassConfig &config,
78  const Target *target,
79  const std::string &saveBefore,
80  bool verbose,
81  bool time,
82  bool verify
83  );
84 
86  template<typename T, typename... Args>
87  void Add(const Args &... args)
88  {
89  if constexpr (std::is_base_of<Analysis, T>::value) {
90  groups_.emplace_back(std::make_unique<T>(this), &AnalysisID<T>::ID, T::kPassID);
91  } else {
92  groups_.emplace_back(std::make_unique<T>(this, args...), nullptr, T::kPassID);
93  }
94  }
95 
97  template<typename... Ts>
98  void Group()
99  {
100  std::vector<PassInfo> ps;
101  ((ps.emplace_back(std::make_unique<Ts>(this), nullptr, Ts::kPassID)), ...);
102  groups_.emplace_back(std::move(ps));
103  }
104 
106  void Add(Pass *pass);
108  void Run(Prog &prog);
109 
111  template<typename T> T* getAnalysis()
112  {
113  if (auto it = analyses_.find(&AnalysisID<T>::ID); it != analyses_.end()) {
114  return static_cast<T *>(it->second);
115  } else {
116  return nullptr;
117  }
118  }
119 
121  const PassConfig &GetConfig() const { return config_; }
123  const Target *GetTarget() const { return target_; }
124 
125 private:
127  struct PassInfo {
129  std::unique_ptr<Pass> P;
131  const char *ID;
133  const char *Name;
134 
135  PassInfo(std::unique_ptr<Pass> &&pass, const char *id, const char *name)
136  : P(std::move(pass))
137  , ID(id)
138  , Name(name)
139  {
140  }
141  };
142 
144  bool Run(PassInfo &pass, Prog &prog);
145 
147  struct GroupInfo {
149  std::vector<PassInfo> Passes;
151  bool Repeat;
152 
153  GroupInfo(std::unique_ptr<Pass> &&pass, const char * id, const char *name)
154  : Repeat(false)
155  {
156  Passes.emplace_back(std::move(pass), id, name);
157  }
158 
159  GroupInfo(std::vector<PassInfo> &&passes)
160  : Passes(std::move(passes))
161  , Repeat(true)
162  {
163  }
164  };
165 
167  PassConfig config_;
169  const Target *target_;
171  std::string saveBefore_;
173  bool verbose_;
175  bool time_;
177  bool verify_;
179  std::vector<GroupInfo> groups_;
181  std::unordered_map<const char *, Pass *> analyses_;
183  std::unordered_map<const char *, std::vector<double>> times_;
185  std::set<std::string> disabled_;
186 };
187 
188 
189 
190 // -----------------------------------------------------------------------------
191 template<typename T> T* Pass::getAnalysis()
192 {
193  return passManager_->getAnalysis<T>();
194 }
AnalysisID
Definition: analysis.h:12
PassManager
Definition: pass_manager.h:74
Pass
Definition: pass.h:17
PassManager::Add
void Add(const Args &... args)
Add an analysis into the pipeline.
Definition: pass_manager.h:87
PassConfig::Shared
bool Shared
Building a shared library.
Definition: pass_manager.h:51
PassConfig
Definition: pass_manager.h:45
Target
Definition: target.h:24
Pass::getAnalysis
T * getAnalysis()
Returns an available analysis.
Definition: pass_manager.h:191
PassManager::getAnalysis
T * getAnalysis()
Returns an available analysis.
Definition: pass_manager.h:111
ID
Definition: id.h:19
PassManager::GetTarget
const Target * GetTarget() const
Returns a reference to the target.
Definition: pass_manager.h:123
PassManager::Group
void Group()
Adds a group of passes to the pipeline.
Definition: pass_manager.h:98
PassManager::GetConfig
const PassConfig & GetConfig() const
Returns a reference to the configuration.
Definition: pass_manager.h:121
PassManager::Run
void Run(Prog &prog)
Runs the pipeline.
Definition: pass_manager.cpp:45
PassConfig::Static
bool Static
Building a static executable.
Definition: pass_manager.h:49
Prog
Definition: prog.h:33
Pass::passManager_
PassManager * passManager_
Pass manager scheduling this pass.
Definition: pass.h:51
PassConfig::Entry
std::string Entry
Name of the entry point.
Definition: pass_manager.h:53
PassConfig::Opt
OptLevel Opt
Optimisation level.
Definition: pass_manager.h:47