Skip to content

Commit 71194ea

Browse files
committed
Update IR
IR commit: 65586bd4cf9cd2d3b41492f52823c5083cea77e4
1 parent b6cf388 commit 71194ea

File tree

8 files changed

+320
-60
lines changed

8 files changed

+320
-60
lines changed

ext/opcache/jit/ir/ir.c

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const char *ir_op_name[IR_LAST_OP] = {
7575
#endif
7676
};
7777

78-
static void ir_print_escaped_str(const char *s, size_t len, FILE *f)
78+
void ir_print_escaped_str(const char *s, size_t len, FILE *f)
7979
{
8080
char ch;
8181

@@ -95,10 +95,14 @@ static void ir_print_escaped_str(const char *s, size_t len, FILE *f)
9595
case '\v': fputs("\\v", f); break;
9696
case '\?': fputs("\\?", f); break;
9797
default:
98+
#ifdef __aarch64__
9899
if (ch < 32) {
100+
#else
101+
if (ch >= 0 && ch < 32) {
102+
#endif
99103
fprintf(f, "\\%c%c%c",
100-
'0' + ((ch >> 3) % 8),
101104
'0' + ((ch >> 6) % 8),
105+
'0' + ((ch >> 3) % 8),
102106
'0' + (ch % 8));
103107
break;
104108
} else {
@@ -1784,48 +1788,64 @@ static ir_alias ir_check_aliasing(ir_ctx *ctx, ir_ref addr1, ir_ref addr2)
17841788
static ir_alias ir_check_partial_aliasing(const ir_ctx *ctx, ir_ref addr1, ir_ref addr2, ir_type type1, ir_type type2)
17851789
{
17861790
ir_insn *insn1, *insn2;
1791+
ir_ref base1, base2, off1, off2;
17871792

17881793
/* this must be already check */
17891794
IR_ASSERT(addr1 != addr2);
17901795

17911796
insn1 = &ctx->ir_base[addr1];
17921797
insn2 = &ctx->ir_base[addr2];
1793-
if (insn1->op == IR_ADD && IR_IS_CONST_REF(insn1->op2)) {
1794-
if (insn1->op1 == addr2) {
1795-
uintptr_t offset1 = ctx->ir_base[insn1->op2].val.addr;
1796-
uintptr_t size2 = ir_type_size[type2];
1797-
1798-
return (offset1 < size2) ? IR_MUST_ALIAS : IR_NO_ALIAS;
1799-
} else if (insn2->op == IR_ADD && IR_IS_CONST_REF(insn1->op2) && insn1->op1 == insn2->op1) {
1800-
if (insn1->op2 == insn2->op2) {
1801-
return IR_MUST_ALIAS;
1802-
} else if (IR_IS_CONST_REF(insn1->op2) && IR_IS_CONST_REF(insn2->op2)) {
1803-
uintptr_t offset1 = ctx->ir_base[insn1->op2].val.addr;
1804-
uintptr_t offset2 = ctx->ir_base[insn2->op2].val.addr;
1805-
1806-
if (offset1 == offset2) {
1807-
return IR_MUST_ALIAS;
1808-
} else if (type1 == type2) {
1809-
return IR_NO_ALIAS;
1810-
} else {
1811-
/* check for partail intersection */
1812-
uintptr_t size1 = ir_type_size[type1];
1813-
uintptr_t size2 = ir_type_size[type2];
1798+
if (insn1->op != IR_ADD) {
1799+
base1 = addr1;
1800+
off1 = IR_UNUSED;
1801+
} else if (ctx->ir_base[insn1->op2].op == IR_SYM) {
1802+
base1 = insn1->op2;
1803+
off1 = insn1->op1;
1804+
} else {
1805+
base1 = insn1->op1;
1806+
off1 = insn1->op2;
1807+
}
1808+
if (insn2->op != IR_ADD) {
1809+
base2 = addr2;
1810+
off2 = IR_UNUSED;
1811+
} else if (ctx->ir_base[insn2->op2].op == IR_SYM) {
1812+
base2 = insn2->op2;
1813+
off2 = insn2->op1;
1814+
} else {
1815+
base2 = insn2->op1;
1816+
off2 = insn2->op2;
1817+
}
1818+
if (base1 == base2) {
1819+
uintptr_t offset1, offset2;
18141820

1815-
if (offset1 > offset2) {
1816-
return offset1 < offset2 + size2 ? IR_MUST_ALIAS : IR_NO_ALIAS;
1817-
} else {
1818-
return offset2 < offset1 + size1 ? IR_MUST_ALIAS : IR_NO_ALIAS;
1819-
}
1820-
}
1821-
}
1821+
if (!off1) {
1822+
offset1 = 0;
1823+
} else if (IR_IS_CONST_REF(off1) && !IR_IS_SYM_CONST(ctx->ir_base[off1].op)) {
1824+
offset1 = ctx->ir_base[off1].val.addr;
1825+
} else {
1826+
return IR_MAY_ALIAS;
18221827
}
1823-
} else if (insn2->op == IR_ADD && IR_IS_CONST_REF(insn2->op2)) {
1824-
if (insn2->op1 == addr1) {
1825-
uintptr_t offset2 = ctx->ir_base[insn2->op2].val.addr;
1826-
uintptr_t size1 = ir_type_size[type1];
1827-
1828-
return (offset2 < size1) ? IR_MUST_ALIAS : IR_NO_ALIAS;
1828+
if (!off2) {
1829+
offset2 = 0;
1830+
} else if (IR_IS_CONST_REF(off2) && !IR_IS_SYM_CONST(ctx->ir_base[off2].op)) {
1831+
offset2 = ctx->ir_base[off2].val.addr;
1832+
} else {
1833+
return IR_MAY_ALIAS;
1834+
}
1835+
if (offset1 == offset2) {
1836+
return IR_MUST_ALIAS;
1837+
} else if (offset1 < offset2) {
1838+
return offset1 + ir_type_size[type1] <= offset2 ? IR_NO_ALIAS : IR_MUST_ALIAS;
1839+
} else {
1840+
return offset2 + ir_type_size[type2] <= offset1 ? IR_NO_ALIAS : IR_MUST_ALIAS;
1841+
}
1842+
} else {
1843+
insn1 = &ctx->ir_base[base1];
1844+
insn2 = &ctx->ir_base[base2];
1845+
if ((insn1->op == IR_ALLOCA && (insn2->op == IR_ALLOCA || insn2->op == IR_SYM || insn2->op == IR_PARAM))
1846+
|| (insn1->op == IR_SYM && (insn2->op == IR_ALLOCA || insn2->op == IR_SYM))
1847+
|| (insn1->op == IR_PARAM && insn2->op == IR_ALLOCA)) {
1848+
return IR_NO_ALIAS;
18291849
}
18301850
}
18311851
return IR_MAY_ALIAS;

ext/opcache/jit/ir/ir.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,9 @@ void ir_strtab_free(ir_strtab *strtab);
513513
#define IR_EXTERN (1<<5)
514514
#define IR_CONST (1<<6)
515515

516+
#define IR_INITIALIZED (1<<7) /* sym data flag: constant or an initialized variable */
517+
#define IR_CONST_STRING (1<<8) /* sym data flag: constant string */
518+
516519
#define IR_SKIP_PROLOGUE (1<<8) /* Don't generate function prologue. */
517520
#define IR_USE_FRAME_POINTER (1<<9)
518521
#define IR_PREALLOCATED_STACK (1<<10)
@@ -825,11 +828,12 @@ struct _ir_loader {
825828
uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types);
826829
bool (*forward_func_dcl) (ir_loader *loader, const char *name,
827830
uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types);
828-
bool (*sym_dcl) (ir_loader *loader, const char *name, uint32_t flags, size_t size, bool has_data);
831+
bool (*sym_dcl) (ir_loader *loader, const char *name, uint32_t flags, size_t size);
829832
bool (*sym_data) (ir_loader *loader, ir_type type, uint32_t count, const void *data);
833+
bool (*sym_data_str) (ir_loader *loader, const char *str, size_t len);
830834
bool (*sym_data_pad) (ir_loader *loader, size_t offset);
831835
bool (*sym_data_ref) (ir_loader *loader, ir_op op, const char *ref, uintptr_t offset);
832-
bool (*sym_data_end) (ir_loader *loader);
836+
bool (*sym_data_end) (ir_loader *loader, uint32_t flags);
833837
bool (*func_init) (ir_loader *loader, ir_ctx *ctx, const char *name);
834838
bool (*func_process) (ir_loader *loader, ir_ctx *ctx, const char *name);
835839
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);
867871
/* IR to C conversion (implementation in ir_emit_c.c) */
868872
int ir_emit_c(ir_ctx *ctx, const char *name, FILE *f);
869873
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);
870-
void ir_emit_c_sym_decl(const char *name, uint32_t flags, bool has_data, FILE *f);
874+
void ir_emit_c_sym_decl(const char *name, uint32_t flags, FILE *f);
871875

872876
/* IR to LLVM conversion (implementation in ir_emit_llvm.c) */
873877
int ir_emit_llvm(ir_ctx *ctx, const char *name, FILE *f);
874878
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);
875-
void ir_emit_llvm_sym_decl(const char *name, uint32_t flags, bool has_data, FILE *f);
879+
void ir_emit_llvm_sym_decl(const char *name, uint32_t flags, FILE *f);
876880

877881
/* IR verification API (implementation in ir_check.c) */
878882
bool ir_check(const ir_ctx *ctx);

ext/opcache/jit/ir/ir_aarch64.dasc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ binop_fp:
10571057
return insn->op;
10581058
case IR_VA_START:
10591059
ctx->flags2 |= IR_HAS_VA_START;
1060-
if (ctx->ir_base[insn->op2].op == IR_ALLOCA) {
1060+
if ((ctx->ir_base[insn->op2].op == IR_ALLOCA) || (ctx->ir_base[insn->op2].op == IR_VADDR)) {
10611061
ir_use_list *use_list = &ctx->use_lists[insn->op2];
10621062
ir_ref *p, n = use_list->count;
10631063
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
@@ -1092,7 +1092,7 @@ binop_fp:
10921092

10931093
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
10941094
if (ctx->ir_base[*p].op != IR_VA_END) {
1095-
return IR_VADDR;
1095+
return IR_STATIC_ALLOCA;
10961096
}
10971097
}
10981098
}
@@ -3802,7 +3802,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref)
38023802
return IR_MEM_BO(reg, ctx->ir_base[addr_insn->op2].val.i32);
38033803
}
38043804
} else {
3805-
IR_ASSERT(addr_insn->op == IR_ALLOCA);
3805+
IR_ASSERT(addr_insn->op == IR_ALLOCA || addr_insn->op == IR_VADDR);
38063806
reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
38073807
offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[ref].op3);
38083808
return IR_MEM_BO(reg, offset);

ext/opcache/jit/ir/ir_check.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,10 @@ bool ir_check(const ir_ctx *ctx)
178178
/* boolean not */
179179
break;
180180
}
181-
if (sizeof(void*) == 8) {
182-
if (insn->type == IR_ADDR && (use_insn->type == IR_U64 || use_insn->type == IR_I64)) {
183-
break;
184-
}
185-
} else {
186-
if (insn->type == IR_ADDR && (use_insn->type == IR_U32 || use_insn->type == IR_I32)) {
187-
break;
188-
}
181+
if (insn->type == IR_ADDR && (use_insn->type == IR_UINTPTR_T || use_insn->type == IR_INTPTR_T)) {
182+
break;
183+
} else if (use_insn->type == IR_ADDR && (insn->type == IR_UINTPTR_T || insn->type == IR_INTPTR_T)) {
184+
break;
189185
}
190186
fprintf(stderr, "ir_base[%d].ops[%d] (%d) type is incompatible with result type (%d != %d)\n",
191187
i, j, use, use_insn->type, insn->type);

0 commit comments

Comments
 (0)