1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008, 2009 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"
51 #include "diagnostic.h"
52 #include "langhooks.h"
55 #include "tree-scalar-evolution.h"
57 static struct pointer_set_t *visited_nodes;
59 /* Lattice values for const and pure functions. Everything starts out
60 being const, then may drop to pure and then neither depending on
62 enum pure_const_state_e
69 /* Holder for the const_state. There is one of these per function
74 enum pure_const_state_e pure_const_state;
75 /* What user set here; we can be always sure about this. */
76 enum pure_const_state_e state_previously_known;
77 bool looping_previously_known;
79 /* True if the function could possibly infinite loop. There are a
80 lot of ways that this could be determined. We are pretty
81 conservative here. While it is possible to cse pure and const
82 calls, it is not legal to have dce get rid of the call if there
83 is a possibility that the call could infinite loop since this is
84 a behavioral change. */
90 typedef struct funct_state_d * funct_state;
92 /* The storage of the funct_state is abstracted because there is the
93 possibility that it may be desirable to move this to the cgraph
96 /* Array, indexed by cgraph node uid, of function states. */
98 DEF_VEC_P (funct_state);
99 DEF_VEC_ALLOC_P (funct_state, heap);
100 static VEC (funct_state, heap) *funct_state_vec;
102 /* Holders of ipa cgraph hooks: */
103 static struct cgraph_node_hook_list *function_insertion_hook_holder;
104 static struct cgraph_2node_hook_list *node_duplication_hook_holder;
105 static struct cgraph_node_hook_list *node_removal_hook_holder;
107 /* Init the function state. */
112 free (funct_state_vec);
116 /* Return the function state from NODE. */
118 static inline funct_state
119 get_function_state (struct cgraph_node *node)
122 || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
124 return VEC_index (funct_state, funct_state_vec, node->uid);
127 /* Set the function state S for NODE. */
130 set_function_state (struct cgraph_node *node, funct_state s)
133 || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
134 VEC_safe_grow_cleared (funct_state, heap, funct_state_vec, node->uid + 1);
135 VEC_replace (funct_state, funct_state_vec, node->uid, s);
138 /* Check to see if the use (or definition when CHECKING_WRITE is true)
139 variable T is legal in a function that is either pure or const. */
142 check_decl (funct_state local,
143 tree t, bool checking_write)
145 /* Do not want to do anything with volatile except mark any
146 function that uses one to be not const or pure. */
147 if (TREE_THIS_VOLATILE (t))
149 local->pure_const_state = IPA_NEITHER;
151 fprintf (dump_file, " Volatile operand is not const/pure");
155 /* Do not care about a local automatic that is not static. */
156 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
159 /* If the variable has the "used" attribute, treat it as if it had a
160 been touched by the devil. */
161 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
163 local->pure_const_state = IPA_NEITHER;
165 fprintf (dump_file, " Used static/global variable is not const/pure\n");
169 /* Since we have dealt with the locals and params cases above, if we
170 are CHECKING_WRITE, this cannot be a pure or constant
174 local->pure_const_state = IPA_NEITHER;
176 fprintf (dump_file, " static/global memory write is not const/pure\n");
180 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
182 /* Readonly reads are safe. */
183 if (TREE_READONLY (t) && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
184 return; /* Read of a constant, do not change the function state. */
188 fprintf (dump_file, " global memory read is not const\n");
189 /* Just a regular read. */
190 if (local->pure_const_state == IPA_CONST)
191 local->pure_const_state = IPA_PURE;
196 /* Compilation level statics can be read if they are readonly
198 if (TREE_READONLY (t))
202 fprintf (dump_file, " static memory read is not const\n");
203 /* Just a regular read. */
204 if (local->pure_const_state == IPA_CONST)
205 local->pure_const_state = IPA_PURE;
210 /* Check to see if the use (or definition when CHECKING_WRITE is true)
211 variable T is legal in a function that is either pure or const. */
214 check_op (funct_state local, tree t, bool checking_write)
216 t = get_base_address (t);
217 if (t && TREE_THIS_VOLATILE (t))
219 local->pure_const_state = IPA_NEITHER;
221 fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
225 && INDIRECT_REF_P (t)
226 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
227 && !ptr_deref_may_alias_global_p (TREE_OPERAND (t, 0)))
230 fprintf (dump_file, " Indirect ref to local memory is OK\n");
233 else if (checking_write)
235 local->pure_const_state = IPA_NEITHER;
237 fprintf (dump_file, " Indirect ref write is not const/pure\n");
243 fprintf (dump_file, " Indirect ref read is not const\n");
244 if (local->pure_const_state == IPA_CONST)
245 local->pure_const_state = IPA_PURE;
249 /* Check the parameters of a function call to CALL_EXPR to see if
250 there are any references in the parameters that are not allowed for
251 pure or const functions. Also check to see if this is either an
252 indirect call, a call outside the compilation unit, or has special
253 attributes that may also effect the purity. The CALL_EXPR node for
254 the entire call expression. */
257 check_call (funct_state local, gimple call, bool ipa)
259 int flags = gimple_call_flags (call);
260 tree callee_t = gimple_call_fndecl (call);
261 struct cgraph_node* callee;
262 enum availability avail = AVAIL_NOT_AVAILABLE;
263 bool possibly_throws = stmt_could_throw_p (call);
264 bool possibly_throws_externally = (possibly_throws
265 && stmt_can_throw_external (call));
270 for (i = 0; i < gimple_num_ops (call); i++)
271 if (gimple_op (call, i)
272 && tree_could_throw_p (gimple_op (call, i)))
274 if (possibly_throws && flag_non_call_exceptions)
277 fprintf (dump_file, " operand can throw; looping\n");
278 local->looping = true;
280 if (possibly_throws_externally)
283 fprintf (dump_file, " operand can throw externally\n");
284 local->can_throw = true;
289 /* The const and pure flags are set by a variety of places in the
290 compiler (including here). If someone has already set the flags
291 for the callee, (such as for some of the builtins) we will use
292 them, otherwise we will compute our own information.
294 Const and pure functions have less clobber effects than other
295 functions so we process these first. Otherwise if it is a call
296 outside the compilation unit or an indirect call we punt. This
297 leaves local calls which will be processed by following the call
301 callee = cgraph_node(callee_t);
302 avail = cgraph_function_body_availability (callee);
304 /* When bad things happen to bad functions, they cannot be const
306 if (setjmp_call_p (callee_t))
309 fprintf (dump_file, " setjmp is not const/pure\n");
310 local->looping = true;
311 local->pure_const_state = IPA_NEITHER;
314 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
315 switch (DECL_FUNCTION_CODE (callee_t))
317 case BUILT_IN_LONGJMP:
318 case BUILT_IN_NONLOCAL_GOTO:
320 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
321 local->pure_const_state = IPA_NEITHER;
322 local->looping = true;
329 /* When not in IPA mode, we can still handle self recursion. */
330 if (!ipa && callee_t == current_function_decl)
331 local->looping = true;
332 /* The callee is either unknown (indirect call) or there is just no
333 scannable code for it (external call) . We look to see if there
334 are any bits available for the callee (such as by declaration or
335 because it is builtin) and process solely on the basis of those
337 else if (avail <= AVAIL_OVERWRITABLE || !ipa)
339 if (possibly_throws && flag_non_call_exceptions)
342 fprintf (dump_file, " can throw; looping\n");
343 local->looping = true;
345 if (possibly_throws_externally)
349 fprintf (dump_file, " can throw externally in region %i\n",
350 lookup_stmt_eh_region (call));
352 fprintf (dump_file, " callee:%s\n",
353 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
355 local->can_throw = true;
357 if (flags & ECF_CONST)
359 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
360 local->looping = true;
362 else if (flags & ECF_PURE)
364 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
365 local->looping = true;
367 fprintf (dump_file, " pure function call in not const\n");
368 if (local->pure_const_state == IPA_CONST)
369 local->pure_const_state = IPA_PURE;
374 fprintf (dump_file, " uknown function call is not const/pure\n");
375 local->pure_const_state = IPA_NEITHER;
376 local->looping = true;
379 /* Direct functions calls are handled by IPA propagation. */
382 /* Wrapper around check_decl for loads. */
385 check_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
388 check_decl ((funct_state)data, op, false);
390 check_op ((funct_state)data, op, false);
394 /* Wrapper around check_decl for stores. */
397 check_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
400 check_decl ((funct_state)data, op, true);
402 check_op ((funct_state)data, op, true);
406 /* Look into pointer pointed to by GSIP and figure out what interesting side
409 check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
411 gimple stmt = gsi_stmt (*gsip);
416 fprintf (dump_file, " scanning: ");
417 print_gimple_stmt (dump_file, stmt, 0, 0);
420 /* Look for loads and stores. */
421 walk_stmt_load_store_ops (stmt, local, check_load, check_store);
423 if (gimple_code (stmt) != GIMPLE_CALL
424 && stmt_could_throw_p (stmt))
426 if (flag_non_call_exceptions)
429 fprintf (dump_file, " can throw; looping");
430 local->looping = true;
432 if (stmt_can_throw_external (stmt))
435 fprintf (dump_file, " can throw externally");
436 local->can_throw = true;
439 switch (gimple_code (stmt))
442 check_call (local, stmt, ipa);
445 if (DECL_NONLOCAL (gimple_label_label (stmt)))
446 /* Target of long jump. */
449 fprintf (dump_file, " nonlocal label is not const/pure");
450 local->pure_const_state = IPA_NEITHER;
454 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
456 tree op = gimple_asm_clobber_op (stmt, i);
457 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
460 fprintf (dump_file, " memory asm clobber is not const/pure");
461 /* Abandon all hope, ye who enter here. */
462 local->pure_const_state = IPA_NEITHER;
465 if (gimple_asm_volatile_p (stmt))
468 fprintf (dump_file, " volatile is not const/pure");
469 /* Abandon all hope, ye who enter here. */
470 local->pure_const_state = IPA_NEITHER;
471 local->looping = true;
480 /* This is the main routine for finding the reference patterns for
481 global variables within a function FN. */
484 analyze_function (struct cgraph_node *fn, bool ipa)
486 tree decl = fn->decl;
487 tree old_decl = current_function_decl;
489 basic_block this_block;
491 if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
494 fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n");
498 l = XCNEW (struct funct_state_d);
499 l->pure_const_state = IPA_CONST;
500 l->state_previously_known = IPA_NEITHER;
501 l->looping_previously_known = true;
503 l->can_throw = false;
507 fprintf (dump_file, "\n\n local analysis of %s\n ",
508 cgraph_node_name (fn));
511 push_cfun (DECL_STRUCT_FUNCTION (decl));
512 current_function_decl = decl;
514 FOR_EACH_BB (this_block)
516 gimple_stmt_iterator gsi;
517 struct walk_stmt_info wi;
519 memset (&wi, 0, sizeof(wi));
520 for (gsi = gsi_start_bb (this_block);
524 check_stmt (&gsi, l, ipa);
525 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
531 if (l->pure_const_state != IPA_NEITHER)
533 /* Const functions cannot have back edges (an
534 indication of possible infinite loop side
536 if (mark_dfs_back_edges ())
538 loop_optimizer_init (LOOPS_HAVE_PREHEADERS);
539 if (dump_file && (dump_flags & TDF_DETAILS))
540 flow_loops_dump (dump_file, NULL, 0);
541 if (mark_irreducible_loops ())
544 fprintf (dump_file, " has irreducible loops\n");
552 FOR_EACH_LOOP (li, loop, 0)
553 if (!finite_loop_p (loop))
556 fprintf (dump_file, " can not prove finiteness of loop %i\n", loop->num);
562 loop_optimizer_finalize ();
566 if (TREE_READONLY (decl))
568 l->pure_const_state = IPA_CONST;
569 l->state_previously_known = IPA_CONST;
570 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
571 l->looping = false, l->looping_previously_known = false;
573 if (DECL_PURE_P (decl))
575 if (l->pure_const_state != IPA_CONST)
576 l->pure_const_state = IPA_PURE;
577 l->state_previously_known = IPA_PURE;
578 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
579 l->looping = false, l->looping_previously_known = false;
581 if (TREE_NOTHROW (decl))
582 l->can_throw = false;
585 current_function_decl = old_decl;
589 fprintf (dump_file, "Function is locally looping.\n");
591 fprintf (dump_file, "Function is locally throwing.\n");
592 if (l->pure_const_state == IPA_CONST)
593 fprintf (dump_file, "Function is locally const.\n");
594 if (l->pure_const_state == IPA_PURE)
595 fprintf (dump_file, "Function is locally pure.\n");
600 /* Called when new function is inserted to callgraph late. */
602 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
604 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
606 /* There are some shared nodes, in particular the initializers on
607 static declarations. We do not need to scan them more than once
608 since all we would be interested in are the addressof
610 visited_nodes = pointer_set_create ();
611 set_function_state (node, analyze_function (node, true));
612 pointer_set_destroy (visited_nodes);
613 visited_nodes = NULL;
616 /* Called when new clone is inserted to callgraph late. */
619 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
620 void *data ATTRIBUTE_UNUSED)
622 if (get_function_state (src))
624 funct_state l = XNEW (struct funct_state_d);
625 gcc_assert (!get_function_state (dst));
626 memcpy (l, get_function_state (src), sizeof (*l));
627 set_function_state (dst, l);
631 /* Called when new clone is inserted to callgraph late. */
634 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
636 if (get_function_state (node))
638 free (get_function_state (node));
639 set_function_state (node, NULL);
644 /* Analyze each function in the cgraph to see if it is locally PURE or
648 generate_summary (void)
650 struct cgraph_node *node;
652 node_removal_hook_holder =
653 cgraph_add_node_removal_hook (&remove_node_data, NULL);
654 node_duplication_hook_holder =
655 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
656 function_insertion_hook_holder =
657 cgraph_add_function_insertion_hook (&add_new_function, NULL);
658 /* There are some shared nodes, in particular the initializers on
659 static declarations. We do not need to scan them more than once
660 since all we would be interested in are the addressof
662 visited_nodes = pointer_set_create ();
664 /* Process all of the functions.
666 We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
667 guarantee that what we learn about the one we see will be true
668 for the one that overrides it.
670 for (node = cgraph_nodes; node; node = node->next)
671 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
672 set_function_state (node, analyze_function (node, true));
674 pointer_set_destroy (visited_nodes);
675 visited_nodes = NULL;
679 ignore_edge (struct cgraph_edge *e)
681 return (!e->can_throw_external);
684 /* Produce the global information by preforming a transitive closure
685 on the local information that was produced by generate_summary.
686 Note that there is no function_transform pass since this only
687 updates the function_decl. */
692 struct cgraph_node *node;
693 struct cgraph_node *w;
694 struct cgraph_node **order =
695 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
698 struct ipa_dfs_info * w_info;
700 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
701 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
702 cgraph_remove_node_removal_hook (node_removal_hook_holder);
703 order_pos = ipa_utils_reduced_inorder (order, true, false, NULL);
706 dump_cgraph (dump_file);
707 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
710 /* Propagate the local information thru the call graph to produce
711 the global information. All the nodes within a cycle will have
712 the same info so we collapse cycles first. Then we can do the
713 propagation in one pass from the leaves to the roots. */
714 for (i = 0; i < order_pos; i++ )
716 enum pure_const_state_e pure_const_state = IPA_CONST;
717 bool looping = false;
721 /* Find the worst state for any node in the cycle. */
725 struct cgraph_edge *e;
726 funct_state w_l = get_function_state (w);
727 if (pure_const_state < w_l->pure_const_state)
728 pure_const_state = w_l->pure_const_state;
733 if (pure_const_state == IPA_NEITHER)
741 for (e = w->callees; e; e = e->next_callee)
743 struct cgraph_node *y = e->callee;
745 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
747 funct_state y_l = get_function_state (y);
748 if (pure_const_state < y_l->pure_const_state)
749 pure_const_state = y_l->pure_const_state;
750 if (pure_const_state == IPA_NEITHER)
756 w_info = (struct ipa_dfs_info *) w->aux;
757 w = w_info->next_cycle;
760 /* Copy back the region's pure_const_state which is shared by
761 all nodes in the region. */
765 funct_state w_l = get_function_state (w);
766 enum pure_const_state_e this_state = pure_const_state;
767 bool this_looping = looping;
769 if (w_l->state_previously_known != IPA_NEITHER
770 && this_state > w_l->state_previously_known)
771 this_state = w_l->state_previously_known;
772 if (!w_l->looping_previously_known)
773 this_looping = false;
775 /* All nodes within a cycle share the same info. */
776 w_l->pure_const_state = this_state;
777 w_l->looping = this_looping;
782 if (!TREE_READONLY (w->decl) && dump_file)
783 fprintf (dump_file, "Function found to be %sconst: %s\n",
784 this_looping ? "looping " : "",
785 cgraph_node_name (w));
786 TREE_READONLY (w->decl) = 1;
787 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
791 if (!DECL_PURE_P (w->decl) && dump_file)
792 fprintf (dump_file, "Function found to be %spure: %s\n",
793 this_looping ? "looping " : "",
794 cgraph_node_name (w));
795 DECL_PURE_P (w->decl) = 1;
796 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
802 w_info = (struct ipa_dfs_info *) w->aux;
803 w = w_info->next_cycle;
808 for (node = cgraph_nodes; node; node = node->next)
810 /* Get rid of the aux information. */
813 w_info = (struct ipa_dfs_info *) node->aux;
818 order_pos = ipa_utils_reduced_inorder (order, true, false, ignore_edge);
821 dump_cgraph (dump_file);
822 ipa_utils_print_order(dump_file, "reduced for nothrow", order, order_pos);
824 /* Propagate the local information thru the call graph to produce
825 the global information. All the nodes within a cycle will have
826 the same info so we collapse cycles first. Then we can do the
827 propagation in one pass from the leaves to the roots. */
828 for (i = 0; i < order_pos; i++ )
830 bool can_throw = false;
833 /* Find the worst state for any node in the cycle. */
837 struct cgraph_edge *e;
838 funct_state w_l = get_function_state (w);
846 for (e = w->callees; e; e = e->next_callee)
848 struct cgraph_node *y = e->callee;
850 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
852 funct_state y_l = get_function_state (y);
856 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
857 && e->can_throw_external)
861 w_info = (struct ipa_dfs_info *) w->aux;
862 w = w_info->next_cycle;
865 /* Copy back the region's pure_const_state which is shared by
866 all nodes in the region. */
870 funct_state w_l = get_function_state (w);
871 if (!can_throw && !TREE_NOTHROW (w->decl))
873 struct cgraph_edge *e;
874 TREE_NOTHROW (w->decl) = true;
875 for (e = w->callers; e; e = e->next_caller)
876 e->can_throw_external = false;
878 fprintf (dump_file, "Function found to be nothrow: %s\n",
879 cgraph_node_name (w));
881 else if (can_throw && !TREE_NOTHROW (w->decl))
882 w_l->can_throw = true;
883 w_info = (struct ipa_dfs_info *) w->aux;
884 w = w_info->next_cycle;
889 for (node = cgraph_nodes; node; node = node->next)
891 /* Get rid of the aux information. */
894 w_info = (struct ipa_dfs_info *) node->aux;
898 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
899 free (get_function_state (node));
903 VEC_free (funct_state, heap, funct_state_vec);
909 gate_pure_const (void)
911 return (flag_ipa_pure_const
912 /* Don't bother doing anything if the program has errors. */
913 && !(errorcount || sorrycount));
916 struct ipa_opt_pass_d pass_ipa_pure_const =
920 "pure-const", /* name */
921 gate_pure_const, /* gate */
922 propagate, /* execute */
925 0, /* static_pass_number */
926 TV_IPA_PURE_CONST, /* tv_id */
927 0, /* properties_required */
928 0, /* properties_provided */
929 0, /* properties_destroyed */
930 0, /* todo_flags_start */
931 0 /* todo_flags_finish */
933 generate_summary, /* generate_summary */
934 NULL, /* write_summary */
935 NULL, /* read_summary */
936 NULL, /* function_read_summary */
938 NULL, /* function_transform */
939 NULL /* variable_transform */
942 /* Simple local pass for pure const discovery reusing the analysis from
943 ipa_pure_const. This pass is effective when executed together with
944 other optimization passes in early optimization pass queue. */
947 local_pure_const (void)
949 bool changed = false;
952 /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations
953 we must not promote functions that are called by already processed functions. */
955 if (function_called_by_processed_nodes_p ())
958 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
962 l = analyze_function (cgraph_node (current_function_decl), false);
966 fprintf (dump_file, "Function has wrong visibility; ignoring\n");
970 switch (l->pure_const_state)
973 if (!TREE_READONLY (current_function_decl))
975 TREE_READONLY (current_function_decl) = 1;
976 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
979 fprintf (dump_file, "Function found to be %sconst: %s\n",
980 l->looping ? "looping " : "",
981 lang_hooks.decl_printable_name (current_function_decl,
984 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
987 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
990 fprintf (dump_file, "Function found to be non-looping: %s\n",
991 lang_hooks.decl_printable_name (current_function_decl,
997 if (!TREE_READONLY (current_function_decl))
999 DECL_PURE_P (current_function_decl) = 1;
1000 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
1003 fprintf (dump_file, "Function found to be %spure: %s\n",
1004 l->looping ? "looping " : "",
1005 lang_hooks.decl_printable_name (current_function_decl,
1008 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1011 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
1014 fprintf (dump_file, "Function found to be non-looping: %s\n",
1015 lang_hooks.decl_printable_name (current_function_decl,
1023 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
1025 struct cgraph_edge *e;
1027 TREE_NOTHROW (current_function_decl) = true;
1028 for (e = cgraph_node (current_function_decl)->callers;
1029 e; e = e->next_caller)
1030 e->can_throw_external = false;
1033 fprintf (dump_file, "Function found to be nothrow: %s\n",
1034 lang_hooks.decl_printable_name (current_function_decl,
1040 return execute_fixup_cfg ();
1045 struct gimple_opt_pass pass_local_pure_const =
1049 "local-pure-const", /* name */
1050 gate_pure_const, /* gate */
1051 local_pure_const, /* execute */
1054 0, /* static_pass_number */
1055 TV_IPA_PURE_CONST, /* tv_id */
1056 0, /* properties_required */
1057 0, /* properties_provided */
1058 0, /* properties_destroyed */
1059 0, /* todo_flags_start */
1060 0 /* todo_flags_finish */