23 for (i =
IR_UNUSED + 1, insn = ctx->
ir_base + i; i < ctx->insns_count; i++, insn++) {
30 for (
j = 1,
p = insn->ops + 1;
j <= 3;
j++,
p++) {
42 for (
j = 0;
j < 4;
j++,
p++) {
58 int CONTROL_WEIGHT = 5;
70 fprintf(f,
")\",style=filled,fillcolor=yellow];\n");
76 if (insn->op == IR_START) {
77 fprintf(f,
"\t{rank=min; n%d [label=\"%d: %s\",shape=box,style=\"rounded,filled\",fillcolor=red];}\n", i, i,
ir_op_name[insn->op]);
78 }
else if (insn->op == IR_ENTRY) {
79 fprintf(f,
"\t{n%d [label=\"%d: %s\",shape=box,style=\"rounded,filled\",fillcolor=red];}\n", i, i,
ir_op_name[insn->op]);
81 fprintf(f,
"\t{rank=max; n%d [label=\"%d: %s\",shape=box,style=\"rounded,filled\",fillcolor=red];}\n", i, i,
ir_op_name[insn->op]);
83 fprintf(f,
"\tn%d [label=\"%d: %s\",shape=box,style=filled,fillcolor=pink];\n", i, i,
ir_op_name[insn->op]);
85 fprintf(f,
"\tn%d [label=\"%d: %s\",shape=box,style=filled,fillcolor=lightcoral];\n", i, i,
ir_op_name[insn->op]);
91 fprintf(f,
",shape=diamond,style=filled,fillcolor=deepskyblue];\n");
93 if (insn->op == IR_PARAM) {
94 fprintf(f,
"\tn%d [label=\"%d: %s %s \\\"%s\\\"\",style=filled,fillcolor=lightblue];\n",
96 }
else if (insn->op == IR_VAR) {
104 for (
j = 1,
p = insn->ops + 1;
j <=
n;
j++,
p++) {
110 fprintf(f,
"\tc%d -> n%d [color=blue,weight=%d];\n", -ref, i, DATA_WEIGHT);
111 }
else if (insn->op == IR_PHI
112 && ctx->
ir_base[insn->op1].op == IR_LOOP_BEGIN
114 fprintf(f,
"\tn%d -> n%d [color=blue,dir=back];\n", i, ref);
116 fprintf(f,
"\tn%d -> n%d [color=blue,weight=%d];\n", ref, i, DATA_WEIGHT);
120 if (insn->op == IR_LOOP_BEGIN && ctx->
ir_base[ref].op == IR_LOOP_END) {
121 fprintf(f,
"\tn%d -> n%d [style=bold,color=red,dir=back];\n", i, ref);
122 }
else if (insn->op == IR_ENTRY) {
123 fprintf(f,
"\tn%d -> n%d [style=bold,color=red,style=dashed,weight=%d];\n", ref, i, CONTROL_WEIGHT);
125 fprintf(f,
"\tn%d -> n%d [style=bold,color=red,weight=%d];\n", ref, i, CONTROL_WEIGHT);
130 fprintf(f,
"\tn%d -> n%d [style=dashed,dir=back,weight=%d];\n", ref, i, REF_WEIGHT);
149 for (i = 1, list = &ctx->
use_lists[1]; i < ctx->insns_count; i++, list++) {
155 for (
j = 1;
j <
n;
j++,
p++) {
165static void ir_dump_dessa_moves(
const ir_ctx *ctx,
int b,
ir_block *bb, FILE *f)
170 ir_ref k, i, *
p, use_ref, input;
182 use_insn = &ctx->
ir_base[use_ref];
183 if (use_insn->op == IR_PHI) {
186 fprintf(f,
"\t# DESSA MOV c_%d", -input);
187 }
else if (ctx->
vregs[input] != ctx->
vregs[use_ref]) {
188 fprintf(f,
"\t# DESSA MOV d_%d {R%d}", input, ctx->
vregs[input]);
193 int8_t *regs = ctx->
regs[use_ref];
194 int8_t reg = regs[k];
200 fprintf(f,
" -> d_%d {R%d}", use_ref, ctx->
vregs[use_ref]);
202 int8_t reg = ctx->
regs[use_ref][0];
213static void ir_dump_cfg_block(
ir_ctx *ctx, FILE *f, uint32_t b,
ir_block *bb)
242 fprintf(f,
"\tdom_children [BB%d", child);
258 fprintf(f,
"\tLOOP_HEADER, LOOP_WITH_ENTRY\n");
264 fprintf(stderr,
"\tIRREDUCIBLE_LOOP\n");
291 for (i = 0; i <
count; i++,
pos++) {
293 fprintf(f,
"\tOSR_ENTRY_LOAD=d_%d\n", ref);
297 ir_dump_dessa_moves(ctx, b, bb, f);
309 for (i = 1; i <= bb_count; i++) {
312 ir_dump_cfg_block(ctx, f, b, bb);
315 for (b = 1; b <= bb_count; b++, bb++) {
316 ir_dump_cfg_block(ctx, f, b, bb);
326 uint32_t *_blocks = ctx->
cfg_map;
329 fprintf(f,
"{ # CFG map (insn -> bb)\n");
331 fprintf(f,
"%d -> %d\n", i, _blocks[i]);
356 if (ctx->
vregs[
j] == (uint32_t)i) {
362 if (ctx->
vregs[
j] == (uint32_t)i) {
409 fprintf(f,
", PHI_USE(%d.%d, phi=d_%d/%d)",
413 fprintf(f,
", USE(%d.%d/%d.%d",
416 if (use_pos->
hint >= 0) {
432 if (use_pos->
hint >= 0) {
443 use_pos = use_pos->
next;
460 fprintf(f,
"[%%%s] : [%d.%d-%d.%d)",
482 uint32_t
flags, _b, b;
487 for (i =
IR_UNUSED + 1, insn = ctx->
ir_base - i; i < ctx->consts_count; i++, insn--) {
489 if (insn->op == IR_FUNC) {
492 }
else if (insn->op == IR_SYM) {
494 }
else if (insn->op == IR_FUNC_ADDR) {
566 int8_t reg = ctx->
regs[i][0];
582 int8_t reg = ctx->
regs[i][0];
593 if ((insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN) &&
n != 2) {
595 }
else if ((insn->op == IR_CALL || insn->op == IR_TAILCALL) &&
n != 2) {
597 }
else if (insn->op == IR_PHI &&
n != 3) {
599 }
else if (insn->op == IR_SNAPSHOT) {
603 for (
j = 1,
p = insn->ops + 1;
j <=
n;
j++,
p++) {
611 fprintf(f,
"%sc_%d", first ?
"(" :
", ", -ref);
613 fprintf(f,
"%sd_%d", first ?
"(" :
", ", ref);
615 if (ctx->
vregs && ref > 0 && ctx->
vregs[ref]) {
619 int8_t *regs = ctx->
regs[i];
620 int8_t reg = regs[
j];
631 fprintf(f,
"%sl_%d", first ?
"(" :
", ", ref);
639 fprintf(f,
"%sfunc ", first ?
"(" :
", ");
648 fprintf(f,
"%s%d", first ?
"(" :
", ", ref);
653 fprintf(f,
"%s%d", first ?
"(" :
", ", ref);
657 fprintf(f,
"%snull", first ?
"(" :
", ");
670 fprintf(f,
" # BIND(0x%x);", -var);
674 uint32_t rule = ctx->
rules[i];
701 ir_dump_dessa_moves(ctx, b, bb, f);
705 if (insn->op == IR_END || insn->op == IR_LOOP_END) {
726 fprintf(f,
"\t# GOTO BB%d\n", succ);
730 fprintf(f,
"\t# GOTO BB%d\n", succ);
733 }
else if (insn->op == IR_IF) {
734 uint32_t true_block, false_block;
737 fprintf(f,
"\t# IF_TRUE BB%d, IF_FALSE BB%d\n", true_block, false_block);
738 }
else if (insn->op == IR_SWITCH) {
739 fprintf(f,
"\t# SWITCH ...\n");
fprintf($stream, string $format, mixed ... $values)
count(Countable|array $value, int $mode=COUNT_NORMAL)
ir_ref ir_binding_find(const ir_ctx *ctx, ir_ref ref)
const char * ir_type_name[IR_LAST_TYPE]
const char * ir_type_cname[IR_LAST_TYPE]
const char * ir_get_str(const ir_ctx *ctx, ir_ref idx)
const uint32_t ir_op_flags[IR_LAST_OP]
void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted)
const char * ir_op_name[IR_LAST_OP]
struct _ir_live_range ir_live_range
struct _ir_live_interval ir_live_interval
#define IR_REG_SPILL_STORE
void ir_print_proto(const ir_ctx *ctx, ir_ref proto, FILE *f)
IR_ALWAYS_INLINE ir_ref ir_insn_op(const ir_insn *insn, int32_t n)
#define IR_IS_CONST_REF(ref)
#define IR_REG_SPILL_LOAD
const char * ir_reg_name(int8_t reg, ir_type type)
#define IR_REG_SPILL_SPECIAL
struct _ir_use_list ir_use_list
struct _ir_block ir_block
uint32_t ir_skip_empty_target_blocks(const ir_ctx *ctx, uint32_t b)
void ir_get_true_false_blocks(const ir_ctx *ctx, uint32_t b, uint32_t *true_block, uint32_t *false_block)
void ir_dump_dot(const ir_ctx *ctx, const char *name, FILE *f)
void ir_dump_live_ranges(const ir_ctx *ctx, FILE *f)
void ir_dump_cfg(ir_ctx *ctx, FILE *f)
void ir_dump_use_lists(const ir_ctx *ctx, FILE *f)
void ir_dump(const ir_ctx *ctx, FILE *f)
void ir_dump_codegen(const ir_ctx *ctx, FILE *f)
void ir_dump_cfg_map(const ir_ctx *ctx, FILE *f)
#define IR_OPND_CONTROL_REF
#define IR_LIVE_POS_TO_SUB_REF(pos)
IR_ALWAYS_INLINE uint32_t ir_phi_input_number(const ir_ctx *ctx, const ir_block *bb, uint32_t from)
#define IR_OPND_CONTROL_DEP
#define IR_BB_DESSA_MOVES
const char * ir_rule_name[]
IR_ALWAYS_INLINE ir_ref ir_operands_count(const ir_ctx *ctx, const ir_insn *insn)
#define IR_USE_MUST_BE_IN_REG
#define IR_BB_IRREDUCIBLE_LOOP
#define IR_BB_LOOP_WITH_ENTRY
IR_ALWAYS_INLINE ir_ref ir_list_at(const ir_list *l, uint32_t i)
#define IR_LIVE_INTERVAL_SPILL_SPECIAL
#define IR_OPND_KIND(flags, i)
#define IR_BB_OSR_ENTRY_LOADS
#define IR_BB_UNREACHABLE
IR_ALWAYS_INLINE uint32_t ir_insn_inputs_to_len(uint32_t inputs_count)
#define IR_OP_FLAG_CONTROL
struct _ir_use_pos ir_use_pos
#define IR_LIVE_POS_TO_REF(pos)
#define IR_BB_LOOP_HEADER
#define IR_IS_REF_OPND_KIND(kind)
#define IR_OP_FLAG_TERMINATOR
unsigned const char * end
unsigned const char * pos
uint32_t successors_count
uint32_t predecessors_count
ir_live_interval ** live_intervals
uint32_t cfg_blocks_count