|
@@ -15,13 +15,14 @@ typedef Array(irValue *) irValueArray;
|
|
#define MAP_NAME MapIrDebugInfo
|
|
#define MAP_NAME MapIrDebugInfo
|
|
#include "map.c"
|
|
#include "map.c"
|
|
|
|
|
|
|
|
+
|
|
typedef struct irModule {
|
|
typedef struct irModule {
|
|
CheckerInfo * info;
|
|
CheckerInfo * info;
|
|
gbArena arena;
|
|
gbArena arena;
|
|
gbArena tmp_arena;
|
|
gbArena tmp_arena;
|
|
gbAllocator allocator;
|
|
gbAllocator allocator;
|
|
gbAllocator tmp_allocator;
|
|
gbAllocator tmp_allocator;
|
|
- bool generate_debug_info;
|
|
|
|
|
|
+ // bool generate_debug_info;
|
|
|
|
|
|
u32 stmt_state_flags;
|
|
u32 stmt_state_flags;
|
|
|
|
|
|
@@ -29,20 +30,20 @@ typedef struct irModule {
|
|
String layout;
|
|
String layout;
|
|
// String triple;
|
|
// String triple;
|
|
|
|
|
|
- MapEntity min_dep_map; // Key: Entity *
|
|
|
|
- MapIrValue values; // Key: Entity *
|
|
|
|
- MapIrValue members; // Key: String
|
|
|
|
- MapString type_names; // Key: Type *
|
|
|
|
- MapIrDebugInfo debug_info; // Key: Unique pointer
|
|
|
|
- i32 global_string_index;
|
|
|
|
- i32 global_array_index; // For ConstantSlice
|
|
|
|
|
|
+ MapEntity min_dep_map; // Key: Entity *
|
|
|
|
+ MapIrValue values; // Key: Entity *
|
|
|
|
+ MapIrValue members; // Key: String
|
|
|
|
+ MapString type_names; // Key: Type *
|
|
|
|
+ MapIrDebugInfo debug_info; // Key: Unique pointer
|
|
|
|
+ i32 global_string_index;
|
|
|
|
+ i32 global_array_index; // For ConstantSlice
|
|
|
|
|
|
- Entity * entry_point_entity;
|
|
|
|
|
|
+ Entity * entry_point_entity;
|
|
|
|
|
|
- Array(irProcedure *) procs; // NOTE(bill): All procedures with bodies
|
|
|
|
- irValueArray procs_to_generate; // NOTE(bill): Procedures to generate
|
|
|
|
|
|
+ Array(irProcedure *) procs; // NOTE(bill): All procedures with bodies
|
|
|
|
+ irValueArray procs_to_generate; // NOTE(bill): Procedures to generate
|
|
|
|
|
|
- Array(String) foreign_library_paths; // Only the ones that were used
|
|
|
|
|
|
+ Array(String) foreign_library_paths; // Only the ones that were used
|
|
} irModule;
|
|
} irModule;
|
|
|
|
|
|
// NOTE(bill): For more info, see https://en.wikipedia.org/wiki/Dominator_(graph_theory)
|
|
// NOTE(bill): For more info, see https://en.wikipedia.org/wiki/Dominator_(graph_theory)
|
|
@@ -121,6 +122,7 @@ struct irProcedure {
|
|
irTargetList * target_list;
|
|
irTargetList * target_list;
|
|
irValueArray referrers;
|
|
irValueArray referrers;
|
|
|
|
|
|
|
|
+
|
|
i32 local_count;
|
|
i32 local_count;
|
|
i32 instr_count;
|
|
i32 instr_count;
|
|
i32 block_count;
|
|
i32 block_count;
|
|
@@ -134,90 +136,99 @@ struct irProcedure {
|
|
|
|
|
|
|
|
|
|
#define IR_INSTR_KINDS \
|
|
#define IR_INSTR_KINDS \
|
|
- IR_INSTR_KIND(Comment, struct { String text; }) \
|
|
|
|
- IR_INSTR_KIND(Local, struct { \
|
|
|
|
- Entity * entity; \
|
|
|
|
- Type * type; \
|
|
|
|
- bool zero_initialized; \
|
|
|
|
- irValueArray referrers; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(ZeroInit, struct { irValue *address; }) \
|
|
|
|
- IR_INSTR_KIND(Store, struct { irValue *address, *value; }) \
|
|
|
|
|
|
+ IR_INSTR_KIND(Comment, struct { String text; }) \
|
|
|
|
+ IR_INSTR_KIND(Local, struct { \
|
|
|
|
+ Entity * entity; \
|
|
|
|
+ Type * type; \
|
|
|
|
+ bool zero_initialized; \
|
|
|
|
+ irValueArray referrers; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(ZeroInit, struct { irValue *address; }) \
|
|
|
|
+ IR_INSTR_KIND(Store, struct { irValue *address, *value; }) \
|
|
IR_INSTR_KIND(Load, struct { Type *type; irValue *address; }) \
|
|
IR_INSTR_KIND(Load, struct { Type *type; irValue *address; }) \
|
|
- IR_INSTR_KIND(PtrOffset, struct { \
|
|
|
|
- irValue *address; \
|
|
|
|
- irValue *offset; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(ArrayElementPtr, struct { \
|
|
|
|
- irValue *address; \
|
|
|
|
- Type * result_type; \
|
|
|
|
- irValue *elem_index; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(StructElementPtr, struct { \
|
|
|
|
- irValue *address; \
|
|
|
|
- Type * result_type; \
|
|
|
|
- i32 elem_index; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(StructExtractValue, struct { \
|
|
|
|
- irValue *address; \
|
|
|
|
- Type * result_type; \
|
|
|
|
- i32 index; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(UnionTagPtr, struct { \
|
|
|
|
- irValue *address; \
|
|
|
|
- Type *type; /* ^int */ \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(UnionTagValue, struct { \
|
|
|
|
- irValue *address; \
|
|
|
|
- Type *type; /* int */ \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(Conv, struct { \
|
|
|
|
- irConvKind kind; \
|
|
|
|
- irValue *value; \
|
|
|
|
- Type *from, *to; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(Jump, struct { irBlock *block; }) \
|
|
|
|
- IR_INSTR_KIND(If, struct { \
|
|
|
|
- irValue *cond; \
|
|
|
|
- irBlock *true_block; \
|
|
|
|
- irBlock *false_block; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(Return, struct { irValue *value; }) \
|
|
|
|
- IR_INSTR_KIND(Select, struct { \
|
|
|
|
- irValue *cond; \
|
|
|
|
- irValue *true_value; \
|
|
|
|
- irValue *false_value; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(Phi, struct { irValueArray edges; Type *type; }) \
|
|
|
|
- IR_INSTR_KIND(Unreachable, i32) \
|
|
|
|
- IR_INSTR_KIND(UnaryOp, struct { \
|
|
|
|
- Type * type; \
|
|
|
|
- TokenKind op; \
|
|
|
|
- irValue *expr; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(BinaryOp, struct { \
|
|
|
|
- Type * type; \
|
|
|
|
- TokenKind op; \
|
|
|
|
- irValue *left, *right; \
|
|
|
|
|
|
+ IR_INSTR_KIND(PtrOffset, struct { \
|
|
|
|
+ irValue *address; \
|
|
|
|
+ irValue *offset; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(ArrayElementPtr, struct { \
|
|
|
|
+ irValue *address; \
|
|
|
|
+ Type * result_type; \
|
|
|
|
+ irValue *elem_index; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(StructElementPtr, struct { \
|
|
|
|
+ irValue *address; \
|
|
|
|
+ Type * result_type; \
|
|
|
|
+ i32 elem_index; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(StructExtractValue, struct { \
|
|
|
|
+ irValue *address; \
|
|
|
|
+ Type * result_type; \
|
|
|
|
+ i32 index; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(UnionTagPtr, struct { \
|
|
|
|
+ irValue *address; \
|
|
|
|
+ Type *type; /* ^int */ \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(UnionTagValue, struct { \
|
|
|
|
+ irValue *address; \
|
|
|
|
+ Type *type; /* int */ \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(Conv, struct { \
|
|
|
|
+ irConvKind kind; \
|
|
|
|
+ irValue *value; \
|
|
|
|
+ Type *from, *to; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(Jump, struct { irBlock *block; }) \
|
|
|
|
+ IR_INSTR_KIND(If, struct { \
|
|
|
|
+ irValue *cond; \
|
|
|
|
+ irBlock *true_block; \
|
|
|
|
+ irBlock *false_block; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(Return, struct { irValue *value; }) \
|
|
|
|
+ IR_INSTR_KIND(Select, struct { \
|
|
|
|
+ irValue *cond; \
|
|
|
|
+ irValue *true_value; \
|
|
|
|
+ irValue *false_value; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(Phi, struct { irValueArray edges; Type *type; }) \
|
|
|
|
+ IR_INSTR_KIND(Unreachable, i32) \
|
|
|
|
+ IR_INSTR_KIND(UnaryOp, struct { \
|
|
|
|
+ Type * type; \
|
|
|
|
+ TokenKind op; \
|
|
|
|
+ irValue * expr; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(BinaryOp, struct { \
|
|
|
|
+ Type * type; \
|
|
|
|
+ TokenKind op; \
|
|
|
|
+ irValue * left, *right; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(Call, struct { \
|
|
|
|
+ Type * type; /* return type */ \
|
|
|
|
+ irValue * value; \
|
|
|
|
+ irValue **args; \
|
|
|
|
+ isize arg_count; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(StartupRuntime, i32) \
|
|
|
|
+ IR_INSTR_KIND(BoundsCheck, struct { \
|
|
|
|
+ TokenPos pos; \
|
|
|
|
+ irValue *index; \
|
|
|
|
+ irValue *len; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(SliceBoundsCheck, struct { \
|
|
|
|
+ TokenPos pos; \
|
|
|
|
+ irValue *low; \
|
|
|
|
+ irValue *high; \
|
|
|
|
+ bool is_substring; \
|
|
|
|
+ }) \
|
|
|
|
+ IR_INSTR_KIND(DebugDeclare, struct { \
|
|
|
|
+ irDebugInfo *debug_info; \
|
|
|
|
+ AstNode * expr; \
|
|
|
|
+ Entity * entity; \
|
|
|
|
+ bool is_addr; \
|
|
|
|
+ irValue * value; \
|
|
}) \
|
|
}) \
|
|
- IR_INSTR_KIND(Call, struct { \
|
|
|
|
- Type * type; /* return type */ \
|
|
|
|
- irValue *value; \
|
|
|
|
- irValue **args; \
|
|
|
|
- isize arg_count; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(StartupRuntime, i32) \
|
|
|
|
- IR_INSTR_KIND(BoundsCheck, struct { \
|
|
|
|
- TokenPos pos; \
|
|
|
|
- irValue *index; \
|
|
|
|
- irValue *len; \
|
|
|
|
- }) \
|
|
|
|
- IR_INSTR_KIND(SliceBoundsCheck, struct { \
|
|
|
|
- TokenPos pos; \
|
|
|
|
- irValue *low; \
|
|
|
|
- irValue *high; \
|
|
|
|
- bool is_substring; \
|
|
|
|
- })
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
#define IR_CONV_KINDS \
|
|
#define IR_CONV_KINDS \
|
|
IR_CONV_KIND(trunc) \
|
|
IR_CONV_KIND(trunc) \
|
|
@@ -394,7 +405,6 @@ irAddr ir_make_addr_map(irValue *addr, irValue *map_key, Type *map_type, Type *m
|
|
return v;
|
|
return v;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
typedef enum irDebugEncoding {
|
|
typedef enum irDebugEncoding {
|
|
irDebugBasicEncoding_Invalid = 0,
|
|
irDebugBasicEncoding_Invalid = 0,
|
|
|
|
|
|
@@ -519,14 +529,19 @@ struct irDebugInfo {
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
typedef struct irGen {
|
|
typedef struct irGen {
|
|
irModule module;
|
|
irModule module;
|
|
- gbFile output_file;
|
|
|
|
- bool opt_called;
|
|
|
|
|
|
+ gbFile output_file;
|
|
|
|
+ bool opt_called;
|
|
} irGen;
|
|
} irGen;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
Type *ir_type(irValue *value);
|
|
Type *ir_type(irValue *value);
|
|
Type *ir_instr_type(irInstr *instr) {
|
|
Type *ir_instr_type(irInstr *instr) {
|
|
switch (instr->kind) {
|
|
switch (instr->kind) {
|
|
@@ -948,6 +963,16 @@ irValue *ir_make_instr_slice_bounds_check(irProcedure *p, TokenPos pos, irValue
|
|
v->Instr.SliceBoundsCheck.is_substring = is_substring;
|
|
v->Instr.SliceBoundsCheck.is_substring = is_substring;
|
|
return v;
|
|
return v;
|
|
}
|
|
}
|
|
|
|
+irValue *ir_make_instr_debug_declare(irProcedure *p, irDebugInfo *debug_info, AstNode *expr, Entity *entity, bool is_addr, irValue *value) {
|
|
|
|
+ irValue *v = ir_alloc_instr(p, irInstr_DebugDeclare);
|
|
|
|
+ v->Instr.DebugDeclare.debug_info = debug_info;
|
|
|
|
+ v->Instr.DebugDeclare.expr = expr;
|
|
|
|
+ v->Instr.DebugDeclare.entity = entity;
|
|
|
|
+ v->Instr.DebugDeclare.is_addr = is_addr;
|
|
|
|
+ v->Instr.DebugDeclare.value = value;
|
|
|
|
+ return v;
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -967,6 +992,23 @@ irValue *ir_make_value_constant_slice(gbAllocator a, Type *type, irValue *backin
|
|
return v;
|
|
return v;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+irValue *ir_emit(irProcedure *proc, irValue *instr) {
|
|
|
|
+ GB_ASSERT(instr->kind == irValue_Instr);
|
|
|
|
+ irBlock *b = proc->curr_block;
|
|
|
|
+ instr->Instr.parent = b;
|
|
|
|
+ if (b != NULL) {
|
|
|
|
+ irInstr *i = ir_get_last_instr(b);
|
|
|
|
+ if (!ir_is_instr_terminating(i)) {
|
|
|
|
+ array_add(&b->instrs, instr);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return instr;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
irValue *ir_make_const_int(gbAllocator a, i64 i) {
|
|
irValue *ir_make_const_int(gbAllocator a, i64 i) {
|
|
return ir_make_value_constant(a, t_int, make_exact_value_integer(i));
|
|
return ir_make_value_constant(a, t_int, make_exact_value_integer(i));
|
|
}
|
|
}
|
|
@@ -1060,13 +1102,6 @@ void ir_add_block_to_proc(irProcedure *proc, irBlock *b) {
|
|
b->index = proc->block_count++;
|
|
b->index = proc->block_count++;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-// irBlock *ir_add_block(irProcedure *proc, AstNode *node, char *label) {
|
|
|
|
-// irBlock *block = ir_new_block(proc, node, label);
|
|
|
|
-// ir_add_block_to_proc(proc, block);
|
|
|
|
-// return block;
|
|
|
|
-// }
|
|
|
|
-
|
|
|
|
void ir_start_block(irProcedure *proc, irBlock *block) {
|
|
void ir_start_block(irProcedure *proc, irBlock *block) {
|
|
proc->curr_block = block;
|
|
proc->curr_block = block;
|
|
if (block != NULL) {
|
|
if (block != NULL) {
|
|
@@ -1166,7 +1201,7 @@ irValue *ir_add_global_string_array(irModule *m, String string) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-irValue *ir_add_local(irProcedure *proc, Entity *e) {
|
|
|
|
|
|
+irValue *ir_add_local(irProcedure *proc, Entity *e, AstNode *expr) {
|
|
irBlock *b = proc->decl_block; // all variables must be in the first block
|
|
irBlock *b = proc->decl_block; // all variables must be in the first block
|
|
irValue *instr = ir_make_instr_local(proc, e, true);
|
|
irValue *instr = ir_make_instr_local(proc, e, true);
|
|
instr->Instr.parent = b;
|
|
instr->Instr.parent = b;
|
|
@@ -1178,6 +1213,11 @@ irValue *ir_add_local(irProcedure *proc, Entity *e) {
|
|
ir_emit_zero_init(proc, instr);
|
|
ir_emit_zero_init(proc, instr);
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
+ if (expr != NULL) {
|
|
|
|
+ irDebugInfo *di = *map_ir_debug_info_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
|
|
|
+ ir_emit(proc, ir_make_instr_debug_declare(proc, di, expr, e, true, instr));
|
|
|
|
+ }
|
|
|
|
+
|
|
return instr;
|
|
return instr;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1186,7 +1226,7 @@ irValue *ir_add_local_for_identifier(irProcedure *proc, AstNode *name, bool zero
|
|
if (found) {
|
|
if (found) {
|
|
Entity *e = *found;
|
|
Entity *e = *found;
|
|
ir_emit_comment(proc, e->token.string);
|
|
ir_emit_comment(proc, e->token.string);
|
|
- return ir_add_local(proc, e);
|
|
|
|
|
|
+ return ir_add_local(proc, e, name);
|
|
}
|
|
}
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -1202,14 +1242,14 @@ irValue *ir_add_local_generated(irProcedure *proc, Type *type) {
|
|
scope,
|
|
scope,
|
|
empty_token,
|
|
empty_token,
|
|
type, false);
|
|
type, false);
|
|
- return ir_add_local(proc, e);
|
|
|
|
|
|
+ return ir_add_local(proc, e, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-irValue *ir_add_param(irProcedure *proc, Entity *e) {
|
|
|
|
|
|
+irValue *ir_add_param(irProcedure *proc, Entity *e, AstNode *expr) {
|
|
irValue *v = ir_make_value_param(proc->module->allocator, proc, e);
|
|
irValue *v = ir_make_value_param(proc->module->allocator, proc, e);
|
|
#if 1
|
|
#if 1
|
|
- irValue *l = ir_add_local(proc, e);
|
|
|
|
|
|
+ irValue *l = ir_add_local(proc, e, expr);
|
|
ir_emit_store(proc, l, v);
|
|
ir_emit_store(proc, l, v);
|
|
|
|
|
|
#else
|
|
#else
|
|
@@ -1227,9 +1267,9 @@ irValue *ir_add_param(irProcedure *proc, Entity *e) {
|
|
////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
irDebugInfo *ir_add_debug_info_file(irProcedure *proc, AstFile *file) {
|
|
irDebugInfo *ir_add_debug_info_file(irProcedure *proc, AstFile *file) {
|
|
- if (!proc->module->generate_debug_info) {
|
|
|
|
- return NULL;
|
|
|
|
- }
|
|
|
|
|
|
+ // if (!proc->module->generate_debug_info) {
|
|
|
|
+ // return NULL;
|
|
|
|
+ // }
|
|
|
|
|
|
GB_ASSERT(file != NULL);
|
|
GB_ASSERT(file != NULL);
|
|
irDebugInfo *di = ir_alloc_debug_info(proc->module->allocator, irDebugInfo_File);
|
|
irDebugInfo *di = ir_alloc_debug_info(proc->module->allocator, irDebugInfo_File);
|
|
@@ -1259,9 +1299,9 @@ irDebugInfo *ir_add_debug_info_file(irProcedure *proc, AstFile *file) {
|
|
|
|
|
|
|
|
|
|
irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String name, irDebugInfo *file) {
|
|
irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String name, irDebugInfo *file) {
|
|
- if (!proc->module->generate_debug_info) {
|
|
|
|
- return NULL;
|
|
|
|
- }
|
|
|
|
|
|
+ // if (!proc->module->generate_debug_info) {
|
|
|
|
+ // return NULL;
|
|
|
|
+ // }
|
|
|
|
|
|
GB_ASSERT(entity != NULL);
|
|
GB_ASSERT(entity != NULL);
|
|
irDebugInfo *di = ir_alloc_debug_info(proc->module->allocator, irDebugInfo_Proc);
|
|
irDebugInfo *di = ir_alloc_debug_info(proc->module->allocator, irDebugInfo_Proc);
|
|
@@ -1281,18 +1321,7 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
|
|
////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
-irValue *ir_emit(irProcedure *proc, irValue *instr) {
|
|
|
|
- GB_ASSERT(instr->kind == irValue_Instr);
|
|
|
|
- irBlock *b = proc->curr_block;
|
|
|
|
- instr->Instr.parent = b;
|
|
|
|
- if (b != NULL) {
|
|
|
|
- irInstr *i = ir_get_last_instr(b);
|
|
|
|
- if (!ir_is_instr_terminating(i)) {
|
|
|
|
- array_add(&b->instrs, instr);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return instr;
|
|
|
|
-}
|
|
|
|
|
|
+
|
|
irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
|
|
irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
|
|
#if 1
|
|
#if 1
|
|
// NOTE(bill): Sanity check
|
|
// NOTE(bill): Sanity check
|
|
@@ -3215,7 +3244,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|
args[3] = capacity;
|
|
args[3] = capacity;
|
|
return ir_emit_global_call(proc, "__dynamic_array_reserve", args, 4);
|
|
return ir_emit_global_call(proc, "__dynamic_array_reserve", args, 4);
|
|
} else if (is_type_dynamic_map(type)) {
|
|
} else if (is_type_dynamic_map(type)) {
|
|
- irValue **args = gb_alloc_array(a, irValue *, 4);
|
|
|
|
|
|
+ irValue **args = gb_alloc_array(a, irValue *, 2);
|
|
args[0] = ir_gen_map_header(proc, ptr, type);
|
|
args[0] = ir_gen_map_header(proc, ptr, type);
|
|
args[1] = capacity;
|
|
args[1] = capacity;
|
|
return ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2);
|
|
return ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2);
|
|
@@ -3331,6 +3360,23 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|
return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5);
|
|
return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5);
|
|
} break;
|
|
} break;
|
|
|
|
|
|
|
|
+ case BuiltinProc_delete: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("delete"));
|
|
|
|
+ irValue *map = ir_build_expr(proc, ce->args.e[0]);
|
|
|
|
+ irValue *key = ir_build_expr(proc, ce->args.e[1]);
|
|
|
|
+ Type *map_type = ir_type(map);
|
|
|
|
+ GB_ASSERT(is_type_dynamic_map(map_type));
|
|
|
|
+ Type *key_type = base_type(map_type)->Map.key;
|
|
|
|
+
|
|
|
|
+ irValue *addr = ir_address_from_load_or_generate_local(proc, map);
|
|
|
|
+
|
|
|
|
+ gbAllocator a = proc->module->allocator;
|
|
|
|
+ irValue **args = gb_alloc_array(a, irValue *, 2);
|
|
|
|
+ args[0] = ir_gen_map_header(proc, addr, map_type);
|
|
|
|
+ args[1] = ir_gen_map_key(proc, key, key_type);
|
|
|
|
+ return ir_emit_global_call(proc, "__dynamic_map_delete", args, 2);
|
|
|
|
+ } break;
|
|
|
|
+
|
|
|
|
|
|
case BuiltinProc_assert: {
|
|
case BuiltinProc_assert: {
|
|
ir_emit_comment(proc, str_lit("assert"));
|
|
ir_emit_comment(proc, str_lit("assert"));
|
|
@@ -5357,7 +5403,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|
|
|
|
|
irValue *tag_var = NULL;
|
|
irValue *tag_var = NULL;
|
|
if (tag_var_entity != NULL) {
|
|
if (tag_var_entity != NULL) {
|
|
- tag_var = ir_add_local(proc, tag_var_entity);
|
|
|
|
|
|
+ tag_var = ir_add_local(proc, tag_var_entity, NULL);
|
|
} else {
|
|
} else {
|
|
tag_var = ir_add_local_generated(proc, tag_var_type);
|
|
tag_var = ir_add_local_generated(proc, tag_var_type);
|
|
}
|
|
}
|
|
@@ -5385,7 +5431,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|
|
|
|
|
irValue *tag_var = NULL;
|
|
irValue *tag_var = NULL;
|
|
if (tag_var_entity != NULL) {
|
|
if (tag_var_entity != NULL) {
|
|
- tag_var = ir_add_local(proc, tag_var_entity);
|
|
|
|
|
|
+ tag_var = ir_add_local(proc, tag_var_entity, NULL);
|
|
} else {
|
|
} else {
|
|
tag_var = ir_add_local_generated(proc, tag_var_type);
|
|
tag_var = ir_add_local_generated(proc, tag_var_type);
|
|
}
|
|
}
|
|
@@ -5558,12 +5604,26 @@ void ir_begin_procedure_body(irProcedure *proc) {
|
|
ir_start_block(proc, proc->entry_block);
|
|
ir_start_block(proc, proc->entry_block);
|
|
|
|
|
|
if (proc->type->Proc.params != NULL) {
|
|
if (proc->type->Proc.params != NULL) {
|
|
|
|
+ ast_node(pt, ProcType, proc->type_expr);
|
|
|
|
+ isize param_index = 0;
|
|
|
|
+ isize q_index = 0;
|
|
|
|
+
|
|
TypeTuple *params = &proc->type->Proc.params->Tuple;
|
|
TypeTuple *params = &proc->type->Proc.params->Tuple;
|
|
for (isize i = 0; i < params->variable_count; i++) {
|
|
for (isize i = 0; i < params->variable_count; i++) {
|
|
|
|
+ ast_node(fl, FieldList, pt->params);
|
|
|
|
+ GB_ASSERT(fl->list.count > 0);
|
|
|
|
+ GB_ASSERT(fl->list.e[0]->kind == AstNode_Field);
|
|
|
|
+ if (q_index == fl->list.e[param_index]->Field.names.count) {
|
|
|
|
+ q_index = 0;
|
|
|
|
+ param_index++;
|
|
|
|
+ }
|
|
|
|
+ ast_node(field, Field, fl->list.e[param_index]);
|
|
|
|
+ AstNode *name = field->names.e[q_index++];
|
|
|
|
+
|
|
Entity *e = params->variables[i];
|
|
Entity *e = params->variables[i];
|
|
if (!str_eq(e->token.string, str_lit("")) &&
|
|
if (!str_eq(e->token.string, str_lit("")) &&
|
|
!str_eq(e->token.string, str_lit("_"))) {
|
|
!str_eq(e->token.string, str_lit("_"))) {
|
|
- irValue *param = ir_add_param(proc, e);
|
|
|
|
|
|
+ irValue *param = ir_add_param(proc, e, name);
|
|
array_add(&proc->params, param);
|
|
array_add(&proc->params, param);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -5790,7 +5850,7 @@ bool ir_gen_init(irGen *s, Checker *c) {
|
|
}
|
|
}
|
|
|
|
|
|
ir_init_module(&s->module, c);
|
|
ir_init_module(&s->module, c);
|
|
- s->module.generate_debug_info = false;
|
|
|
|
|
|
+ // s->module.generate_debug_info = false;
|
|
|
|
|
|
// TODO(bill): generate appropriate output name
|
|
// TODO(bill): generate appropriate output name
|
|
int pos = cast(int)string_extension_position(c->parser->init_fullpath);
|
|
int pos = cast(int)string_extension_position(c->parser->init_fullpath);
|
|
@@ -6025,7 +6085,9 @@ void ir_gen_tree(irGen *s) {
|
|
name = pd->link_name;
|
|
name = pd->link_name;
|
|
}
|
|
}
|
|
|
|
|
|
- irValue *p = ir_make_value_procedure(a, m, e, e->type, decl->type_expr, body, name);
|
|
|
|
|
|
+ AstNode *type_expr = decl->proc_lit->ProcLit.type;
|
|
|
|
+
|
|
|
|
+ irValue *p = ir_make_value_procedure(a, m, e, e->type, type_expr, body, name);
|
|
p->Proc.tags = pd->tags;
|
|
p->Proc.tags = pd->tags;
|
|
|
|
|
|
ir_module_add_value(m, e, p);
|
|
ir_module_add_value(m, e, p);
|
|
@@ -6067,7 +6129,6 @@ void ir_gen_tree(irGen *s) {
|
|
for_array(i, m->debug_info.entries) {
|
|
for_array(i, m->debug_info.entries) {
|
|
MapIrDebugInfoEntry *entry = &m->debug_info.entries.e[i];
|
|
MapIrDebugInfoEntry *entry = &m->debug_info.entries.e[i];
|
|
irDebugInfo *di = entry->value;
|
|
irDebugInfo *di = entry->value;
|
|
- di->id = i;
|
|
|
|
if (di->kind == irDebugInfo_Proc) {
|
|
if (di->kind == irDebugInfo_Proc) {
|
|
array_add(&all_procs->AllProcs.procs, di);
|
|
array_add(&all_procs->AllProcs.procs, di);
|
|
}
|
|
}
|
|
@@ -6406,10 +6467,11 @@ void ir_gen_tree(irGen *s) {
|
|
case Type_Tuple: {
|
|
case Type_Tuple: {
|
|
ir_emit_comment(proc, str_lit("Type_Info_Tuple"));
|
|
ir_emit_comment(proc, str_lit("Type_Info_Tuple"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_tuple_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_tuple_ptr);
|
|
|
|
+ irValue *record = ir_emit_struct_ep(proc, tag, 0);
|
|
|
|
|
|
{
|
|
{
|
|
irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), align);
|
|
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), align);
|
|
}
|
|
}
|
|
|
|
|
|
irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
@@ -6429,14 +6491,15 @@ void ir_gen_tree(irGen *s) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
} break;
|
|
} break;
|
|
case Type_Record: {
|
|
case Type_Record: {
|
|
switch (t->Record.kind) {
|
|
switch (t->Record.kind) {
|
|
case TypeRecord_Struct: {
|
|
case TypeRecord_Struct: {
|
|
ir_emit_comment(proc, str_lit("Type_Info_Struct"));
|
|
ir_emit_comment(proc, str_lit("Type_Info_Struct"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_struct_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_struct_ptr);
|
|
|
|
+ irValue *record = ir_emit_struct_ep(proc, tag, 0);
|
|
|
|
|
|
{
|
|
{
|
|
irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
@@ -6444,11 +6507,11 @@ void ir_gen_tree(irGen *s) {
|
|
irValue *packed = ir_make_const_bool(a, t->Record.struct_is_packed);
|
|
irValue *packed = ir_make_const_bool(a, t->Record.struct_is_packed);
|
|
irValue *ordered = ir_make_const_bool(a, t->Record.struct_is_ordered);
|
|
irValue *ordered = ir_make_const_bool(a, t->Record.struct_is_ordered);
|
|
irValue *custom_align = ir_make_const_bool(a, t->Record.custom_align);
|
|
irValue *custom_align = ir_make_const_bool(a, t->Record.custom_align);
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), size);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), align);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 5), packed);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 6), ordered);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 7), custom_align);
|
|
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), size);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), align);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 5), packed);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 6), ordered);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 7), custom_align);
|
|
}
|
|
}
|
|
|
|
|
|
irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
@@ -6475,28 +6538,52 @@ void ir_gen_tree(irGen *s) {
|
|
ir_emit_store(proc, offset, ir_make_const_int(a, foffset));
|
|
ir_emit_store(proc, offset, ir_make_const_int(a, foffset));
|
|
}
|
|
}
|
|
|
|
|
|
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 2), memory_offsets, ir_make_const_int(a, t->Record.field_count));
|
|
} break;
|
|
} break;
|
|
- case TypeRecord_Union:
|
|
|
|
|
|
+ case TypeRecord_Union: {
|
|
ir_emit_comment(proc, str_lit("Type_Info_Union"));
|
|
ir_emit_comment(proc, str_lit("Type_Info_Union"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_union_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_union_ptr);
|
|
|
|
+ irValue *record = ir_emit_struct_ep(proc, tag, 0);
|
|
{
|
|
{
|
|
irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), size);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), align);
|
|
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), size);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), align);
|
|
}
|
|
}
|
|
- break;
|
|
|
|
|
|
+
|
|
|
|
+ irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
|
|
+ irValue *memory_names = ir_type_info_member_offset(proc, type_info_member_names, t->Record.field_count, &type_info_member_names_index);
|
|
|
|
+
|
|
|
|
+ for (isize source_index = 1; source_index < t->Record.field_count; source_index++) {
|
|
|
|
+ // TODO(bill): Order fields in source order not layout order
|
|
|
|
+ Entity *f = t->Record.fields[source_index];
|
|
|
|
+ irValue *tip = ir_get_type_info_ptr(proc, type_info_data, f->type);
|
|
|
|
+ irValue *index = ir_make_const_int(a, source_index);
|
|
|
|
+ irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
|
|
|
+
|
|
|
|
+ ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
|
|
|
+ if (f->token.string.len > 0) {
|
|
|
|
+ irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
|
|
|
|
+ ir_emit_store(proc, name, ir_make_const_string(a, f->token.string));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+
|
|
|
|
+ } break;
|
|
case TypeRecord_RawUnion: {
|
|
case TypeRecord_RawUnion: {
|
|
ir_emit_comment(proc, str_lit("Type_Info_RawUnion"));
|
|
ir_emit_comment(proc, str_lit("Type_Info_RawUnion"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_raw_union_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_raw_union_ptr);
|
|
|
|
+ irValue *record = ir_emit_struct_ep(proc, tag, 0);
|
|
|
|
+
|
|
{
|
|
{
|
|
irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), size);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), align);
|
|
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), size);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), align);
|
|
}
|
|
}
|
|
|
|
|
|
irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
@@ -6516,9 +6603,9 @@ void ir_gen_tree(irGen *s) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
- ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 2), memory_offsets, ir_make_const_int(a, t->Record.field_count));
|
|
} break;
|
|
} break;
|
|
case TypeRecord_Enum:
|
|
case TypeRecord_Enum:
|
|
ir_emit_comment(proc, str_lit("Type_Info_Enum"));
|
|
ir_emit_comment(proc, str_lit("Type_Info_Enum"));
|
|
@@ -6607,7 +6694,7 @@ void ir_gen_tree(irGen *s) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- GB_ASSERT(found);
|
|
|
|
|
|
+ GB_ASSERT_MSG(found, "%s", type_to_string(tag_type));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -6619,6 +6706,13 @@ void ir_gen_tree(irGen *s) {
|
|
ir_build_proc(m->procs_to_generate.e[i], m->procs_to_generate.e[i]->Proc.parent);
|
|
ir_build_proc(m->procs_to_generate.e[i], m->procs_to_generate.e[i]->Proc.parent);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Number debug info
|
|
|
|
+ for_array(i, m->debug_info.entries) {
|
|
|
|
+ MapIrDebugInfoEntry *entry = &m->debug_info.entries.e[i];
|
|
|
|
+ irDebugInfo *di = entry->value;
|
|
|
|
+ di->id = i;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
// m->layout = str_lit("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
|
|
// m->layout = str_lit("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
|
|
}
|
|
}
|