1 #include <third-party/CLI11.h>
2 #include <utils/Error.h>
3 #include <utils/PassManager.h>
11 bool PassOptions::IsPassDisabled(Pass* p) {
12 auto it = pass_descs_.find(std::string{p->Name()});
13 if(it == pass_descs_.end())
return false;
14 return !it->second.enabled;
17 void PassOptions::setPassEnabled(Pass* p,
bool enabled) {
18 pass_descs_[std::string{p->Name()}].enabled = enabled;
25 void Pass::ComputeDependency(Pass& pass) {
32 if(state == PropagateEnabled) {
34 if(PM().PO().IsPassDisabled(
this))
return;
36 PM().PO().setPassEnabled(&pass,
true);
37 pass.state = PropagateEnabled;
38 pass.computeDependencies();
42 for(
auto& heap : PM().heaps_) {
43 if(heap.owner != &pass)
continue;
44 if(state == AcquireResources) {
46 }
else if(state == Cleanup) {
51 if(state == RegisterDependencies) {
52 PM().addDependency(*
this, pass);
58 void Pass::RegisterCLI() {
60 PO.pass_descs_[std::string{Name()}] =
61 PassOptions::PassDesc{
false, std::string{Desc()}};
64 Pass& Pass::GetPass(std::string_view name) {
return PM().getPass(name); }
72 if(pass.state != Pass::Running && pass.state != Pass::AcquireResources) {
73 throw utils::
FatalError(
"Pass requesting a heap is not running");
76 for(
auto& heap : heaps_) {
77 if(heap.owner !=
nullptr)
continue;
79 heap.refCount = pass.ShouldPreserve() ? 2 : 1;
81 return heap.heap.get();
84 heaps_.emplace_back(&pass);
85 return heaps_.back().heap.get();
88 void PassManager::freeHeap(Heap& h) {
96 if(Diag().Verbose(2)) {
97 Diag().ReportDebug() <<
"[=>] Freeing heap for " << h.owner->Desc();
109 void PassManager::Reset() {
110 for(
auto& heap : heaps_) {
111 heap.owner =
nullptr;
117 for(
auto& pass : passes_) {
118 PO().setPassEnabled(pass.get(),
false);
119 pass->state = Pass::Uninitialized;
123 bool PassManager::Run() {
124 std::vector<Pass*> S;
125 std::vector<Pass*> L;
127 for(
auto& pass : passes_) {
128 pass->state = Pass::PropagateEnabled;
129 pass->computeDependencies();
132 for(
auto& pass : passes_) {
134 if(PO().IsPassDisabled(pass.get()))
continue;
135 pass->state = Pass::AcquireResources;
139 for(
auto& pass : passes_) {
140 if(PO().IsPassDisabled(pass.get()))
continue;
141 pass->computeDependencies();
143 if(Diag().Verbose(2)) {
144 for(
auto& heap : heaps_) {
145 Diag().ReportDebug(2) <<
"[=>] Heap Owner: \"" << heap.owner->Desc()
146 <<
"\" RefCount: " << heap.refCount;
150 size_t NumEnabledPasses = 0;
151 for(
auto& pass : passes_) {
152 if(PO().IsPassDisabled(pass.get()))
continue;
154 passDeps_[pass.get()] = 0;
155 pass->state = Pass::RegisterDependencies;
156 pass->computeDependencies();
158 if(passDeps_[pass.get()] == 0) S.push_back(pass.get());
162 auto* n = *S.begin();
165 for(
auto* m : depgraph_[n]) {
166 if(--passDeps_[m] == 0) S.push_back(m);
168 depgraph_[n].clear();
171 if(L.size() != NumEnabledPasses)
172 throw utils::
FatalError(
"Cyclic pass dependency detected");
174 for(
auto& pass : L) {
175 assert(pass->state != Pass::Valid &&
"Pass already run");
176 pass->state = Pass::Running;
177 if(Diag().Verbose()) {
178 Diag().ReportDebug() <<
"[=>] Running " << pass->Desc() <<
" Pass";
182 if(Diag().hasErrors()) {
183 pass->state = Pass::Invalid;
185 }
else if(Diag().hasWarnings()) {
186 pass->state = Pass::Invalid;
191 pass->state = Pass::Cleanup;
192 pass->computeDependencies();
194 pass->state = Pass::Valid;