]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-pure-const.c
* gimple-walk.h: New File. Relocate prototypes from gimple.h.
[thirdparty/gcc.git] / gcc / ipa-pure-const.c
CommitLineData
f7d118a9 1/* Callgraph based analysis of static variables.
711789cc 2 Copyright (C) 2004-2013 Free Software Foundation, Inc.
f7d118a9 3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
8c4c00c1 9Software Foundation; either version 3, or (at your option) any later
f7d118a9 10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
f7d118a9 20
f0b5f617 21/* This file marks functions as being either const (TREE_READONLY) or
22 pure (DECL_PURE_P). It can also set a variant of these that
23 are allowed to loop indefinitely (DECL_LOOPING_CONST_PURE_P).
f7d118a9 24
25 This must be run after inlining decisions have been made since
26 otherwise, the local sets will not contain information that is
27 consistent with post inlined state. The global sets are not prone
28 to this problem since they are by definition transitive. */
29
30/* The code in this module is called by the ipa pass manager. It
31 should be one of the later passes since it's information is used by
32 the rest of the compilation. */
33
34#include "config.h"
35#include "system.h"
36#include "coretypes.h"
37#include "tm.h"
38#include "tree.h"
073c1fd5 39#include "gimple.h"
dcf1a1ec 40#include "gimple-iterator.h"
41#include "gimple-walk.h"
073c1fd5 42#include "tree-cfg.h"
05d9c18a 43#include "tree-ssa-loop-niter.h"
f7d118a9 44#include "tree-inline.h"
45#include "tree-pass.h"
46#include "langhooks.h"
47#include "pointer-set.h"
48#include "ggc.h"
49#include "ipa-utils.h"
f7d118a9 50#include "flags.h"
f7d118a9 51#include "diagnostic.h"
ce084dfc 52#include "gimple-pretty-print.h"
f7d118a9 53#include "langhooks.h"
959fce68 54#include "target.h"
7bfefa9d 55#include "lto-streamer.h"
2541503d 56#include "data-streamer.h"
57#include "tree-streamer.h"
c9263b6a 58#include "cfgloop.h"
59#include "tree-scalar-evolution.h"
2c06958d 60#include "intl.h"
61#include "opts.h"
f7d118a9 62
63static struct pointer_set_t *visited_nodes;
64
65/* Lattice values for const and pure functions. Everything starts out
66 being const, then may drop to pure and then neither depending on
67 what is found. */
68enum pure_const_state_e
69{
70 IPA_CONST,
71 IPA_PURE,
72 IPA_NEITHER
73};
74
fc94a528 75const char *pure_const_names[3] = {"const", "pure", "neither"};
76
cb886925 77/* Holder for the const_state. There is one of these per function
78 decl. */
48e1416a 79struct funct_state_d
f7d118a9 80{
cb886925 81 /* See above. */
f7d118a9 82 enum pure_const_state_e pure_const_state;
b5cebd44 83 /* What user set here; we can be always sure about this. */
48e1416a 84 enum pure_const_state_e state_previously_known;
85 bool looping_previously_known;
cb886925 86
87 /* True if the function could possibly infinite loop. There are a
88 lot of ways that this could be determined. We are pretty
89 conservative here. While it is possible to cse pure and const
90 calls, it is not legal to have dce get rid of the call if there
91 is a possibility that the call could infinite loop since this is
92 a behavioral change. */
9c2a0c05 93 bool looping;
cb886925 94
b5cebd44 95 bool can_throw;
f7d118a9 96};
97
db86e424 98/* State used when we know nothing about function. */
99static struct funct_state_d varying_state
100 = { IPA_NEITHER, IPA_NEITHER, true, true, true };
101
102
f7d118a9 103typedef struct funct_state_d * funct_state;
104
cb886925 105/* The storage of the funct_state is abstracted because there is the
106 possibility that it may be desirable to move this to the cgraph
48e1416a 107 local info. */
cb886925 108
109/* Array, indexed by cgraph node uid, of function states. */
110
f1f41a6c 111static vec<funct_state> funct_state_vec;
cb886925 112
50828ed8 113/* Holders of ipa cgraph hooks: */
114static struct cgraph_node_hook_list *function_insertion_hook_holder;
86844d6c 115static struct cgraph_2node_hook_list *node_duplication_hook_holder;
116static struct cgraph_node_hook_list *node_removal_hook_holder;
cb886925 117
2c06958d 118/* Try to guess if function body will always be visible to compiler
119 when compiling the call and whether compiler will be able
120 to propagate the information by itself. */
121
122static bool
123function_always_visible_to_compiler_p (tree decl)
124{
125 return (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl));
126}
127
128/* Emit suggestion about attribute ATTRIB_NAME for DECL. KNOWN_FINITE
129 is true if the function is known to be finite. The diagnostic is
130 controlled by OPTION. WARNED_ABOUT is a pointer_set unique for
131 OPTION, this function may initialize it and it is always returned
132 by the function. */
133
134static struct pointer_set_t *
135suggest_attribute (int option, tree decl, bool known_finite,
136 struct pointer_set_t *warned_about,
137 const char * attrib_name)
138{
2c5d2e39 139 if (!option_enabled (option, &global_options))
2c06958d 140 return warned_about;
141 if (TREE_THIS_VOLATILE (decl)
142 || (known_finite && function_always_visible_to_compiler_p (decl)))
143 return warned_about;
144
145 if (!warned_about)
146 warned_about = pointer_set_create ();
147 if (pointer_set_contains (warned_about, decl))
148 return warned_about;
149 pointer_set_insert (warned_about, decl);
150 warning_at (DECL_SOURCE_LOCATION (decl),
151 option,
152 known_finite
153 ? _("function might be candidate for attribute %<%s%>")
154 : _("function might be candidate for attribute %<%s%>"
155 " if it is known to return normally"), attrib_name);
156 return warned_about;
157}
158
159/* Emit suggestion about __attribute_((pure)) for DECL. KNOWN_FINITE
160 is true if the function is known to be finite. */
161
162static void
163warn_function_pure (tree decl, bool known_finite)
164{
165 static struct pointer_set_t *warned_about;
166
167 warned_about
168 = suggest_attribute (OPT_Wsuggest_attribute_pure, decl,
169 known_finite, warned_about, "pure");
170}
171
172/* Emit suggestion about __attribute_((const)) for DECL. KNOWN_FINITE
173 is true if the function is known to be finite. */
174
175static void
176warn_function_const (tree decl, bool known_finite)
177{
178 static struct pointer_set_t *warned_about;
179 warned_about
180 = suggest_attribute (OPT_Wsuggest_attribute_const, decl,
181 known_finite, warned_about, "const");
182}
43d60d64 183
64641360 184static void
43d60d64 185warn_function_noreturn (tree decl)
186{
187 static struct pointer_set_t *warned_about;
08c6cbd2 188 if (!lang_hooks.missing_noreturn_ok_p (decl)
189 && targetm.warn_func_return (decl))
43d60d64 190 warned_about
191 = suggest_attribute (OPT_Wsuggest_attribute_noreturn, decl,
192 true, warned_about, "noreturn");
193}
9631926a 194
1ee39ad1 195/* Return true if we have a function state for NODE. */
196
197static inline bool
198has_function_state (struct cgraph_node *node)
199{
f1f41a6c 200 if (!funct_state_vec.exists ()
201 || funct_state_vec.length () <= (unsigned int)node->uid)
1ee39ad1 202 return false;
f1f41a6c 203 return funct_state_vec[node->uid] != NULL;
1ee39ad1 204}
205
48e1416a 206/* Return the function state from NODE. */
f7d118a9 207
208static inline funct_state
209get_function_state (struct cgraph_node *node)
210{
f1f41a6c 211 if (!funct_state_vec.exists ()
212 || funct_state_vec.length () <= (unsigned int)node->uid
213 || !funct_state_vec[node->uid])
1ee39ad1 214 /* We might want to put correct previously_known state into varying. */
db86e424 215 return &varying_state;
f1f41a6c 216 return funct_state_vec[node->uid];
cb886925 217}
218
219/* Set the function state S for NODE. */
220
221static inline void
222set_function_state (struct cgraph_node *node, funct_state s)
223{
f1f41a6c 224 if (!funct_state_vec.exists ()
225 || funct_state_vec.length () <= (unsigned int)node->uid)
226 funct_state_vec.safe_grow_cleared (node->uid + 1);
227 funct_state_vec[node->uid] = s;
f7d118a9 228}
229
f0b5f617 230/* Check to see if the use (or definition when CHECKING_WRITE is true)
f7d118a9 231 variable T is legal in a function that is either pure or const. */
232
48e1416a 233static inline void
234check_decl (funct_state local,
023a28e1 235 tree t, bool checking_write, bool ipa)
f7d118a9 236{
f7d118a9 237 /* Do not want to do anything with volatile except mark any
238 function that uses one to be not const or pure. */
48e1416a 239 if (TREE_THIS_VOLATILE (t))
240 {
f7d118a9 241 local->pure_const_state = IPA_NEITHER;
b5cebd44 242 if (dump_file)
243 fprintf (dump_file, " Volatile operand is not const/pure");
f7d118a9 244 return;
245 }
246
247 /* Do not care about a local automatic that is not static. */
248 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
249 return;
250
b5cebd44 251 /* If the variable has the "used" attribute, treat it as if it had a
252 been touched by the devil. */
83a23b05 253 if (DECL_PRESERVE_P (t))
b5cebd44 254 {
255 local->pure_const_state = IPA_NEITHER;
256 if (dump_file)
257 fprintf (dump_file, " Used static/global variable is not const/pure\n");
258 return;
259 }
260
023a28e1 261 /* In IPA mode we are not interested in checking actual loads and stores;
262 they will be processed at propagation time using ipa_ref. */
263 if (ipa)
264 return;
265
f7d118a9 266 /* Since we have dealt with the locals and params cases above, if we
267 are CHECKING_WRITE, this cannot be a pure or constant
268 function. */
48e1416a 269 if (checking_write)
bc17fd99 270 {
271 local->pure_const_state = IPA_NEITHER;
b5cebd44 272 if (dump_file)
273 fprintf (dump_file, " static/global memory write is not const/pure\n");
bc17fd99 274 return;
275 }
f7d118a9 276
277 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
278 {
b5cebd44 279 /* Readonly reads are safe. */
280 if (TREE_READONLY (t) && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
281 return; /* Read of a constant, do not change the function state. */
48e1416a 282 else
f7d118a9 283 {
b5cebd44 284 if (dump_file)
285 fprintf (dump_file, " global memory read is not const\n");
f7d118a9 286 /* Just a regular read. */
287 if (local->pure_const_state == IPA_CONST)
288 local->pure_const_state = IPA_PURE;
289 }
290 }
b5cebd44 291 else
292 {
293 /* Compilation level statics can be read if they are readonly
294 variables. */
295 if (TREE_READONLY (t))
296 return;
297
298 if (dump_file)
299 fprintf (dump_file, " static memory read is not const\n");
300 /* Just a regular read. */
301 if (local->pure_const_state == IPA_CONST)
302 local->pure_const_state = IPA_PURE;
303 }
f7d118a9 304}
305
f7d118a9 306
b5cebd44 307/* Check to see if the use (or definition when CHECKING_WRITE is true)
308 variable T is legal in a function that is either pure or const. */
f7d118a9 309
48e1416a 310static inline void
5ed0b345 311check_op (funct_state local, tree t, bool checking_write)
f7d118a9 312{
3ae61172 313 t = get_base_address (t);
314 if (t && TREE_THIS_VOLATILE (t))
f7d118a9 315 {
5ed0b345 316 local->pure_const_state = IPA_NEITHER;
317 if (dump_file)
318 fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
319 return;
320 }
3ae61172 321 else if (t
182cf5a9 322 && (INDIRECT_REF_P (t) || TREE_CODE (t) == MEM_REF)
3ae61172 323 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
324 && !ptr_deref_may_alias_global_p (TREE_OPERAND (t, 0)))
325 {
326 if (dump_file)
327 fprintf (dump_file, " Indirect ref to local memory is OK\n");
328 return;
329 }
5ed0b345 330 else if (checking_write)
331 {
332 local->pure_const_state = IPA_NEITHER;
333 if (dump_file)
334 fprintf (dump_file, " Indirect ref write is not const/pure\n");
335 return;
336 }
337 else
338 {
339 if (dump_file)
340 fprintf (dump_file, " Indirect ref read is not const\n");
341 if (local->pure_const_state == IPA_CONST)
342 local->pure_const_state = IPA_PURE;
f7d118a9 343 }
344}
345
023a28e1 346/* compute state based on ECF FLAGS and store to STATE and LOOPING. */
347
348static void
349state_from_flags (enum pure_const_state_e *state, bool *looping,
350 int flags, bool cannot_lead_to_return)
351{
352 *looping = false;
353 if (flags & ECF_LOOPING_CONST_OR_PURE)
354 {
355 *looping = true;
356 if (dump_file && (dump_flags & TDF_DETAILS))
357 fprintf (dump_file, " looping");
358 }
359 if (flags & ECF_CONST)
360 {
361 *state = IPA_CONST;
362 if (dump_file && (dump_flags & TDF_DETAILS))
363 fprintf (dump_file, " const\n");
364 }
365 else if (flags & ECF_PURE)
366 {
367 *state = IPA_PURE;
368 if (dump_file && (dump_flags & TDF_DETAILS))
369 fprintf (dump_file, " pure\n");
370 }
371 else if (cannot_lead_to_return)
372 {
373 *state = IPA_PURE;
374 *looping = true;
375 if (dump_file && (dump_flags & TDF_DETAILS))
376 fprintf (dump_file, " ignoring side effects->pure looping\n");
377 }
378 else
379 {
380 if (dump_file && (dump_flags & TDF_DETAILS))
9631926a 381 fprintf (dump_file, " neither\n");
023a28e1 382 *state = IPA_NEITHER;
383 *looping = true;
384 }
385}
386
387/* Merge STATE and STATE2 and LOOPING and LOOPING2 and store
388 into STATE and LOOPING better of the two variants.
389 Be sure to merge looping correctly. IPA_NEITHER functions
390 have looping 0 even if they don't have to return. */
391
392static inline void
393better_state (enum pure_const_state_e *state, bool *looping,
394 enum pure_const_state_e state2, bool looping2)
395{
396 if (state2 < *state)
397 {
398 if (*state == IPA_NEITHER)
399 *looping = looping2;
400 else
401 *looping = MIN (*looping, looping2);
26fc128e 402 *state = state2;
023a28e1 403 }
404 else if (state2 != IPA_NEITHER)
405 *looping = MIN (*looping, looping2);
406}
407
408/* Merge STATE and STATE2 and LOOPING and LOOPING2 and store
409 into STATE and LOOPING worse of the two variants. */
410
411static inline void
412worse_state (enum pure_const_state_e *state, bool *looping,
413 enum pure_const_state_e state2, bool looping2)
414{
415 *state = MAX (*state, state2);
416 *looping = MAX (*looping, looping2);
417}
418
0a10fd82 419/* Recognize special cases of builtins that are by themselves not pure or const
7dd42908 420 but function using them is. */
421static bool
a53e7471 422special_builtin_state (enum pure_const_state_e *state, bool *looping,
7dd42908 423 tree callee)
424{
425 if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
426 switch (DECL_FUNCTION_CODE (callee))
427 {
428 case BUILT_IN_RETURN:
429 case BUILT_IN_UNREACHABLE:
430 case BUILT_IN_ALLOCA:
581bf1c2 431 case BUILT_IN_ALLOCA_WITH_ALIGN:
7dd42908 432 case BUILT_IN_STACK_SAVE:
433 case BUILT_IN_STACK_RESTORE:
434 case BUILT_IN_EH_POINTER:
435 case BUILT_IN_EH_FILTER:
436 case BUILT_IN_UNWIND_RESUME:
437 case BUILT_IN_CXA_END_CLEANUP:
438 case BUILT_IN_EH_COPY_VALUES:
439 case BUILT_IN_FRAME_ADDRESS:
440 case BUILT_IN_APPLY:
441 case BUILT_IN_APPLY_ARGS:
7dd42908 442 *looping = false;
443 *state = IPA_CONST;
444 return true;
445 case BUILT_IN_PREFETCH:
446 *looping = true;
447 *state = IPA_CONST;
448 return true;
449 }
450 return false;
451}
452
f7d118a9 453/* Check the parameters of a function call to CALL_EXPR to see if
454 there are any references in the parameters that are not allowed for
455 pure or const functions. Also check to see if this is either an
456 indirect call, a call outside the compilation unit, or has special
457 attributes that may also effect the purity. The CALL_EXPR node for
458 the entire call expression. */
459
460static void
b5cebd44 461check_call (funct_state local, gimple call, bool ipa)
f7d118a9 462{
75a70cf9 463 int flags = gimple_call_flags (call);
b5cebd44 464 tree callee_t = gimple_call_fndecl (call);
b5cebd44 465 bool possibly_throws = stmt_could_throw_p (call);
466 bool possibly_throws_externally = (possibly_throws
467 && stmt_can_throw_external (call));
f7d118a9 468
b5cebd44 469 if (possibly_throws)
470 {
471 unsigned int i;
472 for (i = 0; i < gimple_num_ops (call); i++)
473 if (gimple_op (call, i)
474 && tree_could_throw_p (gimple_op (call, i)))
475 {
cbeb677e 476 if (possibly_throws && cfun->can_throw_non_call_exceptions)
b5cebd44 477 {
478 if (dump_file)
479 fprintf (dump_file, " operand can throw; looping\n");
480 local->looping = true;
481 }
482 if (possibly_throws_externally)
483 {
484 if (dump_file)
485 fprintf (dump_file, " operand can throw externally\n");
486 local->can_throw = true;
487 }
488 }
489 }
48e1416a 490
f7d118a9 491 /* The const and pure flags are set by a variety of places in the
492 compiler (including here). If someone has already set the flags
493 for the callee, (such as for some of the builtins) we will use
48e1416a 494 them, otherwise we will compute our own information.
495
f7d118a9 496 Const and pure functions have less clobber effects than other
497 functions so we process these first. Otherwise if it is a call
498 outside the compilation unit or an indirect call we punt. This
499 leaves local calls which will be processed by following the call
48e1416a 500 graph. */
f7d118a9 501 if (callee_t)
502 {
7dd42908 503 enum pure_const_state_e call_state;
504 bool call_looping;
505
a53e7471 506 if (special_builtin_state (&call_state, &call_looping, callee_t))
7dd42908 507 {
508 worse_state (&local->pure_const_state, &local->looping,
509 call_state, call_looping);
510 return;
511 }
f7d118a9 512 /* When bad things happen to bad functions, they cannot be const
513 or pure. */
514 if (setjmp_call_p (callee_t))
9c2a0c05 515 {
b5cebd44 516 if (dump_file)
517 fprintf (dump_file, " setjmp is not const/pure\n");
518 local->looping = true;
9c2a0c05 519 local->pure_const_state = IPA_NEITHER;
9c2a0c05 520 }
f7d118a9 521
522 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
523 switch (DECL_FUNCTION_CODE (callee_t))
524 {
525 case BUILT_IN_LONGJMP:
526 case BUILT_IN_NONLOCAL_GOTO:
b5cebd44 527 if (dump_file)
528 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
f7d118a9 529 local->pure_const_state = IPA_NEITHER;
b5cebd44 530 local->looping = true;
f7d118a9 531 break;
532 default:
533 break;
534 }
535 }
536
b5cebd44 537 /* When not in IPA mode, we can still handle self recursion. */
e9de52cc 538 if (!ipa && callee_t
539 && recursive_call_p (current_function_decl, callee_t))
2c06958d 540 {
541 if (dump_file)
542 fprintf (dump_file, " Recursive call can loop.\n");
543 local->looping = true;
544 }
0a10fd82 545 /* Either callee is unknown or we are doing local analysis.
ef378c27 546 Look to see if there are any bits available for the callee (such as by
547 declaration or because it is builtin) and process solely on the basis of
548 those bits. */
023a28e1 549 else if (!ipa)
f7d118a9 550 {
023a28e1 551 enum pure_const_state_e call_state;
552 bool call_looping;
cbeb677e 553 if (possibly_throws && cfun->can_throw_non_call_exceptions)
b5cebd44 554 {
555 if (dump_file)
556 fprintf (dump_file, " can throw; looping\n");
557 local->looping = true;
558 }
559 if (possibly_throws_externally)
560 {
561 if (dump_file)
562 {
e38def9c 563 fprintf (dump_file, " can throw externally to lp %i\n",
564 lookup_stmt_eh_lp (call));
b5cebd44 565 if (callee_t)
566 fprintf (dump_file, " callee:%s\n",
567 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
568 }
569 local->can_throw = true;
570 }
023a28e1 571 if (dump_file && (dump_flags & TDF_DETAILS))
572 fprintf (dump_file, " checking flags for call:");
573 state_from_flags (&call_state, &call_looping, flags,
574 ((flags & (ECF_NORETURN | ECF_NOTHROW))
575 == (ECF_NORETURN | ECF_NOTHROW))
576 || (!flag_exceptions && (flags & ECF_NORETURN)));
577 worse_state (&local->pure_const_state, &local->looping,
578 call_state, call_looping);
f7d118a9 579 }
b5cebd44 580 /* Direct functions calls are handled by IPA propagation. */
f7d118a9 581}
582
023a28e1 583/* Wrapper around check_decl for loads in local more. */
5ed0b345 584
585static bool
586check_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
587{
588 if (DECL_P (op))
023a28e1 589 check_decl ((funct_state)data, op, false, false);
5ed0b345 590 else
591 check_op ((funct_state)data, op, false);
592 return false;
593}
594
023a28e1 595/* Wrapper around check_decl for stores in local more. */
5ed0b345 596
597static bool
598check_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
599{
600 if (DECL_P (op))
023a28e1 601 check_decl ((funct_state)data, op, true, false);
602 else
603 check_op ((funct_state)data, op, true);
604 return false;
605}
606
607/* Wrapper around check_decl for loads in ipa mode. */
608
609static bool
610check_ipa_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
611{
612 if (DECL_P (op))
613 check_decl ((funct_state)data, op, false, true);
614 else
615 check_op ((funct_state)data, op, false);
616 return false;
617}
618
619/* Wrapper around check_decl for stores in ipa mode. */
620
621static bool
622check_ipa_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
623{
624 if (DECL_P (op))
625 check_decl ((funct_state)data, op, true, true);
5ed0b345 626 else
627 check_op ((funct_state)data, op, true);
628 return false;
629}
630
dd277d48 631/* Look into pointer pointed to by GSIP and figure out what interesting side
632 effects it has. */
b5cebd44 633static void
634check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
f7d118a9 635{
b5cebd44 636 gimple stmt = gsi_stmt (*gsip);
f7d118a9 637
9845d120 638 if (is_gimple_debug (stmt))
639 return;
640
b5cebd44 641 if (dump_file)
f7d118a9 642 {
b5cebd44 643 fprintf (dump_file, " scanning: ");
644 print_gimple_stmt (dump_file, stmt, 0, 0);
645 }
dd277d48 646
541c6dbb 647 if (gimple_has_volatile_ops (stmt)
648 && !gimple_clobber_p (stmt))
4b68df2e 649 {
650 local->pure_const_state = IPA_NEITHER;
651 if (dump_file)
652 fprintf (dump_file, " Volatile stmt is not const/pure\n");
653 }
654
5ed0b345 655 /* Look for loads and stores. */
023a28e1 656 walk_stmt_load_store_ops (stmt, local,
657 ipa ? check_ipa_load : check_load,
658 ipa ? check_ipa_store : check_store);
b5cebd44 659
660 if (gimple_code (stmt) != GIMPLE_CALL
661 && stmt_could_throw_p (stmt))
662 {
cbeb677e 663 if (cfun->can_throw_non_call_exceptions)
b5cebd44 664 {
665 if (dump_file)
10f4615f 666 fprintf (dump_file, " can throw; looping\n");
b5cebd44 667 local->looping = true;
668 }
669 if (stmt_can_throw_external (stmt))
670 {
671 if (dump_file)
10f4615f 672 fprintf (dump_file, " can throw externally\n");
b5cebd44 673 local->can_throw = true;
674 }
10f4615f 675 else
676 if (dump_file)
677 fprintf (dump_file, " can throw\n");
75a70cf9 678 }
75a70cf9 679 switch (gimple_code (stmt))
680 {
b5cebd44 681 case GIMPLE_CALL:
b5cebd44 682 check_call (local, stmt, ipa);
f7d118a9 683 break;
75a70cf9 684 case GIMPLE_LABEL:
685 if (DECL_NONLOCAL (gimple_label_label (stmt)))
f7d118a9 686 /* Target of long jump. */
9c2a0c05 687 {
b5cebd44 688 if (dump_file)
10f4615f 689 fprintf (dump_file, " nonlocal label is not const/pure\n");
9c2a0c05 690 local->pure_const_state = IPA_NEITHER;
9c2a0c05 691 }
f7d118a9 692 break;
75a70cf9 693 case GIMPLE_ASM:
97cf41ec 694 if (gimple_asm_clobbers_memory_p (stmt))
b5cebd44 695 {
97cf41ec 696 if (dump_file)
10f4615f 697 fprintf (dump_file, " memory asm clobber is not const/pure\n");
97cf41ec 698 /* Abandon all hope, ye who enter here. */
699 local->pure_const_state = IPA_NEITHER;
b5cebd44 700 }
701 if (gimple_asm_volatile_p (stmt))
702 {
703 if (dump_file)
10f4615f 704 fprintf (dump_file, " volatile is not const/pure\n");
b5cebd44 705 /* Abandon all hope, ye who enter here. */
706 local->pure_const_state = IPA_NEITHER;
707 local->looping = true;
708 }
709 return;
f7d118a9 710 default:
711 break;
712 }
f7d118a9 713}
714
cb886925 715
f7d118a9 716/* This is the main routine for finding the reference patterns for
717 global variables within a function FN. */
718
b5cebd44 719static funct_state
720analyze_function (struct cgraph_node *fn, bool ipa)
f7d118a9 721{
02774f2d 722 tree decl = fn->decl;
b5cebd44 723 funct_state l;
724 basic_block this_block;
f7d118a9 725
b5cebd44 726 l = XCNEW (struct funct_state_d);
727 l->pure_const_state = IPA_CONST;
df9b545b 728 l->state_previously_known = IPA_NEITHER;
729 l->looping_previously_known = true;
b5cebd44 730 l->looping = false;
731 l->can_throw = false;
91bf9d9a 732 state_from_flags (&l->state_previously_known, &l->looping_previously_known,
02774f2d 733 flags_from_decl_or_type (fn->decl),
91bf9d9a 734 cgraph_node_cannot_return (fn));
735
02774f2d 736 if (fn->thunk.thunk_p || fn->alias)
91bf9d9a 737 {
738 /* Thunk gets propagated through, so nothing interesting happens. */
739 gcc_assert (ipa);
740 return l;
741 }
f7d118a9 742
743 if (dump_file)
744 {
48e1416a 745 fprintf (dump_file, "\n\n local analysis of %s\n ",
b5cebd44 746 cgraph_node_name (fn));
f7d118a9 747 }
48e1416a 748
b5cebd44 749 push_cfun (DECL_STRUCT_FUNCTION (decl));
48e1416a 750
b5cebd44 751 FOR_EACH_BB (this_block)
f7d118a9 752 {
b5cebd44 753 gimple_stmt_iterator gsi;
754 struct walk_stmt_info wi;
f7d118a9 755
9af5ce0c 756 memset (&wi, 0, sizeof (wi));
b5cebd44 757 for (gsi = gsi_start_bb (this_block);
758 !gsi_end_p (gsi);
759 gsi_next (&gsi))
f7d118a9 760 {
b5cebd44 761 check_stmt (&gsi, l, ipa);
762 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
763 goto end;
f7d118a9 764 }
765 }
dcccac3e 766
767end:
b5cebd44 768 if (l->pure_const_state != IPA_NEITHER)
769 {
770 /* Const functions cannot have back edges (an
771 indication of possible infinite loop side
772 effect. */
773 if (mark_dfs_back_edges ())
c9263b6a 774 {
b1887855 775 /* Preheaders are needed for SCEV to work.
0a10fd82 776 Simple latches and recorded exits improve chances that loop will
8ff30f9a 777 proved to be finite in testcases such as in loop-15.c
778 and loop-24.c */
779 loop_optimizer_init (LOOPS_HAVE_PREHEADERS
780 | LOOPS_HAVE_SIMPLE_LATCHES
b1887855 781 | LOOPS_HAVE_RECORDED_EXITS);
c9263b6a 782 if (dump_file && (dump_flags & TDF_DETAILS))
783 flow_loops_dump (dump_file, NULL, 0);
784 if (mark_irreducible_loops ())
785 {
786 if (dump_file)
787 fprintf (dump_file, " has irreducible loops\n");
788 l->looping = true;
789 }
48e1416a 790 else
c9263b6a 791 {
792 loop_iterator li;
793 struct loop *loop;
794 scev_initialize ();
795 FOR_EACH_LOOP (li, loop, 0)
796 if (!finite_loop_p (loop))
797 {
798 if (dump_file)
8ff30f9a 799 fprintf (dump_file, " can not prove finiteness of "
800 "loop %i\n", loop->num);
c9263b6a 801 l->looping =true;
83b709f2 802 FOR_EACH_LOOP_BREAK (li);
c9263b6a 803 }
804 scev_finalize ();
805 }
806 loop_optimizer_finalize ();
807 }
b5cebd44 808 }
809
023a28e1 810 if (dump_file && (dump_flags & TDF_DETAILS))
811 fprintf (dump_file, " checking previously known:");
023a28e1 812
813 better_state (&l->pure_const_state, &l->looping,
814 l->state_previously_known,
815 l->looping_previously_known);
b5cebd44 816 if (TREE_NOTHROW (decl))
817 l->can_throw = false;
818
819 pop_cfun ();
dcccac3e 820 if (dump_file)
821 {
b5cebd44 822 if (l->looping)
823 fprintf (dump_file, "Function is locally looping.\n");
824 if (l->can_throw)
825 fprintf (dump_file, "Function is locally throwing.\n");
826 if (l->pure_const_state == IPA_CONST)
827 fprintf (dump_file, "Function is locally const.\n");
828 if (l->pure_const_state == IPA_PURE)
829 fprintf (dump_file, "Function is locally pure.\n");
dcccac3e 830 }
b5cebd44 831 return l;
f7d118a9 832}
833
50828ed8 834/* Called when new function is inserted to callgraph late. */
835static void
836add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
837{
ef378c27 838 if (cgraph_function_body_availability (node) < AVAIL_OVERWRITABLE)
86844d6c 839 return;
50828ed8 840 /* There are some shared nodes, in particular the initializers on
841 static declarations. We do not need to scan them more than once
842 since all we would be interested in are the addressof
843 operations. */
844 visited_nodes = pointer_set_create ();
2c06958d 845 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
846 set_function_state (node, analyze_function (node, true));
50828ed8 847 pointer_set_destroy (visited_nodes);
848 visited_nodes = NULL;
849}
850
86844d6c 851/* Called when new clone is inserted to callgraph late. */
852
853static void
854duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
855 void *data ATTRIBUTE_UNUSED)
856{
1ee39ad1 857 if (has_function_state (src))
86844d6c 858 {
859 funct_state l = XNEW (struct funct_state_d);
1ee39ad1 860 gcc_assert (!has_function_state (dst));
86844d6c 861 memcpy (l, get_function_state (src), sizeof (*l));
862 set_function_state (dst, l);
863 }
864}
865
866/* Called when new clone is inserted to callgraph late. */
867
868static void
869remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
870{
1ee39ad1 871 if (has_function_state (node))
86844d6c 872 {
db86e424 873 funct_state l = get_function_state (node);
874 if (l != &varying_state)
875 free (l);
86844d6c 876 set_function_state (node, NULL);
877 }
878}
879
f7d118a9 880\f
7bfefa9d 881static void
882register_hooks (void)
f7d118a9 883{
7bfefa9d 884 static bool init_p = false;
885
886 if (init_p)
887 return;
888
889 init_p = true;
f7d118a9 890
86844d6c 891 node_removal_hook_holder =
892 cgraph_add_node_removal_hook (&remove_node_data, NULL);
893 node_duplication_hook_holder =
894 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
50828ed8 895 function_insertion_hook_holder =
896 cgraph_add_function_insertion_hook (&add_new_function, NULL);
7bfefa9d 897}
898
899
900/* Analyze each function in the cgraph to see if it is locally PURE or
901 CONST. */
902
48e1416a 903static void
80880eb6 904pure_const_generate_summary (void)
7bfefa9d 905{
906 struct cgraph_node *node;
907
908 register_hooks ();
909
f7d118a9 910 /* There are some shared nodes, in particular the initializers on
911 static declarations. We do not need to scan them more than once
912 since all we would be interested in are the addressof
913 operations. */
914 visited_nodes = pointer_set_create ();
915
48e1416a 916 /* Process all of the functions.
f7d118a9 917
ef378c27 918 We process AVAIL_OVERWRITABLE functions. We can not use the results
919 by default, but the info can be used at LTO with -fwhole-program or
0a10fd82 920 when function got cloned and the clone is AVAILABLE. */
ef378c27 921
7c455d87 922 FOR_EACH_DEFINED_FUNCTION (node)
ef378c27 923 if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
b5cebd44 924 set_function_state (node, analyze_function (node, true));
f7d118a9 925
926 pointer_set_destroy (visited_nodes);
927 visited_nodes = NULL;
cb886925 928}
929
7bfefa9d 930
931/* Serialize the ipa info for lto. */
932
933static void
eab36a5a 934pure_const_write_summary (void)
7bfefa9d 935{
936 struct cgraph_node *node;
937 struct lto_simple_output_block *ob
938 = lto_create_simple_output_block (LTO_section_ipa_pure_const);
939 unsigned int count = 0;
eab36a5a 940 lto_symtab_encoder_iterator lsei;
941 lto_symtab_encoder_t encoder;
7bfefa9d 942
eab36a5a 943 encoder = lto_get_out_decl_state ()->symtab_node_encoder;
944
945 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
946 lsei_next_function_in_partition (&lsei))
7bfefa9d 947 {
eab36a5a 948 node = lsei_cgraph_node (lsei);
02774f2d 949 if (node->definition && has_function_state (node))
7bfefa9d 950 count++;
951 }
48e1416a 952
7f385784 953 streamer_write_uhwi_stream (ob->main_stream, count);
48e1416a 954
7bfefa9d 955 /* Process all of the functions. */
eab36a5a 956 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
957 lsei_next_function_in_partition (&lsei))
7bfefa9d 958 {
eab36a5a 959 node = lsei_cgraph_node (lsei);
02774f2d 960 if (node->definition && has_function_state (node))
7bfefa9d 961 {
30baba90 962 struct bitpack_d bp;
7bfefa9d 963 funct_state fs;
964 int node_ref;
70225339 965 lto_symtab_encoder_t encoder;
48e1416a 966
7bfefa9d 967 fs = get_function_state (node);
968
70225339 969 encoder = ob->decl_state->symtab_node_encoder;
02774f2d 970 node_ref = lto_symtab_encoder_encode (encoder, node);
7f385784 971 streamer_write_uhwi_stream (ob->main_stream, node_ref);
48e1416a 972
7bfefa9d 973 /* Note that flags will need to be read in the opposite
974 order as we are pushing the bitflags into FLAGS. */
30baba90 975 bp = bitpack_create (ob->main_stream);
976 bp_pack_value (&bp, fs->pure_const_state, 2);
977 bp_pack_value (&bp, fs->state_previously_known, 2);
978 bp_pack_value (&bp, fs->looping_previously_known, 1);
979 bp_pack_value (&bp, fs->looping, 1);
980 bp_pack_value (&bp, fs->can_throw, 1);
7f385784 981 streamer_write_bitpack (&bp);
7bfefa9d 982 }
983 }
984
985 lto_destroy_simple_output_block (ob);
986}
987
988
989/* Deserialize the ipa info for lto. */
990
48e1416a 991static void
7bfefa9d 992pure_const_read_summary (void)
993{
994 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
995 struct lto_file_decl_data *file_data;
996 unsigned int j = 0;
997
998 register_hooks ();
999 while ((file_data = file_data_vec[j++]))
1000 {
1001 const char *data;
1002 size_t len;
1003 struct lto_input_block *ib
48e1416a 1004 = lto_create_simple_input_block (file_data,
1005 LTO_section_ipa_pure_const,
7bfefa9d 1006 &data, &len);
1007 if (ib)
1008 {
1009 unsigned int i;
7f385784 1010 unsigned int count = streamer_read_uhwi (ib);
7bfefa9d 1011
1012 for (i = 0; i < count; i++)
1013 {
1014 unsigned int index;
1015 struct cgraph_node *node;
30baba90 1016 struct bitpack_d bp;
7bfefa9d 1017 funct_state fs;
70225339 1018 lto_symtab_encoder_t encoder;
7bfefa9d 1019
1020 fs = XCNEW (struct funct_state_d);
7f385784 1021 index = streamer_read_uhwi (ib);
70225339 1022 encoder = file_data->symtab_node_encoder;
1023 node = cgraph (lto_symtab_encoder_deref (encoder, index));
7bfefa9d 1024 set_function_state (node, fs);
1025
1026 /* Note that the flags must be read in the opposite
1027 order in which they were written (the bitflags were
1028 pushed into FLAGS). */
7f385784 1029 bp = streamer_read_bitpack (ib);
7bfefa9d 1030 fs->pure_const_state
30baba90 1031 = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
7bfefa9d 1032 fs->state_previously_known
30baba90 1033 = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
1034 fs->looping_previously_known = bp_unpack_value (&bp, 1);
1035 fs->looping = bp_unpack_value (&bp, 1);
1036 fs->can_throw = bp_unpack_value (&bp, 1);
fc94a528 1037 if (dump_file)
1038 {
02774f2d 1039 int flags = flags_from_decl_or_type (node->decl);
fc94a528 1040 fprintf (dump_file, "Read info for %s/%i ",
1041 cgraph_node_name (node),
02774f2d 1042 node->order);
fc94a528 1043 if (flags & ECF_CONST)
1044 fprintf (dump_file, " const");
1045 if (flags & ECF_PURE)
1046 fprintf (dump_file, " pure");
1047 if (flags & ECF_NOTHROW)
1048 fprintf (dump_file, " nothrow");
1049 fprintf (dump_file, "\n pure const state: %s\n",
1050 pure_const_names[fs->pure_const_state]);
1051 fprintf (dump_file, " previously known state: %s\n",
1052 pure_const_names[fs->looping_previously_known]);
1053 if (fs->looping)
1054 fprintf (dump_file," function is locally looping\n");
1055 if (fs->looping_previously_known)
1056 fprintf (dump_file," function is previously known looping\n");
1057 if (fs->can_throw)
1058 fprintf (dump_file," function is locally throwing\n");
1059 }
7bfefa9d 1060 }
1061
48e1416a 1062 lto_destroy_simple_input_block (file_data,
1063 LTO_section_ipa_pure_const,
7bfefa9d 1064 ib, data, len);
1065 }
1066 }
1067}
1068
1069
17b28e52 1070static bool
1071ignore_edge (struct cgraph_edge *e)
1072{
1073 return (!e->can_throw_external);
1074}
1075
b2c2e188 1076/* Return true if NODE is self recursive function.
e9de52cc 1077 Indirectly recursive functions appears as non-trivial strongly
1078 connected components, so we need to care about self recursion
1079 only. */
a1e88032 1080
1081static bool
1082self_recursive_p (struct cgraph_node *node)
1083{
1084 struct cgraph_edge *e;
1085 for (e = node->callees; e; e = e->next_callee)
b2c2e188 1086 if (cgraph_function_node (e->callee, NULL) == node)
a1e88032 1087 return true;
1088 return false;
1089}
1090
c0240443 1091/* Produce transitive closure over the callgraph and compute pure/const
1092 attributes. */
023a28e1 1093
c0240443 1094static void
1095propagate_pure_const (void)
cb886925 1096{
1097 struct cgraph_node *node;
1098 struct cgraph_node *w;
1099 struct cgraph_node **order =
1100 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1101 int order_pos;
1102 int i;
1103 struct ipa_dfs_info * w_info;
1104
7771d558 1105 order_pos = ipa_reduced_postorder (order, true, false, NULL);
f7d118a9 1106 if (dump_file)
1107 {
1108 dump_cgraph (dump_file);
48669653 1109 ipa_print_order (dump_file, "reduced", order, order_pos);
f7d118a9 1110 }
1111
9d75589a 1112 /* Propagate the local information through the call graph to produce
f7d118a9 1113 the global information. All the nodes within a cycle will have
1114 the same info so we collapse cycles first. Then we can do the
1115 propagation in one pass from the leaves to the roots. */
1116 for (i = 0; i < order_pos; i++ )
1117 {
1118 enum pure_const_state_e pure_const_state = IPA_CONST;
9c2a0c05 1119 bool looping = false;
54157bf1 1120 int count = 0;
f7d118a9 1121 node = order[i];
1122
02774f2d 1123 if (node->alias)
8c1fce46 1124 continue;
1125
fc94a528 1126 if (dump_file && (dump_flags & TDF_DETAILS))
1127 fprintf (dump_file, "Starting cycle\n");
1128
f7d118a9 1129 /* Find the worst state for any node in the cycle. */
1130 w = node;
023a28e1 1131 while (w && pure_const_state != IPA_NEITHER)
f7d118a9 1132 {
b5cebd44 1133 struct cgraph_edge *e;
023a28e1 1134 struct cgraph_edge *ie;
1135 int i;
1136 struct ipa_ref *ref;
1137
f7d118a9 1138 funct_state w_l = get_function_state (w);
fc94a528 1139 if (dump_file && (dump_flags & TDF_DETAILS))
1140 fprintf (dump_file, " Visiting %s/%i state:%s looping %i\n",
1141 cgraph_node_name (w),
02774f2d 1142 w->order,
fc94a528 1143 pure_const_names[w_l->pure_const_state],
1144 w_l->looping);
f7d118a9 1145
023a28e1 1146 /* First merge in function body properties. */
1147 worse_state (&pure_const_state, &looping,
1148 w_l->pure_const_state, w_l->looping);
1149 if (pure_const_state == IPA_NEITHER)
1150 break;
1151
1152 /* For overwritable nodes we can not assume anything. */
ef378c27 1153 if (cgraph_function_body_availability (w) == AVAIL_OVERWRITABLE)
1154 {
023a28e1 1155 worse_state (&pure_const_state, &looping,
1156 w_l->state_previously_known,
1157 w_l->looping_previously_known);
fc94a528 1158 if (dump_file && (dump_flags & TDF_DETAILS))
1159 {
1160 fprintf (dump_file,
1161 " Overwritable. state %s looping %i\n",
1162 pure_const_names[w_l->state_previously_known],
1163 w_l->looping_previously_known);
1164 }
023a28e1 1165 break;
ef378c27 1166 }
9c2a0c05 1167
b5cebd44 1168 count++;
1169
023a28e1 1170 /* We consider recursive cycles as possibly infinite.
1171 This might be relaxed since infinite recursion leads to stack
1172 overflow. */
b5cebd44 1173 if (count > 1)
1174 looping = true;
48e1416a 1175
023a28e1 1176 /* Now walk the edges and merge in callee properties. */
48e1416a 1177 for (e = w->callees; e; e = e->next_callee)
f7d118a9 1178 {
b2c2e188 1179 enum availability avail;
1180 struct cgraph_node *y = cgraph_function_node (e->callee, &avail);
fc94a528 1181 enum pure_const_state_e edge_state = IPA_CONST;
1182 bool edge_looping = false;
54157bf1 1183
fc94a528 1184 if (dump_file && (dump_flags & TDF_DETAILS))
1185 {
1186 fprintf (dump_file,
1187 " Call to %s/%i",
1188 cgraph_node_name (e->callee),
02774f2d 1189 e->callee->order);
fc94a528 1190 }
b2c2e188 1191 if (avail > AVAIL_OVERWRITABLE)
f7d118a9 1192 {
b5cebd44 1193 funct_state y_l = get_function_state (y);
fc94a528 1194 if (dump_file && (dump_flags & TDF_DETAILS))
1195 {
1196 fprintf (dump_file,
1197 " state:%s looping:%i\n",
1198 pure_const_names[y_l->pure_const_state],
1199 y_l->looping);
1200 }
4c170941 1201 if (y_l->pure_const_state > IPA_PURE
1ee39ad1 1202 && cgraph_edge_cannot_lead_to_return (e))
fc94a528 1203 {
1204 if (dump_file && (dump_flags & TDF_DETAILS))
023a28e1 1205 fprintf (dump_file,
1206 " Ignoring side effects"
1207 " -> pure, looping\n");
fc94a528 1208 edge_state = IPA_PURE;
1209 edge_looping = true;
1210 }
1211 else
1212 {
1213 edge_state = y_l->pure_const_state;
1214 edge_looping = y_l->looping;
1215 }
f7d118a9 1216 }
a53e7471 1217 else if (special_builtin_state (&edge_state, &edge_looping,
02774f2d 1218 y->decl))
7dd42908 1219 ;
ef378c27 1220 else
023a28e1 1221 state_from_flags (&edge_state, &edge_looping,
02774f2d 1222 flags_from_decl_or_type (y->decl),
7dd42908 1223 cgraph_edge_cannot_lead_to_return (e));
023a28e1 1224
1225 /* Merge the results with what we already know. */
1226 better_state (&edge_state, &edge_looping,
1227 w_l->state_previously_known,
1228 w_l->looping_previously_known);
1229 worse_state (&pure_const_state, &looping,
1230 edge_state, edge_looping);
1231 if (pure_const_state == IPA_NEITHER)
1232 break;
1233 }
1234 if (pure_const_state == IPA_NEITHER)
1235 break;
ef378c27 1236
023a28e1 1237 /* Now process the indirect call. */
451e322a 1238 for (ie = w->indirect_calls; ie; ie = ie->next_callee)
023a28e1 1239 {
1240 enum pure_const_state_e edge_state = IPA_CONST;
1241 bool edge_looping = false;
4c170941 1242
023a28e1 1243 if (dump_file && (dump_flags & TDF_DETAILS))
1244 fprintf (dump_file, " Indirect call");
1245 state_from_flags (&edge_state, &edge_looping,
1246 ie->indirect_info->ecf_flags,
1247 cgraph_edge_cannot_lead_to_return (ie));
1248 /* Merge the results with what we already know. */
1249 better_state (&edge_state, &edge_looping,
1250 w_l->state_previously_known,
1251 w_l->looping_previously_known);
1252 worse_state (&pure_const_state, &looping,
1253 edge_state, edge_looping);
fc94a528 1254 if (pure_const_state == IPA_NEITHER)
1255 break;
f7d118a9 1256 }
023a28e1 1257 if (pure_const_state == IPA_NEITHER)
1258 break;
1259
1260 /* And finally all loads and stores. */
02774f2d 1261 for (i = 0; ipa_ref_list_reference_iterate (&w->ref_list, i, ref); i++)
023a28e1 1262 {
1263 enum pure_const_state_e ref_state = IPA_CONST;
1264 bool ref_looping = false;
1265 switch (ref->use)
1266 {
1267 case IPA_REF_LOAD:
1268 /* readonly reads are safe. */
02774f2d 1269 if (TREE_READONLY (ipa_ref_varpool_node (ref)->decl))
023a28e1 1270 break;
1271 if (dump_file && (dump_flags & TDF_DETAILS))
1272 fprintf (dump_file, " nonreadonly global var read\n");
1273 ref_state = IPA_PURE;
1274 break;
1275 case IPA_REF_STORE:
1276 if (ipa_ref_cannot_lead_to_return (ref))
1277 break;
1278 ref_state = IPA_NEITHER;
1279 if (dump_file && (dump_flags & TDF_DETAILS))
1280 fprintf (dump_file, " global var write\n");
1281 break;
1282 case IPA_REF_ADDR:
1283 break;
1284 }
1285 better_state (&ref_state, &ref_looping,
1286 w_l->state_previously_known,
1287 w_l->looping_previously_known);
1288 worse_state (&pure_const_state, &looping,
1289 ref_state, ref_looping);
1290 if (pure_const_state == IPA_NEITHER)
1291 break;
1292 }
02774f2d 1293 w_info = (struct ipa_dfs_info *) w->aux;
f7d118a9 1294 w = w_info->next_cycle;
1295 }
fc94a528 1296 if (dump_file && (dump_flags & TDF_DETAILS))
1297 fprintf (dump_file, "Result %s looping %i\n",
1298 pure_const_names [pure_const_state],
1299 looping);
f7d118a9 1300
1301 /* Copy back the region's pure_const_state which is shared by
1302 all nodes in the region. */
1303 w = node;
1304 while (w)
1305 {
1306 funct_state w_l = get_function_state (w);
b5cebd44 1307 enum pure_const_state_e this_state = pure_const_state;
1308 bool this_looping = looping;
f7d118a9 1309
df9b545b 1310 if (w_l->state_previously_known != IPA_NEITHER
1311 && this_state > w_l->state_previously_known)
4c170941 1312 {
1313 this_state = w_l->state_previously_known;
1314 this_looping |= w_l->looping_previously_known;
1315 }
a1e88032 1316 if (!this_looping && self_recursive_p (w))
1317 this_looping = true;
df9b545b 1318 if (!w_l->looping_previously_known)
1319 this_looping = false;
cb886925 1320
b5cebd44 1321 /* All nodes within a cycle share the same info. */
1322 w_l->pure_const_state = this_state;
1323 w_l->looping = this_looping;
1324
1325 switch (this_state)
1326 {
1327 case IPA_CONST:
02774f2d 1328 if (!TREE_READONLY (w->decl))
2c06958d 1329 {
02774f2d 1330 warn_function_const (w->decl, !this_looping);
2c06958d 1331 if (dump_file)
1332 fprintf (dump_file, "Function found to be %sconst: %s\n",
1333 this_looping ? "looping " : "",
1334 cgraph_node_name (w));
1335 }
7f74ac6b 1336 cgraph_set_const_flag (w, true, this_looping);
b5cebd44 1337 break;
48e1416a 1338
b5cebd44 1339 case IPA_PURE:
02774f2d 1340 if (!DECL_PURE_P (w->decl))
2c06958d 1341 {
02774f2d 1342 warn_function_pure (w->decl, !this_looping);
2c06958d 1343 if (dump_file)
1344 fprintf (dump_file, "Function found to be %spure: %s\n",
1345 this_looping ? "looping " : "",
1346 cgraph_node_name (w));
1347 }
7f74ac6b 1348 cgraph_set_pure_flag (w, true, this_looping);
b5cebd44 1349 break;
48e1416a 1350
b5cebd44 1351 default:
1352 break;
1353 }
02774f2d 1354 w_info = (struct ipa_dfs_info *) w->aux;
17b28e52 1355 w = w_info->next_cycle;
1356 }
1357 }
1358
7771d558 1359 ipa_free_postorder_info ();
c0240443 1360 free (order);
1361}
1362
1363/* Produce transitive closure over the callgraph and compute nothrow
1364 attributes. */
1365
1366static void
1367propagate_nothrow (void)
1368{
1369 struct cgraph_node *node;
1370 struct cgraph_node *w;
1371 struct cgraph_node **order =
1372 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1373 int order_pos;
1374 int i;
1375 struct ipa_dfs_info * w_info;
1376
7771d558 1377 order_pos = ipa_reduced_postorder (order, true, false, ignore_edge);
17b28e52 1378 if (dump_file)
1379 {
1380 dump_cgraph (dump_file);
7771d558 1381 ipa_print_order (dump_file, "reduced for nothrow", order, order_pos);
17b28e52 1382 }
c0240443 1383
9d75589a 1384 /* Propagate the local information through the call graph to produce
17b28e52 1385 the global information. All the nodes within a cycle will have
1386 the same info so we collapse cycles first. Then we can do the
1387 propagation in one pass from the leaves to the roots. */
1388 for (i = 0; i < order_pos; i++ )
1389 {
1390 bool can_throw = false;
1391 node = order[i];
1392
02774f2d 1393 if (node->alias)
8c1fce46 1394 continue;
1395
17b28e52 1396 /* Find the worst state for any node in the cycle. */
1397 w = node;
1398 while (w)
1399 {
023a28e1 1400 struct cgraph_edge *e, *ie;
17b28e52 1401 funct_state w_l = get_function_state (w);
1402
ef378c27 1403 if (w_l->can_throw
1404 || cgraph_function_body_availability (w) == AVAIL_OVERWRITABLE)
17b28e52 1405 can_throw = true;
1406
1407 if (can_throw)
1408 break;
48e1416a 1409
1410 for (e = w->callees; e; e = e->next_callee)
17b28e52 1411 {
b2c2e188 1412 enum availability avail;
1413 struct cgraph_node *y = cgraph_function_node (e->callee, &avail);
17b28e52 1414
b2c2e188 1415 if (avail > AVAIL_OVERWRITABLE)
17b28e52 1416 {
1417 funct_state y_l = get_function_state (y);
1418
48e1416a 1419 if (can_throw)
17b28e52 1420 break;
02774f2d 1421 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
17b28e52 1422 && e->can_throw_external)
1423 can_throw = true;
1424 }
02774f2d 1425 else if (e->can_throw_external && !TREE_NOTHROW (y->decl))
ef378c27 1426 can_throw = true;
17b28e52 1427 }
023a28e1 1428 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1429 if (ie->can_throw_external)
73bd65ab 1430 {
1431 can_throw = true;
1432 break;
1433 }
02774f2d 1434 w_info = (struct ipa_dfs_info *) w->aux;
17b28e52 1435 w = w_info->next_cycle;
1436 }
1437
1438 /* Copy back the region's pure_const_state which is shared by
1439 all nodes in the region. */
1440 w = node;
1441 while (w)
1442 {
ecfab407 1443 funct_state w_l = get_function_state (w);
02774f2d 1444 if (!can_throw && !TREE_NOTHROW (w->decl))
b5cebd44 1445 {
16fcf0f4 1446 cgraph_set_nothrow_flag (w, true);
b5cebd44 1447 if (dump_file)
48e1416a 1448 fprintf (dump_file, "Function found to be nothrow: %s\n",
b5cebd44 1449 cgraph_node_name (w));
f7d118a9 1450 }
02774f2d 1451 else if (can_throw && !TREE_NOTHROW (w->decl))
ecfab407 1452 w_l->can_throw = true;
02774f2d 1453 w_info = (struct ipa_dfs_info *) w->aux;
f7d118a9 1454 w = w_info->next_cycle;
1455 }
1456 }
1457
7771d558 1458 ipa_free_postorder_info ();
f7d118a9 1459 free (order);
c0240443 1460}
1461
1462
1463/* Produce the global information by preforming a transitive closure
1464 on the local information that was produced by generate_summary. */
1465
1466static unsigned int
1467propagate (void)
1468{
1469 struct cgraph_node *node;
1470
1471 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
1472 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
1473 cgraph_remove_node_removal_hook (node_removal_hook_holder);
1474
1475 /* Nothrow makes more function to not lead to return and improve
1476 later analysis. */
1477 propagate_nothrow ();
1478 propagate_pure_const ();
1479
1480 /* Cleanup. */
c6d207aa 1481 FOR_EACH_FUNCTION (node)
c0240443 1482 if (has_function_state (node))
1483 free (get_function_state (node));
f1f41a6c 1484 funct_state_vec.release ();
2a1990e9 1485 return 0;
f7d118a9 1486}
1487
1488static bool
1489gate_pure_const (void)
1490{
86844d6c 1491 return (flag_ipa_pure_const
f7d118a9 1492 /* Don't bother doing anything if the program has errors. */
852f689e 1493 && !seen_error ());
f7d118a9 1494}
1495
cbe8bda8 1496namespace {
1497
1498const pass_data pass_data_ipa_pure_const =
f7d118a9 1499{
cbe8bda8 1500 IPA_PASS, /* type */
1501 "pure-const", /* name */
1502 OPTGROUP_NONE, /* optinfo_flags */
1503 true, /* has_gate */
1504 true, /* has_execute */
1505 TV_IPA_PURE_CONST, /* tv_id */
1506 0, /* properties_required */
1507 0, /* properties_provided */
1508 0, /* properties_destroyed */
1509 0, /* todo_flags_start */
1510 0, /* todo_flags_finish */
f7d118a9 1511};
b5cebd44 1512
cbe8bda8 1513class pass_ipa_pure_const : public ipa_opt_pass_d
1514{
1515public:
9af5ce0c 1516 pass_ipa_pure_const (gcc::context *ctxt)
1517 : ipa_opt_pass_d (pass_data_ipa_pure_const, ctxt,
1518 pure_const_generate_summary, /* generate_summary */
1519 pure_const_write_summary, /* write_summary */
1520 pure_const_read_summary, /* read_summary */
1521 NULL, /* write_optimization_summary */
1522 NULL, /* read_optimization_summary */
1523 NULL, /* stmt_fixup */
1524 0, /* function_transform_todo_flags_start */
1525 NULL, /* function_transform */
1526 NULL) /* variable_transform */
cbe8bda8 1527 {}
1528
1529 /* opt_pass methods: */
1530 bool gate () { return gate_pure_const (); }
1531 unsigned int execute () { return propagate (); }
1532
1533}; // class pass_ipa_pure_const
1534
1535} // anon namespace
1536
1537ipa_opt_pass_d *
1538make_pass_ipa_pure_const (gcc::context *ctxt)
1539{
1540 return new pass_ipa_pure_const (ctxt);
1541}
1542
2c06958d 1543/* Return true if function should be skipped for local pure const analysis. */
b5cebd44 1544
2c06958d 1545static bool
1546skip_function_for_local_pure_const (struct cgraph_node *node)
b5cebd44 1547{
b5cebd44 1548 /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations
1549 we must not promote functions that are called by already processed functions. */
1550
1551 if (function_called_by_processed_nodes_p ())
1552 {
1553 if (dump_file)
1554 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
2c06958d 1555 return true;
b5cebd44 1556 }
16fcf0f4 1557 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
b5cebd44 1558 {
1559 if (dump_file)
0a10fd82 1560 fprintf (dump_file, "Function is not available or overwritable; not analyzing.\n");
2c06958d 1561 return true;
b5cebd44 1562 }
2c06958d 1563 return false;
1564}
1565
1566/* Simple local pass for pure const discovery reusing the analysis from
1567 ipa_pure_const. This pass is effective when executed together with
1568 other optimization passes in early optimization pass queue. */
b5cebd44 1569
2c06958d 1570static unsigned int
1571local_pure_const (void)
1572{
1573 bool changed = false;
1574 funct_state l;
1575 bool skip;
1576 struct cgraph_node *node;
1577
fd6a3c41 1578 node = cgraph_get_node (current_function_decl);
2c06958d 1579 skip = skip_function_for_local_pure_const (node);
1580 if (!warn_suggest_attribute_const
1581 && !warn_suggest_attribute_pure
1582 && skip)
1583 return 0;
e0933141 1584
ab3db708 1585 l = analyze_function (node, false);
1586
1587 /* Do NORETURN discovery. */
e0933141 1588 if (!skip && !TREE_THIS_VOLATILE (current_function_decl)
1589 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0)
1590 {
43d60d64 1591 warn_function_noreturn (cfun->decl);
e0933141 1592 if (dump_file)
1593 fprintf (dump_file, "Function found to be noreturn: %s\n",
9631926a 1594 current_function_name ());
e0933141 1595
1596 /* Update declaration and reduce profile to executed once. */
1597 TREE_THIS_VOLATILE (current_function_decl) = 1;
1598 if (node->frequency > NODE_FREQUENCY_EXECUTED_ONCE)
1599 node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
1600
1601 changed = true;
1602 }
ef378c27 1603
b5cebd44 1604 switch (l->pure_const_state)
1605 {
1606 case IPA_CONST:
1607 if (!TREE_READONLY (current_function_decl))
1608 {
2c06958d 1609 warn_function_const (current_function_decl, !l->looping);
1610 if (!skip)
1611 {
7f74ac6b 1612 cgraph_set_const_flag (node, true, l->looping);
2c06958d 1613 changed = true;
1614 }
b5cebd44 1615 if (dump_file)
1616 fprintf (dump_file, "Function found to be %sconst: %s\n",
1617 l->looping ? "looping " : "",
9631926a 1618 current_function_name ());
b5cebd44 1619 }
1620 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1621 && !l->looping)
1622 {
2c06958d 1623 if (!skip)
1624 {
7f74ac6b 1625 cgraph_set_const_flag (node, true, false);
2c06958d 1626 changed = true;
1627 }
b5cebd44 1628 if (dump_file)
1629 fprintf (dump_file, "Function found to be non-looping: %s\n",
9631926a 1630 current_function_name ());
b5cebd44 1631 }
1632 break;
1633
1634 case IPA_PURE:
2c06958d 1635 if (!DECL_PURE_P (current_function_decl))
b5cebd44 1636 {
2c06958d 1637 if (!skip)
1638 {
7f74ac6b 1639 cgraph_set_pure_flag (node, true, l->looping);
2c06958d 1640 changed = true;
1641 }
1642 warn_function_pure (current_function_decl, !l->looping);
b5cebd44 1643 if (dump_file)
1644 fprintf (dump_file, "Function found to be %spure: %s\n",
1645 l->looping ? "looping " : "",
9631926a 1646 current_function_name ());
b5cebd44 1647 }
1648 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1649 && !l->looping)
1650 {
2c06958d 1651 if (!skip)
1652 {
7f74ac6b 1653 cgraph_set_pure_flag (node, true, false);
2c06958d 1654 changed = true;
1655 }
b5cebd44 1656 if (dump_file)
1657 fprintf (dump_file, "Function found to be non-looping: %s\n",
9631926a 1658 current_function_name ());
b5cebd44 1659 }
1660 break;
1661
1662 default:
1663 break;
1664 }
1665 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
1666 {
16fcf0f4 1667 cgraph_set_nothrow_flag (node, true);
b5cebd44 1668 changed = true;
1669 if (dump_file)
1670 fprintf (dump_file, "Function found to be nothrow: %s\n",
9631926a 1671 current_function_name ());
b5cebd44 1672 }
dd045aee 1673 free (l);
b5cebd44 1674 if (changed)
1675 return execute_fixup_cfg ();
1676 else
1677 return 0;
1678}
1679
cbe8bda8 1680namespace {
1681
1682const pass_data pass_data_local_pure_const =
b5cebd44 1683{
cbe8bda8 1684 GIMPLE_PASS, /* type */
1685 "local-pure-const", /* name */
1686 OPTGROUP_NONE, /* optinfo_flags */
1687 true, /* has_gate */
1688 true, /* has_execute */
1689 TV_IPA_PURE_CONST, /* tv_id */
1690 0, /* properties_required */
1691 0, /* properties_provided */
1692 0, /* properties_destroyed */
1693 0, /* todo_flags_start */
1694 0, /* todo_flags_finish */
b5cebd44 1695};
cbe8bda8 1696
1697class pass_local_pure_const : public gimple_opt_pass
1698{
1699public:
9af5ce0c 1700 pass_local_pure_const (gcc::context *ctxt)
1701 : gimple_opt_pass (pass_data_local_pure_const, ctxt)
cbe8bda8 1702 {}
1703
1704 /* opt_pass methods: */
ae84f584 1705 opt_pass * clone () { return new pass_local_pure_const (m_ctxt); }
cbe8bda8 1706 bool gate () { return gate_pure_const (); }
1707 unsigned int execute () { return local_pure_const (); }
1708
1709}; // class pass_local_pure_const
1710
1711} // anon namespace
1712
1713gimple_opt_pass *
1714make_pass_local_pure_const (gcc::context *ctxt)
1715{
1716 return new pass_local_pure_const (ctxt);
1717}
64641360 1718
1719/* Emit noreturn warnings. */
1720
1721static unsigned int
1722execute_warn_function_noreturn (void)
1723{
1724 if (!TREE_THIS_VOLATILE (current_function_decl)
1725 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0)
1726 warn_function_noreturn (current_function_decl);
1727 return 0;
1728}
1729
1730static bool
1731gate_warn_function_noreturn (void)
1732{
1733 return warn_suggest_attribute_noreturn;
1734}
1735
1736namespace {
1737
1738const pass_data pass_data_warn_function_noreturn =
1739{
1740 GIMPLE_PASS, /* type */
1741 "*warn_function_noreturn", /* name */
1742 OPTGROUP_NONE, /* optinfo_flags */
1743 true, /* has_gate */
1744 true, /* has_execute */
1745 TV_NONE, /* tv_id */
1746 PROP_cfg, /* properties_required */
1747 0, /* properties_provided */
1748 0, /* properties_destroyed */
1749 0, /* todo_flags_start */
1750 0, /* todo_flags_finish */
1751};
1752
1753class pass_warn_function_noreturn : public gimple_opt_pass
1754{
1755public:
1756 pass_warn_function_noreturn (gcc::context *ctxt)
1757 : gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
1758 {}
1759
1760 /* opt_pass methods: */
1761 bool gate () { return gate_warn_function_noreturn (); }
1762 unsigned int execute () { return execute_warn_function_noreturn (); }
1763
1764}; // class pass_warn_function_noreturn
1765
1766} // anon namespace
1767
1768gimple_opt_pass *
1769make_pass_warn_function_noreturn (gcc::context *ctxt)
1770{
1771 return new pass_warn_function_noreturn (ctxt);
1772}
1773
1774