This commit is contained in:
Dmitry Stogov 2022-06-15 22:48:19 +03:00
parent ba6bb796a4
commit 3f6c1ee0f5
7 changed files with 31 additions and 47 deletions

36
ir.c
View File

@ -138,38 +138,20 @@ void ir_print_const(ir_ctx *ctx, ir_insn *insn, FILE *f)
#define ir_op_flag_r2 (ir_op_flag_r | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_r2 (ir_op_flag_r | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_r3 (ir_op_flag_r | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_r3 (ir_op_flag_r | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_c IR_OP_FLAG_CONTROL #define ir_op_flag_c IR_OP_FLAG_CONTROL
#define ir_op_flag_c0 ir_op_flag_c
#define ir_op_flag_c0X1 (ir_op_flag_c | 0 | (1 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_c0X2 (ir_op_flag_c | 0 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_c1 (ir_op_flag_c | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_c1X1 (ir_op_flag_c | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_c1X2 (ir_op_flag_c | 1 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_c2 (ir_op_flag_c | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_c2X1 (ir_op_flag_c | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_c3 (ir_op_flag_c | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_c3 (ir_op_flag_c | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_cN (ir_op_flag_c | 4 | (4 << IR_OP_FLAG_OPERANDS_SHIFT)) // MERGE (number of operands encoded in op1) #define ir_op_flag_S (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_START)
#define ir_op_flag_B (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_BEGIN) #define ir_op_flag_S0X2 (ir_op_flag_S | 0 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_B0 ir_op_flag_B #define ir_op_flag_S1 (ir_op_flag_S | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_B0X1 (ir_op_flag_B | 0 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_S1X1 (ir_op_flag_S | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_B0X2 (ir_op_flag_B | 0 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_S2 (ir_op_flag_S | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_B1 (ir_op_flag_B | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_S2X1 (ir_op_flag_S | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_B1X1 (ir_op_flag_B | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_SN (ir_op_flag_S | 4 | (4 << IR_OP_FLAG_OPERANDS_SHIFT)) // MERGE (number of operands encoded in op1)
#define ir_op_flag_B1X2 (ir_op_flag_B | 1 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_B2 (ir_op_flag_B | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_B2X1 (ir_op_flag_B | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_B3 (ir_op_flag_B | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_BN (ir_op_flag_B | 4 | (4 << IR_OP_FLAG_OPERANDS_SHIFT)) // MERGE (number of operands encoded in op1)
#define ir_op_flag_E (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_END) #define ir_op_flag_E (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_END)
#define ir_op_flag_E0 ir_op_flag_B
#define ir_op_flag_E0X1 (ir_op_flag_E | 0 | (1 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_E0X2 (ir_op_flag_E | 0 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_E1 (ir_op_flag_E | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_E1 (ir_op_flag_E | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_E1X1 (ir_op_flag_E | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_E1X1 (ir_op_flag_E | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_E1X2 (ir_op_flag_E | 1 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_E2 (ir_op_flag_E | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_E2 (ir_op_flag_E | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_E2X1 (ir_op_flag_E | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_T (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_END|IR_OP_FLAG_TERMINATOR)
#define ir_op_flag_E3 (ir_op_flag_E | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_T2X1 (ir_op_flag_T | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_EN (ir_op_flag_E | 4 | (4 << IR_OP_FLAG_OPERANDS_SHIFT)) // MERGE (number of operands encoded in op1)
#define ir_op_flag_l (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD) #define ir_op_flag_l (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)
#define ir_op_flag_l0 ir_op_flag_l #define ir_op_flag_l0 ir_op_flag_l
#define ir_op_flag_l1 (ir_op_flag_l | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_l1 (ir_op_flag_l | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT))

25
ir.h
View File

@ -97,8 +97,9 @@ typedef enum _ir_type {
* d - data IR_OP_FLAG_DATA * d - data IR_OP_FLAG_DATA
* r - ref IR_OP_FLAG_DATA alias * r - ref IR_OP_FLAG_DATA alias
* c - control IR_OP_FLAG_CONTROL * c - control IR_OP_FLAG_CONTROL
* B - control IR_OP_FLAG_CONTROL + IR_OP_FLAG_BB_BEGIN * S - control IR_OP_FLAG_CONTROL + IR_OP_FLAG_BB_START
* E - control IR_OP_FLAG_CONTROL + IR_OP_FLAG_BB_END * E - control IR_OP_FLAG_CONTROL + IR_OP_FLAG_BB_END
* T - control IR_OP_FLAG_CONTROL + IR_OP_FLAG_BB_END + IR_OP_FLAG_TERMINATOR
* l - load IR_OP_FLAG_MEM + IR_OP_FLAG_MEM_LOAD * l - load IR_OP_FLAG_MEM + IR_OP_FLAG_MEM_LOAD
* s - store IR_OP_FLAG_MEM + IR_OP_FLAG_STORE * s - store IR_OP_FLAG_MEM + IR_OP_FLAG_STORE
* x - call IR_OP_FLAG_MEM + IR_OP_FLAG_CALL * x - call IR_OP_FLAG_MEM + IR_OP_FLAG_CALL
@ -236,21 +237,21 @@ typedef enum _ir_type {
/* memory reference ops (A, H, U, S, TMP, STR, NEW, X, V) ??? */ \ /* memory reference ops (A, H, U, S, TMP, STR, NEW, X, V) ??? */ \
\ \
/* control-flow nodes */ \ /* control-flow nodes */ \
_(START, B0X2, ret, ent, ___) /* function start */ \ _(START, S0X2, ret, ent, ___) /* function start */ \
_(RETURN, E2X1, src, def, ret) /* function return */ \ _(RETURN, T2X1, src, def, ret) /* function return */ \
_(UNREACHABLE, E2X1, src, def, ret) /* unreachable (tailcall, etc) */ \ _(UNREACHABLE, T2X1, src, def, ret) /* unreachable (tailcall, etc) */ \
_(BEGIN, B1, src, ___, ___) /* block start */ \ _(BEGIN, S1, src, ___, ___) /* block start */ \
_(END, E1, src, ___, ___) /* block end */ \ _(END, E1, src, ___, ___) /* block end */ \
_(IF, E2, src, def, ___) /* conditional control split */ \ _(IF, E2, src, def, ___) /* conditional control split */ \
_(IF_TRUE, B1X1, src, prb, ___) /* IF TRUE proj. */ \ _(IF_TRUE, S1X1, src, prb, ___) /* IF TRUE proj. */ \
_(IF_FALSE, B1X1, src, prb, ___) /* IF FALSE proj. */ \ _(IF_FALSE, S1X1, src, prb, ___) /* IF FALSE proj. */ \
_(SWITCH, E2, src, def, ___) /* multi-way control split */ \ _(SWITCH, E2, src, def, ___) /* multi-way control split */ \
_(CASE_VAL, B2X1, src, def, prb) /* switch proj. */ \ _(CASE_VAL, S2X1, src, def, prb) /* switch proj. */ \
_(CASE_DEFAULT, B1X1, src, prb, ___) /* switch proj. */ \ _(CASE_DEFAULT, S1X1, src, prb, ___) /* switch proj. */ \
_(MERGE, BN, src, src, src) /* control merge */ \ _(MERGE, SN, src, src, src) /* control merge */ \
_(LOOP_BEGIN, B2, src, src, ___) /* loop start */ \ _(LOOP_BEGIN, S2, src, src, ___) /* loop start */ \
_(LOOP_END, E1X1, src, beg, ___) /* loop end */ \ _(LOOP_END, E1X1, src, beg, ___) /* loop end */ \
_(IJMP, E2X1, src, def, ret) /* computed goto */ \ _(IJMP, T2X1, src, def, ret) /* computed goto */ \
\ \
/* guards (floating or not) ??? */ \ /* guards (floating or not) ??? */ \
_(GUARD_TRUE, c3, src, def, def) /* IF without second successor */ \ _(GUARD_TRUE, c3, src, def, def) /* IF without second successor */ \

View File

@ -29,7 +29,7 @@ int ir_build_cfg(ir_ctx *ctx)
while (1) { while (1) {
insn = &ctx->ir_base[ref]; insn = &ctx->ir_base[ref];
_blocks[ref] = bb_count; _blocks[ref] = bb_count;
if (IR_IS_BB_BEGIN(insn->op)) { if (IR_IS_BB_START(insn->op)) {
ir_bitset_incl(worklist.visited, ref); ir_bitset_incl(worklist.visited, ref);
break; break;
} }
@ -62,7 +62,7 @@ int ir_build_cfg(ir_ctx *ctx)
_blocks[ref] = n; _blocks[ref] = n;
bb = &blocks[n]; bb = &blocks[n];
insn = &ctx->ir_base[ref]; insn = &ctx->ir_base[ref];
if (IR_IS_BB_BEGIN(insn->op)) { if (IR_IS_BB_START(insn->op)) {
bb->start = ref; bb->start = ref;
} else { } else {
bb->end = ref; bb->end = ref;

View File

@ -67,7 +67,7 @@ void ir_dump_dot(ir_ctx *ctx, FILE *f)
if (flags & IR_OP_FLAG_CONTROL) { if (flags & IR_OP_FLAG_CONTROL) {
if (insn->op == IR_START) { if (insn->op == IR_START) {
fprintf(f, "\t{rank=min; n%d [label=\"%d: %s\",shape=box,style=\"rounded,filled\",fillcolor=red,rank=min];}\n", i, i, ir_op_name[insn->op]); fprintf(f, "\t{rank=min; n%d [label=\"%d: %s\",shape=box,style=\"rounded,filled\",fillcolor=red,rank=min];}\n", i, i, ir_op_name[insn->op]);
} else if (insn->op == IR_RETURN || insn->op == IR_UNREACHABLE || insn->op == IR_IJMP) { } else if (flags & IR_OP_FLAG_TERMINATOR) {
fprintf(f, "\t{rank=max; n%d [label=\"%d: %s\",shape=box,style=\"rounded,filled\",fillcolor=red,rank=max];}\n", i, i, ir_op_name[insn->op]); fprintf(f, "\t{rank=max; n%d [label=\"%d: %s\",shape=box,style=\"rounded,filled\",fillcolor=red,rank=max];}\n", i, i, ir_op_name[insn->op]);
} else if (flags & IR_OP_FLAG_MEM) { } else if (flags & IR_OP_FLAG_MEM) {
fprintf(f, "\tn%d [label=\"%d: %s\",shape=box,style=filled,fillcolor=pink];\n", i, i, ir_op_name[insn->op]); fprintf(f, "\tn%d [label=\"%d: %s\",shape=box,style=filled,fillcolor=pink];\n", i, i, ir_op_name[insn->op]);

View File

@ -2,7 +2,7 @@
#define IR_PHP_H #define IR_PHP_H
#define IR_PHP_OPS(_) \ #define IR_PHP_OPS(_) \
_(PHP_ENTRY, B0X2, num, ent, ___) /* PHP Code Entry */ \ _(PHP_ENTRY, S0X2, num, ent, ___) /* PHP Code Entry */ \
#if defined(IR_TARGET_X86) #if defined(IR_TARGET_X86)
# define IR_REG_PHP_FP IR_REG_RSI # define IR_REG_PHP_FP IR_REG_RSI

View File

@ -544,8 +544,9 @@ extern const char *ir_op_name[IR_LAST_OP];
#define IR_OP_FLAG_CONTROL (1<<9) #define IR_OP_FLAG_CONTROL (1<<9)
#define IR_OP_FLAG_MEM (1<<10) #define IR_OP_FLAG_MEM (1<<10)
#define IR_OP_FLAG_COMMUTATIVE (1<<11) #define IR_OP_FLAG_COMMUTATIVE (1<<11)
#define IR_OP_FLAG_BB_BEGIN (1<<12) #define IR_OP_FLAG_BB_START (1<<12)
#define IR_OP_FLAG_BB_END (1<<13) #define IR_OP_FLAG_BB_END (1<<13)
#define IR_OP_FLAG_TERMINATOR (1<<14)
#define IR_OP_FLAG_MEM_LOAD ((0<<6)|(0<<7)) #define IR_OP_FLAG_MEM_LOAD ((0<<6)|(0<<7))
#define IR_OP_FLAG_MEM_STORE ((0<<6)|(1<<7)) #define IR_OP_FLAG_MEM_STORE ((0<<6)|(1<<7))
@ -618,8 +619,8 @@ struct _ir_use_list {
}; };
/*** IR Basic Blocks info ***/ /*** IR Basic Blocks info ***/
#define IR_IS_BB_BEGIN(op) \ #define IR_IS_BB_START(op) \
((ir_op_flags[op] & IR_OP_FLAG_BB_BEGIN) != 0) ((ir_op_flags[op] & IR_OP_FLAG_BB_START) != 0)
#define IR_IS_BB_MERGE(op) \ #define IR_IS_BB_MERGE(op) \
((op) == IR_MERGE || (op) == IR_LOOP_BEGIN) ((op) == IR_MERGE || (op) == IR_LOOP_BEGIN)

View File

@ -628,7 +628,7 @@ int ir_sccp(ir_ctx *ctx)
ir_sccp_replace_insn(ctx, _values, i, IR_UNUSED); ir_sccp_replace_insn(ctx, _values, i, IR_UNUSED);
} }
} else { } else {
if (insn->op == IR_RETURN || insn->op == IR_UNREACHABLE || insn->op == IR_IJMP) { if (ir_op_flags[insn->op] & IR_OP_FLAG_TERMINATOR) {
ir_ref ref = ctx->ir_base[1].op1; ir_ref ref = ctx->ir_base[1].op1;
if (ref == i) { if (ref == i) {
ctx->ir_base[1].op1 = insn->op3; ctx->ir_base[1].op1 = insn->op3;