Commit 123e854f authored by Christoph Mallon's avatar Christoph Mallon
Browse files

ia32: Do not accidently lose the stack frame.

Consider a function with frame pointer relative addressing, where the only users of the stack are the Returns.
Still space for values might be allocated on the stack.
To prevent this, during prologue construction the IncSP was kept, if it had at most one user.
If there are multiple returns, then there was more than one user, so the IncSP is not kept.
Then during epilogue construction these uses are replaced by movl %ebp, %esp/leave.
This renders the allocation of the frame unused and it vanishes.
So memory below the stack pointer is accessed.

Now first construct the epilogues.
Then, when the prologue is constructed afterwards, we know whether the IncSP is unused and needs to be kept.

Still this is a hack.
The correct solution would be, that IncSP produces memory, so memory operations accessing stack slots use this memory.
parent d69e161d
...@@ -1130,7 +1130,7 @@ static void introduce_prologue(ir_graph *const irg) ...@@ -1130,7 +1130,7 @@ static void introduce_prologue(ir_graph *const irg)
sched_add_after(curr_sp, incsp); sched_add_after(curr_sp, incsp);
/* make sure the initial IncSP is really used by someone */ /* make sure the initial IncSP is really used by someone */
if (get_irn_n_edges(incsp) <= 1) { if (get_irn_n_edges(incsp) == 0) {
ir_node *in[] = { incsp }; ir_node *in[] = { incsp };
ir_node *keep = be_new_Keep(block, 1, in); ir_node *keep = be_new_Keep(block, 1, in);
sched_add_after(incsp, keep); sched_add_after(incsp, keep);
...@@ -1149,13 +1149,13 @@ static void introduce_prologue(ir_graph *const irg) ...@@ -1149,13 +1149,13 @@ static void introduce_prologue(ir_graph *const irg)
*/ */
static void introduce_prologue_epilogue(ir_graph *const irg) static void introduce_prologue_epilogue(ir_graph *const irg)
{ {
introduce_prologue(irg);
/* introduce epilogue for every return node */ /* introduce epilogue for every return node */
foreach_irn_in(get_irg_end_block(irg), i, ret) { foreach_irn_in(get_irg_end_block(irg), i, ret) {
assert(is_ia32_Return(ret)); assert(is_ia32_Return(ret));
introduce_epilogue(ret); introduce_epilogue(ret);
} }
introduce_prologue(irg);
} }
static void ia32_emit(ir_graph *irg) static void ia32_emit(ir_graph *irg)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment