1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008 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
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
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. */
36 #include "coretypes.h"
39 #include "tree-flow.h"
40 #include "tree-inline.h"
41 #include "tree-pass.h"
42 #include "langhooks.h"
43 #include "pointer-set.h"
45 #include "ipa-utils.h"
52 #include "diagnostic.h"
53 #include "langhooks.h"
56 static struct pointer_set_t *visited_nodes;
58 /* Lattice values for const and pure functions. Everything starts out
59 being const, then may drop to pure and then neither depending on
61 enum pure_const_state_e
68 /* Holder for the const_state. There is one of these per function
73 enum pure_const_state_e pure_const_state;
74 /* What user set here; we can be always sure about this. */
75 enum pure_const_state_e state_previously_known;
76 bool looping_previously_known;
78 /* True if the function could possibly infinite loop. There are a
79 lot of ways that this could be determined. We are pretty
80 conservative here. While it is possible to cse pure and const
81 calls, it is not legal to have dce get rid of the call if there
82 is a possibility that the call could infinite loop since this is
83 a behavioral change. */
89 typedef struct funct_state_d * funct_state;
91 /* The storage of the funct_state is abstracted because there is the
92 possibility that it may be desirable to move this to the cgraph
95 /* Array, indexed by cgraph node uid, of function states. */
97 DEF_VEC_P (funct_state);
98 DEF_VEC_ALLOC_P (funct_state, heap);
99 static VEC (funct_state, heap) *funct_state_vec;
101 /* Holders of ipa cgraph hooks: */
102 static struct cgraph_node_hook_list *function_insertion_hook_holder;
103 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
104 static struct cgraph_node_hook_list *node_removal_hook_holder;
106 /* Init the function state. */
111 free (funct_state_vec);
115 /* Return the function state from NODE. */
117 static inline funct_state
118 get_function_state (struct cgraph_node *node)
121 || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
123 return VEC_index (funct_state, funct_state_vec, node->uid);
126 /* Set the function state S for NODE. */
129 set_function_state (struct cgraph_node *node, funct_state s)
132 || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
133 VEC_safe_grow_cleared (funct_state, heap, funct_state_vec, node->uid + 1);
134 VEC_replace (funct_state, funct_state_vec, node->uid, s);
137 /* Check to see if the use (or definition when CHECKING_WRITE is true)
138 variable T is legal in a function that is either pure or const. */
141 check_decl (funct_state local,
142 tree t, bool checking_write)
144 /* Do not want to do anything with volatile except mark any
145 function that uses one to be not const or pure. */
146 if (TREE_THIS_VOLATILE (t))
148 local->pure_const_state = IPA_NEITHER;
150 fprintf (dump_file, " Volatile operand is not const/pure");
154 /* Do not care about a local automatic that is not static. */
155 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
158 /* If the variable has the "used" attribute, treat it as if it had a
159 been touched by the devil. */
160 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
162 local->pure_const_state = IPA_NEITHER;
164 fprintf (dump_file, " Used static/global variable is not const/pure\n");
168 /* Since we have dealt with the locals and params cases above, if we
169 are CHECKING_WRITE, this cannot be a pure or constant
173 local->pure_const_state = IPA_NEITHER;
175 fprintf (dump_file, " static/global memory write is not const/pure\n");
179 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
181 /* Readonly reads are safe. */
182 if (TREE_READONLY (t) && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
183 return; /* Read of a constant, do not change the function state. */
187 fprintf (dump_file, " global memory read is not const\n");
188 /* Just a regular read. */
189 if (local->pure_const_state == IPA_CONST)
190 local->pure_const_state = IPA_PURE;
195 /* Compilation level statics can be read if they are readonly
197 if (TREE_READONLY (t))
201 fprintf (dump_file, " static memory read is not const\n");
202 /* Just a regular read. */
203 if (local->pure_const_state == IPA_CONST)
204 local->pure_const_state = IPA_PURE;
209 /* Check to see if the use (or definition when CHECKING_WRITE is true)
210 variable T is legal in a function that is either pure or const. */
213 check_op (funct_state local, tree t, bool checking_write)
215 if (TREE_THIS_VOLATILE (t))
217 local->pure_const_state = IPA_NEITHER;
219 fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
222 else if (checking_write)
224 local->pure_const_state = IPA_NEITHER;
226 fprintf (dump_file, " Indirect ref write is not const/pure\n");
232 fprintf (dump_file, " Indirect ref read is not const\n");
233 if (local->pure_const_state == IPA_CONST)
234 local->pure_const_state = IPA_PURE;
238 /* Check the parameters of a function call to CALL_EXPR to see if
239 there are any references in the parameters that are not allowed for
240 pure or const functions. Also check to see if this is either an
241 indirect call, a call outside the compilation unit, or has special
242 attributes that may also effect the purity. The CALL_EXPR node for
243 the entire call expression. */
246 check_call (funct_state local, gimple call, bool ipa)
248 int flags = gimple_call_flags (call);
249 tree callee_t = gimple_call_fndecl (call);
250 struct cgraph_node* callee;
251 enum availability avail = AVAIL_NOT_AVAILABLE;
252 bool possibly_throws = stmt_could_throw_p (call);
253 bool possibly_throws_externally = (possibly_throws
254 && stmt_can_throw_external (call));
259 for (i = 0; i < gimple_num_ops (call); i++)
260 if (gimple_op (call, i)
261 && tree_could_throw_p (gimple_op (call, i)))
263 if (possibly_throws && flag_non_call_exceptions)
266 fprintf (dump_file, " operand can throw; looping\n");
267 local->looping = true;
269 if (possibly_throws_externally)
272 fprintf (dump_file, " operand can throw externally\n");
273 local->can_throw = true;
278 /* The const and pure flags are set by a variety of places in the
279 compiler (including here). If someone has already set the flags
280 for the callee, (such as for some of the builtins) we will use
281 them, otherwise we will compute our own information.
283 Const and pure functions have less clobber effects than other
284 functions so we process these first. Otherwise if it is a call
285 outside the compilation unit or an indirect call we punt. This
286 leaves local calls which will be processed by following the call
290 callee = cgraph_node(callee_t);
291 avail = cgraph_function_body_availability (callee);
293 /* When bad things happen to bad functions, they cannot be const
295 if (setjmp_call_p (callee_t))
298 fprintf (dump_file, " setjmp is not const/pure\n");
299 local->looping = true;
300 local->pure_const_state = IPA_NEITHER;
303 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
304 switch (DECL_FUNCTION_CODE (callee_t))
306 case BUILT_IN_LONGJMP:
307 case BUILT_IN_NONLOCAL_GOTO:
309 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
310 local->pure_const_state = IPA_NEITHER;
311 local->looping = true;
318 /* When not in IPA mode, we can still handle self recursion. */
319 if (!ipa && callee_t == current_function_decl)
320 local->looping = true;
321 /* The callee is either unknown (indirect call) or there is just no
322 scannable code for it (external call) . We look to see if there
323 are any bits available for the callee (such as by declaration or
324 because it is builtin) and process solely on the basis of those
326 else if (avail <= AVAIL_OVERWRITABLE || !ipa)
328 if (possibly_throws && flag_non_call_exceptions)
331 fprintf (dump_file, " can throw; looping\n");
332 local->looping = true;
334 if (possibly_throws_externally)
338 fprintf (dump_file, " can throw externally in region %i\n",
339 lookup_stmt_eh_region (call));
341 fprintf (dump_file, " callee:%s\n",
342 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
344 local->can_throw = true;
346 if (flags & ECF_CONST)
348 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
349 local->looping = true;
351 else if (flags & ECF_PURE)
353 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
354 local->looping = true;
356 fprintf (dump_file, " pure function call in not const\n");
357 if (local->pure_const_state == IPA_CONST)
358 local->pure_const_state = IPA_PURE;
363 fprintf (dump_file, " uknown function call is not const/pure\n");
364 local->pure_const_state = IPA_NEITHER;
365 local->looping = true;
368 /* Direct functions calls are handled by IPA propagation. */
371 /* Wrapper around check_decl for loads. */
374 check_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
377 check_decl ((funct_state)data, op, false);
379 check_op ((funct_state)data, op, false);
383 /* Wrapper around check_decl for stores. */
386 check_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
389 check_decl ((funct_state)data, op, true);
391 check_op ((funct_state)data, op, true);
395 /* Look into pointer pointed to by GSIP and figure out what interesting side
398 check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
400 gimple stmt = gsi_stmt (*gsip);
405 fprintf (dump_file, " scanning: ");
406 print_gimple_stmt (dump_file, stmt, 0, 0);
409 /* Look for loads and stores. */
410 walk_stmt_load_store_ops (stmt, local, check_load, check_store);
412 if (gimple_code (stmt) != GIMPLE_CALL
413 && stmt_could_throw_p (stmt))
415 if (flag_non_call_exceptions)
418 fprintf (dump_file, " can throw; looping");
419 local->looping = true;
421 if (stmt_can_throw_external (stmt))
424 fprintf (dump_file, " can throw externally");
425 local->can_throw = true;
428 switch (gimple_code (stmt))
431 check_call (local, stmt, ipa);
434 if (DECL_NONLOCAL (gimple_label_label (stmt)))
435 /* Target of long jump. */
438 fprintf (dump_file, " nonlocal label is not const/pure");
439 local->pure_const_state = IPA_NEITHER;
443 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
445 tree op = gimple_asm_clobber_op (stmt, i);
446 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
449 fprintf (dump_file, " memory asm clobber is not const/pure");
450 /* Abandon all hope, ye who enter here. */
451 local->pure_const_state = IPA_NEITHER;
454 if (gimple_asm_volatile_p (stmt))
457 fprintf (dump_file, " volatile is not const/pure");
458 /* Abandon all hope, ye who enter here. */
459 local->pure_const_state = IPA_NEITHER;
460 local->looping = true;
469 /* This is the main routine for finding the reference patterns for
470 global variables within a function FN. */
473 analyze_function (struct cgraph_node *fn, bool ipa)
475 tree decl = fn->decl;
476 tree old_decl = current_function_decl;
478 basic_block this_block;
480 if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
483 fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n");
487 l = XCNEW (struct funct_state_d);
488 l->pure_const_state = IPA_CONST;
489 l->state_previously_known = IPA_NEITHER;
490 l->looping_previously_known = true;
492 l->can_throw = false;
496 fprintf (dump_file, "\n\n local analysis of %s\n ",
497 cgraph_node_name (fn));
500 push_cfun (DECL_STRUCT_FUNCTION (decl));
501 current_function_decl = decl;
503 FOR_EACH_BB (this_block)
505 gimple_stmt_iterator gsi;
506 struct walk_stmt_info wi;
508 memset (&wi, 0, sizeof(wi));
509 for (gsi = gsi_start_bb (this_block);
513 check_stmt (&gsi, l, ipa);
514 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
520 if (l->pure_const_state != IPA_NEITHER)
522 /* Const functions cannot have back edges (an
523 indication of possible infinite loop side
525 if (mark_dfs_back_edges ())
530 if (TREE_READONLY (decl))
532 l->pure_const_state = IPA_CONST;
533 l->state_previously_known = IPA_CONST;
534 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
535 l->looping = false, l->looping_previously_known = false;
537 if (DECL_PURE_P (decl))
539 if (l->pure_const_state != IPA_CONST)
540 l->pure_const_state = IPA_PURE;
541 l->state_previously_known = IPA_PURE;
542 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
543 l->looping = false, l->looping_previously_known = false;
545 if (TREE_NOTHROW (decl))
546 l->can_throw = false;
549 current_function_decl = old_decl;
553 fprintf (dump_file, "Function is locally looping.\n");
555 fprintf (dump_file, "Function is locally throwing.\n");
556 if (l->pure_const_state == IPA_CONST)
557 fprintf (dump_file, "Function is locally const.\n");
558 if (l->pure_const_state == IPA_PURE)
559 fprintf (dump_file, "Function is locally pure.\n");
564 /* Called when new function is inserted to callgraph late. */
566 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
568 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
570 /* There are some shared nodes, in particular the initializers on
571 static declarations. We do not need to scan them more than once
572 since all we would be interested in are the addressof
574 visited_nodes = pointer_set_create ();
575 set_function_state (node, analyze_function (node, true));
576 pointer_set_destroy (visited_nodes);
577 visited_nodes = NULL;
580 /* Called when new clone is inserted to callgraph late. */
583 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
584 void *data ATTRIBUTE_UNUSED)
586 if (get_function_state (src))
588 funct_state l = XNEW (struct funct_state_d);
589 gcc_assert (!get_function_state (dst));
590 memcpy (l, get_function_state (src), sizeof (*l));
591 set_function_state (dst, l);
595 /* Called when new clone is inserted to callgraph late. */
598 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
600 if (get_function_state (node))
602 free (get_function_state (node));
603 set_function_state (node, NULL);
608 /* Analyze each function in the cgraph to see if it is locally PURE or
612 generate_summary (void)
614 struct cgraph_node *node;
616 node_removal_hook_holder =
617 cgraph_add_node_removal_hook (&remove_node_data, NULL);
618 node_duplication_hook_holder =
619 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
620 function_insertion_hook_holder =
621 cgraph_add_function_insertion_hook (&add_new_function, NULL);
622 /* There are some shared nodes, in particular the initializers on
623 static declarations. We do not need to scan them more than once
624 since all we would be interested in are the addressof
626 visited_nodes = pointer_set_create ();
628 /* Process all of the functions.
630 We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
631 guarantee that what we learn about the one we see will be true
632 for the one that overrides it.
634 for (node = cgraph_nodes; node; node = node->next)
635 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
636 set_function_state (node, analyze_function (node, true));
638 pointer_set_destroy (visited_nodes);
639 visited_nodes = NULL;
643 ignore_edge (struct cgraph_edge *e)
645 return (!e->can_throw_external);
648 /* Produce the global information by preforming a transitive closure
649 on the local information that was produced by generate_summary.
650 Note that there is no function_transform pass since this only
651 updates the function_decl. */
656 struct cgraph_node *node;
657 struct cgraph_node *w;
658 struct cgraph_node **order =
659 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
662 struct ipa_dfs_info * w_info;
664 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
665 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
666 cgraph_remove_node_removal_hook (node_removal_hook_holder);
667 order_pos = ipa_utils_reduced_inorder (order, true, false, NULL);
670 dump_cgraph (dump_file);
671 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
674 /* Propagate the local information thru the call graph to produce
675 the global information. All the nodes within a cycle will have
676 the same info so we collapse cycles first. Then we can do the
677 propagation in one pass from the leaves to the roots. */
678 for (i = 0; i < order_pos; i++ )
680 enum pure_const_state_e pure_const_state = IPA_CONST;
681 bool looping = false;
685 /* Find the worst state for any node in the cycle. */
689 struct cgraph_edge *e;
690 funct_state w_l = get_function_state (w);
691 if (pure_const_state < w_l->pure_const_state)
692 pure_const_state = w_l->pure_const_state;
697 if (pure_const_state == IPA_NEITHER)
705 for (e = w->callees; e; e = e->next_callee)
707 struct cgraph_node *y = e->callee;
709 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
711 funct_state y_l = get_function_state (y);
712 if (pure_const_state < y_l->pure_const_state)
713 pure_const_state = y_l->pure_const_state;
714 if (pure_const_state == IPA_NEITHER)
720 w_info = (struct ipa_dfs_info *) w->aux;
721 w = w_info->next_cycle;
724 /* Copy back the region's pure_const_state which is shared by
725 all nodes in the region. */
729 funct_state w_l = get_function_state (w);
730 enum pure_const_state_e this_state = pure_const_state;
731 bool this_looping = looping;
733 if (w_l->state_previously_known != IPA_NEITHER
734 && this_state > w_l->state_previously_known)
735 this_state = w_l->state_previously_known;
736 if (!w_l->looping_previously_known)
737 this_looping = false;
739 /* All nodes within a cycle share the same info. */
740 w_l->pure_const_state = this_state;
741 w_l->looping = this_looping;
746 if (!TREE_READONLY (w->decl) && dump_file)
747 fprintf (dump_file, "Function found to be %sconst: %s\n",
748 this_looping ? "looping " : "",
749 cgraph_node_name (w));
750 TREE_READONLY (w->decl) = 1;
751 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
755 if (!DECL_PURE_P (w->decl) && dump_file)
756 fprintf (dump_file, "Function found to be %spure: %s\n",
757 this_looping ? "looping " : "",
758 cgraph_node_name (w));
759 DECL_PURE_P (w->decl) = 1;
760 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
766 w_info = (struct ipa_dfs_info *) w->aux;
767 w = w_info->next_cycle;
772 for (node = cgraph_nodes; node; node = node->next)
774 /* Get rid of the aux information. */
777 w_info = (struct ipa_dfs_info *) node->aux;
782 order_pos = ipa_utils_reduced_inorder (order, true, false, ignore_edge);
785 dump_cgraph (dump_file);
786 ipa_utils_print_order(dump_file, "reduced for nothrow", order, order_pos);
788 /* Propagate the local information thru the call graph to produce
789 the global information. All the nodes within a cycle will have
790 the same info so we collapse cycles first. Then we can do the
791 propagation in one pass from the leaves to the roots. */
792 for (i = 0; i < order_pos; i++ )
794 bool can_throw = false;
797 /* Find the worst state for any node in the cycle. */
801 struct cgraph_edge *e;
802 funct_state w_l = get_function_state (w);
810 for (e = w->callees; e; e = e->next_callee)
812 struct cgraph_node *y = e->callee;
814 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
816 funct_state y_l = get_function_state (y);
820 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
821 && e->can_throw_external)
825 w_info = (struct ipa_dfs_info *) w->aux;
826 w = w_info->next_cycle;
829 /* Copy back the region's pure_const_state which is shared by
830 all nodes in the region. */
834 funct_state w_l = get_function_state (w);
835 if (!can_throw && !TREE_NOTHROW (w->decl))
837 struct cgraph_edge *e;
838 TREE_NOTHROW (w->decl) = true;
839 for (e = w->callers; e; e = e->next_caller)
840 e->can_throw_external = false;
842 fprintf (dump_file, "Function found to be nothrow: %s\n",
843 cgraph_node_name (w));
845 else if (can_throw && !TREE_NOTHROW (w->decl))
846 w_l->can_throw = true;
847 w_info = (struct ipa_dfs_info *) w->aux;
848 w = w_info->next_cycle;
853 for (node = cgraph_nodes; node; node = node->next)
855 /* Get rid of the aux information. */
858 w_info = (struct ipa_dfs_info *) node->aux;
862 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
863 free (get_function_state (node));
867 VEC_free (funct_state, heap, funct_state_vec);
873 gate_pure_const (void)
875 return (flag_ipa_pure_const
876 /* Don't bother doing anything if the program has errors. */
877 && !(errorcount || sorrycount));
880 struct ipa_opt_pass pass_ipa_pure_const =
884 "pure-const", /* name */
885 gate_pure_const, /* gate */
886 propagate, /* execute */
889 0, /* static_pass_number */
890 TV_IPA_PURE_CONST, /* tv_id */
891 0, /* properties_required */
892 0, /* properties_provided */
893 0, /* properties_destroyed */
894 0, /* todo_flags_start */
895 0 /* todo_flags_finish */
897 generate_summary, /* generate_summary */
898 NULL, /* write_summary */
899 NULL, /* read_summary */
900 NULL, /* function_read_summary */
902 NULL, /* function_transform */
903 NULL /* variable_transform */
906 /* Simple local pass for pure const discovery reusing the analysis from
907 ipa_pure_const. This pass is effective when executed together with
908 other optimization passes in early optimization pass queue. */
911 local_pure_const (void)
913 bool changed = false;
916 /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations
917 we must not promote functions that are called by already processed functions. */
919 if (function_called_by_processed_nodes_p ())
922 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
926 l = analyze_function (cgraph_node (current_function_decl), false);
930 fprintf (dump_file, "Function has wrong visibility; ignoring\n");
934 switch (l->pure_const_state)
937 if (!TREE_READONLY (current_function_decl))
939 TREE_READONLY (current_function_decl) = 1;
940 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
943 fprintf (dump_file, "Function found to be %sconst: %s\n",
944 l->looping ? "looping " : "",
945 lang_hooks.decl_printable_name (current_function_decl,
948 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
951 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
954 fprintf (dump_file, "Function found to be non-looping: %s\n",
955 lang_hooks.decl_printable_name (current_function_decl,
961 if (!TREE_READONLY (current_function_decl))
963 DECL_PURE_P (current_function_decl) = 1;
964 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
967 fprintf (dump_file, "Function found to be %spure: %s\n",
968 l->looping ? "looping " : "",
969 lang_hooks.decl_printable_name (current_function_decl,
972 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
975 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
978 fprintf (dump_file, "Function found to be non-looping: %s\n",
979 lang_hooks.decl_printable_name (current_function_decl,
987 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
989 struct cgraph_edge *e;
991 TREE_NOTHROW (current_function_decl) = true;
992 for (e = cgraph_node (current_function_decl)->callers;
993 e; e = e->next_caller)
994 e->can_throw_external = false;
997 fprintf (dump_file, "Function found to be nothrow: %s\n",
998 lang_hooks.decl_printable_name (current_function_decl,
1004 return execute_fixup_cfg ();
1009 struct gimple_opt_pass pass_local_pure_const =
1013 "local-pure-const", /* name */
1014 gate_pure_const, /* gate */
1015 local_pure_const, /* execute */
1018 0, /* static_pass_number */
1019 TV_IPA_PURE_CONST, /* tv_id */
1020 0, /* properties_required */
1021 0, /* properties_provided */
1022 0, /* properties_destroyed */
1023 0, /* todo_flags_start */
1024 0 /* todo_flags_finish */