mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
d2r2: adjustments to type deduper; sketch out topologically-sorted type building path
This commit is contained in:
@@ -1016,6 +1016,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
U64 hash;
|
U64 hash;
|
||||||
U64 unit_idx;
|
U64 unit_idx;
|
||||||
U64 info_off;
|
U64 info_off;
|
||||||
|
U64 order_idx;
|
||||||
};
|
};
|
||||||
typedef struct UnitTypeNode UnitTypeNode;
|
typedef struct UnitTypeNode UnitTypeNode;
|
||||||
struct UnitTypeNode
|
struct UnitTypeNode
|
||||||
@@ -1332,7 +1333,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
//- rjf: produce [0...n) -> unique-tag-node mapping for all types
|
//- rjf: produce [0...n) <-> unique-tag-node mapping for all types
|
||||||
//
|
//
|
||||||
U64 type_count = 0;
|
U64 type_count = 0;
|
||||||
UniqueTypeTagNode **type_tag_nodes = 0;
|
UniqueTypeTagNode **type_tag_nodes = 0;
|
||||||
@@ -1352,6 +1353,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
for EachNode(n, UniqueTypeTagNode, unique_type_tag_slots[slot_idx])
|
for EachNode(n, UniqueTypeTagNode, unique_type_tag_slots[slot_idx])
|
||||||
{
|
{
|
||||||
type_tag_nodes[idx] = n;
|
type_tag_nodes[idx] = n;
|
||||||
|
n->order_idx = idx;
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1366,25 +1368,59 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
struct TypeDepChain
|
struct TypeDepChain
|
||||||
{
|
{
|
||||||
TypeDepChain *next;
|
TypeDepChain *next;
|
||||||
U64 hash;
|
U64 type_idx;
|
||||||
};
|
};
|
||||||
TypeDepChain **type_dep_chains = 0;
|
TypeDepChain **type_dep_chains = 0;
|
||||||
|
U64 *type_dep_chains_counts = 0;
|
||||||
ProfScope("gather per-type dependency chains")
|
ProfScope("gather per-type dependency chains")
|
||||||
{
|
{
|
||||||
if(lane_idx() == 0)
|
if(lane_idx() == 0)
|
||||||
{
|
{
|
||||||
type_dep_chains = push_array(scratch.arena, TypeDepChain *, type_count);
|
type_dep_chains = push_array(scratch.arena, TypeDepChain *, type_count);
|
||||||
|
type_dep_chains_counts = push_array(scratch.arena, U64, type_count);
|
||||||
}
|
}
|
||||||
lane_sync_u64(&type_dep_chains, 0);
|
lane_sync_u64(&type_dep_chains, 0);
|
||||||
|
lane_sync_u64(&type_dep_chains_counts, 0);
|
||||||
Rng1U64 range = lane_range(type_count);
|
Rng1U64 range = lane_range(type_count);
|
||||||
for EachInRange(type_idx, range)
|
for EachInRange(root_type_idx, range)
|
||||||
|
{
|
||||||
|
for(U64 hash = type_tag_nodes[root_type_idx]->hash, next_hash = 0;
|
||||||
|
hash != 0;
|
||||||
|
hash = next_hash)
|
||||||
{
|
{
|
||||||
Temp scratch2 = scratch_begin(&scratch.arena, 1);
|
Temp scratch2 = scratch_begin(&scratch.arena, 1);
|
||||||
|
|
||||||
// rjf: unpack type's tag node
|
// rjf: hash -> unique type tag node
|
||||||
UniqueTypeTagNode *type_tag_node = type_tag_nodes[type_idx];
|
UniqueTypeTagNode *type_tag_node = 0;
|
||||||
U64 info_off = type_tag_node->info_off;
|
{
|
||||||
U64 unit_idx = type_tag_node->unit_idx;
|
U64 slot_idx = hash%unique_type_tag_slots_count;
|
||||||
|
for(UniqueTypeTagNode *n = unique_type_tag_slots[slot_idx]; n != 0; n = n->next)
|
||||||
|
{
|
||||||
|
if(n->hash == hash)
|
||||||
|
{
|
||||||
|
type_tag_node = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rjf: unpack type tag node
|
||||||
|
U64 info_off = 0;
|
||||||
|
U64 unit_idx = 0;
|
||||||
|
if(type_tag_node != 0)
|
||||||
|
{
|
||||||
|
info_off = type_tag_node->info_off;
|
||||||
|
unit_idx = type_tag_node->unit_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rjf: record this type in the dependency chain
|
||||||
|
if(type_tag_node != 0)
|
||||||
|
{
|
||||||
|
TypeDepChain *c = push_array(scratch.arena, TypeDepChain, 1);
|
||||||
|
c->type_idx = type_tag_node->order_idx;
|
||||||
|
SLLStackPush(type_dep_chains[type_tag_node->order_idx], c);
|
||||||
|
type_dep_chains_counts[type_tag_node->order_idx] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
// rjf: unpack unit
|
// rjf: unpack unit
|
||||||
DW2_ParseCtx *unit_parse_ctx = &unit_parse_ctxs[unit_idx];
|
DW2_ParseCtx *unit_parse_ctx = &unit_parse_ctxs[unit_idx];
|
||||||
@@ -1440,13 +1476,109 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: if we got a hash -> record as dependency
|
// rjf: iterate to direct type's hash
|
||||||
if(direct_type_hash != 0)
|
next_hash = direct_type_hash;
|
||||||
{
|
|
||||||
TypeDepChain *chain = push_array(scratch.arena, TypeDepChain, 1);
|
scratch_end(scratch2);
|
||||||
chain->hash = direct_type_hash;
|
|
||||||
SLLStackPush(type_dep_chains[type_idx], chain);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
lane_sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
//- rjf: build all types - build types w/ 1 dependency (leaves) first, then 2, 3, etc.,
|
||||||
|
// to ensure dependencies always travel backwards
|
||||||
|
//
|
||||||
|
RDIM_TypeChunkList *all_types = 0;
|
||||||
|
RDIM_Type **type_from_idx_map = 0;
|
||||||
|
{
|
||||||
|
if(lane_idx() == 0)
|
||||||
|
{
|
||||||
|
all_types = push_array(scratch.arena, RDIM_TypeChunkList, 1);
|
||||||
|
type_from_idx_map = push_array(scratch.arena, RDIM_Type *, type_count);
|
||||||
|
}
|
||||||
|
lane_sync_u64(&all_types, 0);
|
||||||
|
lane_sync_u64(&type_from_idx_map, 0);
|
||||||
|
Rng1U64 range = lane_range(type_count);
|
||||||
|
U64 max_chain_count = 1;
|
||||||
|
for(;max_chain_count < max_U64;)
|
||||||
|
{
|
||||||
|
Temp scratch2 = scratch_begin(&scratch.arena, 1);
|
||||||
|
|
||||||
|
//- rjf: gather all types in this lane that fit the dependency restriction;
|
||||||
|
// find this lane's next dependency restriction
|
||||||
|
U64 next_max_chain_count = max_U64;
|
||||||
|
RDIM_TypeChunkList lane_types = {0};
|
||||||
|
for EachInRange(type_idx, range)
|
||||||
|
{
|
||||||
|
// rjf: if this type has a higher chain count than the current,
|
||||||
|
// but it is lower than our next maximum chain count, collect it,
|
||||||
|
// so we will hit
|
||||||
|
if(type_dep_chains_counts[type_idx] > max_chain_count)
|
||||||
|
{
|
||||||
|
next_max_chain_count = Min(type_dep_chains_counts[type_idx], next_max_chain_count);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Temp temp = temp_begin(scratch2.arena);
|
||||||
|
|
||||||
|
// rjf: idx -> type tag node
|
||||||
|
UniqueTypeTagNode *type_tag_node = type_tag_nodes[type_idx];
|
||||||
|
U64 unit_idx = type_tag_node->unit_idx;
|
||||||
|
U64 info_off = type_tag_node->info_off;
|
||||||
|
|
||||||
|
// rjf: unpack unit
|
||||||
|
Rng1U64 unit_info_tag_range = unit_info_tag_ranges[unit_idx];
|
||||||
|
DW2_ParseCtx *unit_parse_ctx = &unit_parse_ctxs[unit_idx];
|
||||||
|
|
||||||
|
// rjf: parse root-level tag
|
||||||
|
DW2_Tag tag = {0};
|
||||||
|
dw2_read_tag(temp.arena, unit_parse_ctx, raw->sec[DW_Section_Info].data, info_off, &tag);
|
||||||
|
|
||||||
|
// rjf: convert type
|
||||||
|
{
|
||||||
|
// TODO(rjf)
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_end(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: combine all types from all lanes
|
||||||
|
RDIM_TypeChunkList *lanes_types = 0;
|
||||||
|
if(lane_idx() == 0)
|
||||||
|
{
|
||||||
|
lanes_types = push_array(scratch2.arena, RDIM_TypeChunkList, lane_count());
|
||||||
|
}
|
||||||
|
lane_sync_u64(&lanes_types, 0);
|
||||||
|
lanes_types[lane_idx()] = lane_types;
|
||||||
|
lane_sync();
|
||||||
|
if(lane_idx() == 0)
|
||||||
|
{
|
||||||
|
RDIM_TypeChunkList pass_lane_combined_types = {0};
|
||||||
|
for EachIndex(l_idx, lane_count())
|
||||||
|
{
|
||||||
|
rdim_type_chunk_list_concat_in_place(&pass_lane_combined_types, &lanes_types[l_idx]);
|
||||||
|
}
|
||||||
|
rdim_type_chunk_list_concat_in_place(all_types, &pass_lane_combined_types);
|
||||||
|
}
|
||||||
|
lane_sync();
|
||||||
|
|
||||||
|
//- rjf: find minimum next max chain count across all lanes, for next iteration
|
||||||
|
U64 *lane_next_max_chain_counts = 0;
|
||||||
|
if(lane_idx() == 0)
|
||||||
|
{
|
||||||
|
lane_next_max_chain_counts = push_array(scratch2.arena, U64, lane_count());
|
||||||
|
}
|
||||||
|
lane_sync_u64(&lane_next_max_chain_counts, 0);
|
||||||
|
lane_next_max_chain_counts[lane_idx()] = next_max_chain_count;
|
||||||
|
lane_sync();
|
||||||
|
if(lane_idx() == 0)
|
||||||
|
{
|
||||||
|
for EachIndex(l_idx, lane_count())
|
||||||
|
{
|
||||||
|
next_max_chain_count = Min(next_max_chain_count, lane_next_max_chain_counts[l_idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lane_sync_u64(&next_max_chain_count, 0);
|
||||||
|
|
||||||
scratch_end(scratch2);
|
scratch_end(scratch2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user