Skip to content

Commit

Permalink
Merge pull request #115 from AnyDSL/app-node
Browse files Browse the repository at this point in the history
Implement an app node
  • Loading branch information
leissa authored May 6, 2022
2 parents 719833f + 3c61b98 commit fb77d69
Show file tree
Hide file tree
Showing 45 changed files with 1,338 additions and 1,193 deletions.
5 changes: 3 additions & 2 deletions src/thorin/analyses/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,16 @@ CFA::CFA(const Scope& scope)

auto enqueue = [&] (const Def* def) {
if (def->order() > 0 && scope.contains(def) && done.emplace(def).second) {
if (auto dst = def->isa_continuation()) {
if (auto dst = def->isa_nom<Continuation>()) {
cfg_enqueue(dst);
node(src)->link(node(dst));
} else
queue.push(def);
}
};

queue.push(src);
if (src->has_body())
queue.push(src->body());

while (!queue.empty()) {
auto def = pop(queue);
Expand Down
20 changes: 10 additions & 10 deletions src/thorin/analyses/free_defs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,27 @@ DefSet free_defs(const Scope& scope, bool include_closures) {
};

for (auto def : scope.defs()) {
if (auto continuation = def->isa_continuation())
enqueue_ops(continuation);
if (auto nom = def->isa_nom())
enqueue_ops(nom);
}

while (!queue.empty()) {
auto def = pop(queue);
if (auto primop = def->isa<PrimOp>()) {
if (!include_closures && primop->isa<Closure>()) {
result.emplace(primop);
queue.push(primop->op(1));
if (def->isa_structural()) {
if (!include_closures && def->isa<Closure>()) {
result.emplace(def);
queue.push(def->op(1));
goto queue_next;
}
for (auto op : primop->ops()) {
for (auto op : def->ops()) {
if ((op->isa<MemOp>() || op->type()->isa<FrameType>()) && !scope.contains(op)) {
result.emplace(primop);
result.emplace(def);
goto queue_next;
}
}

// HACK for bitcasting address spaces
if (auto bitcast = primop->isa<Bitcast>()) {
if (auto bitcast = def->isa<Bitcast>()) {
if (auto dst_ptr = bitcast->type()->isa<PtrType>()) {
if (auto src_ptr = bitcast->from()->type()->isa<PtrType>()) {
if ( dst_ptr->pointee()->isa<IndefiniteArrayType>()
Expand All @@ -50,7 +50,7 @@ DefSet free_defs(const Scope& scope, bool include_closures) {
}
}

enqueue_ops(primop);
enqueue_ops(def);
} else if (!scope.contains(def))
result.emplace(def);
queue_next:;
Expand Down
6 changes: 3 additions & 3 deletions src/thorin/analyses/schedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ Continuation* Scheduler::early(const Def* def) {
if (auto param = def->isa<Param>()) return early_[def] = param->continuation();

auto result = scope().entry();
for (auto op : def->as<PrimOp>()->ops()) {
if (!op->isa_continuation() && def2uses_.find(op) != def2uses_.end()) {
for (auto op : def->as_structural()->ops()) {
if (!op->isa_nom<Continuation>() && def2uses_.find(op) != def2uses_.end()) {
auto cont = early(op);
if (domtree().depth(cfg(cont)) > domtree().depth(cfg(result)))
result = cont;
Expand All @@ -64,7 +64,7 @@ Continuation* Scheduler::late(const Def* def) {
if (auto cont = late_.lookup(def)) return *cont;

Continuation* result = nullptr;
if (auto continuation = def->isa_continuation()) {
if (auto continuation = def->isa_nom<Continuation>()) {
result = continuation;
} else if (auto param = def->isa<Param>()) {
result = param->continuation();
Expand Down
16 changes: 8 additions & 8 deletions src/thorin/analyses/scope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ void Scope::run() {
if (defs_.insert(def).second) {
queue.push(def);

if (auto continuation = def->isa_continuation()) {
if (auto continuation = def->isa_nom<Continuation>()) {
// when a continuation is part of this scope, we also enqueue its params, and we assert those to be unique
// TODO most likely redundant once params have the continuation in their ops
for (auto param : continuation->params()) {
auto p = defs_.insert(param);
assert_unused(p.second);
Expand Down Expand Up @@ -82,7 +84,7 @@ const ParamSet& Scope::free_params() const {
unique_queue<DefSet> queue;

auto enqueue = [&](const Def* def) {
if (auto param = def->isa<Param>())
if (auto param = def->isa<Param>(); param && !param->continuation()->dead_)
free_params_->emplace(param);
else if (def->isa<Continuation>())
return;
Expand All @@ -92,7 +94,6 @@ const ParamSet& Scope::free_params() const {

for (auto def : free())
enqueue(def);

while (!queue.empty()) {
for (auto op : queue.pop()->ops())
enqueue(op);
Expand All @@ -110,14 +111,13 @@ template<bool elide_empty>
void Scope::for_each(const World& world, std::function<void(Scope&)> f) {
unique_queue<ContinuationSet> continuation_queue;

for (auto continuation : world.exported_continuations()) {
assert(!continuation->empty() && "exported continuation must not be empty");
continuation_queue.push(continuation);
for (auto&& [_, cont] : world.externals()) {
if (cont->has_body()) continuation_queue.push(cont);
}

while (!continuation_queue.empty()) {
auto continuation = continuation_queue.pop();
if (elide_empty && continuation->empty())
if (elide_empty && !continuation->has_body())
continue;
Scope scope(continuation);
f(scope);
Expand All @@ -128,7 +128,7 @@ void Scope::for_each(const World& world, std::function<void(Scope&)> f) {

while (!def_queue.empty()) {
auto def = def_queue.pop();
if (auto continuation = def->isa_continuation())
if (auto continuation = def->isa_nom<Continuation>())
continuation_queue.push(continuation);
else {
for (auto op : def->ops())
Expand Down
82 changes: 12 additions & 70 deletions src/thorin/analyses/verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,91 +5,33 @@

namespace thorin {

// TODO this needs serious rewriting

static void verify_calls(World& world) {
for (auto continuation : world.continuations())
continuation->verify();
for (auto def : world.defs()) {
if (auto cont = def->isa<Continuation>())
cont->verify();
}
}

static void verify_top_level(World& world) {
static bool verify_top_level(World& world) {
bool ok = true;
Scope::for_each(world, [&] (const Scope& scope) {
if (scope.has_free_params()) {
for (auto param : scope.free_params())
world.ELOG("top-level continuation '{}' got free param '{}' belonging to continuation {}", scope.entry(), param, param->continuation());
world.ELOG("here: {}", scope.entry());
ok = false;
}
});
}

class Cycles {
public:
enum Color {
Gray, Black
};

Cycles(World& world)
: world_(world)
{
size_t num = world.primops().size();
for (auto continuation : world.continuations())
num += 1 + continuation->num_params();
def2color_.rehash(round_to_power_of_2(num));
}

World& world() { return world_; }
void run();
void analyze_call(const Continuation*);
void analyze(ParamSet& params, const Continuation*, const Def*);

private:
World& world_;
DefMap<Color> def2color_;
};

void Cycles::run() {
for (auto continuation : world().continuations())
analyze_call(continuation);
}

void Cycles::analyze_call(const Continuation* continuation) {
if (def2color_.emplace(continuation, Gray).second) {
ParamSet params;
for (auto op : continuation->ops())
analyze(params, continuation, op);

for (auto param : params) {
if (def2color_.emplace(param, Gray).second) {
analyze_call(param->continuation());
def2color_[param] = Black;
}
}

def2color_[continuation] = Black;
} else
assertf(def2color_[continuation] != Gray, "detected cycle: '{}'", continuation);
}

void Cycles::analyze(ParamSet& params, const Continuation* continuation, const Def* def) {
if (auto primop = def->isa<PrimOp>()) {
if (def2color_.emplace(def, Black).second) {
for (auto op : primop->ops())
analyze(params, continuation, op);
}
} else if (auto param = def->isa<Param>()) {
if (param->continuation() != continuation) {
auto i = def2color_.find(param);
if (i != def2color_.end())
assertf(i->second != Gray, "detected cycle induced by parameter: '{}'", param);
else
params.emplace(param);
}
}
if (!ok)
world.dump();
return ok;
}

void verify(World& world) {
verify_calls(world);
verify_top_level(world);
Cycles cycles(world);
cycles.run();
}

}
Loading

0 comments on commit fb77d69

Please sign in to comment.