Skip to content

Commit b9756d2

Browse files
committed
eval: sketch out parse/ir cache
1 parent 657b78c commit b9756d2

File tree

10 files changed

+214
-87
lines changed

10 files changed

+214
-87
lines changed

src/eval/eval_bundles.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ e_eval_from_string(Arena *arena, String8 string)
4343
internal E_Eval
4444
e_autoresolved_eval_from_eval(E_Eval eval)
4545
{
46-
if(e_parse_ctx &&
46+
if(e_parse_state &&
4747
e_interpret_ctx &&
48-
e_parse_ctx->modules_count > 0 &&
48+
e_parse_state->ctx->modules_count > 0 &&
4949
e_interpret_ctx->module_base != 0 &&
5050
(e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_S64)) ||
5151
e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_U64)) ||
@@ -54,7 +54,7 @@ e_autoresolved_eval_from_eval(E_Eval eval)
5454
{
5555
U64 vaddr = eval.value.u64;
5656
U64 voff = vaddr - e_interpret_ctx->module_base[0];
57-
RDI_Parsed *rdi = e_parse_ctx->primary_module->rdi;
57+
RDI_Parsed *rdi = e_parse_state->ctx->primary_module->rdi;
5858
RDI_Scope *scope = rdi_scope_from_voff(rdi, voff);
5959
RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff);
6060
RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff);

src/eval/eval_ir.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ e_select_ir_ctx(E_IRCtx *ctx)
8181
e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1);
8282
e_ir_state->type_auto_hook_cache_map->slots_count = 256;
8383
e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count);
84+
e_ir_state->irtree_and_type_cache_slots_count = 1024;
85+
e_ir_state->irtree_and_type_cache_slots = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheSlot, e_ir_state->irtree_and_type_cache_slots_count);
8486
}
8587

8688
////////////////////////////////
@@ -2255,3 +2257,36 @@ e_bytecode_from_oplist(Arena *arena, E_OpList *oplist)
22552257
result.str = str;
22562258
return result;
22572259
}
2260+
2261+
////////////////////////////////
2262+
//~ rjf: IRified Expression Cache
2263+
2264+
internal E_IRTreeAndType
2265+
e_irtree_and_type_from_expr__cached(E_Expr *expr)
2266+
{
2267+
E_IRTreeAndType result = {&e_irnode_nil};
2268+
{
2269+
U64 hash = e_hash_from_string(5381, str8_struct(&expr));
2270+
U64 slot_idx = hash%e_ir_state->irtree_and_type_cache_slots_count;
2271+
E_IRTreeAndTypeCacheNode *node = 0;
2272+
for(E_IRTreeAndTypeCacheNode *n = e_ir_state->irtree_and_type_cache_slots[slot_idx].first; n != 0; n = n->next)
2273+
{
2274+
if(n->expr == expr)
2275+
{
2276+
node = n;
2277+
break;
2278+
}
2279+
}
2280+
if(node == 0)
2281+
{
2282+
node = push_array(e_ir_state->arena, E_IRTreeAndTypeCacheNode, 1);
2283+
SLLQueuePush(e_ir_state->irtree_and_type_cache_slots[slot_idx].first, e_ir_state->irtree_and_type_cache_slots[slot_idx].last, node);
2284+
node->irtree_and_type = e_irtree_and_type_from_expr(e_ir_state->arena, expr);
2285+
}
2286+
if(node != 0)
2287+
{
2288+
result = node->irtree_and_type;
2289+
}
2290+
}
2291+
return result;
2292+
}

src/eval/eval_ir.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,21 @@ struct E_IRCtx
266266
////////////////////////////////
267267
//~ rjf: IR State
268268

269+
typedef struct E_IRTreeAndTypeCacheNode E_IRTreeAndTypeCacheNode;
270+
struct E_IRTreeAndTypeCacheNode
271+
{
272+
E_IRTreeAndTypeCacheNode *next;
273+
E_Expr *expr;
274+
E_IRTreeAndType irtree_and_type;
275+
};
276+
277+
typedef struct E_IRTreeAndTypeCacheSlot E_IRTreeAndTypeCacheSlot;
278+
struct E_IRTreeAndTypeCacheSlot
279+
{
280+
E_IRTreeAndTypeCacheNode *first;
281+
E_IRTreeAndTypeCacheNode *last;
282+
};
283+
269284
typedef struct E_IRState E_IRState;
270285
struct E_IRState
271286
{
@@ -278,6 +293,8 @@ struct E_IRState
278293
// rjf: caches
279294
E_UsedTagMap *used_tag_map;
280295
E_TypeAutoHookCacheMap *type_auto_hook_cache_map;
296+
U64 irtree_and_type_cache_slots_count;
297+
E_IRTreeAndTypeCacheSlot *irtree_and_type_cache_slots;
281298
};
282299

283300
////////////////////////////////
@@ -386,4 +403,9 @@ internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space
386403
internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root);
387404
internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist);
388405

406+
////////////////////////////////
407+
//~ rjf: IRified Expression Cache
408+
409+
internal E_IRTreeAndType e_irtree_and_type_from_expr__cached(E_Expr *expr);
410+
389411
#endif // EVAL_IR_H

src/eval/eval_parse.c

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -619,22 +619,31 @@ e_token_array_make_first_opl(E_Token *first, E_Token *opl)
619619
internal E_ParseCtx *
620620
e_selected_parse_ctx(void)
621621
{
622-
return e_parse_ctx;
622+
return e_parse_state->ctx;
623623
}
624624

625625
internal void
626626
e_select_parse_ctx(E_ParseCtx *ctx)
627627
{
628-
e_parse_ctx = ctx;
628+
if(e_parse_state == 0)
629+
{
630+
Arena *arena = arena_alloc();
631+
e_parse_state = push_array(arena, E_ParseState, 1);
632+
e_parse_state->arena = arena;
633+
e_parse_state->arena_eval_start_pos = arena_pos(arena);
634+
}
635+
e_parse_state->ctx = ctx;
636+
e_parse_state->parse_cache_slots_count = 1024;
637+
e_parse_state->parse_cache_slots = push_array(e_parse_state->arena, E_ParseCacheSlot, e_parse_state->parse_cache_slots_count);
629638
}
630639

631640
internal U32
632641
e_parse_ctx_module_idx_from_rdi(RDI_Parsed *rdi)
633642
{
634643
U32 result = 0;
635-
for(U64 idx = 0; idx < e_parse_ctx->modules_count; idx += 1)
644+
for(U64 idx = 0; idx < e_parse_state->ctx->modules_count; idx += 1)
636645
{
637-
if(e_parse_ctx->modules[idx].rdi == rdi)
646+
if(e_parse_state->ctx->modules[idx].rdi == rdi)
638647
{
639648
result = (U32)idx;
640649
break;
@@ -933,9 +942,9 @@ e_leaf_type_from_name(String8 name)
933942
{
934943
E_TypeKey key = zero_struct;
935944
B32 found = 0;
936-
for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1)
945+
for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1)
937946
{
938-
RDI_Parsed *rdi = e_parse_ctx->modules[module_idx].rdi;
947+
RDI_Parsed *rdi = e_parse_state->ctx->modules[module_idx].rdi;
939948
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types);
940949
RDI_ParsedNameMap parsed_name_map = {0};
941950
rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map);
@@ -1050,7 +1059,7 @@ e_type_from_expr(E_Expr *expr)
10501059
case E_ExprKind_Ptr:
10511060
{
10521061
E_TypeKey direct_type_key = e_type_from_expr(expr->first);
1053-
result = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, direct_type_key, 1, 0);
1062+
result = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, direct_type_key, 1, 0);
10541063
}break;
10551064
case E_ExprKind_Array:
10561065
{
@@ -1365,7 +1374,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
13651374
else
13661375
{
13671376
E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str);
1368-
type->type_key = e_type_key_cons_ptr(e_parse_ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0);
1377+
type->type_key = e_type_key_cons_ptr(e_parse_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_U64), 1, 0);
13691378
E_Expr *casted = atom;
13701379
E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str);
13711380
e_expr_push_child(cast, type);
@@ -1425,9 +1434,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
14251434
//- rjf: form namespaceified fallback versions of this lookup string
14261435
String8List namespaceified_token_strings = {0};
14271436
{
1428-
E_Module *module = e_parse_ctx->primary_module;
1437+
E_Module *module = e_parse_state->ctx->primary_module;
14291438
RDI_Parsed *rdi = module->rdi;
1430-
U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_ctx->ip_voff);
1439+
U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff);
14311440
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx);
14321441
U64 proc_idx = scope->proc_idx;
14331442
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx);
@@ -1454,7 +1463,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
14541463
//- rjf: try members
14551464
if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member")
14561465
{
1457-
U64 data_member_num = e_num_from_string(e_parse_ctx->member_map, token_string);
1466+
U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string);
14581467
if(data_member_num != 0)
14591468
{
14601469
atom_implicit_member_name = token_string;
@@ -1465,23 +1474,23 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
14651474
//- rjf: try locals
14661475
if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local")
14671476
{
1468-
E_Module *module = e_parse_ctx->primary_module;
1477+
E_Module *module = e_parse_state->ctx->primary_module;
14691478
RDI_Parsed *rdi = module->rdi;
1470-
U64 local_num = e_num_from_string(e_parse_ctx->locals_map, local_lookup_string);
1479+
U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string);
14711480
if(local_num != 0)
14721481
{
14731482
identifier_type_is_possibly_dynamically_overridden = 1;
14741483
RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1);
14751484
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx);
1476-
type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_ctx->modules));
1485+
type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules));
14771486

14781487
// rjf: grab location info
14791488
for(U32 loc_block_idx = local_var->location_first;
14801489
loc_block_idx < local_var->location_opl;
14811490
loc_block_idx += 1)
14821491
{
14831492
RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx);
1484-
if(block->scope_off_first <= e_parse_ctx->ip_voff && e_parse_ctx->ip_voff < block->scope_off_opl)
1493+
if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl)
14851494
{
14861495
mapped_identifier = 1;
14871496
space = module->space;
@@ -1534,37 +1543,37 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
15341543
//- rjf: try registers
15351544
if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register")
15361545
{
1537-
U64 reg_num = e_num_from_string(e_parse_ctx->regs_map, token_string);
1546+
U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string);
15381547
if(reg_num != 0)
15391548
{
15401549
reg_code = reg_num;
1541-
type_key = e_type_key_reg(e_parse_ctx->primary_module->arch, reg_code);
1550+
type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code);
15421551
mapped_identifier = 1;
1543-
space = e_parse_ctx->ip_thread_space;
1544-
arch = e_parse_ctx->primary_module->arch;
1552+
space = e_parse_state->ctx->ip_thread_space;
1553+
arch = e_parse_state->ctx->primary_module->arch;
15451554
}
15461555
}
15471556

15481557
//- rjf: try register aliases
15491558
if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias")
15501559
{
1551-
U64 alias_num = e_num_from_string(e_parse_ctx->reg_alias_map, token_string);
1560+
U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string);
15521561
if(alias_num != 0)
15531562
{
15541563
alias_code = (REGS_AliasCode)alias_num;
1555-
type_key = e_type_key_reg_alias(e_parse_ctx->primary_module->arch, alias_code);
1564+
type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code);
15561565
mapped_identifier = 1;
1557-
space = e_parse_ctx->ip_thread_space;
1558-
arch = e_parse_ctx->primary_module->arch;
1566+
space = e_parse_state->ctx->ip_thread_space;
1567+
arch = e_parse_state->ctx->primary_module->arch;
15591568
}
15601569
}
15611570

15621571
//- rjf: try global variables
15631572
if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable")
15641573
{
1565-
for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1)
1574+
for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1)
15661575
{
1567-
E_Module *module = &e_parse_ctx->modules[module_idx];
1576+
E_Module *module = &e_parse_state->ctx->modules[module_idx];
15681577
RDI_Parsed *rdi = module->rdi;
15691578
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables);
15701579
RDI_ParsedNameMap parsed_name_map = {0};
@@ -1606,9 +1615,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
16061615
//- rjf: try thread variables
16071616
if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable")
16081617
{
1609-
for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1)
1618+
for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1)
16101619
{
1611-
E_Module *module = &e_parse_ctx->modules[module_idx];
1620+
E_Module *module = &e_parse_state->ctx->modules[module_idx];
16121621
RDI_Parsed *rdi = module->rdi;
16131622
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables);
16141623
RDI_ParsedNameMap parsed_name_map = {0};
@@ -1646,9 +1655,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
16461655
//- rjf: try procedures
16471656
if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure")
16481657
{
1649-
for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1)
1658+
for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1)
16501659
{
1651-
E_Module *module = &e_parse_ctx->modules[module_idx];
1660+
E_Module *module = &e_parse_state->ctx->modules[module_idx];
16521661
RDI_Parsed *rdi = module->rdi;
16531662
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures);
16541663
RDI_ParsedNameMap parsed_name_map = {0};
@@ -1694,7 +1703,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
16941703
mapped_identifier = 1;
16951704
identifier_looks_like_type_expr = 1;
16961705
MemoryZeroStruct(&space);
1697-
arch = e_parse_ctx->primary_module->arch;
1706+
arch = e_parse_state->ctx->primary_module->arch;
16981707
}
16991708
}
17001709

@@ -1741,7 +1750,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
17411750
}
17421751
else if(reg_code != 0)
17431752
{
1744-
REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_ctx->primary_module->arch)[reg_code];
1753+
REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code];
17451754
E_OpList oplist = {0};
17461755
e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off);
17471756
atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str);
@@ -1753,8 +1762,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
17531762
}
17541763
else if(alias_code != 0)
17551764
{
1756-
REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_ctx->primary_module->arch)[alias_code];
1757-
REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_ctx->primary_module->arch)[alias_slice.code];
1765+
REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code];
1766+
REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code];
17581767
E_OpList oplist = {0};
17591768
e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off);
17601769
atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str);
@@ -2303,3 +2312,35 @@ e_parse_expr_from_text(Arena *arena, String8 text)
23032312
scratch_end(scratch);
23042313
return parse.expr;
23052314
}
2315+
2316+
internal E_Parse
2317+
e_parse_expr_from_text__cached(String8 text)
2318+
{
2319+
E_Parse parse = {0, &e_expr_nil};
2320+
U64 hash = e_hash_from_string(5381, str8_struct(&text));
2321+
U64 slot_idx = hash%e_parse_state->parse_cache_slots_count;
2322+
E_ParseCacheNode *node = 0;
2323+
for(E_ParseCacheNode *n = e_parse_state->parse_cache_slots[slot_idx].first; n != 0; n = n->next)
2324+
{
2325+
if(str8_match(n->string, text, 0))
2326+
{
2327+
node = n;
2328+
break;
2329+
}
2330+
}
2331+
if(node == 0)
2332+
{
2333+
Temp scratch = scratch_begin(0, 0);
2334+
node = push_array(e_parse_state->arena, E_ParseCacheNode, 1);
2335+
SLLQueuePush(e_parse_state->parse_cache_slots[slot_idx].first, e_parse_state->parse_cache_slots[slot_idx].last, node);
2336+
node->string = push_str8_copy(e_parse_state->arena, text);
2337+
E_TokenArray tokens = e_token_array_from_text(scratch.arena, text);
2338+
node->parse = e_parse_expr_from_text_tokens(e_parse_state->arena, node->string, &tokens);
2339+
scratch_end(scratch);
2340+
}
2341+
if(node != 0)
2342+
{
2343+
parse = node->parse;
2344+
}
2345+
return parse;
2346+
}

0 commit comments

Comments
 (0)