Enable dumping of alias graphs.
[official-gcc/Ramakrishna.git] / gcc / ipa-pure-const.c
blob201dc5996c1ef8eb6da5fdc2321ca055d85e664f
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
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 "tree-flow.h"
40 #include "tree-inline.h"
41 #include "tree-pass.h"
42 #include "langhooks.h"
43 #include "pointer-set.h"
44 #include "ggc.h"
45 #include "ipa-utils.h"
46 #include "gimple.h"
47 #include "cgraph.h"
48 #include "output.h"
49 #include "flags.h"
50 #include "timevar.h"
51 #include "diagnostic.h"
52 #include "langhooks.h"
53 #include "target.h"
54 #include "cfgloop.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
61 what is found. */
62 enum pure_const_state_e
64 IPA_CONST,
65 IPA_PURE,
66 IPA_NEITHER
69 /* Holder for the const_state. There is one of these per function
70 decl. */
71 struct funct_state_d
73 /* See above. */
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. */
85 bool looping;
87 bool can_throw;
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
94 local info. */
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. */
109 static void
110 finish_state (void)
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)
121 if (!funct_state_vec
122 || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
123 return NULL;
124 return VEC_index (funct_state, funct_state_vec, node->uid);
127 /* Set the function state S for NODE. */
129 static inline void
130 set_function_state (struct cgraph_node *node, funct_state s)
132 if (!funct_state_vec
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. */
141 static inline void
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;
150 if (dump_file)
151 fprintf (dump_file, " Volatile operand is not const/pure");
152 return;
155 /* Do not care about a local automatic that is not static. */
156 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
157 return;
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;
164 if (dump_file)
165 fprintf (dump_file, " Used static/global variable is not const/pure\n");
166 return;
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
171 function. */
172 if (checking_write)
174 local->pure_const_state = IPA_NEITHER;
175 if (dump_file)
176 fprintf (dump_file, " static/global memory write is not const/pure\n");
177 return;
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. */
185 else
187 if (dump_file)
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;
194 else
196 /* Compilation level statics can be read if they are readonly
197 variables. */
198 if (TREE_READONLY (t))
199 return;
201 if (dump_file)
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. */
213 static inline void
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;
220 if (dump_file)
221 fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
222 return;
224 else if (t
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)))
229 if (dump_file)
230 fprintf (dump_file, " Indirect ref to local memory is OK\n");
231 return;
233 else if (checking_write)
235 local->pure_const_state = IPA_NEITHER;
236 if (dump_file)
237 fprintf (dump_file, " Indirect ref write is not const/pure\n");
238 return;
240 else
242 if (dump_file)
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. */
256 static void
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));
267 if (possibly_throws)
269 unsigned int i;
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)
276 if (dump_file)
277 fprintf (dump_file, " operand can throw; looping\n");
278 local->looping = true;
280 if (possibly_throws_externally)
282 if (dump_file)
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
298 graph. */
299 if (callee_t)
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
305 or pure. */
306 if (setjmp_call_p (callee_t))
308 if (dump_file)
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:
319 if (dump_file)
320 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
321 local->pure_const_state = IPA_NEITHER;
322 local->looping = true;
323 break;
324 default:
325 break;
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
336 bits. */
337 else if (avail <= AVAIL_OVERWRITABLE || !ipa)
339 if (possibly_throws && flag_non_call_exceptions)
341 if (dump_file)
342 fprintf (dump_file, " can throw; looping\n");
343 local->looping = true;
345 if (possibly_throws_externally)
347 if (dump_file)
349 fprintf (dump_file, " can throw externally in region %i\n",
350 lookup_stmt_eh_region (call));
351 if (callee_t)
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;
366 if (dump_file)
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;
371 else
373 if (dump_file)
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. */
384 static bool
385 check_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
387 if (DECL_P (op))
388 check_decl ((funct_state)data, op, false);
389 else
390 check_op ((funct_state)data, op, false);
391 return false;
394 /* Wrapper around check_decl for stores. */
396 static bool
397 check_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
399 if (DECL_P (op))
400 check_decl ((funct_state)data, op, true);
401 else
402 check_op ((funct_state)data, op, true);
403 return false;
406 /* Look into pointer pointed to by GSIP and figure out what interesting side
407 effects it has. */
408 static void
409 check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
411 gimple stmt = gsi_stmt (*gsip);
412 unsigned int i = 0;
414 if (is_gimple_debug (stmt))
415 return;
417 if (dump_file)
419 fprintf (dump_file, " scanning: ");
420 print_gimple_stmt (dump_file, stmt, 0, 0);
423 /* Look for loads and stores. */
424 walk_stmt_load_store_ops (stmt, local, check_load, check_store);
426 if (gimple_code (stmt) != GIMPLE_CALL
427 && stmt_could_throw_p (stmt))
429 if (flag_non_call_exceptions)
431 if (dump_file)
432 fprintf (dump_file, " can throw; looping");
433 local->looping = true;
435 if (stmt_can_throw_external (stmt))
437 if (dump_file)
438 fprintf (dump_file, " can throw externally");
439 local->can_throw = true;
442 switch (gimple_code (stmt))
444 case GIMPLE_CALL:
445 check_call (local, stmt, ipa);
446 break;
447 case GIMPLE_LABEL:
448 if (DECL_NONLOCAL (gimple_label_label (stmt)))
449 /* Target of long jump. */
451 if (dump_file)
452 fprintf (dump_file, " nonlocal label is not const/pure");
453 local->pure_const_state = IPA_NEITHER;
455 break;
456 case GIMPLE_ASM:
457 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
459 tree op = gimple_asm_clobber_op (stmt, i);
460 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
462 if (dump_file)
463 fprintf (dump_file, " memory asm clobber is not const/pure");
464 /* Abandon all hope, ye who enter here. */
465 local->pure_const_state = IPA_NEITHER;
468 if (gimple_asm_volatile_p (stmt))
470 if (dump_file)
471 fprintf (dump_file, " volatile is not const/pure");
472 /* Abandon all hope, ye who enter here. */
473 local->pure_const_state = IPA_NEITHER;
474 local->looping = true;
476 return;
477 default:
478 break;
483 /* This is the main routine for finding the reference patterns for
484 global variables within a function FN. */
486 static funct_state
487 analyze_function (struct cgraph_node *fn, bool ipa)
489 tree decl = fn->decl;
490 tree old_decl = current_function_decl;
491 funct_state l;
492 basic_block this_block;
494 if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
496 if (dump_file)
497 fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n");
498 return NULL;
501 l = XCNEW (struct funct_state_d);
502 l->pure_const_state = IPA_CONST;
503 l->state_previously_known = IPA_NEITHER;
504 l->looping_previously_known = true;
505 l->looping = false;
506 l->can_throw = false;
508 if (dump_file)
510 fprintf (dump_file, "\n\n local analysis of %s\n ",
511 cgraph_node_name (fn));
514 push_cfun (DECL_STRUCT_FUNCTION (decl));
515 current_function_decl = decl;
517 FOR_EACH_BB (this_block)
519 gimple_stmt_iterator gsi;
520 struct walk_stmt_info wi;
522 memset (&wi, 0, sizeof(wi));
523 for (gsi = gsi_start_bb (this_block);
524 !gsi_end_p (gsi);
525 gsi_next (&gsi))
527 check_stmt (&gsi, l, ipa);
528 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
529 goto end;
533 end:
534 if (l->pure_const_state != IPA_NEITHER)
536 /* Const functions cannot have back edges (an
537 indication of possible infinite loop side
538 effect. */
539 if (mark_dfs_back_edges ())
541 /* Preheaders are needed for SCEV to work.
542 Simple lateches and recorded exits improve chances that loop will
543 proved to be finite in testcases such as in loop-15.c and loop-24.c */
544 loop_optimizer_init (LOOPS_NORMAL
545 | LOOPS_HAVE_RECORDED_EXITS);
546 if (dump_file && (dump_flags & TDF_DETAILS))
547 flow_loops_dump (dump_file, NULL, 0);
548 if (mark_irreducible_loops ())
550 if (dump_file)
551 fprintf (dump_file, " has irreducible loops\n");
552 l->looping = true;
554 else
556 loop_iterator li;
557 struct loop *loop;
558 scev_initialize ();
559 FOR_EACH_LOOP (li, loop, 0)
560 if (!finite_loop_p (loop))
562 if (dump_file)
563 fprintf (dump_file, " can not prove finiteness of loop %i\n", loop->num);
564 l->looping =true;
565 break;
567 scev_finalize ();
569 loop_optimizer_finalize ();
573 if (TREE_READONLY (decl))
575 l->pure_const_state = IPA_CONST;
576 l->state_previously_known = IPA_CONST;
577 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
578 l->looping = false, l->looping_previously_known = false;
580 if (DECL_PURE_P (decl))
582 if (l->pure_const_state != IPA_CONST)
583 l->pure_const_state = IPA_PURE;
584 l->state_previously_known = IPA_PURE;
585 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
586 l->looping = false, l->looping_previously_known = false;
588 if (TREE_NOTHROW (decl))
589 l->can_throw = false;
591 pop_cfun ();
592 current_function_decl = old_decl;
593 if (dump_file)
595 if (l->looping)
596 fprintf (dump_file, "Function is locally looping.\n");
597 if (l->can_throw)
598 fprintf (dump_file, "Function is locally throwing.\n");
599 if (l->pure_const_state == IPA_CONST)
600 fprintf (dump_file, "Function is locally const.\n");
601 if (l->pure_const_state == IPA_PURE)
602 fprintf (dump_file, "Function is locally pure.\n");
604 return l;
607 /* Called when new function is inserted to callgraph late. */
608 static void
609 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
611 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
612 return;
613 /* There are some shared nodes, in particular the initializers on
614 static declarations. We do not need to scan them more than once
615 since all we would be interested in are the addressof
616 operations. */
617 visited_nodes = pointer_set_create ();
618 set_function_state (node, analyze_function (node, true));
619 pointer_set_destroy (visited_nodes);
620 visited_nodes = NULL;
623 /* Called when new clone is inserted to callgraph late. */
625 static void
626 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
627 void *data ATTRIBUTE_UNUSED)
629 if (get_function_state (src))
631 funct_state l = XNEW (struct funct_state_d);
632 gcc_assert (!get_function_state (dst));
633 memcpy (l, get_function_state (src), sizeof (*l));
634 set_function_state (dst, l);
638 /* Called when new clone is inserted to callgraph late. */
640 static void
641 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
643 if (get_function_state (node))
645 free (get_function_state (node));
646 set_function_state (node, NULL);
651 /* Analyze each function in the cgraph to see if it is locally PURE or
652 CONST. */
654 static void
655 generate_summary (void)
657 struct cgraph_node *node;
659 node_removal_hook_holder =
660 cgraph_add_node_removal_hook (&remove_node_data, NULL);
661 node_duplication_hook_holder =
662 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
663 function_insertion_hook_holder =
664 cgraph_add_function_insertion_hook (&add_new_function, NULL);
665 /* There are some shared nodes, in particular the initializers on
666 static declarations. We do not need to scan them more than once
667 since all we would be interested in are the addressof
668 operations. */
669 visited_nodes = pointer_set_create ();
671 /* Process all of the functions.
673 We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
674 guarantee that what we learn about the one we see will be true
675 for the one that overrides it.
677 for (node = cgraph_nodes; node; node = node->next)
678 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
679 set_function_state (node, analyze_function (node, true));
681 pointer_set_destroy (visited_nodes);
682 visited_nodes = NULL;
685 static bool
686 ignore_edge (struct cgraph_edge *e)
688 return (!e->can_throw_external);
691 /* Produce the global information by preforming a transitive closure
692 on the local information that was produced by generate_summary.
693 Note that there is no function_transform pass since this only
694 updates the function_decl. */
696 static unsigned int
697 propagate (void)
699 struct cgraph_node *node;
700 struct cgraph_node *w;
701 struct cgraph_node **order =
702 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
703 int order_pos;
704 int i;
705 struct ipa_dfs_info * w_info;
707 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
708 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
709 cgraph_remove_node_removal_hook (node_removal_hook_holder);
710 order_pos = ipa_utils_reduced_inorder (order, true, false, NULL);
711 if (dump_file)
713 dump_cgraph (dump_file);
714 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
717 /* Propagate the local information thru the call graph to produce
718 the global information. All the nodes within a cycle will have
719 the same info so we collapse cycles first. Then we can do the
720 propagation in one pass from the leaves to the roots. */
721 for (i = 0; i < order_pos; i++ )
723 enum pure_const_state_e pure_const_state = IPA_CONST;
724 bool looping = false;
725 int count = 0;
726 node = order[i];
728 /* Find the worst state for any node in the cycle. */
729 w = node;
730 while (w)
732 struct cgraph_edge *e;
733 funct_state w_l = get_function_state (w);
734 if (pure_const_state < w_l->pure_const_state)
735 pure_const_state = w_l->pure_const_state;
737 if (w_l->looping)
738 looping = true;
740 if (pure_const_state == IPA_NEITHER)
741 break;
743 count++;
745 if (count > 1)
746 looping = true;
748 for (e = w->callees; e; e = e->next_callee)
750 struct cgraph_node *y = e->callee;
752 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
754 funct_state y_l = get_function_state (y);
755 if (pure_const_state < y_l->pure_const_state)
756 pure_const_state = y_l->pure_const_state;
757 if (pure_const_state == IPA_NEITHER)
758 break;
759 if (y_l->looping)
760 looping = true;
763 w_info = (struct ipa_dfs_info *) w->aux;
764 w = w_info->next_cycle;
767 /* Copy back the region's pure_const_state which is shared by
768 all nodes in the region. */
769 w = node;
770 while (w)
772 funct_state w_l = get_function_state (w);
773 enum pure_const_state_e this_state = pure_const_state;
774 bool this_looping = looping;
776 if (w_l->state_previously_known != IPA_NEITHER
777 && this_state > w_l->state_previously_known)
778 this_state = w_l->state_previously_known;
779 if (!w_l->looping_previously_known)
780 this_looping = false;
782 /* All nodes within a cycle share the same info. */
783 w_l->pure_const_state = this_state;
784 w_l->looping = this_looping;
786 switch (this_state)
788 case IPA_CONST:
789 if (!TREE_READONLY (w->decl) && dump_file)
790 fprintf (dump_file, "Function found to be %sconst: %s\n",
791 this_looping ? "looping " : "",
792 cgraph_node_name (w));
793 TREE_READONLY (w->decl) = 1;
794 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
795 break;
797 case IPA_PURE:
798 if (!DECL_PURE_P (w->decl) && dump_file)
799 fprintf (dump_file, "Function found to be %spure: %s\n",
800 this_looping ? "looping " : "",
801 cgraph_node_name (w));
802 DECL_PURE_P (w->decl) = 1;
803 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
804 break;
806 default:
807 break;
809 w_info = (struct ipa_dfs_info *) w->aux;
810 w = w_info->next_cycle;
814 /* Cleanup. */
815 for (node = cgraph_nodes; node; node = node->next)
817 /* Get rid of the aux information. */
818 if (node->aux)
820 w_info = (struct ipa_dfs_info *) node->aux;
821 free (node->aux);
822 node->aux = NULL;
825 order_pos = ipa_utils_reduced_inorder (order, true, false, ignore_edge);
826 if (dump_file)
828 dump_cgraph (dump_file);
829 ipa_utils_print_order(dump_file, "reduced for nothrow", order, order_pos);
831 /* Propagate the local information thru the call graph to produce
832 the global information. All the nodes within a cycle will have
833 the same info so we collapse cycles first. Then we can do the
834 propagation in one pass from the leaves to the roots. */
835 for (i = 0; i < order_pos; i++ )
837 bool can_throw = false;
838 node = order[i];
840 /* Find the worst state for any node in the cycle. */
841 w = node;
842 while (w)
844 struct cgraph_edge *e;
845 funct_state w_l = get_function_state (w);
847 if (w_l->can_throw)
848 can_throw = true;
850 if (can_throw)
851 break;
853 for (e = w->callees; e; e = e->next_callee)
855 struct cgraph_node *y = e->callee;
857 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
859 funct_state y_l = get_function_state (y);
861 if (can_throw)
862 break;
863 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
864 && e->can_throw_external)
865 can_throw = true;
868 w_info = (struct ipa_dfs_info *) w->aux;
869 w = w_info->next_cycle;
872 /* Copy back the region's pure_const_state which is shared by
873 all nodes in the region. */
874 w = node;
875 while (w)
877 funct_state w_l = get_function_state (w);
878 if (!can_throw && !TREE_NOTHROW (w->decl))
880 struct cgraph_edge *e;
881 TREE_NOTHROW (w->decl) = true;
882 for (e = w->callers; e; e = e->next_caller)
883 e->can_throw_external = false;
884 if (dump_file)
885 fprintf (dump_file, "Function found to be nothrow: %s\n",
886 cgraph_node_name (w));
888 else if (can_throw && !TREE_NOTHROW (w->decl))
889 w_l->can_throw = true;
890 w_info = (struct ipa_dfs_info *) w->aux;
891 w = w_info->next_cycle;
895 /* Cleanup. */
896 for (node = cgraph_nodes; node; node = node->next)
898 /* Get rid of the aux information. */
899 if (node->aux)
901 w_info = (struct ipa_dfs_info *) node->aux;
902 free (node->aux);
903 node->aux = NULL;
905 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
906 free (get_function_state (node));
909 free (order);
910 VEC_free (funct_state, heap, funct_state_vec);
911 finish_state ();
912 return 0;
915 static bool
916 gate_pure_const (void)
918 return (flag_ipa_pure_const
919 /* Don't bother doing anything if the program has errors. */
920 && !(errorcount || sorrycount));
923 struct ipa_opt_pass_d pass_ipa_pure_const =
926 IPA_PASS,
927 "pure-const", /* name */
928 gate_pure_const, /* gate */
929 propagate, /* execute */
930 NULL, /* sub */
931 NULL, /* next */
932 0, /* static_pass_number */
933 TV_IPA_PURE_CONST, /* tv_id */
934 0, /* properties_required */
935 0, /* properties_provided */
936 0, /* properties_destroyed */
937 0, /* todo_flags_start */
938 0 /* todo_flags_finish */
940 generate_summary, /* generate_summary */
941 NULL, /* write_summary */
942 NULL, /* read_summary */
943 NULL, /* function_read_summary */
944 0, /* TODOs */
945 NULL, /* function_transform */
946 NULL /* variable_transform */
949 /* Simple local pass for pure const discovery reusing the analysis from
950 ipa_pure_const. This pass is effective when executed together with
951 other optimization passes in early optimization pass queue. */
953 static unsigned int
954 local_pure_const (void)
956 bool changed = false;
957 funct_state l;
959 /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations
960 we must not promote functions that are called by already processed functions. */
962 if (function_called_by_processed_nodes_p ())
964 if (dump_file)
965 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
966 return 0;
969 l = analyze_function (cgraph_node (current_function_decl), false);
970 if (!l)
972 if (dump_file)
973 fprintf (dump_file, "Function has wrong visibility; ignoring\n");
974 return 0;
977 switch (l->pure_const_state)
979 case IPA_CONST:
980 if (!TREE_READONLY (current_function_decl))
982 TREE_READONLY (current_function_decl) = 1;
983 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
984 changed = true;
985 if (dump_file)
986 fprintf (dump_file, "Function found to be %sconst: %s\n",
987 l->looping ? "looping " : "",
988 lang_hooks.decl_printable_name (current_function_decl,
989 2));
991 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
992 && !l->looping)
994 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
995 changed = true;
996 if (dump_file)
997 fprintf (dump_file, "Function found to be non-looping: %s\n",
998 lang_hooks.decl_printable_name (current_function_decl,
999 2));
1001 break;
1003 case IPA_PURE:
1004 if (!TREE_READONLY (current_function_decl))
1006 DECL_PURE_P (current_function_decl) = 1;
1007 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
1008 changed = true;
1009 if (dump_file)
1010 fprintf (dump_file, "Function found to be %spure: %s\n",
1011 l->looping ? "looping " : "",
1012 lang_hooks.decl_printable_name (current_function_decl,
1013 2));
1015 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1016 && !l->looping)
1018 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
1019 changed = true;
1020 if (dump_file)
1021 fprintf (dump_file, "Function found to be non-looping: %s\n",
1022 lang_hooks.decl_printable_name (current_function_decl,
1023 2));
1025 break;
1027 default:
1028 break;
1030 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
1032 struct cgraph_edge *e;
1034 TREE_NOTHROW (current_function_decl) = true;
1035 for (e = cgraph_node (current_function_decl)->callers;
1036 e; e = e->next_caller)
1037 e->can_throw_external = false;
1038 changed = true;
1039 if (dump_file)
1040 fprintf (dump_file, "Function found to be nothrow: %s\n",
1041 lang_hooks.decl_printable_name (current_function_decl,
1042 2));
1044 if (l)
1045 free (l);
1046 if (changed)
1047 return execute_fixup_cfg ();
1048 else
1049 return 0;
1052 struct gimple_opt_pass pass_local_pure_const =
1055 GIMPLE_PASS,
1056 "local-pure-const", /* name */
1057 gate_pure_const, /* gate */
1058 local_pure_const, /* execute */
1059 NULL, /* sub */
1060 NULL, /* next */
1061 0, /* static_pass_number */
1062 TV_IPA_PURE_CONST, /* tv_id */
1063 0, /* properties_required */
1064 0, /* properties_provided */
1065 0, /* properties_destroyed */
1066 0, /* todo_flags_start */
1067 0 /* todo_flags_finish */