]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/value-prof.c
This patch rewrites the old VEC macro-based interface into a new one
[thirdparty/gcc.git] / gcc / value-prof.c
CommitLineData
d81602c4 1/* Transformations based on profile information for values.
1cd188fc 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
ce084dfc 3 Free Software Foundation, Inc.
d81602c4 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
d81602c4 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/>. */
d81602c4 20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "rtl.h"
26#include "expr.h"
27#include "hard-reg-set.h"
28#include "basic-block.h"
29#include "value-prof.h"
d81602c4 30#include "flags.h"
31#include "insn-config.h"
32#include "recog.h"
33#include "optabs.h"
1c6a7b8c 34#include "regs.h"
8a5df2ce 35#include "ggc.h"
d2971487 36#include "tree-flow.h"
37#include "tree-flow-inline.h"
38#include "diagnostic.h"
ce084dfc 39#include "gimple-pretty-print.h"
b1b07349 40#include "coverage.h"
d2971487 41#include "tree.h"
42#include "gcov-io.h"
167b550b 43#include "cgraph.h"
77fce4cd 44#include "timevar.h"
b9ed1410 45#include "dumpfile.h"
4992f399 46#include "pointer-set.h"
1ad3e14c 47#include "profile.h"
d81602c4 48
8a5df2ce 49/* In this file value profile based optimizations are placed. Currently the
50 following optimizations are implemented (for more detailed descriptions
51 see comments at value_profile_transformations):
52
597ff315 53 1) Division/modulo specialization. Provided that we can determine that the
8a5df2ce 54 operands of the division have some special properties, we may use it to
55 produce more effective code.
d81602c4 56
3e7f455b 57 2) Indirect/virtual call specialization. If we can determine most
167b550b 58 common function callee in indirect/virtual call. We can use this
0d424440 59 information to improve code effectiveness (especially info for
3e7f455b 60 the inliner).
167b550b 61
3e7f455b 62 3) Speculative prefetching. If we are able to determine that the difference
63 between addresses accessed by a memory reference is usually constant, we
64 may add the prefetch instructions.
65 FIXME: This transformation was removed together with RTL based value
66 profiling.
d2971487 67
d81602c4 68
3e7f455b 69 Value profiling internals
70 ==========================
71
72 Every value profiling transformation starts with defining what values
73 to profile. There are different histogram types (see HIST_TYPE_* in
74 value-prof.h) and each transformation can request one or more histogram
75 types per GIMPLE statement. The function gimple_find_values_to_profile()
f1f41a6c 76 collects the values to profile in a vec, and adds the number of counters
3e7f455b 77 required for the different histogram types.
78
79 For a -fprofile-generate run, the statements for which values should be
80 recorded, are instrumented in instrument_values(). The instrumentation
81 is done by helper functions that can be found in tree-profile.c, where
82 new types of histograms can be added if necessary.
83
84 After a -fprofile-use, the value profiling data is read back in by
85 compute_value_histograms() that translates the collected data to
86 histograms and attaches them to the profiled statements via
87 gimple_add_histogram_value(). Histograms are stored in a hash table
88 that is attached to every intrumented function, see VALUE_HISTOGRAMS
89 in function.h.
90
91 The value-profile transformations driver is the function
92 gimple_value_profile_transformations(). It traverses all statements in
93 the to-be-transformed function, and looks for statements with one or
94 more histograms attached to it. If a statement has histograms, the
95 transformation functions are called on the statement.
96
97 Limitations / FIXME / TODO:
98 * Only one histogram of each type can be associated with a statement.
99 * Currently, HIST_TYPE_CONST_DELTA is not implemented.
100 (This type of histogram was originally used to implement a form of
101 stride profiling based speculative prefetching to improve SPEC2000
102 scores for memory-bound benchmarks, mcf and equake. However, this
103 was an RTL value-profiling transformation, and those have all been
104 removed.)
105 * Some value profile transformations are done in builtins.c (?!)
106 * Updating of histograms needs some TLC.
107 * The value profiling code could be used to record analysis results
108 from non-profiling (e.g. VRP).
109 * Adding new profilers should be simplified, starting with a cleanup
110 of what-happens-where andwith making gimple_find_values_to_profile
111 and gimple_value_profile_transformations table-driven, perhaps...
112*/
ed4294da 113
75a70cf9 114static tree gimple_divmod_fixed_value (gimple, tree, int, gcov_type, gcov_type);
115static tree gimple_mod_pow2 (gimple, int, gcov_type, gcov_type);
116static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type,
117 gcov_type);
118static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *);
119static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *);
120static bool gimple_mod_subtract_transform (gimple_stmt_iterator *);
121static bool gimple_stringops_transform (gimple_stmt_iterator *);
3e7f455b 122static bool gimple_ic_transform (gimple_stmt_iterator *);
d2971487 123
4992f399 124/* Allocate histogram value. */
125
126static histogram_value
127gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
75a70cf9 128 enum hist_type type, gimple stmt, tree value)
4992f399 129{
130 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
131 hist->hvalue.value = value;
132 hist->hvalue.stmt = stmt;
133 hist->type = type;
134 return hist;
135}
136
137/* Hash value for histogram. */
138
139static hashval_t
140histogram_hash (const void *x)
141{
c1fdef8e 142 return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt);
4992f399 143}
144
88c5a1d1 145/* Return nonzero if statement for histogram_value X is Y. */
4992f399 146
147static int
148histogram_eq (const void *x, const void *y)
149{
75a70cf9 150 return ((const_histogram_value) x)->hvalue.stmt == (const_gimple) y;
4992f399 151}
152
153/* Set histogram for STMT. */
154
155static void
75a70cf9 156set_histogram_value (struct function *fun, gimple stmt, histogram_value hist)
4992f399 157{
158 void **loc;
159 if (!hist && !VALUE_HISTOGRAMS (fun))
160 return;
161 if (!VALUE_HISTOGRAMS (fun))
162 VALUE_HISTOGRAMS (fun) = htab_create (1, histogram_hash,
163 histogram_eq, NULL);
164 loc = htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun), stmt,
165 htab_hash_pointer (stmt),
166 hist ? INSERT : NO_INSERT);
167 if (!hist)
168 {
169 if (loc)
170 htab_clear_slot (VALUE_HISTOGRAMS (fun), loc);
171 return;
172 }
173 *loc = hist;
174}
175
176/* Get histogram list for STMT. */
177
178histogram_value
75a70cf9 179gimple_histogram_value (struct function *fun, gimple stmt)
4992f399 180{
181 if (!VALUE_HISTOGRAMS (fun))
182 return NULL;
45ba1503 183 return (histogram_value) htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt,
184 htab_hash_pointer (stmt));
4992f399 185}
186
187/* Add histogram for STMT. */
188
189void
75a70cf9 190gimple_add_histogram_value (struct function *fun, gimple stmt,
191 histogram_value hist)
4992f399 192{
193 hist->hvalue.next = gimple_histogram_value (fun, stmt);
194 set_histogram_value (fun, stmt, hist);
195}
196
75a70cf9 197
4992f399 198/* Remove histogram HIST from STMT's histogram list. */
199
200void
75a70cf9 201gimple_remove_histogram_value (struct function *fun, gimple stmt,
202 histogram_value hist)
4992f399 203{
204 histogram_value hist2 = gimple_histogram_value (fun, stmt);
205 if (hist == hist2)
206 {
207 set_histogram_value (fun, stmt, hist->hvalue.next);
208 }
209 else
210 {
211 while (hist2->hvalue.next != hist)
212 hist2 = hist2->hvalue.next;
213 hist2->hvalue.next = hist->hvalue.next;
214 }
215 free (hist->hvalue.counters);
216#ifdef ENABLE_CHECKING
217 memset (hist, 0xab, sizeof (*hist));
218#endif
219 free (hist);
220}
221
75a70cf9 222
4992f399 223/* Lookup histogram of type TYPE in the STMT. */
224
225histogram_value
75a70cf9 226gimple_histogram_value_of_type (struct function *fun, gimple stmt,
227 enum hist_type type)
4992f399 228{
229 histogram_value hist;
75a70cf9 230 for (hist = gimple_histogram_value (fun, stmt); hist;
231 hist = hist->hvalue.next)
4992f399 232 if (hist->type == type)
233 return hist;
234 return NULL;
235}
236
237/* Dump information about HIST to DUMP_FILE. */
238
239static void
240dump_histogram_value (FILE *dump_file, histogram_value hist)
241{
242 switch (hist->type)
243 {
244 case HIST_TYPE_INTERVAL:
245 fprintf (dump_file, "Interval counter range %d -- %d",
246 hist->hdata.intvl.int_start,
247 (hist->hdata.intvl.int_start
248 + hist->hdata.intvl.steps - 1));
249 if (hist->hvalue.counters)
250 {
251 unsigned int i;
252 fprintf(dump_file, " [");
253 for (i = 0; i < hist->hdata.intvl.steps; i++)
254 fprintf (dump_file, " %d:"HOST_WIDEST_INT_PRINT_DEC,
255 hist->hdata.intvl.int_start + i,
256 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
257 fprintf (dump_file, " ] outside range:"HOST_WIDEST_INT_PRINT_DEC,
258 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
259 }
260 fprintf (dump_file, ".\n");
261 break;
262
263 case HIST_TYPE_POW2:
264 fprintf (dump_file, "Pow2 counter ");
265 if (hist->hvalue.counters)
266 {
267 fprintf (dump_file, "pow2:"HOST_WIDEST_INT_PRINT_DEC
268 " nonpow2:"HOST_WIDEST_INT_PRINT_DEC,
269 (HOST_WIDEST_INT) hist->hvalue.counters[0],
270 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
271 }
272 fprintf (dump_file, ".\n");
273 break;
274
275 case HIST_TYPE_SINGLE_VALUE:
276 fprintf (dump_file, "Single value ");
277 if (hist->hvalue.counters)
278 {
279 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
280 " match:"HOST_WIDEST_INT_PRINT_DEC
281 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
282 (HOST_WIDEST_INT) hist->hvalue.counters[0],
283 (HOST_WIDEST_INT) hist->hvalue.counters[1],
284 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
285 }
286 fprintf (dump_file, ".\n");
287 break;
288
162719b3 289 case HIST_TYPE_AVERAGE:
290 fprintf (dump_file, "Average value ");
291 if (hist->hvalue.counters)
292 {
293 fprintf (dump_file, "sum:"HOST_WIDEST_INT_PRINT_DEC
294 " times:"HOST_WIDEST_INT_PRINT_DEC,
295 (HOST_WIDEST_INT) hist->hvalue.counters[0],
296 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
297 }
298 fprintf (dump_file, ".\n");
299 break;
300
301 case HIST_TYPE_IOR:
302 fprintf (dump_file, "IOR value ");
303 if (hist->hvalue.counters)
304 {
305 fprintf (dump_file, "ior:"HOST_WIDEST_INT_PRINT_DEC,
306 (HOST_WIDEST_INT) hist->hvalue.counters[0]);
307 }
308 fprintf (dump_file, ".\n");
309 break;
310
4992f399 311 case HIST_TYPE_CONST_DELTA:
312 fprintf (dump_file, "Constant delta ");
313 if (hist->hvalue.counters)
314 {
315 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
316 " match:"HOST_WIDEST_INT_PRINT_DEC
317 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
318 (HOST_WIDEST_INT) hist->hvalue.counters[0],
319 (HOST_WIDEST_INT) hist->hvalue.counters[1],
320 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
321 }
322 fprintf (dump_file, ".\n");
323 break;
167b550b 324 case HIST_TYPE_INDIR_CALL:
325 fprintf (dump_file, "Indirect call ");
326 if (hist->hvalue.counters)
327 {
328 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
329 " match:"HOST_WIDEST_INT_PRINT_DEC
330 " all:"HOST_WIDEST_INT_PRINT_DEC,
331 (HOST_WIDEST_INT) hist->hvalue.counters[0],
332 (HOST_WIDEST_INT) hist->hvalue.counters[1],
333 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
334 }
335 fprintf (dump_file, ".\n");
336 break;
4992f399 337 }
338}
339
340/* Dump all histograms attached to STMT to DUMP_FILE. */
341
342void
75a70cf9 343dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple stmt)
4992f399 344{
345 histogram_value hist;
346 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
3e7f455b 347 dump_histogram_value (dump_file, hist);
4992f399 348}
349
350/* Remove all histograms associated with STMT. */
351
352void
75a70cf9 353gimple_remove_stmt_histograms (struct function *fun, gimple stmt)
4992f399 354{
355 histogram_value val;
356 while ((val = gimple_histogram_value (fun, stmt)) != NULL)
357 gimple_remove_histogram_value (fun, stmt, val);
358}
359
360/* Duplicate all histograms associates with OSTMT to STMT. */
361
362void
75a70cf9 363gimple_duplicate_stmt_histograms (struct function *fun, gimple stmt,
364 struct function *ofun, gimple ostmt)
4992f399 365{
366 histogram_value val;
367 for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
368 {
f4e36c33 369 histogram_value new_val = gimple_alloc_histogram_value (fun, val->type, NULL, NULL);
370 memcpy (new_val, val, sizeof (*val));
371 new_val->hvalue.stmt = stmt;
372 new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
373 memcpy (new_val->hvalue.counters, val->hvalue.counters, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
374 gimple_add_histogram_value (fun, stmt, new_val);
4992f399 375 }
376}
377
69eee21d 378
379/* Move all histograms associated with OSTMT to STMT. */
380
381void
75a70cf9 382gimple_move_stmt_histograms (struct function *fun, gimple stmt, gimple ostmt)
69eee21d 383{
384 histogram_value val = gimple_histogram_value (fun, ostmt);
385 if (val)
386 {
387 /* The following three statements can't be reordered,
388 because histogram hashtab relies on stmt field value
389 for finding the exact slot. */
390 set_histogram_value (fun, ostmt, NULL);
391 for (; val != NULL; val = val->hvalue.next)
392 val->hvalue.stmt = stmt;
393 set_histogram_value (fun, stmt, val);
394 }
395}
396
4992f399 397static bool error_found = false;
398
399/* Helper function for verify_histograms. For each histogram reachable via htab
400 walk verify that it was reached via statement walk. */
401
402static int
403visit_hist (void **slot, void *data)
404{
405 struct pointer_set_t *visited = (struct pointer_set_t *) data;
406 histogram_value hist = *(histogram_value *) slot;
407 if (!pointer_set_contains (visited, hist))
408 {
bf776685 409 error ("dead histogram");
4992f399 410 dump_histogram_value (stderr, hist);
75a70cf9 411 debug_gimple_stmt (hist->hvalue.stmt);
4992f399 412 error_found = true;
413 }
a63f3f1d 414 return 1;
4992f399 415}
416
75a70cf9 417
4992f399 418/* Verify sanity of the histograms. */
419
4b987fac 420DEBUG_FUNCTION void
4992f399 421verify_histograms (void)
422{
423 basic_block bb;
75a70cf9 424 gimple_stmt_iterator gsi;
4992f399 425 histogram_value hist;
426 struct pointer_set_t *visited_hists;
427
428 error_found = false;
429 visited_hists = pointer_set_create ();
430 FOR_EACH_BB (bb)
75a70cf9 431 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4992f399 432 {
75a70cf9 433 gimple stmt = gsi_stmt (gsi);
4992f399 434
75a70cf9 435 for (hist = gimple_histogram_value (cfun, stmt); hist;
436 hist = hist->hvalue.next)
4992f399 437 {
438 if (hist->hvalue.stmt != stmt)
439 {
75a70cf9 440 error ("Histogram value statement does not correspond to "
441 "the statement it is associated with");
442 debug_gimple_stmt (stmt);
4992f399 443 dump_histogram_value (stderr, hist);
444 error_found = true;
445 }
446 pointer_set_insert (visited_hists, hist);
447 }
448 }
449 if (VALUE_HISTOGRAMS (cfun))
450 htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, visited_hists);
451 pointer_set_destroy (visited_hists);
452 if (error_found)
453 internal_error ("verify_histograms failed");
454}
455
456/* Helper function for verify_histograms. For each histogram reachable via htab
457 walk verify that it was reached via statement walk. */
458
459static int
460free_hist (void **slot, void *data ATTRIBUTE_UNUSED)
461{
462 histogram_value hist = *(histogram_value *) slot;
463 free (hist->hvalue.counters);
464#ifdef ENABLE_CHECKING
465 memset (hist, 0xab, sizeof (*hist));
466#endif
467 free (hist);
a63f3f1d 468 return 1;
4992f399 469}
470
471void
472free_histograms (void)
473{
474 if (VALUE_HISTOGRAMS (cfun))
475 {
476 htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL);
477 htab_delete (VALUE_HISTOGRAMS (cfun));
478 VALUE_HISTOGRAMS (cfun) = NULL;
479 }
480}
481
75a70cf9 482
483/* The overall number of invocations of the counter should match
484 execution count of basic block. Report it as error rather than
485 internal error as it might mean that user has misused the profile
486 somehow. */
487
2ca9602a 488static bool
e0dc6f2b 489check_counter (gimple stmt, const char * name,
490 gcov_type *count, gcov_type *all, gcov_type bb_count)
2ca9602a 491{
e0dc6f2b 492 if (*all != bb_count || *count > *all)
2ca9602a 493 {
75a70cf9 494 location_t locus;
495 locus = (stmt != NULL)
e0dc6f2b 496 ? gimple_location (stmt)
497 : DECL_SOURCE_LOCATION (current_function_decl);
498 if (flag_profile_correction)
499 {
bf776685 500 inform (locus, "correcting inconsistent value profile: "
e0dc6f2b 501 "%s profiler overall count (%d) does not match BB count "
32fc3782 502 "(%d)", name, (int)*all, (int)bb_count);
e0dc6f2b 503 *all = bb_count;
504 if (*count > *all)
505 *count = *all;
506 return false;
507 }
508 else
509 {
bf776685 510 error_at (locus, "corrupted value profile: %s "
81c388fd 511 "profile counter (%d out of %d) inconsistent with "
512 "basic-block count (%d)",
513 name,
514 (int) *count,
515 (int) *all,
516 (int) bb_count);
e0dc6f2b 517 return true;
518 }
2ca9602a 519 }
75a70cf9 520
2ca9602a 521 return false;
522}
523
75a70cf9 524
525/* GIMPLE based transformations. */
526
fc49fbc1 527bool
75a70cf9 528gimple_value_profile_transformations (void)
d2971487 529{
530 basic_block bb;
75a70cf9 531 gimple_stmt_iterator gsi;
d2971487 532 bool changed = false;
533
534 FOR_EACH_BB (bb)
535 {
75a70cf9 536 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
d2971487 537 {
75a70cf9 538 gimple stmt = gsi_stmt (gsi);
4992f399 539 histogram_value th = gimple_histogram_value (cfun, stmt);
d2971487 540 if (!th)
541 continue;
542
543 if (dump_file)
544 {
4992f399 545 fprintf (dump_file, "Trying transformations on stmt ");
75a70cf9 546 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
4992f399 547 dump_histograms_for_stmt (cfun, dump_file, stmt);
d2971487 548 }
549
550 /* Transformations: */
551 /* The order of things in this conditional controls which
552 transformation is used when more than one is applicable. */
553 /* It is expected that any code added by the transformations
554 will be added before the current statement, and that the
555 current statement remain valid (although possibly
556 modified) upon return. */
3e7f455b 557 if (gimple_mod_subtract_transform (&gsi)
558 || gimple_divmod_fixed_value_transform (&gsi)
559 || gimple_mod_pow2_value_transform (&gsi)
560 || gimple_stringops_transform (&gsi)
561 || gimple_ic_transform (&gsi))
d2971487 562 {
75a70cf9 563 stmt = gsi_stmt (gsi);
d2971487 564 changed = true;
565 /* Original statement may no longer be in the same block. */
75a70cf9 566 if (bb != gimple_bb (stmt))
e3a1de9d 567 {
75a70cf9 568 bb = gimple_bb (stmt);
569 gsi = gsi_for_stmt (stmt);
e3a1de9d 570 }
d2971487 571 }
d2971487 572 }
573 }
574
575 if (changed)
576 {
577 counts_to_freqs ();
578 }
579
580 return changed;
581}
582
75a70cf9 583
584/* Generate code for transformation 1 (with parent gimple assignment
585 STMT and probability of taking the optimal path PROB, which is
586 equivalent to COUNT/ALL within roundoff error). This generates the
587 result into a temp and returns the temp; it does not replace or
588 alter the original STMT. */
589
d2971487 590static tree
75a70cf9 591gimple_divmod_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
592 gcov_type all)
d2971487 593{
0acacf9e 594 gimple stmt1, stmt2, stmt3;
03d37e4e 595 tree tmp0, tmp1, tmp2;
75a70cf9 596 gimple bb1end, bb2end, bb3end;
d2971487 597 basic_block bb, bb2, bb3, bb4;
75a70cf9 598 tree optype, op1, op2;
d2971487 599 edge e12, e13, e23, e24, e34;
75a70cf9 600 gimple_stmt_iterator gsi;
601
602 gcc_assert (is_gimple_assign (stmt)
603 && (gimple_assign_rhs_code (stmt) == TRUNC_DIV_EXPR
604 || gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR));
605
606 optype = TREE_TYPE (gimple_assign_lhs (stmt));
607 op1 = gimple_assign_rhs1 (stmt);
608 op2 = gimple_assign_rhs2 (stmt);
d2971487 609
75a70cf9 610 bb = gimple_bb (stmt);
611 gsi = gsi_for_stmt (stmt);
d2971487 612
03d37e4e 613 tmp0 = make_temp_ssa_name (optype, NULL, "PROF");
614 tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
85344eeb 615 stmt1 = gimple_build_assign (tmp0, fold_convert (optype, value));
75a70cf9 616 stmt2 = gimple_build_assign (tmp1, op2);
85344eeb 617 stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
75a70cf9 618 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
619 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
620 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
d2971487 621 bb1end = stmt3;
622
072f7ab1 623 tmp2 = create_tmp_reg (optype, "PROF");
75a70cf9 624 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
85344eeb 625 op1, tmp0);
75a70cf9 626 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 627 bb2end = stmt1;
628
75a70cf9 629 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
630 op1, op2);
75a70cf9 631 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 632 bb3end = stmt1;
633
d2971487 634 /* Fix CFG. */
635 /* Edge e23 connects bb2 to bb3, etc. */
636 e12 = split_block (bb, bb1end);
637 bb2 = e12->dest;
638 bb2->count = count;
639 e23 = split_block (bb2, bb2end);
640 bb3 = e23->dest;
641 bb3->count = all - count;
642 e34 = split_block (bb3, bb3end);
643 bb4 = e34->dest;
644 bb4->count = all;
645
646 e12->flags &= ~EDGE_FALLTHRU;
647 e12->flags |= EDGE_FALSE_VALUE;
648 e12->probability = prob;
649 e12->count = count;
650
651 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
652 e13->probability = REG_BR_PROB_BASE - prob;
653 e13->count = all - count;
654
655 remove_edge (e23);
48e1416a 656
d2971487 657 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
658 e24->probability = REG_BR_PROB_BASE;
659 e24->count = count;
660
661 e34->probability = REG_BR_PROB_BASE;
662 e34->count = all - count;
663
664 return tmp2;
665}
666
75a70cf9 667
d2971487 668/* Do transform 1) on INSN if applicable. */
75a70cf9 669
d2971487 670static bool
75a70cf9 671gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
d2971487 672{
d2971487 673 histogram_value histogram;
674 enum tree_code code;
675 gcov_type val, count, all;
75a70cf9 676 tree result, value, tree_val;
5b17b7ae 677 gcov_type prob;
75a70cf9 678 gimple stmt;
d2971487 679
75a70cf9 680 stmt = gsi_stmt (*si);
681 if (gimple_code (stmt) != GIMPLE_ASSIGN)
d2971487 682 return false;
75a70cf9 683
684 if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
d2971487 685 return false;
75a70cf9 686
687 code = gimple_assign_rhs_code (stmt);
48e1416a 688
d2971487 689 if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
690 return false;
691
75a70cf9 692 histogram = gimple_histogram_value_of_type (cfun, stmt,
693 HIST_TYPE_SINGLE_VALUE);
d2971487 694 if (!histogram)
695 return false;
696
ed4294da 697 value = histogram->hvalue.value;
698 val = histogram->hvalue.counters[0];
699 count = histogram->hvalue.counters[1];
700 all = histogram->hvalue.counters[2];
4992f399 701 gimple_remove_histogram_value (cfun, stmt, histogram);
d2971487 702
703 /* We require that count is at least half of all; this means
704 that for the transformation to fire the value must be constant
705 at least 50% of time (and 75% gives the guarantee of usage). */
75a70cf9 706 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
707 || 2 * count < all
0bfd8d5c 708 || optimize_bb_for_size_p (gimple_bb (stmt)))
d2971487 709 return false;
710
e0dc6f2b 711 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
2ca9602a 712 return false;
713
d2971487 714 /* Compute probability of taking the optimal path. */
5b17b7ae 715 if (all > 0)
716 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
717 else
718 prob = 0;
d2971487 719
8aa35772 720 tree_val = build_int_cst_wide (get_gcov_type (),
0346372d 721 (unsigned HOST_WIDE_INT) val,
722 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
75a70cf9 723 result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
d2971487 724
421e19dd 725 if (dump_file)
726 {
727 fprintf (dump_file, "Div/mod by constant ");
728 print_generic_expr (dump_file, value, TDF_SLIM);
729 fprintf (dump_file, "=");
730 print_generic_expr (dump_file, tree_val, TDF_SLIM);
731 fprintf (dump_file, " transformation on insn ");
75a70cf9 732 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
421e19dd 733 }
734
75a70cf9 735 gimple_assign_set_rhs_from_tree (si, result);
4b7a4b97 736 update_stmt (gsi_stmt (*si));
d2971487 737
738 return true;
739}
740
75a70cf9 741/* Generate code for transformation 2 (with parent gimple assign STMT and
742 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
48e1416a 743 within roundoff error). This generates the result into a temp and returns
d2971487 744 the temp; it does not replace or alter the original STMT. */
745static tree
75a70cf9 746gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
d2971487 747{
75a70cf9 748 gimple stmt1, stmt2, stmt3, stmt4;
03d37e4e 749 tree tmp2, tmp3;
75a70cf9 750 gimple bb1end, bb2end, bb3end;
d2971487 751 basic_block bb, bb2, bb3, bb4;
75a70cf9 752 tree optype, op1, op2;
d2971487 753 edge e12, e13, e23, e24, e34;
75a70cf9 754 gimple_stmt_iterator gsi;
755 tree result;
d2971487 756
75a70cf9 757 gcc_assert (is_gimple_assign (stmt)
758 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
d2971487 759
75a70cf9 760 optype = TREE_TYPE (gimple_assign_lhs (stmt));
761 op1 = gimple_assign_rhs1 (stmt);
762 op2 = gimple_assign_rhs2 (stmt);
763
764 bb = gimple_bb (stmt);
765 gsi = gsi_for_stmt (stmt);
766
072f7ab1 767 result = create_tmp_reg (optype, "PROF");
03d37e4e 768 tmp2 = make_temp_ssa_name (optype, NULL, "PROF");
769 tmp3 = make_temp_ssa_name (optype, NULL, "PROF");
75a70cf9 770 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
771 build_int_cst (optype, -1));
772 stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
773 stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
774 NULL_TREE, NULL_TREE);
775 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
776 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
777 gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
d2971487 778 bb1end = stmt4;
779
75a70cf9 780 /* tmp2 == op2-1 inherited from previous block. */
75a70cf9 781 stmt1 = gimple_build_assign_with_ops (BIT_AND_EXPR, result, op1, tmp2);
75a70cf9 782 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 783 bb2end = stmt1;
784
75a70cf9 785 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
786 op1, op2);
75a70cf9 787 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 788 bb3end = stmt1;
789
d2971487 790 /* Fix CFG. */
791 /* Edge e23 connects bb2 to bb3, etc. */
792 e12 = split_block (bb, bb1end);
793 bb2 = e12->dest;
794 bb2->count = count;
795 e23 = split_block (bb2, bb2end);
796 bb3 = e23->dest;
797 bb3->count = all - count;
798 e34 = split_block (bb3, bb3end);
799 bb4 = e34->dest;
800 bb4->count = all;
801
802 e12->flags &= ~EDGE_FALLTHRU;
803 e12->flags |= EDGE_FALSE_VALUE;
804 e12->probability = prob;
805 e12->count = count;
806
807 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
808 e13->probability = REG_BR_PROB_BASE - prob;
809 e13->count = all - count;
810
811 remove_edge (e23);
48e1416a 812
d2971487 813 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
814 e24->probability = REG_BR_PROB_BASE;
815 e24->count = count;
816
817 e34->probability = REG_BR_PROB_BASE;
818 e34->count = all - count;
819
820 return result;
821}
822
823/* Do transform 2) on INSN if applicable. */
824static bool
75a70cf9 825gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
d2971487 826{
d2971487 827 histogram_value histogram;
828 enum tree_code code;
829 gcov_type count, wrong_values, all;
75a70cf9 830 tree lhs_type, result, value;
5b17b7ae 831 gcov_type prob;
75a70cf9 832 gimple stmt;
d2971487 833
75a70cf9 834 stmt = gsi_stmt (*si);
835 if (gimple_code (stmt) != GIMPLE_ASSIGN)
d2971487 836 return false;
75a70cf9 837
838 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
839 if (!INTEGRAL_TYPE_P (lhs_type))
d2971487 840 return false;
75a70cf9 841
842 code = gimple_assign_rhs_code (stmt);
48e1416a 843
75a70cf9 844 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
d2971487 845 return false;
846
4992f399 847 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
d2971487 848 if (!histogram)
849 return false;
850
ed4294da 851 value = histogram->hvalue.value;
852 wrong_values = histogram->hvalue.counters[0];
853 count = histogram->hvalue.counters[1];
d2971487 854
4992f399 855 gimple_remove_histogram_value (cfun, stmt, histogram);
856
d2971487 857 /* We require that we hit a power of 2 at least half of all evaluations. */
75a70cf9 858 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
859 || count < wrong_values
0bfd8d5c 860 || optimize_bb_for_size_p (gimple_bb (stmt)))
d2971487 861 return false;
862
863 if (dump_file)
864 {
865 fprintf (dump_file, "Mod power of 2 transformation on insn ");
75a70cf9 866 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
d2971487 867 }
868
869 /* Compute probability of taking the optimal path. */
870 all = count + wrong_values;
4992f399 871
e0dc6f2b 872 if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count))
2ca9602a 873 return false;
874
5b17b7ae 875 if (all > 0)
876 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
877 else
878 prob = 0;
d2971487 879
75a70cf9 880 result = gimple_mod_pow2 (stmt, prob, count, all);
d2971487 881
75a70cf9 882 gimple_assign_set_rhs_from_tree (si, result);
4b7a4b97 883 update_stmt (gsi_stmt (*si));
d2971487 884
885 return true;
886}
887
75a70cf9 888/* Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
889 NCOUNTS the number of cases to support. Currently only NCOUNTS==0 or 1 is
890 supported and this is built into this interface. The probabilities of taking
891 the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
48e1416a 892 COUNT2/ALL respectively within roundoff error). This generates the
893 result into a temp and returns the temp; it does not replace or alter
d2971487 894 the original STMT. */
895/* FIXME: Generalize the interface to handle NCOUNTS > 1. */
896
897static tree
75a70cf9 898gimple_mod_subtract (gimple stmt, int prob1, int prob2, int ncounts,
899 gcov_type count1, gcov_type count2, gcov_type all)
d2971487 900{
75a70cf9 901 gimple stmt1, stmt2, stmt3;
d2971487 902 tree tmp1;
75a70cf9 903 gimple bb1end, bb2end = NULL, bb3end;
d2971487 904 basic_block bb, bb2, bb3, bb4;
75a70cf9 905 tree optype, op1, op2;
d2971487 906 edge e12, e23 = 0, e24, e34, e14;
75a70cf9 907 gimple_stmt_iterator gsi;
908 tree result;
909
910 gcc_assert (is_gimple_assign (stmt)
911 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
d2971487 912
75a70cf9 913 optype = TREE_TYPE (gimple_assign_lhs (stmt));
914 op1 = gimple_assign_rhs1 (stmt);
915 op2 = gimple_assign_rhs2 (stmt);
d2971487 916
75a70cf9 917 bb = gimple_bb (stmt);
918 gsi = gsi_for_stmt (stmt);
919
072f7ab1 920 result = create_tmp_reg (optype, "PROF");
03d37e4e 921 tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
75a70cf9 922 stmt1 = gimple_build_assign (result, op1);
923 stmt2 = gimple_build_assign (tmp1, op2);
924 stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
925 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
926 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
927 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
d2971487 928 bb1end = stmt3;
929
930 if (ncounts) /* Assumed to be 0 or 1 */
931 {
75a70cf9 932 stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1);
933 stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
75a70cf9 934 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
935 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
d2971487 936 bb2end = stmt2;
937 }
938
939 /* Fallback case. */
75a70cf9 940 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
941 result, tmp1);
75a70cf9 942 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 943 bb3end = stmt1;
944
d2971487 945 /* Fix CFG. */
946 /* Edge e23 connects bb2 to bb3, etc. */
947 /* However block 3 is optional; if it is not there, references
948 to 3 really refer to block 2. */
949 e12 = split_block (bb, bb1end);
950 bb2 = e12->dest;
951 bb2->count = all - count1;
48e1416a 952
d2971487 953 if (ncounts) /* Assumed to be 0 or 1. */
954 {
955 e23 = split_block (bb2, bb2end);
956 bb3 = e23->dest;
957 bb3->count = all - count1 - count2;
958 }
959
960 e34 = split_block (ncounts ? bb3 : bb2, bb3end);
961 bb4 = e34->dest;
962 bb4->count = all;
963
964 e12->flags &= ~EDGE_FALLTHRU;
965 e12->flags |= EDGE_FALSE_VALUE;
966 e12->probability = REG_BR_PROB_BASE - prob1;
421e19dd 967 e12->count = all - count1;
d2971487 968
969 e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
970 e14->probability = prob1;
421e19dd 971 e14->count = count1;
d2971487 972
973 if (ncounts) /* Assumed to be 0 or 1. */
974 {
975 e23->flags &= ~EDGE_FALLTHRU;
976 e23->flags |= EDGE_FALSE_VALUE;
977 e23->count = all - count1 - count2;
978 e23->probability = REG_BR_PROB_BASE - prob2;
979
980 e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE);
981 e24->probability = prob2;
982 e24->count = count2;
983 }
984
985 e34->probability = REG_BR_PROB_BASE;
986 e34->count = all - count1 - count2;
987
988 return result;
989}
990
75a70cf9 991
992/* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */
993
d2971487 994static bool
75a70cf9 995gimple_mod_subtract_transform (gimple_stmt_iterator *si)
d2971487 996{
d2971487 997 histogram_value histogram;
998 enum tree_code code;
999 gcov_type count, wrong_values, all;
f018d957 1000 tree lhs_type, result;
5b17b7ae 1001 gcov_type prob1, prob2;
4992f399 1002 unsigned int i, steps;
1003 gcov_type count1, count2;
75a70cf9 1004 gimple stmt;
d2971487 1005
75a70cf9 1006 stmt = gsi_stmt (*si);
1007 if (gimple_code (stmt) != GIMPLE_ASSIGN)
d2971487 1008 return false;
75a70cf9 1009
1010 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
1011 if (!INTEGRAL_TYPE_P (lhs_type))
d2971487 1012 return false;
75a70cf9 1013
1014 code = gimple_assign_rhs_code (stmt);
48e1416a 1015
75a70cf9 1016 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
d2971487 1017 return false;
1018
4992f399 1019 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
d2971487 1020 if (!histogram)
1021 return false;
1022
d2971487 1023 all = 0;
1024 wrong_values = 0;
1025 for (i = 0; i < histogram->hdata.intvl.steps; i++)
ed4294da 1026 all += histogram->hvalue.counters[i];
d2971487 1027
ed4294da 1028 wrong_values += histogram->hvalue.counters[i];
1029 wrong_values += histogram->hvalue.counters[i+1];
4992f399 1030 steps = histogram->hdata.intvl.steps;
d2971487 1031 all += wrong_values;
4992f399 1032 count1 = histogram->hvalue.counters[0];
1033 count2 = histogram->hvalue.counters[1];
d2971487 1034
2ca9602a 1035 /* Compute probability of taking the optimal path. */
e0dc6f2b 1036 if (check_counter (stmt, "interval", &count1, &all, gimple_bb (stmt)->count))
4992f399 1037 {
1038 gimple_remove_histogram_value (cfun, stmt, histogram);
1039 return false;
1040 }
2ca9602a 1041
e0dc6f2b 1042 if (flag_profile_correction && count1 + count2 > all)
1043 all = count1 + count2;
1044
1045 gcc_assert (count1 + count2 <= all);
1046
d2971487 1047 /* We require that we use just subtractions in at least 50% of all
1048 evaluations. */
1049 count = 0;
1050 for (i = 0; i < histogram->hdata.intvl.steps; i++)
1051 {
ed4294da 1052 count += histogram->hvalue.counters[i];
d2971487 1053 if (count * 2 >= all)
1054 break;
1055 }
4992f399 1056 if (i == steps
0bfd8d5c 1057 || optimize_bb_for_size_p (gimple_bb (stmt)))
d2971487 1058 return false;
1059
4992f399 1060 gimple_remove_histogram_value (cfun, stmt, histogram);
d2971487 1061 if (dump_file)
1062 {
1063 fprintf (dump_file, "Mod subtract transformation on insn ");
75a70cf9 1064 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
d2971487 1065 }
1066
1067 /* Compute probability of taking the optimal path(s). */
5b17b7ae 1068 if (all > 0)
1069 {
1070 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all;
1071 prob2 = (count2 * REG_BR_PROB_BASE + all / 2) / all;
1072 }
1073 else
1074 {
1075 prob1 = prob2 = 0;
1076 }
d2971487 1077
1078 /* In practice, "steps" is always 2. This interface reflects this,
1079 and will need to be changed if "steps" can change. */
75a70cf9 1080 result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all);
d2971487 1081
75a70cf9 1082 gimple_assign_set_rhs_from_tree (si, result);
4b7a4b97 1083 update_stmt (gsi_stmt (*si));
d2971487 1084
1085 return true;
1086}
ed4294da 1087
f1f41a6c 1088static vec<cgraph_node_ptr> cgraph_node_map
1089 = vec<cgraph_node_ptr>();
167b550b 1090
1ad3e14c 1091/* Initialize map from FUNCDEF_NO to CGRAPH_NODE. */
167b550b 1092
1ad3e14c 1093void
1094init_node_map (void)
167b550b 1095{
1096 struct cgraph_node *n;
1097
1ad3e14c 1098 if (get_last_funcdef_no ())
f1f41a6c 1099 cgraph_node_map.safe_grow_cleared (get_last_funcdef_no ());
167b550b 1100
7c455d87 1101 FOR_EACH_FUNCTION (n)
167b550b 1102 {
7d0d0ce1 1103 if (DECL_STRUCT_FUNCTION (n->symbol.decl))
f1f41a6c 1104 cgraph_node_map[DECL_STRUCT_FUNCTION (n->symbol.decl)->funcdef_no] = n;
167b550b 1105 }
1106}
1107
1ad3e14c 1108/* Delete the CGRAPH_NODE_MAP. */
1109
1110void
1111del_node_map (void)
1112{
f1f41a6c 1113 cgraph_node_map.release ();
1ad3e14c 1114}
1115
167b550b 1116/* Return cgraph node for function with pid */
1117
1118static inline struct cgraph_node*
1ad3e14c 1119find_func_by_funcdef_no (int func_id)
167b550b 1120{
1ad3e14c 1121 int max_id = get_last_funcdef_no ();
f1f41a6c 1122 if (func_id >= max_id || cgraph_node_map[func_id] == NULL)
1ad3e14c 1123 {
1124 if (flag_profile_correction)
1125 inform (DECL_SOURCE_LOCATION (current_function_decl),
1126 "Inconsistent profile: indirect call target (%d) does not exist", func_id);
1127 else
1128 error ("Inconsistent profile: indirect call target (%d) does not exist", func_id);
1129
1130 return NULL;
1131 }
167b550b 1132
f1f41a6c 1133 return cgraph_node_map[func_id];
167b550b 1134}
1135
850ff64c 1136/* Perform sanity check on the indirect call target. Due to race conditions,
1137 false function target may be attributed to an indirect call site. If the
1138 call expression type mismatches with the target function's type, expand_call
1139 may ICE. Here we only do very minimal sanity check just to make compiler happy.
1140 Returns true if TARGET is considered ok for call CALL_STMT. */
1141
1142static bool
1143check_ic_target (gimple call_stmt, struct cgraph_node *target)
1144{
1145 location_t locus;
7d0d0ce1 1146 if (gimple_check_call_matching_types (call_stmt, target->symbol.decl))
850ff64c 1147 return true;
1148
1149 locus = gimple_location (call_stmt);
1150 inform (locus, "Skipping target %s with mismatching types for icall ",
1151 cgraph_node_name (target));
1152 return false;
1153}
1154
167b550b 1155/* Do transformation
1156
f0b5f617 1157 if (actual_callee_address == address_of_most_common_function/method)
167b550b 1158 do direct call
1159 else
1160 old call
1161 */
1162
75a70cf9 1163static gimple
48e1416a 1164gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
75a70cf9 1165 int prob, gcov_type count, gcov_type all)
167b550b 1166{
e38def9c 1167 gimple dcall_stmt, load_stmt, cond_stmt;
03d37e4e 1168 tree tmp0, tmp1, tmp;
25ae05af 1169 basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL;
167b550b 1170 tree optype = build_pointer_type (void_type_node);
25ae05af 1171 edge e_cd, e_ci, e_di, e_dj = NULL, e_ij;
75a70cf9 1172 gimple_stmt_iterator gsi;
1cd188fc 1173 int lp_nr, dflags;
167b550b 1174
e38def9c 1175 cond_bb = gimple_bb (icall_stmt);
1176 gsi = gsi_for_stmt (icall_stmt);
167b550b 1177
03d37e4e 1178 tmp0 = make_temp_ssa_name (optype, NULL, "PROF");
1179 tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
e38def9c 1180 tmp = unshare_expr (gimple_call_fn (icall_stmt));
85344eeb 1181 load_stmt = gimple_build_assign (tmp0, tmp);
e38def9c 1182 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
75a70cf9 1183
7d0d0ce1 1184 tmp = fold_convert (optype, build_addr (direct_call->symbol.decl,
a0147880 1185 current_function_decl));
e38def9c 1186 load_stmt = gimple_build_assign (tmp1, tmp);
1187 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
167b550b 1188
85344eeb 1189 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
e38def9c 1190 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1191
85344eeb 1192 gimple_set_vdef (icall_stmt, NULL_TREE);
1193 gimple_set_vuse (icall_stmt, NULL_TREE);
1194 update_stmt (icall_stmt);
e38def9c 1195 dcall_stmt = gimple_copy (icall_stmt);
7d0d0ce1 1196 gimple_call_set_fndecl (dcall_stmt, direct_call->symbol.decl);
1197 dflags = flags_from_decl_or_type (direct_call->symbol.decl);
1cd188fc 1198 if ((dflags & ECF_NORETURN) != 0)
1199 gimple_call_set_lhs (dcall_stmt, NULL_TREE);
e38def9c 1200 gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
167b550b 1201
1202 /* Fix CFG. */
e38def9c 1203 /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */
1204 e_cd = split_block (cond_bb, cond_stmt);
1205 dcall_bb = e_cd->dest;
1206 dcall_bb->count = count;
167b550b 1207
e38def9c 1208 e_di = split_block (dcall_bb, dcall_stmt);
1209 icall_bb = e_di->dest;
1210 icall_bb->count = all - count;
167b550b 1211
955700fa 1212 /* Do not disturb existing EH edges from the indirect call. */
33fb6a59 1213 if (!stmt_ends_bb_p (icall_stmt))
955700fa 1214 e_ij = split_block (icall_bb, icall_stmt);
1215 else
8881852c 1216 {
1217 e_ij = find_fallthru_edge (icall_bb->succs);
25ae05af 1218 /* The indirect call might be noreturn. */
1219 if (e_ij != NULL)
1220 {
1221 e_ij->probability = REG_BR_PROB_BASE;
1222 e_ij->count = all - count;
1223 e_ij = single_pred_edge (split_edge (e_ij));
1224 }
1225 }
1226 if (e_ij != NULL)
1227 {
1228 join_bb = e_ij->dest;
1229 join_bb->count = all;
8881852c 1230 }
167b550b 1231
e38def9c 1232 e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1233 e_cd->probability = prob;
1234 e_cd->count = count;
1235
1236 e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE);
1237 e_ci->probability = REG_BR_PROB_BASE - prob;
1238 e_ci->count = all - count;
1239
1240 remove_edge (e_di);
48e1416a 1241
25ae05af 1242 if (e_ij != NULL)
1243 {
1cd188fc 1244 if ((dflags & ECF_NORETURN) != 0)
1245 e_ij->count = all;
1246 else
1247 {
1248 e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
1249 e_dj->probability = REG_BR_PROB_BASE;
1250 e_dj->count = count;
e38def9c 1251
1cd188fc 1252 e_ij->count = all - count;
1253 }
25ae05af 1254 e_ij->probability = REG_BR_PROB_BASE;
25ae05af 1255 }
167b550b 1256
85344eeb 1257 /* Insert PHI node for the call result if necessary. */
1258 if (gimple_call_lhs (icall_stmt)
1cd188fc 1259 && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME
1260 && (dflags & ECF_NORETURN) == 0)
85344eeb 1261 {
1262 tree result = gimple_call_lhs (icall_stmt);
1263 gimple phi = create_phi_node (result, join_bb);
85344eeb 1264 gimple_call_set_lhs (icall_stmt,
7ecda5e8 1265 duplicate_ssa_name (result, icall_stmt));
60d535d2 1266 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
85344eeb 1267 gimple_call_set_lhs (dcall_stmt,
7ecda5e8 1268 duplicate_ssa_name (result, dcall_stmt));
60d535d2 1269 add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
85344eeb 1270 }
1271
955700fa 1272 /* Build an EH edge for the direct call if necessary. */
e38def9c 1273 lp_nr = lookup_stmt_eh_lp (icall_stmt);
955700fa 1274 if (lp_nr != 0
1275 && stmt_could_throw_p (dcall_stmt))
167b550b 1276 {
955700fa 1277 edge e_eh, e;
1278 edge_iterator ei;
1279 gimple_stmt_iterator psi;
1280
1281 add_stmt_to_eh_lp (dcall_stmt, lp_nr);
1282 FOR_EACH_EDGE (e_eh, ei, icall_bb->succs)
1283 if (e_eh->flags & EDGE_EH)
1284 break;
1285 e = make_edge (dcall_bb, e_eh->dest, EDGE_EH);
1286 for (psi = gsi_start_phis (e_eh->dest);
1287 !gsi_end_p (psi); gsi_next (&psi))
e38def9c 1288 {
955700fa 1289 gimple phi = gsi_stmt (psi);
1290 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
1291 PHI_ARG_DEF_FROM_EDGE (phi, e_eh));
e38def9c 1292 }
167b550b 1293 }
1294
e38def9c 1295 return dcall_stmt;
167b550b 1296}
1297
1298/*
1299 For every checked indirect/virtual call determine if most common pid of
1300 function/class method has probability more than 50%. If yes modify code of
1301 this call to:
1302 */
1303
1304static bool
3e7f455b 1305gimple_ic_transform (gimple_stmt_iterator *gsi)
167b550b 1306{
3e7f455b 1307 gimple stmt = gsi_stmt (*gsi);
167b550b 1308 histogram_value histogram;
e0dc6f2b 1309 gcov_type val, count, all, bb_all;
5b17b7ae 1310 gcov_type prob;
75a70cf9 1311 gimple modify;
167b550b 1312 struct cgraph_node *direct_call;
48e1416a 1313
75a70cf9 1314 if (gimple_code (stmt) != GIMPLE_CALL)
167b550b 1315 return false;
1316
2de00a2d 1317 if (gimple_call_fndecl (stmt) != NULL_TREE)
167b550b 1318 return false;
1319
fb049fba 1320 if (gimple_call_internal_p (stmt))
1321 return false;
1322
167b550b 1323 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
1324 if (!histogram)
1325 return false;
1326
1327 val = histogram->hvalue.counters [0];
1328 count = histogram->hvalue.counters [1];
1329 all = histogram->hvalue.counters [2];
1330 gimple_remove_histogram_value (cfun, stmt, histogram);
1331
1332 if (4 * count <= 3 * all)
1333 return false;
1334
e0dc6f2b 1335 bb_all = gimple_bb (stmt)->count;
48e1416a 1336 /* The order of CHECK_COUNTER calls is important -
e0dc6f2b 1337 since check_counter can correct the third parameter
1338 and we want to make count <= all <= bb_all. */
1339 if ( check_counter (stmt, "ic", &all, &bb_all, bb_all)
1340 || check_counter (stmt, "ic", &count, &all, all))
1341 return false;
1342
5b17b7ae 1343 if (all > 0)
1344 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1345 else
1346 prob = 0;
1ad3e14c 1347 direct_call = find_func_by_funcdef_no ((int)val);
167b550b 1348
1349 if (direct_call == NULL)
1350 return false;
1351
850ff64c 1352 if (!check_ic_target (stmt, direct_call))
1353 return false;
1354
e38def9c 1355 modify = gimple_ic (stmt, direct_call, prob, count, all);
167b550b 1356
1357 if (dump_file)
1358 {
1359 fprintf (dump_file, "Indirect call -> direct call ");
75a70cf9 1360 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
167b550b 1361 fprintf (dump_file, "=> ");
7d0d0ce1 1362 print_generic_expr (dump_file, direct_call->symbol.decl, TDF_SLIM);
167b550b 1363 fprintf (dump_file, " transformation on insn ");
75a70cf9 1364 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
167b550b 1365 fprintf (dump_file, " to ");
75a70cf9 1366 print_gimple_stmt (dump_file, modify, 0, TDF_SLIM);
6525819b 1367 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC
1368 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count, all);
167b550b 1369 }
1370
1371 return true;
1372}
1373
e0b41cd1 1374/* Return true if the stringop CALL with FNDECL shall be profiled.
1375 SIZE_ARG be set to the argument index for the size of the string
1376 operation.
1377*/
f656b751 1378static bool
e0b41cd1 1379interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
f656b751 1380{
1381 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
1382
058d05d5 1383 if (fcode != BUILT_IN_MEMCPY && fcode != BUILT_IN_MEMPCPY
1384 && fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_BZERO)
f656b751 1385 return false;
1386
1387 switch (fcode)
1388 {
1389 case BUILT_IN_MEMCPY:
1390 case BUILT_IN_MEMPCPY:
e0b41cd1 1391 *size_arg = 2;
75a70cf9 1392 return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
1393 INTEGER_TYPE, VOID_TYPE);
f656b751 1394 case BUILT_IN_MEMSET:
e0b41cd1 1395 *size_arg = 2;
75a70cf9 1396 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1397 INTEGER_TYPE, VOID_TYPE);
f656b751 1398 case BUILT_IN_BZERO:
e0b41cd1 1399 *size_arg = 1;
75a70cf9 1400 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1401 VOID_TYPE);
f656b751 1402 default:
c2f47e15 1403 gcc_unreachable ();
f656b751 1404 }
1405}
1406
e38def9c 1407/* Convert stringop (..., vcall_size)
48e1416a 1408 into
e38def9c 1409 if (vcall_size == icall_size)
1410 stringop (..., icall_size);
f656b751 1411 else
e38def9c 1412 stringop (..., vcall_size);
1413 assuming we'll propagate a true constant into ICALL_SIZE later. */
1414
f656b751 1415static void
e38def9c 1416gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
1417 gcov_type count, gcov_type all)
f656b751 1418{
e38def9c 1419 gimple tmp_stmt, cond_stmt, icall_stmt;
03d37e4e 1420 tree tmp0, tmp1, vcall_size, optype;
e38def9c 1421 basic_block cond_bb, icall_bb, vcall_bb, join_bb;
1422 edge e_ci, e_cv, e_iv, e_ij, e_vj;
75a70cf9 1423 gimple_stmt_iterator gsi;
e0b41cd1 1424 tree fndecl;
1425 int size_arg;
1426
1427 fndecl = gimple_call_fndecl (vcall_stmt);
1428 if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg))
1429 gcc_unreachable();
f656b751 1430
e38def9c 1431 cond_bb = gimple_bb (vcall_stmt);
1432 gsi = gsi_for_stmt (vcall_stmt);
f656b751 1433
e0b41cd1 1434 vcall_size = gimple_call_arg (vcall_stmt, size_arg);
e38def9c 1435 optype = TREE_TYPE (vcall_size);
f656b751 1436
03d37e4e 1437 tmp0 = make_temp_ssa_name (optype, NULL, "PROF");
1438 tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
85344eeb 1439 tmp_stmt = gimple_build_assign (tmp0, fold_convert (optype, icall_size));
e38def9c 1440 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
f656b751 1441
e38def9c 1442 tmp_stmt = gimple_build_assign (tmp1, vcall_size);
1443 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
1444
85344eeb 1445 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
e38def9c 1446 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1447
85344eeb 1448 gimple_set_vdef (vcall_stmt, NULL);
1449 gimple_set_vuse (vcall_stmt, NULL);
1450 update_stmt (vcall_stmt);
e38def9c 1451 icall_stmt = gimple_copy (vcall_stmt);
e0b41cd1 1452 gimple_call_set_arg (icall_stmt, size_arg, icall_size);
e38def9c 1453 gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
f656b751 1454
1455 /* Fix CFG. */
e38def9c 1456 /* Edge e_ci connects cond_bb to icall_bb, etc. */
1457 e_ci = split_block (cond_bb, cond_stmt);
1458 icall_bb = e_ci->dest;
1459 icall_bb->count = count;
f656b751 1460
e38def9c 1461 e_iv = split_block (icall_bb, icall_stmt);
1462 vcall_bb = e_iv->dest;
1463 vcall_bb->count = all - count;
f656b751 1464
e38def9c 1465 e_vj = split_block (vcall_bb, vcall_stmt);
1466 join_bb = e_vj->dest;
1467 join_bb->count = all;
f656b751 1468
e38def9c 1469 e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1470 e_ci->probability = prob;
1471 e_ci->count = count;
1472
1473 e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE);
1474 e_cv->probability = REG_BR_PROB_BASE - prob;
1475 e_cv->count = all - count;
1476
1477 remove_edge (e_iv);
48e1416a 1478
e38def9c 1479 e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
1480 e_ij->probability = REG_BR_PROB_BASE;
1481 e_ij->count = count;
f656b751 1482
e38def9c 1483 e_vj->probability = REG_BR_PROB_BASE;
1484 e_vj->count = all - count;
1485
bb217be2 1486 /* Insert PHI node for the call result if necessary. */
1487 if (gimple_call_lhs (vcall_stmt)
1488 && TREE_CODE (gimple_call_lhs (vcall_stmt)) == SSA_NAME)
1489 {
1490 tree result = gimple_call_lhs (vcall_stmt);
1491 gimple phi = create_phi_node (result, join_bb);
bb217be2 1492 gimple_call_set_lhs (vcall_stmt,
7ecda5e8 1493 duplicate_ssa_name (result, vcall_stmt));
60d535d2 1494 add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION);
bb217be2 1495 gimple_call_set_lhs (icall_stmt,
7ecda5e8 1496 duplicate_ssa_name (result, icall_stmt));
60d535d2 1497 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
bb217be2 1498 }
1499
e38def9c 1500 /* Because these are all string op builtins, they're all nothrow. */
1501 gcc_assert (!stmt_could_throw_p (vcall_stmt));
1502 gcc_assert (!stmt_could_throw_p (icall_stmt));
f656b751 1503}
1504
1505/* Find values inside STMT for that we want to measure histograms for
1506 division/modulo optimization. */
1507static bool
75a70cf9 1508gimple_stringops_transform (gimple_stmt_iterator *gsi)
f656b751 1509{
75a70cf9 1510 gimple stmt = gsi_stmt (*gsi);
f656b751 1511 tree fndecl;
f656b751 1512 tree blck_size;
1513 enum built_in_function fcode;
f656b751 1514 histogram_value histogram;
1515 gcov_type count, all, val;
f656b751 1516 tree dest, src;
1517 unsigned int dest_align, src_align;
5b17b7ae 1518 gcov_type prob;
f656b751 1519 tree tree_val;
e0b41cd1 1520 int size_arg;
f656b751 1521
75a70cf9 1522 if (gimple_code (stmt) != GIMPLE_CALL)
f656b751 1523 return false;
75a70cf9 1524 fndecl = gimple_call_fndecl (stmt);
f656b751 1525 if (!fndecl)
1526 return false;
1527 fcode = DECL_FUNCTION_CODE (fndecl);
e0b41cd1 1528 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
f656b751 1529 return false;
1530
e0b41cd1 1531 blck_size = gimple_call_arg (stmt, size_arg);
f656b751 1532 if (TREE_CODE (blck_size) == INTEGER_CST)
1533 return false;
1534
4992f399 1535 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
f656b751 1536 if (!histogram)
1537 return false;
f656b751 1538 val = histogram->hvalue.counters[0];
1539 count = histogram->hvalue.counters[1];
1540 all = histogram->hvalue.counters[2];
4992f399 1541 gimple_remove_histogram_value (cfun, stmt, histogram);
f656b751 1542 /* We require that count is at least half of all; this means
1543 that for the transformation to fire the value must be constant
1544 at least 80% of time. */
0bfd8d5c 1545 if ((6 * count / 5) < all || optimize_bb_for_size_p (gimple_bb (stmt)))
f656b751 1546 return false;
e0dc6f2b 1547 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
f656b751 1548 return false;
5b17b7ae 1549 if (all > 0)
1550 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1551 else
1552 prob = 0;
75a70cf9 1553 dest = gimple_call_arg (stmt, 0);
957d0361 1554 dest_align = get_pointer_alignment (dest);
f656b751 1555 switch (fcode)
1556 {
1557 case BUILT_IN_MEMCPY:
1558 case BUILT_IN_MEMPCPY:
75a70cf9 1559 src = gimple_call_arg (stmt, 1);
957d0361 1560 src_align = get_pointer_alignment (src);
f656b751 1561 if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
1562 return false;
1563 break;
1564 case BUILT_IN_MEMSET:
1565 if (!can_store_by_pieces (val, builtin_memset_read_str,
75a70cf9 1566 gimple_call_arg (stmt, 1),
4b297e2e 1567 dest_align, true))
f656b751 1568 return false;
1569 break;
1570 case BUILT_IN_BZERO:
1571 if (!can_store_by_pieces (val, builtin_memset_read_str,
1572 integer_zero_node,
4b297e2e 1573 dest_align, true))
f656b751 1574 return false;
1575 break;
1576 default:
1577 gcc_unreachable ();
1578 }
1579 tree_val = build_int_cst_wide (get_gcov_type (),
1580 (unsigned HOST_WIDE_INT) val,
1581 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
1582 if (dump_file)
1583 {
1584 fprintf (dump_file, "Single value %i stringop transformation on ",
1585 (int)val);
75a70cf9 1586 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
f656b751 1587 }
75a70cf9 1588 gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
48e1416a 1589
f656b751 1590 return true;
1591}
1592
162719b3 1593void
75a70cf9 1594stringop_block_profile (gimple stmt, unsigned int *expected_align,
162719b3 1595 HOST_WIDE_INT *expected_size)
1596{
1597 histogram_value histogram;
1598 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
1599 if (!histogram)
1600 *expected_size = -1;
553eb299 1601 else if (!histogram->hvalue.counters[1])
1602 {
1603 *expected_size = -1;
1604 gimple_remove_histogram_value (cfun, stmt, histogram);
1605 }
162719b3 1606 else
1607 {
1608 gcov_type size;
1609 size = ((histogram->hvalue.counters[0]
553eb299 1610 + histogram->hvalue.counters[1] / 2)
1611 / histogram->hvalue.counters[1]);
162719b3 1612 /* Even if we can hold bigger value in SIZE, INT_MAX
1613 is safe "infinity" for code generation strategies. */
1614 if (size > INT_MAX)
1615 size = INT_MAX;
1616 *expected_size = size;
1617 gimple_remove_histogram_value (cfun, stmt, histogram);
1618 }
1619 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
1620 if (!histogram)
f8eabf22 1621 *expected_align = 0;
553eb299 1622 else if (!histogram->hvalue.counters[0])
1623 {
1624 gimple_remove_histogram_value (cfun, stmt, histogram);
1625 *expected_align = 0;
1626 }
162719b3 1627 else
1628 {
1629 gcov_type count;
1630 int alignment;
1631
1632 count = histogram->hvalue.counters[0];
1633 alignment = 1;
1634 while (!(count & alignment)
1635 && (alignment * 2 * BITS_PER_UNIT))
1636 alignment <<= 1;
1637 *expected_align = alignment * BITS_PER_UNIT;
1638 gimple_remove_histogram_value (cfun, stmt, histogram);
1639 }
1640}
1641
4ee9c684 1642\f
d7683f13 1643/* Find values inside STMT for that we want to measure histograms for
d2971487 1644 division/modulo optimization. */
1645static void
75a70cf9 1646gimple_divmod_values_to_profile (gimple stmt, histogram_values *values)
d2971487 1647{
75a70cf9 1648 tree lhs, divisor, op0, type;
d2971487 1649 histogram_value hist;
1650
75a70cf9 1651 if (gimple_code (stmt) != GIMPLE_ASSIGN)
d2971487 1652 return;
75a70cf9 1653
1654 lhs = gimple_assign_lhs (stmt);
d7683f13 1655 type = TREE_TYPE (lhs);
1656 if (!INTEGRAL_TYPE_P (type))
d2971487 1657 return;
d7683f13 1658
75a70cf9 1659 switch (gimple_assign_rhs_code (stmt))
d2971487 1660 {
1661 case TRUNC_DIV_EXPR:
1662 case TRUNC_MOD_EXPR:
75a70cf9 1663 divisor = gimple_assign_rhs2 (stmt);
1664 op0 = gimple_assign_rhs1 (stmt);
d2971487 1665
f1f41a6c 1666 values->reserve (3);
d7683f13 1667
7c782c9b 1668 if (TREE_CODE (divisor) == SSA_NAME)
4992f399 1669 /* Check for the case where the divisor is the same value most
1670 of the time. */
f1f41a6c 1671 values->quick_push (gimple_alloc_histogram_value (cfun,
75a70cf9 1672 HIST_TYPE_SINGLE_VALUE,
4992f399 1673 stmt, divisor));
d2971487 1674
1675 /* For mod, check whether it is not often a noop (or replaceable by
1676 a few subtractions). */
75a70cf9 1677 if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR
d7683f13 1678 && TYPE_UNSIGNED (type))
d2971487 1679 {
4992f399 1680 tree val;
421e19dd 1681 /* Check for a special case where the divisor is power of 2. */
f1f41a6c 1682 values->quick_push (gimple_alloc_histogram_value (cfun,
1683 HIST_TYPE_POW2,
1684 stmt, divisor));
421e19dd 1685
4992f399 1686 val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
1687 hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
1688 stmt, val);
d2971487 1689 hist->hdata.intvl.int_start = 0;
1690 hist->hdata.intvl.steps = 2;
f1f41a6c 1691 values->quick_push (hist);
d2971487 1692 }
1693 return;
1694
1695 default:
1696 return;
1697 }
1698}
1699
48e1416a 1700/* Find calls inside STMT for that we want to measure histograms for
1701 indirect/virtual call optimization. */
167b550b 1702
1703static void
75a70cf9 1704gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
167b550b 1705{
75a70cf9 1706 tree callee;
167b550b 1707
0acacf9e 1708 if (gimple_code (stmt) != GIMPLE_CALL
fb049fba 1709 || gimple_call_internal_p (stmt)
0acacf9e 1710 || gimple_call_fndecl (stmt) != NULL_TREE)
167b550b 1711 return;
1712
75a70cf9 1713 callee = gimple_call_fn (stmt);
167b550b 1714
f1f41a6c 1715 values->reserve (3);
167b550b 1716
f1f41a6c 1717 values->quick_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
1718 stmt, callee));
167b550b 1719
1720 return;
1721}
1722
f656b751 1723/* Find values inside STMT for that we want to measure histograms for
4992f399 1724 string operations. */
f656b751 1725static void
75a70cf9 1726gimple_stringops_values_to_profile (gimple stmt, histogram_values *values)
f656b751 1727{
f656b751 1728 tree fndecl;
f656b751 1729 tree blck_size;
162719b3 1730 tree dest;
e0b41cd1 1731 int size_arg;
f656b751 1732
75a70cf9 1733 if (gimple_code (stmt) != GIMPLE_CALL)
f656b751 1734 return;
75a70cf9 1735 fndecl = gimple_call_fndecl (stmt);
f656b751 1736 if (!fndecl)
1737 return;
f656b751 1738
e0b41cd1 1739 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
f656b751 1740 return;
1741
75a70cf9 1742 dest = gimple_call_arg (stmt, 0);
e0b41cd1 1743 blck_size = gimple_call_arg (stmt, size_arg);
f656b751 1744
162719b3 1745 if (TREE_CODE (blck_size) != INTEGER_CST)
1746 {
f1f41a6c 1747 values->safe_push (gimple_alloc_histogram_value (cfun,
1748 HIST_TYPE_SINGLE_VALUE,
1749 stmt, blck_size));
1750 values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
1751 stmt, blck_size));
162719b3 1752 }
f656b751 1753 if (TREE_CODE (blck_size) != INTEGER_CST)
f1f41a6c 1754 values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
1755 stmt, dest));
f656b751 1756}
1757
d7683f13 1758/* Find values inside STMT for that we want to measure histograms and adds
1759 them to list VALUES. */
1760
4ee9c684 1761static void
75a70cf9 1762gimple_values_to_profile (gimple stmt, histogram_values *values)
4ee9c684 1763{
3e7f455b 1764 gimple_divmod_values_to_profile (stmt, values);
1765 gimple_stringops_values_to_profile (stmt, values);
1766 gimple_indirect_call_to_profile (stmt, values);
4ee9c684 1767}
1768
fc49fbc1 1769void
75a70cf9 1770gimple_find_values_to_profile (histogram_values *values)
4ee9c684 1771{
d2971487 1772 basic_block bb;
75a70cf9 1773 gimple_stmt_iterator gsi;
d7683f13 1774 unsigned i;
4992f399 1775 histogram_value hist = NULL;
d7683f13 1776
f1f41a6c 1777 values->create (0);
d2971487 1778 FOR_EACH_BB (bb)
75a70cf9 1779 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1780 gimple_values_to_profile (gsi_stmt (gsi), values);
48e1416a 1781
f1f41a6c 1782 FOR_EACH_VEC_ELT (*values, i, hist)
d2971487 1783 {
d2971487 1784 switch (hist->type)
1785 {
1786 case HIST_TYPE_INTERVAL:
d2971487 1787 hist->n_counters = hist->hdata.intvl.steps + 2;
1788 break;
1789
1790 case HIST_TYPE_POW2:
d7683f13 1791 hist->n_counters = 2;
d2971487 1792 break;
1793
1794 case HIST_TYPE_SINGLE_VALUE:
d2971487 1795 hist->n_counters = 3;
1796 break;
1797
1798 case HIST_TYPE_CONST_DELTA:
d2971487 1799 hist->n_counters = 4;
1800 break;
1801
167b550b 1802 case HIST_TYPE_INDIR_CALL:
1803 hist->n_counters = 3;
1804 break;
1805
162719b3 1806 case HIST_TYPE_AVERAGE:
553eb299 1807 hist->n_counters = 2;
162719b3 1808 break;
1809
1810 case HIST_TYPE_IOR:
553eb299 1811 hist->n_counters = 1;
162719b3 1812 break;
1813
d2971487 1814 default:
a53ff4c1 1815 gcc_unreachable ();
d2971487 1816 }
4992f399 1817 if (dump_file)
1818 {
1819 fprintf (dump_file, "Stmt ");
75a70cf9 1820 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM);
4992f399 1821 dump_histogram_value (dump_file, hist);
1822 }
d2971487 1823 }
4ee9c684 1824}