2009-07-17 Richard Guenther <rguenther@suse.de>
[official-gcc.git] / gcc / ipa-pure-const.c
blob4e62eb187a42a2fa87e2623939b242ade7d7c5ec
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 (dump_file)
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)
428 if (dump_file)
429 fprintf (dump_file, " can throw; looping");
430 local->looping = true;
432 if (stmt_can_throw_external (stmt))
434 if (dump_file)
435 fprintf (dump_file, " can throw externally");
436 local->can_throw = true;
439 switch (gimple_code (stmt))
441 case GIMPLE_CALL:
442 check_call (local, stmt, ipa);
443 break;
444 case GIMPLE_LABEL:
445 if (DECL_NONLOCAL (gimple_label_label (stmt)))
446 /* Target of long jump. */
448 if (dump_file)
449 fprintf (dump_file, " nonlocal label is not const/pure");
450 local->pure_const_state = IPA_NEITHER;
452 break;
453 case GIMPLE_ASM:
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)
459 if (dump_file)
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))
467 if (dump_file)
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;
473 return;
474 default:
475 break;
480 /* This is the main routine for finding the reference patterns for
481 global variables within a function FN. */
483 static funct_state
484 analyze_function (struct cgraph_node *fn, bool ipa)
486 tree decl = fn->decl;
487 tree old_decl = current_function_decl;
488 funct_state l;
489 basic_block this_block;
491 if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
493 if (dump_file)
494 fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n");
495 return NULL;
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;
502 l->looping = false;
503 l->can_throw = false;
505 if (dump_file)
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);
521 !gsi_end_p (gsi);
522 gsi_next (&gsi))
524 check_stmt (&gsi, l, ipa);
525 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
526 goto end;
530 end:
531 if (l->pure_const_state != IPA_NEITHER)
533 /* Const functions cannot have back edges (an
534 indication of possible infinite loop side
535 effect. */
536 if (mark_dfs_back_edges ())
538 /* Preheaders are needed for SCEV to work.
539 Simple lateches and recorded exits improve chances that loop will
540 proved to be finite in testcases such as in loop-15.c and loop-24.c */
541 loop_optimizer_init (LOOPS_NORMAL
542 | LOOPS_HAVE_RECORDED_EXITS);
543 if (dump_file && (dump_flags & TDF_DETAILS))
544 flow_loops_dump (dump_file, NULL, 0);
545 if (mark_irreducible_loops ())
547 if (dump_file)
548 fprintf (dump_file, " has irreducible loops\n");
549 l->looping = true;
551 else
553 loop_iterator li;
554 struct loop *loop;
555 scev_initialize ();
556 FOR_EACH_LOOP (li, loop, 0)
557 if (!finite_loop_p (loop))
559 if (dump_file)
560 fprintf (dump_file, " can not prove finiteness of loop %i\n", loop->num);
561 l->looping =true;
562 break;
564 scev_finalize ();
566 loop_optimizer_finalize ();
570 if (TREE_READONLY (decl))
572 l->pure_const_state = IPA_CONST;
573 l->state_previously_known = IPA_CONST;
574 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
575 l->looping = false, l->looping_previously_known = false;
577 if (DECL_PURE_P (decl))
579 if (l->pure_const_state != IPA_CONST)
580 l->pure_const_state = IPA_PURE;
581 l->state_previously_known = IPA_PURE;
582 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
583 l->looping = false, l->looping_previously_known = false;
585 if (TREE_NOTHROW (decl))
586 l->can_throw = false;
588 pop_cfun ();
589 current_function_decl = old_decl;
590 if (dump_file)
592 if (l->looping)
593 fprintf (dump_file, "Function is locally looping.\n");
594 if (l->can_throw)
595 fprintf (dump_file, "Function is locally throwing.\n");
596 if (l->pure_const_state == IPA_CONST)
597 fprintf (dump_file, "Function is locally const.\n");
598 if (l->pure_const_state == IPA_PURE)
599 fprintf (dump_file, "Function is locally pure.\n");
601 return l;
604 /* Called when new function is inserted to callgraph late. */
605 static void
606 add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
608 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
609 return;
610 /* There are some shared nodes, in particular the initializers on
611 static declarations. We do not need to scan them more than once
612 since all we would be interested in are the addressof
613 operations. */
614 visited_nodes = pointer_set_create ();
615 set_function_state (node, analyze_function (node, true));
616 pointer_set_destroy (visited_nodes);
617 visited_nodes = NULL;
620 /* Called when new clone is inserted to callgraph late. */
622 static void
623 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
624 void *data ATTRIBUTE_UNUSED)
626 if (get_function_state (src))
628 funct_state l = XNEW (struct funct_state_d);
629 gcc_assert (!get_function_state (dst));
630 memcpy (l, get_function_state (src), sizeof (*l));
631 set_function_state (dst, l);
635 /* Called when new clone is inserted to callgraph late. */
637 static void
638 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
640 if (get_function_state (node))
642 free (get_function_state (node));
643 set_function_state (node, NULL);
648 /* Analyze each function in the cgraph to see if it is locally PURE or
649 CONST. */
651 static void
652 generate_summary (void)
654 struct cgraph_node *node;
656 node_removal_hook_holder =
657 cgraph_add_node_removal_hook (&remove_node_data, NULL);
658 node_duplication_hook_holder =
659 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
660 function_insertion_hook_holder =
661 cgraph_add_function_insertion_hook (&add_new_function, NULL);
662 /* There are some shared nodes, in particular the initializers on
663 static declarations. We do not need to scan them more than once
664 since all we would be interested in are the addressof
665 operations. */
666 visited_nodes = pointer_set_create ();
668 /* Process all of the functions.
670 We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
671 guarantee that what we learn about the one we see will be true
672 for the one that overrides it.
674 for (node = cgraph_nodes; node; node = node->next)
675 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
676 set_function_state (node, analyze_function (node, true));
678 pointer_set_destroy (visited_nodes);
679 visited_nodes = NULL;
682 static bool
683 ignore_edge (struct cgraph_edge *e)
685 return (!e->can_throw_external);
688 /* Produce the global information by preforming a transitive closure
689 on the local information that was produced by generate_summary.
690 Note that there is no function_transform pass since this only
691 updates the function_decl. */
693 static unsigned int
694 propagate (void)
696 struct cgraph_node *node;
697 struct cgraph_node *w;
698 struct cgraph_node **order =
699 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
700 int order_pos;
701 int i;
702 struct ipa_dfs_info * w_info;
704 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
705 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
706 cgraph_remove_node_removal_hook (node_removal_hook_holder);
707 order_pos = ipa_utils_reduced_inorder (order, true, false, NULL);
708 if (dump_file)
710 dump_cgraph (dump_file);
711 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
714 /* Propagate the local information thru the call graph to produce
715 the global information. All the nodes within a cycle will have
716 the same info so we collapse cycles first. Then we can do the
717 propagation in one pass from the leaves to the roots. */
718 for (i = 0; i < order_pos; i++ )
720 enum pure_const_state_e pure_const_state = IPA_CONST;
721 bool looping = false;
722 int count = 0;
723 node = order[i];
725 /* Find the worst state for any node in the cycle. */
726 w = node;
727 while (w)
729 struct cgraph_edge *e;
730 funct_state w_l = get_function_state (w);
731 if (pure_const_state < w_l->pure_const_state)
732 pure_const_state = w_l->pure_const_state;
734 if (w_l->looping)
735 looping = true;
737 if (pure_const_state == IPA_NEITHER)
738 break;
740 count++;
742 if (count > 1)
743 looping = true;
745 for (e = w->callees; e; e = e->next_callee)
747 struct cgraph_node *y = e->callee;
749 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
751 funct_state y_l = get_function_state (y);
752 if (pure_const_state < y_l->pure_const_state)
753 pure_const_state = y_l->pure_const_state;
754 if (pure_const_state == IPA_NEITHER)
755 break;
756 if (y_l->looping)
757 looping = true;
760 w_info = (struct ipa_dfs_info *) w->aux;
761 w = w_info->next_cycle;
764 /* Copy back the region's pure_const_state which is shared by
765 all nodes in the region. */
766 w = node;
767 while (w)
769 funct_state w_l = get_function_state (w);
770 enum pure_const_state_e this_state = pure_const_state;
771 bool this_looping = looping;
773 if (w_l->state_previously_known != IPA_NEITHER
774 && this_state > w_l->state_previously_known)
775 this_state = w_l->state_previously_known;
776 if (!w_l->looping_previously_known)
777 this_looping = false;
779 /* All nodes within a cycle share the same info. */
780 w_l->pure_const_state = this_state;
781 w_l->looping = this_looping;
783 switch (this_state)
785 case IPA_CONST:
786 if (!TREE_READONLY (w->decl) && dump_file)
787 fprintf (dump_file, "Function found to be %sconst: %s\n",
788 this_looping ? "looping " : "",
789 cgraph_node_name (w));
790 TREE_READONLY (w->decl) = 1;
791 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
792 break;
794 case IPA_PURE:
795 if (!DECL_PURE_P (w->decl) && dump_file)
796 fprintf (dump_file, "Function found to be %spure: %s\n",
797 this_looping ? "looping " : "",
798 cgraph_node_name (w));
799 DECL_PURE_P (w->decl) = 1;
800 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
801 break;
803 default:
804 break;
806 w_info = (struct ipa_dfs_info *) w->aux;
807 w = w_info->next_cycle;
811 /* Cleanup. */
812 for (node = cgraph_nodes; node; node = node->next)
814 /* Get rid of the aux information. */
815 if (node->aux)
817 w_info = (struct ipa_dfs_info *) node->aux;
818 free (node->aux);
819 node->aux = NULL;
822 order_pos = ipa_utils_reduced_inorder (order, true, false, ignore_edge);
823 if (dump_file)
825 dump_cgraph (dump_file);
826 ipa_utils_print_order(dump_file, "reduced for nothrow", order, order_pos);
828 /* Propagate the local information thru the call graph to produce
829 the global information. All the nodes within a cycle will have
830 the same info so we collapse cycles first. Then we can do the
831 propagation in one pass from the leaves to the roots. */
832 for (i = 0; i < order_pos; i++ )
834 bool can_throw = false;
835 node = order[i];
837 /* Find the worst state for any node in the cycle. */
838 w = node;
839 while (w)
841 struct cgraph_edge *e;
842 funct_state w_l = get_function_state (w);
844 if (w_l->can_throw)
845 can_throw = true;
847 if (can_throw)
848 break;
850 for (e = w->callees; e; e = e->next_callee)
852 struct cgraph_node *y = e->callee;
854 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
856 funct_state y_l = get_function_state (y);
858 if (can_throw)
859 break;
860 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
861 && e->can_throw_external)
862 can_throw = true;
865 w_info = (struct ipa_dfs_info *) w->aux;
866 w = w_info->next_cycle;
869 /* Copy back the region's pure_const_state which is shared by
870 all nodes in the region. */
871 w = node;
872 while (w)
874 funct_state w_l = get_function_state (w);
875 if (!can_throw && !TREE_NOTHROW (w->decl))
877 struct cgraph_edge *e;
878 TREE_NOTHROW (w->decl) = true;
879 for (e = w->callers; e; e = e->next_caller)
880 e->can_throw_external = false;
881 if (dump_file)
882 fprintf (dump_file, "Function found to be nothrow: %s\n",
883 cgraph_node_name (w));
885 else if (can_throw && !TREE_NOTHROW (w->decl))
886 w_l->can_throw = true;
887 w_info = (struct ipa_dfs_info *) w->aux;
888 w = w_info->next_cycle;
892 /* Cleanup. */
893 for (node = cgraph_nodes; node; node = node->next)
895 /* Get rid of the aux information. */
896 if (node->aux)
898 w_info = (struct ipa_dfs_info *) node->aux;
899 free (node->aux);
900 node->aux = NULL;
902 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
903 free (get_function_state (node));
906 free (order);
907 VEC_free (funct_state, heap, funct_state_vec);
908 finish_state ();
909 return 0;
912 static bool
913 gate_pure_const (void)
915 return (flag_ipa_pure_const
916 /* Don't bother doing anything if the program has errors. */
917 && !(errorcount || sorrycount));
920 struct ipa_opt_pass_d pass_ipa_pure_const =
923 IPA_PASS,
924 "pure-const", /* name */
925 gate_pure_const, /* gate */
926 propagate, /* execute */
927 NULL, /* sub */
928 NULL, /* next */
929 0, /* static_pass_number */
930 TV_IPA_PURE_CONST, /* tv_id */
931 0, /* properties_required */
932 0, /* properties_provided */
933 0, /* properties_destroyed */
934 0, /* todo_flags_start */
935 0 /* todo_flags_finish */
937 generate_summary, /* generate_summary */
938 NULL, /* write_summary */
939 NULL, /* read_summary */
940 NULL, /* function_read_summary */
941 0, /* TODOs */
942 NULL, /* function_transform */
943 NULL /* variable_transform */
946 /* Simple local pass for pure const discovery reusing the analysis from
947 ipa_pure_const. This pass is effective when executed together with
948 other optimization passes in early optimization pass queue. */
950 static unsigned int
951 local_pure_const (void)
953 bool changed = false;
954 funct_state l;
956 /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations
957 we must not promote functions that are called by already processed functions. */
959 if (function_called_by_processed_nodes_p ())
961 if (dump_file)
962 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
963 return 0;
966 l = analyze_function (cgraph_node (current_function_decl), false);
967 if (!l)
969 if (dump_file)
970 fprintf (dump_file, "Function has wrong visibility; ignoring\n");
971 return 0;
974 switch (l->pure_const_state)
976 case IPA_CONST:
977 if (!TREE_READONLY (current_function_decl))
979 TREE_READONLY (current_function_decl) = 1;
980 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
981 changed = true;
982 if (dump_file)
983 fprintf (dump_file, "Function found to be %sconst: %s\n",
984 l->looping ? "looping " : "",
985 lang_hooks.decl_printable_name (current_function_decl,
986 2));
988 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
989 && !l->looping)
991 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
992 changed = true;
993 if (dump_file)
994 fprintf (dump_file, "Function found to be non-looping: %s\n",
995 lang_hooks.decl_printable_name (current_function_decl,
996 2));
998 break;
1000 case IPA_PURE:
1001 if (!TREE_READONLY (current_function_decl))
1003 DECL_PURE_P (current_function_decl) = 1;
1004 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
1005 changed = true;
1006 if (dump_file)
1007 fprintf (dump_file, "Function found to be %spure: %s\n",
1008 l->looping ? "looping " : "",
1009 lang_hooks.decl_printable_name (current_function_decl,
1010 2));
1012 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1013 && !l->looping)
1015 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
1016 changed = true;
1017 if (dump_file)
1018 fprintf (dump_file, "Function found to be non-looping: %s\n",
1019 lang_hooks.decl_printable_name (current_function_decl,
1020 2));
1022 break;
1024 default:
1025 break;
1027 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
1029 struct cgraph_edge *e;
1031 TREE_NOTHROW (current_function_decl) = true;
1032 for (e = cgraph_node (current_function_decl)->callers;
1033 e; e = e->next_caller)
1034 e->can_throw_external = false;
1035 changed = true;
1036 if (dump_file)
1037 fprintf (dump_file, "Function found to be nothrow: %s\n",
1038 lang_hooks.decl_printable_name (current_function_decl,
1039 2));
1041 if (l)
1042 free (l);
1043 if (changed)
1044 return execute_fixup_cfg ();
1045 else
1046 return 0;
1049 struct gimple_opt_pass pass_local_pure_const =
1052 GIMPLE_PASS,
1053 "local-pure-const", /* name */
1054 gate_pure_const, /* gate */
1055 local_pure_const, /* execute */
1056 NULL, /* sub */
1057 NULL, /* next */
1058 0, /* static_pass_number */
1059 TV_IPA_PURE_CONST, /* tv_id */
1060 0, /* properties_required */
1061 0, /* properties_provided */
1062 0, /* properties_destroyed */
1063 0, /* todo_flags_start */
1064 0 /* todo_flags_finish */