X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ir.c;h=8e92d4da6b368c9f2577146562b8f88c2b8a4018;hb=50f00fb0a75533c467461590c405c20360df0747;hp=4197620a5c2723f415f43ae8a34899283d6d406a;hpb=8035563a459e1e9fd36d6d70306902ca6866173a;p=xonotic%2Fgmqcc.git diff --git a/ir.c b/ir.c index 4197620..8e92d4d 100644 --- a/ir.c +++ b/ir.c @@ -1467,3 +1467,190 @@ on_error: MEM_VECTOR_CLEAR(&new_reads, v); return false; } + +/*********************************************************************** + *IR DEBUG Dump functions... + */ + +#define IND_BUFSZ 1024 + +const char *qc_opname(int op) +{ + if (op < 0) return ""; + if (op < ( sizeof(asm_instr) / sizeof(asm_instr[0]) )) + return asm_instr[op].m; + switch (op) { + case VINSTR_PHI: return "PHI"; + case VINSTR_JUMP: return "JUMP"; + case VINSTR_COND: return "COND"; + default: return ""; + } +} + +void ir_builder_dump(ir_builder *b, int (*oprintf)(const char*, ...)) +{ + size_t i; + char indent[IND_BUFSZ]; + indent[0] = '\t'; + indent[1] = 0; + + oprintf("module %s\n", b->name); + for (i = 0; i < b->globals_count; ++i) + { + oprintf("global "); + if (b->globals[i]->isconst) + oprintf("%s = ", b->globals[i]->name); + ir_value_dump(b->globals[i], oprintf); + oprintf("\n"); + } + for (i = 0; i < b->functions_count; ++i) + ir_function_dump(b->functions[i], indent, oprintf); + oprintf("endmodule %s\n", b->name); +} + +void ir_function_dump(ir_function *f, char *ind, + int (*oprintf)(const char*, ...)) +{ + size_t i; + oprintf("%sfunction %s\n", ind, f->name); + strncat(ind, "\t", IND_BUFSZ); + if (f->locals_count) + { + oprintf("%s%i locals:\n", ind, (int)f->locals_count); + for (i = 0; i < f->locals_count; ++i) { + oprintf("%s\t", ind); + ir_value_dump(f->locals[i], oprintf); + oprintf("\n"); + } + } + if (f->blocks_count) + { + + oprintf("%slife passes: %i\n", ind, (int)f->blocks[0]->run_id); + for (i = 0; i < f->blocks_count; ++i) + ir_block_dump(f->blocks[i], ind, oprintf); + + } + ind[strlen(ind)-1] = 0; + oprintf("%sendfunction %s\n", ind, f->name); +} + +void ir_block_dump(ir_block* b, char *ind, + int (*oprintf)(const char*, ...)) +{ + size_t i; + oprintf("%s:%s\n", ind, b->label); + strncat(ind, "\t", IND_BUFSZ); + + for (i = 0; i < b->instr_count; ++i) + ir_instr_dump(b->instr[i], ind, oprintf); + ind[strlen(ind)-1] = 0; +} + +void dump_phi(ir_instr *in, char *ind, + int (*oprintf)(const char*, ...)) +{ + size_t i; + oprintf("%s <- phi ", in->_ops[0]->name); + for (i = 0; i < in->phi_count; ++i) + { + oprintf("([%s] : %s) ", in->phi[i].from->label, + in->phi[i].value->name); + } + oprintf("\n"); +} + +void ir_instr_dump(ir_instr *in, char *ind, + int (*oprintf)(const char*, ...)) +{ + size_t i; + const char *comma = NULL; + + oprintf("%s (%i) ", ind, (int)in->eid); + + if (in->opcode == VINSTR_PHI) { + dump_phi(in, ind, oprintf); + return; + } + + strncat(ind, "\t", IND_BUFSZ); + + if (in->_ops[0] && (in->_ops[1] || in->_ops[2])) { + ir_value_dump(in->_ops[0], oprintf); + if (in->_ops[1] || in->_ops[2]) + oprintf(" <- "); + } + oprintf("%s\t", qc_opname(in->opcode)); + if (in->_ops[0] && !(in->_ops[1] || in->_ops[2])) { + ir_value_dump(in->_ops[0], oprintf); + comma = ",\t"; + } + else + { + for (i = 1; i != 3; ++i) { + if (in->_ops[i]) { + if (comma) + oprintf(comma); + ir_value_dump(in->_ops[i], oprintf); + comma = ",\t"; + } + } + } + if (in->bops[0]) { + if (comma) + oprintf(comma); + oprintf("[%s]", in->bops[0]->label); + comma = ",\t"; + } + if (in->bops[1]) + oprintf("%s[%s]", comma, in->bops[1]->label); + oprintf("\n"); + ind[strlen(ind)-1] = 0; +} + +void ir_value_dump(ir_value* v, int (*oprintf)(const char*, ...)) +{ + if (v->isconst) { + switch (v->vtype) { + case TYPE_VOID: + oprintf("(void)"); + break; + case TYPE_FLOAT: + oprintf("%g", v->constval.vfloat); + break; + case TYPE_VECTOR: + oprintf("'%g %g %g'", + v->constval.vvec.x, + v->constval.vvec.y, + v->constval.vvec.z); + break; + case TYPE_ENTITY: + oprintf("(entity)"); + break; + case TYPE_STRING: + oprintf("\"%s\"", v->constval.vstring); + break; +#if 0 + case TYPE_INTEGER: + oprintf("%i", v->constval.vint); + break; +#endif + case TYPE_POINTER: + oprintf("&%s", + v->constval.vpointer->name); + break; + } + } else { + oprintf("%s", v->name); + } +} + +void ir_value_dump_life(ir_value *self, int (*oprintf)(const char*,...)) +{ + size_t i; + oprintf("Life of %s:\n", self->name); + for (i = 0; i < self->life_count; ++i) + { + oprintf(" + [%i, %i]\n", self->life[i].start, self->life[i].end); + } +}