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