aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-12-13 01:48:40 -0500
committerAndrew Kelley <superjoe30@gmail.com>2016-12-13 01:48:40 -0500
commita6d2bdf6050642762cc7bc193bca34690f712d49 (patch)
tree10db99199b91f09b0eb908013f96e35a6a5eceae /src
parent76a849b1f2c1bb57de4baf8dfd49fe9f9e2340f3 (diff)
downloadzig-a6d2bdf6050642762cc7bc193bca34690f712d49.tar.gz
zig-a6d2bdf6050642762cc7bc193bca34690f712d49.zip
IR: implement breakpoint builtin
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp5
-rw-r--r--src/codegen.cpp7
-rw-r--r--src/ir.cpp31
-rw-r--r--src/ir_print.cpp7
4 files changed, 44 insertions, 6 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 9be40971b7..1bd4c2917b 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1419,6 +1419,7 @@ enum IrInstructionId {
IrInstructionIdMemcpy,
IrInstructionIdSlice,
IrInstructionIdMemberCount,
+ IrInstructionIdBreakpoint,
};
struct IrInstruction {
@@ -1960,6 +1961,10 @@ struct IrInstructionMemberCount {
IrInstruction *container;
};
+struct IrInstructionBreakpoint {
+ IrInstruction base;
+};
+
enum LValPurpose {
LValPurposeNone,
LValPurposeAssign,
diff --git a/src/codegen.cpp b/src/codegen.cpp
index b0f7cffff6..f89fb84f69 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2053,6 +2053,11 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
}
}
+static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutable *executable, IrInstructionBreakpoint *instruction) {
+ LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
+ return nullptr;
+}
+
static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
AstNode *source_node = instruction->source_node;
Scope *scope = instruction->scope;
@@ -2162,6 +2167,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);
case IrInstructionIdSlice:
return ir_render_slice(g, executable, (IrInstructionSlice *)instruction);
+ case IrInstructionIdBreakpoint:
+ return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);
case IrInstructionIdSwitchVar:
case IrInstructionIdContainerInitList:
case IrInstructionIdStructInit:
diff --git a/src/ir.cpp b/src/ir.cpp
index 7312c5efd6..8b438766db 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -391,6 +391,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) {
return IrInstructionIdMemberCount;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionBreakpoint *) {
+ return IrInstructionIdBreakpoint;
+}
+
template<typename T>
static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate<T>(1);
@@ -1609,6 +1613,17 @@ static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNod
return &instruction->base;
}
+static IrInstruction *ir_build_breakpoint(IrBuilder *irb, Scope *scope, AstNode *source_node) {
+ IrInstructionBreakpoint *instruction = ir_build_instruction<IrInstructionBreakpoint>(irb, scope, source_node);
+ return &instruction->base;
+}
+
+static IrInstruction *ir_build_breakpoint_from(IrBuilder *irb, IrInstruction *old_instruction) {
+ IrInstruction *new_instruction = ir_build_breakpoint(irb, old_instruction->scope, old_instruction->source_node);
+ ir_link_new_instruction(new_instruction, old_instruction);
+ return new_instruction;
+}
+
static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,
bool gen_error_defers, bool gen_maybe_defers)
{
@@ -2491,12 +2506,13 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
return ir_build_member_count(irb, scope, node, arg0_value);
}
+ case BuiltinFnIdBreakpoint:
+ return ir_build_breakpoint(irb, scope, node);
case BuiltinFnIdAlignof:
case BuiltinFnIdAddWithOverflow:
case BuiltinFnIdSubWithOverflow:
case BuiltinFnIdMulWithOverflow:
case BuiltinFnIdShlWithOverflow:
- case BuiltinFnIdBreakpoint:
case BuiltinFnIdReturnAddress:
case BuiltinFnIdFrameAddress:
zig_panic("TODO IR gen more builtin functions");
@@ -8456,6 +8472,11 @@ static TypeTableEntry *ir_analyze_instruction_member_count(IrAnalyze *ira, IrIns
return ira->codegen->builtin_types.entry_num_lit_int;
}
+static TypeTableEntry *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) {
+ ir_build_breakpoint_from(&ira->new_irb, &instruction->base);
+ return ira->codegen->builtin_types.entry_void;
+}
+
static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
switch (instruction->id) {
case IrInstructionIdInvalid:
@@ -8580,6 +8601,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction);
case IrInstructionIdMemberCount:
return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction);
+ case IrInstructionIdBreakpoint:
+ return ir_analyze_instruction_breakpoint(ira, (IrInstructionBreakpoint *)instruction);
case IrInstructionIdCast:
case IrInstructionIdStructFieldPtr:
case IrInstructionIdEnumFieldPtr:
@@ -8683,6 +8706,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdFence:
case IrInstructionIdMemset:
case IrInstructionIdMemcpy:
+ case IrInstructionIdBreakpoint:
return true;
case IrInstructionIdPhi:
case IrInstructionIdUnOp:
@@ -8787,9 +8811,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
// align_in_bytes, false);
// }
// }
-// case BuiltinFnIdBreakpoint:
-// mark_impure_fn(g, context, node);
-// return g->builtin_types.entry_void;
// case BuiltinFnIdReturnAddress:
// case BuiltinFnIdFrameAddress:
// mark_impure_fn(g, context, node);
@@ -9035,8 +9056,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
// zig_unreachable();
// case BuiltinFnIdCompileVar:
// return nullptr;
-// case BuiltinFnIdBreakpoint:
-// return LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
// case BuiltinFnIdFrameAddress:
// case BuiltinFnIdReturnAddress:
// {
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index ede1c6461d..186de8b449 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -812,6 +812,10 @@ static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instru
fprintf(irp->f, ")");
}
+static void ir_print_breakpoint(IrPrint *irp, IrInstructionBreakpoint *instruction) {
+ fprintf(irp->f, "@breakpoint()");
+}
+
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
ir_print_prefix(irp, instruction);
switch (instruction->id) {
@@ -1009,6 +1013,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdMemberCount:
ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);
break;
+ case IrInstructionIdBreakpoint:
+ ir_print_breakpoint(irp, (IrInstructionBreakpoint *)instruction);
+ break;
}
fprintf(irp->f, "\n");
}