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_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_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_cN (ir_op_flag_c | 4 | (4 << IR_OP_FLAG_OPERANDS_SHIFT)) // MERGE (number of operands encoded in op1)
#define ir_op_flag_B (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_BEGIN)
#define ir_op_flag_B0 ir_op_flag_B
#define ir_op_flag_B0X1 (ir_op_flag_B | 0 | (1 << 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_B1 (ir_op_flag_B | 1 | (1 << 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_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_S (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_START)
#define ir_op_flag_S0X2 (ir_op_flag_S | 0 | (2 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_S1 (ir_op_flag_S | 1 | (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_S2 (ir_op_flag_S | 2 | (2 << 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_SN (ir_op_flag_S | 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_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_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_E2X1 (ir_op_flag_E | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#define ir_op_flag_E3 (ir_op_flag_E | 3 | (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_T (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_END|IR_OP_FLAG_TERMINATOR)
#define ir_op_flag_T2X1 (ir_op_flag_T | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT))
#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_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
* r - ref IR_OP_FLAG_DATA alias
* 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
* 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
* s - store IR_OP_FLAG_MEM + IR_OP_FLAG_STORE
* 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) ??? */ \
\
/* control-flow nodes */ \
_(START, B0X2, ret, ent, ___) /* function start */ \
_(RETURN, E2X1, src, def, ret) /* function return */ \
_(UNREACHABLE, E2X1, src, def, ret) /* unreachable (tailcall, etc) */ \
_(BEGIN, B1, src, ___, ___) /* block start */ \
_(START, S0X2, ret, ent, ___) /* function start */ \
_(RETURN, T2X1, src, def, ret) /* function return */ \
_(UNREACHABLE, T2X1, src, def, ret) /* unreachable (tailcall, etc) */ \
_(BEGIN, S1, src, ___, ___) /* block start */ \
_(END, E1, src, ___, ___) /* block end */ \
_(IF, E2, src, def, ___) /* conditional control split */ \
_(IF_TRUE, B1X1, src, prb, ___) /* IF TRUE proj. */ \
_(IF_FALSE, B1X1, src, prb, ___) /* IF FALSE proj. */ \
_(IF_TRUE, S1X1, src, prb, ___) /* IF TRUE proj. */ \
_(IF_FALSE, S1X1, src, prb, ___) /* IF FALSE proj. */ \
_(SWITCH, E2, src, def, ___) /* multi-way control split */ \
_(CASE_VAL, B2X1, src, def, prb) /* switch proj. */ \
_(CASE_DEFAULT, B1X1, src, prb, ___) /* switch proj. */ \
_(MERGE, BN, src, src, src) /* control merge */ \
_(LOOP_BEGIN, B2, src, src, ___) /* loop start */ \
_(CASE_VAL, S2X1, src, def, prb) /* switch proj. */ \
_(CASE_DEFAULT, S1X1, src, prb, ___) /* switch proj. */ \
_(MERGE, SN, src, src, src) /* control merge */ \
_(LOOP_BEGIN, S2, src, src, ___) /* loop start */ \
_(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) ??? */ \
_(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) {
insn = &ctx->ir_base[ref];
_blocks[ref] = bb_count;
if (IR_IS_BB_BEGIN(insn->op)) {
if (IR_IS_BB_START(insn->op)) {
ir_bitset_incl(worklist.visited, ref);
break;
}
@ -62,7 +62,7 @@ int ir_build_cfg(ir_ctx *ctx)
_blocks[ref] = n;
bb = &blocks[n];
insn = &ctx->ir_base[ref];
if (IR_IS_BB_BEGIN(insn->op)) {
if (IR_IS_BB_START(insn->op)) {
bb->start = ref;
} else {
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 (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]);
} 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]);
} 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]);

View File

@ -2,7 +2,7 @@
#define IR_PHP_H
#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)
# 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_MEM (1<<10)
#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_TERMINATOR (1<<14)
#define IR_OP_FLAG_MEM_LOAD ((0<<6)|(0<<7))
#define IR_OP_FLAG_MEM_STORE ((0<<6)|(1<<7))
@ -618,8 +619,8 @@ struct _ir_use_list {
};
/*** IR Basic Blocks info ***/
#define IR_IS_BB_BEGIN(op) \
((ir_op_flags[op] & IR_OP_FLAG_BB_BEGIN) != 0)
#define IR_IS_BB_START(op) \
((ir_op_flags[op] & IR_OP_FLAG_BB_START) != 0)
#define IR_IS_BB_MERGE(op) \
((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);
}
} 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;
if (ref == i) {
ctx->ir_base[1].op1 = insn->op3;