Begin reording of struct members by default.

This commit is contained in:
Ginger Bill
2016-09-09 23:33:54 +01:00
parent 1ca752ce04
commit 6979678ff9
13 changed files with 322 additions and 111 deletions
+40 -14
View File
@@ -133,6 +133,10 @@ enum BuiltinProcId {
BuiltinProc_offset_of,
BuiltinProc_offset_of_val,
BuiltinProc_type_of_val,
BuiltinProc_type_info,
BuiltinProc_compile_assert,
BuiltinProc_assert,
BuiltinProc_len,
@@ -150,7 +154,6 @@ enum BuiltinProcId {
BuiltinProc_max,
BuiltinProc_abs,
BuiltinProc_type_info,
BuiltinProc_Count,
};
@@ -174,6 +177,10 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT("offset_of"), 2, false, Expr_Expr},
{STR_LIT("offset_of_val"), 1, false, Expr_Expr},
{STR_LIT("type_of_val"), 1, false, Expr_Expr},
{STR_LIT("type_info"), 1, false, Expr_Expr},
{STR_LIT("compile_assert"), 1, false, Expr_Stmt},
{STR_LIT("assert"), 1, false, Expr_Stmt},
{STR_LIT("len"), 1, false, Expr_Expr},
@@ -191,7 +198,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT("max"), 2, false, Expr_Expr},
{STR_LIT("abs"), 1, false, Expr_Expr},
{STR_LIT("type_info"), 1, false, Expr_Expr},
};
struct CheckerContext {
@@ -682,26 +688,27 @@ void add_type_info_type(Checker *c, Type *t) {
return;
}
isize found = -1;
isize ti_index = -1;
gb_for_array(i, c->info.type_info_map.entries) {
auto *e = &c->info.type_info_map.entries[i];
Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
if (are_types_identical(t, prev_type)) {
found = i;
// Duplicate entry
ti_index = i;
break;
}
}
if (found >= 0) {
// Duplicate entry
map_set(&c->info.type_info_map, hash_pointer(t), found);
} else {
if (ti_index < 0) {
// Unique entry
isize index = c->info.type_info_index;
// NOTE(bill): map entries grow linearly and in order
ti_index = c->info.type_info_index;
c->info.type_info_index++;
map_set(&c->info.type_info_map, hash_pointer(t), index);
}
map_set(&c->info.type_info_map, hash_pointer(t), ti_index);
// Add nested types
if (t->kind == Type_Named) {
// NOTE(bill): Just in case
add_type_info_type(c, t->Named.base);
@@ -716,6 +723,11 @@ void add_type_info_type(Checker *c, Type *t) {
add_type_info_type(c, t_int);
}
} break;
case Type_Pointer:
add_type_info_type(c, bt->Pointer.elem);
break;
case Type_Array:
add_type_info_type(c, bt->Array.elem);
add_type_info_type(c, make_type_pointer(c->allocator, bt->Array.elem));
@@ -726,8 +738,11 @@ void add_type_info_type(Checker *c, Type *t) {
add_type_info_type(c, make_type_pointer(c->allocator, bt->Slice.elem));
add_type_info_type(c, t_int);
break;
case Type_Vector: add_type_info_type(c, bt->Vector.elem); break;
case Type_Pointer: add_type_info_type(c, bt->Pointer.elem); break;
case Type_Vector:
add_type_info_type(c, bt->Vector.elem);
add_type_info_type(c, t_int);
break;
case Type_Record: {
switch (bt->Record.kind) {
case TypeRecord_Enum:
@@ -741,9 +756,20 @@ void add_type_info_type(Checker *c, Type *t) {
break;
}
} break;
case Type_Tuple:
for (isize i = 0; i < bt->Tuple.variable_count; i++) {
Entity *var = bt->Tuple.variables[i];
add_type_info_type(c, var->type);
}
break;
case Type_Proc:
add_type_info_type(c, bt->Proc.params);
add_type_info_type(c, bt->Proc.results);
break;
}
// TODO(bill): Type info for procedures and tuples
// TODO(bill): Remove duplicate identical types efficiently
}
+60 -16
View File
@@ -386,6 +386,22 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
}
// TODO(bill): Cleanup struct field reordering
gb_global BaseTypeSizes __checker_sizes = {};
gb_global gbAllocator __checker_allocator = {};
GB_COMPARE_PROC(cmp_struct_entity_size) {
// NOTE(bill): Biggest to smallest
Entity *x = *(Entity **)a;
Entity *y = *(Entity **)b;
i64 xs = type_size_of(__checker_sizes, __checker_allocator, x->type);
i64 ys = type_size_of(__checker_sizes, __checker_allocator, y->type);
if (xs == ys) {
return string_cmp(&x->token.string, &y->token.string);
}
return xs > ys ? -1 : xs < ys;
}
void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecker *cycle_checker) {
GB_ASSERT(is_type_struct(struct_type));
ast_node(st, StructType, node);
@@ -414,7 +430,20 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecke
check_fields(c, node, st->decls, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("struct"));
if (!st->is_packed && !st->is_ordered) {
// NOTE(bill): Reorder fields for reduced size/performance
// NOTE(bill): Hacky thing
__checker_sizes = c->sizes;
__checker_allocator = c->allocator;
// TODO(bill): Figure out rules more
// sorting rules
// compound literal order must match source not layout
// gb_sort_array(fields, field_count, cmp_struct_entity_size);
}
struct_type->Record.struct_is_packed = st->is_packed;
struct_type->Record.struct_is_ordered = st->is_ordered;
struct_type->Record.fields = fields;
struct_type->Record.field_count = field_count;
struct_type->Record.other_fields = other_fields;
@@ -1959,7 +1988,8 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_size_of:
case BuiltinProc_align_of:
case BuiltinProc_offset_of:
// NOTE(bill): The first arg is a Type, this will be checked case by case
case BuiltinProc_type_info:
// NOTE(bill): The first arg may be a Type, this will be checked case by case
break;
default:
check_multi_expr(c, operand, ce->args[0]);
@@ -2178,6 +2208,34 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
operand->mode = Addressing_Type;
break;
case BuiltinProc_type_info: {
// type_info :: proc(val_or_type) -> ^Type_Info
Operand op = {};
check_expr_or_type(c, &op, ce->args[0]);
add_type_info_type(c, op.type);
operand->mode = Addressing_Value;
operand->type = t_type_info_ptr;
} break;
case BuiltinProc_compile_assert:
// compile_assert :: proc(cond: bool)
if (!is_type_boolean(operand->type) && operand->mode != Addressing_Constant) {
gbString str = expr_to_string(ce->args[0]);
defer (gb_string_free(str));
error(&c->error_collector, ast_node_token(call),
"`%s` is not a constant boolean", str);
return false;
}
if (!operand->value.value_bool) {
gbString str = expr_to_string(ce->args[0]);
defer (gb_string_free(str));
error(&c->error_collector, ast_node_token(call),
"Compile time assertion: `%s`", str);
}
break;
case BuiltinProc_assert:
// assert :: proc(cond: bool)
@@ -2188,14 +2246,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
"`%s` is not a boolean", str);
return false;
}
if (operand->mode == Addressing_Constant &&
!operand->value.value_bool) {
gbString str = expr_to_string(ce->args[0]);
defer (gb_string_free(str));
error(&c->error_collector, ast_node_token(call),
"Compile time assertion: `%s`", str);
return true;
}
if (operand->mode != Addressing_Constant) {
operand->mode = Addressing_NoValue;
}
@@ -2693,13 +2744,6 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
operand->type = type;
} break;
case BuiltinProc_type_info: {
add_type_info_type(c, operand->type);
operand->mode = Addressing_Value;
operand->type = t_type_info_ptr;
} break;
}
return true;
+1
View File
@@ -132,6 +132,7 @@ struct Type {
i64 * struct_offsets;
b32 struct_are_offsets_set;
b32 struct_is_packed;
b32 struct_is_ordered;
// Entity_Constant or Entity_TypeName
Entity **other_fields;