#include "ircons.h"
#include "irgwalk.h"
#include "heights.h"
-
+#include "beirg.h"
#include "bepeephole.h"
#include "benode.h"
#include "besched.h"
static void introduce_epilog(ir_node *ret)
{
- const arch_register_t *sp_reg = &sparc_registers[REG_SP];
- ir_graph *irg = get_irn_irg(ret);
- be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
- ir_node *block = get_nodes_block(ret);
- ir_type *frame_type = get_irg_frame_type(irg);
- unsigned frame_size = get_type_size_bytes(frame_type);
- int sp_idx = be_find_return_reg_input(ret, sp_reg);
- ir_node *sp = get_irn_n(ret, sp_idx);
+ arch_register_t const *const sp_reg = &sparc_registers[REG_SP];
+ assert(arch_get_irn_register_req_in(ret, n_sparc_Return_sp) == sp_reg->single_req);
+ ir_node *const sp = get_irn_n(ret, n_sparc_Return_sp);
+ ir_node *const block = get_nodes_block(ret);
+ ir_graph *const irg = get_irn_irg(ret);
+ be_stack_layout_t *const layout = be_get_irg_stack_layout(irg);
if (!layout->sp_relative) {
- const arch_register_t *fp_reg = &sparc_registers[REG_FRAME_POINTER];
- const arch_register_t *sp_reg = &sparc_registers[REG_SP];
- ir_node *fp = be_get_initial_reg_value(irg, fp_reg);
- ir_node *sp = be_get_initial_reg_value(irg, sp_reg);
- ir_node *restore = new_bd_sparc_RestoreZero(NULL, block, sp, fp);
+ arch_register_t const *const fp_reg = &sparc_registers[REG_FRAME_POINTER];
+ ir_node *const fp = be_get_initial_reg_value(irg, fp_reg);
+ ir_node *const new_sp = be_get_initial_reg_value(irg, sp_reg);
+ ir_node *const restore = new_bd_sparc_RestoreZero(NULL, block, new_sp, fp);
sched_add_before(ret, restore);
arch_set_irn_register(restore, sp_reg);
- set_irn_n(ret, sp_idx, restore);
-
+ set_irn_n(ret, n_sparc_Return_sp, restore);
kill_unused_stacknodes(sp);
} else {
- ir_node *incsp = be_new_IncSP(sp_reg, block, sp, -frame_size, 0);
- set_irn_n(ret, sp_idx, incsp);
+ ir_type *const frame_type = get_irg_frame_type(irg);
+ unsigned const frame_size = get_type_size_bytes(frame_type);
+ ir_node *const incsp = be_new_IncSP(sp_reg, block, sp, -frame_size, 0);
+ set_irn_n(ret, n_sparc_Return_sp, incsp);
sched_add_before(ret, incsp);
}
}
be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
ir_node *block = get_nodes_block(start);
ir_node *initial_sp = be_get_initial_reg_value(irg, sp_reg);
- ir_node *sp = initial_sp;
ir_node *schedpoint = start;
ir_type *frame_type = get_irg_frame_type(irg);
unsigned frame_size = get_type_size_bytes(frame_type);
schedpoint = sched_next(schedpoint);
if (!layout->sp_relative) {
- ir_node *save = new_bd_sparc_Save_imm(NULL, block, sp, NULL,
- -SPARC_MIN_STACKSIZE-frame_size);
+ ir_node *const save = new_bd_sparc_Save_imm(NULL, block, initial_sp, NULL, -(SPARC_MIN_STACKSIZE + frame_size));
arch_set_irn_register(save, sp_reg);
sched_add_after(schedpoint, save);
schedpoint = save;
- edges_reroute(initial_sp, save);
- set_irn_n(save, n_sparc_Save_stack, initial_sp);
+ edges_reroute_except(initial_sp, save, save);
/* we still need the Save even if noone is explicitely using the
* value. (TODO: this isn't 100% correct yet, something at the end of
sched_add_after(schedpoint, keep);
}
} else {
- ir_node *incsp = be_new_IncSP(sp_reg, block, sp, frame_size, 0);
- edges_reroute(initial_sp, incsp);
- be_set_IncSP_pred(incsp, sp);
+ ir_node *const incsp = be_new_IncSP(sp_reg, block, initial_sp, frame_size, 0);
+ edges_reroute_except(initial_sp, incsp, incsp);
sched_add_after(schedpoint, incsp);
}
}
ir_node *constant = create_constant_from_immediate(node, offset);
ir_node *new_load = new_bd_sparc_Ld_reg(dbgi, block, ptr, constant, mem, load_store_mode);
sparc_load_store_attr_t *new_load_attr = get_sparc_load_store_attr(new_load);
- unsigned n_outs = arch_get_irn_n_outs(node);
- unsigned i;
new_load_attr->is_frame_entity = load_store_attr->is_frame_entity;
new_load_attr->is_reg_reg = load_store_attr->is_reg_reg;
sched_add_before(node, new_load);
- for (i = 0; i < n_outs; i++) {
+ be_foreach_out(node, i) {
arch_set_irn_register_out(new_load, i, arch_get_irn_register_out(node, i));
}
be_peephole_exchange(node, new_load);
ir_node *new_ptr = new_bd_sparc_Add_reg(dbgi, block, ptr, constant);
ir_node *new_load = new_bd_sparc_Ldf_s(dbgi, block, new_ptr, mem, load_store_mode, NULL, 0, true);
sparc_load_store_attr_t *new_load_attr = get_sparc_load_store_attr(new_load);
- unsigned n_outs = arch_get_irn_n_outs(node);
- unsigned i;
new_load_attr->is_frame_entity = load_store_attr->is_frame_entity;
new_load_attr->is_reg_reg = load_store_attr->is_reg_reg;
sched_add_before(node, new_load);
- for (i = 0; i < n_outs; i++) {
+ be_foreach_out(node, i) {
arch_set_irn_register_out(new_load, i, arch_get_irn_register_out(node, i));
}
be_peephole_exchange(node, new_load);
ir_node *constant = create_constant_from_immediate(node, offset);
ir_node *new_load = new_bd_sparc_St_reg(dbgi, block, value, ptr, constant, mem, load_store_mode);
sparc_load_store_attr_t *new_load_attr = get_sparc_load_store_attr(new_load);
- unsigned n_outs = arch_get_irn_n_outs(node);
- unsigned i;
new_load_attr->is_frame_entity = load_store_attr->is_frame_entity;
new_load_attr->is_reg_reg = load_store_attr->is_reg_reg;
sched_add_before(node, new_load);
- for (i = 0; i < n_outs; i++) {
+ be_foreach_out(node, i) {
arch_set_irn_register_out(new_load, i, arch_get_irn_register_out(node, i));
}
be_peephole_exchange(node, new_load);
ir_node *new_ptr = new_bd_sparc_Add_reg(dbgi, block, ptr, constant);
ir_node *new_load = new_bd_sparc_Stf_s(dbgi, block, value, new_ptr, mem, load_store_mode, NULL, 0, true);
sparc_load_store_attr_t *new_load_attr = get_sparc_load_store_attr(new_load);
- unsigned n_outs = arch_get_irn_n_outs(node);
- unsigned i;
new_load_attr->is_frame_entity = load_store_attr->is_frame_entity;
new_load_attr->is_reg_reg = load_store_attr->is_reg_reg;
sched_add_before(node, new_load);
- for (i = 0; i < n_outs; i++) {
+ be_foreach_out(node, i) {
arch_set_irn_register_out(new_load, i, arch_get_irn_register_out(node, i));
}
be_peephole_exchange(node, new_load);
* (and therefore after code selection).
*/
int n_tries = 10; /* limit our search */
- ir_node *schedpoint = node;
- while (sched_has_prev(schedpoint)) {
+ for (ir_node *schedpoint = node;;) {
const arch_register_t *reg;
schedpoint = sched_prev(schedpoint);
+ if (sched_is_begin(schedpoint))
+ break;
if (--n_tries == 0)
break;
continue;
if (be_is_Copy(schedpoint) && be_can_move_down(heights, schedpoint, node)) {
- ir_node *op = get_irn_n(schedpoint, n_be_Copy_op);
+ ir_node *const op = be_get_Copy_op(schedpoint);
replace_with_restore_imm(node, schedpoint, op, NULL, 0);
} else if (is_sparc_Or(schedpoint) &&
arch_get_irn_flags(schedpoint) & ((arch_irn_flags_t)sparc_arch_irn_flag_immediate_form) &&
static void finish_sparc_Return(ir_node *node)
{
- ir_node *schedpoint = node;
- ir_node *restore;
- /* see that there is no code between Return and restore, if there is move
- * it in front of the restore */
- while (true) {
- if (!sched_has_prev(schedpoint))
- return;
- schedpoint = sched_prev(schedpoint);
- if (is_sparc_Restore(schedpoint) || is_sparc_RestoreZero(schedpoint))
+ /* Ensure that the restore is directly before the return. */
+ sched_foreach_reverse_from(sched_prev(node), restore) {
+ if (is_sparc_Restore(restore) || is_sparc_RestoreZero(restore)) {
+ sched_remove(restore);
+ sched_add_before(node, restore);
break;
- }
- restore = schedpoint;
- schedpoint = sched_prev(node);
- /* move all code between return and restore up */
- while (schedpoint != restore) {
- ir_node *next_schedpoint = sched_prev(schedpoint);
- sched_remove(schedpoint);
- sched_add_before(restore, schedpoint);
- schedpoint = next_schedpoint;
+ }
}
}