static int stack_frame_compute_initial_offset(be_stack_layout_t *frame)
{
- ir_type *base = frame->stack_dir < 0 ? frame->between_type : frame->frame_type;
+ ir_type *base = frame->between_type;
ir_entity *ent = search_ent_with_offset(base, 0);
if (ent == NULL) {
- frame->initial_offset
- = frame->stack_dir < 0 ? get_type_size_bytes(frame->frame_type) : get_type_size_bytes(frame->between_type);
+ frame->initial_offset = get_type_size_bytes(frame->frame_type);
} else {
frame->initial_offset = be_get_stack_entity_offset(frame, ent, 0);
}
* If the node modifies the stack pointer by a constant offset,
* record that in the bias.
*/
- ofs = arch_get_sp_bias(irn);
-
if (be_is_IncSP(irn)) {
+ ofs = be_get_IncSP_offset(irn);
/* fill in real stack frame size */
- if (ofs == BE_STACK_FRAME_SIZE_EXPAND) {
- ir_type *frame_type = get_irg_frame_type(irg);
- ofs = (int) get_type_size_bytes(frame_type);
- be_set_IncSP_offset(irn, ofs);
- } else if (ofs == BE_STACK_FRAME_SIZE_SHRINK) {
- ir_type *frame_type = get_irg_frame_type(irg);
- ofs = - (int)get_type_size_bytes(frame_type);
- be_set_IncSP_offset(irn, ofs);
+ if (be_get_IncSP_align(irn)) {
+ /* patch IncSP to produce an aligned stack pointer */
+ ir_type *between_type = layout->between_type;
+ int between_size = get_type_size_bytes(between_type);
+ int alignment = 1 << arch_env->stack_alignment;
+ int delta = (real_bias + ofs + between_size) & (alignment - 1);
+ assert(ofs >= 0);
+ if (delta > 0) {
+ be_set_IncSP_offset(irn, ofs + alignment - delta);
+ real_bias += alignment - delta;
+ }
} else {
- if (be_get_IncSP_align(irn)) {
- /* patch IncSP to produce an aligned stack pointer */
- ir_type *between_type = layout->between_type;
- int between_size = get_type_size_bytes(between_type);
- int alignment = 1 << arch_env->stack_alignment;
- int delta = (real_bias + ofs + between_size) & (alignment - 1);
- assert(ofs >= 0);
- if (delta > 0) {
- be_set_IncSP_offset(irn, ofs + alignment - delta);
- real_bias += alignment - delta;
- }
- } else {
- /* adjust so real_bias corresponds with wanted_bias */
- int delta = wanted_bias - real_bias;
- assert(delta <= 0);
- if (delta != 0) {
- be_set_IncSP_offset(irn, ofs + delta);
- real_bias += delta;
- }
+ /* adjust so real_bias corresponds with wanted_bias */
+ int delta = wanted_bias - real_bias;
+ assert(delta <= 0);
+ if (delta != 0) {
+ be_set_IncSP_offset(irn, ofs + delta);
+ real_bias += delta;
}
}
+ real_bias += ofs;
+ wanted_bias += ofs;
+ } else {
+ ofs = arch_get_sp_bias(irn);
+ if (ofs == SP_BIAS_RESET) {
+ real_bias = 0;
+ wanted_bias = 0;
+ } else {
+ real_bias += ofs;
+ wanted_bias += ofs;
+ }
}
-
- real_bias += ofs;
- wanted_bias += ofs;
}
assert(real_bias == wanted_bias);
insn = get_Proj_pred(node);
}
- if (arch_irn_get_n_outs(insn) == 0)
+ if (arch_get_irn_n_outs(insn) == 0)
return;
if (get_irn_mode(node) == mode_T)
return;
- req = arch_get_register_req_out(node);
+ req = arch_get_irn_register_req(node);
if (! (req->type & arch_register_req_type_produces_sp))
return;
arch_set_irn_register(phi, arch_env->sp);
}
be_ssa_construction_destroy(&senv);
-
DEL_ARR_F(walker_env.sp_nodes);
+
+ /* when doing code with frame-pointers then often the last incsp-nodes are
+ * not used anymore because we copy the framepointer to the stack pointer
+ * when leaving the function. Though the last incsp is often kept (because
+ * you often don't know which incsp is the last one and fixstack should find
+ * them all). Remove unnecessary keeps and IncSP nodes */
+ {
+ ir_node *end = get_irg_end(irg);
+ int arity = get_irn_arity(end);
+ int i;
+ for (i = arity-1; i >= 0; --i) {
+ ir_node *in = get_irn_n(end, i);
+ if (!be_is_IncSP(in)) {
+ continue;
+ }
+
+ remove_End_keepalive(end, in);
+ if (get_irn_n_edges(in) == 0) {
+ sched_remove(in);
+ kill_node(in);
+ }
+ }
+ }
}