mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 07:08:48 +00:00
Minor Entity refactor
This commit is contained in:
+2
-2
@@ -882,7 +882,7 @@ ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr) {
|
||||
}
|
||||
|
||||
ssaValue *ssa_add_using_variable(ssaProcedure *proc, Entity *e) {
|
||||
GB_ASSERT(e->kind == Entity_Variable && e->Variable.anonymous);
|
||||
GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous);
|
||||
String name = e->token.string;
|
||||
Entity *parent = e->using_parent;
|
||||
Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
|
||||
@@ -917,7 +917,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
||||
ssaValue **found = map_get(&proc->module->values, hash_pointer(e));
|
||||
if (found) {
|
||||
v = *found;
|
||||
} else if (e->kind == Entity_Variable && e->Variable.anonymous) {
|
||||
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
|
||||
v = ssa_add_using_variable(proc, e);
|
||||
} else if (e->kind == Entity_ImplicitValue) {
|
||||
// TODO(bill): Should a copy be made?
|
||||
|
||||
+1
-1
@@ -442,7 +442,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
Entity *f = t->Record.fields_in_src_order[source_index];
|
||||
ssaValue *tip = get_type_info_ptr(proc, type_info_data, f->type);
|
||||
i64 foffset = t->Record.struct_offsets[f->Variable.field_index];
|
||||
GB_ASSERT(f->kind == Entity_Variable && f->Variable.field);
|
||||
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
||||
|
||||
ssaValue *field = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, source_index));
|
||||
ssaValue *name = ssa_emit_struct_ep(proc, field, 0);
|
||||
|
||||
+3
-3
@@ -575,7 +575,7 @@ String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
|
||||
GB_ASSERT(is_type_struct(src));
|
||||
for (isize i = 0; i < src->Record.field_count; i++) {
|
||||
Entity *f = src->Record.fields[i];
|
||||
if (f->kind == Entity_Variable && f->Variable.anonymous) {
|
||||
if (f->kind == Entity_Variable && f->flags & EntityFlag_Anonymous) {
|
||||
if (are_types_identical(dst, f->type)) {
|
||||
return f->token.string;
|
||||
}
|
||||
@@ -675,8 +675,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
|
||||
|
||||
// float -> float
|
||||
if (is_type_float(src) && is_type_float(dst)) {
|
||||
i64 sz = basic_type_sizes[src->Basic.kind];
|
||||
i64 dz = basic_type_sizes[dst->Basic.kind];
|
||||
i64 sz = type_size_of(proc->module->sizes, proc->module->allocator, src);
|
||||
i64 dz = type_size_of(proc->module->sizes, proc->module->allocator, dst);
|
||||
ssaConvKind kind = ssaConv_fptrunc;
|
||||
if (dz >= sz) {
|
||||
kind = ssaConv_fpext;
|
||||
|
||||
+19
-19
@@ -13,6 +13,7 @@ ssaValue *ssa_alloc_value(gbAllocator a, ssaValueKind kind) {
|
||||
ssaValue *ssa_alloc_instr(ssaProcedure *proc, ssaInstrKind kind) {
|
||||
ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Instr);
|
||||
v->Instr.kind = kind;
|
||||
proc->instr_count++;
|
||||
return v;
|
||||
}
|
||||
ssaDebugInfo *ssa_alloc_debug_info(gbAllocator a, ssaDebugInfoKind kind) {
|
||||
@@ -330,22 +331,6 @@ ssaValue *ssa_make_value_procedure(gbAllocator a, ssaModule *m, Entity *entity,
|
||||
return v;
|
||||
}
|
||||
|
||||
ssaValue *ssa_make_value_block(ssaProcedure *proc, AstNode *node, Scope *scope, String label) {
|
||||
ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Block);
|
||||
v->Block.label = label;
|
||||
v->Block.node = node;
|
||||
v->Block.scope = scope;
|
||||
v->Block.parent = proc;
|
||||
|
||||
array_init(&v->Block.instrs, heap_allocator());
|
||||
array_init(&v->Block.locals, heap_allocator());
|
||||
|
||||
array_init(&v->Block.preds, heap_allocator());
|
||||
array_init(&v->Block.succs, heap_allocator());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, char *label) {
|
||||
Scope *scope = NULL;
|
||||
if (node != NULL) {
|
||||
@@ -357,9 +342,23 @@ ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, char *label) {
|
||||
}
|
||||
}
|
||||
|
||||
ssaValue *value = ssa_make_value_block(proc, node, scope, make_string(label));
|
||||
ssaBlock *block = &value->Block;
|
||||
ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Block);
|
||||
v->Block.label = make_string(label);
|
||||
v->Block.node = node;
|
||||
v->Block.scope = scope;
|
||||
v->Block.parent = proc;
|
||||
|
||||
array_init(&v->Block.instrs, heap_allocator());
|
||||
array_init(&v->Block.locals, heap_allocator());
|
||||
|
||||
array_init(&v->Block.preds, heap_allocator());
|
||||
array_init(&v->Block.succs, heap_allocator());
|
||||
|
||||
ssaBlock *block = &v->Block;
|
||||
|
||||
array_add(&proc->blocks, block);
|
||||
proc->block_count++;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
@@ -435,7 +434,8 @@ ssaValue *ssa_add_global_string_array(ssaModule *m, String string) {
|
||||
ExactValue ev = make_exact_value_string(string);
|
||||
Entity *entity = make_entity_constant(a, NULL, token, type, ev);
|
||||
ssaValue *g = ssa_make_value_global(a, entity, ssa_add_module_constant(m, type, ev));
|
||||
g->Global.is_private = true;
|
||||
g->Global.is_private = true;
|
||||
// g->Global.is_unnamed_addr = true;
|
||||
// g->Global.is_constant = true;
|
||||
|
||||
ssa_module_add_value(m, entity, g);
|
||||
|
||||
+31
-17
@@ -1,4 +1,6 @@
|
||||
void ssa_add_operands(Array<ssaValue *> *ops, ssaInstr *i) {
|
||||
// Optimizations for the SSA code
|
||||
|
||||
void ssa_opt_add_operands(Array<ssaValue *> *ops, ssaInstr *i) {
|
||||
switch (i->kind) {
|
||||
case ssaInstr_Comment:
|
||||
break;
|
||||
@@ -110,16 +112,6 @@ b32 ssa_block_has_phi(ssaBlock *b) {
|
||||
|
||||
|
||||
|
||||
void ssa_optimize_blocks(ssaProcedure *proc);
|
||||
void ssa_build_referrers(ssaProcedure *proc);
|
||||
void ssa_build_dom_tree (ssaProcedure *proc);
|
||||
void ssa_opt_mem2reg (ssaProcedure *proc);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -245,7 +237,7 @@ b32 ssa_opt_block_fusion(ssaProcedure *proc, ssaBlock *a) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ssa_optimize_blocks(ssaProcedure *proc) {
|
||||
void ssa_opt_blocks(ssaProcedure *proc) {
|
||||
ssa_remove_unreachable_blocks(proc);
|
||||
|
||||
#if 1
|
||||
@@ -269,7 +261,7 @@ void ssa_optimize_blocks(ssaProcedure *proc) {
|
||||
|
||||
ssa_remove_dead_blocks(proc);
|
||||
}
|
||||
void ssa_build_referrers(ssaProcedure *proc) {
|
||||
void ssa_opt_build_referrers(ssaProcedure *proc) {
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
|
||||
defer (gb_temp_arena_memory_end(tmp));
|
||||
|
||||
@@ -280,7 +272,7 @@ void ssa_build_referrers(ssaProcedure *proc) {
|
||||
for_array(j, b->instrs) {
|
||||
ssaValue *instr = b->instrs[j];
|
||||
array_clear(&ops);
|
||||
ssa_add_operands(&ops, &instr->Instr);
|
||||
ssa_opt_add_operands(&ops, &instr->Instr);
|
||||
for_array(k, ops) {
|
||||
ssaValue *op = ops[k];
|
||||
if (op == NULL) {
|
||||
@@ -358,8 +350,8 @@ void ssa_number_dom_tree(ssaBlock *v, i32 pre, i32 post, i32 *pre_out, i32 *post
|
||||
}
|
||||
|
||||
|
||||
// NOTE(bill): Requires `ssa_optimize_blocks` to be called before this
|
||||
void ssa_build_dom_tree(ssaProcedure *proc) {
|
||||
// NOTE(bill): Requires `ssa_opt_blocks` to be called before this
|
||||
void ssa_opt_build_dom_tree(ssaProcedure *proc) {
|
||||
// Based on this paper: http://jgaa.info/accepted/2006/GeorgiadisTarjanWerneck2006.10.1.pdf
|
||||
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
|
||||
@@ -448,5 +440,27 @@ void ssa_build_dom_tree(ssaProcedure *proc) {
|
||||
}
|
||||
|
||||
void ssa_opt_mem2reg(ssaProcedure *proc) {
|
||||
// TODO(bill):
|
||||
// TODO(bill): ssa_opt_mem2reg
|
||||
}
|
||||
|
||||
|
||||
void ssa_opt_proc(ssaProcedure *proc) {
|
||||
ssa_opt_blocks(proc);
|
||||
#if 1
|
||||
ssa_opt_build_referrers(proc);
|
||||
ssa_opt_build_dom_tree(proc);
|
||||
|
||||
// TODO(bill): ssa optimization
|
||||
// [ ] cse (common-subexpression) elim
|
||||
// [ ] copy elim
|
||||
// [ ] dead code elim
|
||||
// [ ] dead store/load elim
|
||||
// [ ] phi elim
|
||||
// [ ] short circuit elim
|
||||
// [ ] bounds check elim
|
||||
// [ ] lift/mem2reg
|
||||
// [ ] lift/mem2reg
|
||||
|
||||
ssa_opt_mem2reg(proc);
|
||||
#endif
|
||||
}
|
||||
|
||||
+1
-12
@@ -29,18 +29,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
|
||||
proc->curr_block = proc->decl_block;
|
||||
ssa_emit_jump(proc, proc->entry_block);
|
||||
|
||||
#if 0
|
||||
ssa_optimize_blocks(proc);
|
||||
ssa_build_referrers(proc);
|
||||
ssa_build_dom_tree(proc);
|
||||
|
||||
// TODO(bill): mem2reg optimization
|
||||
// [ ] Local never loaded? Eliminate
|
||||
// [ ] Local never stored? Replace all loads with `Nil`
|
||||
// [ ] Local stored once? Replace loads with dominating store
|
||||
// [ ] Convert to phi nodes
|
||||
ssa_opt_mem2reg(proc);
|
||||
#endif
|
||||
ssa_opt_proc(proc);
|
||||
|
||||
// Number registers
|
||||
i32 reg_index = 0;
|
||||
|
||||
+137
-43
@@ -1,44 +1,7 @@
|
||||
struct ssaProcedure;
|
||||
struct ssaBlock;
|
||||
struct ssaValue;
|
||||
|
||||
enum ssaDebugInfoKind {
|
||||
ssaDebugInfo_Invalid,
|
||||
|
||||
ssaDebugInfo_CompileUnit,
|
||||
ssaDebugInfo_File,
|
||||
ssaDebugInfo_Proc,
|
||||
ssaDebugInfo_AllProcs,
|
||||
|
||||
ssaDebugInfo_Count,
|
||||
};
|
||||
|
||||
struct ssaDebugInfo {
|
||||
ssaDebugInfoKind kind;
|
||||
i32 id;
|
||||
|
||||
union {
|
||||
struct {
|
||||
AstFile * file;
|
||||
String producer;
|
||||
ssaDebugInfo *all_procs;
|
||||
} CompileUnit;
|
||||
struct {
|
||||
AstFile *file;
|
||||
String filename;
|
||||
String directory;
|
||||
} File;
|
||||
struct {
|
||||
Entity * entity;
|
||||
String name;
|
||||
ssaDebugInfo *file;
|
||||
TokenPos pos;
|
||||
} Proc;
|
||||
struct {
|
||||
Array<ssaDebugInfo *> procs;
|
||||
} AllProcs;
|
||||
};
|
||||
};
|
||||
struct ssaDebugInfo;
|
||||
|
||||
struct ssaModule {
|
||||
CheckerInfo * info;
|
||||
@@ -130,14 +93,17 @@ struct ssaProcedure {
|
||||
AstNode * body;
|
||||
u64 tags;
|
||||
|
||||
isize scope_index;
|
||||
Array<ssaDefer> defer_stmts;
|
||||
Array<ssaBlock *> blocks;
|
||||
i32 scope_index;
|
||||
ssaBlock * decl_block;
|
||||
ssaBlock * entry_block;
|
||||
ssaBlock * curr_block;
|
||||
ssaTargetList * target_list;
|
||||
Array<ssaValue *> referrers;
|
||||
|
||||
i32 instr_count;
|
||||
i32 block_count;
|
||||
};
|
||||
|
||||
#define SSA_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
||||
@@ -376,17 +342,18 @@ struct ssaValue {
|
||||
Type *type;
|
||||
} Nil;
|
||||
struct {
|
||||
String name;
|
||||
Type * type;
|
||||
String name;
|
||||
} TypeName;
|
||||
struct {
|
||||
b32 is_constant;
|
||||
b32 is_private;
|
||||
b32 is_thread_local;
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
ssaValue * value;
|
||||
Array<ssaValue *> referrers;
|
||||
b8 is_constant;
|
||||
b8 is_private;
|
||||
b8 is_thread_local;
|
||||
b8 is_unnamed_addr;
|
||||
} Global;
|
||||
struct {
|
||||
ssaProcedure * parent;
|
||||
@@ -433,6 +400,133 @@ ssaAddr ssa_make_addr_vector(ssaValue *addr, ssaValue *index, AstNode *expr) {
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum ssaDebugEncoding {
|
||||
ssaDebugBasicEncoding_Invalid = 0,
|
||||
|
||||
ssaDebugBasicEncoding_address = 1,
|
||||
ssaDebugBasicEncoding_boolean = 2,
|
||||
ssaDebugBasicEncoding_float = 3,
|
||||
ssaDebugBasicEncoding_signed = 4,
|
||||
ssaDebugBasicEncoding_signed_char = 5,
|
||||
ssaDebugBasicEncoding_unsigned = 6,
|
||||
ssaDebugBasicEncoding_unsigned_char = 7,
|
||||
|
||||
ssaDebugBasicEncoding_member = 13,
|
||||
ssaDebugBasicEncoding_pointer_type = 15,
|
||||
ssaDebugBasicEncoding_typedef = 22,
|
||||
|
||||
ssaDebugBasicEncoding_array_type = 1,
|
||||
ssaDebugBasicEncoding_enumeration_type = 4,
|
||||
ssaDebugBasicEncoding_structure_type = 19,
|
||||
ssaDebugBasicEncoding_union_type = 23,
|
||||
|
||||
};
|
||||
|
||||
enum ssaDebugInfoKind {
|
||||
ssaDebugInfo_Invalid,
|
||||
|
||||
ssaDebugInfo_CompileUnit,
|
||||
ssaDebugInfo_File,
|
||||
ssaDebugInfo_Scope,
|
||||
ssaDebugInfo_Proc,
|
||||
ssaDebugInfo_AllProcs,
|
||||
|
||||
ssaDebugInfo_BasicType, // basic types
|
||||
ssaDebugInfo_ProcType,
|
||||
ssaDebugInfo_DerivedType, // pointer, typedef
|
||||
ssaDebugInfo_CompositeType, // array, struct, enum, (raw_)union
|
||||
ssaDebugInfo_Enumerator, // For ssaDebugInfo_CompositeType if enum
|
||||
ssaDebugInfo_GlobalVariable,
|
||||
ssaDebugInfo_LocalVariable,
|
||||
|
||||
|
||||
ssaDebugInfo_Count,
|
||||
};
|
||||
|
||||
struct ssaDebugInfo {
|
||||
ssaDebugInfoKind kind;
|
||||
i32 id;
|
||||
|
||||
union {
|
||||
struct {
|
||||
AstFile * file;
|
||||
String producer;
|
||||
ssaDebugInfo *all_procs;
|
||||
} CompileUnit;
|
||||
struct {
|
||||
AstFile *file;
|
||||
String filename;
|
||||
String directory;
|
||||
} File;
|
||||
struct {
|
||||
ssaDebugInfo *parent;
|
||||
ssaDebugInfo *file;
|
||||
TokenPos pos;
|
||||
Scope * scope; // Actual scope
|
||||
} Scope;
|
||||
struct {
|
||||
Entity * entity;
|
||||
String name;
|
||||
ssaDebugInfo *file;
|
||||
TokenPos pos;
|
||||
} Proc;
|
||||
struct {
|
||||
Array<ssaDebugInfo *> procs;
|
||||
} AllProcs;
|
||||
|
||||
|
||||
struct {
|
||||
String name;
|
||||
i32 size;
|
||||
i32 align;
|
||||
ssaDebugEncoding encoding;
|
||||
} BasicType;
|
||||
struct {
|
||||
ssaDebugInfo * return_type;
|
||||
Array<ssaDebugInfo *> param_types;
|
||||
} ProcType;
|
||||
struct {
|
||||
ssaDebugInfo * base_type;
|
||||
ssaDebugEncoding encoding;
|
||||
} DerivedType;
|
||||
struct {
|
||||
ssaDebugEncoding encoding;
|
||||
String name;
|
||||
String identifier;
|
||||
ssaDebugInfo * file;
|
||||
TokenPos pos;
|
||||
i32 size;
|
||||
i32 align;
|
||||
Array<ssaDebugInfo *> elements;
|
||||
} CompositeType;
|
||||
struct {
|
||||
String name;
|
||||
i64 value;
|
||||
} Enumerator;
|
||||
struct {
|
||||
String name;
|
||||
String linkage_name;
|
||||
ssaDebugInfo *scope;
|
||||
ssaDebugInfo *file;
|
||||
TokenPos pos;
|
||||
ssaValue *variable;
|
||||
ssaDebugInfo *declaration;
|
||||
} GlobalVariable;
|
||||
struct {
|
||||
String name;
|
||||
ssaDebugInfo *scope;
|
||||
ssaDebugInfo *file;
|
||||
TokenPos pos;
|
||||
i32 arg; // Non-zero if proc parameter
|
||||
ssaDebugInfo *type;
|
||||
} LocalVariable;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct ssaFileBuffer {
|
||||
gbVirtualMemory vm;
|
||||
isize offset;
|
||||
|
||||
Reference in New Issue
Block a user