]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-pure-const.c
* ipa-cp.c (ipcp_write_summary, ipcp_read_summary): New functions.
[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"
7bfefa9d 54#include "lto-streamer.h"
c9263b6a 55#include "cfgloop.h"
56#include "tree-scalar-evolution.h"
f7d118a9 57
58static struct pointer_set_t *visited_nodes;
59
60/* Lattice values for const and pure functions. Everything starts out
61 being const, then may drop to pure and then neither depending on
62 what is found. */
63enum pure_const_state_e
64{
65 IPA_CONST,
66 IPA_PURE,
67 IPA_NEITHER
68};
69
cb886925 70/* Holder for the const_state. There is one of these per function
71 decl. */
f7d118a9 72struct funct_state_d
73{
cb886925 74 /* See above. */
f7d118a9 75 enum pure_const_state_e pure_const_state;
b5cebd44 76 /* What user set here; we can be always sure about this. */
df9b545b 77 enum pure_const_state_e state_previously_known;
78 bool looping_previously_known;
cb886925 79
80 /* True if the function could possibly infinite loop. There are a
81 lot of ways that this could be determined. We are pretty
82 conservative here. While it is possible to cse pure and const
83 calls, it is not legal to have dce get rid of the call if there
84 is a possibility that the call could infinite loop since this is
85 a behavioral change. */
9c2a0c05 86 bool looping;
cb886925 87
b5cebd44 88 bool can_throw;
f7d118a9 89};
90
91typedef struct funct_state_d * funct_state;
92
cb886925 93/* The storage of the funct_state is abstracted because there is the
94 possibility that it may be desirable to move this to the cgraph
95 local info. */
96
97/* Array, indexed by cgraph node uid, of function states. */
98
86844d6c 99DEF_VEC_P (funct_state);
100DEF_VEC_ALLOC_P (funct_state, heap);
101static VEC (funct_state, heap) *funct_state_vec;
cb886925 102
50828ed8 103/* Holders of ipa cgraph hooks: */
104static struct cgraph_node_hook_list *function_insertion_hook_holder;
86844d6c 105static struct cgraph_2node_hook_list *node_duplication_hook_holder;
106static struct cgraph_node_hook_list *node_removal_hook_holder;
cb886925 107
108/* Init the function state. */
109
110static void
111finish_state (void)
112{
113 free (funct_state_vec);
114}
115
116
f7d118a9 117/* Return the function state from NODE. */
118
119static inline funct_state
120get_function_state (struct cgraph_node *node)
121{
86844d6c 122 if (!funct_state_vec
123 || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
124 return NULL;
125 return VEC_index (funct_state, funct_state_vec, node->uid);
cb886925 126}
127
128/* Set the function state S for NODE. */
129
130static inline void
131set_function_state (struct cgraph_node *node, funct_state s)
132{
86844d6c 133 if (!funct_state_vec
134 || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid)
135 VEC_safe_grow_cleared (funct_state, heap, funct_state_vec, node->uid + 1);
136 VEC_replace (funct_state, funct_state_vec, node->uid, s);
f7d118a9 137}
138
f0b5f617 139/* Check to see if the use (or definition when CHECKING_WRITE is true)
f7d118a9 140 variable T is legal in a function that is either pure or const. */
141
142static inline void
143check_decl (funct_state local,
144 tree t, bool checking_write)
145{
f7d118a9 146 /* Do not want to do anything with volatile except mark any
147 function that uses one to be not const or pure. */
148 if (TREE_THIS_VOLATILE (t))
149 {
150 local->pure_const_state = IPA_NEITHER;
b5cebd44 151 if (dump_file)
152 fprintf (dump_file, " Volatile operand is not const/pure");
f7d118a9 153 return;
154 }
155
156 /* Do not care about a local automatic that is not static. */
157 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
158 return;
159
b5cebd44 160 /* If the variable has the "used" attribute, treat it as if it had a
161 been touched by the devil. */
162 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
163 {
164 local->pure_const_state = IPA_NEITHER;
165 if (dump_file)
166 fprintf (dump_file, " Used static/global variable is not const/pure\n");
167 return;
168 }
169
f7d118a9 170 /* Since we have dealt with the locals and params cases above, if we
171 are CHECKING_WRITE, this cannot be a pure or constant
172 function. */
173 if (checking_write)
bc17fd99 174 {
175 local->pure_const_state = IPA_NEITHER;
b5cebd44 176 if (dump_file)
177 fprintf (dump_file, " static/global memory write is not const/pure\n");
bc17fd99 178 return;
179 }
f7d118a9 180
181 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
182 {
b5cebd44 183 /* Readonly reads are safe. */
184 if (TREE_READONLY (t) && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t)))
185 return; /* Read of a constant, do not change the function state. */
f7d118a9 186 else
187 {
b5cebd44 188 if (dump_file)
189 fprintf (dump_file, " global memory read is not const\n");
f7d118a9 190 /* Just a regular read. */
191 if (local->pure_const_state == IPA_CONST)
192 local->pure_const_state = IPA_PURE;
193 }
194 }
b5cebd44 195 else
196 {
197 /* Compilation level statics can be read if they are readonly
198 variables. */
199 if (TREE_READONLY (t))
200 return;
201
202 if (dump_file)
203 fprintf (dump_file, " static memory read is not const\n");
204 /* Just a regular read. */
205 if (local->pure_const_state == IPA_CONST)
206 local->pure_const_state = IPA_PURE;
207 }
f7d118a9 208}
209
f7d118a9 210
b5cebd44 211/* Check to see if the use (or definition when CHECKING_WRITE is true)
212 variable T is legal in a function that is either pure or const. */
f7d118a9 213
b5cebd44 214static inline void
5ed0b345 215check_op (funct_state local, tree t, bool checking_write)
f7d118a9 216{
3ae61172 217 t = get_base_address (t);
218 if (t && TREE_THIS_VOLATILE (t))
f7d118a9 219 {
5ed0b345 220 local->pure_const_state = IPA_NEITHER;
221 if (dump_file)
222 fprintf (dump_file, " Volatile indirect ref is not const/pure\n");
223 return;
224 }
3ae61172 225 else if (t
226 && INDIRECT_REF_P (t)
227 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
228 && !ptr_deref_may_alias_global_p (TREE_OPERAND (t, 0)))
229 {
230 if (dump_file)
231 fprintf (dump_file, " Indirect ref to local memory is OK\n");
232 return;
233 }
5ed0b345 234 else if (checking_write)
235 {
236 local->pure_const_state = IPA_NEITHER;
237 if (dump_file)
238 fprintf (dump_file, " Indirect ref write is not const/pure\n");
239 return;
240 }
241 else
242 {
243 if (dump_file)
244 fprintf (dump_file, " Indirect ref read is not const\n");
245 if (local->pure_const_state == IPA_CONST)
246 local->pure_const_state = IPA_PURE;
f7d118a9 247 }
248}
249
f7d118a9 250/* Check the parameters of a function call to CALL_EXPR to see if
251 there are any references in the parameters that are not allowed for
252 pure or const functions. Also check to see if this is either an
253 indirect call, a call outside the compilation unit, or has special
254 attributes that may also effect the purity. The CALL_EXPR node for
255 the entire call expression. */
256
257static void
b5cebd44 258check_call (funct_state local, gimple call, bool ipa)
f7d118a9 259{
75a70cf9 260 int flags = gimple_call_flags (call);
b5cebd44 261 tree callee_t = gimple_call_fndecl (call);
f7d118a9 262 struct cgraph_node* callee;
263 enum availability avail = AVAIL_NOT_AVAILABLE;
b5cebd44 264 bool possibly_throws = stmt_could_throw_p (call);
265 bool possibly_throws_externally = (possibly_throws
266 && stmt_can_throw_external (call));
f7d118a9 267
b5cebd44 268 if (possibly_throws)
269 {
270 unsigned int i;
271 for (i = 0; i < gimple_num_ops (call); i++)
272 if (gimple_op (call, i)
273 && tree_could_throw_p (gimple_op (call, i)))
274 {
275 if (possibly_throws && flag_non_call_exceptions)
276 {
277 if (dump_file)
278 fprintf (dump_file, " operand can throw; looping\n");
279 local->looping = true;
280 }
281 if (possibly_throws_externally)
282 {
283 if (dump_file)
284 fprintf (dump_file, " operand can throw externally\n");
285 local->can_throw = true;
286 }
287 }
288 }
f7d118a9 289
290 /* The const and pure flags are set by a variety of places in the
291 compiler (including here). If someone has already set the flags
292 for the callee, (such as for some of the builtins) we will use
293 them, otherwise we will compute our own information.
294
295 Const and pure functions have less clobber effects than other
296 functions so we process these first. Otherwise if it is a call
297 outside the compilation unit or an indirect call we punt. This
298 leaves local calls which will be processed by following the call
299 graph. */
300 if (callee_t)
301 {
302 callee = cgraph_node(callee_t);
303 avail = cgraph_function_body_availability (callee);
304
305 /* When bad things happen to bad functions, they cannot be const
306 or pure. */
307 if (setjmp_call_p (callee_t))
9c2a0c05 308 {
b5cebd44 309 if (dump_file)
310 fprintf (dump_file, " setjmp is not const/pure\n");
311 local->looping = true;
9c2a0c05 312 local->pure_const_state = IPA_NEITHER;
9c2a0c05 313 }
f7d118a9 314
315 if (DECL_BUILT_IN_CLASS (callee_t) == BUILT_IN_NORMAL)
316 switch (DECL_FUNCTION_CODE (callee_t))
317 {
318 case BUILT_IN_LONGJMP:
319 case BUILT_IN_NONLOCAL_GOTO:
b5cebd44 320 if (dump_file)
321 fprintf (dump_file, " longjmp and nonlocal goto is not const/pure\n");
f7d118a9 322 local->pure_const_state = IPA_NEITHER;
b5cebd44 323 local->looping = true;
f7d118a9 324 break;
325 default:
326 break;
327 }
328 }
329
b5cebd44 330 /* When not in IPA mode, we can still handle self recursion. */
331 if (!ipa && callee_t == current_function_decl)
332 local->looping = true;
f7d118a9 333 /* The callee is either unknown (indirect call) or there is just no
334 scannable code for it (external call) . We look to see if there
335 are any bits available for the callee (such as by declaration or
336 because it is builtin) and process solely on the basis of those
337 bits. */
b5cebd44 338 else if (avail <= AVAIL_OVERWRITABLE || !ipa)
f7d118a9 339 {
b5cebd44 340 if (possibly_throws && flag_non_call_exceptions)
341 {
342 if (dump_file)
343 fprintf (dump_file, " can throw; looping\n");
344 local->looping = true;
345 }
346 if (possibly_throws_externally)
347 {
348 if (dump_file)
349 {
e38def9c 350 fprintf (dump_file, " can throw externally to lp %i\n",
351 lookup_stmt_eh_lp (call));
b5cebd44 352 if (callee_t)
353 fprintf (dump_file, " callee:%s\n",
354 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
355 }
356 local->can_throw = true;
357 }
358 if (flags & ECF_CONST)
f7d118a9 359 {
b5cebd44 360 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
361 local->looping = true;
362 }
363 else if (flags & ECF_PURE)
364 {
365 if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t))
366 local->looping = true;
367 if (dump_file)
368 fprintf (dump_file, " pure function call in not const\n");
f7d118a9 369 if (local->pure_const_state == IPA_CONST)
370 local->pure_const_state = IPA_PURE;
371 }
372 else
f7d118a9 373 {
b5cebd44 374 if (dump_file)
375 fprintf (dump_file, " uknown function call is not const/pure\n");
376 local->pure_const_state = IPA_NEITHER;
377 local->looping = true;
f7d118a9 378 }
379 }
b5cebd44 380 /* Direct functions calls are handled by IPA propagation. */
f7d118a9 381}
382
5ed0b345 383/* Wrapper around check_decl for loads. */
384
385static bool
386check_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
387{
388 if (DECL_P (op))
389 check_decl ((funct_state)data, op, false);
390 else
391 check_op ((funct_state)data, op, false);
392 return false;
393}
394
395/* Wrapper around check_decl for stores. */
396
397static bool
398check_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
399{
400 if (DECL_P (op))
401 check_decl ((funct_state)data, op, true);
402 else
403 check_op ((funct_state)data, op, true);
404 return false;
405}
406
dd277d48 407/* Look into pointer pointed to by GSIP and figure out what interesting side
408 effects it has. */
b5cebd44 409static void
410check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
f7d118a9 411{
b5cebd44 412 gimple stmt = gsi_stmt (*gsip);
413 unsigned int i = 0;
f7d118a9 414
9845d120 415 if (is_gimple_debug (stmt))
416 return;
417
b5cebd44 418 if (dump_file)
f7d118a9 419 {
b5cebd44 420 fprintf (dump_file, " scanning: ");
421 print_gimple_stmt (dump_file, stmt, 0, 0);
422 }
dd277d48 423
5ed0b345 424 /* Look for loads and stores. */
425 walk_stmt_load_store_ops (stmt, local, check_load, check_store);
b5cebd44 426
427 if (gimple_code (stmt) != GIMPLE_CALL
428 && stmt_could_throw_p (stmt))
429 {
430 if (flag_non_call_exceptions)
431 {
432 if (dump_file)
433 fprintf (dump_file, " can throw; looping");
434 local->looping = true;
435 }
436 if (stmt_can_throw_external (stmt))
437 {
438 if (dump_file)
439 fprintf (dump_file, " can throw externally");
440 local->can_throw = true;
441 }
75a70cf9 442 }
75a70cf9 443 switch (gimple_code (stmt))
444 {
b5cebd44 445 case GIMPLE_CALL:
b5cebd44 446 check_call (local, stmt, ipa);
f7d118a9 447 break;
75a70cf9 448 case GIMPLE_LABEL:
449 if (DECL_NONLOCAL (gimple_label_label (stmt)))
f7d118a9 450 /* Target of long jump. */
9c2a0c05 451 {
b5cebd44 452 if (dump_file)
453 fprintf (dump_file, " nonlocal label is not const/pure");
9c2a0c05 454 local->pure_const_state = IPA_NEITHER;
9c2a0c05 455 }
f7d118a9 456 break;
75a70cf9 457 case GIMPLE_ASM:
b5cebd44 458 for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
459 {
460 tree op = gimple_asm_clobber_op (stmt, i);
461 if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
462 {
463 if (dump_file)
464 fprintf (dump_file, " memory asm clobber is not const/pure");
465 /* Abandon all hope, ye who enter here. */
466 local->pure_const_state = IPA_NEITHER;
467 }
468 }
469 if (gimple_asm_volatile_p (stmt))
470 {
471 if (dump_file)
472 fprintf (dump_file, " volatile is not const/pure");
473 /* Abandon all hope, ye who enter here. */
474 local->pure_const_state = IPA_NEITHER;
475 local->looping = true;
476 }
477 return;
f7d118a9 478 default:
479 break;
480 }
f7d118a9 481}
482
cb886925 483
f7d118a9 484/* This is the main routine for finding the reference patterns for
485 global variables within a function FN. */
486
b5cebd44 487static funct_state
488analyze_function (struct cgraph_node *fn, bool ipa)
f7d118a9 489{
f7d118a9 490 tree decl = fn->decl;
b5cebd44 491 tree old_decl = current_function_decl;
492 funct_state l;
493 basic_block this_block;
f7d118a9 494
b5cebd44 495 if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE)
f7d118a9 496 {
b5cebd44 497 if (dump_file)
498 fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n");
499 return NULL;
f7d118a9 500 }
501
b5cebd44 502 l = XCNEW (struct funct_state_d);
503 l->pure_const_state = IPA_CONST;
df9b545b 504 l->state_previously_known = IPA_NEITHER;
505 l->looping_previously_known = true;
b5cebd44 506 l->looping = false;
507 l->can_throw = false;
f7d118a9 508
509 if (dump_file)
510 {
b5cebd44 511 fprintf (dump_file, "\n\n local analysis of %s\n ",
512 cgraph_node_name (fn));
f7d118a9 513 }
514
b5cebd44 515 push_cfun (DECL_STRUCT_FUNCTION (decl));
516 current_function_decl = decl;
517
518 FOR_EACH_BB (this_block)
f7d118a9 519 {
b5cebd44 520 gimple_stmt_iterator gsi;
521 struct walk_stmt_info wi;
f7d118a9 522
b5cebd44 523 memset (&wi, 0, sizeof(wi));
524 for (gsi = gsi_start_bb (this_block);
525 !gsi_end_p (gsi);
526 gsi_next (&gsi))
f7d118a9 527 {
b5cebd44 528 check_stmt (&gsi, l, ipa);
529 if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
530 goto end;
f7d118a9 531 }
532 }
dcccac3e 533
534end:
b5cebd44 535 if (l->pure_const_state != IPA_NEITHER)
536 {
537 /* Const functions cannot have back edges (an
538 indication of possible infinite loop side
539 effect. */
540 if (mark_dfs_back_edges ())
c9263b6a 541 {
b1887855 542 /* Preheaders are needed for SCEV to work.
543 Simple lateches and recorded exits improve chances that loop will
544 proved to be finite in testcases such as in loop-15.c and loop-24.c */
545 loop_optimizer_init (LOOPS_NORMAL
546 | LOOPS_HAVE_RECORDED_EXITS);
c9263b6a 547 if (dump_file && (dump_flags & TDF_DETAILS))
548 flow_loops_dump (dump_file, NULL, 0);
549 if (mark_irreducible_loops ())
550 {
551 if (dump_file)
552 fprintf (dump_file, " has irreducible loops\n");
553 l->looping = true;
554 }
555 else
556 {
557 loop_iterator li;
558 struct loop *loop;
559 scev_initialize ();
560 FOR_EACH_LOOP (li, loop, 0)
561 if (!finite_loop_p (loop))
562 {
563 if (dump_file)
564 fprintf (dump_file, " can not prove finiteness of loop %i\n", loop->num);
565 l->looping =true;
566 break;
567 }
568 scev_finalize ();
569 }
570 loop_optimizer_finalize ();
571 }
b5cebd44 572 }
573
574 if (TREE_READONLY (decl))
575 {
576 l->pure_const_state = IPA_CONST;
df9b545b 577 l->state_previously_known = IPA_CONST;
b5cebd44 578 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
df9b545b 579 l->looping = false, l->looping_previously_known = false;
b5cebd44 580 }
581 if (DECL_PURE_P (decl))
582 {
583 if (l->pure_const_state != IPA_CONST)
584 l->pure_const_state = IPA_PURE;
df9b545b 585 l->state_previously_known = IPA_PURE;
b5cebd44 586 if (!DECL_LOOPING_CONST_OR_PURE_P (decl))
df9b545b 587 l->looping = false, l->looping_previously_known = false;
b5cebd44 588 }
589 if (TREE_NOTHROW (decl))
590 l->can_throw = false;
591
592 pop_cfun ();
593 current_function_decl = old_decl;
dcccac3e 594 if (dump_file)
595 {
b5cebd44 596 if (l->looping)
597 fprintf (dump_file, "Function is locally looping.\n");
598 if (l->can_throw)
599 fprintf (dump_file, "Function is locally throwing.\n");
600 if (l->pure_const_state == IPA_CONST)
601 fprintf (dump_file, "Function is locally const.\n");
602 if (l->pure_const_state == IPA_PURE)
603 fprintf (dump_file, "Function is locally pure.\n");
dcccac3e 604 }
b5cebd44 605 return l;
f7d118a9 606}
607
50828ed8 608/* Called when new function is inserted to callgraph late. */
609static void
610add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
611{
86844d6c 612 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
613 return;
50828ed8 614 /* There are some shared nodes, in particular the initializers on
615 static declarations. We do not need to scan them more than once
616 since all we would be interested in are the addressof
617 operations. */
618 visited_nodes = pointer_set_create ();
b5cebd44 619 set_function_state (node, analyze_function (node, true));
50828ed8 620 pointer_set_destroy (visited_nodes);
621 visited_nodes = NULL;
622}
623
86844d6c 624/* Called when new clone is inserted to callgraph late. */
625
626static void
627duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst,
628 void *data ATTRIBUTE_UNUSED)
629{
630 if (get_function_state (src))
631 {
632 funct_state l = XNEW (struct funct_state_d);
633 gcc_assert (!get_function_state (dst));
634 memcpy (l, get_function_state (src), sizeof (*l));
635 set_function_state (dst, l);
636 }
637}
638
639/* Called when new clone is inserted to callgraph late. */
640
641static void
642remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
643{
644 if (get_function_state (node))
645 {
646 free (get_function_state (node));
647 set_function_state (node, NULL);
648 }
649}
650
f7d118a9 651\f
7bfefa9d 652static void
653register_hooks (void)
f7d118a9 654{
7bfefa9d 655 static bool init_p = false;
656
657 if (init_p)
658 return;
659
660 init_p = true;
f7d118a9 661
86844d6c 662 node_removal_hook_holder =
663 cgraph_add_node_removal_hook (&remove_node_data, NULL);
664 node_duplication_hook_holder =
665 cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
50828ed8 666 function_insertion_hook_holder =
667 cgraph_add_function_insertion_hook (&add_new_function, NULL);
7bfefa9d 668}
669
670
671/* Analyze each function in the cgraph to see if it is locally PURE or
672 CONST. */
673
674static void
675generate_summary (void)
676{
677 struct cgraph_node *node;
678
679 register_hooks ();
680
f7d118a9 681 /* There are some shared nodes, in particular the initializers on
682 static declarations. We do not need to scan them more than once
683 since all we would be interested in are the addressof
684 operations. */
685 visited_nodes = pointer_set_create ();
686
687 /* Process all of the functions.
688
86844d6c 689 We do NOT process any AVAIL_OVERWRITABLE functions, we cannot
f7d118a9 690 guarantee that what we learn about the one we see will be true
f0b5f617 691 for the one that overrides it.
f7d118a9 692 */
693 for (node = cgraph_nodes; node; node = node->next)
86844d6c 694 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
b5cebd44 695 set_function_state (node, analyze_function (node, true));
f7d118a9 696
697 pointer_set_destroy (visited_nodes);
698 visited_nodes = NULL;
cb886925 699}
700
7bfefa9d 701
702/* Serialize the ipa info for lto. */
703
704static void
705pure_const_write_summary (cgraph_node_set set)
706{
707 struct cgraph_node *node;
708 struct lto_simple_output_block *ob
709 = lto_create_simple_output_block (LTO_section_ipa_pure_const);
710 unsigned int count = 0;
711 cgraph_node_set_iterator csi;
712
713 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
714 {
715 node = csi_node (csi);
716 if (node->analyzed && get_function_state (node) != NULL)
717 count++;
718 }
719
720 lto_output_uleb128_stream (ob->main_stream, count);
721
722 /* Process all of the functions. */
723 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
724 {
725 node = csi_node (csi);
726 if (node->analyzed && get_function_state (node) != NULL)
727 {
728 struct bitpack_d *bp;
729 funct_state fs;
730 int node_ref;
731 lto_cgraph_encoder_t encoder;
732
733 fs = get_function_state (node);
734
735 encoder = ob->decl_state->cgraph_node_encoder;
736 node_ref = lto_cgraph_encoder_encode (encoder, node);
737 lto_output_uleb128_stream (ob->main_stream, node_ref);
738
739 /* Note that flags will need to be read in the opposite
740 order as we are pushing the bitflags into FLAGS. */
741 bp = bitpack_create ();
742 bp_pack_value (bp, fs->pure_const_state, 2);
743 bp_pack_value (bp, fs->state_previously_known, 2);
744 bp_pack_value (bp, fs->looping_previously_known, 1);
745 bp_pack_value (bp, fs->looping, 1);
746 bp_pack_value (bp, fs->can_throw, 1);
747 lto_output_bitpack (ob->main_stream, bp);
748 bitpack_delete (bp);
749 }
750 }
751
752 lto_destroy_simple_output_block (ob);
753}
754
755
756/* Deserialize the ipa info for lto. */
757
758static void
759pure_const_read_summary (void)
760{
761 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
762 struct lto_file_decl_data *file_data;
763 unsigned int j = 0;
764
765 register_hooks ();
766 while ((file_data = file_data_vec[j++]))
767 {
768 const char *data;
769 size_t len;
770 struct lto_input_block *ib
771 = lto_create_simple_input_block (file_data,
772 LTO_section_ipa_pure_const,
773 &data, &len);
774 if (ib)
775 {
776 unsigned int i;
777 unsigned int count = lto_input_uleb128 (ib);
778
779 for (i = 0; i < count; i++)
780 {
781 unsigned int index;
782 struct cgraph_node *node;
783 struct bitpack_d *bp;
784 funct_state fs;
785 lto_cgraph_encoder_t encoder;
786
787 fs = XCNEW (struct funct_state_d);
788 index = lto_input_uleb128 (ib);
789 encoder = file_data->cgraph_node_encoder;
790 node = lto_cgraph_encoder_deref (encoder, index);
791 set_function_state (node, fs);
792
793 /* Note that the flags must be read in the opposite
794 order in which they were written (the bitflags were
795 pushed into FLAGS). */
796 bp = lto_input_bitpack (ib);
797 fs->pure_const_state
798 = (enum pure_const_state_e) bp_unpack_value (bp, 2);
799 fs->state_previously_known
800 = (enum pure_const_state_e) bp_unpack_value (bp, 2);
801 fs->looping_previously_known = bp_unpack_value (bp, 1);
802 fs->looping = bp_unpack_value (bp, 1);
803 fs->can_throw = bp_unpack_value (bp, 1);
804 bitpack_delete (bp);
805 }
806
807 lto_destroy_simple_input_block (file_data,
808 LTO_section_ipa_pure_const,
809 ib, data, len);
810 }
811 }
812}
813
814
17b28e52 815static bool
816ignore_edge (struct cgraph_edge *e)
817{
818 return (!e->can_throw_external);
819}
820
a1e88032 821/* Return true if NODE is self recursive function. */
822
823static bool
824self_recursive_p (struct cgraph_node *node)
825{
826 struct cgraph_edge *e;
827 for (e = node->callees; e; e = e->next_callee)
828 if (e->callee == node)
829 return true;
830 return false;
831}
832
cb886925 833/* Produce the global information by preforming a transitive closure
834 on the local information that was produced by generate_summary.
835 Note that there is no function_transform pass since this only
836 updates the function_decl. */
837
838static unsigned int
839propagate (void)
840{
841 struct cgraph_node *node;
842 struct cgraph_node *w;
843 struct cgraph_node **order =
844 XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
845 int order_pos;
846 int i;
847 struct ipa_dfs_info * w_info;
848
50828ed8 849 cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
86844d6c 850 cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
851 cgraph_remove_node_removal_hook (node_removal_hook_holder);
17b28e52 852 order_pos = ipa_utils_reduced_inorder (order, true, false, NULL);
f7d118a9 853 if (dump_file)
854 {
855 dump_cgraph (dump_file);
856 ipa_utils_print_order(dump_file, "reduced", order, order_pos);
857 }
858
859 /* Propagate the local information thru the call graph to produce
860 the global information. All the nodes within a cycle will have
861 the same info so we collapse cycles first. Then we can do the
862 propagation in one pass from the leaves to the roots. */
863 for (i = 0; i < order_pos; i++ )
864 {
865 enum pure_const_state_e pure_const_state = IPA_CONST;
9c2a0c05 866 bool looping = false;
54157bf1 867 int count = 0;
f7d118a9 868 node = order[i];
869
870 /* Find the worst state for any node in the cycle. */
871 w = node;
872 while (w)
873 {
b5cebd44 874 struct cgraph_edge *e;
f7d118a9 875 funct_state w_l = get_function_state (w);
876 if (pure_const_state < w_l->pure_const_state)
877 pure_const_state = w_l->pure_const_state;
878
9c2a0c05 879 if (w_l->looping)
880 looping = true;
881
17b28e52 882 if (pure_const_state == IPA_NEITHER)
f7d118a9 883 break;
884
b5cebd44 885 count++;
886
887 if (count > 1)
888 looping = true;
889
890 for (e = w->callees; e; e = e->next_callee)
f7d118a9 891 {
b5cebd44 892 struct cgraph_node *y = e->callee;
54157bf1 893
b5cebd44 894 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
f7d118a9 895 {
b5cebd44 896 funct_state y_l = get_function_state (y);
897 if (pure_const_state < y_l->pure_const_state)
898 pure_const_state = y_l->pure_const_state;
17b28e52 899 if (pure_const_state == IPA_NEITHER)
b5cebd44 900 break;
901 if (y_l->looping)
902 looping = true;
f7d118a9 903 }
904 }
cda6870f 905 w_info = (struct ipa_dfs_info *) w->aux;
f7d118a9 906 w = w_info->next_cycle;
907 }
908
909 /* Copy back the region's pure_const_state which is shared by
910 all nodes in the region. */
911 w = node;
912 while (w)
913 {
914 funct_state w_l = get_function_state (w);
b5cebd44 915 enum pure_const_state_e this_state = pure_const_state;
916 bool this_looping = looping;
f7d118a9 917
df9b545b 918 if (w_l->state_previously_known != IPA_NEITHER
919 && this_state > w_l->state_previously_known)
920 this_state = w_l->state_previously_known;
a1e88032 921 if (!this_looping && self_recursive_p (w))
922 this_looping = true;
df9b545b 923 if (!w_l->looping_previously_known)
924 this_looping = false;
cb886925 925
b5cebd44 926 /* All nodes within a cycle share the same info. */
927 w_l->pure_const_state = this_state;
928 w_l->looping = this_looping;
929
930 switch (this_state)
931 {
932 case IPA_CONST:
933 if (!TREE_READONLY (w->decl) && dump_file)
934 fprintf (dump_file, "Function found to be %sconst: %s\n",
935 this_looping ? "looping " : "",
936 cgraph_node_name (w));
937 TREE_READONLY (w->decl) = 1;
938 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
939 break;
940
941 case IPA_PURE:
942 if (!DECL_PURE_P (w->decl) && dump_file)
943 fprintf (dump_file, "Function found to be %spure: %s\n",
944 this_looping ? "looping " : "",
945 cgraph_node_name (w));
946 DECL_PURE_P (w->decl) = 1;
947 DECL_LOOPING_CONST_OR_PURE_P (w->decl) = this_looping;
948 break;
949
950 default:
951 break;
952 }
17b28e52 953 w_info = (struct ipa_dfs_info *) w->aux;
954 w = w_info->next_cycle;
955 }
956 }
957
958 /* Cleanup. */
959 for (node = cgraph_nodes; node; node = node->next)
960 {
961 /* Get rid of the aux information. */
962 if (node->aux)
963 {
964 w_info = (struct ipa_dfs_info *) node->aux;
965 free (node->aux);
966 node->aux = NULL;
967 }
968 }
969 order_pos = ipa_utils_reduced_inorder (order, true, false, ignore_edge);
970 if (dump_file)
971 {
972 dump_cgraph (dump_file);
973 ipa_utils_print_order(dump_file, "reduced for nothrow", order, order_pos);
974 }
975 /* Propagate the local information thru the call graph to produce
976 the global information. All the nodes within a cycle will have
977 the same info so we collapse cycles first. Then we can do the
978 propagation in one pass from the leaves to the roots. */
979 for (i = 0; i < order_pos; i++ )
980 {
981 bool can_throw = false;
982 node = order[i];
983
984 /* Find the worst state for any node in the cycle. */
985 w = node;
986 while (w)
987 {
988 struct cgraph_edge *e;
989 funct_state w_l = get_function_state (w);
990
991 if (w_l->can_throw)
992 can_throw = true;
993
994 if (can_throw)
995 break;
996
997 for (e = w->callees; e; e = e->next_callee)
998 {
999 struct cgraph_node *y = e->callee;
1000
1001 if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE)
1002 {
1003 funct_state y_l = get_function_state (y);
1004
1005 if (can_throw)
1006 break;
1007 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
1008 && e->can_throw_external)
1009 can_throw = true;
1010 }
1011 }
1012 w_info = (struct ipa_dfs_info *) w->aux;
1013 w = w_info->next_cycle;
1014 }
1015
1016 /* Copy back the region's pure_const_state which is shared by
1017 all nodes in the region. */
1018 w = node;
1019 while (w)
1020 {
ecfab407 1021 funct_state w_l = get_function_state (w);
b5cebd44 1022 if (!can_throw && !TREE_NOTHROW (w->decl))
1023 {
17b28e52 1024 struct cgraph_edge *e;
1025 TREE_NOTHROW (w->decl) = true;
1026 for (e = w->callers; e; e = e->next_caller)
1027 e->can_throw_external = false;
b5cebd44 1028 if (dump_file)
1029 fprintf (dump_file, "Function found to be nothrow: %s\n",
1030 cgraph_node_name (w));
f7d118a9 1031 }
ecfab407 1032 else if (can_throw && !TREE_NOTHROW (w->decl))
1033 w_l->can_throw = true;
cda6870f 1034 w_info = (struct ipa_dfs_info *) w->aux;
f7d118a9 1035 w = w_info->next_cycle;
1036 }
1037 }
1038
1039 /* Cleanup. */
1040 for (node = cgraph_nodes; node; node = node->next)
cb886925 1041 {
1042 /* Get rid of the aux information. */
1043 if (node->aux)
1044 {
1045 w_info = (struct ipa_dfs_info *) node->aux;
1046 free (node->aux);
1047 node->aux = NULL;
1048 }
86844d6c 1049 if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE)
cb886925 1050 free (get_function_state (node));
1051 }
1052
f7d118a9 1053 free (order);
86844d6c 1054 VEC_free (funct_state, heap, funct_state_vec);
cb886925 1055 finish_state ();
2a1990e9 1056 return 0;
f7d118a9 1057}
1058
1059static bool
1060gate_pure_const (void)
1061{
86844d6c 1062 return (flag_ipa_pure_const
f7d118a9 1063 /* Don't bother doing anything if the program has errors. */
1064 && !(errorcount || sorrycount));
1065}
1066
26dbec0a 1067struct ipa_opt_pass_d pass_ipa_pure_const =
f7d118a9 1068{
20099e35 1069 {
cb886925 1070 IPA_PASS,
d3d7bd46 1071 "pure-const", /* name */
f7d118a9 1072 gate_pure_const, /* gate */
cb886925 1073 propagate, /* execute */
f7d118a9 1074 NULL, /* sub */
1075 NULL, /* next */
1076 0, /* static_pass_number */
1077 TV_IPA_PURE_CONST, /* tv_id */
1078 0, /* properties_required */
1079 0, /* properties_provided */
1080 0, /* properties_destroyed */
1081 0, /* todo_flags_start */
20099e35 1082 0 /* todo_flags_finish */
cb886925 1083 },
1084 generate_summary, /* generate_summary */
7bfefa9d 1085 pure_const_write_summary, /* write_summary */
1086 pure_const_read_summary, /* read_summary */
cb886925 1087 NULL, /* function_read_summary */
1088 0, /* TODOs */
1089 NULL, /* function_transform */
1090 NULL /* variable_transform */
f7d118a9 1091};
b5cebd44 1092
1093/* Simple local pass for pure const discovery reusing the analysis from
1094 ipa_pure_const. This pass is effective when executed together with
1095 other optimization passes in early optimization pass queue. */
1096
1097static unsigned int
1098local_pure_const (void)
1099{
1100 bool changed = false;
1101 funct_state l;
1102
1103 /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations
1104 we must not promote functions that are called by already processed functions. */
1105
1106 if (function_called_by_processed_nodes_p ())
1107 {
1108 if (dump_file)
1109 fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
1110 return 0;
1111 }
1112
1113 l = analyze_function (cgraph_node (current_function_decl), false);
1114 if (!l)
1115 {
1116 if (dump_file)
1117 fprintf (dump_file, "Function has wrong visibility; ignoring\n");
1118 return 0;
1119 }
1120
1121 switch (l->pure_const_state)
1122 {
1123 case IPA_CONST:
1124 if (!TREE_READONLY (current_function_decl))
1125 {
1126 TREE_READONLY (current_function_decl) = 1;
1127 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
1128 changed = true;
1129 if (dump_file)
1130 fprintf (dump_file, "Function found to be %sconst: %s\n",
1131 l->looping ? "looping " : "",
1132 lang_hooks.decl_printable_name (current_function_decl,
1133 2));
1134 }
1135 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1136 && !l->looping)
1137 {
1138 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
1139 changed = true;
1140 if (dump_file)
1141 fprintf (dump_file, "Function found to be non-looping: %s\n",
1142 lang_hooks.decl_printable_name (current_function_decl,
1143 2));
1144 }
1145 break;
1146
1147 case IPA_PURE:
1148 if (!TREE_READONLY (current_function_decl))
1149 {
1150 DECL_PURE_P (current_function_decl) = 1;
1151 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = l->looping;
1152 changed = true;
1153 if (dump_file)
1154 fprintf (dump_file, "Function found to be %spure: %s\n",
1155 l->looping ? "looping " : "",
1156 lang_hooks.decl_printable_name (current_function_decl,
1157 2));
1158 }
1159 else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
1160 && !l->looping)
1161 {
1162 DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) = false;
1163 changed = true;
1164 if (dump_file)
1165 fprintf (dump_file, "Function found to be non-looping: %s\n",
1166 lang_hooks.decl_printable_name (current_function_decl,
1167 2));
1168 }
1169 break;
1170
1171 default:
1172 break;
1173 }
1174 if (!l->can_throw && !TREE_NOTHROW (current_function_decl))
1175 {
17b28e52 1176 struct cgraph_edge *e;
1177
1178 TREE_NOTHROW (current_function_decl) = true;
1179 for (e = cgraph_node (current_function_decl)->callers;
1180 e; e = e->next_caller)
1181 e->can_throw_external = false;
b5cebd44 1182 changed = true;
1183 if (dump_file)
1184 fprintf (dump_file, "Function found to be nothrow: %s\n",
1185 lang_hooks.decl_printable_name (current_function_decl,
1186 2));
1187 }
1188 if (l)
1189 free (l);
1190 if (changed)
1191 return execute_fixup_cfg ();
1192 else
1193 return 0;
1194}
1195
1196struct gimple_opt_pass pass_local_pure_const =
1197{
1198 {
1199 GIMPLE_PASS,
1200 "local-pure-const", /* name */
1201 gate_pure_const, /* gate */
1202 local_pure_const, /* execute */
1203 NULL, /* sub */
1204 NULL, /* next */
1205 0, /* static_pass_number */
1206 TV_IPA_PURE_CONST, /* tv_id */
1207 0, /* properties_required */
1208 0, /* properties_provided */
1209 0, /* properties_destroyed */
1210 0, /* todo_flags_start */
1211 0 /* todo_flags_finish */
1212 }
1213};