Skip to content

Commit 4630f77

Browse files
committed
Update IR
IR commit: a746ceb6506b21705bd35473144c60194ae3191d
1 parent f3ece81 commit 4630f77

File tree

11 files changed

+503
-285
lines changed

11 files changed

+503
-285
lines changed

ext/opcache/jit/ir/ir.c

Lines changed: 109 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "ir.h"
2929
#include "ir_private.h"
3030

31+
#include <stddef.h>
3132
#include <math.h>
3233

3334
#ifdef HAVE_VALGRIND
@@ -70,13 +71,13 @@ const char *ir_op_name[IR_LAST_OP] = {
7071
void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted)
7172
{
7273
if (insn->op == IR_FUNC || insn->op == IR_SYM) {
73-
fprintf(f, "%s", ir_get_str(ctx, insn->val.i32));
74+
fprintf(f, "%s", ir_get_str(ctx, insn->val.name));
7475
return;
7576
} else if (insn->op == IR_STR) {
7677
if (quoted) {
77-
fprintf(f, "\"%s\"", ir_get_str(ctx, insn->val.i32));
78+
fprintf(f, "\"%s\"", ir_get_str(ctx, insn->val.str));
7879
} else {
79-
fprintf(f, "%s", ir_get_str(ctx, insn->val.i32));
80+
fprintf(f, "%s", ir_get_str(ctx, insn->val.str));
8081
}
8182
return;
8283
}
@@ -217,6 +218,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted
217218
#define ir_op_kind_var IR_OPND_DATA
218219
#define ir_op_kind_prb IR_OPND_PROB
219220
#define ir_op_kind_opt IR_OPND_PROB
221+
#define ir_op_kind_pro IR_OPND_PROTO
220222

221223
#define _IR_OP_FLAGS(name, flags, op1, op2, op3) \
222224
IR_OP_FLAGS(ir_op_flag_ ## flags, ir_op_kind_ ## op1, ir_op_kind_ ## op2, ir_op_kind_ ## op3),
@@ -562,34 +564,36 @@ ir_ref ir_const_addr(ir_ctx *ctx, uintptr_t c)
562564
return ir_const(ctx, val, IR_ADDR);
563565
}
564566

565-
ir_ref ir_const_func_addr(ir_ctx *ctx, uintptr_t c, uint16_t flags)
567+
ir_ref ir_const_func_addr(ir_ctx *ctx, uintptr_t c, ir_ref proto)
566568
{
567569
if (c == 0) {
568570
return IR_NULL;
569571
}
570572
ir_val val;
571573
val.u64 = c;
572-
return ir_const_ex(ctx, val, IR_ADDR, IR_OPTX(IR_FUNC_ADDR, IR_ADDR, flags));
574+
IR_ASSERT(proto >= 0 && proto < 0xffff);
575+
return ir_const_ex(ctx, val, IR_ADDR, IR_OPTX(IR_FUNC_ADDR, IR_ADDR, proto));
573576
}
574577

575-
ir_ref ir_const_func(ir_ctx *ctx, ir_ref str, uint16_t flags)
578+
ir_ref ir_const_func(ir_ctx *ctx, ir_ref str, ir_ref proto)
576579
{
577580
ir_val val;
578-
val.addr = str;
579-
return ir_const_ex(ctx, val, IR_ADDR, IR_OPTX(IR_FUNC, IR_ADDR, flags));
581+
val.u64 = str;
582+
IR_ASSERT(proto >= 0 && proto < 0xffff);
583+
return ir_const_ex(ctx, val, IR_ADDR, IR_OPTX(IR_FUNC, IR_ADDR, proto));
580584
}
581585

582586
ir_ref ir_const_sym(ir_ctx *ctx, ir_ref str)
583587
{
584588
ir_val val;
585-
val.addr = str;
589+
val.u64 = str;
586590
return ir_const_ex(ctx, val, IR_ADDR, IR_OPTX(IR_SYM, IR_ADDR, 0));
587591
}
588592

589593
ir_ref ir_const_str(ir_ctx *ctx, ir_ref str)
590594
{
591595
ir_val val;
592-
val.addr = str;
596+
val.u64 = str;
593597
return ir_const_ex(ctx, val, IR_ADDR, IR_OPTX(IR_STR, IR_ADDR, 0));
594598
}
595599

@@ -620,6 +624,101 @@ const char *ir_get_str(const ir_ctx *ctx, ir_ref idx)
620624
return ir_strtab_str(&ctx->strtab, idx - 1);
621625
}
622626

627+
const char *ir_get_strl(const ir_ctx *ctx, ir_ref idx, size_t *len)
628+
{
629+
IR_ASSERT(ctx->strtab.data);
630+
return ir_strtab_strl(&ctx->strtab, idx - 1, len);
631+
}
632+
633+
ir_ref ir_proto_0(ir_ctx *ctx, uint8_t flags, ir_type ret_type)
634+
{
635+
ir_proto_t proto;
636+
637+
proto.flags = flags;
638+
proto.ret_type = ret_type;
639+
proto.params_count = 0;
640+
return ir_strl(ctx, (const char *)&proto, offsetof(ir_proto_t, param_types) + 0);
641+
}
642+
643+
ir_ref ir_proto_1(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1)
644+
{
645+
ir_proto_t proto;
646+
647+
proto.flags = flags;
648+
proto.ret_type = ret_type;
649+
proto.params_count = 1;
650+
proto.param_types[0] = t1;
651+
return ir_strl(ctx, (const char *)&proto, offsetof(ir_proto_t, param_types) + 1);
652+
}
653+
654+
ir_ref ir_proto_2(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2)
655+
{
656+
ir_proto_t proto;
657+
658+
proto.flags = flags;
659+
proto.ret_type = ret_type;
660+
proto.params_count = 2;
661+
proto.param_types[0] = t1;
662+
proto.param_types[1] = t2;
663+
return ir_strl(ctx, (const char *)&proto, offsetof(ir_proto_t, param_types) + 2);
664+
}
665+
666+
ir_ref ir_proto_3(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3)
667+
{
668+
ir_proto_t proto;
669+
670+
proto.flags = flags;
671+
proto.ret_type = ret_type;
672+
proto.params_count = 3;
673+
proto.param_types[0] = t1;
674+
proto.param_types[1] = t2;
675+
proto.param_types[2] = t3;
676+
return ir_strl(ctx, (const char *)&proto, offsetof(ir_proto_t, param_types) + 3);
677+
}
678+
679+
ir_ref ir_proto_4(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3,
680+
ir_type t4)
681+
{
682+
ir_proto_t proto;
683+
684+
proto.flags = flags;
685+
proto.ret_type = ret_type;
686+
proto.params_count = 4;
687+
proto.param_types[0] = t1;
688+
proto.param_types[1] = t2;
689+
proto.param_types[2] = t3;
690+
proto.param_types[3] = t4;
691+
return ir_strl(ctx, (const char *)&proto, offsetof(ir_proto_t, param_types) + 4);
692+
}
693+
694+
ir_ref ir_proto_5(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3,
695+
ir_type t4, ir_type t5)
696+
{
697+
ir_proto_t proto;
698+
699+
proto.flags = flags;
700+
proto.ret_type = ret_type;
701+
proto.params_count = 5;
702+
proto.param_types[0] = t1;
703+
proto.param_types[1] = t2;
704+
proto.param_types[2] = t3;
705+
proto.param_types[3] = t4;
706+
proto.param_types[4] = t5;
707+
return ir_strl(ctx, (const char *)&proto, offsetof(ir_proto_t, param_types) + 5);
708+
}
709+
710+
ir_ref ir_proto(ir_ctx *ctx, uint8_t flags, ir_type ret_type, uint32_t params_count, uint8_t *param_types)
711+
{
712+
ir_proto_t *proto = alloca(offsetof(ir_proto_t, param_types) + params_count);
713+
714+
IR_ASSERT(params_count <= IR_MAX_PROTO_PARAMS);
715+
proto->flags = flags;
716+
proto->ret_type = ret_type;
717+
proto->params_count = params_count;
718+
memcpy(proto->param_types, param_types, params_count);
719+
return ir_strl(ctx, (const char *)proto, offsetof(ir_proto_t, param_types) + params_count);
720+
}
721+
623722
/* IR construction */
624723
ir_ref ir_emit(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3)
625724
{

ext/opcache/jit/ir/ir.h

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ typedef enum _ir_type {
186186
* num - number: argument number (PARAM)
187187
* prb - branch probability 1-99 (0 - unspecified): (IF_TRUE, IF_FALSE, CASE_VAL, CASE_DEFAULT)
188188
* opt - optional number
189+
* pro - function prototype
189190
*
190191
* The order of IR opcodes is carefully selected for efficient folding.
191192
* - foldable instruction go first
@@ -246,6 +247,7 @@ typedef enum _ir_type {
246247
_(INT2FP, d1, def, ___, ___) /* int to float conversion */ \
247248
_(FP2INT, d1, def, ___, ___) /* float to int conversion */ \
248249
_(FP2FP, d1, def, ___, ___) /* float to float conversion */ \
250+
_(PROTO, d1X1, def, pro, ___) /* apply function prototype */ \
249251
\
250252
/* overflow-check */ \
251253
_(ADD_OV, d2C, def, def, ___) /* addition */ \
@@ -376,7 +378,6 @@ typedef int32_t ir_ref;
376378
#define IR_CONSTS_LIMIT_MIN (-(IR_TRUE - 1))
377379
#define IR_INSNS_LIMIT_MIN (IR_UNUSED + 1)
378380

379-
380381
#ifndef IR_64
381382
# define ADDR_MEMBER uintptr_t addr;
382383
#else
@@ -395,6 +396,8 @@ typedef union _ir_val {
395396
int32_t i32;
396397
float f;
397398
ADDR_MEMBER
399+
ir_ref name;
400+
ir_ref str;
398401
IR_STRUCT_LOHI(
399402
union {
400403
uint16_t u16;
@@ -417,12 +420,6 @@ typedef union _ir_val {
417420
} ir_val;
418421
#undef ADDR_MEMBER
419422

420-
/* IR constant flags */
421-
#define IR_CONST_EMIT (1<<0)
422-
#define IR_CONST_FASTCALL_FUNC (1<<1)
423-
#define IR_CONST_VARARG_FUNC (1<<2)
424-
#define IR_CONST_BUILTIN_FUNC (1<<3)
425-
426423
/* IR Instruction */
427424
typedef struct _ir_insn {
428425
IR_STRUCT_LOHI(
@@ -438,7 +435,7 @@ typedef struct _ir_insn {
438435
union {
439436
uint16_t inputs_count; /* number of input control edges for MERGE, PHI, CALL, TAILCALL */
440437
uint16_t prev_insn_offset; /* 16-bit backward offset from current instruction for CSE */
441-
uint16_t const_flags; /* flag to emit constant in rodat section */
438+
uint16_t proto;
442439
}
443440
);
444441
uint32_t optx;
@@ -482,38 +479,40 @@ ir_ref ir_strtab_lookup(ir_strtab *strtab, const char *str, uint32_t len, ir_ref
482479
ir_ref ir_strtab_find(const ir_strtab *strtab, const char *str, uint32_t len);
483480
ir_ref ir_strtab_update(ir_strtab *strtab, const char *str, uint32_t len, ir_ref val);
484481
const char *ir_strtab_str(const ir_strtab *strtab, ir_ref idx);
482+
const char *ir_strtab_strl(const ir_strtab *strtab, ir_ref idx, size_t *len);
485483
void ir_strtab_apply(const ir_strtab *strtab, ir_strtab_apply_t func);
486484
void ir_strtab_free(ir_strtab *strtab);
487485

488486
/* IR Context Flags */
489487
#define IR_FUNCTION (1<<0) /* Generate a function. */
490488
#define IR_FASTCALL_FUNC (1<<1) /* Generate a function with fastcall calling convention, x86 32-bit only. */
491489
#define IR_VARARG_FUNC (1<<2)
492-
#define IR_STATIC (1<<3)
493-
#define IR_EXTERN (1<<4)
494-
#define IR_CONST (1<<5)
495-
496-
#define IR_SKIP_PROLOGUE (1<<6) /* Don't generate function prologue. */
497-
#define IR_USE_FRAME_POINTER (1<<7)
498-
#define IR_PREALLOCATED_STACK (1<<8)
499-
#define IR_NO_STACK_COMBINE (1<<9)
500-
#define IR_START_BR_TARGET (1<<10)
501-
#define IR_ENTRY_BR_TARGET (1<<11)
502-
#define IR_GEN_ENDBR (1<<12)
503-
#define IR_MERGE_EMPTY_ENTRIES (1<<13)
504-
505-
#define IR_OPT_FOLDING (1<<18)
506-
#define IR_OPT_CFG (1<<19) /* merge BBs, by remove END->BEGIN nodes during CFG construction */
507-
#define IR_OPT_CODEGEN (1<<20)
508-
#define IR_GEN_NATIVE (1<<23)
509-
#define IR_GEN_CODE (1<<24) /* C or LLVM */
490+
#define IR_BUILTIN_FUNC (1<<3)
491+
#define IR_STATIC (1<<4)
492+
#define IR_EXTERN (1<<5)
493+
#define IR_CONST (1<<6)
494+
495+
#define IR_SKIP_PROLOGUE (1<<8) /* Don't generate function prologue. */
496+
#define IR_USE_FRAME_POINTER (1<<9)
497+
#define IR_PREALLOCATED_STACK (1<<10)
498+
#define IR_NO_STACK_COMBINE (1<<11)
499+
#define IR_START_BR_TARGET (1<<12)
500+
#define IR_ENTRY_BR_TARGET (1<<13)
501+
#define IR_GEN_ENDBR (1<<14)
502+
#define IR_MERGE_EMPTY_ENTRIES (1<<15)
503+
504+
#define IR_OPT_FOLDING (1<<16)
505+
#define IR_OPT_CFG (1<<17) /* merge BBs, by remove END->BEGIN nodes during CFG construction */
506+
#define IR_OPT_CODEGEN (1<<18)
507+
#define IR_GEN_NATIVE (1<<19)
508+
#define IR_GEN_CODE (1<<20) /* C or LLVM */
510509

511510
/* debug related */
512511
#ifdef IR_DEBUG
513-
# define IR_DEBUG_SCCP (1<<27)
514-
# define IR_DEBUG_GCM (1<<28)
515-
# define IR_DEBUG_SCHEDULE (1<<29)
516-
# define IR_DEBUG_RA (1<<30)
512+
# define IR_DEBUG_SCCP (1<<27)
513+
# define IR_DEBUG_GCM (1<<28)
514+
# define IR_DEBUG_SCHEDULE (1<<29)
515+
# define IR_DEBUG_RA (1<<30)
517516
#endif
518517

519518
typedef struct _ir_ctx ir_ctx;
@@ -627,9 +626,9 @@ ir_ref ir_const_char(ir_ctx *ctx, char c);
627626
ir_ref ir_const_float(ir_ctx *ctx, float c);
628627
ir_ref ir_const_double(ir_ctx *ctx, double c);
629628
ir_ref ir_const_addr(ir_ctx *ctx, uintptr_t c);
630-
ir_ref ir_const_func_addr(ir_ctx *ctx, uintptr_t c, uint16_t flags);
631629

632-
ir_ref ir_const_func(ir_ctx *ctx, ir_ref str, uint16_t flags);
630+
ir_ref ir_const_func_addr(ir_ctx *ctx, uintptr_t c, ir_ref proto);
631+
ir_ref ir_const_func(ir_ctx *ctx, ir_ref str, ir_ref proto);
633632
ir_ref ir_const_sym(ir_ctx *ctx, ir_ref str);
634633
ir_ref ir_const_str(ir_ctx *ctx, ir_ref str);
635634

@@ -640,6 +639,26 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted
640639
ir_ref ir_str(ir_ctx *ctx, const char *s);
641640
ir_ref ir_strl(ir_ctx *ctx, const char *s, size_t len);
642641
const char *ir_get_str(const ir_ctx *ctx, ir_ref idx);
642+
const char *ir_get_strl(const ir_ctx *ctx, ir_ref idx, size_t *len);
643+
644+
#define IR_MAX_PROTO_PARAMS 255
645+
646+
typedef struct _ir_proto_t {
647+
uint8_t flags;
648+
uint8_t ret_type;
649+
uint8_t params_count;
650+
uint8_t param_types[5];
651+
} ir_proto_t;
652+
653+
ir_ref ir_proto_0(ir_ctx *ctx, uint8_t flags, ir_type ret_type);
654+
ir_ref ir_proto_1(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1);
655+
ir_ref ir_proto_2(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2);
656+
ir_ref ir_proto_3(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3);
657+
ir_ref ir_proto_4(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3,
658+
ir_type t4);
659+
ir_ref ir_proto_5(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3,
660+
ir_type t4, ir_type t5);
661+
ir_ref ir_proto(ir_ctx *ctx, uint8_t flags, ir_type ret_type, uint32_t params_counts, uint8_t *param_types);
643662

644663
ir_ref ir_emit(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3);
645664

@@ -768,9 +787,9 @@ struct _ir_loader {
768787
bool (*init_module) (ir_loader *loader, const char *name, const char *filename, const char *target);
769788
bool (*external_sym_dcl) (ir_loader *loader, const char *name, uint32_t flags);
770789
bool (*external_func_dcl) (ir_loader *loader, const char *name,
771-
uint32_t flags, ir_type ret_type, uint32_t params_count, ir_type *param_types);
790+
uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types);
772791
bool (*forward_func_dcl) (ir_loader *loader, const char *name,
773-
uint32_t flags, ir_type ret_type, uint32_t params_count, ir_type *param_types);
792+
uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types);
774793
bool (*sym_dcl) (ir_loader *loader, const char *name, uint32_t flags, size_t size, bool has_data);
775794
bool (*sym_data) (ir_loader *loader, ir_type type, uint32_t count, const void *data);
776795
bool (*sym_data_ref) (ir_loader *loader, ir_op op, const char *ref);
@@ -789,6 +808,7 @@ int ir_load_llvm_bitcode(ir_loader *loader, const char *filename);
789808
int ir_load_llvm_asm(ir_loader *loader, const char *filename);
790809

791810
/* IR save API (implementation in ir_save.c) */
811+
void ir_print_proto(const ir_ctx *ctx, ir_ref proto, FILE *f);
792812
void ir_save(const ir_ctx *ctx, FILE *f);
793813

794814
/* IR debug dump API (implementation in ir_dump.c) */
@@ -802,11 +822,11 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f);
802822

803823
/* IR to C conversion (implementation in ir_emit_c.c) */
804824
int ir_emit_c(ir_ctx *ctx, const char *name, FILE *f);
805-
void ir_emit_c_func_decl(const char *name, uint32_t flags, ir_type ret_type, uint32_t params_count, ir_type *param_types, FILE *f);
825+
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);
806826

807827
/* IR to LLVM conversion (implementation in ir_emit_llvm.c) */
808828
int ir_emit_llvm(ir_ctx *ctx, const char *name, FILE *f);
809-
void ir_emit_llvm_func_decl(const char *name, uint32_t flags, ir_type ret_type, uint32_t params_count, ir_type *param_types, FILE *f);
829+
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);
810830

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

0 commit comments

Comments
 (0)