1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Update IR

IR commit: 65586bd4cf9cd2d3b41492f52823c5083cea77e4
This commit is contained in:
Dmitry Stogov
2024-04-23 23:14:54 +03:00
parent b6cf38836f
commit 71194ea767
8 changed files with 320 additions and 60 deletions

View File

@@ -75,7 +75,7 @@ const char *ir_op_name[IR_LAST_OP] = {
#endif
};
static void ir_print_escaped_str(const char *s, size_t len, FILE *f)
void ir_print_escaped_str(const char *s, size_t len, FILE *f)
{
char ch;
@@ -95,10 +95,14 @@ static void ir_print_escaped_str(const char *s, size_t len, FILE *f)
case '\v': fputs("\\v", f); break;
case '\?': fputs("\\?", f); break;
default:
#ifdef __aarch64__
if (ch < 32) {
#else
if (ch >= 0 && ch < 32) {
#endif
fprintf(f, "\\%c%c%c",
'0' + ((ch >> 3) % 8),
'0' + ((ch >> 6) % 8),
'0' + ((ch >> 3) % 8),
'0' + (ch % 8));
break;
} else {
@@ -1784,48 +1788,64 @@ static ir_alias ir_check_aliasing(ir_ctx *ctx, ir_ref addr1, ir_ref addr2)
static ir_alias ir_check_partial_aliasing(const ir_ctx *ctx, ir_ref addr1, ir_ref addr2, ir_type type1, ir_type type2)
{
ir_insn *insn1, *insn2;
ir_ref base1, base2, off1, off2;
/* this must be already check */
IR_ASSERT(addr1 != addr2);
insn1 = &ctx->ir_base[addr1];
insn2 = &ctx->ir_base[addr2];
if (insn1->op == IR_ADD && IR_IS_CONST_REF(insn1->op2)) {
if (insn1->op1 == addr2) {
uintptr_t offset1 = ctx->ir_base[insn1->op2].val.addr;
uintptr_t size2 = ir_type_size[type2];
if (insn1->op != IR_ADD) {
base1 = addr1;
off1 = IR_UNUSED;
} else if (ctx->ir_base[insn1->op2].op == IR_SYM) {
base1 = insn1->op2;
off1 = insn1->op1;
} else {
base1 = insn1->op1;
off1 = insn1->op2;
}
if (insn2->op != IR_ADD) {
base2 = addr2;
off2 = IR_UNUSED;
} else if (ctx->ir_base[insn2->op2].op == IR_SYM) {
base2 = insn2->op2;
off2 = insn2->op1;
} else {
base2 = insn2->op1;
off2 = insn2->op2;
}
if (base1 == base2) {
uintptr_t offset1, offset2;
return (offset1 < size2) ? IR_MUST_ALIAS : IR_NO_ALIAS;
} else if (insn2->op == IR_ADD && IR_IS_CONST_REF(insn1->op2) && insn1->op1 == insn2->op1) {
if (insn1->op2 == insn2->op2) {
return IR_MUST_ALIAS;
} else if (IR_IS_CONST_REF(insn1->op2) && IR_IS_CONST_REF(insn2->op2)) {
uintptr_t offset1 = ctx->ir_base[insn1->op2].val.addr;
uintptr_t offset2 = ctx->ir_base[insn2->op2].val.addr;
if (offset1 == offset2) {
return IR_MUST_ALIAS;
} else if (type1 == type2) {
return IR_NO_ALIAS;
} else {
/* check for partail intersection */
uintptr_t size1 = ir_type_size[type1];
uintptr_t size2 = ir_type_size[type2];
if (offset1 > offset2) {
return offset1 < offset2 + size2 ? IR_MUST_ALIAS : IR_NO_ALIAS;
} else {
return offset2 < offset1 + size1 ? IR_MUST_ALIAS : IR_NO_ALIAS;
}
}
}
if (!off1) {
offset1 = 0;
} else if (IR_IS_CONST_REF(off1) && !IR_IS_SYM_CONST(ctx->ir_base[off1].op)) {
offset1 = ctx->ir_base[off1].val.addr;
} else {
return IR_MAY_ALIAS;
}
} else if (insn2->op == IR_ADD && IR_IS_CONST_REF(insn2->op2)) {
if (insn2->op1 == addr1) {
uintptr_t offset2 = ctx->ir_base[insn2->op2].val.addr;
uintptr_t size1 = ir_type_size[type1];
return (offset2 < size1) ? IR_MUST_ALIAS : IR_NO_ALIAS;
if (!off2) {
offset2 = 0;
} else if (IR_IS_CONST_REF(off2) && !IR_IS_SYM_CONST(ctx->ir_base[off2].op)) {
offset2 = ctx->ir_base[off2].val.addr;
} else {
return IR_MAY_ALIAS;
}
if (offset1 == offset2) {
return IR_MUST_ALIAS;
} else if (offset1 < offset2) {
return offset1 + ir_type_size[type1] <= offset2 ? IR_NO_ALIAS : IR_MUST_ALIAS;
} else {
return offset2 + ir_type_size[type2] <= offset1 ? IR_NO_ALIAS : IR_MUST_ALIAS;
}
} else {
insn1 = &ctx->ir_base[base1];
insn2 = &ctx->ir_base[base2];
if ((insn1->op == IR_ALLOCA && (insn2->op == IR_ALLOCA || insn2->op == IR_SYM || insn2->op == IR_PARAM))
|| (insn1->op == IR_SYM && (insn2->op == IR_ALLOCA || insn2->op == IR_SYM))
|| (insn1->op == IR_PARAM && insn2->op == IR_ALLOCA)) {
return IR_NO_ALIAS;
}
}
return IR_MAY_ALIAS;

View File

@@ -513,6 +513,9 @@ void ir_strtab_free(ir_strtab *strtab);
#define IR_EXTERN (1<<5)
#define IR_CONST (1<<6)
#define IR_INITIALIZED (1<<7) /* sym data flag: constant or an initialized variable */
#define IR_CONST_STRING (1<<8) /* sym data flag: constant string */
#define IR_SKIP_PROLOGUE (1<<8) /* Don't generate function prologue. */
#define IR_USE_FRAME_POINTER (1<<9)
#define IR_PREALLOCATED_STACK (1<<10)
@@ -825,11 +828,12 @@ struct _ir_loader {
uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types);
bool (*forward_func_dcl) (ir_loader *loader, const char *name,
uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types);
bool (*sym_dcl) (ir_loader *loader, const char *name, uint32_t flags, size_t size, bool has_data);
bool (*sym_dcl) (ir_loader *loader, const char *name, uint32_t flags, size_t size);
bool (*sym_data) (ir_loader *loader, ir_type type, uint32_t count, const void *data);
bool (*sym_data_str) (ir_loader *loader, const char *str, size_t len);
bool (*sym_data_pad) (ir_loader *loader, size_t offset);
bool (*sym_data_ref) (ir_loader *loader, ir_op op, const char *ref, uintptr_t offset);
bool (*sym_data_end) (ir_loader *loader);
bool (*sym_data_end) (ir_loader *loader, uint32_t flags);
bool (*func_init) (ir_loader *loader, ir_ctx *ctx, const char *name);
bool (*func_process) (ir_loader *loader, ir_ctx *ctx, const char *name);
void*(*resolve_sym_name) (ir_loader *loader, const char *name, bool add_thunk);
@@ -867,12 +871,12 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f);
/* IR to C conversion (implementation in ir_emit_c.c) */
int ir_emit_c(ir_ctx *ctx, const char *name, FILE *f);
void ir_emit_c_func_decl(const char *name, uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types, FILE *f);
void ir_emit_c_sym_decl(const char *name, uint32_t flags, bool has_data, FILE *f);
void ir_emit_c_sym_decl(const char *name, uint32_t flags, FILE *f);
/* IR to LLVM conversion (implementation in ir_emit_llvm.c) */
int ir_emit_llvm(ir_ctx *ctx, const char *name, FILE *f);
void ir_emit_llvm_func_decl(const char *name, uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types, FILE *f);
void ir_emit_llvm_sym_decl(const char *name, uint32_t flags, bool has_data, FILE *f);
void ir_emit_llvm_sym_decl(const char *name, uint32_t flags, FILE *f);
/* IR verification API (implementation in ir_check.c) */
bool ir_check(const ir_ctx *ctx);

View File

@@ -1057,7 +1057,7 @@ binop_fp:
return insn->op;
case IR_VA_START:
ctx->flags2 |= IR_HAS_VA_START;
if (ctx->ir_base[insn->op2].op == IR_ALLOCA) {
if ((ctx->ir_base[insn->op2].op == IR_ALLOCA) || (ctx->ir_base[insn->op2].op == IR_VADDR)) {
ir_use_list *use_list = &ctx->use_lists[insn->op2];
ir_ref *p, n = use_list->count;
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
@@ -1092,7 +1092,7 @@ binop_fp:
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
if (ctx->ir_base[*p].op != IR_VA_END) {
return IR_VADDR;
return IR_STATIC_ALLOCA;
}
}
}
@@ -3802,7 +3802,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref)
return IR_MEM_BO(reg, ctx->ir_base[addr_insn->op2].val.i32);
}
} else {
IR_ASSERT(addr_insn->op == IR_ALLOCA);
IR_ASSERT(addr_insn->op == IR_ALLOCA || addr_insn->op == IR_VADDR);
reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[ref].op3);
return IR_MEM_BO(reg, offset);

View File

@@ -178,14 +178,10 @@ bool ir_check(const ir_ctx *ctx)
/* boolean not */
break;
}
if (sizeof(void*) == 8) {
if (insn->type == IR_ADDR && (use_insn->type == IR_U64 || use_insn->type == IR_I64)) {
break;
}
} else {
if (insn->type == IR_ADDR && (use_insn->type == IR_U32 || use_insn->type == IR_I32)) {
break;
}
if (insn->type == IR_ADDR && (use_insn->type == IR_UINTPTR_T || use_insn->type == IR_INTPTR_T)) {
break;
} else if (use_insn->type == IR_ADDR && (insn->type == IR_UINTPTR_T || insn->type == IR_INTPTR_T)) {
break;
}
fprintf(stderr, "ir_base[%d].ops[%d] (%d) type is incompatible with result type (%d != %d)\n",
i, j, use, use_insn->type, insn->type);

View File

@@ -2501,10 +2501,230 @@ IR_FOLD(ADD(ADD, C_I64))
IR_FOLD_NEXT;
}
IR_FOLD(ADD(SUB, C_U8))
IR_FOLD(ADD(SUB, C_U16))
IR_FOLD(ADD(SUB, C_U32))
IR_FOLD(ADD(SUB, C_U64))
IR_FOLD(ADD(SUB, C_ADDR))
{
if (IR_IS_CONST_REF(op1_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op)) {
/* (x - c1) + c2 => x + (c2 - c1) */
val.u64 = op2_insn->val.u64 - ctx->ir_base[op1_insn->op2].val.u64;
op1 = op1_insn->op1;
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
} else if (IR_IS_CONST_REF(op1_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op1].op)) {
/* (c1 - x) + c2 => (c1 + c2) - x */
val.u64 = ctx->ir_base[op1_insn->op1].val.u64 + op2_insn->val.u64;
opt++; /* ADD -> SUB */
op1 = ir_const(ctx, val, IR_OPT_TYPE(opt));
op2 = op1_insn->op2;
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(ADD(SUB, C_I8))
IR_FOLD(ADD(SUB, C_I16))
IR_FOLD(ADD(SUB, C_I32))
IR_FOLD(ADD(SUB, C_I64))
{
if (IR_IS_CONST_REF(op1_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op)) {
/* (x - c1) + c2 => x + (c2 - c1) */
val.i64 = op2_insn->val.i64 - ctx->ir_base[op1_insn->op2].val.i64;
if (val.i64 < 0 && val.i64 - 1 < 0) {
val.i64 = -val.i64;
opt++; /* ADD -> SUB */
}
op1 = op1_insn->op1;
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
} else if (IR_IS_CONST_REF(op1_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op1].op)) {
/* (c1 - x) + c2 => (c1 + c2) - x */
val.i64 = ctx->ir_base[op1_insn->op1].val.i64 + op2_insn->val.i64;
opt++; /* ADD -> SUB */
op1 = ir_const(ctx, val, IR_OPT_TYPE(opt));
op2 = op1_insn->op2;
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(SUB(ADD, C_U8))
IR_FOLD(SUB(ADD, C_U16))
IR_FOLD(SUB(ADD, C_U32))
IR_FOLD(SUB(ADD, C_U64))
IR_FOLD(SUB(ADD, C_ADDR))
{
if (IR_IS_CONST_REF(op1_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op)) {
/* (x + c1) - c2 => x + (c1 - c2) */
val.u64 = ctx->ir_base[op1_insn->op2].val.u64 - op2_insn->val.u64;
opt--; /* SUB -> ADD */
op1 = op1_insn->op1;
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(SUB(ADD, C_I8))
IR_FOLD(SUB(ADD, C_I16))
IR_FOLD(SUB(ADD, C_I32))
IR_FOLD(SUB(ADD, C_I64))
{
if (IR_IS_CONST_REF(op1_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op)) {
/* (x + c1) - c2 => x + (c1 - c2) */
val.i64 = ctx->ir_base[op1_insn->op2].val.i64 - op2_insn->val.i64;
if (val.i64 < 0 && val.i64 - 1 < 0) {
val.i64 = -val.i64;
} else {
opt--; /* SUB -> ADD */
}
op1 = op1_insn->op1;
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(SUB(C_U8, ADD))
IR_FOLD(SUB(C_U16, ADD))
IR_FOLD(SUB(C_U32, ADD))
IR_FOLD(SUB(C_U64, ADD))
IR_FOLD(SUB(C_ADDR, ADD))
{
if (IR_IS_CONST_REF(op2_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op2].op)) {
/* c1 - (x + c2) => (c1 - c2) - x */
val.u64 = op1_insn->val.u64 - ctx->ir_base[op2_insn->op2].val.u64;
op1 = ir_const(ctx, val, IR_OPT_TYPE(opt));
op2 = op2_insn->op1;
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(SUB(C_I8, ADD))
IR_FOLD(SUB(C_I16, ADD))
IR_FOLD(SUB(C_I32, ADD))
IR_FOLD(SUB(C_I64, ADD))
{
if (IR_IS_CONST_REF(op2_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op2].op)) {
/* c1 - (x + c2) => (c1 - c2) - x */
val.i64 = op1_insn->val.i64 - ctx->ir_base[op2_insn->op2].val.i64;
op1 = ir_const(ctx, val, IR_OPT_TYPE(opt));
op2 = op2_insn->op1;
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(SUB(SUB, C_U8))
IR_FOLD(SUB(SUB, C_U16))
IR_FOLD(SUB(SUB, C_U32))
IR_FOLD(SUB(SUB, C_U64))
IR_FOLD(SUB(SUB, C_ADDR))
{
if (IR_IS_CONST_REF(op1_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op)) {
/* (x - c1) - c2 => x - (c1 + c2) */
val.u64 = ctx->ir_base[op1_insn->op2].val.u64 + op2_insn->val.u64;
if (val.i64 < 0 && val.i64 - 1 < 0) {
val.i64 = -val.i64;
opt--; /* SUB -> ADD */
}
op1 = op1_insn->op1;
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
} else if (IR_IS_CONST_REF(op1_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op1].op)) {
/* (c1 - x) - c2 => (c1 - c2) - x */
val.u64 = ctx->ir_base[op1_insn->op1].val.u64 - op2_insn->val.u64;
op1 = ir_const(ctx, val, IR_OPT_TYPE(opt));
op2 = op1_insn->op2;
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(SUB(SUB, C_I8))
IR_FOLD(SUB(SUB, C_I16))
IR_FOLD(SUB(SUB, C_I32))
IR_FOLD(SUB(SUB, C_I64))
{
if (IR_IS_CONST_REF(op1_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op)) {
/* (x - c1) - c2 => x - (c1 + c2) */
val.i64 = ctx->ir_base[op1_insn->op2].val.i64 + op2_insn->val.i64;
if (val.i64 < 0 && val.i64 - 1 < 0) {
val.i64 = -val.i64;
opt--; /* SUB -> ADD */
}
op1 = op1_insn->op1;
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
} else if (IR_IS_CONST_REF(op1_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op1].op)) {
/* (c1 - x) - c2 => (c1 - c2) - x */
val.i64 = ctx->ir_base[op1_insn->op1].val.i64 - op2_insn->val.i64;
op1 = ir_const(ctx, val, IR_OPT_TYPE(opt));
op2 = op1_insn->op2;
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(SUB(C_U8, SUB))
IR_FOLD(SUB(C_U16, SUB))
IR_FOLD(SUB(C_U32, SUB))
IR_FOLD(SUB(C_U64, SUB))
IR_FOLD(SUB(C_ADDR, SUB))
{
if (IR_IS_CONST_REF(op2_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op2].op)) {
/* c1 - (x - c2) => (c1 + c2) - x */
val.u64 = op1_insn->val.u64 + ctx->ir_base[op2_insn->op2].val.u64;
op1 = ir_const(ctx, val, IR_OPT_TYPE(opt));
op2 = op2_insn->op1;
IR_FOLD_RESTART;
} else if (IR_IS_CONST_REF(op2_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op1].op)) {
/* c1 - (c2 - x) => x + (c1 - c2) */
val.u64 = op1_insn->val.u64 - ctx->ir_base[op2_insn->op1].val.u64;
if (val.i64 < 0 && val.i64 - 1 < 0) {
val.i64 = -val.i64;
opt++; /* ADD -> SUB */
}
op1 = op2_insn->op2;
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(SUB(C_I8, SUB))
IR_FOLD(SUB(C_I16, SUB))
IR_FOLD(SUB(C_I32, SUB))
IR_FOLD(SUB(C_I64, SUB))
{
if (IR_IS_CONST_REF(op2_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op2].op)) {
/* c1 - (x - c2) => (c1 + c2) - x */
val.i64 = op1_insn->val.i64 + ctx->ir_base[op2_insn->op2].val.i64;
op1 = ir_const(ctx, val, IR_OPT_TYPE(opt));
op2 = op2_insn->op1;
IR_FOLD_RESTART;
} else if (IR_IS_CONST_REF(op2_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op1].op)) {
/* c1 - (c2 - x) => x + (c1 - c2) */
val.i64 = op1_insn->val.i64 - ctx->ir_base[op2_insn->op1].val.i64;
if (val.i64 < 0 && val.i64 - 1 < 0) {
val.i64 = -val.i64;
opt++; /* ADD -> SUB */
}
op1 = op2_insn->op2;
op2 = ir_const(ctx, val, IR_OPT_TYPE(opt));
IR_FOLD_RESTART;
}
IR_FOLD_NEXT;
}
IR_FOLD(MUL(MUL, C_U8))
IR_FOLD(MUL(MUL, C_U16))
IR_FOLD(MUL(MUL, C_U32))
IR_FOLD(MUL(MUL, C_U64))
IR_FOLD(MUL(MUL, C_ADDR))
{
if (IR_IS_CONST_REF(op1_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op)) {
/* (x * c1) * c2 => x * (c1 * c2) */
@@ -2520,7 +2740,6 @@ IR_FOLD(MUL(MUL, C_I8))
IR_FOLD(MUL(MUL, C_I16))
IR_FOLD(MUL(MUL, C_I32))
IR_FOLD(MUL(MUL, C_I64))
IR_FOLD(MUL(MUL, C_ADDR))
{
if (IR_IS_CONST_REF(op1_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op2].op)) {
/* (x * c1) * c2 => x * (c1 * c2) */

View File

@@ -855,6 +855,8 @@ extern const uint8_t ir_type_size[IR_LAST_TYPE];
extern const uint32_t ir_op_flags[IR_LAST_OP];
extern const char *ir_op_name[IR_LAST_OP];
void ir_print_escaped_str(const char *s, size_t len, FILE *f);
#define IR_IS_CONST_OP(op) ((op) > IR_NOP && (op) <= IR_C_FLOAT)
#define IR_IS_FOLDABLE_OP(op) ((op) <= IR_LAST_FOLDABLE_OP)
#define IR_IS_SYM_CONST(op) ((op) == IR_STR || (op) == IR_SYM || (op) == IR_FUNC)

View File

@@ -722,8 +722,10 @@ int ir_compute_live_ranges(ir_ctx *ctx)
|| (ctx->rules[ref] & IR_RULE_MASK) == IR_ALLOCA)
&& ctx->use_lists[ref].count > 0) {
insn = &ctx->ir_base[ref];
insn->op3 = ctx->vars;
ctx->vars = ref;
if (insn->op != IR_VADDR) {
insn->op3 = ctx->vars;
ctx->vars = ref;
}
}
continue;
}
@@ -1338,8 +1340,10 @@ int ir_compute_live_ranges(ir_ctx *ctx)
|| (ctx->rules[ref] & IR_RULE_MASK) == IR_ALLOCA)
&& ctx->use_lists[ref].count > 0) {
insn = &ctx->ir_base[ref];
insn->op3 = ctx->vars;
ctx->vars = ref;
if (insn->op != IR_VADDR) {
insn->op3 = ctx->vars;
ctx->vars = ref;
}
}
continue;
}
@@ -3507,13 +3511,27 @@ static int ir_linear_scan(ir_ctx *ctx)
data.handled = NULL;
while (vars) {
ir_insn *insn = &ctx->ir_base[vars];
ir_ref var = vars;
ir_insn *insn = &ctx->ir_base[var];
IR_ASSERT(insn->op == IR_VAR || insn->op == IR_ALLOCA);
vars = insn->op3; /* list next */
if (insn->op == IR_VAR) {
insn->op3 = ir_allocate_spill_slot(ctx, insn->type, &data);
ir_ref slot = ir_allocate_spill_slot(ctx, insn->type, &data);;
ir_use_list *use_list;
ir_ref n, *p;
insn->op3 = slot;
use_list = &ctx->use_lists[var];
n = use_list->count;
p = &ctx->use_edges[use_list->refs];
for (; n > 0; p++, n--) {
insn = &ctx->ir_base[*p];
if (insn->op == IR_VADDR) {
insn->op3 = slot;
}
}
} else {
ir_insn *val = &ctx->ir_base[insn->op2];
@@ -4060,7 +4078,8 @@ static void assign_regs(ir_ctx *ctx)
if (IR_IS_CONST_REF(ops[ival->tmp_op_num])) {
/* constant rematerialization */
reg |= IR_REG_SPILL_LOAD;
} else if (ctx->ir_base[ops[ival->tmp_op_num]].op == IR_ALLOCA) {
} else if (ctx->ir_base[ops[ival->tmp_op_num]].op == IR_ALLOCA
|| ctx->ir_base[ops[ival->tmp_op_num]].op == IR_VADDR) {
/* local address rematerialization */
reg |= IR_REG_SPILL_LOAD;
}

View File

@@ -2810,7 +2810,7 @@ store_int:
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
if (ctx->ir_base[*p].op != IR_VA_END) {
return IR_VADDR;
return IR_STATIC_ALLOCA;
}
}
}