+ if (! is_pseudo_ir_graph(cg->irg)) {
+ irg_walk_blkwise_graph(cg->irg, ia32_place_consts, ia32_transform_node, cg);
+ dump_ir_block_graph_sched(cg->irg, "-transformed");
+ irg_walk_blkwise_graph(cg->irg, NULL, ia32_optimize_am, cg);
+ dump_ir_block_graph_sched(cg->irg, "-am");
+ }
+}
+
+
+
+/**
+ * Stack reservation and StackParam lowering.
+ */
+static void ia32_finish_irg(ir_graph *irg, ia32_code_gen_t *cg) {
+#if 0
+ firm_dbg_module_t *mod = cg->mod;
+ ir_node *frame = get_irg_frame(irg);
+ ir_node *end_block = get_irg_end_block(irg);
+ ir_node **returns, **in, **new_in;
+ ir_node *stack_reserve, *sched_point;
+ ir_node *stack_free, *new_ret, *return_block;
+ int stack_size = 0, i, n_arg;
+ arch_register_t *stack_reg;
+ tarval *stack_size_tv;
+ dbg_info *frame_dbg;
+
+ /* Determine stack register */
+ if (cg->has_alloca) {
+ stack_reg = &ia32_gp_regs[REG_EBP];
+ }
+ else {
+ stack_reg = &ia32_gp_regs[REG_ESP];
+ }
+
+ /* If frame is used, then we need to reserve some stackspace. */
+ if (get_irn_n_edges(frame) > 0) {
+ /* The initial stack reservation. */
+ stack_size = get_type_size_bytes(get_irg_frame_type(irg));
+ frame_dbg = get_irn_dbg_info(frame);
+ stack_reserve = new_rd_ia32_Sub_i(frame_dbg, irg, get_nodes_block(frame), new_NoMem(), mode_Is);
+ stack_size_tv = new_tarval_from_long(stack_size, mode_Is);
+ set_ia32_Immop_tarval(stack_reserve, stack_size_tv);
+
+ assert(stack_size && "bOrken stack layout");
+
+ /* reroute all edges from frame pointer to corrected frame pointer */
+ edges_reroute(frame, stack_reserve, irg);
+ set_irn_n(stack_reserve, 0, frame);
+
+ /* schedule frame pointer */
+ if (! sched_is_scheduled(frame)) {
+ sched_add_after(get_irg_start(irg), frame);
+ }
+
+ /* set register */
+ arch_set_irn_register(cg->arch_env, frame, stack_reg);
+ arch_set_irn_register(cg->arch_env, stack_reserve, stack_reg);
+
+ /* insert into schedule */
+ sched_add_after(frame, stack_reserve);
+
+ /* Free stack for each Return node */
+ returns = get_Block_cfgpred_arr(end_block);
+ for (i = 0; i < get_Block_n_cfgpreds(end_block); i++) {
+ assert(get_irn_opcode(returns[i]) == iro_Return && "cfgpred of endblock is not a return");
+
+ return_block = get_nodes_block(returns[i]);
+
+ /* free the stack */
+ stack_free = new_rd_ia32_Add_i(frame_dbg, irg, return_block, stack_reserve, mode_Is);
+ set_ia32_Immop_tarval(stack_free, stack_size_tv);
+ arch_set_irn_register(cg->arch_env, stack_free, stack_reg);
+
+ DBG((mod, LEVEL_1, "examining %+F, %+F created, block %+F", returns[i], stack_free, return_block));
+
+ /* get the old Return arguments */
+ n_arg = get_Return_n_ress(returns[i]);
+ in = get_Return_res_arr(returns[i]);
+ new_in = alloca((n_arg + 2) * sizeof(new_in[0]));
+
+ /* copy the old to the new in's */
+ memcpy(new_in, in, n_arg * sizeof(in[0]));
+ new_in[n_arg++] = stack_free;
+ new_in[n_arg++] = get_Return_mem(returns[i]);
+
+ /* create the new return node */
+ new_ret = new_rd_ia32_Return(get_irn_dbg_info(returns[i]), irg, return_block, n_arg, new_in);
+
+ /* In case the return node is the only node in the block, */
+ /* it is not scheduled, so we need this work-around. */
+ if (! sched_is_scheduled(returns[i])) {
+ sched_point = return_block;
+ }
+ else {
+ sched_point = sched_prev(returns[i]);
+ sched_remove(returns[i]);
+ }
+
+ /* exchange the old return with the new one */
+ exchange(returns[i], new_ret);
+
+ DB((mod, LEVEL_1, " ... replaced with %+F\n", new_ret));
+
+ /* remove the old one from schedule and add the new nodes properly */
+ sched_add_after(sched_point, new_ret);
+ sched_add_after(sched_point, stack_free);
+ }
+ }
+#endif