/**
* Called immediatly before emit phase.
*/
-static void TEMPLATE_finish_irg(ir_graph *irg, TEMPLATE_code_gen_t *cg) {
- /* TODO: - fix offsets for nodes accessing stack
- - ...
- */
+static void TEMPLATE_finish_irg(void *self) {
+ TEMPLATE_code_gen_t *cg = self;
+ ir_graph *irg = cg->irg;
+
+ dump_ir_block_graph_sched(irg, "-TEMPLATE-finished");
}
cg->emit_decls = 0;
}
- TEMPLATE_finish_irg(irg, cg);
- dump_ir_block_graph_sched(irg, "-TEMPLATE-finished");
TEMPLATE_gen_routine(out, irg, cg);
cur_reg_set = NULL;
TEMPLATE_before_sched, /* before scheduling hook */
TEMPLATE_before_ra, /* before register allocation hook */
TEMPLATE_after_ra, /* after register allocation hook */
+ TEMPLATE_finish_irg,
TEMPLATE_emit_and_done
};
/**
* Called immediately before emit phase.
*/
-static void arm_finish_irg(ir_graph *irg, arm_code_gen_t *cg) {
+static void arm_finish_irg(void *self) {
/* TODO: - fix offsets for nodes accessing stack
- ...
*/
cg->emit_decls = 0;
}
- arm_finish_irg(irg, cg);
dump_ir_block_graph_sched(irg, "-arm-finished");
arm_gen_routine(out, irg, cg);
arm_before_sched, /* before scheduling hook */
arm_before_ra, /* before register allocation hook */
NULL, /* after register allocation */
+ arm_finish_irg,
arm_emit_and_done,
};
void (*after_ra)(void *self);
/**
- * Called after everything happened.
+ * Called directly before done is called. This should be the last place
+ * where the irg is modified.
+ */
+ void (*finish)(void *self);
+
+ /**
+ * Called after everything happened. This call should emit the final
+ * assembly code but avoid changing the irg.
* The code generator must also be de-allocated here.
*/
void (*done)(void *self);
#define arch_code_generator_before_sched(cg) _arch_cg_call(cg, before_sched)
#define arch_code_generator_before_ra(cg) _arch_cg_call(cg, before_ra)
#define arch_code_generator_after_ra(cg) _arch_cg_call(cg, after_ra)
+#define arch_code_generator_finish(cg) _arch_cg_call(cg, finish)
#define arch_code_generator_done(cg) _arch_cg_call(cg, done)
/**
free_execfreq(chordal_env.exec_freq);
BE_TIMER_POP(ra_timer.t_epilog);
-
- BE_TIMER_PUSH(ra_timer.t_verify);
-
- /* verify spillslots */
- if (options.vrfy_option == BE_CH_VRFY_WARN) {
- be_verify_schedule(irg);
- }
- else if (options.vrfy_option == BE_CH_VRFY_ASSERT) {
- assert(be_verify_schedule(irg) && "Schedule verification failed");
- }
- BE_TIMER_POP(ra_timer.t_verify);
-
BE_TIMER_POP(ra_timer.t_other);
#undef BE_TIMER_PUSH
be_abi_fix_stack_bias(birg.abi);
BE_TIMER_POP(t_abi);
+ BE_TIMER_PUSH(t_finish);
+ arch_code_generator_finish(birg.cg);
+ BE_TIMER_POP(t_finish);
+
/* check schedule */
BE_TIMER_PUSH(t_verify);
be_sched_vrfy(birg.irg, vrfy_option);
}
}
+/**
+ * Last touchups for the graph before emit
+ */
+static void ia32_finish(void *self) {
+ ia32_code_gen_t *cg = self;
+ ir_graph *irg = cg->irg;
+
+ ia32_finish_irg(irg, cg);
+ if (cg->dump)
+ be_dump(irg, "-finished", dump_ir_block_graph_sched);
+}
/**
* Emits the code, closes the output file and frees
ia32_code_gen_t *cg = self;
ir_graph *irg = cg->irg;
- ia32_finish_irg(irg, cg);
- if (cg->dump)
- be_dump(irg, "-finished", dump_ir_block_graph_sched);
ia32_gen_routine(cg->isa->out, irg, cg);
cur_reg_set = NULL;
/* de-allocate code generator */
del_set(cg->reg_set);
free(self);
-
}
static void *ia32_cg_init(const be_irg_t *birg);
ia32_before_sched, /* before scheduling hook */
ia32_before_ra, /* before register allocation hook */
ia32_after_ra, /* after register allocation hook */
+ ia32_finish, /* called before codegen */
ia32_codegen /* emit && done */
};
/**
* Called immediately before emit phase.
*/
-static void mips_finish_irg(ir_graph *irg, mips_code_gen_t *cg) {
- /* TODO: - fix offsets for nodes accessing stack
- - ...
- */
+static void mips_finish_irg(void *self) {
+ mips_code_gen_t *cg = self;
+ ir_graph *irg = cg->irg;
+
+ dump_ir_block_graph_sched(irg, "-mips-finished");
}
cg->emit_decls = 0;
}
- mips_finish_irg(irg, cg);
- dump_ir_block_graph_sched(irg, "-mips-finished");
mips_gen_routine(out, irg, cg);
cur_reg_set = NULL;
mips_before_sched, /* before scheduling hook */
mips_before_ra, /* before register allocation hook */
mips_after_ra,
+ mips_finish_irg,
mips_emit_and_done
};
/**
* Called immediatly before emit phase.
*/
-static void ppc32_finish_irg(ir_graph *irg, ppc32_code_gen_t *cg) {
+static void ppc32_finish_irg(void *self) {
/* TODO: - fix offsets for nodes accessing stack
- ...
*/
cg->emit_decls = 0;
}
- ppc32_finish_irg(irg, cg);
dump_ir_block_graph_sched(irg, "-ppc-finished");
ppc32_gen_routine(out, irg, cg);
ppc32_before_sched, /* before scheduling hook */
ppc32_before_ra, /* before register allocation hook */
ppc32_after_ra,
+ ppc32_finish_irg,
ppc32_emit_and_done
};