mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Use arena in calculate_global_init_order
This commit is contained in:
+81
-55
@@ -3006,22 +3006,37 @@ gb_internal bool is_entity_a_dependency(Entity *e) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info, gbAllocator allocator) {
|
gb_internal Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info, Arena *arena) {
|
||||||
PtrMap<Entity *, EntityGraphNode *> M = {};
|
PtrMap<Entity *, EntityGraphNode *> M_procs = {};
|
||||||
map_init(&M, info->entities.count);
|
PtrMap<Entity *, EntityGraphNode *> M_vars = {};
|
||||||
defer (map_destroy(&M));
|
PtrMap<Entity *, EntityGraphNode *> M_other = {};
|
||||||
|
|
||||||
|
map_init(&M_procs, info->entities.count);
|
||||||
|
defer (map_destroy(&M_procs));
|
||||||
|
|
||||||
|
map_init(&M_vars, info->entities.count);
|
||||||
|
defer (map_destroy(&M_vars));
|
||||||
|
|
||||||
|
map_init(&M_other, info->entities.count);
|
||||||
|
defer (map_destroy(&M_other));
|
||||||
|
|
||||||
for_array(i, info->entities) {
|
for_array(i, info->entities) {
|
||||||
Entity *e = info->entities[i];
|
Entity *e = info->entities[i];
|
||||||
if (is_entity_a_dependency(e)) {
|
if (!is_entity_a_dependency(e)) {
|
||||||
EntityGraphNode *n = gb_alloc_item(allocator, EntityGraphNode);
|
continue;
|
||||||
n->entity = e;
|
}
|
||||||
map_set(&M, e, n);
|
EntityGraphNode *n = arena_alloc_item<EntityGraphNode>(arena);
|
||||||
|
n->entity = e;
|
||||||
|
switch (e->kind) {
|
||||||
|
case Entity_Procedure: map_set(&M_procs, e, n); break;
|
||||||
|
case Entity_Variable: map_set(&M_vars, e, n); break;
|
||||||
|
default: map_set(&M_other, e, n); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1");
|
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1");
|
||||||
// Calculate edges for graph M
|
// Calculate edges for graph M
|
||||||
for (auto const &entry : M) {
|
for (auto const &entry : M_procs) {
|
||||||
EntityGraphNode *n = entry.value;
|
EntityGraphNode *n = entry.value;
|
||||||
Entity *e = n->entity;
|
Entity *e = n->entity;
|
||||||
|
|
||||||
@@ -3033,56 +3048,70 @@ gb_internal Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInf
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
GB_ASSERT(dep != nullptr);
|
GB_ASSERT(dep != nullptr);
|
||||||
if (is_entity_a_dependency(dep)) {
|
if (!is_entity_a_dependency(dep)) {
|
||||||
EntityGraphNode *m = map_must_get(&M, dep);
|
continue;
|
||||||
entity_graph_node_set_add(&n->succ, m);
|
|
||||||
entity_graph_node_set_add(&m->pred, n);
|
|
||||||
}
|
}
|
||||||
|
EntityGraphNode *m = nullptr;
|
||||||
|
|
||||||
|
switch (dep->kind) {
|
||||||
|
case Entity_Procedure: m = map_must_get(&M_procs, dep); break;
|
||||||
|
case Entity_Variable: m = map_must_get(&M_vars, dep); break;
|
||||||
|
default: m = map_must_get(&M_other, dep); break;
|
||||||
|
}
|
||||||
|
entity_graph_node_set_add(&n->succ, m);
|
||||||
|
entity_graph_node_set_add(&m->pred, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2");
|
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2a (init)");
|
||||||
auto G = array_make<EntityGraphNode *>(allocator, 0, M.count);
|
|
||||||
|
|
||||||
for (auto const &m_entry : M) {
|
auto G = array_make<EntityGraphNode *>(arena_allocator(arena), 0, M_procs.count + M_vars.count + M_other.count);
|
||||||
auto *e = m_entry.key;
|
|
||||||
|
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2b (procs)");
|
||||||
|
|
||||||
|
for (auto const &m_entry : M_procs) {
|
||||||
EntityGraphNode *n = m_entry.value;
|
EntityGraphNode *n = m_entry.value;
|
||||||
|
|
||||||
if (e->kind == Entity_Procedure) {
|
// Connect each pred 'p' of 'n' with each succ 's' and from
|
||||||
// Connect each pred 'p' of 'n' with each succ 's' and from
|
// the procedure node
|
||||||
// the procedure node
|
for (EntityGraphNode *p : n->pred) {
|
||||||
for (EntityGraphNode *p : n->pred) {
|
// Ignore self-cycles
|
||||||
// Ignore self-cycles
|
if (p == n) {
|
||||||
if (p != n) {
|
continue;
|
||||||
// Each succ 's' of 'n' becomes a succ of 'p', and
|
|
||||||
// each pred 'p' of 'n' becomes a pred of 's'
|
|
||||||
for (EntityGraphNode *s : n->succ) {
|
|
||||||
// Ignore self-cycles
|
|
||||||
if (s != n) {
|
|
||||||
if (p->entity->kind == Entity_Procedure &&
|
|
||||||
s->entity->kind == Entity_Procedure) {
|
|
||||||
// NOTE(bill, 2020-11-15): Only care about variable initialization ordering
|
|
||||||
// TODO(bill): This is probably wrong!!!!
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// IMPORTANT NOTE/TODO(bill, 2020-11-15): These three calls take the majority of the
|
|
||||||
// the time to process
|
|
||||||
entity_graph_node_set_add(&p->succ, s);
|
|
||||||
entity_graph_node_set_add(&s->pred, p);
|
|
||||||
// Remove edge to 'n'
|
|
||||||
entity_graph_node_set_remove(&s->pred, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove edge to 'n'
|
|
||||||
entity_graph_node_set_remove(&p->succ, n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (e->kind == Entity_Variable) {
|
// Each succ 's' of 'n' becomes a succ of 'p', and
|
||||||
array_add(&G, n);
|
// each pred 'p' of 'n' becomes a pred of 's'
|
||||||
|
for (EntityGraphNode *s : n->succ) {
|
||||||
|
// Ignore self-cycles
|
||||||
|
if (s == n) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (p->entity->kind == Entity_Procedure &&
|
||||||
|
s->entity->kind == Entity_Procedure) {
|
||||||
|
// NOTE(bill, 2020-11-15): Only care about variable initialization ordering
|
||||||
|
// TODO(bill): This is probably wrong!!!!
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// IMPORTANT NOTE/TODO(bill, 2020-11-15): These three calls take the majority of the
|
||||||
|
// the time to process
|
||||||
|
entity_graph_node_set_add(&p->succ, s);
|
||||||
|
entity_graph_node_set_add(&s->pred, p);
|
||||||
|
// Remove edge to 'n'
|
||||||
|
entity_graph_node_set_remove(&s->pred, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove edge to 'n'
|
||||||
|
entity_graph_node_set_remove(&p->succ, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2c (vars)");
|
||||||
|
|
||||||
|
for (auto const &m_entry : M_vars) {
|
||||||
|
EntityGraphNode *n = m_entry.value;
|
||||||
|
array_add(&G, n);
|
||||||
|
}
|
||||||
|
|
||||||
TIME_SECTION("generate_entity_dependency_graph: Dependency Count Checker");
|
TIME_SECTION("generate_entity_dependency_graph: Dependency Count Checker");
|
||||||
for_array(i, G) {
|
for_array(i, G) {
|
||||||
EntityGraphNode *n = G[i];
|
EntityGraphNode *n = G[i];
|
||||||
@@ -6012,13 +6041,10 @@ gb_internal void calculate_global_init_order(Checker *c) {
|
|||||||
CheckerInfo *info = &c->info;
|
CheckerInfo *info = &c->info;
|
||||||
|
|
||||||
TIME_SECTION("calculate_global_init_order: generate entity dependency graph");
|
TIME_SECTION("calculate_global_init_order: generate entity dependency graph");
|
||||||
Array<EntityGraphNode *> dep_graph = generate_entity_dependency_graph(info, heap_allocator());
|
Arena *arena = get_arena(ThreadArena_Temporary);
|
||||||
defer ({
|
ArenaTempGuard arena_guard(arena);
|
||||||
for_array(i, dep_graph) {
|
|
||||||
entity_graph_node_destroy(dep_graph[i], heap_allocator());
|
Array<EntityGraphNode *> dep_graph = generate_entity_dependency_graph(info, arena);
|
||||||
}
|
|
||||||
array_free(&dep_graph);
|
|
||||||
});
|
|
||||||
|
|
||||||
TIME_SECTION("calculate_global_init_order: priority queue create");
|
TIME_SECTION("calculate_global_init_order: priority queue create");
|
||||||
// NOTE(bill): Priority queue
|
// NOTE(bill): Priority queue
|
||||||
|
|||||||
@@ -113,6 +113,13 @@ gb_internal void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
gb_internal T *arena_alloc_item(Arena *arena) {
|
||||||
|
return cast(T *)arena_alloc(arena, gb_size_of(T), gb_align_of(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal void arena_free_all(Arena *arena) {
|
gb_internal void arena_free_all(Arena *arena) {
|
||||||
while (arena->curr_block != nullptr) {
|
while (arena->curr_block != nullptr) {
|
||||||
MemoryBlock *free_block = arena->curr_block;
|
MemoryBlock *free_block = arena->curr_block;
|
||||||
|
|||||||
Reference in New Issue
Block a user