Add basic debug information needed for stepping over code

This commit is contained in:
gingerBill
2018-01-18 12:12:18 +00:00
parent dbf8f9ab38
commit d90008cc52
3 changed files with 80 additions and 48 deletions
+35 -23
View File
@@ -59,7 +59,7 @@ struct irDomNode {
struct irBlock {
i32 index;
String label;
irProcedure *parent;
irProcedure *proc;
AstNode * node; // Can be nullptr
Scope * scope;
isize scope_index;
@@ -114,11 +114,6 @@ struct irDebugLocation {
irDebugInfo *debug_scope;
};
struct irDebugScope {
irDebugScope * parent;
irDebugLocation loc;
};
struct irProcedure {
irProcedure * parent;
Array<irProcedure *> children;
@@ -319,7 +314,7 @@ String const ir_conv_strings[] = {
struct irInstr {
irInstrKind kind;
irBlock *parent;
irBlock *block;
Type *type;
union {
@@ -743,9 +738,9 @@ void ir_add_edge(irBlock *from, irBlock *to) {
}
}
void ir_set_instr_parent(irValue *instr, irBlock *parent) {
void ir_set_instr_block(irValue *instr, irBlock *block) {
if (instr->kind == irValue_Instr) {
instr->Instr.parent = parent;
instr->Instr.block = block;
}
}
@@ -783,7 +778,7 @@ Array<irValue *> *ir_value_referrers(irValue *v) {
////////////////////////////////////////////////////////////////
void ir_module_add_value (irModule *m, Entity *e, irValue *v);
irValue *ir_emit_zero_init (irProcedure *p, irValue *address);
irValue *ir_emit_zero_init (irProcedure *p, irValue *address, AstNode *expr);
irValue *ir_emit_comment (irProcedure *p, String text);
irValue *ir_emit_store (irProcedure *p, irValue *address, irValue *value);
irValue *ir_emit_load (irProcedure *p, irValue *address);
@@ -1134,7 +1129,7 @@ irValue *ir_value_constant_slice(gbAllocator a, Type *type, irValue *backing_arr
irValue *ir_emit(irProcedure *proc, irValue *instr) {
GB_ASSERT(instr->kind == irValue_Instr);
irBlock *b = proc->curr_block;
instr->Instr.parent = b;
instr->Instr.block = b;
if (b != nullptr) {
irInstr *i = ir_get_last_instr(b);
if (!ir_is_instr_terminating(i)) {
@@ -1230,7 +1225,7 @@ irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) {
v->Block.label = make_string_c(label);
v->Block.node = node;
v->Block.scope = scope;
v->Block.parent = proc;
v->Block.proc = proc;
// TODO(bill): Is this correct or even needed?
v->Block.scope_index = proc->scope_index;
@@ -1356,13 +1351,13 @@ irValue *ir_add_global_string_array(irModule *m, String string) {
irValue *ir_add_local(irProcedure *proc, Entity *e, AstNode *expr, bool zero_initialized) {
irBlock *b = proc->decl_block; // all variables must be in the first block
irValue *instr = ir_instr_local(proc, e, true);
instr->Instr.parent = b;
instr->Instr.block = b;
array_add(&b->instrs, instr);
array_add(&b->locals, instr);
proc->local_count++;
if (zero_initialized) {
ir_emit_zero_init(proc, instr);
ir_emit_zero_init(proc, instr, expr);
}
if (expr != nullptr && proc->entity != nullptr) {
@@ -1539,7 +1534,7 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
//
////////////////////////////////////////////////////////////////
irValue *ir_emit_global_call(irProcedure *proc, char const *name_, irValue **args, isize arg_count);
irValue *ir_emit_global_call(irProcedure *proc, char const *name_, irValue **args, isize arg_count, AstNode *expr = nullptr);
irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
Type *a = type_deref(ir_type(address));
@@ -1567,13 +1562,20 @@ irValue *ir_emit_select(irProcedure *p, irValue *cond, irValue *t, irValue *f) {
return ir_emit(p, ir_instr_select(p, cond, t, f));
}
irValue *ir_emit_zero_init(irProcedure *p, irValue *address) {
void ir_add_debug_location_to_value(irProcedure *proc, irValue *v, AstNode *e) {
if (v != nullptr && e != nullptr) {
v->loc.debug_scope = proc->debug_scope;
v->loc.pos = ast_node_token(e).pos;
}
}
irValue *ir_emit_zero_init(irProcedure *p, irValue *address, AstNode *expr) {
gbAllocator a = p->module->allocator;
Type *t = type_deref(ir_type(address));
irValue **args = gb_alloc_array(a, irValue *, 2);
args[0] = ir_emit_conv(p, address, t_rawptr);
args[1] = ir_const_int(a, type_size_of(a, t));
return ir_emit_global_call(p, "__mem_zero", args, 2);
return ir_emit_global_call(p, "__mem_zero", args, 2, expr);
// return ir_emit(p, ir_instr_zero_init(p, address));
}
@@ -1668,12 +1670,14 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, irValue **args, isize arg_
return result;
}
irValue *ir_emit_global_call(irProcedure *proc, char const *name_, irValue **args, isize arg_count) {
irValue *ir_emit_global_call(irProcedure *proc, char const *name_, irValue **args, isize arg_count, AstNode *expr) {
String name = make_string_c(cast(char *)name_);
irValue **found = map_get(&proc->module->members, hash_string(name));
GB_ASSERT_MSG(found != nullptr, "%.*s", LIT(name));
irValue *gp = *found;
return ir_emit_call(proc, gp, args, arg_count);
irValue *call = ir_emit_call(proc, gp, args, arg_count);
ir_add_debug_location_to_value(proc, call, expr);
return call;
}
@@ -4033,7 +4037,7 @@ void ir_emit_increment(irProcedure *proc, irValue *addr) {
}
void ir_init_data_with_defaults(irProcedure *proc, irValue *ptr, irValue *count) {
void ir_init_data_with_defaults(irProcedure *proc, irValue *ptr, irValue *count, AstNode *expr) {
Type *elem_type = type_deref(ir_type(ptr));
GB_ASSERT(is_type_struct(elem_type) || is_type_array(elem_type));
@@ -4056,7 +4060,7 @@ void ir_init_data_with_defaults(irProcedure *proc, irValue *ptr, irValue *count)
ir_start_block(proc, body);
irValue *offset_ptr = ir_emit_ptr_offset(proc, ptr, ir_emit_load(proc, index));
ir_emit_zero_init(proc, offset_ptr);
ir_emit_zero_init(proc, offset_ptr, expr);
ir_emit_increment(proc, index);
@@ -4229,7 +4233,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
irValue *ptr = ir_emit_conv(proc, call, elem_ptr_type);
if (ir_type_has_default_values(elem_type)) {
ir_init_data_with_defaults(proc, ptr, len);
ir_init_data_with_defaults(proc, ptr, len, expr);
}
irValue *slice = ir_add_local_generated(proc, type);
@@ -4278,7 +4282,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
ir_emit_global_call(proc, "__dynamic_array_make", args, 6);
if (ir_type_has_default_values(elem_type)) {
ir_init_data_with_defaults(proc, ir_dynamic_array_elem(proc, ir_emit_load(proc, array)), len);
ir_init_data_with_defaults(proc, ir_dynamic_array_elem(proc, ir_emit_load(proc, array)), len, expr);
}
return ir_emit_load(proc, array);
@@ -4708,7 +4712,15 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
return nullptr;
}
irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr);
irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
irValue *v = ir_build_expr_internal(proc, expr);
ir_add_debug_location_to_value(proc, v, expr);
return v;
}
irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
expr = unparen_expr(expr);
TypeAndValue tv = type_and_value_of_expr(proc->module->info, expr);
+1 -1
View File
@@ -232,7 +232,7 @@ bool ir_opt_block_fusion(irProcedure *proc, irBlock *a) {
array_pop(&a->instrs); // Remove branch at end
for_array(i, b->instrs) {
array_add(&a->instrs, b->instrs[i]);
ir_set_instr_parent(b->instrs[i], a);
ir_set_instr_block(b->instrs[i], a);
}
array_clear(&a->succs);
+44 -24
View File
@@ -193,6 +193,33 @@ void ir_print_encoded_global(irFileBuffer *f, String name, bool remove_prefix) {
ir_print_escape_string(f, name, true, !remove_prefix);
}
bool ir_print_debug_location(irFileBuffer *f, irModule *m, irValue *v, irProcedure *proc = nullptr) {
#if 1
if (m->generate_debug_info && v != nullptr) {
TokenPos pos = v->loc.pos;
irDebugInfo *scope = v->loc.debug_scope;
i32 id = 0;
if (scope != nullptr) {
id = scope->id;
} else if (proc != nullptr) {
if (proc->debug_scope != nullptr) {
id = proc->debug_scope->id;
pos = proc->entity->token.pos;
}
}
if (id > 0 && pos.line > 0) {
ir_fprintf(f, ", !dbg !DILocation(line: %td, column: %td, scope: !%d)", pos.line, pos.column, id);
return true;
}
}
return false;
#else
return true;
#endif
}
void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct = false);
void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hint);
@@ -964,6 +991,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_type(f, m, type);
ir_write_string(f, "* ");
ir_print_value(f, m, instr->Store.address, type);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
}
@@ -976,7 +1004,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_type(f, m, type);
ir_write_string(f, "* ");
ir_print_value(f, m, instr->Load.address, type);
ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type));
ir_fprintf(f, ", align %lld", type_align_of(m->allocator, type));
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
}
case irInstr_ArrayElementPtr: {
@@ -1060,9 +1090,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
irValue *edge = instr->Phi.edges[i];
irBlock *block = nullptr;
if (instr->parent != nullptr &&
i < instr->parent->preds.count) {
block = instr->parent->preds[i];
if (instr->block != nullptr &&
i < instr->block->preds.count) {
block = instr->block->preds[i];
}
ir_write_string(f, "[ ");
@@ -1131,6 +1161,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
case irInstr_Jump: {;
ir_write_string(f, "br label %");
ir_print_block_name(f, instr->Jump.block);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
}
@@ -1142,6 +1173,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_write_string(f, ", ");
ir_write_string(f, "label %"); ir_print_block_name(f, instr->If.true_block);
ir_write_string(f, ", label %"); ir_print_block_name(f, instr->If.false_block);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
}
@@ -1157,7 +1189,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_write_byte(f, ' ');
ir_print_value(f, m, ret->value, t);
}
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
@@ -1171,6 +1203,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_value(f, m, c->value, c->from);
ir_write_string(f, " to ");
ir_print_type(f, m, c->to);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
@@ -1224,6 +1257,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
}
ir_write_string(f, str_lit(", "));
ir_print_value(f, m, uo->expr, type);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
}
@@ -1313,6 +1347,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_value(f, m, bo->left, type);
ir_write_string(f, str_lit(", "));
ir_print_value(f, m, bo->right, type);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
}
@@ -1417,25 +1453,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
}
ir_write_string(f, ")");
if (m->generate_debug_info) {
TokenPos pos = value->loc.pos;
irDebugInfo *scope = value->loc.debug_scope;
i32 id = 0;
irProcedure *proc = instr->parent->parent;
if (scope != nullptr) {
id = scope->id;
} else if (proc->debug_scope != nullptr) {
id = proc->debug_scope->id;
}
if (proc->entity != nullptr) {
pos = proc->entity->token.pos;
}
if (id > 0) {
ir_fprintf(f, ", !dbg !DILocation(line: %td, column: %td, scope: !%d)", pos.line, pos.column, id);
}
}
ir_print_debug_location(f, m, value, instr->block->proc);
ir_write_string(f, "\n");
break;
@@ -1452,6 +1470,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_type(f, m, ir_type(instr->Select.false_value));
ir_write_byte(f, ' ');
ir_print_value(f, m, instr->Select.false_value, ir_type(instr->Select.false_value));
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n');
break;
}
@@ -1809,6 +1828,7 @@ void ir_print_type_name(irFileBuffer *f, irModule *m, irValue *v) {
void print_llvm_ir(irGen *ir) {
irModule *m = &ir->module;
irFileBuffer buf = {}, *f = &buf;
ir_file_buffer_init(f, &ir->output_file);
defer (ir_file_buffer_destroy(f));