2014-10-24 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / ipa-pure-const.c
blobc221cd0a3babf94a2beaff3e8f4fb5f8c2052f48
1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004-2014 Free Software Foundation, Inc.
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
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).
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. */
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. */
34 #include "config.h"
35 #include "system.h"
36 #include "coretypes.h"
37 #include "tm.h"
38 #include "tree.h"
39 #include "print-tree.h"
40 #include "calls.h"
41 #include "basic-block.h"
42 #include "tree-ssa-alias.h"
43 #include "internal-fn.h"
44 #include "tree-eh.h"
45 #include "gimple-expr.h"
46 #include "is-a.h"
47 #include "gimple.h"
48 #include "gimple-iterator.h"
49 #include "gimple-walk.h"
50 #include "tree-cfg.h"
51 #include "tree-ssa-loop-niter.h"
52 #include "tree-inline.h"
53 #include "tree-pass.h"
54 #include "langhooks.h"
55 #include "ipa-utils.h"
56 #include "flags.h"
57 #include "diagnostic.h"
58 #include "gimple-pretty-print.h"
59 #include "langhooks.h"
60 #include "target.h"
61 #include "lto-streamer.h"
62 #include "data-streamer.h"
63 #include "tree-streamer.h"
64 #include "cfgloop.h"
65 #include "tree-scalar-evolution.h"
66 #include "intl.h"
67 #include "opts.h"
68 #include "hash-set.h"
70 /* Lattice values for const and pure functions. Everything starts out
71 being const, then may drop to pure and then neither depending on
72 what is found. */
73 enum pure_const_state_e
75 IPA_CONST,
76 IPA_PURE,
77 IPA_NEITHER
80 const char *pure_const_names[3] = {"const", "pure", "neither"};
82 /* Holder for the const_state. There is one of these per function
83 decl. */
84 struct funct_state_d
86 /* See above. */
87 enum pure_const_state_e pure_const_state;
88 /* What user set here; we can be always sure about this. */
89 enum pure_const_state_e state_previously_known;
90 bool looping_previously_known;
92 /* True if the function could possibly infinite loop. There are a
93 lot of ways that this could be determined. We are pretty
94 conservative here. While it is possible to cse pure and const
95 calls, it is not legal to have dce get rid of the call if there
96 is a possibility that the call could infinite loop since this is
97 a behavioral change. */
98 bool looping;
100 bool can_throw;
103 /* State used when we know nothing about function. */
104 static struct funct_state_d varying_state
105 = { IPA_NEITHER, IPA_NEITHER, true, true, true };
108 typedef struct funct_state_d * funct_state;
110 /* The storage of the funct_state is abstracted because there is the
111 possibility that it may be desirable to move this to the cgraph
112 local info. */
114 /* Array, indexed by cgraph node uid, of function states. */
116 static vec<funct_state> funct_state_vec;
118 static bool gate_pure_const (void);
120 namespace {
122 const pass_data pass_data_ipa_pure_const =
124 IPA_PASS, /* type */
125 "pure-const", /* name */
126 OPTGROUP_NONE, /* optinfo_flags */
127 TV_IPA_PURE_CONST, /* tv_id */
128 0, /* properties_required */
129 0, /* properties_provided */
130 0, /* properties_destroyed */
131 0, /* todo_flags_start */
132 0, /* todo_flags_finish */
135 class pass_ipa_pure_const : public ipa_opt_pass_d
137 public:
138 pass_ipa_pure_const(gcc::context *ctxt);
140 /* opt_pass methods: */
141 bool gate (function *) { return gate_pure_const (); }
142 unsigned int execute (function *fun);
144 void register_hooks (void);
146 private:
147 bool init_p;
149 /* Holders of ipa cgraph hooks: */
150 struct cgraph_node_hook_list *function_insertion_hook_holder;
151 struct cgraph_2node_hook_list *node_duplication_hook_holder;
152 struct cgraph_node_hook_list *node_removal_hook_holder;
154 }; // class pass_ipa_pure_const
156 } // anon namespace
158 /* Try to guess if function body will always be visible to compiler
159 when compiling the call and whether compiler will be able
160 to propagate the information by itself. */
162 static bool
163 function_always_visible_to_compiler_p (tree decl)
165 return (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl));
168 /* Emit suggestion about attribute ATTRIB_NAME for DECL. KNOWN_FINITE
169 is true if the function is known to be finite. The diagnostic is
170 controlled by OPTION. WARNED_ABOUT is a hash_set<tree> unique for
171 OPTION, this function may initialize it and it is always returned
172 by the function. */
174 static hash_set<tree> *
175 suggest_attribute (int option, tree decl, bool known_finite,
176 hash_set<tree> *warned_about,
177 const char * attrib_name)
179 if (!option_enabled (option, &global_options))
180 return warned_about;
181 if (TREE_THIS_VOLATILE (decl)
182 || (known_finite && function_always_visible_to_compiler_p (decl)))
183 return warned_about;
185 if (!warned_about)
186 warned_about = new hash_set<tree>;
187 if (warned_about->contains (decl))
188 return warned_about;
189 warned_about->add (decl);
190 warning_at (DECL_SOURCE_LOCATION (decl),
191 option,
192 known_finite
193 ? _("function might be candidate for attribute %<%s%>")
194 : _("function might be candidate for attribute %<%s%>"
195 " if it is known to return normally"), attrib_name);
196 return warned_about;
199 /* Emit suggestion about __attribute_((pure)) for DECL. KNOWN_FINITE
200 is true if the function is known to be finite. */
202 static void
203 warn_function_pure (tree decl, bool known_finite)
205 static hash_set<tree> *warned_about;
207 warned_about
208 = suggest_attribute (OPT_Wsuggest_attribute_pure, decl,
209 known_finite, warned_about, "pure");
212 /* Emit suggestion about __attribute_((const)) for DECL. KNOWN_FINITE
213 is true if the function is known to be finite. */
215 static void
216 warn_function_const (tree decl, bool known_finite)
218 static hash_set<tree> *warned_about;
219 warned_about
220 = suggest_attribute (OPT_Wsuggest_attribute_const, decl,
221 known_finite, warned_about, "const");
224 static void
225 warn_function_noreturn (tree decl)
227 static hash_set<tree> *warned_about;
228 if (!lang_hooks.missing_noreturn_ok_p (decl)
229 && targetm.warn_func_return (decl))
230 warned_about
231 = suggest_attribute (OPT_Wsuggest_attribute_noreturn, decl,
232 true, warned_about, "noreturn");
235 /* Return true if we have a function state for NODE. */
237 static inline bool
238 has_function_state (struct cgraph_node *node)
240 if (!funct_state_vec.exists ()
241 || funct_state_vec.length () <= (unsigned int)node->uid)
242 return false;
243 return funct_state_vec[node->uid] != NULL;
246 /* Return the function state from NODE. */
248 static inline funct_state
249 get_function_state (struct cgraph_node *node)
251 if (!funct_state_vec.exists ()
252 || funct_state_vec.length () <= (unsigned int)node->uid
253 || !funct_state_vec[node->uid])
254 /* We might want to put correct previously_known state into varying. */
255 return &varying_state;
256 return funct_state_vec[node->uid];
259 /* Set the function state S for NODE. */
261 static inline void
262 set_function_state (struct cgraph_node *node, funct_state s)
264 if (!funct_state_vec.exists ()
265 || funct_state_vec.length () <= (unsigned int)node->uid)
266 funct_state_vec.safe_grow_cleared (node->uid + 1);
267 funct_state_vec[node->uid] = s;
270 /* Check to see if the use (or definition when CHECKING_WRITE is true)
271 variable T is legal in a function that is either pure or const. */
273 static inline void
274 check_decl (funct_state local,
275 tree t, bool checking_write, bool ipa)
277 /* Do not want to do anything with volatile except mark any
278 function that uses one to be not const or pure. */
279 if (TREE_THIS_VOLATILE (t))
281 local->pure_const_state = IPA_NEITHER;
282 if (dump_file)
283 fprintf (dump_file, " Volatile operand is not const/pure");
284 return;
287 /* Do not care about a local automatic that is not static. */
288 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
289 return;
291 /* If the variable has the "used" attribute, treat it as if it had a
292 been touched by the devil. */
293 if (DECL_PRESERVE_P (t))
295 local->pure_const_state = IPA_NEITHER;
296 if (dump_file)
297 fprintf (dump_file, " Used static/global variable is not const/pure\n");
298 return;
301 /* In IPA mode we are not interested in checking actual loads and stores;
302 they will be processed at propagation time using ipa_ref. */
303 if (ipa)
304 return;
306 /* Since we have dealt with the locals and params cases above, if we
307 are CHECKING_WRITE, this cannot be a pure or constant
308 function. */
309 if (checking_write)
311 local->pure_const_state = IPA_NEITHER;
312 if (dump_file)
313 fprintf (dump_file, " static/global memory write is not const/pure\n");
314 return;
317 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
319 /* Readonly reads are safe. */
320 if (TREE_READONLY (t) && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
321 return; /* Read of a constant, do not change the function state. */
322 else
324 if (dump_file)
325 fprintf (dump_file, " global memory read is not const\n");
326 /* Just a regular read. */
327 if (local->pure_const_state == IPA_CONST)
328 local->pure_const_state = IPA_PURE;
331 else
333 /* Compilation level statics can be read if they are readonly
334 variables. */
335 if (TREE_READONLY (t))
336 return;
338 if (dump_file)
339 fprintf (dump_file, " static memory read is not const\n");
340 /* Just a regular read. */
341 if (local->pure_const_state == IPA_CONST)
342 local->pure_const_state = IPA_PURE;
347 /* Check to see if the use (or definition when CHECKING_WRITE is true)
348 variable T is legal in a function that is either pure or const. */
350 static inline void
351 check_op (funct_state local, tree t, bool checking_write)
353 t = get_base_address (t);
354 if (t && TREE_THIS_VOLATILE (t))
356 local->pure_const_state = IPA_NEITHER;
357 if (dump_file)
358 fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
359 return;
361 else if (t
362 && (INDIRECT_REF_P (t) || TREE_CODE (t) == MEM_REF)
363 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
364 && !ptr_deref_may_alias_global_p (TREE_OPERAND (t, 0)))
366 if (dump_file)
367 fprintf (dump_file, " Indirect ref to local memory is OK\n");
368 return;
370 else if (checking_write)
372 local->pure_const_state = IPA_NEITHER;
373 if (dump_file)
374 fprintf (dump_file, " Indirect ref write is not const/pure\n");
375 return;
377 else
379 if (dump_file)
380 fprintf (dump_file, " Indirect ref read is not const\n");
381 if (local->pure_const_state == IPA_CONST)
382 local->pure_const_state = IPA_PURE;
386 /* compute state based on ECF FLAGS and store to STATE and LOOPING. */
388 static void
389 state_from_flags (enum pure_const_state_e *state, bool *looping,
390 int flags, bool cannot_lead_to_return)
392 *looping = false;
393 if (flags & ECF_LOOPING_CONST_OR_PURE)
395 *looping = true;
396 if (dump_file && (dump_flags & TDF_DETAILS))
397 fprintf (dump_file, " looping");
399 if (flags & ECF_CONST)
401 *state = IPA_CONST;
402 if (dump_file && (dump_flags & TDF_DETAILS))
403 fprintf (dump_file, " const\n");
405 else if (flags & ECF_PURE)
407 *state = IPA_PURE;
408 if (dump_file && (dump_flags & TDF_DETAILS))
409 fprintf (dump_file, " pure\n");
411 else if (cannot_lead_to_return)
413 *state = IPA_PURE;
414 *looping = true;
415 if (dump_file && (dump_flags & TDF_DETAILS))
416 fprintf (dump_file, " ignoring side effects->pure looping\n");
418 else
420 if (dump_file && (dump_flags & TDF_DETAILS))
421 fprintf (dump_file, " neither\n");
422 *state = IPA_NEITHER;
423 *looping = true;
427 /* Merge STATE and STATE2 and LOOPING and LOOPING2 and store
428 into STATE and LOOPING better of the two variants.
429 Be sure to merge looping correctly. IPA_NEITHER functions
430 have looping 0 even if they don't have to return. */
432 static inline void
433 better_state (enum pure_const_state_e *state, bool *looping,
434 enum pure_const_state_e state2, bool looping2)
436 if (state2 < *state)
438 if (*state == IPA_NEITHER)
439 *looping = looping2;
440 else
441 *looping = MIN (*looping, looping2);
442 *state = state2;
444 else if (state2 != IPA_NEITHER)
445 *looping = MIN (*looping, looping2);
448 /* Merge STATE and STATE2 and LOOPING and LOOPING2 and store
449 into STATE and LOOPING worse of the two variants. */
451 static inline void
452 worse_state (enum pure_const_state_e *state, bool *looping,
453 enum pure_const_state_e state2, bool looping2)
455 *state = MAX (*state, state2);
456 *looping = MAX (*looping, looping2);
459 /* Recognize special cases of builtins that are by themselves not pure or const
460 but function using them is. */
461 static bool
462 special_builtin_state (enum pure_const_state_e *state, bool *looping,
463 tree callee)
465 if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
466 switch (DECL_FUNCTION_CODE (callee))
468 case BUILT_IN_RETURN:
469 case BUILT_IN_UNREACHABLE:
470 case BUILT_IN_ALLOCA:
471 case BUILT_IN_ALLOCA_WITH_ALIGN:
472 case BUILT_IN_STACK_SAVE:
473 case BUILT_IN_STACK_RESTORE:
474 case BUILT_IN_EH_POINTER:
475 case BUILT_IN_EH_FILTER:
476 case BUILT_IN_UNWIND_RESUME:
477 case BUILT_IN_CXA_END_CLEANUP:
478 case BUILT_IN_EH_COPY_VALUES:
479 case BUILT_IN_FRAME_ADDRESS:
480 case BUILT_IN_APPLY:
481 case BUILT_IN_APPLY_ARGS:
482 *looping = false;
483 *state = IPA_CONST;
484 return true;
485 case BUILT_IN_PREFETCH:
486 *looping = true;
487 *state = IPA_CONST;
488 return true;
489 default:
490 break;
492 return false;
495 /* Check the parameters of a function call to CALL_EXPR to see if
496 there are any references in the parameters that are not allowed for
497 pure or const functions. Also check to see if this is either an
498 indirect call, a call outside the compilation unit, or has special
499 attributes that may also effect the purity. The CALL_EXPR node for
500 the entire call expression. */
502 static void
503 check_call (funct_state local, gimple call, bool ipa)
505 int flags = gimple_call_flags (call);
506 tree callee_t = gimple_call_fndecl (call);
507 bool possibly_throws = stmt_could_throw_p (call);
508 bool possibly_throws_externally = (possibly_throws
509 && stmt_can_throw_external (call));
511 if (possibly_throws)
513 unsigned int i;
514 for (i = 0; i < gimple_num_ops (call); i++)
515 if (gimple_op (call, i)
516 && tree_could_throw_p (gimple_op (call, i)))
518 if (possibly_throws && cfun->can_throw_non_call_exceptions)
520 if (dump_file)
521 fprintf (dump_file, " operand can throw; looping\n");
522 local->looping = true;
524 if (possibly_throws_externally)
526 if (dump_file)
527 fprintf (dump_file, " operand can throw externally\n");
528 local->can_throw = true;
533 /* The const and pure flags are set by a variety of places in the
534 compiler (including here). If someone has already set the flags
535 for the callee, (such as for some of the builtins) we will use
536 them, otherwise we will compute our own information.
538 Const and pure functions have less clobber effects than other
539 functions so we process these first. Otherwise if it is a call
540 outside the compilation unit or an indirect call we punt. This
541 leaves local calls which will be processed by following the call
542 graph. */
543 if (callee_t)
545 enum pure_const_state_e call_state;
546 bool call_looping;
548 if (special_builtin_state (&call_state, &call_looping, callee_t))
550 worse_state (&local->pure_const_state, &local->looping,
551 call_state, call_looping);
552 return;
554 /* When bad things happen to bad functions, they cannot be const
555 or pure. */
556 if (setjmp_call_p (callee_t))
558 if (dump_file)
559 fprintf (dump_file, " setjmp is not const/pure\n");
560 local->looping = true;
561 local->pure_const_state = IPA_NEITHER;
564 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
565 switch (DECL_FUNCTION_CODE (callee_t))
567 case BUILT_IN_LONGJMP:
568 case BUILT_IN_NONLOCAL_GOTO:
569 if (dump_file)
570 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
571 local->pure_const_state = IPA_NEITHER;
572 local->looping = true;
573 break;
574 default:
575 break;
579 /* When not in IPA mode, we can still handle self recursion. */
580 if (!ipa && callee_t
581 && recursive_call_p (current_function_decl, callee_t))
583 if (dump_file)
584 fprintf (dump_file, " Recursive call can loop.\n");
585 local->looping = true;
587 /* Either callee is unknown or we are doing local analysis.
588 Look to see if there are any bits available for the callee (such as by
589 declaration or because it is builtin) and process solely on the basis of
590 those bits. */
591 else if (!ipa)
593 enum pure_const_state_e call_state;
594 bool call_looping;
595 if (possibly_throws && cfun->can_throw_non_call_exceptions)
597 if (dump_file)
598 fprintf (dump_file, " can throw; looping\n");
599 local->looping = true;
601 if (possibly_throws_externally)
603 if (dump_file)
605 fprintf (dump_file, " can throw externally to lp %i\n",
606 lookup_stmt_eh_lp (call));
607 if (callee_t)
608 fprintf (dump_file, " callee:%s\n",
609 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
611 local->can_throw = true;
613 if (dump_file && (dump_flags & TDF_DETAILS))
614 fprintf (dump_file, " checking flags for call:");
615 state_from_flags (&call_state, &call_looping, flags,
616 ((flags & (ECF_NORETURN | ECF_NOTHROW))
617 == (ECF_NORETURN | ECF_NOTHROW))
618 || (!flag_exceptions && (flags & ECF_NORETURN)));
619 worse_state (&local->pure_const_state, &local->looping,
620 call_state, call_looping);
622 /* Direct functions calls are handled by IPA propagation. */
625 /* Wrapper around check_decl for loads in local more. */
627 static bool
628 check_load (gimple, tree op, tree, void *data)
630 if (DECL_P (op))
631 check_decl ((funct_state)data, op, false, false);
632 else
633 check_op ((funct_state)data, op, false);
634 return false;
637 /* Wrapper around check_decl for stores in local more. */
639 static bool
640 check_store (gimple, tree op, tree, void *data)
642 if (DECL_P (op))
643 check_decl ((funct_state)data, op, true, false);
644 else
645 check_op ((funct_state)data, op, true);
646 return false;
649 /* Wrapper around check_decl for loads in ipa mode. */
651 static bool
652 check_ipa_load (gimple, tree op, tree, void *data)
654 if (DECL_P (op))
655 check_decl ((funct_state)data, op, false, true);
656 else
657 check_op ((funct_state)data, op, false);
658 return false;
661 /* Wrapper around check_decl for stores in ipa mode. */
663 static bool
664 check_ipa_store (gimple, tree op, tree, void *data)
666 if (DECL_P (op))
667 check_decl ((funct_state)data, op, true, true);
668 else
669 check_op ((funct_state)data, op, true);
670 return false;
673 /* Look into pointer pointed to by GSIP and figure out what interesting side
674 effects it has. */
675 static void
676 check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
678 gimple stmt = gsi_stmt (*gsip);
680 if (is_gimple_debug (stmt))
681 return;
683 if (dump_file)
685 fprintf (dump_file, " scanning: ");
686 print_gimple_stmt (dump_file, stmt, 0, 0);
689 if (gimple_has_volatile_ops (stmt)
690 && !gimple_clobber_p (stmt))
692 local->pure_const_state = IPA_NEITHER;
693 if (dump_file)
694 fprintf (dump_file, " Volatile stmt is not const/pure\n");
697 /* Look for loads and stores. */
698 walk_stmt_load_store_ops (stmt, local,
699 ipa ? check_ipa_load : check_load,
700 ipa ? check_ipa_store : check_store);
702 if (gimple_code (stmt) != GIMPLE_CALL
703 && stmt_could_throw_p (stmt))
705 if (cfun->can_throw_non_call_exceptions)
707 if (dump_file)
708 fprintf (dump_file, " can throw; looping\n");
709 local->looping = true;
711 if (stmt_can_throw_external (stmt))
713 if (dump_file)
714 fprintf (dump_file, " can throw externally\n");
715 local->can_throw = true;
717 else
718 if (dump_file)
719 fprintf (dump_file, " can throw\n");
721 switch (gimple_code (stmt))
723 case GIMPLE_CALL:
724 check_call (local, stmt, ipa);
725 break;
726 case GIMPLE_LABEL:
727 if (DECL_NONLOCAL (gimple_label_label (stmt)))
728 /* Target of long jump. */
730 if (dump_file)
731 fprintf (dump_file, " nonlocal label is not const/pure\n");
732 local->pure_const_state = IPA_NEITHER;
734 break;
735 case GIMPLE_ASM:
736 if (gimple_asm_clobbers_memory_p (stmt))
738 if (dump_file)
739 fprintf (dump_file, " memory asm clobber is not const/pure\n");
740 /* Abandon all hope, ye who enter here. */
741 local->pure_const_state = IPA_NEITHER;
743 if (gimple_asm_volatile_p (stmt))
745 if (dump_file)
746 fprintf (dump_file, " volatile is not const/pure\n");
747 /* Abandon all hope, ye who enter here. */
748 local->pure_const_state = IPA_NEITHER;
749 local->looping = true;
751 return;
752 default:
753 break;
758 /* This is the main routine for finding the reference patterns for
759 global variables within a function FN. */
761 static funct_state
762 analyze_function (struct cgraph_node *fn, bool ipa)
764 tree decl = fn->decl;
765 funct_state l;
766 basic_block this_block;
768 l = XCNEW (struct funct_state_d);
769 l->pure_const_state = IPA_CONST;
770 l->state_previously_known = IPA_NEITHER;
771 l->looping_previously_known = true;
772 l->looping = false;
773 l->can_throw = false;
774 state_from_flags (&l->state_previously_known, &l->looping_previously_known,
775 flags_from_decl_or_type (fn->decl),
776 fn->cannot_return_p ());
778 if (fn->thunk.thunk_p || fn->alias)
780 /* Thunk gets propagated through, so nothing interesting happens. */
781 gcc_assert (ipa);
782 return l;
785 if (dump_file)
787 fprintf (dump_file, "\n\n local analysis of %s\n ",
788 fn->name ());
791 push_cfun (DECL_STRUCT_FUNCTION (decl));
793 FOR_EACH_BB_FN (this_block, cfun)
795 gimple_stmt_iterator gsi;
796 struct walk_stmt_info wi;
798 memset (&wi, 0, sizeof (wi));
799 for (gsi = gsi_start_bb (this_block);
800 !gsi_end_p (gsi);
801 gsi_next (&gsi))
803 check_stmt (&gsi, l, ipa);
804 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
805 goto end;
809 end:
810 if (l->pure_const_state != IPA_NEITHER)
812 /* Const functions cannot have back edges (an
813 indication of possible infinite loop side
814 effect. */
815 if (mark_dfs_back_edges ())
817 /* Preheaders are needed for SCEV to work.
818 Simple latches and recorded exits improve chances that loop will
819 proved to be finite in testcases such as in loop-15.c
820 and loop-24.c */
821 loop_optimizer_init (LOOPS_HAVE_PREHEADERS
822 | LOOPS_HAVE_SIMPLE_LATCHES
823 | LOOPS_HAVE_RECORDED_EXITS);
824 if (dump_file && (dump_flags & TDF_DETAILS))
825 flow_loops_dump (dump_file, NULL, 0);
826 if (mark_irreducible_loops ())
828 if (dump_file)
829 fprintf (dump_file, " has irreducible loops\n");
830 l->looping = true;
832 else
834 struct loop *loop;
835 scev_initialize ();
836 FOR_EACH_LOOP (loop, 0)
837 if (!finite_loop_p (loop))
839 if (dump_file)
840 fprintf (dump_file, " can not prove finiteness of "
841 "loop %i\n", loop->num);
842 l->looping =true;
843 break;
845 scev_finalize ();
847 loop_optimizer_finalize ();
851 if (dump_file && (dump_flags & TDF_DETAILS))
852 fprintf (dump_file, " checking previously known:");
854 better_state (&l->pure_const_state, &l->looping,
855 l->state_previously_known,
856 l->looping_previously_known);
857 if (TREE_NOTHROW (decl))
858 l->can_throw = false;
860 pop_cfun ();
861 if (dump_file)
863 if (l->looping)
864 fprintf (dump_file, "Function is locally looping.\n");
865 if (l->can_throw)
866 fprintf (dump_file, "Function is locally throwing.\n");
867 if (l->pure_const_state == IPA_CONST)
868 fprintf (dump_file, "Function is locally const.\n");
869 if (l->pure_const_state == IPA_PURE)
870 fprintf (dump_file, "Function is locally pure.\n");
872 return l;
875 /* Called when new function is inserted to callgraph late. */
876 static void
877 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
879 if (node->get_availability () < AVAIL_INTERPOSABLE)
880 return;
881 /* There are some shared nodes, in particular the initializers on
882 static declarations. We do not need to scan them more than once
883 since all we would be interested in are the addressof
884 operations. */
885 if (node->get_availability () > AVAIL_INTERPOSABLE)
886 set_function_state (node, analyze_function (node, true));
889 /* Called when new clone is inserted to callgraph late. */
891 static void
892 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
893 void *data ATTRIBUTE_UNUSED)
895 if (has_function_state (src))
897 funct_state l = XNEW (struct funct_state_d);
898 gcc_assert (!has_function_state (dst));
899 memcpy (l, get_function_state (src), sizeof (*l));
900 set_function_state (dst, l);
904 /* Called when new clone is inserted to callgraph late. */
906 static void
907 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
909 if (has_function_state (node))
911 funct_state l = get_function_state (node);
912 if (l != &varying_state)
913 free (l);
914 set_function_state (node, NULL);
919 void
920 pass_ipa_pure_const::
921 register_hooks (void)
923 if (init_p)
924 return;
926 init_p = true;
928 node_removal_hook_holder =
929 symtab->add_cgraph_removal_hook (&remove_node_data, NULL);
930 node_duplication_hook_holder =
931 symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL);
932 function_insertion_hook_holder =
933 symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
937 /* Analyze each function in the cgraph to see if it is locally PURE or
938 CONST. */
940 static void
941 pure_const_generate_summary (void)
943 struct cgraph_node *node;
945 pass_ipa_pure_const *pass = static_cast <pass_ipa_pure_const *> (current_pass);
946 pass->register_hooks ();
948 /* Process all of the functions.
950 We process AVAIL_INTERPOSABLE functions. We can not use the results
951 by default, but the info can be used at LTO with -fwhole-program or
952 when function got cloned and the clone is AVAILABLE. */
954 FOR_EACH_DEFINED_FUNCTION (node)
955 if (node->get_availability () >= AVAIL_INTERPOSABLE)
956 set_function_state (node, analyze_function (node, true));
960 /* Serialize the ipa info for lto. */
962 static void
963 pure_const_write_summary (void)
965 struct cgraph_node *node;
966 struct lto_simple_output_block *ob
967 = lto_create_simple_output_block (LTO_section_ipa_pure_const);
968 unsigned int count = 0;
969 lto_symtab_encoder_iterator lsei;
970 lto_symtab_encoder_t encoder;
972 encoder = lto_get_out_decl_state ()->symtab_node_encoder;
974 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
975 lsei_next_function_in_partition (&lsei))
977 node = lsei_cgraph_node (lsei);
978 if (node->definition && has_function_state (node))
979 count++;
982 streamer_write_uhwi_stream (ob->main_stream, count);
984 /* Process all of the functions. */
985 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
986 lsei_next_function_in_partition (&lsei))
988 node = lsei_cgraph_node (lsei);
989 if (node->definition && has_function_state (node))
991 struct bitpack_d bp;
992 funct_state fs;
993 int node_ref;
994 lto_symtab_encoder_t encoder;
996 fs = get_function_state (node);
998 encoder = ob->decl_state->symtab_node_encoder;
999 node_ref = lto_symtab_encoder_encode (encoder, node);
1000 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1002 /* Note that flags will need to be read in the opposite
1003 order as we are pushing the bitflags into FLAGS. */
1004 bp = bitpack_create (ob->main_stream);
1005 bp_pack_value (&bp, fs->pure_const_state, 2);
1006 bp_pack_value (&bp, fs->state_previously_known, 2);
1007 bp_pack_value (&bp, fs->looping_previously_known, 1);
1008 bp_pack_value (&bp, fs->looping, 1);
1009 bp_pack_value (&bp, fs->can_throw, 1);
1010 streamer_write_bitpack (&bp);
1014 lto_destroy_simple_output_block (ob);
1018 /* Deserialize the ipa info for lto. */
1020 static void
1021 pure_const_read_summary (void)
1023 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
1024 struct lto_file_decl_data *file_data;
1025 unsigned int j = 0;
1027 pass_ipa_pure_const *pass = static_cast <pass_ipa_pure_const *> (current_pass);
1028 pass->register_hooks ();
1030 while ((file_data = file_data_vec[j++]))
1032 const char *data;
1033 size_t len;
1034 struct lto_input_block *ib
1035 = lto_create_simple_input_block (file_data,
1036 LTO_section_ipa_pure_const,
1037 &data, &len);
1038 if (ib)
1040 unsigned int i;
1041 unsigned int count = streamer_read_uhwi (ib);
1043 for (i = 0; i < count; i++)
1045 unsigned int index;
1046 struct cgraph_node *node;
1047 struct bitpack_d bp;
1048 funct_state fs;
1049 lto_symtab_encoder_t encoder;
1051 fs = XCNEW (struct funct_state_d);
1052 index = streamer_read_uhwi (ib);
1053 encoder = file_data->symtab_node_encoder;
1054 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
1055 index));
1056 set_function_state (node, fs);
1058 /* Note that the flags must be read in the opposite
1059 order in which they were written (the bitflags were
1060 pushed into FLAGS). */
1061 bp = streamer_read_bitpack (ib);
1062 fs->pure_const_state
1063 = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
1064 fs->state_previously_known
1065 = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
1066 fs->looping_previously_known = bp_unpack_value (&bp, 1);
1067 fs->looping = bp_unpack_value (&bp, 1);
1068 fs->can_throw = bp_unpack_value (&bp, 1);
1069 if (dump_file)
1071 int flags = flags_from_decl_or_type (node->decl);
1072 fprintf (dump_file, "Read info for %s/%i ",
1073 node->name (),
1074 node->order);
1075 if (flags & ECF_CONST)
1076 fprintf (dump_file, " const");
1077 if (flags & ECF_PURE)
1078 fprintf (dump_file, " pure");
1079 if (flags & ECF_NOTHROW)
1080 fprintf (dump_file, " nothrow");
1081 fprintf (dump_file, "\n pure const state: %s\n",
1082 pure_const_names[fs->pure_const_state]);
1083 fprintf (dump_file, " previously known state: %s\n",
1084 pure_const_names[fs->looping_previously_known]);
1085 if (fs->looping)
1086 fprintf (dump_file," function is locally looping\n");
1087 if (fs->looping_previously_known)
1088 fprintf (dump_file," function is previously known looping\n");
1089 if (fs->can_throw)
1090 fprintf (dump_file," function is locally throwing\n");
1094 lto_destroy_simple_input_block (file_data,
1095 LTO_section_ipa_pure_const,
1096 ib, data, len);
1102 static bool
1103 ignore_edge (struct cgraph_edge *e)
1105 return (!e->can_throw_external);
1108 /* Return true if NODE is self recursive function.
1109 Indirectly recursive functions appears as non-trivial strongly
1110 connected components, so we need to care about self recursion
1111 only. */
1113 static bool
1114 self_recursive_p (struct cgraph_node *node)
1116 struct cgraph_edge *e;
1117 for (e = node->callees; e; e = e->next_callee)
1118 if (e->callee->function_symbol () == node)
1119 return true;
1120 return false;
1123 /* Produce transitive closure over the callgraph and compute pure/const
1124 attributes. */
1126 static void
1127 propagate_pure_const (void)
1129 struct cgraph_node *node;
1130 struct cgraph_node *w;
1131 struct cgraph_node **order =
1132 XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
1133 int order_pos;
1134 int i;
1135 struct ipa_dfs_info * w_info;
1137 order_pos = ipa_reduced_postorder (order, true, false, NULL);
1138 if (dump_file)
1140 cgraph_node::dump_cgraph (dump_file);
1141 ipa_print_order (dump_file, "reduced", order, order_pos);
1144 /* Propagate the local information through the call graph to produce
1145 the global information. All the nodes within a cycle will have
1146 the same info so we collapse cycles first. Then we can do the
1147 propagation in one pass from the leaves to the roots. */
1148 for (i = 0; i < order_pos; i++ )
1150 enum pure_const_state_e pure_const_state = IPA_CONST;
1151 bool looping = false;
1152 int count = 0;
1153 node = order[i];
1155 if (node->alias)
1156 continue;
1158 if (dump_file && (dump_flags & TDF_DETAILS))
1159 fprintf (dump_file, "Starting cycle\n");
1161 /* Find the worst state for any node in the cycle. */
1162 w = node;
1163 while (w && pure_const_state != IPA_NEITHER)
1165 struct cgraph_edge *e;
1166 struct cgraph_edge *ie;
1167 int i;
1168 struct ipa_ref *ref = NULL;
1170 funct_state w_l = get_function_state (w);
1171 if (dump_file && (dump_flags & TDF_DETAILS))
1172 fprintf (dump_file, " Visiting %s/%i state:%s looping %i\n",
1173 w->name (),
1174 w->order,
1175 pure_const_names[w_l->pure_const_state],
1176 w_l->looping);
1178 /* First merge in function body properties. */
1179 worse_state (&pure_const_state, &looping,
1180 w_l->pure_const_state, w_l->looping);
1181 if (pure_const_state == IPA_NEITHER)
1182 break;
1184 /* For overwritable nodes we can not assume anything. */
1185 if (w->get_availability () == AVAIL_INTERPOSABLE)
1187 worse_state (&pure_const_state, &looping,
1188 w_l->state_previously_known,
1189 w_l->looping_previously_known);
1190 if (dump_file && (dump_flags & TDF_DETAILS))
1192 fprintf (dump_file,
1193 " Overwritable. state %s looping %i\n",
1194 pure_const_names[w_l->state_previously_known],
1195 w_l->looping_previously_known);
1197 break;
1200 count++;
1202 /* We consider recursive cycles as possibly infinite.
1203 This might be relaxed since infinite recursion leads to stack
1204 overflow. */
1205 if (count > 1)
1206 looping = true;
1208 /* Now walk the edges and merge in callee properties. */
1209 for (e = w->callees; e; e = e->next_callee)
1211 enum availability avail;
1212 struct cgraph_node *y = e->callee->function_symbol (&avail);
1213 enum pure_const_state_e edge_state = IPA_CONST;
1214 bool edge_looping = false;
1216 if (dump_file && (dump_flags & TDF_DETAILS))
1218 fprintf (dump_file,
1219 " Call to %s/%i",
1220 e->callee->name (),
1221 e->callee->order);
1223 if (avail > AVAIL_INTERPOSABLE)
1225 funct_state y_l = get_function_state (y);
1226 if (dump_file && (dump_flags & TDF_DETAILS))
1228 fprintf (dump_file,
1229 " state:%s looping:%i\n",
1230 pure_const_names[y_l->pure_const_state],
1231 y_l->looping);
1233 if (y_l->pure_const_state > IPA_PURE
1234 && e->cannot_lead_to_return_p ())
1236 if (dump_file && (dump_flags & TDF_DETAILS))
1237 fprintf (dump_file,
1238 " Ignoring side effects"
1239 " -> pure, looping\n");
1240 edge_state = IPA_PURE;
1241 edge_looping = true;
1243 else
1245 edge_state = y_l->pure_const_state;
1246 edge_looping = y_l->looping;
1249 else if (special_builtin_state (&edge_state, &edge_looping,
1250 y->decl))
1252 else
1253 state_from_flags (&edge_state, &edge_looping,
1254 flags_from_decl_or_type (y->decl),
1255 e->cannot_lead_to_return_p ());
1257 /* Merge the results with what we already know. */
1258 better_state (&edge_state, &edge_looping,
1259 w_l->state_previously_known,
1260 w_l->looping_previously_known);
1261 worse_state (&pure_const_state, &looping,
1262 edge_state, edge_looping);
1263 if (pure_const_state == IPA_NEITHER)
1264 break;
1266 if (pure_const_state == IPA_NEITHER)
1267 break;
1269 /* Now process the indirect call. */
1270 for (ie = w->indirect_calls; ie; ie = ie->next_callee)
1272 enum pure_const_state_e edge_state = IPA_CONST;
1273 bool edge_looping = false;
1275 if (dump_file && (dump_flags & TDF_DETAILS))
1276 fprintf (dump_file, " Indirect call");
1277 state_from_flags (&edge_state, &edge_looping,
1278 ie->indirect_info->ecf_flags,
1279 ie->cannot_lead_to_return_p ());
1280 /* Merge the results with what we already know. */
1281 better_state (&edge_state, &edge_looping,
1282 w_l->state_previously_known,
1283 w_l->looping_previously_known);
1284 worse_state (&pure_const_state, &looping,
1285 edge_state, edge_looping);
1286 if (pure_const_state == IPA_NEITHER)
1287 break;
1289 if (pure_const_state == IPA_NEITHER)
1290 break;
1292 /* And finally all loads and stores. */
1293 for (i = 0; w->iterate_reference (i, ref); i++)
1295 enum pure_const_state_e ref_state = IPA_CONST;
1296 bool ref_looping = false;
1297 switch (ref->use)
1299 case IPA_REF_LOAD:
1300 /* readonly reads are safe. */
1301 if (TREE_READONLY (ref->referred->decl))
1302 break;
1303 if (dump_file && (dump_flags & TDF_DETAILS))
1304 fprintf (dump_file, " nonreadonly global var read\n");
1305 ref_state = IPA_PURE;
1306 break;
1307 case IPA_REF_STORE:
1308 if (ref->cannot_lead_to_return ())
1309 break;
1310 ref_state = IPA_NEITHER;
1311 if (dump_file && (dump_flags & TDF_DETAILS))
1312 fprintf (dump_file, " global var write\n");
1313 break;
1314 case IPA_REF_ADDR:
1315 break;
1316 default:
1317 gcc_unreachable ();
1319 better_state (&ref_state, &ref_looping,
1320 w_l->state_previously_known,
1321 w_l->looping_previously_known);
1322 worse_state (&pure_const_state, &looping,
1323 ref_state, ref_looping);
1324 if (pure_const_state == IPA_NEITHER)
1325 break;
1327 w_info = (struct ipa_dfs_info *) w->aux;
1328 w = w_info->next_cycle;
1330 if (dump_file && (dump_flags & TDF_DETAILS))
1331 fprintf (dump_file, "Result %s looping %i\n",
1332 pure_const_names [pure_const_state],
1333 looping);
1335 /* Copy back the region's pure_const_state which is shared by
1336 all nodes in the region. */
1337 w = node;
1338 while (w)
1340 funct_state w_l = get_function_state (w);
1341 enum pure_const_state_e this_state = pure_const_state;
1342 bool this_looping = looping;
1344 if (w_l->state_previously_known != IPA_NEITHER
1345 && this_state > w_l->state_previously_known)
1347 this_state = w_l->state_previously_known;
1348 this_looping |= w_l->looping_previously_known;
1350 if (!this_looping && self_recursive_p (w))
1351 this_looping = true;
1352 if (!w_l->looping_previously_known)
1353 this_looping = false;
1355 /* All nodes within a cycle share the same info. */
1356 w_l->pure_const_state = this_state;
1357 w_l->looping = this_looping;
1359 /* Inline clones share declaration with their offline copies;
1360 do not modify their declarations since the offline copy may
1361 be different. */
1362 if (!w->global.inlined_to)
1363 switch (this_state)
1365 case IPA_CONST:
1366 if (!TREE_READONLY (w->decl))
1368 warn_function_const (w->decl, !this_looping);
1369 if (dump_file)
1370 fprintf (dump_file, "Function found to be %sconst: %s\n",
1371 this_looping ? "looping " : "",
1372 w->name ());
1374 w->set_const_flag (true, this_looping);
1375 break;
1377 case IPA_PURE:
1378 if (!DECL_PURE_P (w->decl))
1380 warn_function_pure (w->decl, !this_looping);
1381 if (dump_file)
1382 fprintf (dump_file, "Function found to be %spure: %s\n",
1383 this_looping ? "looping " : "",
1384 w->name ());
1386 w->set_pure_flag (true, this_looping);
1387 break;
1389 default:
1390 break;
1392 w_info = (struct ipa_dfs_info *) w->aux;
1393 w = w_info->next_cycle;
1397 ipa_free_postorder_info ();
1398 free (order);
1401 /* Produce transitive closure over the callgraph and compute nothrow
1402 attributes. */
1404 static void
1405 propagate_nothrow (void)
1407 struct cgraph_node *node;
1408 struct cgraph_node *w;
1409 struct cgraph_node **order =
1410 XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
1411 int order_pos;
1412 int i;
1413 struct ipa_dfs_info * w_info;
1415 order_pos = ipa_reduced_postorder (order, true, false, ignore_edge);
1416 if (dump_file)
1418 cgraph_node::dump_cgraph (dump_file);
1419 ipa_print_order (dump_file, "reduced for nothrow", order, order_pos);
1422 /* Propagate the local information through the call graph to produce
1423 the global information. All the nodes within a cycle will have
1424 the same info so we collapse cycles first. Then we can do the
1425 propagation in one pass from the leaves to the roots. */
1426 for (i = 0; i < order_pos; i++ )
1428 bool can_throw = false;
1429 node = order[i];
1431 if (node->alias)
1432 continue;
1434 /* Find the worst state for any node in the cycle. */
1435 w = node;
1436 while (w)
1438 struct cgraph_edge *e, *ie;
1439 funct_state w_l = get_function_state (w);
1441 if (w_l->can_throw
1442 || w->get_availability () == AVAIL_INTERPOSABLE)
1443 can_throw = true;
1445 if (can_throw)
1446 break;
1448 for (e = w->callees; e; e = e->next_callee)
1450 enum availability avail;
1451 struct cgraph_node *y = e->callee->function_symbol (&avail);
1453 if (avail > AVAIL_INTERPOSABLE)
1455 funct_state y_l = get_function_state (y);
1457 if (can_throw)
1458 break;
1459 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
1460 && e->can_throw_external)
1461 can_throw = true;
1463 else if (e->can_throw_external && !TREE_NOTHROW (y->decl))
1464 can_throw = true;
1466 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1467 if (ie->can_throw_external)
1469 can_throw = true;
1470 break;
1472 w_info = (struct ipa_dfs_info *) w->aux;
1473 w = w_info->next_cycle;
1476 /* Copy back the region's pure_const_state which is shared by
1477 all nodes in the region. */
1478 w = node;
1479 while (w)
1481 funct_state w_l = get_function_state (w);
1482 if (!can_throw && !TREE_NOTHROW (w->decl))
1484 /* Inline clones share declaration with their offline copies;
1485 do not modify their declarations since the offline copy may
1486 be different. */
1487 if (!w->global.inlined_to)
1489 w->set_nothrow_flag (true);
1490 if (dump_file)
1491 fprintf (dump_file, "Function found to be nothrow: %s\n",
1492 w->name ());
1495 else if (can_throw && !TREE_NOTHROW (w->decl))
1496 w_l->can_throw = true;
1497 w_info = (struct ipa_dfs_info *) w->aux;
1498 w = w_info->next_cycle;
1502 ipa_free_postorder_info ();
1503 free (order);
1507 /* Produce the global information by preforming a transitive closure
1508 on the local information that was produced by generate_summary. */
1510 unsigned int
1511 pass_ipa_pure_const::
1512 execute (function *)
1514 struct cgraph_node *node;
1516 symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
1517 symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
1518 symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
1520 /* Nothrow makes more function to not lead to return and improve
1521 later analysis. */
1522 propagate_nothrow ();
1523 propagate_pure_const ();
1525 /* Cleanup. */
1526 FOR_EACH_FUNCTION (node)
1527 if (has_function_state (node))
1528 free (get_function_state (node));
1529 funct_state_vec.release ();
1530 return 0;
1533 static bool
1534 gate_pure_const (void)
1536 return (flag_ipa_pure_const
1537 /* Don't bother doing anything if the program has errors. */
1538 && !seen_error ());
1541 pass_ipa_pure_const::pass_ipa_pure_const(gcc::context *ctxt)
1542 : ipa_opt_pass_d(pass_data_ipa_pure_const, ctxt,
1543 pure_const_generate_summary, /* generate_summary */
1544 pure_const_write_summary, /* write_summary */
1545 pure_const_read_summary, /* read_summary */
1546 NULL, /* write_optimization_summary */
1547 NULL, /* read_optimization_summary */
1548 NULL, /* stmt_fixup */
1549 0, /* function_transform_todo_flags_start */
1550 NULL, /* function_transform */
1551 NULL), /* variable_transform */
1552 init_p(false),
1553 function_insertion_hook_holder(NULL),
1554 node_duplication_hook_holder(NULL),
1555 node_removal_hook_holder(NULL)
1559 ipa_opt_pass_d *
1560 make_pass_ipa_pure_const (gcc::context *ctxt)
1562 return new pass_ipa_pure_const (ctxt);
1565 /* Return true if function should be skipped for local pure const analysis. */
1567 static bool
1568 skip_function_for_local_pure_const (struct cgraph_node *node)
1570 /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations
1571 we must not promote functions that are called by already processed functions. */
1573 if (function_called_by_processed_nodes_p ())
1575 if (dump_file)
1576 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
1577 return true;
1579 if (node->get_availability () <= AVAIL_INTERPOSABLE)
1581 if (dump_file)
1582 fprintf (dump_file, "Function is not available or overwritable; not analyzing.\n");
1583 return true;
1585 return false;
1588 /* Simple local pass for pure const discovery reusing the analysis from
1589 ipa_pure_const. This pass is effective when executed together with
1590 other optimization passes in early optimization pass queue. */
1592 namespace {
1594 const pass_data pass_data_local_pure_const =
1596 GIMPLE_PASS, /* type */
1597 "local-pure-const", /* name */
1598 OPTGROUP_NONE, /* optinfo_flags */
1599 TV_IPA_PURE_CONST, /* tv_id */
1600 0, /* properties_required */
1601 0, /* properties_provided */
1602 0, /* properties_destroyed */
1603 0, /* todo_flags_start */
1604 0, /* todo_flags_finish */
1607 class pass_local_pure_const : public gimple_opt_pass
1609 public:
1610 pass_local_pure_const (gcc::context *ctxt)
1611 : gimple_opt_pass (pass_data_local_pure_const, ctxt)
1614 /* opt_pass methods: */
1615 opt_pass * clone () { return new pass_local_pure_const (m_ctxt); }
1616 virtual bool gate (function *) { return gate_pure_const (); }
1617 virtual unsigned int execute (function *);
1619 }; // class pass_local_pure_const
1621 unsigned int
1622 pass_local_pure_const::execute (function *fun)
1624 bool changed = false;
1625 funct_state l;
1626 bool skip;
1627 struct cgraph_node *node;
1629 node = cgraph_node::get (current_function_decl);
1630 skip = skip_function_for_local_pure_const (node);
1631 if (!warn_suggest_attribute_const
1632 && !warn_suggest_attribute_pure
1633 && skip)
1634 return 0;
1636 l = analyze_function (node, false);
1638 /* Do NORETURN discovery. */
1639 if (!skip && !TREE_THIS_VOLATILE (current_function_decl)
1640 && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) == 0)
1642 warn_function_noreturn (fun->decl);
1643 if (dump_file)
1644 fprintf (dump_file, "Function found to be noreturn: %s\n",
1645 current_function_name ());
1647 /* Update declaration and reduce profile to executed once. */
1648 TREE_THIS_VOLATILE (current_function_decl) = 1;
1649 if (node->frequency > NODE_FREQUENCY_EXECUTED_ONCE)
1650 node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
1652 changed = true;
1655 switch (l->pure_const_state)
1657 case IPA_CONST:
1658 if (!TREE_READONLY (current_function_decl))
1660 warn_function_const (current_function_decl, !l->looping);
1661 if (!skip)
1663 node->set_const_flag (true, l->looping);
1664 changed = true;
1666 if (dump_file)
1667 fprintf (dump_file, "Function found to be %sconst: %s\n",
1668 l->looping ? "looping " : "",
1669 current_function_name ());
1671 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1672 && !l->looping)
1674 if (!skip)
1676 node->set_const_flag (true, false);
1677 changed = true;
1679 if (dump_file)
1680 fprintf (dump_file, "Function found to be non-looping: %s\n",
1681 current_function_name ());
1683 break;
1685 case IPA_PURE:
1686 if (!DECL_PURE_P (current_function_decl))
1688 if (!skip)
1690 node->set_pure_flag (true, l->looping);
1691 changed = true;
1693 warn_function_pure (current_function_decl, !l->looping);
1694 if (dump_file)
1695 fprintf (dump_file, "Function found to be %spure: %s\n",
1696 l->looping ? "looping " : "",
1697 current_function_name ());
1699 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1700 && !l->looping)
1702 if (!skip)
1704 node->set_pure_flag (true, false);
1705 changed = true;
1707 if (dump_file)
1708 fprintf (dump_file, "Function found to be non-looping: %s\n",
1709 current_function_name ());
1711 break;
1713 default:
1714 break;
1716 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
1718 node->set_nothrow_flag (true);
1719 changed = true;
1720 if (dump_file)
1721 fprintf (dump_file, "Function found to be nothrow: %s\n",
1722 current_function_name ());
1724 free (l);
1725 if (changed)
1726 return execute_fixup_cfg ();
1727 else
1728 return 0;
1731 } // anon namespace
1733 gimple_opt_pass *
1734 make_pass_local_pure_const (gcc::context *ctxt)
1736 return new pass_local_pure_const (ctxt);
1739 /* Emit noreturn warnings. */
1741 namespace {
1743 const pass_data pass_data_warn_function_noreturn =
1745 GIMPLE_PASS, /* type */
1746 "*warn_function_noreturn", /* name */
1747 OPTGROUP_NONE, /* optinfo_flags */
1748 TV_NONE, /* tv_id */
1749 PROP_cfg, /* properties_required */
1750 0, /* properties_provided */
1751 0, /* properties_destroyed */
1752 0, /* todo_flags_start */
1753 0, /* todo_flags_finish */
1756 class pass_warn_function_noreturn : public gimple_opt_pass
1758 public:
1759 pass_warn_function_noreturn (gcc::context *ctxt)
1760 : gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
1763 /* opt_pass methods: */
1764 virtual bool gate (function *) { return warn_suggest_attribute_noreturn; }
1765 virtual unsigned int execute (function *fun)
1767 if (!TREE_THIS_VOLATILE (current_function_decl)
1768 && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) == 0)
1769 warn_function_noreturn (current_function_decl);
1770 return 0;
1773 }; // class pass_warn_function_noreturn
1775 } // anon namespace
1777 gimple_opt_pass *
1778 make_pass_warn_function_noreturn (gcc::context *ctxt)
1780 return new pass_warn_function_noreturn (ctxt);