]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/stack-ptr-mod.c
2012-11-01 Sharad Singhai <singhai@google.com>
[thirdparty/gcc.git] / gcc / stack-ptr-mod.c
CommitLineData
48e1416a 1/* Discover if the stack pointer is modified in a function.
0b1615c1 2 Copyright (C) 2007, 2008, 2009
3072d30e 3 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
8c4c00c1 9Software Foundation; either version 3, or (at your option) any later
3072d30e 10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
3072d30e 20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "tree.h"
26#include "rtl.h"
27#include "regs.h"
28#include "expr.h"
29#include "tree-pass.h"
30#include "basic-block.h"
31#include "flags.h"
32#include "output.h"
33#include "df.h"
34
35/* Determine if the stack pointer is constant over the life of the function.
36 Only useful before prologues have been emitted. */
37
38static void
81a410b1 39notice_stack_pointer_modification_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED,
3072d30e 40 void *data ATTRIBUTE_UNUSED)
41{
42 if (x == stack_pointer_rtx
43 /* The stack pointer is only modified indirectly as the result
44 of a push until later. See the comments in rtl.texi
45 regarding Embedded Side-Effects on Addresses. */
46 || (MEM_P (x)
47 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_AUTOINC
48 && XEXP (XEXP (x, 0), 0) == stack_pointer_rtx))
d5bf7b64 49 crtl->sp_is_unchanging = 0;
3072d30e 50}
51
52static void
53notice_stack_pointer_modification (void)
54{
55 basic_block bb;
56 rtx insn;
57
58 /* Assume that the stack pointer is unchanging if alloca hasn't
59 been used. */
d5bf7b64 60 crtl->sp_is_unchanging = !cfun->calls_alloca;
61 if (crtl->sp_is_unchanging)
3072d30e 62 FOR_EACH_BB (bb)
63 FOR_BB_INSNS (bb, insn)
64 {
65 if (INSN_P (insn))
66 {
67 /* Check if insn modifies the stack pointer. */
68 note_stores (PATTERN (insn),
69 notice_stack_pointer_modification_1,
70 NULL);
d5bf7b64 71 if (! crtl->sp_is_unchanging)
3072d30e 72 return;
73 }
74 }
75
76 /* The value coming into this pass was 0, and the exit block uses
77 are based on this. If the value is now 1, we need to redo the
78 exit block uses. */
d5bf7b64 79 if (df && crtl->sp_is_unchanging)
3072d30e 80 df_update_exit_block_uses ();
81}
82
83 /* Some targets can emit simpler epilogues if they know that sp was
84 not ever modified during the function. After reload, of course,
85 we've already emitted the epilogue so there's no sense searching. */
86
87static unsigned int
88rest_of_handle_stack_ptr_mod (void)
89{
90 notice_stack_pointer_modification ();
91 return 0;
92}
93
20099e35 94struct rtl_opt_pass pass_stack_ptr_mod =
3072d30e 95{
20099e35 96 {
97 RTL_PASS,
0c297edc 98 "*stack_ptr_mod", /* name */
c7875731 99 OPTGROUP_NONE, /* optinfo_flags */
3072d30e 100 NULL, /* gate */
101 rest_of_handle_stack_ptr_mod, /* execute */
102 NULL, /* sub */
103 NULL, /* next */
104 0, /* static_pass_number */
0b1615c1 105 TV_NONE, /* tv_id */
3072d30e 106 0, /* properties_required */
107 0, /* properties_provided */
108 0, /* properties_destroyed */
109 0, /* todo_flags_start */
20099e35 110 0 /* todo_flags_finish */
111 }
3072d30e 112};