#include "mcg.h" struct procedure* current_proc; static void print_blocks(char k) { int i; tracef(k, "%c: procedure %s\n", k, current_proc->name); for (i=0; iblocks.count; i++) { struct basicblock* bb = current_proc->blocks.item[i]; int j; tracef(k, "%c:\n", k); tracef(k, "%c: %sBLOCK: %s\n", k, bb->is_fake ? "FAKE " : "", bb->name); if (bb->prevs.count > 0) { tracef(k, "%c: FROM:", k); for (j=0; jprevs.count; j++) tracef(k, " %s", bb->prevs.item[j]->name); tracef(k, "\n"); } if (bb->nexts.count > 0) { tracef(k, "%c: TO:", k); for (j=0; jnexts.count; j++) tracef(k, " %s", bb->nexts.item[j]->name); tracef(k, "\n"); } for (j=0; jirs.count; j++) ir_print(k, bb->irs.item[j]); } } static void print_vreg(char k, register_assignment_t* assignments, struct vreg* vreg) { struct hreg* hreg; tracef(k, "%%%d", vreg->id); if (assignments) { hreg = pmap_findright(assignments, vreg); if (hreg) tracef(k, "(%s)", hreg->id); } } static void print_hops(char k) { int i; tracef(k, "%c: procedure %s\n", k, current_proc->name); for (i=0; iis_fake ? "FAKE " : "", bb->name); if (bb->prevs.count > 0) { tracef(k, "%c: FROM:", k); for (j=0; jprevs.count; j++) tracef(k, " %s", bb->prevs.item[j]->name); tracef(k, "\n"); } if (bb->nexts.count > 0) { tracef(k, "%c: TO:", k); for (j=0; jnexts.count; j++) tracef(k, " %s", bb->nexts.item[j]->name); tracef(k, "\n"); } if (bb->liveins.count > 0) { tracef(k, "%c: INS:", k); for (j=0; jliveins.count; j++) { tracef(k, " "); print_vreg(k, &bb->regsin, bb->liveins.item[j]); } tracef(k, "\n"); } if (bb->liveouts.count > 0) { tracef(k, "%c: OUTS:", k); for (j=0; jliveouts.count; j++) { tracef(k, " "); print_vreg(k, bb->regsout, bb->liveouts.item[j]); } tracef(k, "\n"); } if (bb->phis.count > 0) { tracef(k, "%c: PHIS:", k); for (j=0; jphis.count; j++) { struct vreg* vreg = bb->phis.item[j].left; struct phi* phi = bb->phis.item[j].right; tracef(k, " %%%d(via %s)=>", phi->ir->result->id, phi->prev->name); print_vreg(k, &bb->regsin, vreg); } tracef(k, "\n"); } for (j=0; jhops.count; j++) hop_print(k, bb->hops.item[j]); } } static void emit_procedure(struct procedure* proc) { int i, j; fprintf(outputfile, "\n.sect .text\n"); for (i=0; iname)); for (j=0; jhops.count; j++) { struct hop* hop = bb->hops.item[j]; fprintf(outputfile, "%s", hop_render(hop)); } } } static void write_cfg_graph(const char* name) { int i; fprintf(cfg_dot_file, "subgraph \"%s\" {\n", name); fprintf(cfg_dot_file, "\t\"%s\" [color=red];\n", cfg.entry->name); for (i=0; i \"%s\";\n", cfg.graph.item[i].left->name, cfg.graph.item[i].right->name); } fprintf(cfg_dot_file, "}\n"); } static void write_dominance_graph(const char* name) { int i; fprintf(dominance_dot_file, "subgraph \"%s\" {\n", name); fprintf(dominance_dot_file, "\t\"%s\" [color=green];\n", cfg.entry->name); for (i=0; i \"%s\";\n", dominance.graph.item[i].right->name, dominance.graph.item[i].left->name); } fprintf(dominance_dot_file, "}\n"); } void procedure_compile(struct procedure* proc) { current_proc = proc; pass_group_irs(); print_blocks('1'); /* Passes from here on must preserve IR grouping */ pass_eliminate_trivial_blocks(); pass_remove_dead_blocks(); print_blocks('2'); update_graph_data(); pass_split_critical_edges(); update_graph_data(); /* Passes from here on can't alter the BB graph without also updating prevs * and nexts (and then calling update_graph_data()). */ print_blocks('3'); pass_wire_up_return_values(); pass_convert_stack_ops(); #if defined MCGG_OPTION_LOWER_PUSHES_TO_LOADS_AND_STORES pass_lower_pushes(); #endif print_blocks('4'); pass_convert_locals_to_ssa(); print_blocks('5'); pass_remove_dead_phis(); pass_infer_types(); print_blocks('6'); pass_instruction_selector(); print_hops('7'); pass_find_phi_congruence_groups(); pass_live_vreg_analysis(); print_hops('8'); pass_register_allocator(); pass_add_prologue_epilogue(); print_hops('9'); emit_procedure(proc); if (cfg_dot_file) write_cfg_graph(proc->name); if (dominance_dot_file) write_dominance_graph(proc->name); } /* vim: set sw=4 ts=4 expandtab : */