Browse Source

Add basic debug information needed for stepping over code

gingerBill 7 years ago
parent
commit
d90008cc52
3 changed files with 80 additions and 48 deletions
  1. 35 23
      src/ir.cpp
  2. 1 1
      src/ir_opt.cpp
  3. 44 24
      src/ir_print.cpp

+ 35 - 23
src/ir.cpp

@@ -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
src/ir_opt.cpp

@@ -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
src/ir_print.cpp

@@ -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 &&
-			    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, "[ ");
 			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) {
-			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");
 		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));