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 { struct irBlock {
i32 index; i32 index;
String label; String label;
irProcedure *parent; irProcedure *proc;
AstNode * node; // Can be nullptr AstNode * node; // Can be nullptr
Scope * scope; Scope * scope;
isize scope_index; isize scope_index;
@@ -114,11 +114,6 @@ struct irDebugLocation {
irDebugInfo *debug_scope; irDebugInfo *debug_scope;
}; };
struct irDebugScope {
irDebugScope * parent;
irDebugLocation loc;
};
struct irProcedure { struct irProcedure {
irProcedure * parent; irProcedure * parent;
Array<irProcedure *> children; Array<irProcedure *> children;
@@ -319,7 +314,7 @@ String const ir_conv_strings[] = {
struct irInstr { struct irInstr {
irInstrKind kind; irInstrKind kind;
irBlock *parent; irBlock *block;
Type *type; Type *type;
union { 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) { 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); 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_comment (irProcedure *p, String text);
irValue *ir_emit_store (irProcedure *p, irValue *address, irValue *value); irValue *ir_emit_store (irProcedure *p, irValue *address, irValue *value);
irValue *ir_emit_load (irProcedure *p, irValue *address); 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) { irValue *ir_emit(irProcedure *proc, irValue *instr) {
GB_ASSERT(instr->kind == irValue_Instr); GB_ASSERT(instr->kind == irValue_Instr);
irBlock *b = proc->curr_block; irBlock *b = proc->curr_block;
instr->Instr.parent = b; instr->Instr.block = b;
if (b != nullptr) { if (b != nullptr) {
irInstr *i = ir_get_last_instr(b); irInstr *i = ir_get_last_instr(b);
if (!ir_is_instr_terminating(i)) { 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.label = make_string_c(label);
v->Block.node = node; v->Block.node = node;
v->Block.scope = scope; v->Block.scope = scope;
v->Block.parent = proc; v->Block.proc = proc;
// TODO(bill): Is this correct or even needed? // TODO(bill): Is this correct or even needed?
v->Block.scope_index = proc->scope_index; 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) { 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 irBlock *b = proc->decl_block; // all variables must be in the first block
irValue *instr = ir_instr_local(proc, e, true); irValue *instr = ir_instr_local(proc, e, true);
instr->Instr.parent = b; instr->Instr.block = b;
array_add(&b->instrs, instr); array_add(&b->instrs, instr);
array_add(&b->locals, instr); array_add(&b->locals, instr);
proc->local_count++; proc->local_count++;
if (zero_initialized) { if (zero_initialized) {
ir_emit_zero_init(proc, instr); ir_emit_zero_init(proc, instr, expr);
} }
if (expr != nullptr && proc->entity != nullptr) { 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) { irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
Type *a = type_deref(ir_type(address)); 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)); 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; gbAllocator a = p->module->allocator;
Type *t = type_deref(ir_type(address)); Type *t = type_deref(ir_type(address));
irValue **args = gb_alloc_array(a, irValue *, 2); irValue **args = gb_alloc_array(a, irValue *, 2);
args[0] = ir_emit_conv(p, address, t_rawptr); args[0] = ir_emit_conv(p, address, t_rawptr);
args[1] = ir_const_int(a, type_size_of(a, t)); 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)); // 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; 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_); String name = make_string_c(cast(char *)name_);
irValue **found = map_get(&proc->module->members, hash_string(name)); irValue **found = map_get(&proc->module->members, hash_string(name));
GB_ASSERT_MSG(found != nullptr, "%.*s", LIT(name)); GB_ASSERT_MSG(found != nullptr, "%.*s", LIT(name));
irValue *gp = *found; 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)); Type *elem_type = type_deref(ir_type(ptr));
GB_ASSERT(is_type_struct(elem_type) || is_type_array(elem_type)); 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); ir_start_block(proc, body);
irValue *offset_ptr = ir_emit_ptr_offset(proc, ptr, ir_emit_load(proc, index)); 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); 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); irValue *ptr = ir_emit_conv(proc, call, elem_ptr_type);
if (ir_type_has_default_values(elem_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); 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); ir_emit_global_call(proc, "__dynamic_array_make", args, 6);
if (ir_type_has_default_values(elem_type)) { 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); return ir_emit_load(proc, array);
@@ -4708,7 +4712,15 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
return nullptr; return nullptr;
} }
irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr);
irValue *ir_build_expr(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); expr = unparen_expr(expr);
TypeAndValue tv = type_and_value_of_expr(proc->module->info, 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 array_pop(&a->instrs); // Remove branch at end
for_array(i, b->instrs) { for_array(i, b->instrs) {
array_add(&a->instrs, b->instrs[i]); 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); 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); 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_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct = false);
void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hint); 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_print_type(f, m, type);
ir_write_string(f, "* "); ir_write_string(f, "* ");
ir_print_value(f, m, instr->Store.address, type); ir_print_value(f, m, instr->Store.address, type);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; break;
} }
@@ -976,7 +1004,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_type(f, m, type); ir_print_type(f, m, type);
ir_write_string(f, "* "); ir_write_string(f, "* ");
ir_print_value(f, m, instr->Load.address, type); 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; break;
} }
case irInstr_ArrayElementPtr: { case irInstr_ArrayElementPtr: {
@@ -1060,9 +1090,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
irValue *edge = instr->Phi.edges[i]; irValue *edge = instr->Phi.edges[i];
irBlock *block = nullptr; irBlock *block = nullptr;
if (instr->parent != nullptr && if (instr->block != nullptr &&
i < instr->parent->preds.count) { i < instr->block->preds.count) {
block = instr->parent->preds[i]; block = instr->block->preds[i];
} }
ir_write_string(f, "[ "); ir_write_string(f, "[ ");
@@ -1131,6 +1161,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
case irInstr_Jump: {; case irInstr_Jump: {;
ir_write_string(f, "br label %"); ir_write_string(f, "br label %");
ir_print_block_name(f, instr->Jump.block); ir_print_block_name(f, instr->Jump.block);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; break;
} }
@@ -1142,6 +1173,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_write_string(f, ", "); 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.true_block);
ir_write_string(f, ", label %"); ir_print_block_name(f, instr->If.false_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'); ir_write_byte(f, '\n');
break; break;
} }
@@ -1157,7 +1189,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, ret->value, t); ir_print_value(f, m, ret->value, t);
} }
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; 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_print_value(f, m, c->value, c->from);
ir_write_string(f, " to "); ir_write_string(f, " to ");
ir_print_type(f, m, c->to); ir_print_type(f, m, c->to);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; break;
@@ -1224,6 +1257,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
} }
ir_write_string(f, str_lit(", ")); ir_write_string(f, str_lit(", "));
ir_print_value(f, m, uo->expr, type); ir_print_value(f, m, uo->expr, type);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; break;
} }
@@ -1313,6 +1347,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_value(f, m, bo->left, type); ir_print_value(f, m, bo->left, type);
ir_write_string(f, str_lit(", ")); ir_write_string(f, str_lit(", "));
ir_print_value(f, m, bo->right, type); ir_print_value(f, m, bo->right, type);
ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; break;
} }
@@ -1417,25 +1453,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
} }
ir_write_string(f, ")"); ir_write_string(f, ")");
if (m->generate_debug_info) { ir_print_debug_location(f, m, value, instr->block->proc);
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_write_string(f, "\n"); ir_write_string(f, "\n");
break; 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_print_type(f, m, ir_type(instr->Select.false_value));
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, instr->Select.false_value, ir_type(instr->Select.false_value)); 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'); ir_write_byte(f, '\n');
break; break;
} }
@@ -1809,6 +1828,7 @@ void ir_print_type_name(irFileBuffer *f, irModule *m, irValue *v) {
void print_llvm_ir(irGen *ir) { void print_llvm_ir(irGen *ir) {
irModule *m = &ir->module; irModule *m = &ir->module;
irFileBuffer buf = {}, *f = &buf; irFileBuffer buf = {}, *f = &buf;
ir_file_buffer_init(f, &ir->output_file); ir_file_buffer_init(f, &ir->output_file);
defer (ir_file_buffer_destroy(f)); defer (ir_file_buffer_destroy(f));