Add $debugtrap builtin. (#1220)

Add `$breakpoint` builtin.
This commit is contained in:
Christian Buttner
2024-07-04 00:50:29 +02:00
committed by GitHub
parent 4a50de8318
commit cc9ca35e04
8 changed files with 32 additions and 1 deletions

View File

@@ -159,6 +159,14 @@ macro void unsupported(String string = "Unsupported function invoked") @builtin
$$unreachable(); $$unreachable();
} }
/**
* Unconditionally break into an attached debugger when reached.
**/
macro void breakpoint() @builtin
{
$$breakpoint();
}
macro any_make(void* ptr, typeid type) @builtin macro any_make(void* ptr, typeid type) @builtin
{ {
return $$any_make(ptr, type); return $$any_make(ptr, type);

View File

@@ -888,6 +888,7 @@ typedef enum
BUILTIN_ATOMIC_FETCH_INC_WRAP, BUILTIN_ATOMIC_FETCH_INC_WRAP,
BUILTIN_ATOMIC_FETCH_DEC_WRAP, BUILTIN_ATOMIC_FETCH_DEC_WRAP,
BUILTIN_BITREVERSE, BUILTIN_BITREVERSE,
BUILTIN_BREAKPOINT,
BUILTIN_BSWAP, BUILTIN_BSWAP,
BUILTIN_CEIL, BUILTIN_CEIL,
BUILTIN_COMPARE_EXCHANGE, BUILTIN_COMPARE_EXCHANGE,

View File

@@ -740,6 +740,7 @@ static void llvm_codegen_setup()
intrinsic_id.ctlz = lookup_intrinsic("llvm.ctlz"); intrinsic_id.ctlz = lookup_intrinsic("llvm.ctlz");
intrinsic_id.ctpop = lookup_intrinsic("llvm.ctpop"); intrinsic_id.ctpop = lookup_intrinsic("llvm.ctpop");
intrinsic_id.cttz = lookup_intrinsic("llvm.cttz"); intrinsic_id.cttz = lookup_intrinsic("llvm.cttz");
intrinsic_id.debugtrap = lookup_intrinsic("llvm.debugtrap");
intrinsic_id.exp = lookup_intrinsic("llvm.exp"); intrinsic_id.exp = lookup_intrinsic("llvm.exp");
intrinsic_id.exp2 = lookup_intrinsic("llvm.exp2"); intrinsic_id.exp2 = lookup_intrinsic("llvm.exp2");
intrinsic_id.expect = lookup_intrinsic("llvm.expect"); intrinsic_id.expect = lookup_intrinsic("llvm.expect");

View File

@@ -888,6 +888,9 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
case BUILTIN_TRAP: case BUILTIN_TRAP:
llvm_value_set(result_value, llvm_emit_call_intrinsic(c, intrinsic_id.trap, NULL, 0, NULL, 0), type_void); llvm_value_set(result_value, llvm_emit_call_intrinsic(c, intrinsic_id.trap, NULL, 0, NULL, 0), type_void);
return; return;
case BUILTIN_BREAKPOINT:
llvm_value_set(result_value, llvm_emit_call_intrinsic(c, intrinsic_id.debugtrap, NULL, 0, NULL, 0), type_void);
return;
case BUILTIN_PREFETCH: case BUILTIN_PREFETCH:
llvm_emit_prefetch(c, result_value, expr); llvm_emit_prefetch(c, result_value, expr);
return; return;

View File

@@ -221,6 +221,7 @@ typedef struct
unsigned ssub_overflow; unsigned ssub_overflow;
unsigned ssub_sat; unsigned ssub_sat;
unsigned trap; unsigned trap;
unsigned debugtrap;
unsigned trunc; unsigned trunc;
unsigned uadd_overflow; unsigned uadd_overflow;
unsigned uadd_sat; unsigned uadd_sat;

View File

@@ -415,8 +415,10 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
return sema_expr_analyse_syscall(context, expr); return sema_expr_analyse_syscall(context, expr);
case BUILTIN_TRAP: case BUILTIN_TRAP:
case BUILTIN_UNREACHABLE: case BUILTIN_UNREACHABLE:
expr->type = type_void;
expr->call_expr.no_return = true; expr->call_expr.no_return = true;
FALLTHROUGH;
case BUILTIN_BREAKPOINT:
expr->type = type_void;
return true; return true;
case BUILTIN_SYSCLOCK: case BUILTIN_SYSCLOCK:
expr->type = type_ulong; expr->type = type_ulong;
@@ -1002,6 +1004,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
case BUILTIN_SWIZZLE2: case BUILTIN_SWIZZLE2:
case BUILTIN_SYSCLOCK: case BUILTIN_SYSCLOCK:
case BUILTIN_TRAP: case BUILTIN_TRAP:
case BUILTIN_BREAKPOINT:
case BUILTIN_UNREACHABLE: case BUILTIN_UNREACHABLE:
UNREACHABLE UNREACHABLE
} }
@@ -1022,6 +1025,7 @@ static inline int builtin_expected_args(BuiltinFunction func)
case BUILTIN_GET_ROUNDING_MODE: case BUILTIN_GET_ROUNDING_MODE:
case BUILTIN_SYSCLOCK: case BUILTIN_SYSCLOCK:
case BUILTIN_TRAP: case BUILTIN_TRAP:
case BUILTIN_BREAKPOINT:
case BUILTIN_UNREACHABLE: case BUILTIN_UNREACHABLE:
return 0; return 0;
case BUILTIN_ABS: case BUILTIN_ABS:

View File

@@ -190,6 +190,7 @@ void symtab_init(uint32_t capacity)
builtin_list[BUILTIN_ATOMIC_FETCH_INC_WRAP] = KW_DEF("atomic_fetch_inc_wrap"); builtin_list[BUILTIN_ATOMIC_FETCH_INC_WRAP] = KW_DEF("atomic_fetch_inc_wrap");
builtin_list[BUILTIN_ATOMIC_FETCH_DEC_WRAP] = KW_DEF("atomic_fetch_dec_wrap"); builtin_list[BUILTIN_ATOMIC_FETCH_DEC_WRAP] = KW_DEF("atomic_fetch_dec_wrap");
builtin_list[BUILTIN_BITREVERSE] = KW_DEF("bitreverse"); builtin_list[BUILTIN_BITREVERSE] = KW_DEF("bitreverse");
builtin_list[BUILTIN_BREAKPOINT] = KW_DEF("breakpoint");
builtin_list[BUILTIN_BSWAP] = KW_DEF("bswap"); builtin_list[BUILTIN_BSWAP] = KW_DEF("bswap");
builtin_list[BUILTIN_CEIL] = KW_DEF("ceil"); builtin_list[BUILTIN_CEIL] = KW_DEF("ceil");
builtin_list[BUILTIN_COMPARE_EXCHANGE] = KW_DEF(("compare_exchange")); builtin_list[BUILTIN_COMPARE_EXCHANGE] = KW_DEF(("compare_exchange"));

View File

@@ -0,0 +1,12 @@
module test;
fn void main()
{
$$breakpoint();
$$trap();
}
/* #expect: test.ll
call void @llvm.debugtrap()
call void @llvm.trap()