Backport from LTO branch:
[gcc.git] / gcc / ipa-pure-const.c
1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
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).
24
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. */
29
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. */
33
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 "c-common.h"
47 #include "gimple.h"
48 #include "cgraph.h"
49 #include "output.h"
50 #include "flags.h"
51 #include "timevar.h"
52 #include "diagnostic.h"
53 #include "langhooks.h"
54 #include "target.h"
55
56 static struct pointer_set_t *visited_nodes;
57
58 /* Lattice values for const and pure functions. Everything starts out
59 being const, then may drop to pure and then neither depending on
60 what is found. */
61 enum pure_const_state_e
62 {
63 IPA_CONST,
64 IPA_PURE,
65 IPA_NEITHER
66 };
67
68 /* Holder for the const_state. There is one of these per function
69 decl. */
70 struct funct_state_d
71 {
72 /* See above. */
73 enum pure_const_state_e pure_const_state;
74
75 /* True if the function could possibly infinite loop. There are a
76 lot of ways that this could be determined. We are pretty
77 conservative here. While it is possible to cse pure and const
78 calls, it is not legal to have dce get rid of the call if there
79 is a possibility that the call could infinite loop since this is
80 a behavioral change. */
81 bool looping;
82
83 /* If the state of the function was set in the source, then assume
84 that it was done properly even if the analysis we do would be
85 more pessimestic. */
86 bool state_set_in_source;
87 };
88
89 typedef struct funct_state_d * funct_state;
90
91 /* The storage of the funct_state is abstracted because there is the
92 possibility that it may be desirable to move this to the cgraph
93 local info. */
94
95 /* Array, indexed by cgraph node uid, of function states. */
96
97 static funct_state *funct_state_vec;
98
99
100 /* Init the function state. */
101
102 static void
103 init_state (void)
104 {
105 funct_state_vec = XCNEWVEC (funct_state, cgraph_max_uid);
106 }
107
108
109 /* Init the function state. */
110
111 static void
112 finish_state (void)
113 {
114 free (funct_state_vec);
115 }
116
117
118 /* Return the function state from NODE. */
119
120 static inline funct_state
121 get_function_state (struct cgraph_node *node)
122 {
123 return funct_state_vec[node->uid];
124 }
125
126 /* Set the function state S for NODE. */
127
128 static inline void
129 set_function_state (struct cgraph_node *node, funct_state s)
130 {
131 funct_state_vec[node->uid] = s;
132 }
133
134 /* Check to see if the use (or definition when CHECKING_WRITE is true)
135 variable T is legal in a function that is either pure or const. */
136
137 static inline void
138 check_decl (funct_state local,
139 tree t, bool checking_write)
140 {
141 /* If the variable has the "used" attribute, treat it as if it had a
142 been touched by the devil. */
143 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
144 {
145 local->pure_const_state = IPA_NEITHER;
146 local->looping = false;
147 return;
148 }
149
150 /* Do not want to do anything with volatile except mark any
151 function that uses one to be not const or pure. */
152 if (TREE_THIS_VOLATILE (t))
153 {
154 local->pure_const_state = IPA_NEITHER;
155 local->looping = false;
156 return;
157 }
158
159 /* Do not care about a local automatic that is not static. */
160 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
161 return;
162
163 /* Since we have dealt with the locals and params cases above, if we
164 are CHECKING_WRITE, this cannot be a pure or constant
165 function. */
166 if (checking_write)
167 {
168 local->pure_const_state = IPA_NEITHER;
169 local->looping = false;
170 return;
171 }
172
173 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
174 {
175 /* If the front end set the variable to be READONLY and
176 constant, we can allow this variable in pure or const
177 functions but the scope is too large for our analysis to set
178 these bits ourselves. */
179
180 if (TREE_READONLY (t)
181 && DECL_INITIAL (t)
182 && is_gimple_min_invariant (DECL_INITIAL (t)))
183 ; /* Read of a constant, do not change the function state. */
184 else
185 {
186 /* Just a regular read. */
187 if (local->pure_const_state == IPA_CONST)
188 local->pure_const_state = IPA_PURE;
189 }
190 }
191
192 /* Compilation level statics can be read if they are readonly
193 variables. */
194 if (TREE_READONLY (t))
195 return;
196
197 /* Just a regular read. */
198 if (local->pure_const_state == IPA_CONST)
199 local->pure_const_state = IPA_PURE;
200 }
201
202 /* If T is a VAR_DECL check to see if it is an allowed reference. */
203
204 static void
205 check_operand (funct_state local,
206 tree t, bool checking_write)
207 {
208 if (!t) return;
209
210 if (TREE_CODE (t) == VAR_DECL)
211 check_decl (local, t, checking_write);
212 }
213
214 /* Examine tree T for references. */
215
216 static void
217 check_tree (funct_state local, tree t, bool checking_write)
218 {
219 if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR)
220 || TREE_CODE (t) == SSA_NAME)
221 return;
222
223 /* Any tree which is volatile disqualifies this function from being
224 const or pure. */
225 if (TREE_THIS_VOLATILE (t))
226 {
227 local->pure_const_state = IPA_NEITHER;
228 local->looping = false;
229 return;
230 }
231
232 while (TREE_CODE (t) == REALPART_EXPR
233 || TREE_CODE (t) == IMAGPART_EXPR
234 || handled_component_p (t))
235 {
236 if (TREE_CODE (t) == ARRAY_REF)
237 check_operand (local, TREE_OPERAND (t, 1), false);
238 t = TREE_OPERAND (t, 0);
239 }
240
241 /* The bottom of an indirect reference can only be read, not
242 written. */
243 if (INDIRECT_REF_P (t))
244 {
245 check_tree (local, TREE_OPERAND (t, 0), false);
246
247 /* Any indirect reference that occurs on the lhs
248 disqualifies the function from being pure or const. Any
249 indirect reference that occurs on the rhs disqualifies the
250 function from being const. */
251 if (checking_write)
252 {
253 local->pure_const_state = IPA_NEITHER;
254 local->looping = false;
255 return;
256 }
257 else if (local->pure_const_state == IPA_CONST)
258 local->pure_const_state = IPA_PURE;
259 }
260
261 if (SSA_VAR_P (t))
262 check_operand (local, t, checking_write);
263 }
264
265 /* Scan tree T to see if there are any addresses taken in within T. */
266
267 static void
268 look_for_address_of (funct_state local, tree t)
269 {
270 if (TREE_CODE (t) == ADDR_EXPR)
271 {
272 tree x = get_base_var (t);
273 if (TREE_CODE (x) == VAR_DECL)
274 {
275 check_decl (local, x, false);
276
277 /* Taking the address of something appears to be reasonable
278 in PURE code. Not allowed in const. */
279 if (local->pure_const_state == IPA_CONST)
280 local->pure_const_state = IPA_PURE;
281 }
282 }
283 }
284
285 /* Check to see if T is a read or address of operation on a var we are
286 interested in analyzing. LOCAL is passed in to get access to its
287 bit vectors. */
288
289 static void
290 check_rhs_var (funct_state local, tree t)
291 {
292 look_for_address_of (local, t);
293
294 /* Memcmp and strlen can both trap and they are declared pure. */
295 if (tree_could_trap_p (t)
296 && local->pure_const_state == IPA_CONST)
297 local->pure_const_state = IPA_PURE;
298
299 check_tree(local, t, false);
300 }
301
302 /* Check to see if T is an assignment to a var we are interested in
303 analyzing. LOCAL is passed in to get access to its bit vectors. */
304
305 static void
306 check_lhs_var (funct_state local, tree t)
307 {
308 /* Memcmp and strlen can both trap and they are declared pure.
309 Which seems to imply that we can apply the same rule here. */
310 if (tree_could_trap_p (t)
311 && local->pure_const_state == IPA_CONST)
312 local->pure_const_state = IPA_PURE;
313
314 check_tree(local, t, true);
315 }
316
317 /* This is a scaled down version of get_asm_expr_operands from
318 tree_ssa_operands.c. The version there runs much later and assumes
319 that aliasing information is already available. Here we are just
320 trying to find if the set of inputs and outputs contain references
321 or address of operations to local static variables. STMT is the
322 actual asm statement. */
323
324 static void
325 get_asm_expr_operands (funct_state local, gimple stmt)
326 {
327 size_t noutputs = gimple_asm_noutputs (stmt);
328 const char **oconstraints
329 = (const char **) alloca ((noutputs) * sizeof (const char *));
330 size_t i;
331 tree op;
332 const char *constraint;
333 bool allows_mem, allows_reg, is_inout;
334
335 for (i = 0; i < noutputs; i++)
336 {
337 op = gimple_asm_output_op (stmt, i);
338 oconstraints[i] = constraint
339 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
340 parse_output_constraint (&constraint, i, 0, 0,
341 &allows_mem, &allows_reg, &is_inout);
342
343 check_lhs_var (local, TREE_VALUE (op));
344 }
345
346 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
347 {
348 op = gimple_asm_input_op (stmt, i);
349 constraint
350 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
351 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
352 oconstraints, &allows_mem, &allows_reg);
353
354 check_rhs_var (local, TREE_VALUE (op));
355 }
356
357 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
358 {
359 op = gimple_asm_clobber_op (stmt, i);
360 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
361 /* Abandon all hope, ye who enter here. */
362 local->pure_const_state = IPA_NEITHER;
363 }
364
365 if (gimple_asm_volatile_p (stmt))
366 local->pure_const_state = IPA_NEITHER;
367 }
368
369 /* Check the parameters of a function call to CALL_EXPR to see if
370 there are any references in the parameters that are not allowed for
371 pure or const functions. Also check to see if this is either an
372 indirect call, a call outside the compilation unit, or has special
373 attributes that may also effect the purity. The CALL_EXPR node for
374 the entire call expression. */
375
376 static void
377 check_call (funct_state local, gimple call)
378 {
379 int flags = gimple_call_flags (call);
380 tree lhs, callee_t = gimple_call_fndecl (call);
381 struct cgraph_node* callee;
382 enum availability avail = AVAIL_NOT_AVAILABLE;
383 size_t i;
384
385 lhs = gimple_call_lhs (call);
386 if (lhs)
387 check_lhs_var (local, lhs);
388
389 for (i = 0; i < gimple_call_num_args (call); i++)
390 check_rhs_var (local, gimple_call_arg (call, i));
391
392 /* The const and pure flags are set by a variety of places in the
393 compiler (including here). If someone has already set the flags
394 for the callee, (such as for some of the builtins) we will use
395 them, otherwise we will compute our own information.
396
397 Const and pure functions have less clobber effects than other
398 functions so we process these first. Otherwise if it is a call
399 outside the compilation unit or an indirect call we punt. This
400 leaves local calls which will be processed by following the call
401 graph. */
402 if (callee_t)
403 {
404 callee = cgraph_node(callee_t);
405 avail = cgraph_function_body_availability (callee);
406
407 /* When bad things happen to bad functions, they cannot be const
408 or pure. */
409 if (setjmp_call_p (callee_t))
410 {
411 local->pure_const_state = IPA_NEITHER;
412 local->looping = false;
413 }
414
415 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
416 switch (DECL_FUNCTION_CODE (callee_t))
417 {
418 case BUILT_IN_LONGJMP:
419 case BUILT_IN_NONLOCAL_GOTO:
420 local->pure_const_state = IPA_NEITHER;
421 local->looping = false;
422 break;
423 default:
424 break;
425 }
426 }
427
428 /* The callee is either unknown (indirect call) or there is just no
429 scannable code for it (external call) . We look to see if there
430 are any bits available for the callee (such as by declaration or
431 because it is builtin) and process solely on the basis of those
432 bits. */
433 if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
434 {
435 if (flags & ECF_PURE)
436 {
437 if (local->pure_const_state == IPA_CONST)
438 local->pure_const_state = IPA_PURE;
439 }
440 else
441 local->pure_const_state = IPA_NEITHER;
442 }
443 else
444 {
445 /* We have the code and we will scan it for the effects. */
446 if (flags & ECF_PURE)
447 {
448 if (local->pure_const_state == IPA_CONST)
449 local->pure_const_state = IPA_PURE;
450 }
451 }
452 }
453
454 /* TP is the part of the tree currently under the microscope.
455 WALK_SUBTREES is part of the walk_tree api but is unused here.
456 DATA is cgraph_node of the function being walked. */
457
458 /* FIXME: When this is converted to run over SSA form, this code
459 should be converted to use the operand scanner. */
460
461 static tree
462 scan_function_op (tree *tp, int *walk_subtrees, void *data)
463 {
464 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
465 struct cgraph_node *fn = (struct cgraph_node *) wi->info;
466 tree t = *tp;
467 funct_state local = get_function_state (fn);
468
469 switch (TREE_CODE (t))
470 {
471 case VAR_DECL:
472 if (DECL_INITIAL (t))
473 walk_tree (&DECL_INITIAL (t), scan_function_op, data, visited_nodes);
474 *walk_subtrees = 0;
475 break;
476
477 case ADDR_EXPR:
478 /* This case is here to find addresses on rhs of constructors in
479 decl_initial of static variables. */
480 check_rhs_var (local, t);
481 *walk_subtrees = 0;
482 break;
483
484 default:
485 break;
486 }
487 return NULL;
488 }
489
490 static tree
491 scan_function_stmt (gimple_stmt_iterator *gsi_p,
492 bool *handled_ops_p,
493 struct walk_stmt_info *wi)
494 {
495 struct cgraph_node *fn = (struct cgraph_node *) wi->info;
496 gimple stmt = gsi_stmt (*gsi_p);
497 funct_state local = get_function_state (fn);
498
499 switch (gimple_code (stmt))
500 {
501 case GIMPLE_ASSIGN:
502 {
503 /* First look on the lhs and see what variable is stored to */
504 tree lhs = gimple_assign_lhs (stmt);
505 tree rhs1 = gimple_assign_rhs1 (stmt);
506 tree rhs2 = gimple_assign_rhs2 (stmt);
507 enum tree_code code = gimple_assign_rhs_code (stmt);
508
509 check_lhs_var (local, lhs);
510
511 /* For the purposes of figuring out what the cast affects */
512
513 /* Next check the operands on the rhs to see if they are ok. */
514 switch (TREE_CODE_CLASS (code))
515 {
516 case tcc_binary:
517 {
518 check_rhs_var (local, rhs1);
519 check_rhs_var (local, rhs2);
520 }
521 break;
522 case tcc_unary:
523 {
524 check_rhs_var (local, rhs1);
525 }
526
527 break;
528 case tcc_reference:
529 check_rhs_var (local, rhs1);
530 break;
531 case tcc_declaration:
532 check_rhs_var (local, rhs1);
533 break;
534 case tcc_expression:
535 switch (code)
536 {
537 case ADDR_EXPR:
538 check_rhs_var (local, rhs1);
539 break;
540 default:
541 break;
542 }
543 break;
544 default:
545 break;
546 }
547 *handled_ops_p = true;
548 }
549 break;
550
551 case GIMPLE_LABEL:
552 if (DECL_NONLOCAL (gimple_label_label (stmt)))
553 /* Target of long jump. */
554 {
555 local->pure_const_state = IPA_NEITHER;
556 local->looping = false;
557 }
558 break;
559
560 case GIMPLE_CALL:
561 check_call (local, stmt);
562 *handled_ops_p = true;
563 break;
564
565 case GIMPLE_ASM:
566 get_asm_expr_operands (local, stmt);
567 *handled_ops_p = true;
568 break;
569
570 default:
571 break;
572 }
573 return NULL;
574 }
575
576
577 /* This is the main routine for finding the reference patterns for
578 global variables within a function FN. */
579
580 static void
581 analyze_function (struct cgraph_node *fn)
582 {
583 tree decl = fn->decl;
584 funct_state l = XCNEW (struct funct_state_d);
585
586 set_function_state (fn, l);
587
588 l->pure_const_state = IPA_CONST;
589 l->state_set_in_source = false;
590 if (DECL_LOOPING_CONST_OR_PURE_P (decl))
591 l->looping = true;
592 else
593 l->looping = false;
594
595 /* If this function does not return normally or does not bind local,
596 do not touch this unless it has been marked as const or pure by the
597 front end. */
598 if (TREE_THIS_VOLATILE (decl)
599 || !targetm.binds_local_p (decl))
600 {
601 l->pure_const_state = IPA_NEITHER;
602 return;
603 }
604
605 if (TREE_READONLY (decl))
606 {
607 l->pure_const_state = IPA_CONST;
608 l->state_set_in_source = true;
609 }
610 if (DECL_PURE_P (decl))
611 {
612 l->pure_const_state = IPA_PURE;
613 l->state_set_in_source = true;
614 }
615
616 if (dump_file)
617 {
618 fprintf (dump_file, "\n local analysis of %s with initial value = %d\n ",
619 cgraph_node_name (fn),
620 l->pure_const_state);
621 }
622
623 if (!l->state_set_in_source)
624 {
625 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
626 basic_block this_block;
627
628 FOR_EACH_BB_FN (this_block, this_cfun)
629 {
630 gimple_stmt_iterator gsi;
631 struct walk_stmt_info wi;
632
633 memset (&wi, 0, sizeof(wi));
634 for (gsi = gsi_start_bb (this_block);
635 !gsi_end_p (gsi);
636 gsi_next (&gsi))
637 {
638 wi.info = fn;
639 wi.pset = visited_nodes;
640 walk_gimple_stmt (&gsi, scan_function_stmt, scan_function_op,
641 &wi);
642 if (l->pure_const_state == IPA_NEITHER)
643 goto end;
644 }
645 }
646
647 if (l->pure_const_state != IPA_NEITHER)
648 {
649 tree old_decl = current_function_decl;
650 /* Const functions cannot have back edges (an
651 indication of possible infinite loop side
652 effect. */
653
654 current_function_decl = fn->decl;
655
656 /* The C++ front end, has a tendency to some times jerk away
657 a function after it has created it. This should have
658 been fixed. */
659 gcc_assert (DECL_STRUCT_FUNCTION (fn->decl));
660
661 push_cfun (DECL_STRUCT_FUNCTION (fn->decl));
662
663 if (mark_dfs_back_edges ())
664 l->pure_const_state = IPA_NEITHER;
665
666 current_function_decl = old_decl;
667 pop_cfun ();
668 }
669 }
670
671 end:
672 if (dump_file)
673 {
674 fprintf (dump_file, "after local analysis of %s with initial value = %d\n ",
675 cgraph_node_name (fn),
676 l->pure_const_state);
677 }
678 }
679
680 \f
681 /* Analyze each function in the cgraph to see if it is locally PURE or
682 CONST. */
683
684 static void
685 generate_summary (void)
686 {
687 struct cgraph_node *node;
688
689 init_state ();
690 /* There are some shared nodes, in particular the initializers on
691 static declarations. We do not need to scan them more than once
692 since all we would be interested in are the addressof
693 operations. */
694 visited_nodes = pointer_set_create ();
695
696 /* Process all of the functions.
697
698 We do not want to process any of the clones so we check that this
699 is a master clone. However, we do NOT process any
700 AVAIL_OVERWRITABLE functions (these are never clones) we cannot
701 guarantee that what we learn about the one we see will be true
702 for the one that overrides it.
703 */
704 for (node = cgraph_nodes; node; node = node->next)
705 if (node->analyzed && cgraph_is_master_clone (node))
706 analyze_function (node);
707
708 pointer_set_destroy (visited_nodes);
709 visited_nodes = NULL;
710 }
711
712 /* Produce the global information by preforming a transitive closure
713 on the local information that was produced by generate_summary.
714 Note that there is no function_transform pass since this only
715 updates the function_decl. */
716
717 static unsigned int
718 propagate (void)
719 {
720 struct cgraph_node *node;
721 struct cgraph_node *w;
722 struct cgraph_node **order =
723 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
724 int order_pos;
725 int i;
726 struct ipa_dfs_info * w_info;
727
728 order_pos = ipa_utils_reduced_inorder (order, true, false);
729 if (dump_file)
730 {
731 dump_cgraph (dump_file);
732 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
733 }
734
735 /* Propagate the local information thru the call graph to produce
736 the global information. All the nodes within a cycle will have
737 the same info so we collapse cycles first. Then we can do the
738 propagation in one pass from the leaves to the roots. */
739 for (i = 0; i < order_pos; i++ )
740 {
741 enum pure_const_state_e pure_const_state = IPA_CONST;
742 bool looping = false;
743 int count = 0;
744 node = order[i];
745
746 /* Find the worst state for any node in the cycle. */
747 w = node;
748 while (w)
749 {
750 funct_state w_l = get_function_state (w);
751 if (pure_const_state < w_l->pure_const_state)
752 pure_const_state = w_l->pure_const_state;
753
754 if (w_l->looping)
755 looping = true;
756
757 if (pure_const_state == IPA_NEITHER)
758 break;
759
760 if (!w_l->state_set_in_source)
761 {
762 struct cgraph_edge *e;
763 count++;
764
765 if (count > 1)
766 looping = true;
767
768 for (e = w->callees; e; e = e->next_callee)
769 {
770 struct cgraph_node *y = e->callee;
771 /* Only look at the master nodes and skip external nodes. */
772 y = cgraph_master_clone (y);
773
774 if (w == y)
775 looping = true;
776 if (y)
777 {
778 funct_state y_l = get_function_state (y);
779 if (pure_const_state < y_l->pure_const_state)
780 pure_const_state = y_l->pure_const_state;
781 if (pure_const_state == IPA_NEITHER)
782 break;
783 if (y_l->looping)
784 looping = true;
785 }
786 }
787 }
788 w_info = (struct ipa_dfs_info *) w->aux;
789 w = w_info->next_cycle;
790 }
791
792 /* Copy back the region's pure_const_state which is shared by
793 all nodes in the region. */
794 w = node;
795 while (w)
796 {
797 funct_state w_l = get_function_state (w);
798
799 /* All nodes within a cycle share the same info. */
800 if (!w_l->state_set_in_source)
801 {
802 w_l->pure_const_state = pure_const_state;
803 w_l->looping = looping;
804
805 switch (pure_const_state)
806 {
807 case IPA_CONST:
808 TREE_READONLY (w->decl) = 1;
809 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = looping;
810 if (dump_file)
811 fprintf (dump_file, "Function found to be %sconst: %s\n",
812 looping ? "looping " : "",
813 lang_hooks.decl_printable_name(w->decl, 2));
814 break;
815
816 case IPA_PURE:
817 DECL_PURE_P (w->decl) = 1;
818 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = looping;
819 if (dump_file)
820 fprintf (dump_file, "Function found to be %spure: %s\n",
821 looping ? "looping " : "",
822 lang_hooks.decl_printable_name(w->decl, 2));
823 break;
824
825 default:
826 break;
827 }
828 }
829 w_info = (struct ipa_dfs_info *) w->aux;
830 w = w_info->next_cycle;
831 }
832 }
833
834 /* Cleanup. */
835 for (node = cgraph_nodes; node; node = node->next)
836 {
837 /* Get rid of the aux information. */
838 if (node->aux)
839 {
840 w_info = (struct ipa_dfs_info *) node->aux;
841 free (node->aux);
842 node->aux = NULL;
843 }
844 if (node->analyzed && cgraph_is_master_clone (node))
845 free (get_function_state (node));
846 }
847
848 free (order);
849 finish_state ();
850 return 0;
851 }
852
853 static bool
854 gate_pure_const (void)
855 {
856 return (flag_ipa_pure_const
857 /* Don't bother doing anything if the program has errors. */
858 && !(errorcount || sorrycount));
859 }
860
861 struct ipa_opt_pass pass_ipa_pure_const =
862 {
863 {
864 IPA_PASS,
865 "pure-const", /* name */
866 gate_pure_const, /* gate */
867 propagate, /* execute */
868 NULL, /* sub */
869 NULL, /* next */
870 0, /* static_pass_number */
871 TV_IPA_PURE_CONST, /* tv_id */
872 0, /* properties_required */
873 0, /* properties_provided */
874 0, /* properties_destroyed */
875 0, /* todo_flags_start */
876 0 /* todo_flags_finish */
877 },
878 generate_summary, /* generate_summary */
879 NULL, /* write_summary */
880 NULL, /* read_summary */
881 NULL, /* function_read_summary */
882 0, /* TODOs */
883 NULL, /* function_transform */
884 NULL /* variable_transform */
885 };