diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index afd48835..9dd34f37 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -1534,10 +1534,10 @@ rdim_bake_string_chunk_list_concat_in_place(RDIM_BakeStringChunkList *dst, RDIM_ rdim_memzero_struct(to_push); } - -RSFORCEINLINE int rdim_bake_string_hash_is_before(void *elementa, void *elementb) +RSFORCEINLINE int +rdim_bake_string_is_before(void *l, void *r) { - return ((RDIM_BakeString *)elementa)->hash < ((RDIM_BakeString *)elementb)->hash; + return ((RDIM_BakeString *)l)->hash < ((RDIM_BakeString *)r)->hash; } RDI_PROC RDIM_BakeStringChunkList @@ -1558,7 +1558,7 @@ rdim_bake_string_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeStr //- rjf: sort chunk node if(dst.first != 0) { - radsort(dst.first->v, dst.first->count, rdim_bake_string_hash_is_before); + radsort(dst.first->v, dst.first->count, rdim_bake_string_is_before); } //- rjf: iterate sorted chunk node, remove duplicates, count # of duplicates @@ -1611,7 +1611,6 @@ rdim_bake_string_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeStr } } - return dst; } @@ -1737,6 +1736,173 @@ rdim_bake_idx_from_string(RDIM_BakeStringMapTight *map, RDIM_String8 string) return idx; } +//- rjf: bake name chunk list + +RDI_PROC RDIM_BakeName * +rdim_bake_name_chunk_list_push(RDIM_Arena *arena, RDIM_BakeNameChunkList *list, RDI_U64 cap) +{ + RDIM_BakeNameChunkNode *n = list->last; + if(n == 0 || n->count >= n->cap) + { + n = rdim_push_array(arena, RDIM_BakeNameChunkNode, 1); + n->cap = cap; + n->base_idx = list->total_count; + n->v = rdim_push_array(arena, RDIM_BakeName, n->cap); + RDIM_SLLQueuePush(list->first, list->last, n); + list->chunk_count += 1; + } + RDIM_BakeName *result = &n->v[n->count]; + n->count += 1; + list->total_count += 1; + return result; +} + +RDI_PROC void +rdim_bake_name_chunk_list_concat_in_place(RDIM_BakeNameChunkList *dst, RDIM_BakeNameChunkList *to_push) +{ + for(RDIM_BakeNameChunkNode *n = to_push->first; n != 0; n = n->next) + { + n->base_idx += dst->total_count; + } + if(dst->last != 0 && to_push->first != 0) + { + dst->last->next = to_push->first; + dst->last = to_push->last; + dst->chunk_count += to_push->chunk_count; + dst->total_count += to_push->total_count; + } + else if(dst->first == 0) + { + rdim_memcpy_struct(dst, to_push); + } + rdim_memzero_struct(to_push); +} + +RSFORCEINLINE int +rdim_bake_name_is_before(void *l, void *r) +{ + return ((RDIM_BakeName *)l)->hash < ((RDIM_BakeName *)r)->hash; +} + +RDI_PROC RDIM_BakeNameChunkList +rdim_bake_name_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeNameChunkList *src) +{ + //- rjf: produce unsorted destination list with single chunk node + RDIM_BakeNameChunkList dst = {0}; + for(RDIM_BakeNameChunkNode *n = src->first; n != 0; n = n->next) + { + for(RDI_U64 idx = 0; idx < n->count; idx += 1) + { + RDIM_BakeName *src_str = &n->v[idx]; + RDIM_BakeName *dst_str = rdim_bake_name_chunk_list_push(arena, &dst, src->total_count); + rdim_memcpy_struct(dst_str, src_str); + } + } + + //- rjf: sort chunk node + if(dst.first != 0) + { + radsort(dst.first->v, dst.first->count, rdim_bake_name_is_before); + } + + //- rjf: iterate sorted chunk node, remove duplicates, count # of duplicates + RDI_U64 num_duplicates = 0; + if(dst.first != 0) + { + RDI_U64 last_idx = 0; + for(RDI_U64 idx = 1; idx < dst.first->count; idx += 1) + { + if(rdim_str8_match(dst.first->v[last_idx].string, dst.first->v[idx].string, 0)) + { + rdim_memzero_struct(&dst.first->v[idx]); + num_duplicates += 1; + } + else + { + last_idx = idx; + } + } + } + + //- rjf: iterate sorted chunk node, make non-empty elements contiguous + if(num_duplicates != 0) + { + RDI_U64 last_idx = 0; + for(RDI_U64 idx = 1; idx < dst.first->count; idx += 1) + { + if(last_idx == 0 && + dst.first->v[idx].string.RDIM_String8_SizeMember == 0 && + dst.first->v[idx].hash == 0) + { + last_idx = idx; + } + if(last_idx != 0 && dst.first->v[idx].string.RDIM_String8_SizeMember != 0) + { + rdim_memcpy_struct(&dst.first->v[last_idx], &dst.first->v[idx]); + rdim_memzero_struct(&dst.first->v[idx]); + last_idx += 1; + } + } + + //- rjf: pop extras + if(num_duplicates != 0) + { + RDI_U64 arena_pos_pre_pop = rdim_arena_pos(arena); + rdim_arena_pop_to(arena, arena_pos_pre_pop - num_duplicates*sizeof(dst.first->v[0])); + dst.first->count -= num_duplicates; + dst.first->cap -= num_duplicates; + dst.total_count -= num_duplicates; + } + } + + return dst; +} + +//- rjf: bake name chunk list maps + +RDI_PROC RDIM_BakeNameMap2 * +rdim_bake_name_map_2_make(RDIM_Arena *arena, RDIM_BakeNameMapTopology *top) +{ + RDIM_BakeNameMap2 *map = rdim_push_array(arena, RDIM_BakeNameMap2, 1); + map->slots = rdim_push_array(arena, RDIM_BakeNameChunkList *, top->slots_count); + return map; +} + +RDI_PROC void +rdim_bake_name_map_2_insert(RDIM_Arena *arena, RDIM_BakeNameMapTopology *map_topology, RDIM_BakeNameMap2 *map, RDI_U64 chunk_cap, RDIM_String8 string, RDI_U64 idx) +{ + if(string.RDIM_String8_SizeMember != 0) + { + RDI_U64 hash = rdi_hash(string.RDIM_String8_BaseMember, string.RDIM_String8_SizeMember); + RDI_U64 slot_idx = hash%map_topology->slots_count; + RDIM_BakeNameChunkList *slot = map->slots[slot_idx]; + if(slot == 0) + { + slot = map->slots[slot_idx] = rdim_push_array(arena, RDIM_BakeNameChunkList, 1); + } + RDI_S32 is_duplicate = 0; + for(RDIM_BakeNameChunkNode *n = slot->first; n != 0; n = n->next) + { + for(RDI_U64 idx = 0; idx < n->count; idx += 1) + { + if(rdim_str8_match(n->v[idx].string, string, 0)) + { + is_duplicate = 1; + goto break_all; + } + } + } + break_all:; + if(!is_duplicate) + { + RDIM_BakeName *bstr = rdim_bake_name_chunk_list_push(arena, slot, chunk_cap); + bstr->string = string; + bstr->idx = idx; + bstr->hash = hash; + } + } +} + //- rjf: bake idx run map reading/writing RDI_PROC RDI_U64 @@ -1992,6 +2158,15 @@ rdim_bake_path_tree_insert(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_Stri //- rjf: bake name maps writing +RDI_PROC RDIM_BakeNameMap * +rdim_bake_name_map_make(RDIM_Arena *arena, RDI_U64 expected_count) +{ + RDIM_BakeNameMap *map = push_array(arena, RDIM_BakeNameMap, 1); + map->slots_count = Max(64, expected_count); + map->slots = push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); + return map; +} + RDI_PROC void rdim_bake_name_map_push(RDIM_Arena *arena, RDIM_BakeNameMap *map, RDIM_String8 string, RDI_U32 idx) { diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index f3d86b53..eb9c4fc5 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -1105,6 +1105,47 @@ struct RDIM_BakePathTree //- rjf: name maps +typedef struct RDIM_BakeName RDIM_BakeName; +struct RDIM_BakeName +{ + RDIM_String8 string; + RDI_U64 hash; + RDI_U64 idx; +}; + +typedef struct RDIM_BakeNameChunkNode RDIM_BakeNameChunkNode; +struct RDIM_BakeNameChunkNode +{ + RDIM_BakeNameChunkNode *next; + RDIM_BakeName *v; + RDI_U64 count; + RDI_U64 cap; + RDI_U64 base_idx; +}; + +typedef struct RDIM_BakeNameChunkList RDIM_BakeNameChunkList; +struct RDIM_BakeNameChunkList +{ + RDIM_BakeNameChunkNode *first; + RDIM_BakeNameChunkNode *last; + RDI_U64 chunk_count; + RDI_U64 total_count; +}; + +typedef struct RDIM_BakeNameMapTopology RDIM_BakeNameMapTopology; +struct RDIM_BakeNameMapTopology +{ + RDI_U64 slots_count; +}; + +typedef struct RDIM_BakeNameMap2 RDIM_BakeNameMap2; +struct RDIM_BakeNameMap2 +{ + RDIM_BakeNameChunkList **slots; +}; + +//- rjf: name maps (OLD) + typedef struct RDIM_BakeNameMapValNode RDIM_BakeNameMapValNode; struct RDIM_BakeNameMapValNode { @@ -1558,6 +1599,15 @@ RDI_PROC RDIM_BakeStringMapBaseIndices rdim_bake_string_map_base_indices_from_ma RDI_PROC RDIM_BakeStringMapTight rdim_bake_string_map_tight_from_loose(RDIM_Arena *arena, RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapBaseIndices *map_base_indices, RDIM_BakeStringMapLoose *map); RDI_PROC RDI_U32 rdim_bake_idx_from_string(RDIM_BakeStringMapTight *map, RDIM_String8 string); +//- rjf: bake name chunk list +RDI_PROC RDIM_BakeName *rdim_bake_name_chunk_list_push(RDIM_Arena *arena, RDIM_BakeNameChunkList *list, RDI_U64 cap); +RDI_PROC void rdim_bake_name_chunk_list_concat_in_place(RDIM_BakeNameChunkList *dst, RDIM_BakeNameChunkList *to_push); +RDI_PROC RDIM_BakeNameChunkList rdim_bake_name_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeNameChunkList *src); + +//- rjf: bake name chunk list maps +RDI_PROC RDIM_BakeNameMap2 *rdim_bake_name_map_2_make(RDIM_Arena *arena, RDIM_BakeNameMapTopology *top); +RDI_PROC void rdim_bake_name_map_2_insert(RDIM_Arena *arena, RDIM_BakeNameMapTopology *map_topology, RDIM_BakeNameMap2 *map, RDI_U64 chunk_cap, RDIM_String8 string, RDI_U64 idx); + //- rjf: bake idx run map reading/writing RDI_PROC RDI_U64 rdim_hash_from_idx_run(RDI_U32 *idx_run, RDI_U32 count); RDI_PROC RDI_U32 rdim_bake_idx_from_idx_run(RDIM_BakeIdxRunMap *map, RDI_U32 *idx_run, RDI_U32 count); @@ -1569,6 +1619,7 @@ RDI_PROC RDI_U32 rdim_bake_path_node_idx_from_string(RDIM_BakePathTree *tree, RD RDI_PROC RDIM_BakePathNode *rdim_bake_path_tree_insert(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_String8 string); //- rjf: bake name maps writing +RDI_PROC RDIM_BakeNameMap *rdim_bake_name_map_make(RDIM_Arena *arena, RDI_U64 expected_count); RDI_PROC void rdim_bake_name_map_push(RDIM_Arena *arena, RDIM_BakeNameMap *map, RDIM_String8 string, RDI_U32 idx); //////////////////////////////// diff --git a/src/rdi_make/rdi_make_local_2.c b/src/rdi_make/rdi_make_local_2.c index cb3a48c2..0f674453 100644 --- a/src/rdi_make/rdi_make_local_2.c +++ b/src/rdi_make/rdi_make_local_2.c @@ -28,7 +28,7 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params) // ProfScope("gather all unsorted, joined, line table info; & sort") { - //- rjf: set up outputsw + //- rjf: set up outputs ProfScope("set up outputs") if(lane_idx() == 0) { rdim2_shared->line_tables_count = params->line_tables.total_count; @@ -350,6 +350,151 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params) lane_sync(); RDIM_BakeStringMapTight *bake_strings = &rdim2_shared->bake_strings; + ////////////////////////////////////////////////////////////// + //- rjf: bake name maps + // + ProfScope("bake name maps") + { + //- rjf: set up + if(lane_idx() == 0) + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + U64 slot_count = 0; + switch((RDI_NameMapKindEnum)k) + { + case RDI_NameMapKind_NULL: + case RDI_NameMapKind_COUNT: + {}break; +#define Case(name, total_count) case RDI_NameMapKind_##name:{slot_count = ((total_count) + (total_count)/4);}break + Case(GlobalVariables, params->global_variables.total_count); + Case(ThreadVariables, params->thread_variables.total_count); + Case(Constants, params->constants.total_count); + Case(Procedures, params->procedures.total_count); + Case(LinkNameProcedures, params->procedures.total_count); + Case(Types, params->types.total_count); + Case(NormalSourcePaths, params->src_files.total_count); +#undef Case + } + rdim2_shared->lane_bake_name_maps[k] = push_array(arena, RDIM_BakeNameMap2 *, lane_count()); + rdim2_shared->bake_name_map_topology[k].slots_count = slot_count; + } + } + lane_sync(); + + //- rjf: wide build + for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("name map build %.*s", str8_varg(rdi_string_from_name_map_kind(k))) + { + RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; + rdim2_shared->lane_bake_name_maps[k][lane_idx()] = rdim_bake_name_map_2_make(arena, top); + RDIM_BakeNameMap2 *map = rdim2_shared->lane_bake_name_maps[k][lane_idx()]; + B32 link_names = 0; + RDIM_SymbolChunkList *symbols = 0; + switch((RDI_NameMapKindEnum)k) + { + case RDI_NameMapKind_NULL: + case RDI_NameMapKind_COUNT: + {}break; + case RDI_NameMapKind_GlobalVariables: {symbols = ¶ms->global_variables;}goto symbol_name_map_build; + case RDI_NameMapKind_ThreadVariables: {symbols = ¶ms->thread_variables;}goto symbol_name_map_build; + case RDI_NameMapKind_Constants: {symbols = ¶ms->constants;}goto symbol_name_map_build; + case RDI_NameMapKind_Procedures: {symbols = ¶ms->procedures;}goto symbol_name_map_build; + case RDI_NameMapKind_LinkNameProcedures:{symbols = ¶ms->procedures; link_names = 1;}goto symbol_name_map_build; + symbol_name_map_build:; + { + for EachNode(n, RDIM_SymbolChunkNode, symbols->first) + { + Rng1U64 n_range = lane_range(n->count); + for EachInRange(n_idx, n_range) + { + RDIM_Symbol *symbol = &n->v[n_idx]; + rdim_bake_name_map_2_insert(arena, top, map, 4, link_names ? symbol->link_name : symbol->name, rdim_idx_from_symbol(symbol)); + } + } + }break; + case RDI_NameMapKind_Types: + { + RDIM_TypeChunkList *types = ¶ms->types; + for EachNode(n, RDIM_TypeChunkNode, types->first) + { + Rng1U64 n_range = lane_range(n->count); + for EachInRange(n_idx, n_range) + { + RDIM_Type *type = &n->v[n_idx]; + rdim_bake_name_map_2_insert(arena, top, map, 4, type->name, rdim_idx_from_type(type)); + } + } + }break; + case RDI_NameMapKind_NormalSourcePaths: + { + RDIM_SrcFileChunkList *src_files = ¶ms->src_files; + for EachNode(n, RDIM_SrcFileChunkNode, src_files->first) + { + Rng1U64 n_range = lane_range(n->count); + for EachInRange(n_idx, n_range) + { + RDIM_SrcFile *src_file = &n->v[n_idx]; + RDIM_String8 normalized_path = rdim_lower_from_str8(arena, src_file->path); + rdim_bake_name_map_2_insert(arena, top, map, 4, normalized_path, rdim_idx_from_src_file(src_file)); + } + } + }break; + } + } + lane_sync(); + + //- rjf: join & sort + if(lane_idx() == 0) + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + rdim2_shared->bake_name_maps[k] = rdim_bake_name_map_2_make(arena, &rdim2_shared->bake_name_map_topology[k]); + } + } + lane_sync(); + for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("name map join & sort %.*s", str8_varg(rdi_string_from_name_map_kind(k))) + { + RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; + RDIM_BakeNameMap2 *map = rdim2_shared->bake_name_maps[k]; + + //- rjf: join + ProfScope("join") + { + Rng1U64 slot_range = lane_range(top->slots_count); + for EachInRange(slot_idx, slot_range) + { + for EachIndex(src_lane_idx, lane_count()) + { + RDIM_BakeNameMap2 *src_map = rdim2_shared->lane_bake_name_maps[k][src_lane_idx]; + RDIM_BakeNameMap2 *dst_map = map; + if(dst_map->slots[slot_idx] == 0 && src_map->slots[slot_idx] != 0) + { + dst_map->slots[slot_idx] = src_map->slots[slot_idx]; + } + else if(dst_map->slots[slot_idx] != 0 && src_map->slots[slot_idx] != 0) + { + rdim_bake_name_chunk_list_concat_in_place(dst_map->slots[slot_idx], src_map->slots[slot_idx]); + } + } + } + } + + //- rjf: sort + ProfScope("sort") + { + Rng1U64 slot_range = lane_range(top->slots_count); + for EachInRange(slot_idx, slot_range) + { + if(map->slots[slot_idx] != 0 && map->slots[slot_idx]->total_count > 1) + { + *map->slots[slot_idx] = rdim_bake_name_chunk_list_sorted_from_unsorted(arena, map->slots[slot_idx]); + } + } + } + } + } + lane_sync(); + ////////////////////////////////////////////////////////////// //- rjf: bake units, src files, symbols, UDTs // diff --git a/src/rdi_make/rdi_make_local_2.h b/src/rdi_make/rdi_make_local_2.h index ad52af1d..92586c9c 100644 --- a/src/rdi_make/rdi_make_local_2.h +++ b/src/rdi_make/rdi_make_local_2.h @@ -37,6 +37,10 @@ struct RDIM2_Shared RDIM_BakeStringMapLoose *bake_string_map__loose; RDIM_BakeStringMapTight bake_strings; + RDIM_BakeNameMapTopology bake_name_map_topology[RDI_NameMapKind_COUNT]; + RDIM_BakeNameMap2 **lane_bake_name_maps[RDI_NameMapKind_COUNT]; + RDIM_BakeNameMap2 *bake_name_maps[RDI_NameMapKind_COUNT]; + RDIM_UnitBakeResult baked_units; RDIM_UnitVMapBakeResult baked_unit_vmap; RDIM_SrcFileBakeResult baked_src_files;