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 if (TREE_THIS_VOLATILE (t))
218 local->pure_const_state = IPA_NEITHER;
220 fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
223 else if (checking_write)
225 local->pure_const_state = IPA_NEITHER;
227 fprintf (dump_file, " Indirect ref write is not const/pure\n");
233 fprintf (dump_file, " Indirect ref read is not const\n");
234 if (local->pure_const_state == IPA_CONST)
235 local->pure_const_state = IPA_PURE;
239 /* Check the parameters of a function call to CALL_EXPR to see if
240 there are any references in the parameters that are not allowed for
241 pure or const functions. Also check to see if this is either an
242 indirect call, a call outside the compilation unit, or has special
243 attributes that may also effect the purity. The CALL_EXPR node for
244 the entire call expression. */
247 check_call (funct_state local, gimple call, bool ipa)
249 int flags = gimple_call_flags (call);
250 tree callee_t = gimple_call_fndecl (call);
251 struct cgraph_node* callee;
252 enum availability avail = AVAIL_NOT_AVAILABLE;
253 bool possibly_throws = stmt_could_throw_p (call);
254 bool possibly_throws_externally = (possibly_throws
255 && stmt_can_throw_external (call));
260 for (i = 0; i < gimple_num_ops (call); i++)
261 if (gimple_op (call, i)
262 && tree_could_throw_p (gimple_op (call, i)))
264 if (possibly_throws && flag_non_call_exceptions)
267 fprintf (dump_file, " operand can throw; looping\n");
268 local->looping = true;
270 if (possibly_throws_externally)
273 fprintf (dump_file, " operand can throw externally\n");
274 local->can_throw = true;
279 /* The const and pure flags are set by a variety of places in the
280 compiler (including here). If someone has already set the flags
281 for the callee, (such as for some of the builtins) we will use
282 them, otherwise we will compute our own information.
284 Const and pure functions have less clobber effects than other
285 functions so we process these first. Otherwise if it is a call
286 outside the compilation unit or an indirect call we punt. This
287 leaves local calls which will be processed by following the call
291 callee = cgraph_node(callee_t);
292 avail = cgraph_function_body_availability (callee);
294 /* When bad things happen to bad functions, they cannot be const
296 if (setjmp_call_p (callee_t))
299 fprintf (dump_file, " setjmp is not const/pure\n");
300 local->looping = true;
301 local->pure_const_state = IPA_NEITHER;
304 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
305 switch (DECL_FUNCTION_CODE (callee_t))
307 case BUILT_IN_LONGJMP:
308 case BUILT_IN_NONLOCAL_GOTO:
310 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
311 local->pure_const_state = IPA_NEITHER;
312 local->looping = true;
319 /* When not in IPA mode, we can still handle self recursion. */
320 if (!ipa && callee_t == current_function_decl)
321 local->looping = true;
322 /* The callee is either unknown (indirect call) or there is just no
323 scannable code for it (external call) . We look to see if there
324 are any bits available for the callee (such as by declaration or
325 because it is builtin) and process solely on the basis of those
327 else if (avail <= AVAIL_OVERWRITABLE || !ipa)
329 if (possibly_throws && flag_non_call_exceptions)
332 fprintf (dump_file, " can throw; looping\n");
333 local->looping = true;
335 if (possibly_throws_externally)
339 fprintf (dump_file, " can throw externally in region %i\n",
340 lookup_stmt_eh_region (call));
342 fprintf (dump_file, " callee:%s\n",
343 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
345 local->can_throw = true;
347 if (flags & ECF_CONST)
349 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
350 local->looping = true;
352 else if (flags & ECF_PURE)
354 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
355 local->looping = true;
357 fprintf (dump_file, " pure function call in not const\n");
358 if (local->pure_const_state == IPA_CONST)
359 local->pure_const_state = IPA_PURE;
364 fprintf (dump_file, " uknown function call is not const/pure\n");
365 local->pure_const_state = IPA_NEITHER;
366 local->looping = true;
369 /* Direct functions calls are handled by IPA propagation. */
372 /* Wrapper around check_decl for loads. */
375 check_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
378 check_decl ((funct_state)data, op, false);
380 check_op ((funct_state)data, op, false);
384 /* Wrapper around check_decl for stores. */
387 check_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
390 check_decl ((funct_state)data, op, true);
392 check_op ((funct_state)data, op, true);
396 /* Look into pointer pointed to by GSIP and figure out what interesting side
399 check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
401 gimple stmt = gsi_stmt (*gsip);
406 fprintf (dump_file, " scanning: ");
407 print_gimple_stmt (dump_file, stmt, 0, 0);
410 /* Look for loads and stores. */
411 walk_stmt_load_store_ops (stmt, local, check_load, check_store);
413 if (gimple_code (stmt) != GIMPLE_CALL
414 && stmt_could_throw_p (stmt))
416 if (flag_non_call_exceptions)
419 fprintf (dump_file, " can throw; looping");
420 local->looping = true;
422 if (stmt_can_throw_external (stmt))
425 fprintf (dump_file, " can throw externally");
426 local->can_throw = true;
429 switch (gimple_code (stmt))
432 check_call (local, stmt, ipa);
435 if (DECL_NONLOCAL (gimple_label_label (stmt)))
436 /* Target of long jump. */
439 fprintf (dump_file, " nonlocal label is not const/pure");
440 local->pure_const_state = IPA_NEITHER;
444 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
446 tree op = gimple_asm_clobber_op (stmt, i);
447 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
450 fprintf (dump_file, " memory asm clobber is not const/pure");
451 /* Abandon all hope, ye who enter here. */
452 local->pure_const_state = IPA_NEITHER;
455 if (gimple_asm_volatile_p (stmt))
458 fprintf (dump_file, " volatile is not const/pure");
459 /* Abandon all hope, ye who enter here. */
460 local->pure_const_state = IPA_NEITHER;
461 local->looping = true;
470 /* This is the main routine for finding the reference patterns for
471 global variables within a function FN. */
474 analyze_function (struct cgraph_node *fn, bool ipa)
476 tree decl = fn->decl;
477 tree old_decl = current_function_decl;
479 basic_block this_block;
481 if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
484 fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n");
488 l = XCNEW (struct funct_state_d);
489 l->pure_const_state = IPA_CONST;
490 l->state_previously_known = IPA_NEITHER;
491 l->looping_previously_known = true;
493 l->can_throw = false;
497 fprintf (dump_file, "\n\n local analysis of %s\n ",
498 cgraph_node_name (fn));
501 push_cfun (DECL_STRUCT_FUNCTION (decl));
502 current_function_decl = decl;
504 FOR_EACH_BB (this_block)
506 gimple_stmt_iterator gsi;
507 struct walk_stmt_info wi;
509 memset (&wi, 0, sizeof(wi));
510 for (gsi = gsi_start_bb (this_block);
514 check_stmt (&gsi, l, ipa);
515 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
521 if (l->pure_const_state != IPA_NEITHER)
523 /* Const functions cannot have back edges (an
524 indication of possible infinite loop side
526 if (mark_dfs_back_edges ())
528 loop_optimizer_init (LOOPS_HAVE_PREHEADERS);
529 if (dump_file && (dump_flags & TDF_DETAILS))
530 flow_loops_dump (dump_file, NULL, 0);
531 if (mark_irreducible_loops ())
534 fprintf (dump_file, " has irreducible loops\n");
542 FOR_EACH_LOOP (li, loop, 0)
543 if (!finite_loop_p (loop))
546 fprintf (dump_file, " can not prove finiteness of loop %i\n", loop->num);
552 loop_optimizer_finalize ();
556 if (TREE_READONLY (decl))
558 l->pure_const_state = IPA_CONST;
559 l->state_previously_known = IPA_CONST;
560 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
561 l->looping = false, l->looping_previously_known = false;
563 if (DECL_PURE_P (decl))
565 if (l->pure_const_state != IPA_CONST)
566 l->pure_const_state = IPA_PURE;
567 l->state_previously_known = IPA_PURE;
568 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
569 l->looping = false, l->looping_previously_known = false;
571 if (TREE_NOTHROW (decl))
572 l->can_throw = false;
575 current_function_decl = old_decl;
579 fprintf (dump_file, "Function is locally looping.\n");
581 fprintf (dump_file, "Function is locally throwing.\n");
582 if (l->pure_const_state == IPA_CONST)
583 fprintf (dump_file, "Function is locally const.\n");
584 if (l->pure_const_state == IPA_PURE)
585 fprintf (dump_file, "Function is locally pure.\n");
590 /* Called when new function is inserted to callgraph late. */
592 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
594 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
596 /* There are some shared nodes, in particular the initializers on
597 static declarations. We do not need to scan them more than once
598 since all we would be interested in are the addressof
600 visited_nodes = pointer_set_create ();
601 set_function_state (node, analyze_function (node, true));
602 pointer_set_destroy (visited_nodes);
603 visited_nodes = NULL;
606 /* Called when new clone is inserted to callgraph late. */
609 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
610 void *data ATTRIBUTE_UNUSED)
612 if (get_function_state (src))
614 funct_state l = XNEW (struct funct_state_d);
615 gcc_assert (!get_function_state (dst));
616 memcpy (l, get_function_state (src), sizeof (*l));
617 set_function_state (dst, l);
621 /* Called when new clone is inserted to callgraph late. */
624 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
626 if (get_function_state (node))
628 free (get_function_state (node));
629 set_function_state (node, NULL);
634 /* Analyze each function in the cgraph to see if it is locally PURE or
638 generate_summary (void)
640 struct cgraph_node *node;
642 node_removal_hook_holder =
643 cgraph_add_node_removal_hook (&remove_node_data, NULL);
644 node_duplication_hook_holder =
645 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
646 function_insertion_hook_holder =
647 cgraph_add_function_insertion_hook (&add_new_function, NULL);
648 /* There are some shared nodes, in particular the initializers on
649 static declarations. We do not need to scan them more than once
650 since all we would be interested in are the addressof
652 visited_nodes = pointer_set_create ();
654 /* Process all of the functions.
656 We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
657 guarantee that what we learn about the one we see will be true
658 for the one that overrides it.
660 for (node = cgraph_nodes; node; node = node->next)
661 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
662 set_function_state (node, analyze_function (node, true));
664 pointer_set_destroy (visited_nodes);
665 visited_nodes = NULL;
669 ignore_edge (struct cgraph_edge *e)
671 return (!e->can_throw_external);
674 /* Produce the global information by preforming a transitive closure
675 on the local information that was produced by generate_summary.
676 Note that there is no function_transform pass since this only
677 updates the function_decl. */
682 struct cgraph_node *node;
683 struct cgraph_node *w;
684 struct cgraph_node **order =
685 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
688 struct ipa_dfs_info * w_info;
690 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
691 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
692 cgraph_remove_node_removal_hook (node_removal_hook_holder);
693 order_pos = ipa_utils_reduced_inorder (order, true, false, NULL);
696 dump_cgraph (dump_file);
697 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
700 /* Propagate the local information thru the call graph to produce
701 the global information. All the nodes within a cycle will have
702 the same info so we collapse cycles first. Then we can do the
703 propagation in one pass from the leaves to the roots. */
704 for (i = 0; i < order_pos; i++ )
706 enum pure_const_state_e pure_const_state = IPA_CONST;
707 bool looping = false;
711 /* Find the worst state for any node in the cycle. */
715 struct cgraph_edge *e;
716 funct_state w_l = get_function_state (w);
717 if (pure_const_state < w_l->pure_const_state)
718 pure_const_state = w_l->pure_const_state;
723 if (pure_const_state == IPA_NEITHER)
731 for (e = w->callees; e; e = e->next_callee)
733 struct cgraph_node *y = e->callee;
735 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
737 funct_state y_l = get_function_state (y);
738 if (pure_const_state < y_l->pure_const_state)
739 pure_const_state = y_l->pure_const_state;
740 if (pure_const_state == IPA_NEITHER)
746 w_info = (struct ipa_dfs_info *) w->aux;
747 w = w_info->next_cycle;
750 /* Copy back the region's pure_const_state which is shared by
751 all nodes in the region. */
755 funct_state w_l = get_function_state (w);
756 enum pure_const_state_e this_state = pure_const_state;
757 bool this_looping = looping;
759 if (w_l->state_previously_known != IPA_NEITHER
760 && this_state > w_l->state_previously_known)
761 this_state = w_l->state_previously_known;
762 if (!w_l->looping_previously_known)
763 this_looping = false;
765 /* All nodes within a cycle share the same info. */
766 w_l->pure_const_state = this_state;
767 w_l->looping = this_looping;
772 if (!TREE_READONLY (w->decl) && dump_file)
773 fprintf (dump_file, "Function found to be %sconst: %s\n",
774 this_looping ? "looping " : "",
775 cgraph_node_name (w));
776 TREE_READONLY (w->decl) = 1;
777 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
781 if (!DECL_PURE_P (w->decl) && dump_file)
782 fprintf (dump_file, "Function found to be %spure: %s\n",
783 this_looping ? "looping " : "",
784 cgraph_node_name (w));
785 DECL_PURE_P (w->decl) = 1;
786 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
792 w_info = (struct ipa_dfs_info *) w->aux;
793 w = w_info->next_cycle;
798 for (node = cgraph_nodes; node; node = node->next)
800 /* Get rid of the aux information. */
803 w_info = (struct ipa_dfs_info *) node->aux;
808 order_pos = ipa_utils_reduced_inorder (order, true, false, ignore_edge);
811 dump_cgraph (dump_file);
812 ipa_utils_print_order(dump_file, "reduced for nothrow", order, order_pos);
814 /* Propagate the local information thru the call graph to produce
815 the global information. All the nodes within a cycle will have
816 the same info so we collapse cycles first. Then we can do the
817 propagation in one pass from the leaves to the roots. */
818 for (i = 0; i < order_pos; i++ )
820 bool can_throw = false;
823 /* Find the worst state for any node in the cycle. */
827 struct cgraph_edge *e;
828 funct_state w_l = get_function_state (w);
836 for (e = w->callees; e; e = e->next_callee)
838 struct cgraph_node *y = e->callee;
840 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
842 funct_state y_l = get_function_state (y);
846 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
847 && e->can_throw_external)
851 w_info = (struct ipa_dfs_info *) w->aux;
852 w = w_info->next_cycle;
855 /* Copy back the region's pure_const_state which is shared by
856 all nodes in the region. */
860 funct_state w_l = get_function_state (w);
861 if (!can_throw && !TREE_NOTHROW (w->decl))
863 struct cgraph_edge *e;
864 TREE_NOTHROW (w->decl) = true;
865 for (e = w->callers; e; e = e->next_caller)
866 e->can_throw_external = false;
868 fprintf (dump_file, "Function found to be nothrow: %s\n",
869 cgraph_node_name (w));
871 else if (can_throw && !TREE_NOTHROW (w->decl))
872 w_l->can_throw = true;
873 w_info = (struct ipa_dfs_info *) w->aux;
874 w = w_info->next_cycle;
879 for (node = cgraph_nodes; node; node = node->next)
881 /* Get rid of the aux information. */
884 w_info = (struct ipa_dfs_info *) node->aux;
888 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
889 free (get_function_state (node));
893 VEC_free (funct_state, heap, funct_state_vec);
899 gate_pure_const (void)
901 return (flag_ipa_pure_const
902 /* Don't bother doing anything if the program has errors. */
903 && !(errorcount || sorrycount));
906 struct ipa_opt_pass_d pass_ipa_pure_const =
910 "pure-const", /* name */
911 gate_pure_const, /* gate */
912 propagate, /* execute */
915 0, /* static_pass_number */
916 TV_IPA_PURE_CONST, /* tv_id */
917 0, /* properties_required */
918 0, /* properties_provided */
919 0, /* properties_destroyed */
920 0, /* todo_flags_start */
921 0 /* todo_flags_finish */
923 generate_summary, /* generate_summary */
924 NULL, /* write_summary */
925 NULL, /* read_summary */
926 NULL, /* function_read_summary */
928 NULL, /* function_transform */
929 NULL /* variable_transform */
932 /* Simple local pass for pure const discovery reusing the analysis from
933 ipa_pure_const. This pass is effective when executed together with
934 other optimization passes in early optimization pass queue. */
937 local_pure_const (void)
939 bool changed = false;
942 /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations
943 we must not promote functions that are called by already processed functions. */
945 if (function_called_by_processed_nodes_p ())
948 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
952 l = analyze_function (cgraph_node (current_function_decl), false);
956 fprintf (dump_file, "Function has wrong visibility; ignoring\n");
960 switch (l->pure_const_state)
963 if (!TREE_READONLY (current_function_decl))
965 TREE_READONLY (current_function_decl) = 1;
966 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
969 fprintf (dump_file, "Function found to be %sconst: %s\n",
970 l->looping ? "looping " : "",
971 lang_hooks.decl_printable_name (current_function_decl,
974 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
977 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
980 fprintf (dump_file, "Function found to be non-looping: %s\n",
981 lang_hooks.decl_printable_name (current_function_decl,
987 if (!TREE_READONLY (current_function_decl))
989 DECL_PURE_P (current_function_decl) = 1;
990 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
993 fprintf (dump_file, "Function found to be %spure: %s\n",
994 l->looping ? "looping " : "",
995 lang_hooks.decl_printable_name (current_function_decl,
998 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1001 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
1004 fprintf (dump_file, "Function found to be non-looping: %s\n",
1005 lang_hooks.decl_printable_name (current_function_decl,
1013 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
1015 struct cgraph_edge *e;
1017 TREE_NOTHROW (current_function_decl) = true;
1018 for (e = cgraph_node (current_function_decl)->callers;
1019 e; e = e->next_caller)
1020 e->can_throw_external = false;
1023 fprintf (dump_file, "Function found to be nothrow: %s\n",
1024 lang_hooks.decl_printable_name (current_function_decl,
1030 return execute_fixup_cfg ();
1035 struct gimple_opt_pass pass_local_pure_const =
1039 "local-pure-const", /* name */
1040 gate_pure_const, /* gate */
1041 local_pure_const, /* execute */
1044 0, /* static_pass_number */
1045 TV_IPA_PURE_CONST, /* tv_id */
1046 0, /* properties_required */
1047 0, /* properties_provided */
1048 0, /* properties_destroyed */
1049 0, /* todo_flags_start */
1050 0 /* todo_flags_finish */