OSDN Git Service

Fix AIX version number in comment.
[pf3gnuchains/gcc-fork.git] / gcc / value-prof.c
1 /* Transformations based on profile information for values.
2    Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "rtl.h"
25 #include "expr.h"
26 #include "hard-reg-set.h"
27 #include "basic-block.h"
28 #include "value-prof.h"
29 #include "output.h"
30 #include "flags.h"
31 #include "insn-config.h"
32 #include "recog.h"
33 #include "optabs.h"
34 #include "regs.h"
35 #include "ggc.h"
36 #include "tree-flow.h"
37 #include "tree-flow-inline.h"
38 #include "diagnostic.h"
39 #include "coverage.h"
40 #include "tree.h"
41 #include "gcov-io.h"
42 #include "cgraph.h"
43 #include "timevar.h"
44 #include "tree-pass.h"
45 #include "toplev.h"
46 #include "pointer-set.h"
47
48 static struct value_prof_hooks *value_prof_hooks;
49
50 /* In this file value profile based optimizations are placed.  Currently the
51    following optimizations are implemented (for more detailed descriptions
52    see comments at value_profile_transformations):
53
54    1) Division/modulo specialization.  Provided that we can determine that the
55       operands of the division have some special properties, we may use it to
56       produce more effective code.
57    2) Speculative prefetching.  If we are able to determine that the difference
58       between addresses accessed by a memory reference is usually constant, we
59       may add the prefetch instructions.
60       FIXME: This transformation was removed together with RTL based value
61       profiling.
62
63    3) Indirect/virtual call specialization. If we can determine most
64       common function callee in indirect/virtual call. We can use this
65       information to improve code effectiveness (especially info for
66       inliner).
67
68    Every such optimization should add its requirements for profiled values to
69    insn_values_to_profile function.  This function is called from branch_prob
70    in profile.c and the requested values are instrumented by it in the first
71    compilation with -fprofile-arcs.  The optimization may then read the
72    gathered data in the second compilation with -fbranch-probabilities.
73
74    The measured data is pointed to from the histograms
75    field of the statement annotation of the instrumented insns.  It is
76    kept as a linked list of struct histogram_value_t's, which contain the
77    same information as above.  */
78
79
80 static tree tree_divmod_fixed_value (tree, tree, tree, tree, 
81                                     tree, int, gcov_type, gcov_type);
82 static tree tree_mod_pow2 (tree, tree, tree, tree, int, gcov_type, gcov_type);
83 static tree tree_mod_subtract (tree, tree, tree, tree, int, int, int,
84                                 gcov_type, gcov_type, gcov_type);
85 static bool tree_divmod_fixed_value_transform (tree);
86 static bool tree_mod_pow2_value_transform (tree);
87 static bool tree_mod_subtract_transform (tree);
88 static bool tree_stringops_transform (block_stmt_iterator *);
89 static bool tree_ic_transform (tree);
90
91 /* Allocate histogram value.  */
92
93 static histogram_value
94 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
95                               enum hist_type type, tree stmt, tree value)
96 {
97    histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
98    hist->hvalue.value = value;
99    hist->hvalue.stmt = stmt;
100    hist->type = type;
101    return hist;
102 }
103
104 /* Hash value for histogram.  */
105
106 static hashval_t
107 histogram_hash (const void *x)
108 {
109   return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt);
110 }
111
112 /* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y.  */
113
114 static int
115 histogram_eq (const void *x, const void *y)
116 {
117   return ((const_histogram_value) x)->hvalue.stmt == (const_tree)y;
118 }
119
120 /* Set histogram for STMT.  */
121
122 static void
123 set_histogram_value (struct function *fun, tree stmt, histogram_value hist)
124 {
125   void **loc;
126   if (!hist && !VALUE_HISTOGRAMS (fun))
127     return;
128   if (!VALUE_HISTOGRAMS (fun))
129     VALUE_HISTOGRAMS (fun) = htab_create (1, histogram_hash,
130                                            histogram_eq, NULL);
131   loc = htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun), stmt,
132                                   htab_hash_pointer (stmt),
133                                   hist ? INSERT : NO_INSERT);
134   if (!hist)
135     {
136       if (loc)
137         htab_clear_slot (VALUE_HISTOGRAMS (fun), loc);
138       return;
139     }
140   *loc = hist;
141 }
142
143 /* Get histogram list for STMT.  */
144
145 histogram_value
146 gimple_histogram_value (struct function *fun, tree stmt)
147 {
148   if (!VALUE_HISTOGRAMS (fun))
149     return NULL;
150   return htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt,
151                               htab_hash_pointer (stmt));
152 }
153
154 /* Add histogram for STMT.  */
155
156 void
157 gimple_add_histogram_value (struct function *fun, tree stmt, histogram_value hist)
158 {
159   hist->hvalue.next = gimple_histogram_value (fun, stmt);
160   set_histogram_value (fun, stmt, hist);
161 }
162
163 /* Remove histogram HIST from STMT's histogram list.  */
164
165 void
166 gimple_remove_histogram_value (struct function *fun, tree stmt, histogram_value hist)
167 {
168   histogram_value hist2 = gimple_histogram_value (fun, stmt);
169   if (hist == hist2)
170     {
171       set_histogram_value (fun, stmt, hist->hvalue.next);
172     }
173   else
174     {
175       while (hist2->hvalue.next != hist)
176         hist2 = hist2->hvalue.next;
177       hist2->hvalue.next = hist->hvalue.next;
178     }
179   free (hist->hvalue.counters);
180 #ifdef ENABLE_CHECKING
181   memset (hist, 0xab, sizeof (*hist));
182 #endif
183   free (hist);
184 }
185
186 /* Lookup histogram of type TYPE in the STMT.  */
187
188 histogram_value
189 gimple_histogram_value_of_type (struct function *fun, tree stmt, enum hist_type type)
190 {
191   histogram_value hist;
192   for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
193     if (hist->type == type)
194       return hist;
195   return NULL;
196 }
197
198 /* Dump information about HIST to DUMP_FILE.  */
199
200 static void
201 dump_histogram_value (FILE *dump_file, histogram_value hist)
202 {
203   switch (hist->type)
204     {
205     case HIST_TYPE_INTERVAL:
206       fprintf (dump_file, "Interval counter range %d -- %d",
207                hist->hdata.intvl.int_start,
208                (hist->hdata.intvl.int_start
209                 + hist->hdata.intvl.steps - 1));
210       if (hist->hvalue.counters)
211         {
212            unsigned int i;
213            fprintf(dump_file, " [");
214            for (i = 0; i < hist->hdata.intvl.steps; i++)
215              fprintf (dump_file, " %d:"HOST_WIDEST_INT_PRINT_DEC,
216                       hist->hdata.intvl.int_start + i,
217                       (HOST_WIDEST_INT) hist->hvalue.counters[i]);
218            fprintf (dump_file, " ] outside range:"HOST_WIDEST_INT_PRINT_DEC,
219                     (HOST_WIDEST_INT) hist->hvalue.counters[i]);
220         }
221       fprintf (dump_file, ".\n");
222       break;
223
224     case HIST_TYPE_POW2:
225       fprintf (dump_file, "Pow2 counter ");
226       if (hist->hvalue.counters)
227         {
228            fprintf (dump_file, "pow2:"HOST_WIDEST_INT_PRINT_DEC
229                     " nonpow2:"HOST_WIDEST_INT_PRINT_DEC,
230                     (HOST_WIDEST_INT) hist->hvalue.counters[0],
231                     (HOST_WIDEST_INT) hist->hvalue.counters[1]);
232         }
233       fprintf (dump_file, ".\n");
234       break;
235
236     case HIST_TYPE_SINGLE_VALUE:
237       fprintf (dump_file, "Single value ");
238       if (hist->hvalue.counters)
239         {
240            fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
241                     " match:"HOST_WIDEST_INT_PRINT_DEC
242                     " wrong:"HOST_WIDEST_INT_PRINT_DEC,
243                     (HOST_WIDEST_INT) hist->hvalue.counters[0],
244                     (HOST_WIDEST_INT) hist->hvalue.counters[1],
245                     (HOST_WIDEST_INT) hist->hvalue.counters[2]);
246         }
247       fprintf (dump_file, ".\n");
248       break;
249
250     case HIST_TYPE_AVERAGE:
251       fprintf (dump_file, "Average value ");
252       if (hist->hvalue.counters)
253         {
254            fprintf (dump_file, "sum:"HOST_WIDEST_INT_PRINT_DEC
255                     " times:"HOST_WIDEST_INT_PRINT_DEC,
256                     (HOST_WIDEST_INT) hist->hvalue.counters[0],
257                     (HOST_WIDEST_INT) hist->hvalue.counters[1]);
258         }
259       fprintf (dump_file, ".\n");
260       break;
261
262     case HIST_TYPE_IOR:
263       fprintf (dump_file, "IOR value ");
264       if (hist->hvalue.counters)
265         {
266            fprintf (dump_file, "ior:"HOST_WIDEST_INT_PRINT_DEC,
267                     (HOST_WIDEST_INT) hist->hvalue.counters[0]);
268         }
269       fprintf (dump_file, ".\n");
270       break;
271
272     case HIST_TYPE_CONST_DELTA:
273       fprintf (dump_file, "Constant delta ");
274       if (hist->hvalue.counters)
275         {
276            fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
277                     " match:"HOST_WIDEST_INT_PRINT_DEC
278                     " wrong:"HOST_WIDEST_INT_PRINT_DEC,
279                     (HOST_WIDEST_INT) hist->hvalue.counters[0],
280                     (HOST_WIDEST_INT) hist->hvalue.counters[1],
281                     (HOST_WIDEST_INT) hist->hvalue.counters[2]);
282         }
283       fprintf (dump_file, ".\n");
284       break;
285     case HIST_TYPE_INDIR_CALL:
286       fprintf (dump_file, "Indirect call ");
287       if (hist->hvalue.counters)
288         {
289            fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
290                     " match:"HOST_WIDEST_INT_PRINT_DEC
291                     " all:"HOST_WIDEST_INT_PRINT_DEC,
292                     (HOST_WIDEST_INT) hist->hvalue.counters[0],
293                     (HOST_WIDEST_INT) hist->hvalue.counters[1],
294                     (HOST_WIDEST_INT) hist->hvalue.counters[2]);
295         }
296       fprintf (dump_file, ".\n");
297       break;
298    }
299 }
300
301 /* Dump all histograms attached to STMT to DUMP_FILE.  */
302
303 void
304 dump_histograms_for_stmt (struct function *fun, FILE *dump_file, tree stmt)
305 {
306   histogram_value hist;
307   for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
308    dump_histogram_value (dump_file, hist);
309 }
310
311 /* Remove all histograms associated with STMT.  */
312
313 void
314 gimple_remove_stmt_histograms (struct function *fun, tree stmt)
315 {
316   histogram_value val;
317   while ((val = gimple_histogram_value (fun, stmt)) != NULL)
318     gimple_remove_histogram_value (fun, stmt, val);
319 }
320
321 /* Duplicate all histograms associates with OSTMT to STMT.  */
322
323 void
324 gimple_duplicate_stmt_histograms (struct function *fun, tree stmt,
325                                   struct function *ofun, tree ostmt)
326 {
327   histogram_value val;
328   for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
329     {
330       histogram_value new = gimple_alloc_histogram_value (fun, val->type, NULL, NULL);
331       memcpy (new, val, sizeof (*val));
332       new->hvalue.stmt = stmt;
333       new->hvalue.counters = xmalloc (sizeof (*new->hvalue.counters) * new->n_counters);
334       memcpy (new->hvalue.counters, val->hvalue.counters, sizeof (*new->hvalue.counters) * new->n_counters);
335       gimple_add_histogram_value (fun, stmt, new);
336     }
337 }
338
339 static bool error_found = false;
340
341 /* Helper function for verify_histograms.  For each histogram reachable via htab
342    walk verify that it was reached via statement walk.  */
343
344 static int
345 visit_hist (void **slot, void *data)
346 {
347   struct pointer_set_t *visited = (struct pointer_set_t *) data;
348   histogram_value hist = *(histogram_value *) slot;
349   if (!pointer_set_contains (visited, hist))
350     {
351       error ("Dead histogram");
352       dump_histogram_value (stderr, hist);
353       debug_generic_stmt (hist->hvalue.stmt);
354       error_found = true;
355     }
356   return 1;
357 }
358
359 /* Verify sanity of the histograms.  */
360
361 void
362 verify_histograms (void)
363 {
364   basic_block bb;
365   block_stmt_iterator bsi;
366   histogram_value hist;
367   struct pointer_set_t *visited_hists;
368
369   error_found = false;
370   visited_hists = pointer_set_create ();
371   FOR_EACH_BB (bb)
372     for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
373       {
374         tree stmt = bsi_stmt (bsi);
375
376         for (hist = gimple_histogram_value (cfun, stmt); hist; hist = hist->hvalue.next)
377           {
378             if (hist->hvalue.stmt != stmt)
379               {
380                 error ("Histogram value statement does not correspond to statement"
381                        " it is associated with");
382                 debug_generic_stmt (stmt);
383                 dump_histogram_value (stderr, hist);
384                 error_found = true;
385               }
386             pointer_set_insert (visited_hists, hist);
387           }
388       }
389   if (VALUE_HISTOGRAMS (cfun))
390     htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, visited_hists);
391   pointer_set_destroy (visited_hists);
392   if (error_found)
393     internal_error ("verify_histograms failed");
394 }
395
396 /* Helper function for verify_histograms.  For each histogram reachable via htab
397    walk verify that it was reached via statement walk.  */
398
399 static int
400 free_hist (void **slot, void *data ATTRIBUTE_UNUSED)
401 {
402   histogram_value hist = *(histogram_value *) slot;
403   free (hist->hvalue.counters);
404 #ifdef ENABLE_CHECKING
405   memset (hist, 0xab, sizeof (*hist));
406 #endif
407   free (hist);
408   return 1;
409 }
410
411 void
412 free_histograms (void)
413 {
414   if (VALUE_HISTOGRAMS (cfun))
415     {
416       htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL);
417       htab_delete (VALUE_HISTOGRAMS (cfun));
418       VALUE_HISTOGRAMS (cfun) = NULL;
419     }
420 }
421
422 /* The overall number of invocations of the counter should match execution count
423    of basic block.  Report it as error rather than internal error as it might
424    mean that user has misused the profile somehow.  */
425 static bool
426 check_counter (tree stmt, const char * name, gcov_type all, gcov_type bb_count)
427 {
428   if (all != bb_count)
429     {
430       location_t * locus;
431       locus = (stmt != NULL && EXPR_HAS_LOCATION (stmt)
432                ? EXPR_LOCUS (stmt)
433                : &DECL_SOURCE_LOCATION (current_function_decl));
434       error ("%HCorrupted value profile: %s profiler overall count (%d) does not match BB count (%d)",
435              locus, name, (int)all, (int)bb_count);
436       return true;
437     }
438   return false;
439 }
440
441 /* Tree based transformations. */
442 static bool
443 tree_value_profile_transformations (void)
444 {
445   basic_block bb;
446   block_stmt_iterator bsi;
447   bool changed = false;
448
449   FOR_EACH_BB (bb)
450     {
451       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
452         {
453           tree stmt = bsi_stmt (bsi);
454           histogram_value th = gimple_histogram_value (cfun, stmt);
455           if (!th)
456             continue;
457
458           if (dump_file)
459             {
460               fprintf (dump_file, "Trying transformations on stmt ");
461               print_generic_stmt (dump_file, stmt, TDF_SLIM);
462               dump_histograms_for_stmt (cfun, dump_file, stmt);
463             }
464
465           /* Transformations:  */
466           /* The order of things in this conditional controls which
467              transformation is used when more than one is applicable.  */
468           /* It is expected that any code added by the transformations
469              will be added before the current statement, and that the
470              current statement remain valid (although possibly
471              modified) upon return.  */
472           if (flag_value_profile_transformations
473               && (tree_mod_subtract_transform (stmt)
474                   || tree_divmod_fixed_value_transform (stmt)
475                   || tree_mod_pow2_value_transform (stmt)
476                   || tree_stringops_transform (&bsi)
477                   || tree_ic_transform (stmt)))
478             {
479               stmt = bsi_stmt (bsi);
480               changed = true;
481               /* Original statement may no longer be in the same block. */
482               if (bb != bb_for_stmt (stmt))
483                 {
484                   bb = bb_for_stmt (stmt);
485                   bsi = bsi_for_stmt (stmt);
486                 }
487             }
488         }
489     }
490
491   if (changed)
492     {
493       counts_to_freqs ();
494     }
495
496   return changed;
497 }
498
499 /* Generate code for transformation 1 (with OPERATION, operands OP1
500    and OP2, whose value is expected to be VALUE, parent modify-expr STMT and
501    probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
502    within roundoff error).  This generates the result into a temp and returns 
503    the temp; it does not replace or alter the original STMT.  */
504 static tree
505 tree_divmod_fixed_value (tree stmt, tree operation, 
506                          tree op1, tree op2, tree value, int prob, gcov_type count,
507                          gcov_type all)
508 {
509   tree stmt1, stmt2, stmt3;
510   tree tmp1, tmp2, tmpv;
511   tree label_decl1 = create_artificial_label ();
512   tree label_decl2 = create_artificial_label ();
513   tree label1, label2;
514   tree bb1end, bb2end, bb3end;
515   basic_block bb, bb2, bb3, bb4;
516   tree optype = TREE_TYPE (operation);
517   edge e12, e13, e23, e24, e34;
518   block_stmt_iterator bsi;
519
520   bb = bb_for_stmt (stmt);
521   bsi = bsi_for_stmt (stmt);
522
523   tmpv = create_tmp_var (optype, "PROF");
524   tmp1 = create_tmp_var (optype, "PROF");
525   stmt1 = build_gimple_modify_stmt (tmpv, fold_convert (optype, value));
526   stmt2 = build_gimple_modify_stmt (tmp1, op2);
527   stmt3 = build3 (COND_EXPR, void_type_node,
528             build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
529             NULL_TREE, NULL_TREE);
530   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
531   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
532   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
533   bb1end = stmt3;
534
535   tmp2 = create_tmp_var (optype, "PROF");
536   label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
537   stmt1 = build_gimple_modify_stmt (tmp2,
538                                     build2 (TREE_CODE (operation), optype,
539                                             op1, tmpv));
540   bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
541   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
542   bb2end = stmt1;
543
544   label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
545   stmt1 = build_gimple_modify_stmt (tmp2,
546                                     build2 (TREE_CODE (operation), optype,
547                                             op1, op2));
548   bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
549   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
550   bb3end = stmt1;
551
552   /* Fix CFG. */
553   /* Edge e23 connects bb2 to bb3, etc. */
554   e12 = split_block (bb, bb1end);
555   bb2 = e12->dest;
556   bb2->count = count;
557   e23 = split_block (bb2, bb2end);
558   bb3 = e23->dest;
559   bb3->count = all - count;
560   e34 = split_block (bb3, bb3end);
561   bb4 = e34->dest;
562   bb4->count = all;
563
564   e12->flags &= ~EDGE_FALLTHRU;
565   e12->flags |= EDGE_FALSE_VALUE;
566   e12->probability = prob;
567   e12->count = count;
568
569   e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
570   e13->probability = REG_BR_PROB_BASE - prob;
571   e13->count = all - count;
572
573   remove_edge (e23);
574   
575   e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
576   e24->probability = REG_BR_PROB_BASE;
577   e24->count = count;
578
579   e34->probability = REG_BR_PROB_BASE;
580   e34->count = all - count;
581
582   return tmp2;
583 }
584
585 /* Do transform 1) on INSN if applicable.  */
586 static bool
587 tree_divmod_fixed_value_transform (tree stmt)
588 {
589   histogram_value histogram;
590   enum tree_code code;
591   gcov_type val, count, all;
592   tree modify, op, op1, op2, result, value, tree_val;
593   int prob;
594
595   modify = stmt;
596   if (TREE_CODE (stmt) == RETURN_EXPR
597       && TREE_OPERAND (stmt, 0)
598       && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
599     modify = TREE_OPERAND (stmt, 0);
600   if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
601     return false;
602   op = GIMPLE_STMT_OPERAND (modify, 1);
603   if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
604     return false;
605   code = TREE_CODE (op);
606   
607   if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
608     return false;
609
610   op1 = TREE_OPERAND (op, 0);
611   op2 = TREE_OPERAND (op, 1);
612
613   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
614   if (!histogram)
615     return false;
616
617   value = histogram->hvalue.value;
618   val = histogram->hvalue.counters[0];
619   count = histogram->hvalue.counters[1];
620   all = histogram->hvalue.counters[2];
621   gimple_remove_histogram_value (cfun, stmt, histogram);
622
623   /* We require that count is at least half of all; this means
624      that for the transformation to fire the value must be constant
625      at least 50% of time (and 75% gives the guarantee of usage).  */
626   if (simple_cst_equal (op2, value) != 1 || 2 * count < all
627       || !maybe_hot_bb_p (bb_for_stmt (stmt)))
628     return false;
629
630   if (check_counter (stmt, "value", all, bb_for_stmt (stmt)->count))
631     return false;
632
633   /* Compute probability of taking the optimal path.  */
634   prob = (count * REG_BR_PROB_BASE + all / 2) / all;
635
636   tree_val = build_int_cst_wide (get_gcov_type (),
637                                  (unsigned HOST_WIDE_INT) val,
638                                  val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
639   result = tree_divmod_fixed_value (stmt, op, op1, op2, tree_val, prob, count, all);
640
641   if (dump_file)
642     {
643       fprintf (dump_file, "Div/mod by constant ");
644       print_generic_expr (dump_file, value, TDF_SLIM);
645       fprintf (dump_file, "=");
646       print_generic_expr (dump_file, tree_val, TDF_SLIM);
647       fprintf (dump_file, " transformation on insn ");
648       print_generic_stmt (dump_file, stmt, TDF_SLIM);
649     }
650
651   GIMPLE_STMT_OPERAND (modify, 1) = result;
652
653   return true;
654 }
655
656 /* Generate code for transformation 2 (with OPERATION, operands OP1
657    and OP2, parent modify-expr STMT and probability of taking the optimal 
658    path PROB, which is equivalent to COUNT/ALL within roundoff error).  
659    This generates the result into a temp and returns 
660    the temp; it does not replace or alter the original STMT.  */
661 static tree
662 tree_mod_pow2 (tree stmt, tree operation, tree op1, tree op2, int prob, 
663                gcov_type count, gcov_type all)
664 {
665   tree stmt1, stmt2, stmt3, stmt4;
666   tree tmp2, tmp3;
667   tree label_decl1 = create_artificial_label ();
668   tree label_decl2 = create_artificial_label ();
669   tree label1, label2;
670   tree bb1end, bb2end, bb3end;
671   basic_block bb, bb2, bb3, bb4;
672   tree optype = TREE_TYPE (operation);
673   edge e12, e13, e23, e24, e34;
674   block_stmt_iterator bsi;
675   tree result = create_tmp_var (optype, "PROF");
676
677   bb = bb_for_stmt (stmt);
678   bsi = bsi_for_stmt (stmt);
679
680   tmp2 = create_tmp_var (optype, "PROF");
681   tmp3 = create_tmp_var (optype, "PROF");
682   stmt2 = build_gimple_modify_stmt (tmp2, 
683                                     build2 (PLUS_EXPR, optype, op2,
684                                             build_int_cst (optype, -1)));
685   stmt3 = build_gimple_modify_stmt (tmp3,
686                                     build2 (BIT_AND_EXPR, optype, tmp2, op2));
687   stmt4 = build3 (COND_EXPR, void_type_node,
688                   build2 (NE_EXPR, boolean_type_node,
689                           tmp3, build_int_cst (optype, 0)),
690                   NULL_TREE, NULL_TREE);
691   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
692   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
693   bsi_insert_before (&bsi, stmt4, BSI_SAME_STMT);
694   bb1end = stmt4;
695
696   /* tmp2 == op2-1 inherited from previous block */
697   label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
698   stmt1 = build_gimple_modify_stmt (result,
699                                     build2 (BIT_AND_EXPR, optype, op1, tmp2));
700   bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
701   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
702   bb2end = stmt1;
703
704   label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
705   stmt1 = build_gimple_modify_stmt (result,
706                                     build2 (TREE_CODE (operation), optype,
707                                             op1, op2));
708   bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
709   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
710   bb3end = stmt1;
711
712   /* Fix CFG. */
713   /* Edge e23 connects bb2 to bb3, etc. */
714   e12 = split_block (bb, bb1end);
715   bb2 = e12->dest;
716   bb2->count = count;
717   e23 = split_block (bb2, bb2end);
718   bb3 = e23->dest;
719   bb3->count = all - count;
720   e34 = split_block (bb3, bb3end);
721   bb4 = e34->dest;
722   bb4->count = all;
723
724   e12->flags &= ~EDGE_FALLTHRU;
725   e12->flags |= EDGE_FALSE_VALUE;
726   e12->probability = prob;
727   e12->count = count;
728
729   e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
730   e13->probability = REG_BR_PROB_BASE - prob;
731   e13->count = all - count;
732
733   remove_edge (e23);
734   
735   e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
736   e24->probability = REG_BR_PROB_BASE;
737   e24->count = count;
738
739   e34->probability = REG_BR_PROB_BASE;
740   e34->count = all - count;
741
742   return result;
743 }
744
745 /* Do transform 2) on INSN if applicable.  */
746 static bool
747 tree_mod_pow2_value_transform (tree stmt)
748 {
749   histogram_value histogram;
750   enum tree_code code;
751   gcov_type count, wrong_values, all;
752   tree modify, op, op1, op2, result, value;
753   int prob;
754
755   modify = stmt;
756   if (TREE_CODE (stmt) == RETURN_EXPR
757       && TREE_OPERAND (stmt, 0)
758       && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
759     modify = TREE_OPERAND (stmt, 0);
760   if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
761     return false;
762   op = GIMPLE_STMT_OPERAND (modify, 1);
763   if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
764     return false;
765   code = TREE_CODE (op);
766   
767   if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (TREE_TYPE (op)))
768     return false;
769
770   op1 = TREE_OPERAND (op, 0);
771   op2 = TREE_OPERAND (op, 1);
772
773   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
774   if (!histogram)
775     return false;
776
777   value = histogram->hvalue.value;
778   wrong_values = histogram->hvalue.counters[0];
779   count = histogram->hvalue.counters[1];
780
781   gimple_remove_histogram_value (cfun, stmt, histogram);
782
783   /* We require that we hit a power of 2 at least half of all evaluations.  */
784   if (simple_cst_equal (op2, value) != 1 || count < wrong_values
785       || !maybe_hot_bb_p (bb_for_stmt (stmt)))
786     return false;
787
788   if (dump_file)
789     {
790       fprintf (dump_file, "Mod power of 2 transformation on insn ");
791       print_generic_stmt (dump_file, stmt, TDF_SLIM);
792     }
793
794   /* Compute probability of taking the optimal path.  */
795   all = count + wrong_values;
796
797   if (check_counter (stmt, "pow2", all, bb_for_stmt (stmt)->count))
798     return false;
799
800   prob = (count * REG_BR_PROB_BASE + all / 2) / all;
801
802   result = tree_mod_pow2 (stmt, op, op1, op2, prob, count, all);
803
804   GIMPLE_STMT_OPERAND (modify, 1) = result;
805
806   return true;
807 }
808
809 /* Generate code for transformations 3 and 4 (with OPERATION, operands OP1
810    and OP2, parent modify-expr STMT, and NCOUNTS the number of cases to
811    support.  Currently only NCOUNTS==0 or 1 is supported and this is
812    built into this interface.  The probabilities of taking the optimal 
813    paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
814    COUNT2/ALL respectively within roundoff error).  This generates the 
815    result into a temp and returns the temp; it does not replace or alter 
816    the original STMT.  */
817 /* FIXME: Generalize the interface to handle NCOUNTS > 1.  */
818
819 static tree
820 tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2, 
821                     int prob1, int prob2, int ncounts,
822                     gcov_type count1, gcov_type count2, gcov_type all)
823 {
824   tree stmt1, stmt2, stmt3;
825   tree tmp1;
826   tree label_decl1 = create_artificial_label ();
827   tree label_decl2 = create_artificial_label ();
828   tree label_decl3 = create_artificial_label ();
829   tree label1, label2, label3;
830   tree bb1end, bb2end = NULL_TREE, bb3end;
831   basic_block bb, bb2, bb3, bb4;
832   tree optype = TREE_TYPE (operation);
833   edge e12, e23 = 0, e24, e34, e14;
834   block_stmt_iterator bsi;
835   tree result = create_tmp_var (optype, "PROF");
836
837   bb = bb_for_stmt (stmt);
838   bsi = bsi_for_stmt (stmt);
839
840   tmp1 = create_tmp_var (optype, "PROF");
841   stmt1 = build_gimple_modify_stmt (result, op1);
842   stmt2 = build_gimple_modify_stmt (tmp1, op2);
843   stmt3 = build3 (COND_EXPR, void_type_node,
844             build2 (LT_EXPR, boolean_type_node, result, tmp1),
845             NULL_TREE, NULL_TREE);
846   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
847   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
848   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
849   bb1end = stmt3;
850
851   if (ncounts)  /* Assumed to be 0 or 1 */
852     {
853       label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
854       stmt1 = build_gimple_modify_stmt (result,
855                                         build2 (MINUS_EXPR, optype,
856                                                 result, tmp1));
857       stmt2 = build3 (COND_EXPR, void_type_node,
858                 build2 (LT_EXPR, boolean_type_node, result, tmp1),
859                 NULL_TREE, NULL_TREE);
860       bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
861       bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
862       bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
863       bb2end = stmt2;
864     }
865
866   /* Fallback case. */
867   label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
868   stmt1 = build_gimple_modify_stmt (result,
869                                     build2 (TREE_CODE (operation), optype,
870                                             result, tmp1));
871   bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
872   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
873   bb3end = stmt1;
874
875   label3 = build1 (LABEL_EXPR, void_type_node, label_decl3);
876   bsi_insert_before (&bsi, label3, BSI_SAME_STMT);
877
878   /* Fix CFG. */
879   /* Edge e23 connects bb2 to bb3, etc. */
880   /* However block 3 is optional; if it is not there, references
881      to 3 really refer to block 2. */
882   e12 = split_block (bb, bb1end);
883   bb2 = e12->dest;
884   bb2->count = all - count1;
885     
886   if (ncounts)  /* Assumed to be 0 or 1.  */
887     {
888       e23 = split_block (bb2, bb2end);
889       bb3 = e23->dest;
890       bb3->count = all - count1 - count2;
891     }
892
893   e34 = split_block (ncounts ? bb3 : bb2, bb3end);
894   bb4 = e34->dest;
895   bb4->count = all;
896
897   e12->flags &= ~EDGE_FALLTHRU;
898   e12->flags |= EDGE_FALSE_VALUE;
899   e12->probability = REG_BR_PROB_BASE - prob1;
900   e12->count = all - count1;
901
902   e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
903   e14->probability = prob1;
904   e14->count = count1;
905
906   if (ncounts)  /* Assumed to be 0 or 1.  */
907     {
908       e23->flags &= ~EDGE_FALLTHRU;
909       e23->flags |= EDGE_FALSE_VALUE;
910       e23->count = all - count1 - count2;
911       e23->probability = REG_BR_PROB_BASE - prob2;
912
913       e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE);
914       e24->probability = prob2;
915       e24->count = count2;
916     }
917
918   e34->probability = REG_BR_PROB_BASE;
919   e34->count = all - count1 - count2;
920
921   return result;
922 }
923
924 /* Do transforms 3) and 4) on INSN if applicable.  */
925 static bool
926 tree_mod_subtract_transform (tree stmt)
927 {
928   histogram_value histogram;
929   enum tree_code code;
930   gcov_type count, wrong_values, all;
931   tree modify, op, op1, op2, result, value;
932   int prob1, prob2;
933   unsigned int i, steps;
934   gcov_type count1, count2;
935
936   modify = stmt;
937   if (TREE_CODE (stmt) == RETURN_EXPR
938       && TREE_OPERAND (stmt, 0)
939       && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
940     modify = TREE_OPERAND (stmt, 0);
941   if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
942     return false;
943   op = GIMPLE_STMT_OPERAND (modify, 1);
944   if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
945     return false;
946   code = TREE_CODE (op);
947   
948   if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (TREE_TYPE (op)))
949     return false;
950
951   op1 = TREE_OPERAND (op, 0);
952   op2 = TREE_OPERAND (op, 1);
953
954   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
955   if (!histogram)
956     return false;
957
958   value = histogram->hvalue.value;
959   all = 0;
960   wrong_values = 0;
961   for (i = 0; i < histogram->hdata.intvl.steps; i++)
962     all += histogram->hvalue.counters[i];
963
964   wrong_values += histogram->hvalue.counters[i];
965   wrong_values += histogram->hvalue.counters[i+1];
966   steps = histogram->hdata.intvl.steps;
967   all += wrong_values;
968   count1 = histogram->hvalue.counters[0];
969   count2 = histogram->hvalue.counters[1];
970
971   /* Compute probability of taking the optimal path.  */
972   if (check_counter (stmt, "interval", all, bb_for_stmt (stmt)->count))
973     {
974       gimple_remove_histogram_value (cfun, stmt, histogram);
975       return false;
976     }
977
978   /* We require that we use just subtractions in at least 50% of all
979      evaluations.  */
980   count = 0;
981   for (i = 0; i < histogram->hdata.intvl.steps; i++)
982     {
983       count += histogram->hvalue.counters[i];
984       if (count * 2 >= all)
985         break;
986     }
987   if (i == steps
988       || !maybe_hot_bb_p (bb_for_stmt (stmt)))
989     return false;
990
991   gimple_remove_histogram_value (cfun, stmt, histogram);
992   if (dump_file)
993     {
994       fprintf (dump_file, "Mod subtract transformation on insn ");
995       print_generic_stmt (dump_file, stmt, TDF_SLIM);
996     }
997
998   /* Compute probability of taking the optimal path(s).  */
999   prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all;
1000   prob2 = (count2 * REG_BR_PROB_BASE + all / 2) / all;
1001
1002   /* In practice, "steps" is always 2.  This interface reflects this,
1003      and will need to be changed if "steps" can change.  */
1004   result = tree_mod_subtract (stmt, op, op1, op2, prob1, prob2, i,
1005                               count1, count2, all);
1006
1007   GIMPLE_STMT_OPERAND (modify, 1) = result;
1008
1009   return true;
1010 }
1011
1012 static struct cgraph_node** pid_map = NULL;
1013
1014 /* Initialize map of pids (pid -> cgraph node) */
1015
1016 static void 
1017 init_pid_map (void)
1018 {
1019   struct cgraph_node *n;
1020
1021   if (pid_map != NULL)
1022     return;
1023
1024   pid_map 
1025     = (struct cgraph_node**) xmalloc (sizeof (struct cgraph_node*) * cgraph_max_pid);
1026
1027   for (n = cgraph_nodes; n; n = n->next)
1028     {
1029       if (n->pid != -1)
1030         pid_map [n->pid] = n;
1031     }
1032 }
1033
1034 /* Return cgraph node for function with pid */
1035
1036 static inline struct cgraph_node*
1037 find_func_by_pid (int   pid)
1038 {
1039   init_pid_map ();
1040
1041   return pid_map [pid];
1042 }
1043
1044 /* Do transformation
1045
1046   if (actual_callee_addres == addres_of_most_common_function/method)
1047     do direct call
1048   else
1049     old call
1050  */
1051
1052 static tree
1053 tree_ic (tree stmt, tree call, struct cgraph_node* direct_call, 
1054          int prob, gcov_type count, gcov_type all)
1055 {
1056   tree stmt1, stmt2, stmt3;
1057   tree tmp1, tmpv, tmp;
1058   tree label_decl1 = create_artificial_label ();
1059   tree label_decl2 = create_artificial_label ();
1060   tree label1, label2;
1061   tree bb1end, bb2end, bb3end;
1062   tree new_call;
1063   basic_block bb, bb2, bb3, bb4;
1064   tree optype = build_pointer_type (void_type_node);
1065   edge e12, e13, e23, e24, e34;
1066   block_stmt_iterator bsi;
1067   int region;
1068
1069   bb = bb_for_stmt (stmt);
1070   bsi = bsi_for_stmt (stmt);
1071
1072   tmpv = create_tmp_var (optype, "PROF");
1073   tmp1 = create_tmp_var (optype, "PROF");
1074   stmt1 = build_gimple_modify_stmt (tmpv, 
1075                                     unshare_expr (CALL_EXPR_FN (call)));
1076   tmp = fold_convert (optype, build_addr (direct_call->decl, 
1077                                           current_function_decl));
1078   stmt2 = build_gimple_modify_stmt (tmp1, tmp);
1079   stmt3 = build3 (COND_EXPR, void_type_node,
1080                   build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
1081                   NULL_TREE, NULL_TREE);
1082   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
1083   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
1084   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
1085   bb1end = stmt3;
1086
1087   label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
1088   stmt1 = unshare_expr (stmt);
1089   new_call = get_call_expr_in (stmt1);
1090   CALL_EXPR_FN (new_call) = build_addr (direct_call->decl, 
1091                                         current_function_decl);
1092   bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
1093   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
1094   bb2end = stmt1;
1095
1096   label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
1097   bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
1098   bb3end = stmt;
1099
1100   /* Fix CFG. */
1101   /* Edge e23 connects bb2 to bb3, etc. */
1102   e12 = split_block (bb, bb1end);
1103   bb2 = e12->dest;
1104   bb2->count = count;
1105   e23 = split_block (bb2, bb2end);
1106   bb3 = e23->dest;
1107   bb3->count = all - count;
1108   e34 = split_block (bb3, bb3end);
1109   bb4 = e34->dest;
1110   bb4->count = all;
1111
1112   e12->flags &= ~EDGE_FALLTHRU;
1113   e12->flags |= EDGE_FALSE_VALUE;
1114   e12->probability = prob;
1115   e12->count = count;
1116
1117   e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
1118   e13->probability = REG_BR_PROB_BASE - prob;
1119   e13->count = all - count;
1120
1121   remove_edge (e23);
1122   
1123   e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
1124   e24->probability = REG_BR_PROB_BASE;
1125   e24->count = count;
1126   e34->probability = REG_BR_PROB_BASE;
1127   e34->count = all - count;
1128
1129   /* Fix eh edges */
1130   region = lookup_stmt_eh_region (stmt);
1131   if (region >=0 && tree_could_throw_p (stmt1))
1132     {
1133       add_stmt_to_eh_region (stmt1, region);
1134       make_eh_edges (stmt1);
1135     }
1136
1137   if (region >=0 && tree_could_throw_p (stmt))
1138     {
1139       tree_purge_dead_eh_edges (bb4);
1140       make_eh_edges (stmt);
1141     }
1142
1143   return stmt1;
1144 }
1145
1146 /*
1147   For every checked indirect/virtual call determine if most common pid of
1148   function/class method has probability more than 50%. If yes modify code of
1149   this call to:
1150  */
1151
1152 static bool
1153 tree_ic_transform (tree stmt)
1154 {
1155   histogram_value histogram;
1156   gcov_type val, count, all;
1157   int prob;
1158   tree call, callee, modify;
1159   struct cgraph_node *direct_call;
1160   
1161   call = get_call_expr_in (stmt);
1162
1163   if (!call || TREE_CODE (call) != CALL_EXPR)
1164     return false;
1165
1166   callee = CALL_EXPR_FN (call);
1167
1168   if (TREE_CODE (callee) == ADDR_EXPR)
1169     return false;
1170
1171   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
1172   if (!histogram)
1173     return false;
1174
1175   val = histogram->hvalue.counters [0];
1176   count = histogram->hvalue.counters [1];
1177   all = histogram->hvalue.counters [2];
1178   gimple_remove_histogram_value (cfun, stmt, histogram);
1179
1180   if (4 * count <= 3 * all)
1181     return false;
1182
1183   prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1184   direct_call = find_func_by_pid ((int)val);
1185
1186   if (direct_call == NULL)
1187     return false;
1188
1189   modify = tree_ic (stmt, call, direct_call, prob, count, all);
1190
1191   if (dump_file)
1192     {
1193       fprintf (dump_file, "Indirect call -> direct call ");
1194       print_generic_expr (dump_file, call, TDF_SLIM);
1195       fprintf (dump_file, "=> ");
1196       print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
1197       fprintf (dump_file, " transformation on insn ");
1198       print_generic_stmt (dump_file, stmt, TDF_SLIM);
1199       fprintf (dump_file, " to ");
1200       print_generic_stmt (dump_file, modify, TDF_SLIM);
1201     }
1202
1203   return true;
1204 }
1205
1206 /* Return true if the stringop CALL with FNDECL shall be profiled.  */
1207 static bool
1208 interesting_stringop_to_profile_p (tree fndecl, tree call)
1209 {
1210   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
1211
1212   if (fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_MEMCPY
1213       && fcode != BUILT_IN_BZERO)
1214     return false;
1215
1216   switch (fcode)
1217     {
1218      case BUILT_IN_MEMCPY:
1219      case BUILT_IN_MEMPCPY:
1220        return validate_arglist (call,
1221                                 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
1222                                 VOID_TYPE);
1223      case BUILT_IN_MEMSET:
1224        return validate_arglist (call,
1225                                 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE,
1226                                 VOID_TYPE);
1227      case BUILT_IN_BZERO:
1228        return validate_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1229                                 VOID_TYPE);
1230      default:
1231        gcc_unreachable ();
1232     }
1233 }
1234
1235 /* Convert   stringop (..., size)
1236    into 
1237    if (size == VALUE)
1238      stringop (...., VALUE);
1239    else
1240      stringop (...., size);
1241    assuming constant propagation of VALUE will happen later.
1242 */
1243 static void
1244 tree_stringop_fixed_value (tree stmt, tree value, int prob, gcov_type count,
1245                            gcov_type all)
1246 {
1247   tree stmt1, stmt2, stmt3;
1248   tree tmp1, tmpv;
1249   tree label_decl1 = create_artificial_label ();
1250   tree label_decl2 = create_artificial_label ();
1251   tree label1, label2;
1252   tree bb1end, bb2end;
1253   basic_block bb, bb2, bb3, bb4;
1254   edge e12, e13, e23, e24, e34;
1255   block_stmt_iterator bsi;
1256   tree call = get_call_expr_in (stmt);
1257   tree blck_size = CALL_EXPR_ARG (call, 2);
1258   tree optype = TREE_TYPE (blck_size);
1259   int region;
1260
1261   bb = bb_for_stmt (stmt);
1262   bsi = bsi_for_stmt (stmt);
1263
1264   if (bsi_end_p (bsi))
1265     {
1266       edge_iterator ei;
1267       for (ei = ei_start (bb->succs); (e34 = ei_safe_edge (ei)); )
1268         if (!e34->flags & EDGE_ABNORMAL)
1269           break;
1270     }
1271   else
1272     {
1273       e34 = split_block (bb, stmt);
1274       bsi = bsi_for_stmt (stmt);
1275     }
1276   bb4 = e34->dest;
1277
1278   tmpv = create_tmp_var (optype, "PROF");
1279   tmp1 = create_tmp_var (optype, "PROF");
1280   stmt1 = build_gimple_modify_stmt (tmpv, fold_convert (optype, value));
1281   stmt2 = build_gimple_modify_stmt (tmp1, blck_size);
1282   stmt3 = build3 (COND_EXPR, void_type_node,
1283             build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
1284             NULL_TREE, NULL_TREE);
1285   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
1286   bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
1287   bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
1288   bb1end = stmt3;
1289
1290   label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
1291   stmt1 = unshare_expr (stmt);
1292   call = get_call_expr_in (stmt1);
1293   CALL_EXPR_ARG (call, 2) = value;
1294   bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
1295   bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
1296   region = lookup_stmt_eh_region (stmt);
1297   if (region >= 0)
1298     add_stmt_to_eh_region (stmt1, region);
1299   bb2end = stmt1;
1300   label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
1301   bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
1302
1303   /* Fix CFG. */
1304   /* Edge e23 connects bb2 to bb3, etc. */
1305   e12 = split_block (bb, bb1end);
1306   bb2 = e12->dest;
1307   bb2->count = count;
1308   e23 = split_block (bb2, bb2end);
1309   bb3 = e23->dest;
1310   bb3->count = all - count;
1311
1312   e12->flags &= ~EDGE_FALLTHRU;
1313   e12->flags |= EDGE_FALSE_VALUE;
1314   e12->probability = prob;
1315   e12->count = count;
1316
1317   e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
1318   e13->probability = REG_BR_PROB_BASE - prob;
1319   e13->count = all - count;
1320
1321   remove_edge (e23);
1322   
1323   e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
1324   e24->probability = REG_BR_PROB_BASE;
1325   e24->count = count;
1326
1327   e34->probability = REG_BR_PROB_BASE;
1328   e34->count = all - count;
1329 }
1330
1331 /* Find values inside STMT for that we want to measure histograms for
1332    division/modulo optimization.  */
1333 static bool
1334 tree_stringops_transform (block_stmt_iterator *bsi)
1335 {
1336   tree stmt = bsi_stmt (*bsi);
1337   tree call = get_call_expr_in (stmt);
1338   tree fndecl;
1339   tree blck_size;
1340   enum built_in_function fcode;
1341   histogram_value histogram;
1342   gcov_type count, all, val;
1343   tree value;
1344   tree dest, src;
1345   unsigned int dest_align, src_align;
1346   int prob;
1347   tree tree_val;
1348
1349   if (!call)
1350     return false;
1351   fndecl = get_callee_fndecl (call);
1352   if (!fndecl)
1353     return false;
1354   fcode = DECL_FUNCTION_CODE (fndecl);
1355   if (!interesting_stringop_to_profile_p (fndecl, call))
1356     return false;
1357
1358   if (fcode == BUILT_IN_BZERO)
1359     blck_size = CALL_EXPR_ARG (call, 1);
1360   else
1361     blck_size = CALL_EXPR_ARG (call, 2);
1362   if (TREE_CODE (blck_size) == INTEGER_CST)
1363     return false;
1364
1365   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
1366   if (!histogram)
1367     return false;
1368   value = histogram->hvalue.value;
1369   val = histogram->hvalue.counters[0];
1370   count = histogram->hvalue.counters[1];
1371   all = histogram->hvalue.counters[2];
1372   gimple_remove_histogram_value (cfun, stmt, histogram);
1373   /* We require that count is at least half of all; this means
1374      that for the transformation to fire the value must be constant
1375      at least 80% of time.  */
1376   if ((6 * count / 5) < all || !maybe_hot_bb_p (bb_for_stmt (stmt)))
1377     return false;
1378   if (check_counter (stmt, "value", all, bb_for_stmt (stmt)->count))
1379     return false;
1380   prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1381   dest = CALL_EXPR_ARG (call, 0);
1382   dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1383   switch (fcode)
1384     {
1385     case BUILT_IN_MEMCPY:
1386     case BUILT_IN_MEMPCPY:
1387       src = CALL_EXPR_ARG (call, 1);
1388       src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1389       if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
1390         return false;
1391       break;
1392     case BUILT_IN_MEMSET:
1393       if (!can_store_by_pieces (val, builtin_memset_read_str,
1394                                 CALL_EXPR_ARG (call, 1),
1395                                 dest_align, true))
1396         return false;
1397       break;
1398     case BUILT_IN_BZERO:
1399       if (!can_store_by_pieces (val, builtin_memset_read_str,
1400                                 integer_zero_node,
1401                                 dest_align, true))
1402         return false;
1403       break;
1404     default:
1405       gcc_unreachable ();
1406     }
1407   tree_val = build_int_cst_wide (get_gcov_type (),
1408                                  (unsigned HOST_WIDE_INT) val,
1409                                  val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
1410   if (dump_file)
1411     {
1412       fprintf (dump_file, "Single value %i stringop transformation on ",
1413                (int)val);
1414       print_generic_stmt (dump_file, stmt, TDF_SLIM);
1415     }
1416   tree_stringop_fixed_value (stmt, tree_val, prob, count, all);
1417   
1418   return true;
1419 }
1420
1421 void
1422 stringop_block_profile (tree stmt, unsigned int *expected_align,
1423                         HOST_WIDE_INT *expected_size)
1424 {
1425   histogram_value histogram;
1426   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
1427   if (!histogram)
1428     *expected_size = -1;
1429   else if (!histogram->hvalue.counters[1])
1430     {
1431       *expected_size = -1;
1432       gimple_remove_histogram_value (cfun, stmt, histogram);
1433     }
1434   else
1435     {
1436       gcov_type size;
1437       size = ((histogram->hvalue.counters[0]
1438               + histogram->hvalue.counters[1] / 2)
1439                / histogram->hvalue.counters[1]);
1440       /* Even if we can hold bigger value in SIZE, INT_MAX
1441          is safe "infinity" for code generation strategies.  */
1442       if (size > INT_MAX)
1443         size = INT_MAX;
1444       *expected_size = size;
1445       gimple_remove_histogram_value (cfun, stmt, histogram);
1446     }
1447   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
1448   if (!histogram)
1449     *expected_align = 0;
1450   else if (!histogram->hvalue.counters[0])
1451     {
1452       gimple_remove_histogram_value (cfun, stmt, histogram);
1453       *expected_align = 0;
1454     }
1455   else
1456     {
1457       gcov_type count;
1458       int alignment;
1459
1460       count = histogram->hvalue.counters[0];
1461       alignment = 1;
1462       while (!(count & alignment)
1463              && (alignment * 2 * BITS_PER_UNIT))
1464         alignment <<= 1;
1465       *expected_align = alignment * BITS_PER_UNIT;
1466       gimple_remove_histogram_value (cfun, stmt, histogram);
1467     }
1468 }
1469
1470 struct value_prof_hooks {
1471   /* Find list of values for which we want to measure histograms.  */
1472   void (*find_values_to_profile) (histogram_values *);
1473
1474   /* Identify and exploit properties of values that are hard to analyze
1475      statically.  See value-prof.c for more detail.  */
1476   bool (*value_profile_transformations) (void);  
1477 };
1478 \f
1479 /* Find values inside STMT for that we want to measure histograms for
1480    division/modulo optimization.  */
1481 static void
1482 tree_divmod_values_to_profile (tree stmt, histogram_values *values)
1483 {
1484   tree assign, lhs, rhs, divisor, op0, type;
1485   histogram_value hist;
1486
1487   if (TREE_CODE (stmt) == RETURN_EXPR)
1488     assign = TREE_OPERAND (stmt, 0);
1489   else
1490     assign = stmt;
1491
1492   if (!assign
1493       || TREE_CODE (assign) != GIMPLE_MODIFY_STMT)
1494     return;
1495   lhs = GIMPLE_STMT_OPERAND (assign, 0);
1496   type = TREE_TYPE (lhs);
1497   if (!INTEGRAL_TYPE_P (type))
1498     return;
1499
1500   rhs = GIMPLE_STMT_OPERAND (assign, 1);
1501   switch (TREE_CODE (rhs))
1502     {
1503     case TRUNC_DIV_EXPR:
1504     case TRUNC_MOD_EXPR:
1505       divisor = TREE_OPERAND (rhs, 1);
1506       op0 = TREE_OPERAND (rhs, 0);
1507
1508       VEC_reserve (histogram_value, heap, *values, 3);
1509
1510       if (is_gimple_reg (divisor))
1511         /* Check for the case where the divisor is the same value most
1512            of the time.  */
1513         VEC_quick_push (histogram_value, *values,
1514                         gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE,
1515                                                       stmt, divisor));
1516
1517       /* For mod, check whether it is not often a noop (or replaceable by
1518          a few subtractions).  */
1519       if (TREE_CODE (rhs) == TRUNC_MOD_EXPR
1520           && TYPE_UNSIGNED (type))
1521         {
1522           tree val;
1523           /* Check for a special case where the divisor is power of 2.  */
1524           VEC_quick_push (histogram_value, *values,
1525                           gimple_alloc_histogram_value (cfun, HIST_TYPE_POW2,
1526                                                         stmt, divisor));
1527
1528           val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
1529           hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
1530                                                stmt, val);
1531           hist->hdata.intvl.int_start = 0;
1532           hist->hdata.intvl.steps = 2;
1533           VEC_quick_push (histogram_value, *values, hist);
1534         }
1535       return;
1536
1537     default:
1538       return;
1539     }
1540 }
1541
1542 /* Find calls inside STMT for that we want to measure histograms for 
1543    indirect/virtual call optimization. */ 
1544
1545 static void
1546 tree_indirect_call_to_profile (tree stmt, histogram_values *values)
1547 {
1548   tree                  call;
1549   tree                  callee;
1550
1551   call = get_call_expr_in (stmt);
1552
1553   if (!call || TREE_CODE (call) != CALL_EXPR)
1554     return;
1555
1556   callee = CALL_EXPR_FN (call);
1557   
1558   if (TREE_CODE (callee) == ADDR_EXPR)
1559     return;
1560
1561   VEC_reserve (histogram_value, heap, *values, 3);
1562
1563   VEC_quick_push (histogram_value, *values, 
1564                   gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
1565                                                 stmt, callee));
1566
1567   return;
1568 }
1569
1570 /* Find values inside STMT for that we want to measure histograms for
1571    string operations.  */
1572 static void
1573 tree_stringops_values_to_profile (tree stmt, histogram_values *values)
1574 {
1575   tree call = get_call_expr_in (stmt);
1576   tree fndecl;
1577   tree blck_size;
1578   tree dest;
1579   enum built_in_function fcode;
1580
1581   if (!call)
1582     return;
1583   fndecl = get_callee_fndecl (call);
1584   if (!fndecl)
1585     return;
1586   fcode = DECL_FUNCTION_CODE (fndecl);
1587
1588   if (!interesting_stringop_to_profile_p (fndecl, call))
1589     return;
1590
1591   dest = CALL_EXPR_ARG (call, 0);
1592   if (fcode == BUILT_IN_BZERO)
1593     blck_size = CALL_EXPR_ARG (call, 1);
1594   else
1595     blck_size = CALL_EXPR_ARG (call, 2);
1596
1597   if (TREE_CODE (blck_size) != INTEGER_CST)
1598     {
1599       VEC_safe_push (histogram_value, heap, *values,
1600                      gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE,
1601                                                    stmt, blck_size));
1602       VEC_safe_push (histogram_value, heap, *values,
1603                      gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
1604                                                    stmt, blck_size));
1605     }
1606   if (TREE_CODE (blck_size) != INTEGER_CST)
1607     VEC_safe_push (histogram_value, heap, *values,
1608                    gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
1609                                                  stmt, dest));
1610 }
1611
1612 /* Find values inside STMT for that we want to measure histograms and adds
1613    them to list VALUES.  */
1614
1615 static void
1616 tree_values_to_profile (tree stmt, histogram_values *values)
1617 {
1618   if (flag_value_profile_transformations)
1619     {
1620       tree_divmod_values_to_profile (stmt, values);
1621       tree_stringops_values_to_profile (stmt, values);
1622       tree_indirect_call_to_profile (stmt, values);
1623     }
1624 }
1625
1626 static void
1627 tree_find_values_to_profile (histogram_values *values)
1628 {
1629   basic_block bb;
1630   block_stmt_iterator bsi;
1631   unsigned i;
1632   histogram_value hist = NULL;
1633
1634   *values = NULL;
1635   FOR_EACH_BB (bb)
1636     for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1637       tree_values_to_profile (bsi_stmt (bsi), values);
1638   
1639   for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++)
1640     {
1641       switch (hist->type)
1642         {
1643         case HIST_TYPE_INTERVAL:
1644           hist->n_counters = hist->hdata.intvl.steps + 2;
1645           break;
1646
1647         case HIST_TYPE_POW2:
1648           hist->n_counters = 2;
1649           break;
1650
1651         case HIST_TYPE_SINGLE_VALUE:
1652           hist->n_counters = 3;
1653           break;
1654
1655         case HIST_TYPE_CONST_DELTA:
1656           hist->n_counters = 4;
1657           break;
1658
1659         case HIST_TYPE_INDIR_CALL:
1660           hist->n_counters = 3;
1661           break;
1662
1663         case HIST_TYPE_AVERAGE:
1664           hist->n_counters = 2;
1665           break;
1666
1667         case HIST_TYPE_IOR:
1668           hist->n_counters = 1;
1669           break;
1670
1671         default:
1672           gcc_unreachable ();
1673         }
1674       if (dump_file)
1675         {
1676           fprintf (dump_file, "Stmt ");
1677           print_generic_expr (dump_file, hist->hvalue.stmt, TDF_SLIM);
1678           dump_histogram_value (dump_file, hist);
1679         }
1680     }
1681 }
1682
1683 static struct value_prof_hooks tree_value_prof_hooks = {
1684   tree_find_values_to_profile,
1685   tree_value_profile_transformations
1686 };
1687
1688 void
1689 tree_register_value_prof_hooks (void)
1690 {
1691   gcc_assert (current_ir_type () == IR_GIMPLE);
1692   value_prof_hooks = &tree_value_prof_hooks;
1693 }
1694 \f
1695 /* IR-independent entry points.  */
1696 void
1697 find_values_to_profile (histogram_values *values)
1698 {
1699   (value_prof_hooks->find_values_to_profile) (values);
1700 }
1701
1702 bool
1703 value_profile_transformations (void)
1704 {
1705   return (value_prof_hooks->value_profile_transformations) ();
1706 }
1707 \f
1708