eliminate dead code

This commit is contained in:
Ryan Fleury
2025-04-10 15:19:58 -07:00
parent 0dd0f1b8bc
commit b7e12f900c
-421
View File
@@ -103,427 +103,6 @@ e_select_ir_ctx(E_IRCtx *ctx)
}
}
////////////////////////////////
//~ rjf: Slice Lookup Rules
#if 0 // TODO(rjf): @eval
typedef struct E_SliceAccel E_SliceAccel;
struct E_SliceAccel
{
Arch arch;
U64 count;
U64 base_ptr_vaddr;
E_TypeKey element_type_key;
};
E_LOOKUP_INFO_FUNCTION_DEF(slice)
{
E_LookupInfo info = {0};
{
Temp scratch = scratch_begin(&arena, 1);
// rjf: unpack struct type
E_TypeKey struct_type_key = e_type_unwrap(lhs->type_key);
for(;;)
{
if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(struct_type_key)))
{
struct_type_key = e_type_unwrap(e_type_direct_from_key(struct_type_key));
}
else
{
break;
}
}
// rjf: build info from struct type
E_TypeKind type_kind = e_type_kind_from_key(struct_type_key);
if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class)
{
// rjf: unpack members
E_MemberArray members = e_type_data_members_from_key__cached(struct_type_key);
// rjf: choose base pointer & count members
E_Member *base_ptr_member = 0;
E_Member *opl_ptr_member = 0;
E_Member *count_member = 0;
for(U64 idx = 0; idx < members.count; idx += 1)
{
E_Member *member = &members.v[idx];
E_TypeKey member_type = e_type_unwrap(member->type_key);
E_TypeKind member_type_kind = e_type_kind_from_key(member_type);
if(count_member == 0 && e_type_kind_is_integer(member_type_kind))
{
count_member = member;
}
if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind))
{
base_ptr_member = &members.v[idx];
}
else if(base_ptr_member != 0 && opl_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind))
{
opl_ptr_member = &members.v[idx];
}
if(count_member != 0 && base_ptr_member != 0)
{
break;
}
else if(base_ptr_member != 0 && opl_ptr_member != 0)
{
break;
}
}
// rjf: determine architecture
Arch arch = e_type_state->ctx->primary_module->arch;
if(base_ptr_member != 0)
{
E_Type *type = e_type_from_key__cached(base_ptr_member->type_key);
arch = type->arch;
}
// rjf: evaluate count member, determine count
U64 count = 0;
if(count_member != 0)
{
E_Expr *count_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, count_member->name);
E_Value count_member_value = e_value_from_expr(count_member_expr);
count = count_member_value.u64;
}
// rjf: evaluate base ptr member, determine base address
U64 base_ptr_vaddr = 0;
if(base_ptr_member != 0)
{
E_Expr *base_ptr_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, base_ptr_member->name);
E_Value base_ptr_member_value = e_value_from_expr(base_ptr_member_expr);
base_ptr_vaddr = base_ptr_member_value.u64;
}
// rjf: evaluate opl ptr member, determine opl address
U64 opl_ptr_vaddr = 0;
if(count_member == 0 && opl_ptr_member != 0)
{
E_Expr *opl_ptr_member_expr = e_expr_irext_member_access(arena, &e_expr_nil, lhs, opl_ptr_member->name);
E_Value opl_ptr_member_value = e_value_from_expr(opl_ptr_member_expr);
opl_ptr_vaddr = opl_ptr_member_value.u64;
}
// rjf: determine element type
E_TypeKey element_type_key = zero_struct;
if(base_ptr_member != 0)
{
element_type_key = e_type_direct_from_key(base_ptr_member->type_key);
}
// rjf: if no count, but base/opl, swap base/opl if needed, and measure count
if(count_member == 0 && opl_ptr_member != 0 && base_ptr_member != 0)
{
U64 min_vaddr = Min(base_ptr_vaddr, opl_ptr_vaddr);
U64 max_vaddr = Max(base_ptr_vaddr, opl_ptr_vaddr);
base_ptr_vaddr = min_vaddr;
opl_ptr_vaddr = max_vaddr;
count = (opl_ptr_vaddr - base_ptr_vaddr) / e_type_byte_size_from_key(element_type_key);
}
// rjf: fill
if((count_member || opl_ptr_member) && base_ptr_member)
{
E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1);
accel->arch = arch;
accel->count = count;
accel->base_ptr_vaddr = base_ptr_vaddr;
accel->element_type_key = element_type_key;
info.user_data = accel;
info.idxed_expr_count = accel->count;
}
// rjf: fall back to default
else
{
info = E_LOOKUP_INFO_FUNCTION_NAME(default)(arena, lhs, tag, filter);
}
}
scratch_end(scratch);
}
return info;
}
E_LOOKUP_RANGE_FUNCTION_DEF(slice)
{
if(user_data == 0)
{
E_LOOKUP_RANGE_FUNCTION_NAME(default)(arena, lhs, tag, filter, idx_range, exprs, exprs_strings, user_data);
}
else
{
E_SliceAccel *accel = (E_SliceAccel *)user_data;
U64 out_idx = 0;
U64 element_type_size = e_type_byte_size_from_key(accel->element_type_key);
for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1)
{
E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0);
expr->value.u64 = accel->base_ptr_vaddr + idx*element_type_size;
expr->type_key = accel->element_type_key;
exprs[out_idx] = expr;
exprs_strings[out_idx] = push_str8f(arena, "[%I64u]", idx);
}
}
}
E_LOOKUP_ACCESS_FUNCTION_DEF(default)
{
//
// TODO(rjf): need to define what it means to access a set expression
// whose type *does not* define its IR generation rules, BUT it does
// define specific child expressions. so e.g. `watches`, does not
// define `watches[0]`, because it has defined that `watches[0]`
// maps to another expression, which is whatever the first watch
// expression is (e.g. `basics`). so, in that case, we can just use
// the lookup-range rule, grab the Nth expression, and IR-ify *that*.
//
E_LookupAccess result = {{&e_irnode_nil}};
switch(kind)
{
default:{}break;
//- rjf: member accessing
case E_ExprKind_MemberAccess:
{
// rjf: unpack left/right expressions
E_Expr *exprl = lhs;
E_Expr *exprr = rhs;
E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl);
E_TypeKey l_restype = e_type_unwrap(l.type_key);
E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype);
E_TypeKey check_type_key = l_restype;
E_TypeKind check_type_kind = l_restype_kind;
if(l_restype_kind == E_TypeKind_Ptr ||
l_restype_kind == E_TypeKind_LRef ||
l_restype_kind == E_TypeKind_RRef)
{
check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype)));
check_type_kind = e_type_kind_from_key(check_type_key);
}
e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs);
// rjf: look up member
E_Member member = zero_struct;
B32 r_found = 0;
E_TypeKey r_type = zero_struct;
U64 r_value = 0;
B32 r_is_constant_value = 0;
{
Temp scratch = scratch_begin(&arena, 1);
E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string);
member = match;
if(match.kind != E_MemberKind_Null)
{
r_found = 1;
r_type = match.type_key;
r_value = match.off;
}
if(match.kind == E_MemberKind_Null)
{
E_Type *type = e_type_from_key__cached(check_type_key);
if(type->enum_vals != 0)
{
String8 lookup_string = exprr->string;
String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string);
String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string);
E_EnumVal *enum_val_match = 0;
for EachIndex(idx, type->count)
{
if(str8_match(type->enum_vals[idx].name, lookup_string, 0) ||
str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) ||
str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0))
{
enum_val_match = &type->enum_vals[idx];
break;
}
}
if(enum_val_match != 0)
{
r_found = 1;
r_type = check_type_key;
r_value = enum_val_match->val;
r_is_constant_value = 1;
}
}
}
scratch_end(scratch);
}
// rjf: bad conditions? -> error if applicable, exit
if(e_type_key_match(e_type_key_zero(), check_type_key))
{
break;
}
else if(exprr->kind != E_ExprKind_LeafIdentifier)
{
e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name.");
break;
}
else if(!r_found)
{
e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string);
break;
}
else if(check_type_kind != E_TypeKind_Struct &&
check_type_kind != E_TypeKind_Class &&
check_type_kind != E_TypeKind_Union &&
check_type_kind != E_TypeKind_Enum)
{
e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type.");
break;
}
// rjf: generate
{
// rjf: build tree
E_IRNode *new_tree = l.root;
E_TypeKey new_tree_type = r_type;
E_Mode mode = l.mode;
if(l_restype_kind == E_TypeKind_Ptr ||
l_restype_kind == E_TypeKind_LRef ||
l_restype_kind == E_TypeKind_RRef)
{
new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype);
mode = E_Mode_Offset;
}
if(r_value != 0 && !r_is_constant_value)
{
E_IRNode *const_tree = e_irtree_const_u(arena, r_value);
new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree);
}
else if(r_is_constant_value)
{
new_tree = e_irtree_const_u(arena, r_value);
mode = E_Mode_Value;
}
// rjf: fill
result.irtree_and_type.root = new_tree;
result.irtree_and_type.type_key = r_type;
result.irtree_and_type.mode = mode;
}
}break;
//- rjf: array indexing
case E_ExprKind_ArrayIndex:
{
// rjf: unpack left/right expressions
E_Expr *exprl = lhs;
E_Expr *exprr = rhs;
E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl);
E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr);
E_TypeKey l_restype = e_type_unwrap(l.type_key);
E_TypeKey r_restype = e_type_unwrap(r.type_key);
E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype);
E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype);
if(e_type_kind_is_basic_or_enum(r_restype_kind))
{
r_restype = e_type_unwrap_enum(r_restype);
r_restype_kind = e_type_kind_from_key(r_restype);
}
E_TypeKey direct_type = e_type_unwrap(l_restype);
direct_type = e_type_direct_from_key(direct_type);
direct_type = e_type_unwrap(direct_type);
U64 direct_type_size = e_type_byte_size_from_key(direct_type);
e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &l.msgs);
e_msg_list_concat_in_place(&result.irtree_and_type.msgs, &r.msgs);
// rjf: bad conditions? -> error if applicable, exit
if(r.root->op == 0)
{
break;
}
else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array)
{
e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type.");
break;
}
else if(!e_type_kind_is_integer(r_restype_kind))
{
e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type.");
break;
}
else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0)
{
e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types.");
break;
}
else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0)
{
e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types.");
break;
}
// rjf: generate
E_IRNode *new_tree = &e_irnode_nil;
E_Mode mode = l.mode;
{
// rjf: reading from an array value -> read from stack value
if(l.mode == E_Mode_Value && l_restype_kind == E_TypeKind_Array)
{
// rjf: ops to compute the offset
E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype);
if(direct_type_size > 1)
{
E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size);
offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree);
}
// rjf: ops to push stack value, push offset, + read from stack value
new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead);
new_tree->value.u64 = direct_type_size;
e_irnode_push_child(new_tree, offset_tree);
e_irnode_push_child(new_tree, l.root);
}
// rjf: all other cases -> read from base offset
else
{
// rjf: ops to compute the offset
E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype);
if(direct_type_size > 1)
{
E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size);
offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree);
}
// rjf: ops to compute the base offset (resolve to value if addr-of-pointer)
E_IRNode *base_tree = l.root;
if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value)
{
base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype);
}
// rjf: ops to compute the final address
new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree);
}
}
// rjf: fill
result.irtree_and_type.root = new_tree;
result.irtree_and_type.type_key = direct_type;
result.irtree_and_type.mode = mode;
}break;
}
return result;
}
E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default)
{
return num;
}
E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default)
{
return id;
}
#endif
////////////////////////////////
//~ rjf: Member Filtering Lookup Rules