annotate gcc/ipa-pure-const.c @ 142:c83ff0b5a2ed

merge
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 22 Nov 2018 19:45:33 +0900
parents 84e7813d76e9
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Callgraph based analysis of static variables.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2004-2018 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 /* This file marks functions as being either const (TREE_READONLY) or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 pure (DECL_PURE_P). It can also set a variant of these that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 are allowed to loop indefinitely (DECL_LOOPING_CONST_PURE_P).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 This must be run after inlining decisions have been made since
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 otherwise, the local sets will not contain information that is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 consistent with post inlined state. The global sets are not prone
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 to this problem since they are by definition transitive. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 /* The code in this module is called by the ipa pass manager. It
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 should be one of the later passes since it's information is used by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 the rest of the compilation. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 #include "coretypes.h"
111
kono
parents: 67
diff changeset
37 #include "backend.h"
kono
parents: 67
diff changeset
38 #include "target.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 #include "tree.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 #include "gimple.h"
111
kono
parents: 67
diff changeset
41 #include "tree-pass.h"
kono
parents: 67
diff changeset
42 #include "tree-streamer.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 #include "cgraph.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 #include "diagnostic.h"
111
kono
parents: 67
diff changeset
45 #include "calls.h"
kono
parents: 67
diff changeset
46 #include "cfganal.h"
kono
parents: 67
diff changeset
47 #include "tree-eh.h"
kono
parents: 67
diff changeset
48 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
49 #include "gimple-walk.h"
kono
parents: 67
diff changeset
50 #include "tree-cfg.h"
kono
parents: 67
diff changeset
51 #include "tree-ssa-loop-niter.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 #include "langhooks.h"
111
kono
parents: 67
diff changeset
53 #include "ipa-utils.h"
kono
parents: 67
diff changeset
54 #include "gimple-pretty-print.h"
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
55 #include "cfgloop.h"
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
56 #include "tree-scalar-evolution.h"
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
57 #include "intl.h"
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
58 #include "opts.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
59 #include "ssa.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
60 #include "alloc-pool.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
61 #include "symbol-summary.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
62 #include "ipa-prop.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
63 #include "ipa-fnsummary.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 /* Lattice values for const and pure functions. Everything starts out
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 being const, then may drop to pure and then neither depending on
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 what is found. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 enum pure_const_state_e
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 IPA_CONST,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 IPA_PURE,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 IPA_NEITHER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75 static const char *pure_const_names[3] = {"const", "pure", "neither"};
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
77 enum malloc_state_e
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 STATE_MALLOC_TOP,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
80 STATE_MALLOC,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 STATE_MALLOC_BOTTOM
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84 static const char *malloc_state_names[] = {"malloc_top", "malloc", "malloc_bottom"};
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
85
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 /* Holder for the const_state. There is one of these per function
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 decl. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88 class funct_state_d
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
90 public:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
91 funct_state_d (): pure_const_state (IPA_NEITHER),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
92 state_previously_known (IPA_NEITHER), looping_previously_known (true),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
93 looping (true), can_throw (true), can_free (true),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
94 malloc_state (STATE_MALLOC_BOTTOM) {}
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
95
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 funct_state_d (const funct_state_d &s): pure_const_state (s.pure_const_state),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
97 state_previously_known (s.state_previously_known),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98 looping_previously_known (s.looping_previously_known),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 looping (s.looping), can_throw (s.can_throw), can_free (s.can_free),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 malloc_state (s.malloc_state) {}
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
101
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 /* See above. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 enum pure_const_state_e pure_const_state;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
104 /* What user set here; we can be always sure about this. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
105 enum pure_const_state_e state_previously_known;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
106 bool looping_previously_known;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 /* True if the function could possibly infinite loop. There are a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 lot of ways that this could be determined. We are pretty
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 conservative here. While it is possible to cse pure and const
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 calls, it is not legal to have dce get rid of the call if there
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 is a possibility that the call could infinite loop since this is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 a behavioral change. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 bool looping;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
116 bool can_throw;
111
kono
parents: 67
diff changeset
117
kono
parents: 67
diff changeset
118 /* If function can call free, munmap or otherwise make previously
kono
parents: 67
diff changeset
119 non-trapping memory accesses trapping. */
kono
parents: 67
diff changeset
120 bool can_free;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
121
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
122 enum malloc_state_e malloc_state;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 typedef struct funct_state_d * funct_state;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 /* The storage of the funct_state is abstracted because there is the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 possibility that it may be desirable to move this to the cgraph
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
129 local info. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131 class funct_state_summary_t: public function_summary <funct_state_d *>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133 public:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
134 funct_state_summary_t (symbol_table *symtab):
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135 function_summary <funct_state_d *> (symtab) {}
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
137 virtual void insert (cgraph_node *, funct_state_d *state);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
138 virtual void duplicate (cgraph_node *src_node, cgraph_node *dst_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
139 funct_state_d *src_data,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
140 funct_state_d *dst_data);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
141 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
142
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
143 static funct_state_summary_t *funct_state_summaries = NULL;
111
kono
parents: 67
diff changeset
144
kono
parents: 67
diff changeset
145 static bool gate_pure_const (void);
kono
parents: 67
diff changeset
146
kono
parents: 67
diff changeset
147 namespace {
kono
parents: 67
diff changeset
148
kono
parents: 67
diff changeset
149 const pass_data pass_data_ipa_pure_const =
kono
parents: 67
diff changeset
150 {
kono
parents: 67
diff changeset
151 IPA_PASS, /* type */
kono
parents: 67
diff changeset
152 "pure-const", /* name */
kono
parents: 67
diff changeset
153 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
154 TV_IPA_PURE_CONST, /* tv_id */
kono
parents: 67
diff changeset
155 0, /* properties_required */
kono
parents: 67
diff changeset
156 0, /* properties_provided */
kono
parents: 67
diff changeset
157 0, /* properties_destroyed */
kono
parents: 67
diff changeset
158 0, /* todo_flags_start */
kono
parents: 67
diff changeset
159 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
160 };
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161
111
kono
parents: 67
diff changeset
162 class pass_ipa_pure_const : public ipa_opt_pass_d
kono
parents: 67
diff changeset
163 {
kono
parents: 67
diff changeset
164 public:
kono
parents: 67
diff changeset
165 pass_ipa_pure_const(gcc::context *ctxt);
kono
parents: 67
diff changeset
166
kono
parents: 67
diff changeset
167 /* opt_pass methods: */
kono
parents: 67
diff changeset
168 bool gate (function *) { return gate_pure_const (); }
kono
parents: 67
diff changeset
169 unsigned int execute (function *fun);
kono
parents: 67
diff changeset
170
kono
parents: 67
diff changeset
171 void register_hooks (void);
kono
parents: 67
diff changeset
172
kono
parents: 67
diff changeset
173 private:
kono
parents: 67
diff changeset
174 bool init_p;
kono
parents: 67
diff changeset
175 }; // class pass_ipa_pure_const
kono
parents: 67
diff changeset
176
kono
parents: 67
diff changeset
177 } // anon namespace
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
179 /* Try to guess if function body will always be visible to compiler
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
180 when compiling the call and whether compiler will be able
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
181 to propagate the information by itself. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
182
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
183 static bool
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
184 function_always_visible_to_compiler_p (tree decl)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
185 {
111
kono
parents: 67
diff changeset
186 return (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl)
kono
parents: 67
diff changeset
187 || DECL_COMDAT (decl));
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
188 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
189
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
190 /* Emit suggestion about attribute ATTRIB_NAME for DECL. KNOWN_FINITE
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
191 is true if the function is known to be finite. The diagnostic is
111
kono
parents: 67
diff changeset
192 controlled by OPTION. WARNED_ABOUT is a hash_set<tree> unique for
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
193 OPTION, this function may initialize it and it is always returned
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
194 by the function. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
195
111
kono
parents: 67
diff changeset
196 static hash_set<tree> *
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
197 suggest_attribute (int option, tree decl, bool known_finite,
111
kono
parents: 67
diff changeset
198 hash_set<tree> *warned_about,
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
199 const char * attrib_name)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
200 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
201 if (!option_enabled (option, &global_options))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
202 return warned_about;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
203 if (TREE_THIS_VOLATILE (decl)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
204 || (known_finite && function_always_visible_to_compiler_p (decl)))
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
205 return warned_about;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
206
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
207 if (!warned_about)
111
kono
parents: 67
diff changeset
208 warned_about = new hash_set<tree>;
kono
parents: 67
diff changeset
209 if (warned_about->contains (decl))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
210 return warned_about;
111
kono
parents: 67
diff changeset
211 warned_about->add (decl);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
212 warning_at (DECL_SOURCE_LOCATION (decl),
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
213 option,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
214 known_finite
111
kono
parents: 67
diff changeset
215 ? G_("function might be candidate for attribute %qs")
kono
parents: 67
diff changeset
216 : G_("function might be candidate for attribute %qs"
kono
parents: 67
diff changeset
217 " if it is known to return normally"), attrib_name);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
218 return warned_about;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
219 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
220
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
221 /* Emit suggestion about __attribute_((pure)) for DECL. KNOWN_FINITE
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
222 is true if the function is known to be finite. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
223
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
224 static void
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
225 warn_function_pure (tree decl, bool known_finite)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
226 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
227 /* Declaring a void function pure makes no sense and is diagnosed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
228 by -Wattributes because calling it would have no effect. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
230 return;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
231
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
232 static hash_set<tree> *warned_about;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
233 warned_about
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
234 = suggest_attribute (OPT_Wsuggest_attribute_pure, decl,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
235 known_finite, warned_about, "pure");
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
236 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
237
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
238 /* Emit suggestion about __attribute_((const)) for DECL. KNOWN_FINITE
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
239 is true if the function is known to be finite. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
240
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
241 static void
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
242 warn_function_const (tree decl, bool known_finite)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
243 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 /* Declaring a void function const makes no sense is diagnosed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 by -Wattributes because calling it would have no effect. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
246 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
247 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
248
111
kono
parents: 67
diff changeset
249 static hash_set<tree> *warned_about;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
250 warned_about
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
251 = suggest_attribute (OPT_Wsuggest_attribute_const, decl,
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
252 known_finite, warned_about, "const");
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
253 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
254
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
255 /* Emit suggestion about __attribute__((malloc)) for DECL. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
256
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
257 static void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
258 warn_function_malloc (tree decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
259 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
260 static hash_set<tree> *warned_about;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
261 warned_about
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
262 = suggest_attribute (OPT_Wsuggest_attribute_malloc, decl,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
263 true, warned_about, "malloc");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
264 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
265
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
266 /* Emit suggestion about __attribute__((noreturn)) for DECL. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
267
111
kono
parents: 67
diff changeset
268 static void
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
269 warn_function_noreturn (tree decl)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
270 {
111
kono
parents: 67
diff changeset
271 tree original_decl = decl;
kono
parents: 67
diff changeset
272
kono
parents: 67
diff changeset
273 static hash_set<tree> *warned_about;
kono
parents: 67
diff changeset
274 if (!lang_hooks.missing_noreturn_ok_p (decl)
kono
parents: 67
diff changeset
275 && targetm.warn_func_return (decl))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
276 warned_about
111
kono
parents: 67
diff changeset
277 = suggest_attribute (OPT_Wsuggest_attribute_noreturn, original_decl,
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
278 true, warned_about, "noreturn");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
279 }
111
kono
parents: 67
diff changeset
280
kono
parents: 67
diff changeset
281 void
kono
parents: 67
diff changeset
282 warn_function_cold (tree decl)
kono
parents: 67
diff changeset
283 {
kono
parents: 67
diff changeset
284 tree original_decl = decl;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285
111
kono
parents: 67
diff changeset
286 static hash_set<tree> *warned_about;
kono
parents: 67
diff changeset
287 warned_about
kono
parents: 67
diff changeset
288 = suggest_attribute (OPT_Wsuggest_attribute_cold, original_decl,
kono
parents: 67
diff changeset
289 true, warned_about, "cold");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 /* Check to see if the use (or definition when CHECKING_WRITE is true)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 variable T is legal in a function that is either pure or const. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
295 static inline void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
296 check_decl (funct_state local,
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
297 tree t, bool checking_write, bool ipa)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
299 /* Do not want to do anything with volatile except mark any
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
300 function that uses one to be not const or pure. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
301 if (TREE_THIS_VOLATILE (t))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 local->pure_const_state = IPA_NEITHER;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
304 if (dump_file)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
305 fprintf (dump_file, " Volatile operand is not const/pure\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 /* Do not care about a local automatic that is not static. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
313 /* If the variable has the "used" attribute, treat it as if it had a
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
314 been touched by the devil. */
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
315 if (DECL_PRESERVE_P (t))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
316 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
317 local->pure_const_state = IPA_NEITHER;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
318 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
319 fprintf (dump_file, " Used static/global variable is not const/pure\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
320 return;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
321 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
322
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
323 /* In IPA mode we are not interested in checking actual loads and stores;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
324 they will be processed at propagation time using ipa_ref. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
325 if (ipa)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
326 return;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
327
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 /* Since we have dealt with the locals and params cases above, if we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 are CHECKING_WRITE, this cannot be a pure or constant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 function. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
331 if (checking_write)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 local->pure_const_state = IPA_NEITHER;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
334 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
335 fprintf (dump_file, " static/global memory write is not const/pure\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
341 /* Readonly reads are safe. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
342 if (TREE_READONLY (t) && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
343 return; /* Read of a constant, do not change the function state. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
344 else
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
346 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
347 fprintf (dump_file, " global memory read is not const\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 /* Just a regular read. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 if (local->pure_const_state == IPA_CONST)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 local->pure_const_state = IPA_PURE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
353 else
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
355 /* Compilation level statics can be read if they are readonly
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
356 variables. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
357 if (TREE_READONLY (t))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
358 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
360 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
361 fprintf (dump_file, " static memory read is not const\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
362 /* Just a regular read. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
363 if (local->pure_const_state == IPA_CONST)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 local->pure_const_state = IPA_PURE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
366 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
369 /* Check to see if the use (or definition when CHECKING_WRITE is true)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
370 variable T is legal in a function that is either pure or const. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
372 static inline void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
373 check_op (funct_state local, tree t, bool checking_write)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
375 t = get_base_address (t);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
376 if (t && TREE_THIS_VOLATILE (t))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
378 local->pure_const_state = IPA_NEITHER;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
379 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
380 fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
381 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
383 else if (t
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
384 && (INDIRECT_REF_P (t) || TREE_CODE (t) == MEM_REF)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
385 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
386 && !ptr_deref_may_alias_global_p (TREE_OPERAND (t, 0)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
388 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
389 fprintf (dump_file, " Indirect ref to local memory is OK\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
390 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
392 else if (checking_write)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
394 local->pure_const_state = IPA_NEITHER;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
395 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
396 fprintf (dump_file, " Indirect ref write is not const/pure\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
397 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
399 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
400 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
401 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
402 fprintf (dump_file, " Indirect ref read is not const\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
403 if (local->pure_const_state == IPA_CONST)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
404 local->pure_const_state = IPA_PURE;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
405 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
408 /* compute state based on ECF FLAGS and store to STATE and LOOPING. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
409
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
410 static void
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
411 state_from_flags (enum pure_const_state_e *state, bool *looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
412 int flags, bool cannot_lead_to_return)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
413 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
414 *looping = false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
415 if (flags & ECF_LOOPING_CONST_OR_PURE)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
416 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
417 *looping = true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
418 if (dump_file && (dump_flags & TDF_DETAILS))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
419 fprintf (dump_file, " looping\n");
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
420 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
421 if (flags & ECF_CONST)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
422 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
423 *state = IPA_CONST;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
424 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
425 fprintf (dump_file, " const\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
426 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
427 else if (flags & ECF_PURE)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
428 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
429 *state = IPA_PURE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
430 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
431 fprintf (dump_file, " pure\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
432 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
433 else if (cannot_lead_to_return)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
434 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
435 *state = IPA_PURE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
436 *looping = true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
437 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
438 fprintf (dump_file, " ignoring side effects->pure looping\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
439 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
440 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
441 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
442 if (dump_file && (dump_flags & TDF_DETAILS))
111
kono
parents: 67
diff changeset
443 fprintf (dump_file, " neither\n");
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
444 *state = IPA_NEITHER;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
445 *looping = true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
446 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
447 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
448
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
449 /* Merge STATE and STATE2 and LOOPING and LOOPING2 and store
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
450 into STATE and LOOPING better of the two variants.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
451 Be sure to merge looping correctly. IPA_NEITHER functions
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
452 have looping 0 even if they don't have to return. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
453
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
454 static inline void
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
455 better_state (enum pure_const_state_e *state, bool *looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
456 enum pure_const_state_e state2, bool looping2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
457 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
458 if (state2 < *state)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
459 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
460 if (*state == IPA_NEITHER)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
461 *looping = looping2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
462 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
463 *looping = MIN (*looping, looping2);
111
kono
parents: 67
diff changeset
464 *state = state2;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
465 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
466 else if (state2 != IPA_NEITHER)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
467 *looping = MIN (*looping, looping2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
468 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
469
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
470 /* Merge STATE and STATE2 and LOOPING and LOOPING2 and store
111
kono
parents: 67
diff changeset
471 into STATE and LOOPING worse of the two variants.
kono
parents: 67
diff changeset
472 N is the actual node called. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
473
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
474 static inline void
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
475 worse_state (enum pure_const_state_e *state, bool *looping,
111
kono
parents: 67
diff changeset
476 enum pure_const_state_e state2, bool looping2,
kono
parents: 67
diff changeset
477 struct symtab_node *from,
kono
parents: 67
diff changeset
478 struct symtab_node *to)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
479 {
111
kono
parents: 67
diff changeset
480 /* Consider function:
kono
parents: 67
diff changeset
481
kono
parents: 67
diff changeset
482 bool a(int *p)
kono
parents: 67
diff changeset
483 {
kono
parents: 67
diff changeset
484 return *p==*p;
kono
parents: 67
diff changeset
485 }
kono
parents: 67
diff changeset
486
kono
parents: 67
diff changeset
487 During early optimization we will turn this into:
kono
parents: 67
diff changeset
488
kono
parents: 67
diff changeset
489 bool a(int *p)
kono
parents: 67
diff changeset
490 {
kono
parents: 67
diff changeset
491 return true;
kono
parents: 67
diff changeset
492 }
kono
parents: 67
diff changeset
493
kono
parents: 67
diff changeset
494 Now if this function will be detected as CONST however when interposed it
kono
parents: 67
diff changeset
495 may end up being just pure. We always must assume the worst scenario here.
kono
parents: 67
diff changeset
496 */
kono
parents: 67
diff changeset
497 if (*state == IPA_CONST && state2 == IPA_CONST
kono
parents: 67
diff changeset
498 && to && !TREE_READONLY (to->decl) && !to->binds_to_current_def_p (from))
kono
parents: 67
diff changeset
499 {
kono
parents: 67
diff changeset
500 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
501 fprintf (dump_file, "Dropping state to PURE because call to %s may not "
kono
parents: 67
diff changeset
502 "bind to current def.\n", to->name ());
kono
parents: 67
diff changeset
503 state2 = IPA_PURE;
kono
parents: 67
diff changeset
504 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
505 *state = MAX (*state, state2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
506 *looping = MAX (*looping, looping2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
507 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
508
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
509 /* Recognize special cases of builtins that are by themselves not pure or const
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
510 but function using them is. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
511 static bool
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
512 special_builtin_state (enum pure_const_state_e *state, bool *looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
513 tree callee)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
514 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
515 if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
516 switch (DECL_FUNCTION_CODE (callee))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
517 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
518 case BUILT_IN_RETURN:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
519 case BUILT_IN_UNREACHABLE:
111
kono
parents: 67
diff changeset
520 CASE_BUILT_IN_ALLOCA:
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
521 case BUILT_IN_STACK_SAVE:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
522 case BUILT_IN_STACK_RESTORE:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
523 case BUILT_IN_EH_POINTER:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
524 case BUILT_IN_EH_FILTER:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
525 case BUILT_IN_UNWIND_RESUME:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
526 case BUILT_IN_CXA_END_CLEANUP:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
527 case BUILT_IN_EH_COPY_VALUES:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
528 case BUILT_IN_FRAME_ADDRESS:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
529 case BUILT_IN_APPLY:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
530 case BUILT_IN_APPLY_ARGS:
111
kono
parents: 67
diff changeset
531 case BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT:
kono
parents: 67
diff changeset
532 case BUILT_IN_ASAN_AFTER_DYNAMIC_INIT:
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
533 *looping = false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
534 *state = IPA_CONST;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
535 return true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
536 case BUILT_IN_PREFETCH:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
537 *looping = true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
538 *state = IPA_CONST;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
539 return true;
111
kono
parents: 67
diff changeset
540 default:
kono
parents: 67
diff changeset
541 break;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
542 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
543 return false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
544 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
545
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 /* Check the parameters of a function call to CALL_EXPR to see if
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 there are any references in the parameters that are not allowed for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 pure or const functions. Also check to see if this is either an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 indirect call, a call outside the compilation unit, or has special
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 attributes that may also effect the purity. The CALL_EXPR node for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 the entire call expression. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 static void
111
kono
parents: 67
diff changeset
554 check_call (funct_state local, gcall *call, bool ipa)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
555 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
556 int flags = gimple_call_flags (call);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
557 tree callee_t = gimple_call_fndecl (call);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
558 bool possibly_throws = stmt_could_throw_p (cfun, call);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
559 bool possibly_throws_externally = (possibly_throws
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
560 && stmt_can_throw_external (cfun, call));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
562 if (possibly_throws)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
563 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
564 unsigned int i;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
565 for (i = 0; i < gimple_num_ops (call); i++)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
566 if (gimple_op (call, i)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
567 && tree_could_throw_p (gimple_op (call, i)))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
568 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
569 if (possibly_throws && cfun->can_throw_non_call_exceptions)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
570 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
571 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
572 fprintf (dump_file, " operand can throw; looping\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
573 local->looping = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
574 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
575 if (possibly_throws_externally)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
576 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
577 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
578 fprintf (dump_file, " operand can throw externally\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
579 local->can_throw = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
580 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
581 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
582 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 /* The const and pure flags are set by a variety of places in the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 compiler (including here). If someone has already set the flags
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 for the callee, (such as for some of the builtins) we will use
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
587 them, otherwise we will compute our own information.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
588
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589 Const and pure functions have less clobber effects than other
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 functions so we process these first. Otherwise if it is a call
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 outside the compilation unit or an indirect call we punt. This
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 leaves local calls which will be processed by following the call
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
593 graph. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 if (callee_t)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
596 enum pure_const_state_e call_state;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
597 bool call_looping;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
598
111
kono
parents: 67
diff changeset
599 if (gimple_call_builtin_p (call, BUILT_IN_NORMAL)
kono
parents: 67
diff changeset
600 && !nonfreeing_call_p (call))
kono
parents: 67
diff changeset
601 local->can_free = true;
kono
parents: 67
diff changeset
602
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
603 if (special_builtin_state (&call_state, &call_looping, callee_t))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
604 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
605 worse_state (&local->pure_const_state, &local->looping,
111
kono
parents: 67
diff changeset
606 call_state, call_looping,
kono
parents: 67
diff changeset
607 NULL, NULL);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
608 return;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
609 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 /* When bad things happen to bad functions, they cannot be const
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 or pure. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612 if (setjmp_call_p (callee_t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
614 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
615 fprintf (dump_file, " setjmp is not const/pure\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
616 local->looping = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 local->pure_const_state = IPA_NEITHER;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
619
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 switch (DECL_FUNCTION_CODE (callee_t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 case BUILT_IN_LONGJMP:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
624 case BUILT_IN_NONLOCAL_GOTO:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
625 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
626 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
627 local->pure_const_state = IPA_NEITHER;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
628 local->looping = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
629 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
630 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
631 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
632 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 }
111
kono
parents: 67
diff changeset
634 else if (gimple_call_internal_p (call) && !nonfreeing_call_p (call))
kono
parents: 67
diff changeset
635 local->can_free = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
637 /* When not in IPA mode, we can still handle self recursion. */
111
kono
parents: 67
diff changeset
638 if (!ipa && callee_t
kono
parents: 67
diff changeset
639 && recursive_call_p (current_function_decl, callee_t))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
640 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
641 if (dump_file)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
642 fprintf (dump_file, " Recursive call can loop.\n");
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
643 local->looping = true;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
644 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
645 /* Either callee is unknown or we are doing local analysis.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
646 Look to see if there are any bits available for the callee (such as by
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
647 declaration or because it is builtin) and process solely on the basis of
111
kono
parents: 67
diff changeset
648 those bits. Handle internal calls always, those calls don't have
kono
parents: 67
diff changeset
649 corresponding cgraph edges and thus aren't processed during
kono
parents: 67
diff changeset
650 the propagation. */
kono
parents: 67
diff changeset
651 else if (!ipa || gimple_call_internal_p (call))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
653 enum pure_const_state_e call_state;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
654 bool call_looping;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
655 if (possibly_throws && cfun->can_throw_non_call_exceptions)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
656 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
657 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
658 fprintf (dump_file, " can throw; looping\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
659 local->looping = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
660 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
661 if (possibly_throws_externally)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
662 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
663 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
664 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
665 fprintf (dump_file, " can throw externally to lp %i\n",
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
666 lookup_stmt_eh_lp (call));
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
667 if (callee_t)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
668 fprintf (dump_file, " callee:%s\n",
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
669 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
670 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
671 local->can_throw = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
672 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
673 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
674 fprintf (dump_file, " checking flags for call:");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
675 state_from_flags (&call_state, &call_looping, flags,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
676 ((flags & (ECF_NORETURN | ECF_NOTHROW))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
677 == (ECF_NORETURN | ECF_NOTHROW))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
678 || (!flag_exceptions && (flags & ECF_NORETURN)));
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
679 worse_state (&local->pure_const_state, &local->looping,
111
kono
parents: 67
diff changeset
680 call_state, call_looping, NULL, NULL);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
682 /* Direct functions calls are handled by IPA propagation. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
683 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
684
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
685 /* Wrapper around check_decl for loads in local more. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
686
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
687 static bool
111
kono
parents: 67
diff changeset
688 check_load (gimple *, tree op, tree, void *data)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
689 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
690 if (DECL_P (op))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
691 check_decl ((funct_state)data, op, false, false);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
692 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
693 check_op ((funct_state)data, op, false);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
694 return false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
695 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
696
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
697 /* Wrapper around check_decl for stores in local more. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
698
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
699 static bool
111
kono
parents: 67
diff changeset
700 check_store (gimple *, tree op, tree, void *data)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
701 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
702 if (DECL_P (op))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
703 check_decl ((funct_state)data, op, true, false);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
704 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
705 check_op ((funct_state)data, op, true);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
706 return false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
707 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
708
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
709 /* Wrapper around check_decl for loads in ipa mode. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
710
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
711 static bool
111
kono
parents: 67
diff changeset
712 check_ipa_load (gimple *, tree op, tree, void *data)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
713 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
714 if (DECL_P (op))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
715 check_decl ((funct_state)data, op, false, true);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
716 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
717 check_op ((funct_state)data, op, false);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
718 return false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
719 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
720
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
721 /* Wrapper around check_decl for stores in ipa mode. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
722
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
723 static bool
111
kono
parents: 67
diff changeset
724 check_ipa_store (gimple *, tree op, tree, void *data)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
725 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
726 if (DECL_P (op))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
727 check_decl ((funct_state)data, op, true, true);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
728 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
729 check_op ((funct_state)data, op, true);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
730 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
733 /* Look into pointer pointed to by GSIP and figure out what interesting side
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
734 effects it has. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
735 static void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
736 check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 {
111
kono
parents: 67
diff changeset
738 gimple *stmt = gsi_stmt (*gsip);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
739
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
740 if (is_gimple_debug (stmt))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
741 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742
111
kono
parents: 67
diff changeset
743 /* Do consider clobber as side effects before IPA, so we rather inline
kono
parents: 67
diff changeset
744 C++ destructors and keep clobber semantics than eliminate them.
kono
parents: 67
diff changeset
745
kono
parents: 67
diff changeset
746 TODO: We may get smarter during early optimizations on these and let
kono
parents: 67
diff changeset
747 functions containing only clobbers to be optimized more. This is a common
kono
parents: 67
diff changeset
748 case of C++ destructors. */
kono
parents: 67
diff changeset
749
kono
parents: 67
diff changeset
750 if ((ipa || cfun->after_inlining) && gimple_clobber_p (stmt))
kono
parents: 67
diff changeset
751 return;
kono
parents: 67
diff changeset
752
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
753 if (dump_file)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
755 fprintf (dump_file, " scanning: ");
111
kono
parents: 67
diff changeset
756 print_gimple_stmt (dump_file, stmt, 0);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
757 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
758
111
kono
parents: 67
diff changeset
759 if (gimple_has_volatile_ops (stmt)
kono
parents: 67
diff changeset
760 && !gimple_clobber_p (stmt))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
761 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
762 local->pure_const_state = IPA_NEITHER;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
763 if (dump_file)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
764 fprintf (dump_file, " Volatile stmt is not const/pure\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
765 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
766
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
767 /* Look for loads and stores. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
768 walk_stmt_load_store_ops (stmt, local,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
769 ipa ? check_ipa_load : check_load,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
770 ipa ? check_ipa_store : check_store);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
771
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
772 if (gimple_code (stmt) != GIMPLE_CALL
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
773 && stmt_could_throw_p (cfun, stmt))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
774 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
775 if (cfun->can_throw_non_call_exceptions)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
776 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
777 if (dump_file)
111
kono
parents: 67
diff changeset
778 fprintf (dump_file, " can throw; looping\n");
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
779 local->looping = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
780 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
781 if (stmt_can_throw_external (cfun, stmt))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
782 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
783 if (dump_file)
111
kono
parents: 67
diff changeset
784 fprintf (dump_file, " can throw externally\n");
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
785 local->can_throw = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
786 }
111
kono
parents: 67
diff changeset
787 else
kono
parents: 67
diff changeset
788 if (dump_file)
kono
parents: 67
diff changeset
789 fprintf (dump_file, " can throw\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
790 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
791 switch (gimple_code (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
792 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
793 case GIMPLE_CALL:
111
kono
parents: 67
diff changeset
794 check_call (local, as_a <gcall *> (stmt), ipa);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
795 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
796 case GIMPLE_LABEL:
111
kono
parents: 67
diff changeset
797 if (DECL_NONLOCAL (gimple_label_label (as_a <glabel *> (stmt))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
798 /* Target of long jump. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
800 if (dump_file)
111
kono
parents: 67
diff changeset
801 fprintf (dump_file, " nonlocal label is not const/pure\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
802 local->pure_const_state = IPA_NEITHER;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805 case GIMPLE_ASM:
111
kono
parents: 67
diff changeset
806 if (gimple_asm_clobbers_memory_p (as_a <gasm *> (stmt)))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
807 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
808 if (dump_file)
111
kono
parents: 67
diff changeset
809 fprintf (dump_file, " memory asm clobber is not const/pure\n");
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
810 /* Abandon all hope, ye who enter here. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
811 local->pure_const_state = IPA_NEITHER;
111
kono
parents: 67
diff changeset
812 local->can_free = true;
kono
parents: 67
diff changeset
813 }
kono
parents: 67
diff changeset
814 if (gimple_asm_volatile_p (as_a <gasm *> (stmt)))
kono
parents: 67
diff changeset
815 {
kono
parents: 67
diff changeset
816 if (dump_file)
kono
parents: 67
diff changeset
817 fprintf (dump_file, " volatile is not const/pure\n");
kono
parents: 67
diff changeset
818 /* Abandon all hope, ye who enter here. */
kono
parents: 67
diff changeset
819 local->pure_const_state = IPA_NEITHER;
kono
parents: 67
diff changeset
820 local->looping = true;
kono
parents: 67
diff changeset
821 local->can_free = true;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
822 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
823 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
826 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
827 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
828
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
829 /* Check that RETVAL is used only in STMT and in comparisons against 0.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
830 RETVAL is return value of the function and STMT is return stmt. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
831
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
832 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
833 check_retval_uses (tree retval, gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
834 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
835 imm_use_iterator use_iter;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
836 gimple *use_stmt;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
837
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
838 FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, retval)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
839 if (gcond *cond = dyn_cast<gcond *> (use_stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
840 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
841 tree op2 = gimple_cond_rhs (cond);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
842 if (!integer_zerop (op2))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
843 RETURN_FROM_IMM_USE_STMT (use_iter, false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
844 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
845 else if (gassign *ga = dyn_cast<gassign *> (use_stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
846 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
847 enum tree_code code = gimple_assign_rhs_code (ga);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
848 if (TREE_CODE_CLASS (code) != tcc_comparison)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
849 RETURN_FROM_IMM_USE_STMT (use_iter, false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
850 if (!integer_zerop (gimple_assign_rhs2 (ga)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
851 RETURN_FROM_IMM_USE_STMT (use_iter, false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
852 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
853 else if (is_gimple_debug (use_stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
854 ;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
855 else if (use_stmt != stmt)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
856 RETURN_FROM_IMM_USE_STMT (use_iter, false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
857
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
858 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
859 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
860
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
861 /* malloc_candidate_p() checks if FUN can possibly be annotated with malloc
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
862 attribute. Currently this function does a very conservative analysis.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
863 FUN is considered to be a candidate if
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
864 1) It returns a value of pointer type.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
865 2) SSA_NAME_DEF_STMT (return_value) is either a function call or
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
866 a phi, and element of phi is either NULL or
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
867 SSA_NAME_DEF_STMT(element) is function call.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
868 3) The return-value has immediate uses only within comparisons (gcond or gassign)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
869 and return_stmt (and likewise a phi arg has immediate use only within comparison
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
870 or the phi stmt). */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
871
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
872 #define DUMP_AND_RETURN(reason) \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
873 { \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
874 if (dump_file && (dump_flags & TDF_DETAILS)) \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
875 fprintf (dump_file, "\n%s is not a malloc candidate, reason: %s\n", \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
876 (node->name()), (reason)); \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
877 return false; \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
878 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
880 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
881 malloc_candidate_p_1 (function *fun, tree retval, gimple *ret_stmt, bool ipa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
882 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
883 cgraph_node *node = cgraph_node::get_create (fun->decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
884
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
885 if (!check_retval_uses (retval, ret_stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
886 DUMP_AND_RETURN("Return value has uses outside return stmt"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
887 " and comparisons against 0.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
888
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 gimple *def = SSA_NAME_DEF_STMT (retval);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 if (gcall *call_stmt = dyn_cast<gcall *> (def))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
892 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
893 tree callee_decl = gimple_call_fndecl (call_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
894 if (!callee_decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
895 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
896
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
897 if (!ipa && !DECL_IS_MALLOC (callee_decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
898 DUMP_AND_RETURN("callee_decl does not have malloc attribute for"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
899 " non-ipa mode.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
900
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
901 cgraph_edge *cs = node->get_edge (call_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
902 if (cs)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
903 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
904 ipa_call_summary *es = ipa_call_summaries->get_create (cs);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
905 es->is_return_callee_uncaptured = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
906 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
907 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
908
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
909 else if (gphi *phi = dyn_cast<gphi *> (def))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
910 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
911 bool all_args_zero = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
912 for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
913 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
914 tree arg = gimple_phi_arg_def (phi, i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
915 if (integer_zerop (arg))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
916 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
917
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
918 all_args_zero = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
919 if (TREE_CODE (arg) != SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
920 DUMP_AND_RETURN ("phi arg is not SSA_NAME.");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
921 if (!check_retval_uses (arg, phi))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
922 DUMP_AND_RETURN ("phi arg has uses outside phi"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
923 " and comparisons against 0.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
924
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
925 gimple *arg_def = SSA_NAME_DEF_STMT (arg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
926 if (is_a<gphi *> (arg_def))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
927 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
928 if (!malloc_candidate_p_1 (fun, arg, phi, ipa))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
929 DUMP_AND_RETURN ("nested phi fail")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
931 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
932
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
933 gcall *call_stmt = dyn_cast<gcall *> (arg_def);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
934 if (!call_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
935 DUMP_AND_RETURN ("phi arg is a not a call_stmt.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
936
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 tree callee_decl = gimple_call_fndecl (call_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 if (!callee_decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940 if (!ipa && !DECL_IS_MALLOC (callee_decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
941 DUMP_AND_RETURN("callee_decl does not have malloc attribute"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
942 " for non-ipa mode.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
943
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
944 cgraph_edge *cs = node->get_edge (call_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
945 if (cs)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
946 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
947 ipa_call_summary *es = ipa_call_summaries->get_create (cs);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
948 es->is_return_callee_uncaptured = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
949 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
950 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
951
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
952 if (all_args_zero)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
953 DUMP_AND_RETURN ("Return value is a phi with all args equal to 0.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
954 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
955
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
956 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
957 DUMP_AND_RETURN("def_stmt of return value is not a call or phi-stmt.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
958
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
959 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
960 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
961
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
962 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
963 malloc_candidate_p (function *fun, bool ipa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
964 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
965 basic_block exit_block = EXIT_BLOCK_PTR_FOR_FN (fun);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
966 edge e;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
967 edge_iterator ei;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
968 cgraph_node *node = cgraph_node::get_create (fun->decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
969
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
970 if (EDGE_COUNT (exit_block->preds) == 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
971 || !flag_delete_null_pointer_checks)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
972 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
973
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
974 FOR_EACH_EDGE (e, ei, exit_block->preds)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
975 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
976 gimple_stmt_iterator gsi = gsi_last_bb (e->src);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
977 greturn *ret_stmt = dyn_cast<greturn *> (gsi_stmt (gsi));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
978
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
979 if (!ret_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
980 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
981
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
982 tree retval = gimple_return_retval (ret_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
983 if (!retval)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 DUMP_AND_RETURN("No return value.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
986 if (TREE_CODE (retval) != SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
987 || TREE_CODE (TREE_TYPE (retval)) != POINTER_TYPE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
988 DUMP_AND_RETURN("Return value is not SSA_NAME or not a pointer type.")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
989
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
990 if (!malloc_candidate_p_1 (fun, retval, ret_stmt, ipa))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
991 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
992 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
993
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
994 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
995 fprintf (dump_file, "\nFound %s to be candidate for malloc attribute\n",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
996 IDENTIFIER_POINTER (DECL_NAME (fun->decl)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
997 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
998 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
999
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1000 #undef DUMP_AND_RETURN
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1001
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002 /* This is the main routine for finding the reference patterns for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003 global variables within a function FN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1005 static funct_state
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1006 analyze_function (struct cgraph_node *fn, bool ipa)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1007 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 tree decl = fn->decl;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1009 funct_state l;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1010 basic_block this_block;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1011
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1012 l = XCNEW (struct funct_state_d);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1013 l->pure_const_state = IPA_CONST;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1014 l->state_previously_known = IPA_NEITHER;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1015 l->looping_previously_known = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1016 l->looping = false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1017 l->can_throw = false;
111
kono
parents: 67
diff changeset
1018 l->can_free = false;
kono
parents: 67
diff changeset
1019 state_from_flags (&l->state_previously_known, &l->looping_previously_known,
kono
parents: 67
diff changeset
1020 flags_from_decl_or_type (fn->decl),
kono
parents: 67
diff changeset
1021 fn->cannot_return_p ());
kono
parents: 67
diff changeset
1022
kono
parents: 67
diff changeset
1023 if (fn->thunk.thunk_p || fn->alias)
kono
parents: 67
diff changeset
1024 {
kono
parents: 67
diff changeset
1025 /* Thunk gets propagated through, so nothing interesting happens. */
kono
parents: 67
diff changeset
1026 gcc_assert (ipa);
kono
parents: 67
diff changeset
1027 if (fn->thunk.thunk_p && fn->thunk.virtual_offset_p)
kono
parents: 67
diff changeset
1028 l->pure_const_state = IPA_NEITHER;
kono
parents: 67
diff changeset
1029 return l;
kono
parents: 67
diff changeset
1030 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1031
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1032 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1033 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1034 fprintf (dump_file, "\n\n local analysis of %s\n ",
111
kono
parents: 67
diff changeset
1035 fn->name ());
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1036 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1037
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1038 push_cfun (DECL_STRUCT_FUNCTION (decl));
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1039
111
kono
parents: 67
diff changeset
1040 FOR_EACH_BB_FN (this_block, cfun)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1041 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1042 gimple_stmt_iterator gsi;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1043 struct walk_stmt_info wi;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1044
111
kono
parents: 67
diff changeset
1045 memset (&wi, 0, sizeof (wi));
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1046 for (gsi = gsi_start_bb (this_block);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1047 !gsi_end_p (gsi);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1048 gsi_next (&gsi))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1049 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1050 check_stmt (&gsi, l, ipa);
111
kono
parents: 67
diff changeset
1051 if (l->pure_const_state == IPA_NEITHER
kono
parents: 67
diff changeset
1052 && l->looping
kono
parents: 67
diff changeset
1053 && l->can_throw
kono
parents: 67
diff changeset
1054 && l->can_free)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1055 goto end;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1056 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1057 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1058
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1059 end:
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1060 if (l->pure_const_state != IPA_NEITHER)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1061 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1062 /* Const functions cannot have back edges (an
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1063 indication of possible infinite loop side
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1064 effect. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1065 if (mark_dfs_back_edges ())
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1066 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1067 /* Preheaders are needed for SCEV to work.
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1068 Simple latches and recorded exits improve chances that loop will
111
kono
parents: 67
diff changeset
1069 proved to be finite in testcases such as in loop-15.c
kono
parents: 67
diff changeset
1070 and loop-24.c */
kono
parents: 67
diff changeset
1071 loop_optimizer_init (LOOPS_HAVE_PREHEADERS
kono
parents: 67
diff changeset
1072 | LOOPS_HAVE_SIMPLE_LATCHES
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1073 | LOOPS_HAVE_RECORDED_EXITS);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1074 if (dump_file && (dump_flags & TDF_DETAILS))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1075 flow_loops_dump (dump_file, NULL, 0);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1076 if (mark_irreducible_loops ())
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1077 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1078 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1079 fprintf (dump_file, " has irreducible loops\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1080 l->looping = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1081 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1082 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1083 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1084 struct loop *loop;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1085 scev_initialize ();
111
kono
parents: 67
diff changeset
1086 FOR_EACH_LOOP (loop, 0)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1087 if (!finite_loop_p (loop))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1088 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1089 if (dump_file)
111
kono
parents: 67
diff changeset
1090 fprintf (dump_file, " can not prove finiteness of "
kono
parents: 67
diff changeset
1091 "loop %i\n", loop->num);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1092 l->looping =true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1093 break;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1094 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1095 scev_finalize ();
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1096 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1097 loop_optimizer_finalize ();
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1098 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1101 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1102 fprintf (dump_file, " checking previously known:");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1103
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1104 better_state (&l->pure_const_state, &l->looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1105 l->state_previously_known,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1106 l->looping_previously_known);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1107 if (TREE_NOTHROW (decl))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1108 l->can_throw = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1109
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1110 l->malloc_state = STATE_MALLOC_BOTTOM;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1111 if (DECL_IS_MALLOC (decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1112 l->malloc_state = STATE_MALLOC;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1113 else if (ipa && malloc_candidate_p (DECL_STRUCT_FUNCTION (decl), true))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1114 l->malloc_state = STATE_MALLOC_TOP;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1115 else if (malloc_candidate_p (DECL_STRUCT_FUNCTION (decl), false))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1116 l->malloc_state = STATE_MALLOC;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1117
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1118 pop_cfun ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1121 if (l->looping)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1122 fprintf (dump_file, "Function is locally looping.\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1123 if (l->can_throw)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1124 fprintf (dump_file, "Function is locally throwing.\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1125 if (l->pure_const_state == IPA_CONST)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1126 fprintf (dump_file, "Function is locally const.\n");
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1127 if (l->pure_const_state == IPA_PURE)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1128 fprintf (dump_file, "Function is locally pure.\n");
111
kono
parents: 67
diff changeset
1129 if (l->can_free)
kono
parents: 67
diff changeset
1130 fprintf (dump_file, "Function can locally free.\n");
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1131 if (l->malloc_state == STATE_MALLOC)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1132 fprintf (dump_file, "Function is locally malloc.\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1133 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1134 return l;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1135 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1136
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1137 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1138 funct_state_summary_t::insert (cgraph_node *node, funct_state_d *state)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 /* There are some shared nodes, in particular the initializers on
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141 static declarations. We do not need to scan them more than once
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142 since all we would be interested in are the addressof
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 operations. */
111
kono
parents: 67
diff changeset
1144 if (opt_for_fn (node->decl, flag_ipa_pure_const))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1146 funct_state_d *a = analyze_function (node, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1147 new (state) funct_state_d (*a);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1148 free (a);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1149 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1151
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152 /* Called when new clone is inserted to callgraph late. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1154 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1155 funct_state_summary_t::duplicate (cgraph_node *, cgraph_node *,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1156 funct_state_d *src_data,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1157 funct_state_d *dst_data)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1159 new (dst_data) funct_state_d (*src_data);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1161
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162
111
kono
parents: 67
diff changeset
1163 void
kono
parents: 67
diff changeset
1164 pass_ipa_pure_const::
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1165 register_hooks (void)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1166 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1167 if (init_p)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1168 return;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1169
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1170 init_p = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1172 funct_state_summaries = new funct_state_summary_t (symtab);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1173 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1174
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1175
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1176 /* Analyze each function in the cgraph to see if it is locally PURE or
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1177 CONST. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1178
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1179 static void
111
kono
parents: 67
diff changeset
1180 pure_const_generate_summary (void)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1181 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1182 struct cgraph_node *node;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1183
111
kono
parents: 67
diff changeset
1184 pass_ipa_pure_const *pass = static_cast <pass_ipa_pure_const *> (current_pass);
kono
parents: 67
diff changeset
1185 pass->register_hooks ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1186
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1187 /* Process all of the functions.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1188
111
kono
parents: 67
diff changeset
1189 We process AVAIL_INTERPOSABLE functions. We can not use the results
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1190 by default, but the info can be used at LTO with -fwhole-program or
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1191 when function got cloned and the clone is AVAILABLE. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1192
111
kono
parents: 67
diff changeset
1193 FOR_EACH_DEFINED_FUNCTION (node)
kono
parents: 67
diff changeset
1194 if (opt_for_fn (node->decl, flag_ipa_pure_const))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1195 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1196 funct_state_d *a = analyze_function (node, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1197 new (funct_state_summaries->get_create (node)) funct_state_d (*a);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1198 free (a);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1199 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1200 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1201
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1202
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1203 /* Serialize the ipa info for lto. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1204
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1205 static void
111
kono
parents: 67
diff changeset
1206 pure_const_write_summary (void)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1207 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1208 struct cgraph_node *node;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1209 struct lto_simple_output_block *ob
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1210 = lto_create_simple_output_block (LTO_section_ipa_pure_const);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1211 unsigned int count = 0;
111
kono
parents: 67
diff changeset
1212 lto_symtab_encoder_iterator lsei;
kono
parents: 67
diff changeset
1213 lto_symtab_encoder_t encoder;
kono
parents: 67
diff changeset
1214
kono
parents: 67
diff changeset
1215 encoder = lto_get_out_decl_state ()->symtab_node_encoder;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1216
111
kono
parents: 67
diff changeset
1217 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
kono
parents: 67
diff changeset
1218 lsei_next_function_in_partition (&lsei))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1219 {
111
kono
parents: 67
diff changeset
1220 node = lsei_cgraph_node (lsei);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1221 if (node->definition && funct_state_summaries->exists (node))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1222 count++;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1223 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1224
111
kono
parents: 67
diff changeset
1225 streamer_write_uhwi_stream (ob->main_stream, count);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1226
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1227 /* Process all of the functions. */
111
kono
parents: 67
diff changeset
1228 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
kono
parents: 67
diff changeset
1229 lsei_next_function_in_partition (&lsei))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1230 {
111
kono
parents: 67
diff changeset
1231 node = lsei_cgraph_node (lsei);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1232 funct_state_d *fs = funct_state_summaries->get (node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1233 if (node->definition && fs != NULL)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1234 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1235 struct bitpack_d bp;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1236 int node_ref;
111
kono
parents: 67
diff changeset
1237 lto_symtab_encoder_t encoder;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1238
111
kono
parents: 67
diff changeset
1239 encoder = ob->decl_state->symtab_node_encoder;
kono
parents: 67
diff changeset
1240 node_ref = lto_symtab_encoder_encode (encoder, node);
kono
parents: 67
diff changeset
1241 streamer_write_uhwi_stream (ob->main_stream, node_ref);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1242
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1243 /* Note that flags will need to be read in the opposite
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1244 order as we are pushing the bitflags into FLAGS. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1245 bp = bitpack_create (ob->main_stream);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1246 bp_pack_value (&bp, fs->pure_const_state, 2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1247 bp_pack_value (&bp, fs->state_previously_known, 2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1248 bp_pack_value (&bp, fs->looping_previously_known, 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1249 bp_pack_value (&bp, fs->looping, 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1250 bp_pack_value (&bp, fs->can_throw, 1);
111
kono
parents: 67
diff changeset
1251 bp_pack_value (&bp, fs->can_free, 1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1252 bp_pack_value (&bp, fs->malloc_state, 2);
111
kono
parents: 67
diff changeset
1253 streamer_write_bitpack (&bp);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1254 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1255 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1256
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1257 lto_destroy_simple_output_block (ob);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1258 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1259
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1260
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1261 /* Deserialize the ipa info for lto. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1262
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1263 static void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1264 pure_const_read_summary (void)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1265 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1266 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1267 struct lto_file_decl_data *file_data;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1268 unsigned int j = 0;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1269
111
kono
parents: 67
diff changeset
1270 pass_ipa_pure_const *pass = static_cast <pass_ipa_pure_const *> (current_pass);
kono
parents: 67
diff changeset
1271 pass->register_hooks ();
kono
parents: 67
diff changeset
1272
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1273 while ((file_data = file_data_vec[j++]))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1274 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1275 const char *data;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1276 size_t len;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1277 struct lto_input_block *ib
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1278 = lto_create_simple_input_block (file_data,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1279 LTO_section_ipa_pure_const,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1280 &data, &len);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1281 if (ib)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1282 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1283 unsigned int i;
111
kono
parents: 67
diff changeset
1284 unsigned int count = streamer_read_uhwi (ib);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1285
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1286 for (i = 0; i < count; i++)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1287 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1288 unsigned int index;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1289 struct cgraph_node *node;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1290 struct bitpack_d bp;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1291 funct_state fs;
111
kono
parents: 67
diff changeset
1292 lto_symtab_encoder_t encoder;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1293
111
kono
parents: 67
diff changeset
1294 index = streamer_read_uhwi (ib);
kono
parents: 67
diff changeset
1295 encoder = file_data->symtab_node_encoder;
kono
parents: 67
diff changeset
1296 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
kono
parents: 67
diff changeset
1297 index));
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1298
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1299 fs = funct_state_summaries->get_create (node);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1300 /* Note that the flags must be read in the opposite
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1301 order in which they were written (the bitflags were
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1302 pushed into FLAGS). */
111
kono
parents: 67
diff changeset
1303 bp = streamer_read_bitpack (ib);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1304 fs->pure_const_state
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1305 = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1306 fs->state_previously_known
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1307 = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1308 fs->looping_previously_known = bp_unpack_value (&bp, 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1309 fs->looping = bp_unpack_value (&bp, 1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1310 fs->can_throw = bp_unpack_value (&bp, 1);
111
kono
parents: 67
diff changeset
1311 fs->can_free = bp_unpack_value (&bp, 1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1312 fs->malloc_state
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1313 = (enum malloc_state_e) bp_unpack_value (&bp, 2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1314
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1315 if (dump_file)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1316 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1317 int flags = flags_from_decl_or_type (node->decl);
111
kono
parents: 67
diff changeset
1318 fprintf (dump_file, "Read info for %s ", node->dump_name ());
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1319 if (flags & ECF_CONST)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1320 fprintf (dump_file, " const");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1321 if (flags & ECF_PURE)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1322 fprintf (dump_file, " pure");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1323 if (flags & ECF_NOTHROW)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1324 fprintf (dump_file, " nothrow");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1325 fprintf (dump_file, "\n pure const state: %s\n",
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1326 pure_const_names[fs->pure_const_state]);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1327 fprintf (dump_file, " previously known state: %s\n",
111
kono
parents: 67
diff changeset
1328 pure_const_names[fs->state_previously_known]);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1329 if (fs->looping)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1330 fprintf (dump_file," function is locally looping\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1331 if (fs->looping_previously_known)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1332 fprintf (dump_file," function is previously known looping\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1333 if (fs->can_throw)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1334 fprintf (dump_file," function is locally throwing\n");
111
kono
parents: 67
diff changeset
1335 if (fs->can_free)
kono
parents: 67
diff changeset
1336 fprintf (dump_file," function can locally free\n");
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1337 fprintf (dump_file, "\n malloc state: %s\n",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1338 malloc_state_names[fs->malloc_state]);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1339 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1340 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1341
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1342 lto_destroy_simple_input_block (file_data,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1343 LTO_section_ipa_pure_const,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1344 ib, data, len);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1345 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1346 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1347 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1348
111
kono
parents: 67
diff changeset
1349 /* We only propagate across edges that can throw externally and their callee
kono
parents: 67
diff changeset
1350 is not interposable. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1351
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1352 static bool
111
kono
parents: 67
diff changeset
1353 ignore_edge_for_nothrow (struct cgraph_edge *e)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1354 {
111
kono
parents: 67
diff changeset
1355 if (!e->can_throw_external || TREE_NOTHROW (e->callee->decl))
kono
parents: 67
diff changeset
1356 return true;
kono
parents: 67
diff changeset
1357
kono
parents: 67
diff changeset
1358 enum availability avail;
kono
parents: 67
diff changeset
1359 cgraph_node *n = e->callee->function_or_virtual_thunk_symbol (&avail,
kono
parents: 67
diff changeset
1360 e->caller);
kono
parents: 67
diff changeset
1361 if (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (n->decl))
kono
parents: 67
diff changeset
1362 return true;
kono
parents: 67
diff changeset
1363 return opt_for_fn (e->callee->decl, flag_non_call_exceptions)
kono
parents: 67
diff changeset
1364 && !e->callee->binds_to_current_def_p (e->caller);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1365 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1366
111
kono
parents: 67
diff changeset
1367 /* Return true if NODE is self recursive function.
kono
parents: 67
diff changeset
1368 Indirectly recursive functions appears as non-trivial strongly
kono
parents: 67
diff changeset
1369 connected components, so we need to care about self recursion
kono
parents: 67
diff changeset
1370 only. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1371
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1372 static bool
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1373 self_recursive_p (struct cgraph_node *node)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1374 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1375 struct cgraph_edge *e;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1376 for (e = node->callees; e; e = e->next_callee)
111
kono
parents: 67
diff changeset
1377 if (e->callee->function_symbol () == node)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1378 return true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1379 return false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1380 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1381
111
kono
parents: 67
diff changeset
1382 /* Return true if N is cdtor that is not const or pure. In this case we may
kono
parents: 67
diff changeset
1383 need to remove unreachable function if it is marked const/pure. */
kono
parents: 67
diff changeset
1384
kono
parents: 67
diff changeset
1385 static bool
kono
parents: 67
diff changeset
1386 cdtor_p (cgraph_node *n, void *)
kono
parents: 67
diff changeset
1387 {
kono
parents: 67
diff changeset
1388 if (DECL_STATIC_CONSTRUCTOR (n->decl) || DECL_STATIC_DESTRUCTOR (n->decl))
kono
parents: 67
diff changeset
1389 return ((!TREE_READONLY (n->decl) && !DECL_PURE_P (n->decl))
kono
parents: 67
diff changeset
1390 || DECL_LOOPING_CONST_OR_PURE_P (n->decl));
kono
parents: 67
diff changeset
1391 return false;
kono
parents: 67
diff changeset
1392 }
kono
parents: 67
diff changeset
1393
kono
parents: 67
diff changeset
1394 /* We only propagate across edges with non-interposable callee. */
kono
parents: 67
diff changeset
1395
kono
parents: 67
diff changeset
1396 static bool
kono
parents: 67
diff changeset
1397 ignore_edge_for_pure_const (struct cgraph_edge *e)
kono
parents: 67
diff changeset
1398 {
kono
parents: 67
diff changeset
1399 enum availability avail;
kono
parents: 67
diff changeset
1400 e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
kono
parents: 67
diff changeset
1401 return (avail <= AVAIL_INTERPOSABLE);
kono
parents: 67
diff changeset
1402 }
kono
parents: 67
diff changeset
1403
kono
parents: 67
diff changeset
1404
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1405 /* Produce transitive closure over the callgraph and compute pure/const
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1406 attributes. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1407
111
kono
parents: 67
diff changeset
1408 static bool
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1409 propagate_pure_const (void)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1410 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1411 struct cgraph_node *node;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1412 struct cgraph_node *w;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1413 struct cgraph_node **order =
111
kono
parents: 67
diff changeset
1414 XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1415 int order_pos;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1416 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1417 struct ipa_dfs_info * w_info;
111
kono
parents: 67
diff changeset
1418 bool remove_p = false;
kono
parents: 67
diff changeset
1419 bool has_cdtor;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1420
111
kono
parents: 67
diff changeset
1421 order_pos = ipa_reduced_postorder (order, true, false,
kono
parents: 67
diff changeset
1422 ignore_edge_for_pure_const);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1423 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1424 {
111
kono
parents: 67
diff changeset
1425 cgraph_node::dump_cgraph (dump_file);
kono
parents: 67
diff changeset
1426 ipa_print_order (dump_file, "reduced", order, order_pos);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1427 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428
111
kono
parents: 67
diff changeset
1429 /* Propagate the local information through the call graph to produce
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430 the global information. All the nodes within a cycle will have
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1431 the same info so we collapse cycles first. Then we can do the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1432 propagation in one pass from the leaves to the roots. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 for (i = 0; i < order_pos; i++ )
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1434 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435 enum pure_const_state_e pure_const_state = IPA_CONST;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1436 bool looping = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437 int count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438 node = order[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1439
111
kono
parents: 67
diff changeset
1440 if (node->alias)
kono
parents: 67
diff changeset
1441 continue;
kono
parents: 67
diff changeset
1442
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1443 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1444 fprintf (dump_file, "Starting cycle\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1445
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1446 /* Find the worst state for any node in the cycle. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1447 w = node;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1448 while (w && pure_const_state != IPA_NEITHER)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1449 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1450 struct cgraph_edge *e;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1451 struct cgraph_edge *ie;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1452 int i;
111
kono
parents: 67
diff changeset
1453 struct ipa_ref *ref = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1454
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1455 funct_state w_l = funct_state_summaries->get_create (w);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1456 if (dump_file && (dump_flags & TDF_DETAILS))
111
kono
parents: 67
diff changeset
1457 fprintf (dump_file, " Visiting %s state:%s looping %i\n",
kono
parents: 67
diff changeset
1458 w->dump_name (),
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1459 pure_const_names[w_l->pure_const_state],
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1460 w_l->looping);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1461
111
kono
parents: 67
diff changeset
1462 /* First merge in function body properties.
kono
parents: 67
diff changeset
1463 We are safe to pass NULL as FROM and TO because we will take care
kono
parents: 67
diff changeset
1464 of possible interposition when walking callees. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1465 worse_state (&pure_const_state, &looping,
111
kono
parents: 67
diff changeset
1466 w_l->pure_const_state, w_l->looping,
kono
parents: 67
diff changeset
1467 NULL, NULL);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1468 if (pure_const_state == IPA_NEITHER)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1471 count++;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1472
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1473 /* We consider recursive cycles as possibly infinite.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1474 This might be relaxed since infinite recursion leads to stack
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1475 overflow. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1476 if (count > 1)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1477 looping = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1479 /* Now walk the edges and merge in callee properties. */
111
kono
parents: 67
diff changeset
1480 for (e = w->callees; e && pure_const_state != IPA_NEITHER;
kono
parents: 67
diff changeset
1481 e = e->next_callee)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1482 {
111
kono
parents: 67
diff changeset
1483 enum availability avail;
kono
parents: 67
diff changeset
1484 struct cgraph_node *y = e->callee->
kono
parents: 67
diff changeset
1485 function_or_virtual_thunk_symbol (&avail,
kono
parents: 67
diff changeset
1486 e->caller);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1487 enum pure_const_state_e edge_state = IPA_CONST;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1488 bool edge_looping = false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1489
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1490 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1491 {
111
kono
parents: 67
diff changeset
1492 fprintf (dump_file, " Call to %s",
kono
parents: 67
diff changeset
1493 e->callee->dump_name ());
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1494 }
111
kono
parents: 67
diff changeset
1495 if (avail > AVAIL_INTERPOSABLE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1496 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1497 funct_state y_l = funct_state_summaries->get (y);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1498 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1499 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1500 fprintf (dump_file,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1501 " state:%s looping:%i\n",
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1502 pure_const_names[y_l->pure_const_state],
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1503 y_l->looping);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1504 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1505 if (y_l->pure_const_state > IPA_PURE
111
kono
parents: 67
diff changeset
1506 && e->cannot_lead_to_return_p ())
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1507 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1508 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1509 fprintf (dump_file,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1510 " Ignoring side effects"
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1511 " -> pure, looping\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1512 edge_state = IPA_PURE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1513 edge_looping = true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1514 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1515 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1516 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1517 edge_state = y_l->pure_const_state;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1518 edge_looping = y_l->looping;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1519 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1520 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1521 else if (special_builtin_state (&edge_state, &edge_looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1522 y->decl))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1523 ;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1524 else
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1525 state_from_flags (&edge_state, &edge_looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1526 flags_from_decl_or_type (y->decl),
111
kono
parents: 67
diff changeset
1527 e->cannot_lead_to_return_p ());
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1528
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1529 /* Merge the results with what we already know. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1530 better_state (&edge_state, &edge_looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1531 w_l->state_previously_known,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1532 w_l->looping_previously_known);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1533 worse_state (&pure_const_state, &looping,
111
kono
parents: 67
diff changeset
1534 edge_state, edge_looping, e->caller, e->callee);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1535 if (pure_const_state == IPA_NEITHER)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1536 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1537 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1538
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1539 /* Now process the indirect call. */
111
kono
parents: 67
diff changeset
1540 for (ie = w->indirect_calls;
kono
parents: 67
diff changeset
1541 ie && pure_const_state != IPA_NEITHER; ie = ie->next_callee)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1542 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1543 enum pure_const_state_e edge_state = IPA_CONST;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1544 bool edge_looping = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1545
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1546 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1547 fprintf (dump_file, " Indirect call");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1548 state_from_flags (&edge_state, &edge_looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1549 ie->indirect_info->ecf_flags,
111
kono
parents: 67
diff changeset
1550 ie->cannot_lead_to_return_p ());
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1551 /* Merge the results with what we already know. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1552 better_state (&edge_state, &edge_looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1553 w_l->state_previously_known,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1554 w_l->looping_previously_known);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1555 worse_state (&pure_const_state, &looping,
111
kono
parents: 67
diff changeset
1556 edge_state, edge_looping, NULL, NULL);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1557 if (pure_const_state == IPA_NEITHER)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1558 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1559 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1560
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1561 /* And finally all loads and stores. */
111
kono
parents: 67
diff changeset
1562 for (i = 0; w->iterate_reference (i, ref)
kono
parents: 67
diff changeset
1563 && pure_const_state != IPA_NEITHER; i++)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1564 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1565 enum pure_const_state_e ref_state = IPA_CONST;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1566 bool ref_looping = false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1567 switch (ref->use)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1568 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1569 case IPA_REF_LOAD:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1570 /* readonly reads are safe. */
111
kono
parents: 67
diff changeset
1571 if (TREE_READONLY (ref->referred->decl))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1572 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1573 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1574 fprintf (dump_file, " nonreadonly global var read\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1575 ref_state = IPA_PURE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1576 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1577 case IPA_REF_STORE:
111
kono
parents: 67
diff changeset
1578 if (ref->cannot_lead_to_return ())
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1579 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1580 ref_state = IPA_NEITHER;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1581 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1582 fprintf (dump_file, " global var write\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1583 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1584 case IPA_REF_ADDR:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1585 break;
111
kono
parents: 67
diff changeset
1586 default:
kono
parents: 67
diff changeset
1587 gcc_unreachable ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1588 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1589 better_state (&ref_state, &ref_looping,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1590 w_l->state_previously_known,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1591 w_l->looping_previously_known);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1592 worse_state (&pure_const_state, &looping,
111
kono
parents: 67
diff changeset
1593 ref_state, ref_looping, NULL, NULL);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1594 if (pure_const_state == IPA_NEITHER)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1595 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1596 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1597 w_info = (struct ipa_dfs_info *) w->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 w = w_info->next_cycle;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1599 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1600 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1601 fprintf (dump_file, "Result %s looping %i\n",
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1602 pure_const_names [pure_const_state],
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1603 looping);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1604
111
kono
parents: 67
diff changeset
1605 /* Find the worst state of can_free for any node in the cycle. */
kono
parents: 67
diff changeset
1606 bool can_free = false;
kono
parents: 67
diff changeset
1607 w = node;
kono
parents: 67
diff changeset
1608 while (w && !can_free)
kono
parents: 67
diff changeset
1609 {
kono
parents: 67
diff changeset
1610 struct cgraph_edge *e;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1611 funct_state w_l = funct_state_summaries->get (w);
111
kono
parents: 67
diff changeset
1612
kono
parents: 67
diff changeset
1613 if (w_l->can_free
kono
parents: 67
diff changeset
1614 || w->get_availability () == AVAIL_INTERPOSABLE
kono
parents: 67
diff changeset
1615 || w->indirect_calls)
kono
parents: 67
diff changeset
1616 can_free = true;
kono
parents: 67
diff changeset
1617
kono
parents: 67
diff changeset
1618 for (e = w->callees; e && !can_free; e = e->next_callee)
kono
parents: 67
diff changeset
1619 {
kono
parents: 67
diff changeset
1620 enum availability avail;
kono
parents: 67
diff changeset
1621 struct cgraph_node *y = e->callee->
kono
parents: 67
diff changeset
1622 function_or_virtual_thunk_symbol (&avail,
kono
parents: 67
diff changeset
1623 e->caller);
kono
parents: 67
diff changeset
1624
kono
parents: 67
diff changeset
1625 if (avail > AVAIL_INTERPOSABLE)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1626 can_free = funct_state_summaries->get (y)->can_free;
111
kono
parents: 67
diff changeset
1627 else
kono
parents: 67
diff changeset
1628 can_free = true;
kono
parents: 67
diff changeset
1629 }
kono
parents: 67
diff changeset
1630 w_info = (struct ipa_dfs_info *) w->aux;
kono
parents: 67
diff changeset
1631 w = w_info->next_cycle;
kono
parents: 67
diff changeset
1632 }
kono
parents: 67
diff changeset
1633
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1634 /* Copy back the region's pure_const_state which is shared by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1635 all nodes in the region. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1636 w = node;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1637 while (w)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1638 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1639 funct_state w_l = funct_state_summaries->get (w);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1640 enum pure_const_state_e this_state = pure_const_state;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1641 bool this_looping = looping;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1642
111
kono
parents: 67
diff changeset
1643 w_l->can_free = can_free;
kono
parents: 67
diff changeset
1644 w->nonfreeing_fn = !can_free;
kono
parents: 67
diff changeset
1645 if (!can_free && dump_file)
kono
parents: 67
diff changeset
1646 fprintf (dump_file, "Function found not to call free: %s\n",
kono
parents: 67
diff changeset
1647 w->name ());
kono
parents: 67
diff changeset
1648
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1649 if (w_l->state_previously_known != IPA_NEITHER
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1650 && this_state > w_l->state_previously_known)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1651 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1652 this_state = w_l->state_previously_known;
111
kono
parents: 67
diff changeset
1653 if (this_state == IPA_NEITHER)
kono
parents: 67
diff changeset
1654 this_looping = w_l->looping_previously_known;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1655 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1656 if (!this_looping && self_recursive_p (w))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1657 this_looping = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1658 if (!w_l->looping_previously_known)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1659 this_looping = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1660
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1661 /* All nodes within a cycle share the same info. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1662 w_l->pure_const_state = this_state;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1663 w_l->looping = this_looping;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1664
111
kono
parents: 67
diff changeset
1665 /* Inline clones share declaration with their offline copies;
kono
parents: 67
diff changeset
1666 do not modify their declarations since the offline copy may
kono
parents: 67
diff changeset
1667 be different. */
kono
parents: 67
diff changeset
1668 if (!w->global.inlined_to)
kono
parents: 67
diff changeset
1669 switch (this_state)
kono
parents: 67
diff changeset
1670 {
kono
parents: 67
diff changeset
1671 case IPA_CONST:
kono
parents: 67
diff changeset
1672 if (!TREE_READONLY (w->decl))
kono
parents: 67
diff changeset
1673 {
kono
parents: 67
diff changeset
1674 warn_function_const (w->decl, !this_looping);
kono
parents: 67
diff changeset
1675 if (dump_file)
kono
parents: 67
diff changeset
1676 fprintf (dump_file, "Function found to be %sconst: %s\n",
kono
parents: 67
diff changeset
1677 this_looping ? "looping " : "",
kono
parents: 67
diff changeset
1678 w->name ());
kono
parents: 67
diff changeset
1679 }
kono
parents: 67
diff changeset
1680 /* Turning constructor or destructor to non-looping const/pure
kono
parents: 67
diff changeset
1681 enables us to possibly remove the function completely. */
kono
parents: 67
diff changeset
1682 if (this_looping)
kono
parents: 67
diff changeset
1683 has_cdtor = false;
kono
parents: 67
diff changeset
1684 else
kono
parents: 67
diff changeset
1685 has_cdtor = w->call_for_symbol_and_aliases (cdtor_p,
kono
parents: 67
diff changeset
1686 NULL, true);
kono
parents: 67
diff changeset
1687 if (w->set_const_flag (true, this_looping))
kono
parents: 67
diff changeset
1688 {
kono
parents: 67
diff changeset
1689 if (dump_file)
kono
parents: 67
diff changeset
1690 fprintf (dump_file,
kono
parents: 67
diff changeset
1691 "Declaration updated to be %sconst: %s\n",
kono
parents: 67
diff changeset
1692 this_looping ? "looping " : "",
kono
parents: 67
diff changeset
1693 w->name ());
kono
parents: 67
diff changeset
1694 remove_p |= has_cdtor;
kono
parents: 67
diff changeset
1695 }
kono
parents: 67
diff changeset
1696 break;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1697
111
kono
parents: 67
diff changeset
1698 case IPA_PURE:
kono
parents: 67
diff changeset
1699 if (!DECL_PURE_P (w->decl))
kono
parents: 67
diff changeset
1700 {
kono
parents: 67
diff changeset
1701 warn_function_pure (w->decl, !this_looping);
kono
parents: 67
diff changeset
1702 if (dump_file)
kono
parents: 67
diff changeset
1703 fprintf (dump_file, "Function found to be %spure: %s\n",
kono
parents: 67
diff changeset
1704 this_looping ? "looping " : "",
kono
parents: 67
diff changeset
1705 w->name ());
kono
parents: 67
diff changeset
1706 }
kono
parents: 67
diff changeset
1707 if (this_looping)
kono
parents: 67
diff changeset
1708 has_cdtor = false;
kono
parents: 67
diff changeset
1709 else
kono
parents: 67
diff changeset
1710 has_cdtor = w->call_for_symbol_and_aliases (cdtor_p,
kono
parents: 67
diff changeset
1711 NULL, true);
kono
parents: 67
diff changeset
1712 if (w->set_pure_flag (true, this_looping))
kono
parents: 67
diff changeset
1713 {
kono
parents: 67
diff changeset
1714 if (dump_file)
kono
parents: 67
diff changeset
1715 fprintf (dump_file,
kono
parents: 67
diff changeset
1716 "Declaration updated to be %spure: %s\n",
kono
parents: 67
diff changeset
1717 this_looping ? "looping " : "",
kono
parents: 67
diff changeset
1718 w->name ());
kono
parents: 67
diff changeset
1719 remove_p |= has_cdtor;
kono
parents: 67
diff changeset
1720 }
kono
parents: 67
diff changeset
1721 break;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1722
111
kono
parents: 67
diff changeset
1723 default:
kono
parents: 67
diff changeset
1724 break;
kono
parents: 67
diff changeset
1725 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1726 w_info = (struct ipa_dfs_info *) w->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1727 w = w_info->next_cycle;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1728 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1729 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1730
111
kono
parents: 67
diff changeset
1731 ipa_free_postorder_info ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1732 free (order);
111
kono
parents: 67
diff changeset
1733 return remove_p;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1734 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1735
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1736 /* Produce transitive closure over the callgraph and compute nothrow
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1737 attributes. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1738
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1739 static void
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1740 propagate_nothrow (void)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1741 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1742 struct cgraph_node *node;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1743 struct cgraph_node *w;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1744 struct cgraph_node **order =
111
kono
parents: 67
diff changeset
1745 XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1746 int order_pos;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1747 int i;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1748 struct ipa_dfs_info * w_info;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1749
111
kono
parents: 67
diff changeset
1750 order_pos = ipa_reduced_postorder (order, true, false,
kono
parents: 67
diff changeset
1751 ignore_edge_for_nothrow);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1752 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1753 {
111
kono
parents: 67
diff changeset
1754 cgraph_node::dump_cgraph (dump_file);
kono
parents: 67
diff changeset
1755 ipa_print_order (dump_file, "reduced for nothrow", order, order_pos);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1756 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1757
111
kono
parents: 67
diff changeset
1758 /* Propagate the local information through the call graph to produce
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1759 the global information. All the nodes within a cycle will have
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1760 the same info so we collapse cycles first. Then we can do the
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1761 propagation in one pass from the leaves to the roots. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1762 for (i = 0; i < order_pos; i++ )
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1763 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1764 bool can_throw = false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1765 node = order[i];
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1766
111
kono
parents: 67
diff changeset
1767 if (node->alias)
kono
parents: 67
diff changeset
1768 continue;
kono
parents: 67
diff changeset
1769
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1770 /* Find the worst state for any node in the cycle. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1771 w = node;
111
kono
parents: 67
diff changeset
1772 while (w && !can_throw)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1773 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1774 struct cgraph_edge *e, *ie;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1775
111
kono
parents: 67
diff changeset
1776 if (!TREE_NOTHROW (w->decl))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1777 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1778 funct_state w_l = funct_state_summaries->get_create (w);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1779
111
kono
parents: 67
diff changeset
1780 if (w_l->can_throw
kono
parents: 67
diff changeset
1781 || w->get_availability () == AVAIL_INTERPOSABLE)
kono
parents: 67
diff changeset
1782 can_throw = true;
kono
parents: 67
diff changeset
1783
kono
parents: 67
diff changeset
1784 for (e = w->callees; e && !can_throw; e = e->next_callee)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1785 {
111
kono
parents: 67
diff changeset
1786 enum availability avail;
kono
parents: 67
diff changeset
1787
kono
parents: 67
diff changeset
1788 if (!e->can_throw_external || TREE_NOTHROW (e->callee->decl))
kono
parents: 67
diff changeset
1789 continue;
kono
parents: 67
diff changeset
1790
kono
parents: 67
diff changeset
1791 struct cgraph_node *y = e->callee->
kono
parents: 67
diff changeset
1792 function_or_virtual_thunk_symbol (&avail,
kono
parents: 67
diff changeset
1793 e->caller);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1794
111
kono
parents: 67
diff changeset
1795 /* We can use info about the callee only if we know it can
kono
parents: 67
diff changeset
1796 not be interposed.
kono
parents: 67
diff changeset
1797 When callee is compiled with non-call exceptions we also
kono
parents: 67
diff changeset
1798 must check that the declaration is bound to current
kono
parents: 67
diff changeset
1799 body as other semantically equivalent body may still
kono
parents: 67
diff changeset
1800 throw. */
kono
parents: 67
diff changeset
1801 if (avail <= AVAIL_INTERPOSABLE
kono
parents: 67
diff changeset
1802 || (!TREE_NOTHROW (y->decl)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1803 && (funct_state_summaries->get_create (y)->can_throw
111
kono
parents: 67
diff changeset
1804 || (opt_for_fn (y->decl, flag_non_call_exceptions)
kono
parents: 67
diff changeset
1805 && !e->callee->binds_to_current_def_p (w)))))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1806 can_throw = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1807 }
111
kono
parents: 67
diff changeset
1808 for (ie = w->indirect_calls; ie && !can_throw;
kono
parents: 67
diff changeset
1809 ie = ie->next_callee)
kono
parents: 67
diff changeset
1810 if (ie->can_throw_external
kono
parents: 67
diff changeset
1811 && !(ie->indirect_info->ecf_flags & ECF_NOTHROW))
kono
parents: 67
diff changeset
1812 can_throw = true;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1813 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1814 w_info = (struct ipa_dfs_info *) w->aux;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1815 w = w_info->next_cycle;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1816 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1817
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1818 /* Copy back the region's pure_const_state which is shared by
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1819 all nodes in the region. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1820 w = node;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1821 while (w)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1822 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1823 funct_state w_l = funct_state_summaries->get_create (w);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1824 if (!can_throw && !TREE_NOTHROW (w->decl))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1825 {
111
kono
parents: 67
diff changeset
1826 /* Inline clones share declaration with their offline copies;
kono
parents: 67
diff changeset
1827 do not modify their declarations since the offline copy may
kono
parents: 67
diff changeset
1828 be different. */
kono
parents: 67
diff changeset
1829 if (!w->global.inlined_to)
kono
parents: 67
diff changeset
1830 {
kono
parents: 67
diff changeset
1831 w->set_nothrow_flag (true);
kono
parents: 67
diff changeset
1832 if (dump_file)
kono
parents: 67
diff changeset
1833 fprintf (dump_file, "Function found to be nothrow: %s\n",
kono
parents: 67
diff changeset
1834 w->name ());
kono
parents: 67
diff changeset
1835 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1836 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1837 else if (can_throw && !TREE_NOTHROW (w->decl))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1838 w_l->can_throw = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1839 w_info = (struct ipa_dfs_info *) w->aux;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1840 w = w_info->next_cycle;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1841 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1842 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1843
111
kono
parents: 67
diff changeset
1844 ipa_free_postorder_info ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1845 free (order);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1846 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1847
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1848 /* Debugging function to dump state of malloc lattice. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1849
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1850 DEBUG_FUNCTION
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1851 static void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1852 dump_malloc_lattice (FILE *dump_file, const char *s)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1853 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1854 if (!dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1855 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1856
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1857 fprintf (dump_file, "\n\nMALLOC LATTICE %s:\n", s);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1858 cgraph_node *node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1859 FOR_EACH_FUNCTION (node)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1860 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1861 funct_state fs = funct_state_summaries->get (node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1862 if (fs)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1863 fprintf (dump_file, "%s: %s\n", node->name (),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1864 malloc_state_names[fs->malloc_state]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1865 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1866 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1867
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1868 /* Propagate malloc attribute across the callgraph. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1869
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1870 static void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1871 propagate_malloc (void)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1872 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1873 cgraph_node *node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1874 FOR_EACH_FUNCTION (node)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1875 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1876 if (DECL_IS_MALLOC (node->decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1877 if (!funct_state_summaries->exists (node))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1878 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1879 funct_state fs = funct_state_summaries->get_create (node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1880 fs->malloc_state = STATE_MALLOC;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1881 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1882 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1883
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1884 dump_malloc_lattice (dump_file, "Initial");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1885 struct cgraph_node **order
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1886 = XNEWVEC (struct cgraph_node *, symtab->cgraph_count);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1887 int order_pos = ipa_reverse_postorder (order);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1888 bool changed = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1889
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1890 while (changed)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1891 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1892 changed = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1893 /* Walk in postorder. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1894 for (int i = order_pos - 1; i >= 0; --i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1895 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1896 cgraph_node *node = order[i];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1897 if (node->alias
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1898 || !node->definition
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1899 || !funct_state_summaries->exists (node))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1900 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1901
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1902 funct_state l = funct_state_summaries->get (node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1903
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1904 /* FIXME: add support for indirect-calls. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1905 if (node->indirect_calls)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1906 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1907 l->malloc_state = STATE_MALLOC_BOTTOM;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1908 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1909 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1910
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1911 if (node->get_availability () <= AVAIL_INTERPOSABLE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1912 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1913 l->malloc_state = STATE_MALLOC_BOTTOM;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1914 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1915 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1916
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1917 if (l->malloc_state == STATE_MALLOC_BOTTOM)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1918 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1919
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1920 vec<cgraph_node *> callees = vNULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1921 for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1922 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1923 ipa_call_summary *es = ipa_call_summaries->get_create (cs);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1924 if (es && es->is_return_callee_uncaptured)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1925 callees.safe_push (cs->callee);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1926 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1927
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1928 malloc_state_e new_state = l->malloc_state;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1929 for (unsigned j = 0; j < callees.length (); j++)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1930 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1931 cgraph_node *callee = callees[j];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1932 if (!funct_state_summaries->exists (node))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1933 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1934 new_state = STATE_MALLOC_BOTTOM;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1935 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1936 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1937 malloc_state_e callee_state
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1938 = funct_state_summaries->get_create (callee)->malloc_state;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1939 if (new_state < callee_state)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1940 new_state = callee_state;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1941 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1942 if (new_state != l->malloc_state)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1943 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1944 changed = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1945 l->malloc_state = new_state;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1946 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1947 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1948 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1949
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1950 FOR_EACH_DEFINED_FUNCTION (node)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1951 if (funct_state_summaries->exists (node))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1952 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1953 funct_state l = funct_state_summaries->get (node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1954 if (!node->alias
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1955 && l->malloc_state == STATE_MALLOC
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1956 && !node->global.inlined_to)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1957 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1958 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1959 fprintf (dump_file, "Function %s found to be malloc\n",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1960 node->name ());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1961
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1962 bool malloc_decl_p = DECL_IS_MALLOC (node->decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1963 node->set_malloc_flag (true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1964 if (!malloc_decl_p && warn_suggest_attribute_malloc)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1965 warn_function_malloc (node->decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1966 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1967 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1968
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1969 dump_malloc_lattice (dump_file, "after propagation");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1970 ipa_free_postorder_info ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1971 free (order);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1972 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1973
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1974 /* Produce the global information by preforming a transitive closure
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1975 on the local information that was produced by generate_summary. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1976
111
kono
parents: 67
diff changeset
1977 unsigned int
kono
parents: 67
diff changeset
1978 pass_ipa_pure_const::
kono
parents: 67
diff changeset
1979 execute (function *)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1980 {
111
kono
parents: 67
diff changeset
1981 bool remove_p;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1982
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1983 /* Nothrow makes more function to not lead to return and improve
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1984 later analysis. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1985 propagate_nothrow ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1986 propagate_malloc ();
111
kono
parents: 67
diff changeset
1987 remove_p = propagate_pure_const ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1988
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1989 delete funct_state_summaries;
111
kono
parents: 67
diff changeset
1990 return remove_p ? TODO_remove_functions : 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1991 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1992
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1993 static bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1994 gate_pure_const (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1995 {
111
kono
parents: 67
diff changeset
1996 return flag_ipa_pure_const || in_lto_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1997 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1998
111
kono
parents: 67
diff changeset
1999 pass_ipa_pure_const::pass_ipa_pure_const(gcc::context *ctxt)
kono
parents: 67
diff changeset
2000 : ipa_opt_pass_d(pass_data_ipa_pure_const, ctxt,
kono
parents: 67
diff changeset
2001 pure_const_generate_summary, /* generate_summary */
kono
parents: 67
diff changeset
2002 pure_const_write_summary, /* write_summary */
kono
parents: 67
diff changeset
2003 pure_const_read_summary, /* read_summary */
kono
parents: 67
diff changeset
2004 NULL, /* write_optimization_summary */
kono
parents: 67
diff changeset
2005 NULL, /* read_optimization_summary */
kono
parents: 67
diff changeset
2006 NULL, /* stmt_fixup */
kono
parents: 67
diff changeset
2007 0, /* function_transform_todo_flags_start */
kono
parents: 67
diff changeset
2008 NULL, /* function_transform */
kono
parents: 67
diff changeset
2009 NULL), /* variable_transform */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2010 init_p (false) {}
111
kono
parents: 67
diff changeset
2011
kono
parents: 67
diff changeset
2012 ipa_opt_pass_d *
kono
parents: 67
diff changeset
2013 make_pass_ipa_pure_const (gcc::context *ctxt)
kono
parents: 67
diff changeset
2014 {
kono
parents: 67
diff changeset
2015 return new pass_ipa_pure_const (ctxt);
kono
parents: 67
diff changeset
2016 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2017
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2018 /* Return true if function should be skipped for local pure const analysis. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2019
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2020 static bool
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2021 skip_function_for_local_pure_const (struct cgraph_node *node)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2022 {
111
kono
parents: 67
diff changeset
2023 /* Because we do not schedule pass_fixup_cfg over whole program after early
kono
parents: 67
diff changeset
2024 optimizations we must not promote functions that are called by already
kono
parents: 67
diff changeset
2025 processed functions. */
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2026
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2027 if (function_called_by_processed_nodes_p ())
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2028 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2029 if (dump_file)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2030 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2031 return true;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2032 }
111
kono
parents: 67
diff changeset
2033 /* Save some work and do not analyze functions which are interposable and
kono
parents: 67
diff changeset
2034 do not have any non-interposable aliases. */
kono
parents: 67
diff changeset
2035 if (node->get_availability () <= AVAIL_INTERPOSABLE
kono
parents: 67
diff changeset
2036 && !node->has_aliases_p ())
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2037 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2038 if (dump_file)
111
kono
parents: 67
diff changeset
2039 fprintf (dump_file,
kono
parents: 67
diff changeset
2040 "Function is interposable; not analyzing.\n");
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2041 return true;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2042 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2043 return false;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2044 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2045
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2046 /* Simple local pass for pure const discovery reusing the analysis from
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2047 ipa_pure_const. This pass is effective when executed together with
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2048 other optimization passes in early optimization pass queue. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2049
111
kono
parents: 67
diff changeset
2050 namespace {
kono
parents: 67
diff changeset
2051
kono
parents: 67
diff changeset
2052 const pass_data pass_data_local_pure_const =
kono
parents: 67
diff changeset
2053 {
kono
parents: 67
diff changeset
2054 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
2055 "local-pure-const", /* name */
kono
parents: 67
diff changeset
2056 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
2057 TV_IPA_PURE_CONST, /* tv_id */
kono
parents: 67
diff changeset
2058 0, /* properties_required */
kono
parents: 67
diff changeset
2059 0, /* properties_provided */
kono
parents: 67
diff changeset
2060 0, /* properties_destroyed */
kono
parents: 67
diff changeset
2061 0, /* todo_flags_start */
kono
parents: 67
diff changeset
2062 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
2063 };
kono
parents: 67
diff changeset
2064
kono
parents: 67
diff changeset
2065 class pass_local_pure_const : public gimple_opt_pass
kono
parents: 67
diff changeset
2066 {
kono
parents: 67
diff changeset
2067 public:
kono
parents: 67
diff changeset
2068 pass_local_pure_const (gcc::context *ctxt)
kono
parents: 67
diff changeset
2069 : gimple_opt_pass (pass_data_local_pure_const, ctxt)
kono
parents: 67
diff changeset
2070 {}
kono
parents: 67
diff changeset
2071
kono
parents: 67
diff changeset
2072 /* opt_pass methods: */
kono
parents: 67
diff changeset
2073 opt_pass * clone () { return new pass_local_pure_const (m_ctxt); }
kono
parents: 67
diff changeset
2074 virtual bool gate (function *) { return gate_pure_const (); }
kono
parents: 67
diff changeset
2075 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
2076
kono
parents: 67
diff changeset
2077 }; // class pass_local_pure_const
kono
parents: 67
diff changeset
2078
kono
parents: 67
diff changeset
2079 unsigned int
kono
parents: 67
diff changeset
2080 pass_local_pure_const::execute (function *fun)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2081 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2082 bool changed = false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2083 funct_state l;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2084 bool skip;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2085 struct cgraph_node *node;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2086
111
kono
parents: 67
diff changeset
2087 node = cgraph_node::get (current_function_decl);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2088 skip = skip_function_for_local_pure_const (node);
111
kono
parents: 67
diff changeset
2089
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2090 if (!warn_suggest_attribute_const
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2091 && !warn_suggest_attribute_pure
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2092 && skip)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2093 return 0;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2094
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2095 l = analyze_function (node, false);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2096
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2097 /* Do NORETURN discovery. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2098 if (!skip && !TREE_THIS_VOLATILE (current_function_decl)
111
kono
parents: 67
diff changeset
2099 && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) == 0)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2100 {
111
kono
parents: 67
diff changeset
2101 warn_function_noreturn (fun->decl);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2102 if (dump_file)
111
kono
parents: 67
diff changeset
2103 fprintf (dump_file, "Function found to be noreturn: %s\n",
kono
parents: 67
diff changeset
2104 current_function_name ());
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2105
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2106 /* Update declaration and reduce profile to executed once. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2107 TREE_THIS_VOLATILE (current_function_decl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2108 if (node->frequency > NODE_FREQUENCY_EXECUTED_ONCE)
111
kono
parents: 67
diff changeset
2109 node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2110
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2111 changed = true;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2112 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
2113
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2114 switch (l->pure_const_state)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2115 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2116 case IPA_CONST:
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2117 if (!TREE_READONLY (current_function_decl))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2118 {
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2119 warn_function_const (current_function_decl, !l->looping);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2120 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2121 fprintf (dump_file, "Function found to be %sconst: %s\n",
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2122 l->looping ? "looping " : "",
111
kono
parents: 67
diff changeset
2123 current_function_name ());
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2124 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2125 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2126 && !l->looping)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2127 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2128 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2129 fprintf (dump_file, "Function found to be non-looping: %s\n",
111
kono
parents: 67
diff changeset
2130 current_function_name ());
kono
parents: 67
diff changeset
2131 }
kono
parents: 67
diff changeset
2132 if (!skip && node->set_const_flag (true, l->looping))
kono
parents: 67
diff changeset
2133 {
kono
parents: 67
diff changeset
2134 if (dump_file)
kono
parents: 67
diff changeset
2135 fprintf (dump_file, "Declaration updated to be %sconst: %s\n",
kono
parents: 67
diff changeset
2136 l->looping ? "looping " : "",
kono
parents: 67
diff changeset
2137 current_function_name ());
kono
parents: 67
diff changeset
2138 changed = true;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2139 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2140 break;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2141
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2142 case IPA_PURE:
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2143 if (!DECL_PURE_P (current_function_decl))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2144 {
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
2145 warn_function_pure (current_function_decl, !l->looping);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2146 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2147 fprintf (dump_file, "Function found to be %spure: %s\n",
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2148 l->looping ? "looping " : "",
111
kono
parents: 67
diff changeset
2149 current_function_name ());
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2150 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2151 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2152 && !l->looping)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2153 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2154 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2155 fprintf (dump_file, "Function found to be non-looping: %s\n",
111
kono
parents: 67
diff changeset
2156 current_function_name ());
kono
parents: 67
diff changeset
2157 }
kono
parents: 67
diff changeset
2158 if (!skip && node->set_pure_flag (true, l->looping))
kono
parents: 67
diff changeset
2159 {
kono
parents: 67
diff changeset
2160 if (dump_file)
kono
parents: 67
diff changeset
2161 fprintf (dump_file, "Declaration updated to be %spure: %s\n",
kono
parents: 67
diff changeset
2162 l->looping ? "looping " : "",
kono
parents: 67
diff changeset
2163 current_function_name ());
kono
parents: 67
diff changeset
2164 changed = true;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2165 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2166 break;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2167
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2168 default:
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2169 break;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2170 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2171 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2172 {
111
kono
parents: 67
diff changeset
2173 node->set_nothrow_flag (true);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2174 changed = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2175 if (dump_file)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2176 fprintf (dump_file, "Function found to be nothrow: %s\n",
111
kono
parents: 67
diff changeset
2177 current_function_name ());
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2178 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2179
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2180 if (l->malloc_state == STATE_MALLOC
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2181 && !DECL_IS_MALLOC (current_function_decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2182 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2183 node->set_malloc_flag (true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2184 if (warn_suggest_attribute_malloc)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2185 warn_function_malloc (node->decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2186 changed = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2187 if (dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2188 fprintf (dump_file, "Function found to be malloc: %s\n",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2189 node->name ());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2190 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2191
111
kono
parents: 67
diff changeset
2192 free (l);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2193 if (changed)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2194 return execute_fixup_cfg ();
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2195 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2196 return 0;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2197 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2198
111
kono
parents: 67
diff changeset
2199 } // anon namespace
kono
parents: 67
diff changeset
2200
kono
parents: 67
diff changeset
2201 gimple_opt_pass *
kono
parents: 67
diff changeset
2202 make_pass_local_pure_const (gcc::context *ctxt)
kono
parents: 67
diff changeset
2203 {
kono
parents: 67
diff changeset
2204 return new pass_local_pure_const (ctxt);
kono
parents: 67
diff changeset
2205 }
kono
parents: 67
diff changeset
2206
kono
parents: 67
diff changeset
2207 /* Emit noreturn warnings. */
kono
parents: 67
diff changeset
2208
kono
parents: 67
diff changeset
2209 namespace {
kono
parents: 67
diff changeset
2210
kono
parents: 67
diff changeset
2211 const pass_data pass_data_warn_function_noreturn =
kono
parents: 67
diff changeset
2212 {
kono
parents: 67
diff changeset
2213 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
2214 "*warn_function_noreturn", /* name */
kono
parents: 67
diff changeset
2215 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
2216 TV_NONE, /* tv_id */
kono
parents: 67
diff changeset
2217 PROP_cfg, /* properties_required */
kono
parents: 67
diff changeset
2218 0, /* properties_provided */
kono
parents: 67
diff changeset
2219 0, /* properties_destroyed */
kono
parents: 67
diff changeset
2220 0, /* todo_flags_start */
kono
parents: 67
diff changeset
2221 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
2222 };
kono
parents: 67
diff changeset
2223
kono
parents: 67
diff changeset
2224 class pass_warn_function_noreturn : public gimple_opt_pass
kono
parents: 67
diff changeset
2225 {
kono
parents: 67
diff changeset
2226 public:
kono
parents: 67
diff changeset
2227 pass_warn_function_noreturn (gcc::context *ctxt)
kono
parents: 67
diff changeset
2228 : gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
kono
parents: 67
diff changeset
2229 {}
kono
parents: 67
diff changeset
2230
kono
parents: 67
diff changeset
2231 /* opt_pass methods: */
kono
parents: 67
diff changeset
2232 virtual bool gate (function *) { return warn_suggest_attribute_noreturn; }
kono
parents: 67
diff changeset
2233 virtual unsigned int execute (function *fun)
kono
parents: 67
diff changeset
2234 {
kono
parents: 67
diff changeset
2235 if (!TREE_THIS_VOLATILE (current_function_decl)
kono
parents: 67
diff changeset
2236 && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) == 0)
kono
parents: 67
diff changeset
2237 warn_function_noreturn (current_function_decl);
kono
parents: 67
diff changeset
2238 return 0;
kono
parents: 67
diff changeset
2239 }
kono
parents: 67
diff changeset
2240
kono
parents: 67
diff changeset
2241 }; // class pass_warn_function_noreturn
kono
parents: 67
diff changeset
2242
kono
parents: 67
diff changeset
2243 } // anon namespace
kono
parents: 67
diff changeset
2244
kono
parents: 67
diff changeset
2245 gimple_opt_pass *
kono
parents: 67
diff changeset
2246 make_pass_warn_function_noreturn (gcc::context *ctxt)
kono
parents: 67
diff changeset
2247 {
kono
parents: 67
diff changeset
2248 return new pass_warn_function_noreturn (ctxt);
kono
parents: 67
diff changeset
2249 }
kono
parents: 67
diff changeset
2250
kono
parents: 67
diff changeset
2251 /* Simple local pass for pure const discovery reusing the analysis from
kono
parents: 67
diff changeset
2252 ipa_pure_const. This pass is effective when executed together with
kono
parents: 67
diff changeset
2253 other optimization passes in early optimization pass queue. */
kono
parents: 67
diff changeset
2254
kono
parents: 67
diff changeset
2255 namespace {
kono
parents: 67
diff changeset
2256
kono
parents: 67
diff changeset
2257 const pass_data pass_data_nothrow =
kono
parents: 67
diff changeset
2258 {
kono
parents: 67
diff changeset
2259 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
2260 "nothrow", /* name */
kono
parents: 67
diff changeset
2261 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
2262 TV_IPA_PURE_CONST, /* tv_id */
kono
parents: 67
diff changeset
2263 0, /* properties_required */
kono
parents: 67
diff changeset
2264 0, /* properties_provided */
kono
parents: 67
diff changeset
2265 0, /* properties_destroyed */
kono
parents: 67
diff changeset
2266 0, /* todo_flags_start */
kono
parents: 67
diff changeset
2267 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
2268 };
kono
parents: 67
diff changeset
2269
kono
parents: 67
diff changeset
2270 class pass_nothrow : public gimple_opt_pass
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
2271 {
111
kono
parents: 67
diff changeset
2272 public:
kono
parents: 67
diff changeset
2273 pass_nothrow (gcc::context *ctxt)
kono
parents: 67
diff changeset
2274 : gimple_opt_pass (pass_data_nothrow, ctxt)
kono
parents: 67
diff changeset
2275 {}
kono
parents: 67
diff changeset
2276
kono
parents: 67
diff changeset
2277 /* opt_pass methods: */
kono
parents: 67
diff changeset
2278 opt_pass * clone () { return new pass_nothrow (m_ctxt); }
kono
parents: 67
diff changeset
2279 virtual bool gate (function *) { return optimize; }
kono
parents: 67
diff changeset
2280 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
2281
kono
parents: 67
diff changeset
2282 }; // class pass_nothrow
kono
parents: 67
diff changeset
2283
kono
parents: 67
diff changeset
2284 unsigned int
kono
parents: 67
diff changeset
2285 pass_nothrow::execute (function *)
kono
parents: 67
diff changeset
2286 {
kono
parents: 67
diff changeset
2287 struct cgraph_node *node;
kono
parents: 67
diff changeset
2288 basic_block this_block;
kono
parents: 67
diff changeset
2289
kono
parents: 67
diff changeset
2290 if (TREE_NOTHROW (current_function_decl))
kono
parents: 67
diff changeset
2291 return 0;
kono
parents: 67
diff changeset
2292
kono
parents: 67
diff changeset
2293 node = cgraph_node::get (current_function_decl);
kono
parents: 67
diff changeset
2294
kono
parents: 67
diff changeset
2295 /* We run during lowering, we can not really use availability yet. */
kono
parents: 67
diff changeset
2296 if (cgraph_node::get (current_function_decl)->get_availability ()
kono
parents: 67
diff changeset
2297 <= AVAIL_INTERPOSABLE)
kono
parents: 67
diff changeset
2298 {
kono
parents: 67
diff changeset
2299 if (dump_file)
kono
parents: 67
diff changeset
2300 fprintf (dump_file, "Function is interposable;"
kono
parents: 67
diff changeset
2301 " not analyzing.\n");
kono
parents: 67
diff changeset
2302 return true;
kono
parents: 67
diff changeset
2303 }
kono
parents: 67
diff changeset
2304
kono
parents: 67
diff changeset
2305 FOR_EACH_BB_FN (this_block, cfun)
kono
parents: 67
diff changeset
2306 {
kono
parents: 67
diff changeset
2307 for (gimple_stmt_iterator gsi = gsi_start_bb (this_block);
kono
parents: 67
diff changeset
2308 !gsi_end_p (gsi);
kono
parents: 67
diff changeset
2309 gsi_next (&gsi))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2310 if (stmt_can_throw_external (cfun, gsi_stmt (gsi)))
111
kono
parents: 67
diff changeset
2311 {
kono
parents: 67
diff changeset
2312 if (is_gimple_call (gsi_stmt (gsi)))
kono
parents: 67
diff changeset
2313 {
kono
parents: 67
diff changeset
2314 tree callee_t = gimple_call_fndecl (gsi_stmt (gsi));
kono
parents: 67
diff changeset
2315 if (callee_t && recursive_call_p (current_function_decl,
kono
parents: 67
diff changeset
2316 callee_t))
kono
parents: 67
diff changeset
2317 continue;
kono
parents: 67
diff changeset
2318 }
kono
parents: 67
diff changeset
2319
kono
parents: 67
diff changeset
2320 if (dump_file)
kono
parents: 67
diff changeset
2321 {
kono
parents: 67
diff changeset
2322 fprintf (dump_file, "Statement can throw: ");
kono
parents: 67
diff changeset
2323 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
kono
parents: 67
diff changeset
2324 }
kono
parents: 67
diff changeset
2325 return 0;
kono
parents: 67
diff changeset
2326 }
kono
parents: 67
diff changeset
2327 }
kono
parents: 67
diff changeset
2328
kono
parents: 67
diff changeset
2329 node->set_nothrow_flag (true);
kono
parents: 67
diff changeset
2330
kono
parents: 67
diff changeset
2331 bool cfg_changed = false;
kono
parents: 67
diff changeset
2332 if (self_recursive_p (node))
kono
parents: 67
diff changeset
2333 FOR_EACH_BB_FN (this_block, cfun)
kono
parents: 67
diff changeset
2334 if (gimple *g = last_stmt (this_block))
kono
parents: 67
diff changeset
2335 if (is_gimple_call (g))
kono
parents: 67
diff changeset
2336 {
kono
parents: 67
diff changeset
2337 tree callee_t = gimple_call_fndecl (g);
kono
parents: 67
diff changeset
2338 if (callee_t
kono
parents: 67
diff changeset
2339 && recursive_call_p (current_function_decl, callee_t)
kono
parents: 67
diff changeset
2340 && maybe_clean_eh_stmt (g)
kono
parents: 67
diff changeset
2341 && gimple_purge_dead_eh_edges (this_block))
kono
parents: 67
diff changeset
2342 cfg_changed = true;
kono
parents: 67
diff changeset
2343 }
kono
parents: 67
diff changeset
2344
kono
parents: 67
diff changeset
2345 if (dump_file)
kono
parents: 67
diff changeset
2346 fprintf (dump_file, "Function found to be nothrow: %s\n",
kono
parents: 67
diff changeset
2347 current_function_name ());
kono
parents: 67
diff changeset
2348 return cfg_changed ? TODO_cleanup_cfg : 0;
kono
parents: 67
diff changeset
2349 }
kono
parents: 67
diff changeset
2350
kono
parents: 67
diff changeset
2351 } // anon namespace
kono
parents: 67
diff changeset
2352
kono
parents: 67
diff changeset
2353 gimple_opt_pass *
kono
parents: 67
diff changeset
2354 make_pass_nothrow (gcc::context *ctxt)
kono
parents: 67
diff changeset
2355 {
kono
parents: 67
diff changeset
2356 return new pass_nothrow (ctxt);
kono
parents: 67
diff changeset
2357 }