Skip to content

Commit 11a00b4

Browse files
author
Roland Leißa
committed
just refactoring/simplifiny a couple of rewrite related things
1 parent 6ff3037 commit 11a00b4

File tree

6 files changed

+59
-93
lines changed

6 files changed

+59
-93
lines changed

thorin/be/emitter.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ class Emitter : public ScopePhase {
1313
constexpr const Child& child() const { return *static_cast<const Child*>(this); };
1414
constexpr Child& child() { return *static_cast<Child*>(this); };
1515

16-
/// Integer wrapper for Emitter::emit that checks and retrieves/puts the `Value` from
17-
/// Emitter::locals_/Emitter::globals_.
16+
/// Internal wrapper for Emitter::emit that schedules @p def and invokes `child().emit_bb`.
1817
Value emit_(const Def* def) {
1918
auto place = scheduler_.smart(def);
2019
auto& bb = lam2bb_[place->as_nom<Lam>()];

thorin/def.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,6 @@ class Def : public RuntimeCast<Def> {
357357
/// @name var
358358
///@{
359359
/// Retrieve Var for *nominals*.
360-
361360
const Var* var(const Def* dbg = {});
362361
THORIN_PROJ(var, )
363362
///@}

thorin/phase/phase.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,17 @@
22

33
namespace thorin {
44

5-
std::pair<const Def*, bool> PhaseRewriter::pre_rewrite(const Def* def) { return phase.pre_rewrite(def); }
6-
std::pair<const Def*, bool> PhaseRewriter::post_rewrite(const Def* def) { return phase.post_rewrite(def); }
7-
85
void Phase::run() {
96
world().ILOG("=== {}: start ===", name());
107
start();
118
world().ILOG("=== {}: done ===", name());
129
}
1310

1411
void RWPhase::start() {
15-
for (const auto& [_, ax] : world().axioms()) rewrite(ax);
16-
for (const auto& [_, nom] : world().externals()) rewrite(nom)->as_nom()->make_external();
12+
for (const auto& [_, ax] : old_world().axioms()) rewrite(ax);
13+
for (const auto& [_, nom] : old_world().externals()) rewrite(nom)->as_nom()->make_external();
1714

18-
swap(world_, new_world());
15+
swap(world_, new_world_);
1916
}
2017

2118
void FPPhase::start() {

thorin/phase/phase.h

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -47,52 +47,34 @@ class Phase {
4747
bool dirty_;
4848
};
4949

50-
class RWPhase;
51-
52-
class PhaseRewriter : public Rewriter {
53-
public:
54-
PhaseRewriter(RWPhase& phase, World& old_world, World& new_world)
55-
: Rewriter(old_world, new_world)
56-
, phase(phase) {}
57-
58-
std::pair<const Def*, bool> pre_rewrite(const Def*) override;
59-
std::pair<const Def*, bool> post_rewrite(const Def*) override;
60-
61-
RWPhase& phase;
62-
};
63-
64-
/// Visits the current Phase::world and constructs a new World Phase::new_world along the way.
50+
/// Visits the current Phase::world and constructs a new RWPhase::world along the way.
6551
/// It recursively **rewrites** all World::externals().
6652
class RWPhase : public Phase {
6753
public:
68-
RWPhase(World& world, std::string_view name)
69-
: Phase(world, name, false)
70-
, new_world_(world.state())
71-
, rewriter_(*this, world, new_world_) {}
54+
RWPhase(World& old_world, std::string_view name)
55+
: Phase(old_world, name, false)
56+
, new_world_(old_world.state())
57+
, rewriter_(new_world_) {}
7258

7359
void start() override;
7460

7561
/// @name getters
7662
///@{
77-
const World& old_world() { return world(); }
78-
World& new_world() { return new_world_; }
79-
Def2Def& old2new() { return rewriter_.old2new; }
63+
const World& old_world() { return world_; }
64+
World& world() { return new_world_; } ///< RWPhase::new_world_ is the "default" world.
65+
const Def* map(const Def* old_def, const Def* new_def) { return rewriter_.map(old_def, new_def); }
8066
///@}
8167

8268
/// @name rewrite
8369
///@{
84-
85-
/// See thorin::Rewriter::rewrite.
86-
const Def* rewrite(const Def* old_def) { return rewriter_.rewrite(old_def); }
87-
/// See thorin::Rewriter::pre_rewrite.
88-
virtual std::pair<const Def*, bool> pre_rewrite(const Def*) { return {nullptr, false}; }
89-
/// See thorin::Rewriter::post_rewrite.
90-
virtual std::pair<const Def*, bool> post_rewrite(const Def*) { return {nullptr, false}; }
70+
virtual const Def* rewrite(const Def* old_def) { return rewriter_.rewrite(old_def); }
71+
virtual const Def* rewrite_structural(const Def* old_def) { return rewriter_.rewrite_structural(old_def); }
72+
virtual const Def* rewrite_nom(Def* old_nom) { return rewriter_.rewrite_nom(old_nom); }
9173
///@}
9274

9375
protected:
9476
World new_world_;
95-
PhaseRewriter rewriter_;
77+
Rewriter rewriter_;
9678
};
9779

9880
/// Removes unreachable and dead code by rebuilding the whole World into a new one and `swap`ping afterwards.

thorin/rewrite.cpp

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,44 @@
77
namespace thorin {
88

99
const Def* Rewriter::rewrite(const Def* old_def) {
10-
if (auto i = old2new.find(old_def); i != old2new.end()) return i->second;
11-
12-
if (auto [pre, recurse] = pre_rewrite(old_def); pre) {
13-
auto new_def = recurse ? rewrite(pre) : pre;
14-
return old2new[pre] = new_def;
15-
}
16-
17-
auto new_type = old_def->type() ? rewrite(old_def->type()) : nullptr;
18-
auto new_dbg = old_def->dbg() ? rewrite(old_def->dbg()) : nullptr;
10+
if (!old_def) return nullptr;
11+
if (old_def->isa<Univ>()) return world().univ();
12+
if (auto i = old2new_.find(old_def); i != old2new_.end()) return i->second;
1913

2014
if (auto infer = old_def->isa_nom<Infer>()) {
2115
if (auto op = infer->op()) return rewrite(op);
2216
}
2317

24-
if (auto old_nom = old_def->isa_nom()) {
25-
auto new_nom = old_nom->stub(new_world, new_type, new_dbg);
26-
old2new[old_nom] = new_nom;
27-
28-
for (size_t i = 0, e = old_nom->num_ops(); i != e; ++i) {
29-
if (auto old_op = old_nom->op(i)) new_nom->set(i, rewrite(old_op));
30-
}
31-
32-
if (auto new_def = new_nom->restructure()) return old2new[old_nom] = new_def;
18+
if (auto old_nom = old_def->isa_nom()) return rewrite_nom(old_nom);
3319

34-
return new_nom;
35-
}
20+
auto new_def = rewrite_structural(old_def);
21+
return map(old_def, new_def);
22+
}
3623

24+
const Def* Rewriter::rewrite_structural(const Def* old_def) {
25+
auto new_type = rewrite(old_def->type());
26+
auto new_dbg = rewrite(old_def->dbg());
3727
DefArray new_ops(old_def->num_ops(), [&](auto i) { return rewrite(old_def->op(i)); });
38-
auto new_def = old_def->rebuild(new_world, new_type, new_ops, new_dbg);
28+
return old_def->rebuild(world(), new_type, new_ops, new_dbg);
29+
}
30+
31+
const Def* Rewriter::rewrite_nom(Def* old_nom) {
32+
auto new_type = rewrite(old_nom->type());
33+
auto new_dbg = rewrite(old_nom->dbg());
34+
auto new_nom = old_nom->stub(world(), new_type, new_dbg);
35+
map(old_nom, new_nom);
3936

40-
if (auto [post, recurse] = post_rewrite(new_def); post) {
41-
auto new_def = recurse ? rewrite(post) : post;
42-
return old2new[post] = new_def;
37+
for (size_t i = 0, e = old_nom->num_ops(); i != e; ++i) {
38+
if (auto old_op = old_nom->op(i)) new_nom->set(i, rewrite(old_op));
4339
}
4440

45-
return old2new[old_def] = new_def;
41+
if (auto new_def = new_nom->restructure()) return map(old_nom, new_def);
42+
return new_nom;
4643
}
4744

4845
const Def* rewrite(const Def* def, const Def* old_def, const Def* new_def, const Scope& scope) {
4946
ScopeRewriter rewriter(def->world(), scope);
50-
rewriter.old2new[old_def] = new_def;
47+
rewriter.map(old_def, new_def);
5148
return rewriter.rewrite(def);
5249
}
5350

@@ -62,7 +59,7 @@ const Def* rewrite(Def* nom, const Def* arg, size_t i) {
6259

6360
DefArray rewrite(Def* nom, const Def* arg, const Scope& scope) {
6461
ScopeRewriter rewriter(nom->world(), scope);
65-
rewriter.old2new[nom->var()] = arg;
62+
rewriter.map(nom->var(), arg);
6663
return DefArray(nom->num_ops(), [&](size_t i) { return rewriter.rewrite(nom->op(i)); });
6764
}
6865

thorin/rewrite.h

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,43 @@
66

77
namespace thorin {
88

9-
/// Rewrites part of a program.
9+
/// Recurseivly rewrites part of a program **into** the provided World.
10+
/// This World may be different than the World we started with.
1011
class Rewriter {
1112
public:
12-
Rewriter(World& old_world, World& new_world)
13-
: old_world(old_world)
14-
, new_world(new_world) {
15-
old2new[old_world.univ()] = new_world.univ();
16-
}
1713
Rewriter(World& world)
18-
: Rewriter(world, world) {}
14+
: world_(world) {}
1915

20-
/// @name rewrite
21-
///@{
16+
World& world() { return world_; }
2217

23-
/// Recursively rewrites @p old_def.
24-
/// Invokes Rewriter::pre_rewrite at the beginning and Rewriter::post_rewrite at the end.
25-
virtual const Def* rewrite(const Def* old_def);
26-
27-
/// Rewrite a given Def in pre-order.
28-
/// @return
29-
/// * `{nullptr, false}` to do nothing
30-
/// * `{new_def, false}` to return `new_def` **without** recursing on `new_def` again
31-
/// * `{new_def, true}` to return `new_def` **with** recursing on `new_def` again
32-
virtual std::pair<const Def*, bool> pre_rewrite(const Def*) { return {nullptr, false}; }
33-
/// As above but in post-order.
34-
virtual std::pair<const Def*, bool> post_rewrite(const Def*) { return {nullptr, false}; }
18+
/// @name recursively rewrite old Defs
19+
///@{
20+
const Def* map(const Def* old_def, const Def* new_def) { return old2new_[old_def] = new_def; }
21+
virtual const Def* rewrite(const Def*);
22+
virtual const Def* rewrite_structural(const Def*);
23+
virtual const Def* rewrite_nom(Def*);
3524
///@}
3625

37-
World& old_world;
38-
World& new_world;
39-
Def2Def old2new;
26+
private:
27+
World& world_;
28+
Def2Def old2new_;
4029
};
4130

4231
class ScopeRewriter : public Rewriter {
4332
public:
4433
ScopeRewriter(World& world, const Scope& scope)
4534
: Rewriter(world)
46-
, scope(scope) {}
35+
, scope_(scope) {}
36+
37+
const Scope& scope() const { return scope_; }
4738

4839
const Def* rewrite(const Def* old_def) override {
49-
if (!scope.bound(old_def)) return old_def;
40+
if (!old_def || !scope().bound(old_def)) return old_def;
5041
return Rewriter::rewrite(old_def);
5142
}
5243

53-
const Scope& scope;
44+
private:
45+
const Scope& scope_;
5446
};
5547

5648
/// Rewrites @p def by mapping @p old_def to @p new_def while obeying @p scope.

0 commit comments

Comments
 (0)