]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-pure-const.c
2009-10-01 Loren J. Rittle <ljrittle@acm.org>
[thirdparty/gcc.git] / gcc / ipa-pure-const.c
CommitLineData
f7d118a9 1/* Callgraph based analysis of static variables.
26dbec0a 2 Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
f7d118a9 3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
8c4c00c1 9Software Foundation; either version 3, or (at your option) any later
f7d118a9 10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
f7d118a9 20
f0b5f617 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).
f7d118a9 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"
75a70cf9 46#include "gimple.h"
f7d118a9 47#include "cgraph.h"
48#include "output.h"
49#include "flags.h"
50#include "timevar.h"
51#include "diagnostic.h"
52#include "langhooks.h"
959fce68 53#include "target.h"
c9263b6a 54#include "cfgloop.h"
55#include "tree-scalar-evolution.h"
f7d118a9 56
57static struct pointer_set_t *visited_nodes;
58
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. */
62enum pure_const_state_e
63{
64 IPA_CONST,
65 IPA_PURE,
66 IPA_NEITHER
67};
68
cb886925 69/* Holder for the const_state. There is one of these per function
70 decl. */
f7d118a9 71struct funct_state_d
72{
cb886925 73 /* See above. */
f7d118a9 74 enum pure_const_state_e pure_const_state;
b5cebd44 75 /* What user set here; we can be always sure about this. */
df9b545b 76 enum pure_const_state_e state_previously_known;
77 bool looping_previously_known;
cb886925 78
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. */
9c2a0c05 85 bool looping;
cb886925 86
b5cebd44 87 bool can_throw;
f7d118a9 88};
89
90typedef struct funct_state_d * funct_state;
91
cb886925 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. */
95
96/* Array, indexed by cgraph node uid, of function states. */
97
86844d6c 98DEF_VEC_P (funct_state);
99DEF_VEC_ALLOC_P (funct_state, heap);
100static VEC (funct_state, heap) *funct_state_vec;
cb886925 101
50828ed8 102/* Holders of ipa cgraph hooks: */
103static struct cgraph_node_hook_list *function_insertion_hook_holder;
86844d6c 104static struct cgraph_2node_hook_list *node_duplication_hook_holder;
105static struct cgraph_node_hook_list *node_removal_hook_holder;
cb886925 106
107/* Init the function state. */
108
109static void
110finish_state (void)
111{
112 free (funct_state_vec);
113}
114
115
f7d118a9 116/* Return the function state from NODE. */
117
118static inline funct_state
119get_function_state (struct cgraph_node *node)
120{
86844d6c 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);
cb886925 125}
126
127/* Set the function state S for NODE. */
128
129static inline void
130set_function_state (struct cgraph_node *node, funct_state s)
131{
86844d6c 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);
f7d118a9 136}
137
f0b5f617 138/* Check to see if the use (or definition when CHECKING_WRITE is true)
f7d118a9 139 variable T is legal in a function that is either pure or const. */
140
141static inline void
142check_decl (funct_state local,
143 tree t, bool checking_write)
144{
f7d118a9 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))
148 {
149 local->pure_const_state = IPA_NEITHER;
b5cebd44 150 if (dump_file)
151 fprintf (dump_file, " Volatile operand is not const/pure");
f7d118a9 152 return;
153 }
154
155 /* Do not care about a local automatic that is not static. */
156 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
157 return;
158
b5cebd44 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)))
162 {
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;
167 }
168
f7d118a9 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)
bc17fd99 173 {
174 local->pure_const_state = IPA_NEITHER;
b5cebd44 175 if (dump_file)
176 fprintf (dump_file, " static/global memory write is not const/pure\n");
bc17fd99 177 return;
178 }
f7d118a9 179
180 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
181 {
b5cebd44 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. */
f7d118a9 185 else
186 {
b5cebd44 187 if (dump_file)
188 fprintf (dump_file, " global memory read is not const\n");
f7d118a9 189 /* Just a regular read. */
190 if (local->pure_const_state == IPA_CONST)
191 local->pure_const_state = IPA_PURE;
192 }
193 }
b5cebd44 194 else
195 {
196 /* Compilation level statics can be read if they are readonly
197 variables. */
198 if (TREE_READONLY (t))
199 return;
200
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;
206 }
f7d118a9 207}
208
f7d118a9 209
b5cebd44 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. */
f7d118a9 212
b5cebd44 213static inline void
5ed0b345 214check_op (funct_state local, tree t, bool checking_write)
f7d118a9 215{
3ae61172 216 t = get_base_address (t);
217 if (t && TREE_THIS_VOLATILE (t))
f7d118a9 218 {
5ed0b345 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;
223 }
3ae61172 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)))
228 {
229 if (dump_file)
230 fprintf (dump_file, " Indirect ref to local memory is OK\n");
231 return;
232 }
5ed0b345 233 else if (checking_write)
234 {
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;
239 }
240 else
241 {
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;
f7d118a9 246 }
247}
248
f7d118a9 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. */
255
256static void
b5cebd44 257check_call (funct_state local, gimple call, bool ipa)
f7d118a9 258{
75a70cf9 259 int flags = gimple_call_flags (call);
b5cebd44 260 tree callee_t = gimple_call_fndecl (call);
f7d118a9 261 struct cgraph_node* callee;
262 enum availability avail = AVAIL_NOT_AVAILABLE;
b5cebd44 263 bool possibly_throws = stmt_could_throw_p (call);
264 bool possibly_throws_externally = (possibly_throws
265 && stmt_can_throw_external (call));
f7d118a9 266
b5cebd44 267 if (possibly_throws)
268 {
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)))
273 {
274 if (possibly_throws && flag_non_call_exceptions)
275 {
276 if (dump_file)
277 fprintf (dump_file, " operand can throw; looping\n");
278 local->looping = true;
279 }
280 if (possibly_throws_externally)
281 {
282 if (dump_file)
283 fprintf (dump_file, " operand can throw externally\n");
284 local->can_throw = true;
285 }
286 }
287 }
f7d118a9 288
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.
293
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)
300 {
301 callee = cgraph_node(callee_t);
302 avail = cgraph_function_body_availability (callee);
303
304 /* When bad things happen to bad functions, they cannot be const
305 or pure. */
306 if (setjmp_call_p (callee_t))
9c2a0c05 307 {
b5cebd44 308 if (dump_file)
309 fprintf (dump_file, " setjmp is not const/pure\n");
310 local->looping = true;
9c2a0c05 311 local->pure_const_state = IPA_NEITHER;
9c2a0c05 312 }
f7d118a9 313
314 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
315 switch (DECL_FUNCTION_CODE (callee_t))
316 {
317 case BUILT_IN_LONGJMP:
318 case BUILT_IN_NONLOCAL_GOTO:
b5cebd44 319 if (dump_file)
320 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
f7d118a9 321 local->pure_const_state = IPA_NEITHER;
b5cebd44 322 local->looping = true;
f7d118a9 323 break;
324 default:
325 break;
326 }
327 }
328
b5cebd44 329 /* When not in IPA mode, we can still handle self recursion. */
330 if (!ipa && callee_t == current_function_decl)
331 local->looping = true;
f7d118a9 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. */
b5cebd44 337 else if (avail <= AVAIL_OVERWRITABLE || !ipa)
f7d118a9 338 {
b5cebd44 339 if (possibly_throws && flag_non_call_exceptions)
340 {
341 if (dump_file)
342 fprintf (dump_file, " can throw; looping\n");
343 local->looping = true;
344 }
345 if (possibly_throws_externally)
346 {
347 if (dump_file)
348 {
e38def9c 349 fprintf (dump_file, " can throw externally to lp %i\n",
350 lookup_stmt_eh_lp (call));
b5cebd44 351 if (callee_t)
352 fprintf (dump_file, " callee:%s\n",
353 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
354 }
355 local->can_throw = true;
356 }
357 if (flags & ECF_CONST)
f7d118a9 358 {
b5cebd44 359 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
360 local->looping = true;
361 }
362 else if (flags & ECF_PURE)
363 {
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");
f7d118a9 368 if (local->pure_const_state == IPA_CONST)
369 local->pure_const_state = IPA_PURE;
370 }
371 else
f7d118a9 372 {
b5cebd44 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;
f7d118a9 377 }
378 }
b5cebd44 379 /* Direct functions calls are handled by IPA propagation. */
f7d118a9 380}
381
5ed0b345 382/* Wrapper around check_decl for loads. */
383
384static bool
385check_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
386{
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;
392}
393
394/* Wrapper around check_decl for stores. */
395
396static bool
397check_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
398{
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;
404}
405
dd277d48 406/* Look into pointer pointed to by GSIP and figure out what interesting side
407 effects it has. */
b5cebd44 408static void
409check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
f7d118a9 410{
b5cebd44 411 gimple stmt = gsi_stmt (*gsip);
412 unsigned int i = 0;
f7d118a9 413
9845d120 414 if (is_gimple_debug (stmt))
415 return;
416
b5cebd44 417 if (dump_file)
f7d118a9 418 {
b5cebd44 419 fprintf (dump_file, " scanning: ");
420 print_gimple_stmt (dump_file, stmt, 0, 0);
421 }
dd277d48 422
5ed0b345 423 /* Look for loads and stores. */
424 walk_stmt_load_store_ops (stmt, local, check_load, check_store);
b5cebd44 425
426 if (gimple_code (stmt) != GIMPLE_CALL
427 && stmt_could_throw_p (stmt))
428 {
429 if (flag_non_call_exceptions)
430 {
431 if (dump_file)
432 fprintf (dump_file, " can throw; looping");
433 local->looping = true;
434 }
435 if (stmt_can_throw_external (stmt))
436 {
437 if (dump_file)
438 fprintf (dump_file, " can throw externally");
439 local->can_throw = true;
440 }
75a70cf9 441 }
75a70cf9 442 switch (gimple_code (stmt))
443 {
b5cebd44 444 case GIMPLE_CALL:
b5cebd44 445 check_call (local, stmt, ipa);
f7d118a9 446 break;
75a70cf9 447 case GIMPLE_LABEL:
448 if (DECL_NONLOCAL (gimple_label_label (stmt)))
f7d118a9 449 /* Target of long jump. */
9c2a0c05 450 {
b5cebd44 451 if (dump_file)
452 fprintf (dump_file, " nonlocal label is not const/pure");
9c2a0c05 453 local->pure_const_state = IPA_NEITHER;
9c2a0c05 454 }
f7d118a9 455 break;
75a70cf9 456 case GIMPLE_ASM:
b5cebd44 457 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
458 {
459 tree op = gimple_asm_clobber_op (stmt, i);
460 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
461 {
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;
466 }
467 }
468 if (gimple_asm_volatile_p (stmt))
469 {
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;
475 }
476 return;
f7d118a9 477 default:
478 break;
479 }
f7d118a9 480}
481
cb886925 482
f7d118a9 483/* This is the main routine for finding the reference patterns for
484 global variables within a function FN. */
485
b5cebd44 486static funct_state
487analyze_function (struct cgraph_node *fn, bool ipa)
f7d118a9 488{
f7d118a9 489 tree decl = fn->decl;
b5cebd44 490 tree old_decl = current_function_decl;
491 funct_state l;
492 basic_block this_block;
f7d118a9 493
b5cebd44 494 if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
f7d118a9 495 {
b5cebd44 496 if (dump_file)
497 fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n");
498 return NULL;
f7d118a9 499 }
500
b5cebd44 501 l = XCNEW (struct funct_state_d);
502 l->pure_const_state = IPA_CONST;
df9b545b 503 l->state_previously_known = IPA_NEITHER;
504 l->looping_previously_known = true;
b5cebd44 505 l->looping = false;
506 l->can_throw = false;
f7d118a9 507
508 if (dump_file)
509 {
b5cebd44 510 fprintf (dump_file, "\n\n local analysis of %s\n ",
511 cgraph_node_name (fn));
f7d118a9 512 }
513
b5cebd44 514 push_cfun (DECL_STRUCT_FUNCTION (decl));
515 current_function_decl = decl;
516
517 FOR_EACH_BB (this_block)
f7d118a9 518 {
b5cebd44 519 gimple_stmt_iterator gsi;
520 struct walk_stmt_info wi;
f7d118a9 521
b5cebd44 522 memset (&wi, 0, sizeof(wi));
523 for (gsi = gsi_start_bb (this_block);
524 !gsi_end_p (gsi);
525 gsi_next (&gsi))
f7d118a9 526 {
b5cebd44 527 check_stmt (&gsi, l, ipa);
528 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
529 goto end;
f7d118a9 530 }
531 }
dcccac3e 532
533end:
b5cebd44 534 if (l->pure_const_state != IPA_NEITHER)
535 {
536 /* Const functions cannot have back edges (an
537 indication of possible infinite loop side
538 effect. */
539 if (mark_dfs_back_edges ())
c9263b6a 540 {
b1887855 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);
c9263b6a 546 if (dump_file && (dump_flags & TDF_DETAILS))
547 flow_loops_dump (dump_file, NULL, 0);
548 if (mark_irreducible_loops ())
549 {
550 if (dump_file)
551 fprintf (dump_file, " has irreducible loops\n");
552 l->looping = true;
553 }
554 else
555 {
556 loop_iterator li;
557 struct loop *loop;
558 scev_initialize ();
559 FOR_EACH_LOOP (li, loop, 0)
560 if (!finite_loop_p (loop))
561 {
562 if (dump_file)
563 fprintf (dump_file, " can not prove finiteness of loop %i\n", loop->num);
564 l->looping =true;
565 break;
566 }
567 scev_finalize ();
568 }
569 loop_optimizer_finalize ();
570 }
b5cebd44 571 }
572
573 if (TREE_READONLY (decl))
574 {
575 l->pure_const_state = IPA_CONST;
df9b545b 576 l->state_previously_known = IPA_CONST;
b5cebd44 577 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
df9b545b 578 l->looping = false, l->looping_previously_known = false;
b5cebd44 579 }
580 if (DECL_PURE_P (decl))
581 {
582 if (l->pure_const_state != IPA_CONST)
583 l->pure_const_state = IPA_PURE;
df9b545b 584 l->state_previously_known = IPA_PURE;
b5cebd44 585 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
df9b545b 586 l->looping = false, l->looping_previously_known = false;
b5cebd44 587 }
588 if (TREE_NOTHROW (decl))
589 l->can_throw = false;
590
591 pop_cfun ();
592 current_function_decl = old_decl;
dcccac3e 593 if (dump_file)
594 {
b5cebd44 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");
dcccac3e 603 }
b5cebd44 604 return l;
f7d118a9 605}
606
50828ed8 607/* Called when new function is inserted to callgraph late. */
608static void
609add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
610{
86844d6c 611 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
612 return;
50828ed8 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 ();
b5cebd44 618 set_function_state (node, analyze_function (node, true));
50828ed8 619 pointer_set_destroy (visited_nodes);
620 visited_nodes = NULL;
621}
622
86844d6c 623/* Called when new clone is inserted to callgraph late. */
624
625static void
626duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
627 void *data ATTRIBUTE_UNUSED)
628{
629 if (get_function_state (src))
630 {
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);
635 }
636}
637
638/* Called when new clone is inserted to callgraph late. */
639
640static void
641remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
642{
643 if (get_function_state (node))
644 {
645 free (get_function_state (node));
646 set_function_state (node, NULL);
647 }
648}
649
f7d118a9 650\f
cb886925 651/* Analyze each function in the cgraph to see if it is locally PURE or
652 CONST. */
f7d118a9 653
cb886925 654static void
655generate_summary (void)
f7d118a9 656{
657 struct cgraph_node *node;
f7d118a9 658
86844d6c 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);
50828ed8 663 function_insertion_hook_holder =
664 cgraph_add_function_insertion_hook (&add_new_function, NULL);
f7d118a9 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 ();
670
671 /* Process all of the functions.
672
86844d6c 673 We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
f7d118a9 674 guarantee that what we learn about the one we see will be true
f0b5f617 675 for the one that overrides it.
f7d118a9 676 */
677 for (node = cgraph_nodes; node; node = node->next)
86844d6c 678 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
b5cebd44 679 set_function_state (node, analyze_function (node, true));
f7d118a9 680
681 pointer_set_destroy (visited_nodes);
682 visited_nodes = NULL;
cb886925 683}
684
17b28e52 685static bool
686ignore_edge (struct cgraph_edge *e)
687{
688 return (!e->can_throw_external);
689}
690
cb886925 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. */
695
696static unsigned int
697propagate (void)
698{
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;
706
50828ed8 707 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
86844d6c 708 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
709 cgraph_remove_node_removal_hook (node_removal_hook_holder);
17b28e52 710 order_pos = ipa_utils_reduced_inorder (order, true, false, NULL);
f7d118a9 711 if (dump_file)
712 {
713 dump_cgraph (dump_file);
714 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
715 }
716
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++ )
722 {
723 enum pure_const_state_e pure_const_state = IPA_CONST;
9c2a0c05 724 bool looping = false;
54157bf1 725 int count = 0;
f7d118a9 726 node = order[i];
727
728 /* Find the worst state for any node in the cycle. */
729 w = node;
730 while (w)
731 {
b5cebd44 732 struct cgraph_edge *e;
f7d118a9 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;
736
9c2a0c05 737 if (w_l->looping)
738 looping = true;
739
17b28e52 740 if (pure_const_state == IPA_NEITHER)
f7d118a9 741 break;
742
b5cebd44 743 count++;
744
745 if (count > 1)
746 looping = true;
747
748 for (e = w->callees; e; e = e->next_callee)
f7d118a9 749 {
b5cebd44 750 struct cgraph_node *y = e->callee;
54157bf1 751
b5cebd44 752 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
f7d118a9 753 {
b5cebd44 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;
17b28e52 757 if (pure_const_state == IPA_NEITHER)
b5cebd44 758 break;
759 if (y_l->looping)
760 looping = true;
f7d118a9 761 }
762 }
cda6870f 763 w_info = (struct ipa_dfs_info *) w->aux;
f7d118a9 764 w = w_info->next_cycle;
765 }
766
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)
771 {
772 funct_state w_l = get_function_state (w);
b5cebd44 773 enum pure_const_state_e this_state = pure_const_state;
774 bool this_looping = looping;
f7d118a9 775
df9b545b 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;
cb886925 781
b5cebd44 782 /* All nodes within a cycle share the same info. */
783 w_l->pure_const_state = this_state;
784 w_l->looping = this_looping;
785
786 switch (this_state)
787 {
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;
796
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;
805
806 default:
807 break;
808 }
17b28e52 809 w_info = (struct ipa_dfs_info *) w->aux;
810 w = w_info->next_cycle;
811 }
812 }
813
814 /* Cleanup. */
815 for (node = cgraph_nodes; node; node = node->next)
816 {
817 /* Get rid of the aux information. */
818 if (node->aux)
819 {
820 w_info = (struct ipa_dfs_info *) node->aux;
821 free (node->aux);
822 node->aux = NULL;
823 }
824 }
825 order_pos = ipa_utils_reduced_inorder (order, true, false, ignore_edge);
826 if (dump_file)
827 {
828 dump_cgraph (dump_file);
829 ipa_utils_print_order(dump_file, "reduced for nothrow", order, order_pos);
830 }
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++ )
836 {
837 bool can_throw = false;
838 node = order[i];
839
840 /* Find the worst state for any node in the cycle. */
841 w = node;
842 while (w)
843 {
844 struct cgraph_edge *e;
845 funct_state w_l = get_function_state (w);
846
847 if (w_l->can_throw)
848 can_throw = true;
849
850 if (can_throw)
851 break;
852
853 for (e = w->callees; e; e = e->next_callee)
854 {
855 struct cgraph_node *y = e->callee;
856
857 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
858 {
859 funct_state y_l = get_function_state (y);
860
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;
866 }
867 }
868 w_info = (struct ipa_dfs_info *) w->aux;
869 w = w_info->next_cycle;
870 }
871
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)
876 {
ecfab407 877 funct_state w_l = get_function_state (w);
b5cebd44 878 if (!can_throw && !TREE_NOTHROW (w->decl))
879 {
17b28e52 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;
b5cebd44 884 if (dump_file)
885 fprintf (dump_file, "Function found to be nothrow: %s\n",
886 cgraph_node_name (w));
f7d118a9 887 }
ecfab407 888 else if (can_throw && !TREE_NOTHROW (w->decl))
889 w_l->can_throw = true;
cda6870f 890 w_info = (struct ipa_dfs_info *) w->aux;
f7d118a9 891 w = w_info->next_cycle;
892 }
893 }
894
895 /* Cleanup. */
896 for (node = cgraph_nodes; node; node = node->next)
cb886925 897 {
898 /* Get rid of the aux information. */
899 if (node->aux)
900 {
901 w_info = (struct ipa_dfs_info *) node->aux;
902 free (node->aux);
903 node->aux = NULL;
904 }
86844d6c 905 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
cb886925 906 free (get_function_state (node));
907 }
908
f7d118a9 909 free (order);
86844d6c 910 VEC_free (funct_state, heap, funct_state_vec);
cb886925 911 finish_state ();
2a1990e9 912 return 0;
f7d118a9 913}
914
915static bool
916gate_pure_const (void)
917{
86844d6c 918 return (flag_ipa_pure_const
f7d118a9 919 /* Don't bother doing anything if the program has errors. */
920 && !(errorcount || sorrycount));
921}
922
26dbec0a 923struct ipa_opt_pass_d pass_ipa_pure_const =
f7d118a9 924{
20099e35 925 {
cb886925 926 IPA_PASS,
d3d7bd46 927 "pure-const", /* name */
f7d118a9 928 gate_pure_const, /* gate */
cb886925 929 propagate, /* execute */
f7d118a9 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 */
20099e35 938 0 /* todo_flags_finish */
cb886925 939 },
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 */
f7d118a9 947};
b5cebd44 948
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. */
952
953static unsigned int
954local_pure_const (void)
955{
956 bool changed = false;
957 funct_state l;
958
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. */
961
962 if (function_called_by_processed_nodes_p ())
963 {
964 if (dump_file)
965 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
966 return 0;
967 }
968
969 l = analyze_function (cgraph_node (current_function_decl), false);
970 if (!l)
971 {
972 if (dump_file)
973 fprintf (dump_file, "Function has wrong visibility; ignoring\n");
974 return 0;
975 }
976
977 switch (l->pure_const_state)
978 {
979 case IPA_CONST:
980 if (!TREE_READONLY (current_function_decl))
981 {
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));
990 }
991 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
992 && !l->looping)
993 {
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));
1000 }
1001 break;
1002
1003 case IPA_PURE:
1004 if (!TREE_READONLY (current_function_decl))
1005 {
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));
1014 }
1015 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1016 && !l->looping)
1017 {
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));
1024 }
1025 break;
1026
1027 default:
1028 break;
1029 }
1030 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
1031 {
17b28e52 1032 struct cgraph_edge *e;
1033
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;
b5cebd44 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));
1043 }
1044 if (l)
1045 free (l);
1046 if (changed)
1047 return execute_fixup_cfg ();
1048 else
1049 return 0;
1050}
1051
1052struct gimple_opt_pass pass_local_pure_const =
1053{
1054 {
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 */
1068 }
1069};