mirror of
https://github.com/danog/ir.git
synced 2025-01-22 05:31:32 +01:00
Use ir_emit_exitgroup() helper API instead of IR_EXITGROUP node
This commit is contained in:
parent
2dea40bfab
commit
9b7835a05e
2
TODO
2
TODO
@ -11,7 +11,7 @@
|
|||||||
- irreducable loops detection/support
|
- irreducable loops detection/support
|
||||||
|
|
||||||
- range inference and PI node
|
- range inference and PI node
|
||||||
- SCCP edge cases
|
- SCCP edge cases (remove MERGE with PHIs)
|
||||||
- Folding after SCCP (see combo4.ir)
|
- Folding after SCCP (see combo4.ir)
|
||||||
- Extend SCCP to remove dead LOADs
|
- Extend SCCP to remove dead LOADs
|
||||||
|
|
||||||
|
3
ir.h
3
ir.h
@ -264,7 +264,6 @@ typedef enum _ir_type {
|
|||||||
\
|
\
|
||||||
/* tracing JIT helpers */ \
|
/* tracing JIT helpers */ \
|
||||||
_(EXITCALL, x2, src, def, ___) /* save all CPU registers */ \
|
_(EXITCALL, x2, src, def, ___) /* save all CPU registers */ \
|
||||||
_(EXITGROUP, c1X2, src, num, num) /* code to push exit number */ \
|
|
||||||
_(SNAPSHOT, xN, src, def, def) /* CALL(src, args...) */ \
|
_(SNAPSHOT, xN, src, def, def) /* CALL(src, args...) */ \
|
||||||
|
|
||||||
|
|
||||||
@ -613,6 +612,8 @@ void ir_consistency_check(void);
|
|||||||
/* Code patching (implementation in ir_patch.c) */
|
/* Code patching (implementation in ir_patch.c) */
|
||||||
int ir_patch(const void *code, size_t size, uint32_t jmp_table_size, const void *from_addr, const void *to_addr);
|
int ir_patch(const void *code, size_t size, uint32_t jmp_table_size, const void *from_addr, const void *to_addr);
|
||||||
|
|
||||||
|
/* Deoptimization helpers */
|
||||||
|
const void *ir_emit_exitgroup(uint32_t first_exit_point, uint32_t exit_points_per_group, const void *exit_addr, void *code_buffer, size_t code_buffer_size, size_t *size_ptr);
|
||||||
|
|
||||||
/* IR Memmory Allocation */
|
/* IR Memmory Allocation */
|
||||||
#ifndef ir_mem_malloc
|
#ifndef ir_mem_malloc
|
||||||
|
103
ir_aarch64.dasc
103
ir_aarch64.dasc
@ -4435,28 +4435,6 @@ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_emit_exitgroup(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|
||||||
{
|
|
||||||
ir_backend_data *data = ctx->data;
|
|
||||||
dasm_State **Dst = &data->dasm_state;
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t first_exit_point = insn->op2;
|
|
||||||
uint32_t exit_points_per_group = insn->op3;
|
|
||||||
|
|
||||||
| bl >2
|
|
||||||
|1:
|
|
||||||
for (i = 1; i < exit_points_per_group; i++) {
|
|
||||||
| bl >2
|
|
||||||
}
|
|
||||||
|2:
|
|
||||||
| adr Rx(IR_REG_INT_TMP), <1
|
|
||||||
| sub Rx(IR_REG_INT_TMP), lr, Rx(IR_REG_INT_TMP)
|
|
||||||
| lsr Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #2
|
|
||||||
if (first_exit_point) {
|
|
||||||
| add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #first_exit_point
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ir_emit_dessa_move(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to)
|
static int ir_emit_dessa_move(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to)
|
||||||
{
|
{
|
||||||
ir_backend_data *data = ctx->data;
|
ir_backend_data *data = ctx->data;
|
||||||
@ -5319,9 +5297,6 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
|||||||
case IR_EXITCALL:
|
case IR_EXITCALL:
|
||||||
ir_emit_exitcall(ctx, i, insn);
|
ir_emit_exitcall(ctx, i, insn);
|
||||||
break;
|
break;
|
||||||
case IR_EXITGROUP:
|
|
||||||
ir_emit_exitgroup(ctx, i, insn);
|
|
||||||
break;
|
|
||||||
case IR_GUARD:
|
case IR_GUARD:
|
||||||
case IR_GUARD_NOT:
|
case IR_GUARD_NOT:
|
||||||
ir_emit_guard(ctx, i, insn);
|
ir_emit_guard(ctx, i, insn);
|
||||||
@ -5481,3 +5456,81 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
|||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void *ir_emit_exitgroup(uint32_t first_exit_point, uint32_t exit_points_per_group, const void *exit_addr, void *code_buffer, size_t code_buffer_size, size_t *size_ptr)
|
||||||
|
{
|
||||||
|
void *entry;
|
||||||
|
size_t size;
|
||||||
|
uint32_t i;
|
||||||
|
dasm_State **Dst, *dasm_state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* IR_ASSERT(aarch64_may_use_b(ctx, exit_addr)) */
|
||||||
|
IR_ASSERT(code_buffer);
|
||||||
|
if ((char*)exit_addr >= (char*)code_buffer && (char*)exit_addr < (char*)code_buffer + code_buffer_size) {
|
||||||
|
IR_ASSERT(code_buffer_size < B_IMM);
|
||||||
|
} else if ((char*)exit_addr >= (char*)code_buffer + code_buffer_size) {
|
||||||
|
IR_ASSERT(((char*)exit_addr - (char*)code_buffer) < B_IMM);
|
||||||
|
} else if ((char*)exit_addr < (char*)code_buffer) {
|
||||||
|
IR_ASSERT(((((char*)(code_buffer)) + code_buffer_size) - (char*)exit_addr) < B_IMM);
|
||||||
|
} else {
|
||||||
|
IR_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dst = &dasm_state;
|
||||||
|
dasm_state = NULL;
|
||||||
|
dasm_init(&dasm_state, DASM_MAXSECTION);
|
||||||
|
dasm_setupglobal(&dasm_state, dasm_labels, ir_lb_MAX);
|
||||||
|
dasm_setup(&dasm_state, dasm_actions);
|
||||||
|
|
||||||
|
| bl >2
|
||||||
|
|1:
|
||||||
|
for (i = 1; i < exit_points_per_group; i++) {
|
||||||
|
| bl >2
|
||||||
|
}
|
||||||
|
|2:
|
||||||
|
| adr Rx(IR_REG_INT_TMP), <1
|
||||||
|
| sub Rx(IR_REG_INT_TMP), lr, Rx(IR_REG_INT_TMP)
|
||||||
|
| lsr Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #2
|
||||||
|
if (first_exit_point) {
|
||||||
|
| add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #first_exit_point
|
||||||
|
}
|
||||||
|
| b &exit_addr
|
||||||
|
|
||||||
|
ret = dasm_link(&dasm_state, &size);
|
||||||
|
if (ret != DASM_S_OK) {
|
||||||
|
IR_ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code_buffer != NULL) {
|
||||||
|
if (IR_ALIGNED_SIZE(size, 16) > code_buffer_size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
entry = code_buffer;
|
||||||
|
IR_ASSERT((uintptr_t)entry % 16 == 0);
|
||||||
|
} else {
|
||||||
|
entry = ir_mem_mmap(size);
|
||||||
|
ir_mem_unprotect(entry, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dasm_encode(&dasm_state, entry);
|
||||||
|
if (ret != DASM_S_OK) {
|
||||||
|
IR_ASSERT(0);
|
||||||
|
if (code_buffer == NULL) {
|
||||||
|
ir_mem_unmap(entry, size);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dasm_free(&dasm_state);
|
||||||
|
|
||||||
|
ir_mem_flush(entry, size);
|
||||||
|
|
||||||
|
if (code_buffer == NULL) {
|
||||||
|
ir_mem_protect(entry, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
*size_ptr = size;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
85
ir_x86.dasc
85
ir_x86.dasc
@ -6893,23 +6893,6 @@ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_emit_exitgroup(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|
||||||
{
|
|
||||||
ir_backend_data *data = ctx->data;
|
|
||||||
dasm_State **Dst = &data->dasm_state;
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t first_exit_point = insn->op2;
|
|
||||||
uint32_t exit_points_per_group = insn->op3;
|
|
||||||
|
|
||||||
for (i = 0; i < exit_points_per_group - 1; i++) {
|
|
||||||
| push byte i
|
|
||||||
| .byte 0xeb, (4*(exit_points_per_group-i)-6) // jmp >1
|
|
||||||
}
|
|
||||||
| push byte i
|
|
||||||
|// 1:
|
|
||||||
| add aword [r4], first_exit_point
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ir_emit_dessa_move(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to)
|
static int ir_emit_dessa_move(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to)
|
||||||
{
|
{
|
||||||
ir_backend_data *data = ctx->data;
|
ir_backend_data *data = ctx->data;
|
||||||
@ -8162,9 +8145,6 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
|||||||
case IR_EXITCALL:
|
case IR_EXITCALL:
|
||||||
ir_emit_exitcall(ctx, i, insn);
|
ir_emit_exitcall(ctx, i, insn);
|
||||||
break;
|
break;
|
||||||
case IR_EXITGROUP:
|
|
||||||
ir_emit_exitgroup(ctx, i, insn);
|
|
||||||
break;
|
|
||||||
case IR_GUARD:
|
case IR_GUARD:
|
||||||
case IR_GUARD_NOT:
|
case IR_GUARD_NOT:
|
||||||
ir_emit_guard(ctx, i, insn);
|
ir_emit_guard(ctx, i, insn);
|
||||||
@ -8318,3 +8298,68 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
|||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void *ir_emit_exitgroup(uint32_t first_exit_point, uint32_t exit_points_per_group, const void *exit_addr, void *code_buffer, size_t code_buffer_size, size_t *size_ptr)
|
||||||
|
{
|
||||||
|
void *entry;
|
||||||
|
size_t size;
|
||||||
|
uint32_t i;
|
||||||
|
dasm_State **Dst, *dasm_state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
IR_ASSERT(code_buffer);
|
||||||
|
IR_ASSERT(IR_IS_SIGNED_32BIT((char*)exit_addr - (char*)code_buffer));
|
||||||
|
IR_ASSERT(IR_IS_SIGNED_32BIT((char*)exit_addr - ((char*)code_buffer + code_buffer_size)));
|
||||||
|
|
||||||
|
Dst = &dasm_state;
|
||||||
|
dasm_state = NULL;
|
||||||
|
dasm_init(&dasm_state, DASM_MAXSECTION);
|
||||||
|
dasm_setupglobal(&dasm_state, dasm_labels, ir_lb_MAX);
|
||||||
|
dasm_setup(&dasm_state, dasm_actions);
|
||||||
|
|
||||||
|
for (i = 0; i < exit_points_per_group - 1; i++) {
|
||||||
|
| push byte i
|
||||||
|
| .byte 0xeb, (4*(exit_points_per_group-i)-6) // jmp >1
|
||||||
|
}
|
||||||
|
| push byte i
|
||||||
|
|// 1:
|
||||||
|
| add aword [r4], first_exit_point
|
||||||
|
| jmp aword &exit_addr
|
||||||
|
|
||||||
|
ret = dasm_link(&dasm_state, &size);
|
||||||
|
if (ret != DASM_S_OK) {
|
||||||
|
IR_ASSERT(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code_buffer != NULL) {
|
||||||
|
if (IR_ALIGNED_SIZE(size, 16) > code_buffer_size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
entry = code_buffer;
|
||||||
|
IR_ASSERT((uintptr_t)entry % 16 == 0);
|
||||||
|
} else {
|
||||||
|
entry = ir_mem_mmap(size);
|
||||||
|
ir_mem_unprotect(entry, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dasm_encode(&dasm_state, entry);
|
||||||
|
if (ret != DASM_S_OK) {
|
||||||
|
IR_ASSERT(0);
|
||||||
|
if (code_buffer == NULL) {
|
||||||
|
ir_mem_unmap(entry, size);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dasm_free(&dasm_state);
|
||||||
|
|
||||||
|
ir_mem_flush(entry, size);
|
||||||
|
|
||||||
|
if (code_buffer == NULL) {
|
||||||
|
ir_mem_protect(entry, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
*size_ptr = size;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user