Thorin 1.9.0
The Higher ORder INtermediate representation
Loading...
Searching...
No Matches
scope.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4
5#include "thorin/rewrite.h"
6#include "thorin/world.h"
7
12#include "thorin/util/util.h"
13
14namespace thorin {
15
17 : world_(entry->world())
18 , entry_(entry)
19 , exit_(world().exit()) {
20 run();
21}
22
24
25void Scope::run() {
26 unique_queue<DefSet&> queue(bound_);
27
28 if (auto var = entry_->has_var()) {
29 queue.push(var);
30
31 while (!queue.empty()) {
32 for (auto use : queue.pop()->uses())
33 if (use != entry_ && use != exit_) queue.push(use);
34 }
35 }
36}
37
38void Scope::calc_bound() const {
39 if (has_bound_) return;
40 has_bound_ = true;
41
42 DefSet live;
43 unique_queue<DefSet&> queue(live);
44
45 auto enqueue = [&](const Def* def) {
46 if (def == nullptr) return;
47 if (def->dep_const()) return;
48
49 if (bound_.contains(def))
50 queue.push(def);
51 else
52 free_defs_.emplace(def);
53 };
54
55 for (auto op : entry()->partial_ops()) enqueue(op);
56
57 while (!queue.empty())
58 for (auto op : queue.pop()->partial_ops()) enqueue(op);
59
60 swap(live, bound_);
61}
62
63void Scope::calc_free() const {
64 if (has_free_) return;
65 has_free_ = true;
66
67 unique_queue<DefSet> queue;
68
69 auto enqueue = [&](const Def* def) {
70 if (def->dep_const()) return;
71
72 if (auto var = def->isa<Var>())
73 free_vars_.emplace(var);
74 else if (auto mut = def->isa_mut())
75 free_muts_.emplace(mut);
76 else
77 queue.push(def);
78 };
79
80 for (auto free : free_defs()) enqueue(free);
81
82 while (!queue.empty())
83 for (auto op : queue.pop()->extended_ops()) enqueue(op);
84}
85
86const CFA& Scope::cfa() const { return lazy_init(this, cfa_); }
87const F_CFG& Scope::f_cfg() const { return cfa().f_cfg(); }
88const B_CFG& Scope::b_cfg() const { return cfa().b_cfg(); }
89
90bool Scope::is_free(Def* mut, const Def* def) {
91 if (auto v = mut->var()) {
92 if (auto var = v->isa<Var>()) {
93 // optimize common cases first
94 if (def->num_ops() == 0) return false;
95 if (var == def) return true;
96 for (auto v : var->mut()->tvars())
97 if (v == def) return true;
98
99 Scope scope(mut);
100 return scope.bound(def);
101 }
102 }
103
104 return false;
105}
106
107} // namespace thorin
Control Flow Analysis.
Definition cfg.h:62
const B_CFG & b_cfg() const
Definition cfg.cpp:82
const F_CFG & f_cfg() const
Definition cfg.cpp:81
A Control-Flow Graph.
Definition cfg.h:116
Base class for all Defs.
Definition def.h:222
Ref var(nat_t a, nat_t i)
Definition def.h:403
size_t num_ops() const
Definition def.h:270
const Var * has_var()
Only returns not nullptr, if Var of this mutable has ever been created.
Definition def.h:407
A Scope represents a region of Defs that are live from the view of an entry's Var.
Definition scope.h:22
Scope(const Scope &)=delete
const CFA & cfa() const
Definition scope.cpp:86
const F_CFG & f_cfg() const
Definition scope.cpp:87
const DefSet & free_defs() const
All non-const Defs directly referenced but not bound within this Scope. May also include Vars or muts...
Definition scope.h:43
const B_CFG & b_cfg() const
Definition scope.cpp:88
static bool is_free(Def *mut, const Def *def)
Does mut's Var occurr free in def?
Definition scope.cpp:90
Def * entry() const
Definition scope.h:33
bool bound(const Def *def) const
Definition scope.h:40
Ref op(trait o, Ref type)
Definition core.h:35
Definition cfg.h:11
GIDSet< const Def * > DefSet
Definition def.h:60
auto pop(S &s) -> decltype(s.top(), typename S::value_type())
Definition util.h:78
T & lazy_init(const This *self, std::unique_ptr< T > &ptr)
Definition util.h:21