From 63965f1de54e1656a567b0ef37797d8756ee12cd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 22 Jan 2025 18:30:33 +0300 Subject: [PATCH] Update IR IR commit: 02909bc123845fc2c41ec333b44b6f5ea1a196fe --- ext/opcache/jit/ir/ir.c | 6 ++++++ ext/opcache/jit/ir/ir.h | 8 ++++++-- ext/opcache/jit/ir/ir_aarch64.dasc | 8 ++++---- ext/opcache/jit/ir/ir_builder.h | 2 +- ext/opcache/jit/ir/ir_cfg.c | 2 +- ext/opcache/jit/ir/ir_check.c | 6 ++++++ ext/opcache/jit/ir/ir_emit.c | 2 +- ext/opcache/jit/ir/ir_private.h | 9 ++++++--- 8 files changed, 31 insertions(+), 12 deletions(-) diff --git a/ext/opcache/jit/ir/ir.c b/ext/opcache/jit/ir/ir.c index 17e24833162f3..1aa887f6a949e 100644 --- a/ext/opcache/jit/ir/ir.c +++ b/ext/opcache/jit/ir/ir.c @@ -348,6 +348,12 @@ static void ir_grow_top(ir_ctx *ctx) memset(ctx->use_lists + old_insns_limit, 0, (ctx->insns_limit - old_insns_limit) * sizeof(ir_use_list)); } + + if (ctx->cfg_map) { + ctx->cfg_map = ir_mem_realloc(ctx->cfg_map, ctx->insns_limit * sizeof(uint32_t)); + memset(ctx->cfg_map + old_insns_limit, 0, + (ctx->insns_limit - old_insns_limit) * sizeof(uint32_t)); + } } static ir_ref ir_next_insn(ir_ctx *ctx) diff --git a/ext/opcache/jit/ir/ir.h b/ext/opcache/jit/ir/ir.h index 5d22e0f874c1e..2670fdfa96d4f 100644 --- a/ext/opcache/jit/ir/ir.h +++ b/ext/opcache/jit/ir/ir.h @@ -29,7 +29,9 @@ extern "C" { # endif /* Only supported is little endian for any arch on Windows, so just fake the same for all. */ -# define __ORDER_LITTLE_ENDIAN__ 1 +# ifndef __ORDER_LITTLE_ENDIAN__ +# define __ORDER_LITTLE_ENDIAN__ 1 +# endif # define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ # ifndef __has_builtin # define __has_builtin(arg) (0) @@ -958,10 +960,12 @@ IR_ALWAYS_INLINE void *ir_jit_compile(ir_ctx *ctx, int opt_level, size_t *size) || !ir_mem2ssa(ctx)) { return NULL; } + if (opt_level > 1) { + ir_reset_cfg(ctx); + } } if (opt_level > 1) { - ir_reset_cfg(ctx); if (!ir_sccp(ctx)) { return NULL; } diff --git a/ext/opcache/jit/ir/ir_aarch64.dasc b/ext/opcache/jit/ir/ir_aarch64.dasc index 6b397f27b31ad..b96d47461196c 100644 --- a/ext/opcache/jit/ir/ir_aarch64.dasc +++ b/ext/opcache/jit/ir/ir_aarch64.dasc @@ -925,7 +925,7 @@ binop_fp: if (ctx->flags & IR_FUNCTION) { ctx->flags |= IR_USE_FRAME_POINTER; } - ctx->flags2 |= IR_HAS_CALLS | IR_16B_FRAME_ALIGNMENT; + ctx->flags2 |= IR_HAS_CALLS; return IR_CALL; case IR_VAR: return IR_SKIPPED | IR_VAR; @@ -941,7 +941,7 @@ binop_fp: } } ctx->flags |= IR_USE_FRAME_POINTER; - ctx->flags2 |= IR_HAS_ALLOCA | IR_16B_FRAME_ALIGNMENT; + ctx->flags2 |= IR_HAS_ALLOCA; } return IR_ALLOCA; case IR_LOAD: @@ -5788,12 +5788,12 @@ void ir_fix_stack_frame(ir_ctx *ctx) ctx->stack_frame_alignment = 0; ctx->call_stack_size = 0; - if ((ctx->flags2 & IR_16B_FRAME_ALIGNMENT) && !(ctx->flags & IR_FUNCTION)) { + if (!(ctx->flags & IR_FUNCTION)) { while (IR_ALIGNED_SIZE(ctx->stack_frame_size, 16) != ctx->stack_frame_size) { ctx->stack_frame_size += sizeof(void*); ctx->stack_frame_alignment += sizeof(void*); } - } else if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) { + } else { /* Stack must be 16 byte aligned */ if (!(ctx->flags & IR_FUNCTION)) { while (IR_ALIGNED_SIZE(ctx->stack_frame_size, 16) != ctx->stack_frame_size) { diff --git a/ext/opcache/jit/ir/ir_builder.h b/ext/opcache/jit/ir/ir_builder.h index 0fbdcb3e04586..208c1ae4c8167 100644 --- a/ext/opcache/jit/ir/ir_builder.h +++ b/ext/opcache/jit/ir/ir_builder.h @@ -461,7 +461,7 @@ extern "C" { #define ir_COND_A(_op1, _op2, _op3) ir_fold3(_ir_CTX, IR_OPT(IR_COND, IR_ADDR), (_op1), (_op2), (_op3)) #define ir_COND_C(_op1, _op2, _op3) ir_fold3(_ir_CTX, IR_OPT(IR_COND, IR_CHAR), (_op1), (_op2), (_op3)) #define ir_COND_I8(_op1, _op2, _op3) ir_fold3(_ir_CTX, IR_OPT(IR_COND, IR_I8), (_op1), (_op2), (_op3)) -#define ir_COND_I16(_op1, _op2, _op3) ir_fold3(_ir_CTX, IR_OPT(IR_COMD, IR_I16), (_op1), (_op2), (_op3)) +#define ir_COND_I16(_op1, _op2, _op3) ir_fold3(_ir_CTX, IR_OPT(IR_COND, IR_I16), (_op1), (_op2), (_op3)) #define ir_COND_I32(_op1, _op2, _op3) ir_fold3(_ir_CTX, IR_OPT(IR_COND, IR_I32), (_op1), (_op2), (_op3)) #define ir_COND_I64(_op1, _op2, _op3) ir_fold3(_ir_CTX, IR_OPT(IR_COND, IR_I64), (_op1), (_op2), (_op3)) #define ir_COND_D(_op1, _op2, _op3) ir_fold3(_ir_CTX, IR_OPT(IR_COND, IR_DOUBLE), (_op1), (_op2), (_op3)) diff --git a/ext/opcache/jit/ir/ir_cfg.c b/ext/opcache/jit/ir/ir_cfg.c index 7a71208d7823c..3678867e46c7a 100644 --- a/ext/opcache/jit/ir/ir_cfg.c +++ b/ext/opcache/jit/ir/ir_cfg.c @@ -92,7 +92,7 @@ int ir_build_cfg(ir_ctx *ctx) uint32_t len = ir_bitset_len(ctx->insns_count); ir_bitset bb_starts = ir_mem_calloc(len * 2, IR_BITSET_BITS / 8); ir_bitset bb_leaks = bb_starts + len; - _blocks = ir_mem_calloc(ctx->insns_count, sizeof(uint32_t)); + _blocks = ir_mem_calloc(ctx->insns_limit, sizeof(uint32_t)); ir_worklist_init(&worklist, ctx->insns_count); /* First try to perform backward DFS search starting from "stop" nodes */ diff --git a/ext/opcache/jit/ir/ir_check.c b/ext/opcache/jit/ir/ir_check.c index 656f8dbe7c1a2..0e0bf3ca4c535 100644 --- a/ext/opcache/jit/ir/ir_check.c +++ b/ext/opcache/jit/ir/ir_check.c @@ -291,6 +291,12 @@ bool ir_check(const ir_ctx *ctx) ok = 0; } break; + case IR_PARAM: + if (i > 2 && ctx->ir_base[i - 1].op != IR_PARAM) { + fprintf(stderr, "ir_base[%d].op PARAMs must be used only right after START\n", i); + ok = 0; + } + break; } if (ctx->use_lists) { diff --git a/ext/opcache/jit/ir/ir_emit.c b/ext/opcache/jit/ir/ir_emit.c index 83fc242a20c11..367dee72963bf 100644 --- a/ext/opcache/jit/ir/ir_emit.c +++ b/ext/opcache/jit/ir/ir_emit.c @@ -272,10 +272,10 @@ static bool ir_is_same_mem_var(const ir_ctx *ctx, ir_ref r1, int32_t offset) void *ir_resolve_sym_name(const char *name) { - void *handle = NULL; void *addr; #ifndef _WIN32 + void *handle = NULL; # ifdef RTLD_DEFAULT handle = RTLD_DEFAULT; # endif diff --git a/ext/opcache/jit/ir/ir_private.h b/ext/opcache/jit/ir/ir_private.h index 4d1e8dd32bb22..f980b86b89320 100644 --- a/ext/opcache/jit/ir/ir_private.h +++ b/ext/opcache/jit/ir/ir_private.h @@ -137,9 +137,10 @@ IR_ALWAYS_INLINE uint32_t ir_ntz(uint32_t num) /* Number of trailing zero bits (0x01 -> 0; 0x40 -> 6; 0x00 -> LEN) */ IR_ALWAYS_INLINE uint32_t ir_ntzl(uint64_t num) { -#if (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) - return __builtin_ctzl(num); -#elif defined(_WIN64) + // Note that the _WIN64 case should come before __has_builtin() below so that + // clang-cl on Windows will use the uint64_t version, not the "long" uint32_t + // version. +#if defined(_WIN64) unsigned long index; if (!_BitScanForward64(&index, num)) { @@ -148,6 +149,8 @@ IR_ALWAYS_INLINE uint32_t ir_ntzl(uint64_t num) } return (uint32_t) index; +#elif (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) + return __builtin_ctzl(num); #else uint32_t n;