1 /* Transformations based on profile information for values.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
22 #include "coretypes.h"
26 #include "hard-reg-set.h"
27 #include "basic-block.h"
28 #include "value-prof.h"
31 #include "insn-config.h"
36 #include "tree-flow.h"
37 #include "tree-flow-inline.h"
38 #include "diagnostic.h"
44 #include "tree-pass.h"
46 #include "pointer-set.h"
48 static struct value_prof_hooks
*value_prof_hooks
;
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):
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
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
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.
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. */
80 static tree
gimple_divmod_fixed_value (gimple
, tree
, int, gcov_type
, gcov_type
);
81 static tree
gimple_mod_pow2 (gimple
, int, gcov_type
, gcov_type
);
82 static tree
gimple_mod_subtract (gimple
, int, int, int, gcov_type
, gcov_type
,
84 static bool gimple_divmod_fixed_value_transform (gimple
);
85 static bool gimple_mod_pow2_value_transform (gimple
);
86 static bool gimple_mod_subtract_transform (gimple
);
87 static bool gimple_stringops_transform (gimple_stmt_iterator
*);
88 static bool gimple_ic_transform (gimple
);
90 /* Allocate histogram value. */
92 static histogram_value
93 gimple_alloc_histogram_value (struct function
*fun ATTRIBUTE_UNUSED
,
94 enum hist_type type
, gimple stmt
, tree value
)
96 histogram_value hist
= (histogram_value
) xcalloc (1, sizeof (*hist
));
97 hist
->hvalue
.value
= value
;
98 hist
->hvalue
.stmt
= stmt
;
103 /* Hash value for histogram. */
106 histogram_hash (const void *x
)
108 return htab_hash_pointer (((const_histogram_value
)x
)->hvalue
.stmt
);
111 /* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */
114 histogram_eq (const void *x
, const void *y
)
116 return ((const_histogram_value
) x
)->hvalue
.stmt
== (gimple
)y
;
119 /* Set histogram for STMT. */
122 set_histogram_value (struct function
*fun
, gimple stmt
, histogram_value hist
)
125 if (!hist
&& !VALUE_HISTOGRAMS (fun
))
127 if (!VALUE_HISTOGRAMS (fun
))
128 VALUE_HISTOGRAMS (fun
) = htab_create (1, histogram_hash
,
130 loc
= htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun
), stmt
,
131 htab_hash_pointer (stmt
),
132 hist
? INSERT
: NO_INSERT
);
136 htab_clear_slot (VALUE_HISTOGRAMS (fun
), loc
);
142 /* Get histogram list for STMT. */
145 gimple_histogram_value (struct function
*fun
, gimple stmt
)
147 if (!VALUE_HISTOGRAMS (fun
))
149 return htab_find_with_hash (VALUE_HISTOGRAMS (fun
), stmt
,
150 htab_hash_pointer (stmt
));
153 /* Add histogram for STMT. */
156 gimple_add_histogram_value (struct function
*fun
, gimple stmt
,
157 histogram_value hist
)
159 hist
->hvalue
.next
= gimple_histogram_value (fun
, stmt
);
160 set_histogram_value (fun
, stmt
, hist
);
164 /* Remove histogram HIST from STMT's histogram list. */
167 gimple_remove_histogram_value (struct function
*fun
, gimple stmt
,
168 histogram_value hist
)
170 histogram_value hist2
= gimple_histogram_value (fun
, stmt
);
173 set_histogram_value (fun
, stmt
, hist
->hvalue
.next
);
177 while (hist2
->hvalue
.next
!= hist
)
178 hist2
= hist2
->hvalue
.next
;
179 hist2
->hvalue
.next
= hist
->hvalue
.next
;
181 free (hist
->hvalue
.counters
);
182 #ifdef ENABLE_CHECKING
183 memset (hist
, 0xab, sizeof (*hist
));
189 /* Lookup histogram of type TYPE in the STMT. */
192 gimple_histogram_value_of_type (struct function
*fun
, gimple stmt
,
195 histogram_value hist
;
196 for (hist
= gimple_histogram_value (fun
, stmt
); hist
;
197 hist
= hist
->hvalue
.next
)
198 if (hist
->type
== type
)
203 /* Dump information about HIST to DUMP_FILE. */
206 dump_histogram_value (FILE *dump_file
, histogram_value hist
)
210 case HIST_TYPE_INTERVAL
:
211 fprintf (dump_file
, "Interval counter range %d -- %d",
212 hist
->hdata
.intvl
.int_start
,
213 (hist
->hdata
.intvl
.int_start
214 + hist
->hdata
.intvl
.steps
- 1));
215 if (hist
->hvalue
.counters
)
218 fprintf(dump_file
, " [");
219 for (i
= 0; i
< hist
->hdata
.intvl
.steps
; i
++)
220 fprintf (dump_file
, " %d:"HOST_WIDEST_INT_PRINT_DEC
,
221 hist
->hdata
.intvl
.int_start
+ i
,
222 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[i
]);
223 fprintf (dump_file
, " ] outside range:"HOST_WIDEST_INT_PRINT_DEC
,
224 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[i
]);
226 fprintf (dump_file
, ".\n");
230 fprintf (dump_file
, "Pow2 counter ");
231 if (hist
->hvalue
.counters
)
233 fprintf (dump_file
, "pow2:"HOST_WIDEST_INT_PRINT_DEC
234 " nonpow2:"HOST_WIDEST_INT_PRINT_DEC
,
235 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[0],
236 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[1]);
238 fprintf (dump_file
, ".\n");
241 case HIST_TYPE_SINGLE_VALUE
:
242 fprintf (dump_file
, "Single value ");
243 if (hist
->hvalue
.counters
)
245 fprintf (dump_file
, "value:"HOST_WIDEST_INT_PRINT_DEC
246 " match:"HOST_WIDEST_INT_PRINT_DEC
247 " wrong:"HOST_WIDEST_INT_PRINT_DEC
,
248 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[0],
249 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[1],
250 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[2]);
252 fprintf (dump_file
, ".\n");
255 case HIST_TYPE_AVERAGE
:
256 fprintf (dump_file
, "Average value ");
257 if (hist
->hvalue
.counters
)
259 fprintf (dump_file
, "sum:"HOST_WIDEST_INT_PRINT_DEC
260 " times:"HOST_WIDEST_INT_PRINT_DEC
,
261 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[0],
262 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[1]);
264 fprintf (dump_file
, ".\n");
268 fprintf (dump_file
, "IOR value ");
269 if (hist
->hvalue
.counters
)
271 fprintf (dump_file
, "ior:"HOST_WIDEST_INT_PRINT_DEC
,
272 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[0]);
274 fprintf (dump_file
, ".\n");
277 case HIST_TYPE_CONST_DELTA
:
278 fprintf (dump_file
, "Constant delta ");
279 if (hist
->hvalue
.counters
)
281 fprintf (dump_file
, "value:"HOST_WIDEST_INT_PRINT_DEC
282 " match:"HOST_WIDEST_INT_PRINT_DEC
283 " wrong:"HOST_WIDEST_INT_PRINT_DEC
,
284 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[0],
285 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[1],
286 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[2]);
288 fprintf (dump_file
, ".\n");
290 case HIST_TYPE_INDIR_CALL
:
291 fprintf (dump_file
, "Indirect call ");
292 if (hist
->hvalue
.counters
)
294 fprintf (dump_file
, "value:"HOST_WIDEST_INT_PRINT_DEC
295 " match:"HOST_WIDEST_INT_PRINT_DEC
296 " all:"HOST_WIDEST_INT_PRINT_DEC
,
297 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[0],
298 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[1],
299 (HOST_WIDEST_INT
) hist
->hvalue
.counters
[2]);
301 fprintf (dump_file
, ".\n");
306 /* Dump all histograms attached to STMT to DUMP_FILE. */
309 dump_histograms_for_stmt (struct function
*fun
, FILE *dump_file
, gimple stmt
)
311 histogram_value hist
;
312 for (hist
= gimple_histogram_value (fun
, stmt
); hist
; hist
= hist
->hvalue
.next
)
313 dump_histogram_value (dump_file
, hist
);
316 /* Remove all histograms associated with STMT. */
319 gimple_remove_stmt_histograms (struct function
*fun
, gimple stmt
)
322 while ((val
= gimple_histogram_value (fun
, stmt
)) != NULL
)
323 gimple_remove_histogram_value (fun
, stmt
, val
);
326 /* Duplicate all histograms associates with OSTMT to STMT. */
329 gimple_duplicate_stmt_histograms (struct function
*fun
, gimple stmt
,
330 struct function
*ofun
, gimple ostmt
)
333 for (val
= gimple_histogram_value (ofun
, ostmt
); val
!= NULL
; val
= val
->hvalue
.next
)
335 histogram_value
new = gimple_alloc_histogram_value (fun
, val
->type
, NULL
, NULL
);
336 memcpy (new, val
, sizeof (*val
));
337 new->hvalue
.stmt
= stmt
;
338 new->hvalue
.counters
= xmalloc (sizeof (*new->hvalue
.counters
) * new->n_counters
);
339 memcpy (new->hvalue
.counters
, val
->hvalue
.counters
, sizeof (*new->hvalue
.counters
) * new->n_counters
);
340 gimple_add_histogram_value (fun
, stmt
, new);
344 static bool error_found
= false;
346 /* Helper function for verify_histograms. For each histogram reachable via htab
347 walk verify that it was reached via statement walk. */
350 visit_hist (void **slot
, void *data
)
352 struct pointer_set_t
*visited
= (struct pointer_set_t
*) data
;
353 histogram_value hist
= *(histogram_value
*) slot
;
354 if (!pointer_set_contains (visited
, hist
))
356 error ("Dead histogram");
357 dump_histogram_value (stderr
, hist
);
358 debug_gimple_stmt (hist
->hvalue
.stmt
);
365 /* Verify sanity of the histograms. */
368 verify_histograms (void)
371 gimple_stmt_iterator gsi
;
372 histogram_value hist
;
373 struct pointer_set_t
*visited_hists
;
376 visited_hists
= pointer_set_create ();
378 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
380 gimple stmt
= gsi_stmt (gsi
);
382 for (hist
= gimple_histogram_value (cfun
, stmt
); hist
;
383 hist
= hist
->hvalue
.next
)
385 if (hist
->hvalue
.stmt
!= stmt
)
387 error ("Histogram value statement does not correspond to "
388 "the statement it is associated with");
389 debug_gimple_stmt (stmt
);
390 dump_histogram_value (stderr
, hist
);
393 pointer_set_insert (visited_hists
, hist
);
396 if (VALUE_HISTOGRAMS (cfun
))
397 htab_traverse (VALUE_HISTOGRAMS (cfun
), visit_hist
, visited_hists
);
398 pointer_set_destroy (visited_hists
);
400 internal_error ("verify_histograms failed");
403 /* Helper function for verify_histograms. For each histogram reachable via htab
404 walk verify that it was reached via statement walk. */
407 free_hist (void **slot
, void *data ATTRIBUTE_UNUSED
)
409 histogram_value hist
= *(histogram_value
*) slot
;
410 free (hist
->hvalue
.counters
);
411 #ifdef ENABLE_CHECKING
412 memset (hist
, 0xab, sizeof (*hist
));
419 free_histograms (void)
421 if (VALUE_HISTOGRAMS (cfun
))
423 htab_traverse (VALUE_HISTOGRAMS (cfun
), free_hist
, NULL
);
424 htab_delete (VALUE_HISTOGRAMS (cfun
));
425 VALUE_HISTOGRAMS (cfun
) = NULL
;
430 /* The overall number of invocations of the counter should match
431 execution count of basic block. Report it as error rather than
432 internal error as it might mean that user has misused the profile
436 check_counter (gimple stmt
, const char *name
, gcov_type all
, gcov_type bb_count
)
441 locus
= (stmt
!= NULL
)
442 ? gimple_location (stmt
)
443 : DECL_SOURCE_LOCATION (current_function_decl
);
444 error ("%HCorrupted value profile: %s profiler overall count (%d) "
445 "does not match BB count (%d)", &locus
, name
, (int)all
,
454 /* GIMPLE based transformations. */
457 gimple_value_profile_transformations (void)
460 gimple_stmt_iterator gsi
;
461 bool changed
= false;
465 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
467 gimple stmt
= gsi_stmt (gsi
);
468 histogram_value th
= gimple_histogram_value (cfun
, stmt
);
474 fprintf (dump_file
, "Trying transformations on stmt ");
475 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
476 dump_histograms_for_stmt (cfun
, dump_file
, stmt
);
479 /* Transformations: */
480 /* The order of things in this conditional controls which
481 transformation is used when more than one is applicable. */
482 /* It is expected that any code added by the transformations
483 will be added before the current statement, and that the
484 current statement remain valid (although possibly
485 modified) upon return. */
486 if (flag_value_profile_transformations
487 && (gimple_mod_subtract_transform (stmt
)
488 || gimple_divmod_fixed_value_transform (stmt
)
489 || gimple_mod_pow2_value_transform (stmt
)
490 || gimple_stringops_transform (&gsi
)
491 || gimple_ic_transform (stmt
)))
493 stmt
= gsi_stmt (gsi
);
495 /* Original statement may no longer be in the same block. */
496 if (bb
!= gimple_bb (stmt
))
498 bb
= gimple_bb (stmt
);
499 gsi
= gsi_for_stmt (stmt
);
514 /* Generate code for transformation 1 (with parent gimple assignment
515 STMT and probability of taking the optimal path PROB, which is
516 equivalent to COUNT/ALL within roundoff error). This generates the
517 result into a temp and returns the temp; it does not replace or
518 alter the original STMT. */
521 gimple_divmod_fixed_value (gimple stmt
, tree value
, int prob
, gcov_type count
,
524 gimple stmt1
, stmt2
, stmt3
, label1
, label2
;
525 tree tmp1
, tmp2
, tmpv
;
526 tree label_decl1
= create_artificial_label ();
527 tree label_decl2
= create_artificial_label ();
528 gimple bb1end
, bb2end
, bb3end
;
529 basic_block bb
, bb2
, bb3
, bb4
;
530 tree optype
, op1
, op2
;
531 edge e12
, e13
, e23
, e24
, e34
;
532 gimple_stmt_iterator gsi
;
534 gcc_assert (gimple_code (stmt
) == GIMPLE_ASSIGN
535 && (gimple_subcode (stmt
) == TRUNC_DIV_EXPR
536 || gimple_subcode (stmt
) == TRUNC_MOD_EXPR
));
538 optype
= TREE_TYPE (gimple_assign_lhs (stmt
));
539 op1
= gimple_assign_rhs1 (stmt
);
540 op2
= gimple_assign_rhs2 (stmt
);
542 bb
= gimple_bb (stmt
);
543 gsi
= gsi_for_stmt (stmt
);
545 tmpv
= create_tmp_var (optype
, "PROF");
546 tmp1
= create_tmp_var (optype
, "PROF");
547 stmt1
= gimple_build_assign (tmpv
, fold_convert (optype
, value
));
548 stmt2
= gimple_build_assign (tmp1
, op2
);
549 stmt3
= gimple_build_cond (NE_EXPR
, tmp1
, tmpv
, NULL_TREE
, NULL_TREE
);
550 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
551 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
552 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
555 tmp2
= create_tmp_var (optype
, "PROF");
556 label1
= gimple_build_label (label_decl1
);
557 stmt1
= gimple_build_assign_with_ops (gimple_subcode (stmt
), tmp2
, op1
, tmpv
);
558 gsi_insert_before (&gsi
, label1
, GSI_SAME_STMT
);
559 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
562 label2
= gimple_build_label (label_decl2
);
563 stmt1
= gimple_build_assign_with_ops (gimple_subcode (stmt
), tmp2
, op1
, op2
);
564 gsi_insert_before (&gsi
, label2
, GSI_SAME_STMT
);
565 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
569 /* Edge e23 connects bb2 to bb3, etc. */
570 e12
= split_block (bb
, bb1end
);
573 e23
= split_block (bb2
, bb2end
);
575 bb3
->count
= all
- count
;
576 e34
= split_block (bb3
, bb3end
);
580 e12
->flags
&= ~EDGE_FALLTHRU
;
581 e12
->flags
|= EDGE_FALSE_VALUE
;
582 e12
->probability
= prob
;
585 e13
= make_edge (bb
, bb3
, EDGE_TRUE_VALUE
);
586 e13
->probability
= REG_BR_PROB_BASE
- prob
;
587 e13
->count
= all
- count
;
591 e24
= make_edge (bb2
, bb4
, EDGE_FALLTHRU
);
592 e24
->probability
= REG_BR_PROB_BASE
;
595 e34
->probability
= REG_BR_PROB_BASE
;
596 e34
->count
= all
- count
;
602 /* Do transform 1) on INSN if applicable. */
605 gimple_divmod_fixed_value_transform (gimple stmt
)
607 histogram_value histogram
;
609 gcov_type val
, count
, all
;
610 tree result
, value
, tree_val
;
613 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
616 if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt
))))
619 code
= gimple_assign_rhs_code (stmt
);
621 if (code
!= TRUNC_DIV_EXPR
&& code
!= TRUNC_MOD_EXPR
)
624 histogram
= gimple_histogram_value_of_type (cfun
, stmt
,
625 HIST_TYPE_SINGLE_VALUE
);
629 value
= histogram
->hvalue
.value
;
630 val
= histogram
->hvalue
.counters
[0];
631 count
= histogram
->hvalue
.counters
[1];
632 all
= histogram
->hvalue
.counters
[2];
633 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
635 /* We require that count is at least half of all; this means
636 that for the transformation to fire the value must be constant
637 at least 50% of time (and 75% gives the guarantee of usage). */
638 if (simple_cst_equal (gimple_assign_rhs2 (stmt
), value
) != 1
640 || !maybe_hot_bb_p (gimple_bb (stmt
)))
643 if (check_counter (stmt
, "value", all
, gimple_bb (stmt
)->count
))
646 /* Compute probability of taking the optimal path. */
647 prob
= (count
* REG_BR_PROB_BASE
+ all
/ 2) / all
;
649 tree_val
= build_int_cst_wide (get_gcov_type (),
650 (unsigned HOST_WIDE_INT
) val
,
651 val
>> (HOST_BITS_PER_WIDE_INT
- 1) >> 1);
652 result
= gimple_divmod_fixed_value (stmt
, tree_val
, prob
, count
, all
);
656 fprintf (dump_file
, "Div/mod by constant ");
657 print_generic_expr (dump_file
, value
, TDF_SLIM
);
658 fprintf (dump_file
, "=");
659 print_generic_expr (dump_file
, tree_val
, TDF_SLIM
);
660 fprintf (dump_file
, " transformation on insn ");
661 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
664 gimple_assign_set_rhs_from_tree (stmt
, result
);
669 /* Generate code for transformation 2 (with parent gimple assign STMT and
670 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
671 within roundoff error). This generates the result into a temp and returns
672 the temp; it does not replace or alter the original STMT. */
674 gimple_mod_pow2 (gimple stmt
, int prob
, gcov_type count
, gcov_type all
)
676 gimple stmt1
, stmt2
, stmt3
, stmt4
;
678 tree label_decl1
= create_artificial_label ();
679 tree label_decl2
= create_artificial_label ();
680 gimple label1
, label2
;
681 gimple bb1end
, bb2end
, bb3end
;
682 basic_block bb
, bb2
, bb3
, bb4
;
683 tree optype
, op1
, op2
;
684 edge e12
, e13
, e23
, e24
, e34
;
685 gimple_stmt_iterator gsi
;
688 gcc_assert (gimple_code (stmt
) == GIMPLE_ASSIGN
689 && gimple_subcode (stmt
) == TRUNC_MOD_EXPR
);
691 optype
= TREE_TYPE (gimple_assign_lhs (stmt
));
692 op1
= gimple_assign_rhs1 (stmt
);
693 op2
= gimple_assign_rhs2 (stmt
);
695 bb
= gimple_bb (stmt
);
696 gsi
= gsi_for_stmt (stmt
);
698 result
= create_tmp_var (optype
, "PROF");
699 tmp2
= create_tmp_var (optype
, "PROF");
700 tmp3
= create_tmp_var (optype
, "PROF");
701 stmt2
= gimple_build_assign_with_ops (PLUS_EXPR
, tmp2
, op2
,
702 build_int_cst (optype
, -1));
703 stmt3
= gimple_build_assign_with_ops (BIT_AND_EXPR
, tmp3
, tmp2
, op2
);
704 stmt4
= gimple_build_cond (NE_EXPR
, tmp3
, build_int_cst (optype
, 0),
705 NULL_TREE
, NULL_TREE
);
706 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
707 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
708 gsi_insert_before (&gsi
, stmt4
, GSI_SAME_STMT
);
711 /* tmp2 == op2-1 inherited from previous block */
712 label1
= gimple_build_label (label_decl1
);
713 stmt1
= gimple_build_assign_with_ops (BIT_AND_EXPR
, result
, op1
, tmp2
);
714 gsi_insert_before (&gsi
, label1
, GSI_SAME_STMT
);
715 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
718 label2
= gimple_build_label (label_decl2
);
719 stmt1
= gimple_build_assign_with_ops (gimple_subcode (stmt
), result
, op1
, op2
);
720 gsi_insert_before (&gsi
, label2
, GSI_SAME_STMT
);
721 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
725 /* Edge e23 connects bb2 to bb3, etc. */
726 e12
= split_block (bb
, bb1end
);
729 e23
= split_block (bb2
, bb2end
);
731 bb3
->count
= all
- count
;
732 e34
= split_block (bb3
, bb3end
);
736 e12
->flags
&= ~EDGE_FALLTHRU
;
737 e12
->flags
|= EDGE_FALSE_VALUE
;
738 e12
->probability
= prob
;
741 e13
= make_edge (bb
, bb3
, EDGE_TRUE_VALUE
);
742 e13
->probability
= REG_BR_PROB_BASE
- prob
;
743 e13
->count
= all
- count
;
747 e24
= make_edge (bb2
, bb4
, EDGE_FALLTHRU
);
748 e24
->probability
= REG_BR_PROB_BASE
;
751 e34
->probability
= REG_BR_PROB_BASE
;
752 e34
->count
= all
- count
;
757 /* Do transform 2) on INSN if applicable. */
759 gimple_mod_pow2_value_transform (gimple stmt
)
761 histogram_value histogram
;
763 gcov_type count
, wrong_values
, all
;
764 tree lhs_type
, result
, value
;
767 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
770 lhs_type
= TREE_TYPE (gimple_assign_lhs (stmt
));
771 if (!INTEGRAL_TYPE_P (lhs_type
))
774 code
= gimple_assign_rhs_code (stmt
);
776 if (code
!= TRUNC_MOD_EXPR
|| !TYPE_UNSIGNED (lhs_type
))
779 histogram
= gimple_histogram_value_of_type (cfun
, stmt
, HIST_TYPE_POW2
);
783 value
= histogram
->hvalue
.value
;
784 wrong_values
= histogram
->hvalue
.counters
[0];
785 count
= histogram
->hvalue
.counters
[1];
787 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
789 /* We require that we hit a power of 2 at least half of all evaluations. */
790 if (simple_cst_equal (gimple_assign_rhs2 (stmt
), value
) != 1
791 || count
< wrong_values
792 || !maybe_hot_bb_p (gimple_bb (stmt
)))
797 fprintf (dump_file
, "Mod power of 2 transformation on insn ");
798 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
801 /* Compute probability of taking the optimal path. */
802 all
= count
+ wrong_values
;
804 if (check_counter (stmt
, "pow2", all
, gimple_bb (stmt
)->count
))
807 prob
= (count
* REG_BR_PROB_BASE
+ all
/ 2) / all
;
809 result
= gimple_mod_pow2 (stmt
, prob
, count
, all
);
811 gimple_assign_set_rhs_from_tree (stmt
, result
);
816 /* Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
817 NCOUNTS the number of cases to support. Currently only NCOUNTS==0 or 1 is
818 supported and this is built into this interface. The probabilities of taking
819 the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
820 COUNT2/ALL respectively within roundoff error). This generates the
821 result into a temp and returns the temp; it does not replace or alter
822 the original STMT. */
823 /* FIXME: Generalize the interface to handle NCOUNTS > 1. */
826 gimple_mod_subtract (gimple stmt
, int prob1
, int prob2
, int ncounts
,
827 gcov_type count1
, gcov_type count2
, gcov_type all
)
829 gimple stmt1
, stmt2
, stmt3
;
831 tree label_decl1
= create_artificial_label ();
832 tree label_decl2
= create_artificial_label ();
833 tree label_decl3
= create_artificial_label ();
834 gimple label1
, label2
, label3
;
835 gimple bb1end
, bb2end
= NULL
, bb3end
;
836 basic_block bb
, bb2
, bb3
, bb4
;
837 tree optype
, op1
, op2
;
838 edge e12
, e23
= 0, e24
, e34
, e14
;
839 gimple_stmt_iterator gsi
;
842 gcc_assert (gimple_code (stmt
) == GIMPLE_ASSIGN
843 && gimple_subcode (stmt
) == TRUNC_MOD_EXPR
);
845 optype
= TREE_TYPE (gimple_assign_lhs (stmt
));
846 op1
= gimple_assign_rhs1 (stmt
);
847 op2
= gimple_assign_rhs2 (stmt
);
849 bb
= gimple_bb (stmt
);
850 gsi
= gsi_for_stmt (stmt
);
852 result
= create_tmp_var (optype
, "PROF");
853 tmp1
= create_tmp_var (optype
, "PROF");
854 stmt1
= gimple_build_assign (result
, op1
);
855 stmt2
= gimple_build_assign (tmp1
, op2
);
856 stmt3
= gimple_build_cond (LT_EXPR
, result
, tmp1
, NULL_TREE
, NULL_TREE
);
857 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
858 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
859 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
862 if (ncounts
) /* Assumed to be 0 or 1 */
864 label1
= gimple_build_label (label_decl1
);
865 stmt1
= gimple_build_assign_with_ops (MINUS_EXPR
, result
, result
, tmp1
);
866 stmt2
= gimple_build_cond (LT_EXPR
, result
, tmp1
, NULL_TREE
, NULL_TREE
);
867 gsi_insert_before (&gsi
, label1
, GSI_SAME_STMT
);
868 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
869 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
874 label2
= gimple_build_label (label_decl2
);
875 stmt1
= gimple_build_assign_with_ops (gimple_subcode (stmt
), result
, result
,
877 gsi_insert_before (&gsi
, label2
, GSI_SAME_STMT
);
878 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
881 label3
= gimple_build_label (label_decl3
);
882 gsi_insert_before (&gsi
, label3
, GSI_SAME_STMT
);
885 /* Edge e23 connects bb2 to bb3, etc. */
886 /* However block 3 is optional; if it is not there, references
887 to 3 really refer to block 2. */
888 e12
= split_block (bb
, bb1end
);
890 bb2
->count
= all
- count1
;
892 if (ncounts
) /* Assumed to be 0 or 1. */
894 e23
= split_block (bb2
, bb2end
);
896 bb3
->count
= all
- count1
- count2
;
899 e34
= split_block (ncounts
? bb3
: bb2
, bb3end
);
903 e12
->flags
&= ~EDGE_FALLTHRU
;
904 e12
->flags
|= EDGE_FALSE_VALUE
;
905 e12
->probability
= REG_BR_PROB_BASE
- prob1
;
906 e12
->count
= all
- count1
;
908 e14
= make_edge (bb
, bb4
, EDGE_TRUE_VALUE
);
909 e14
->probability
= prob1
;
912 if (ncounts
) /* Assumed to be 0 or 1. */
914 e23
->flags
&= ~EDGE_FALLTHRU
;
915 e23
->flags
|= EDGE_FALSE_VALUE
;
916 e23
->count
= all
- count1
- count2
;
917 e23
->probability
= REG_BR_PROB_BASE
- prob2
;
919 e24
= make_edge (bb2
, bb4
, EDGE_TRUE_VALUE
);
920 e24
->probability
= prob2
;
924 e34
->probability
= REG_BR_PROB_BASE
;
925 e34
->count
= all
- count1
- count2
;
931 /* Do transforms 3) and 4) on STMT if applicable. */
934 gimple_mod_subtract_transform (gimple stmt
)
936 histogram_value histogram
;
938 gcov_type count
, wrong_values
, all
;
939 tree lhs_type
, result
, value
;
941 unsigned int i
, steps
;
942 gcov_type count1
, count2
;
944 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
947 lhs_type
= TREE_TYPE (gimple_assign_lhs (stmt
));
948 if (!INTEGRAL_TYPE_P (lhs_type
))
951 code
= gimple_assign_rhs_code (stmt
);
953 if (code
!= TRUNC_MOD_EXPR
|| !TYPE_UNSIGNED (lhs_type
))
956 histogram
= gimple_histogram_value_of_type (cfun
, stmt
, HIST_TYPE_INTERVAL
);
960 value
= histogram
->hvalue
.value
;
963 for (i
= 0; i
< histogram
->hdata
.intvl
.steps
; i
++)
964 all
+= histogram
->hvalue
.counters
[i
];
966 wrong_values
+= histogram
->hvalue
.counters
[i
];
967 wrong_values
+= histogram
->hvalue
.counters
[i
+1];
968 steps
= histogram
->hdata
.intvl
.steps
;
970 count1
= histogram
->hvalue
.counters
[0];
971 count2
= histogram
->hvalue
.counters
[1];
973 /* Compute probability of taking the optimal path. */
974 if (check_counter (stmt
, "interval", all
, gimple_bb (stmt
)->count
))
976 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
980 /* We require that we use just subtractions in at least 50% of all
983 for (i
= 0; i
< histogram
->hdata
.intvl
.steps
; i
++)
985 count
+= histogram
->hvalue
.counters
[i
];
986 if (count
* 2 >= all
)
990 || !maybe_hot_bb_p (gimple_bb (stmt
)))
993 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
996 fprintf (dump_file
, "Mod subtract transformation on insn ");
997 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1000 /* Compute probability of taking the optimal path(s). */
1001 prob1
= (count1
* REG_BR_PROB_BASE
+ all
/ 2) / all
;
1002 prob2
= (count2
* REG_BR_PROB_BASE
+ all
/ 2) / all
;
1004 /* In practice, "steps" is always 2. This interface reflects this,
1005 and will need to be changed if "steps" can change. */
1006 result
= gimple_mod_subtract (stmt
, prob1
, prob2
, i
, count1
, count2
, all
);
1008 gimple_assign_set_rhs_from_tree (stmt
, result
);
1013 static struct cgraph_node
** pid_map
= NULL
;
1015 /* Initialize map of pids (pid -> cgraph node) */
1020 struct cgraph_node
*n
;
1022 if (pid_map
!= NULL
)
1026 = (struct cgraph_node
**) xmalloc (sizeof (struct cgraph_node
*) * cgraph_max_pid
);
1028 for (n
= cgraph_nodes
; n
; n
= n
->next
)
1031 pid_map
[n
->pid
] = n
;
1035 /* Return cgraph node for function with pid */
1037 static inline struct cgraph_node
*
1038 find_func_by_pid (int pid
)
1042 return pid_map
[pid
];
1045 /* Do transformation
1047 if (actual_callee_addres == addres_of_most_common_function/method)
1054 gimple_ic (gimple stmt
, gimple call
, struct cgraph_node
*direct_call
,
1055 int prob
, gcov_type count
, gcov_type all
)
1057 gimple stmt1
, stmt2
, stmt3
;
1058 tree tmp1
, tmpv
, tmp
;
1059 tree label_decl1
= create_artificial_label ();
1060 tree label_decl2
= create_artificial_label ();
1061 gimple label1
, label2
;
1062 gimple bb1end
, bb2end
, bb3end
;
1063 basic_block bb
, bb2
, bb3
, bb4
;
1064 tree optype
= build_pointer_type (void_type_node
);
1065 edge e12
, e13
, e23
, e24
, e34
;
1066 gimple_stmt_iterator gsi
;
1069 bb
= gimple_bb (stmt
);
1070 gsi
= gsi_for_stmt (stmt
);
1072 tmpv
= create_tmp_var (optype
, "PROF");
1073 tmp1
= create_tmp_var (optype
, "PROF");
1074 stmt1
= gimple_build_assign (tmpv
, unshare_expr (gimple_call_fn (call
)));
1076 tmp
= fold_convert (optype
, build_addr (direct_call
->decl
,
1077 current_function_decl
));
1078 stmt2
= gimple_build_assign (tmp1
, tmp
);
1079 stmt3
= gimple_build_cond (NE_EXPR
, tmp1
, tmpv
, NULL_TREE
, NULL_TREE
);
1080 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
1081 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
1082 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
1085 label1
= gimple_build_label (label_decl1
);
1086 stmt1
= gimple_copy (stmt
);
1087 gimple_call_set_fn (stmt
,
1088 build_addr (direct_call
->decl
, current_function_decl
));
1089 gsi_insert_before (&gsi
, label1
, GSI_SAME_STMT
);
1090 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
1093 label2
= gimple_build_label (label_decl2
);
1094 gsi_insert_before (&gsi
, label2
, GSI_SAME_STMT
);
1098 /* Edge e23 connects bb2 to bb3, etc. */
1099 e12
= split_block (bb
, bb1end
);
1102 e23
= split_block (bb2
, bb2end
);
1104 bb3
->count
= all
- count
;
1105 e34
= split_block (bb3
, bb3end
);
1109 e12
->flags
&= ~EDGE_FALLTHRU
;
1110 e12
->flags
|= EDGE_FALSE_VALUE
;
1111 e12
->probability
= prob
;
1114 e13
= make_edge (bb
, bb3
, EDGE_TRUE_VALUE
);
1115 e13
->probability
= REG_BR_PROB_BASE
- prob
;
1116 e13
->count
= all
- count
;
1120 e24
= make_edge (bb2
, bb4
, EDGE_FALLTHRU
);
1121 e24
->probability
= REG_BR_PROB_BASE
;
1123 e34
->probability
= REG_BR_PROB_BASE
;
1124 e34
->count
= all
- count
;
1127 region
= lookup_stmt_eh_region (stmt
);
1128 if (region
>= 0 && stmt_could_throw_p (stmt1
))
1130 add_stmt_to_eh_region (stmt1
, region
);
1131 make_eh_edges (stmt1
);
1134 if (region
>= 0 && stmt_could_throw_p (stmt
))
1136 gimple_purge_dead_eh_edges (bb4
);
1137 make_eh_edges (stmt
);
1144 For every checked indirect/virtual call determine if most common pid of
1145 function/class method has probability more than 50%. If yes modify code of
1150 gimple_ic_transform (gimple stmt
)
1152 histogram_value histogram
;
1153 gcov_type val
, count
, all
;
1157 struct cgraph_node
*direct_call
;
1159 if (gimple_code (stmt
) != GIMPLE_CALL
)
1162 callee
= gimple_call_fn (stmt
);
1164 if (TREE_CODE (callee
) == FUNCTION_DECL
)
1167 histogram
= gimple_histogram_value_of_type (cfun
, stmt
, HIST_TYPE_INDIR_CALL
);
1171 val
= histogram
->hvalue
.counters
[0];
1172 count
= histogram
->hvalue
.counters
[1];
1173 all
= histogram
->hvalue
.counters
[2];
1174 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
1176 if (4 * count
<= 3 * all
)
1179 prob
= (count
* REG_BR_PROB_BASE
+ all
/ 2) / all
;
1180 direct_call
= find_func_by_pid ((int)val
);
1182 if (direct_call
== NULL
)
1185 modify
= gimple_ic (stmt
, stmt
, direct_call
, prob
, count
, all
);
1189 fprintf (dump_file
, "Indirect call -> direct call ");
1190 print_generic_expr (dump_file
, gimple_call_fn (stmt
), TDF_SLIM
);
1191 fprintf (dump_file
, "=> ");
1192 print_generic_expr (dump_file
, direct_call
->decl
, TDF_SLIM
);
1193 fprintf (dump_file
, " transformation on insn ");
1194 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1195 fprintf (dump_file
, " to ");
1196 print_gimple_stmt (dump_file
, modify
, 0, TDF_SLIM
);
1202 /* Return true if the stringop CALL with FNDECL shall be profiled. */
1204 interesting_stringop_to_profile_p (tree fndecl
, gimple call
)
1206 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
1208 if (fcode
!= BUILT_IN_MEMSET
&& fcode
!= BUILT_IN_MEMCPY
1209 && fcode
!= BUILT_IN_BZERO
)
1214 case BUILT_IN_MEMCPY
:
1215 case BUILT_IN_MEMPCPY
:
1216 return validate_gimple_arglist (call
, POINTER_TYPE
, POINTER_TYPE
,
1217 INTEGER_TYPE
, VOID_TYPE
);
1218 case BUILT_IN_MEMSET
:
1219 return validate_gimple_arglist (call
, POINTER_TYPE
, INTEGER_TYPE
,
1220 INTEGER_TYPE
, VOID_TYPE
);
1221 case BUILT_IN_BZERO
:
1222 return validate_gimple_arglist (call
, POINTER_TYPE
, INTEGER_TYPE
,
1229 /* Convert stringop (..., size)
1232 stringop (...., VALUE);
1234 stringop (...., size);
1235 assuming constant propagation of VALUE will happen later.
1238 gimple_stringop_fixed_value (gimple stmt
, tree value
, int prob
, gcov_type count
,
1241 gimple stmt1
, stmt2
, stmt3
;
1243 tree label_decl1
= create_artificial_label ();
1244 tree label_decl2
= create_artificial_label ();
1245 gimple label1
, label2
;
1246 gimple bb1end
, bb2end
;
1247 basic_block bb
, bb2
, bb3
, bb4
;
1248 edge e12
, e13
, e23
, e24
, e34
;
1249 gimple_stmt_iterator gsi
;
1250 tree blck_size
= gimple_call_arg (stmt
, 2);
1251 tree optype
= TREE_TYPE (blck_size
);
1254 bb
= gimple_bb (stmt
);
1255 gsi
= gsi_for_stmt (stmt
);
1257 if (gsi_end_p (gsi
))
1260 for (ei
= ei_start (bb
->succs
); (e34
= ei_safe_edge (ei
)); )
1261 if (!e34
->flags
& EDGE_ABNORMAL
)
1266 e34
= split_block (bb
, stmt
);
1267 gsi
= gsi_for_stmt (stmt
);
1271 tmpv
= create_tmp_var (optype
, "PROF");
1272 tmp1
= create_tmp_var (optype
, "PROF");
1273 stmt1
= gimple_build_assign (tmpv
, fold_convert (optype
, value
));
1274 stmt2
= gimple_build_assign (tmp1
, blck_size
);
1275 stmt3
= gimple_build_cond (NE_EXPR
, tmp1
, tmpv
, NULL_TREE
, NULL_TREE
);
1276 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
1277 gsi_insert_before (&gsi
, stmt2
, GSI_SAME_STMT
);
1278 gsi_insert_before (&gsi
, stmt3
, GSI_SAME_STMT
);
1281 label1
= gimple_build_label (label_decl1
);
1282 stmt1
= gimple_copy (stmt
);
1283 gimple_call_set_arg (stmt1
, 2, value
);
1284 gsi_insert_before (&gsi
, label1
, GSI_SAME_STMT
);
1285 gsi_insert_before (&gsi
, stmt1
, GSI_SAME_STMT
);
1286 region
= lookup_stmt_eh_region (stmt
);
1288 add_stmt_to_eh_region (stmt1
, region
);
1290 label2
= gimple_build_label (label_decl2
);
1291 gsi_insert_before (&gsi
, label2
, GSI_SAME_STMT
);
1294 /* Edge e23 connects bb2 to bb3, etc. */
1295 e12
= split_block (bb
, bb1end
);
1298 e23
= split_block (bb2
, bb2end
);
1300 bb3
->count
= all
- count
;
1302 e12
->flags
&= ~EDGE_FALLTHRU
;
1303 e12
->flags
|= EDGE_FALSE_VALUE
;
1304 e12
->probability
= prob
;
1307 e13
= make_edge (bb
, bb3
, EDGE_TRUE_VALUE
);
1308 e13
->probability
= REG_BR_PROB_BASE
- prob
;
1309 e13
->count
= all
- count
;
1313 e24
= make_edge (bb2
, bb4
, EDGE_FALLTHRU
);
1314 e24
->probability
= REG_BR_PROB_BASE
;
1317 e34
->probability
= REG_BR_PROB_BASE
;
1318 e34
->count
= all
- count
;
1321 /* Find values inside STMT for that we want to measure histograms for
1322 division/modulo optimization. */
1324 gimple_stringops_transform (gimple_stmt_iterator
*gsi
)
1326 gimple stmt
= gsi_stmt (*gsi
);
1329 enum built_in_function fcode
;
1330 histogram_value histogram
;
1331 gcov_type count
, all
, val
;
1334 unsigned int dest_align
, src_align
;
1338 if (gimple_code (stmt
) != GIMPLE_CALL
)
1340 fndecl
= gimple_call_fndecl (stmt
);
1343 fcode
= DECL_FUNCTION_CODE (fndecl
);
1344 if (!interesting_stringop_to_profile_p (fndecl
, stmt
))
1347 if (fcode
== BUILT_IN_BZERO
)
1348 blck_size
= gimple_call_arg (stmt
, 1);
1350 blck_size
= gimple_call_arg (stmt
, 2);
1351 if (TREE_CODE (blck_size
) == INTEGER_CST
)
1354 histogram
= gimple_histogram_value_of_type (cfun
, stmt
, HIST_TYPE_SINGLE_VALUE
);
1357 value
= histogram
->hvalue
.value
;
1358 val
= histogram
->hvalue
.counters
[0];
1359 count
= histogram
->hvalue
.counters
[1];
1360 all
= histogram
->hvalue
.counters
[2];
1361 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
1362 /* We require that count is at least half of all; this means
1363 that for the transformation to fire the value must be constant
1364 at least 80% of time. */
1365 if ((6 * count
/ 5) < all
|| !maybe_hot_bb_p (gimple_bb (stmt
)))
1367 if (check_counter (stmt
, "value", all
, gimple_bb (stmt
)->count
))
1369 prob
= (count
* REG_BR_PROB_BASE
+ all
/ 2) / all
;
1370 dest
= gimple_call_arg (stmt
, 0);
1371 dest_align
= get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
1374 case BUILT_IN_MEMCPY
:
1375 case BUILT_IN_MEMPCPY
:
1376 src
= gimple_call_arg (stmt
, 1);
1377 src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
1378 if (!can_move_by_pieces (val
, MIN (dest_align
, src_align
)))
1381 case BUILT_IN_MEMSET
:
1382 if (!can_store_by_pieces (val
, builtin_memset_read_str
,
1383 gimple_call_arg (stmt
, 1),
1387 case BUILT_IN_BZERO
:
1388 if (!can_store_by_pieces (val
, builtin_memset_read_str
,
1396 tree_val
= build_int_cst_wide (get_gcov_type (),
1397 (unsigned HOST_WIDE_INT
) val
,
1398 val
>> (HOST_BITS_PER_WIDE_INT
- 1) >> 1);
1401 fprintf (dump_file
, "Single value %i stringop transformation on ",
1403 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1405 gimple_stringop_fixed_value (stmt
, tree_val
, prob
, count
, all
);
1411 stringop_block_profile (gimple stmt
, unsigned int *expected_align
,
1412 HOST_WIDE_INT
*expected_size
)
1414 histogram_value histogram
;
1415 histogram
= gimple_histogram_value_of_type (cfun
, stmt
, HIST_TYPE_AVERAGE
);
1417 *expected_size
= -1;
1418 else if (!histogram
->hvalue
.counters
[1])
1420 *expected_size
= -1;
1421 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
1426 size
= ((histogram
->hvalue
.counters
[0]
1427 + histogram
->hvalue
.counters
[1] / 2)
1428 / histogram
->hvalue
.counters
[1]);
1429 /* Even if we can hold bigger value in SIZE, INT_MAX
1430 is safe "infinity" for code generation strategies. */
1433 *expected_size
= size
;
1434 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
1436 histogram
= gimple_histogram_value_of_type (cfun
, stmt
, HIST_TYPE_IOR
);
1438 *expected_align
= 0;
1439 else if (!histogram
->hvalue
.counters
[0])
1441 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
1442 *expected_align
= 0;
1449 count
= histogram
->hvalue
.counters
[0];
1451 while (!(count
& alignment
)
1452 && (alignment
* 2 * BITS_PER_UNIT
))
1454 *expected_align
= alignment
* BITS_PER_UNIT
;
1455 gimple_remove_histogram_value (cfun
, stmt
, histogram
);
1459 struct value_prof_hooks
{
1460 /* Find list of values for which we want to measure histograms. */
1461 void (*find_values_to_profile
) (histogram_values
*);
1463 /* Identify and exploit properties of values that are hard to analyze
1464 statically. See value-prof.c for more detail. */
1465 bool (*value_profile_transformations
) (void);
1468 /* Find values inside STMT for that we want to measure histograms for
1469 division/modulo optimization. */
1471 gimple_divmod_values_to_profile (gimple stmt
, histogram_values
*values
)
1473 tree lhs
, divisor
, op0
, type
;
1474 histogram_value hist
;
1476 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
1479 lhs
= gimple_assign_lhs (stmt
);
1480 type
= TREE_TYPE (lhs
);
1481 if (!INTEGRAL_TYPE_P (type
))
1484 switch (gimple_subcode (stmt
))
1486 case TRUNC_DIV_EXPR
:
1487 case TRUNC_MOD_EXPR
:
1488 divisor
= gimple_assign_rhs2 (stmt
);
1489 op0
= gimple_assign_rhs1 (stmt
);
1491 VEC_reserve (histogram_value
, heap
, *values
, 3);
1493 if (is_gimple_reg (divisor
))
1494 /* Check for the case where the divisor is the same value most
1496 VEC_quick_push (histogram_value
, *values
,
1497 gimple_alloc_histogram_value (cfun
, HIST_TYPE_SINGLE_VALUE
,
1500 /* For mod, check whether it is not often a noop (or replaceable by
1501 a few subtractions). */
1502 if (gimple_subcode (stmt
) == TRUNC_MOD_EXPR
1503 && TYPE_UNSIGNED (type
))
1506 /* Check for a special case where the divisor is power of 2. */
1507 VEC_quick_push (histogram_value
, *values
,
1508 gimple_alloc_histogram_value (cfun
, HIST_TYPE_POW2
,
1511 val
= build2 (TRUNC_DIV_EXPR
, type
, op0
, divisor
);
1512 hist
= gimple_alloc_histogram_value (cfun
, HIST_TYPE_INTERVAL
,
1514 hist
->hdata
.intvl
.int_start
= 0;
1515 hist
->hdata
.intvl
.steps
= 2;
1516 VEC_quick_push (histogram_value
, *values
, hist
);
1525 /* Find calls inside STMT for that we want to measure histograms for
1526 indirect/virtual call optimization. */
1529 gimple_indirect_call_to_profile (gimple stmt
, histogram_values
*values
)
1533 if (gimple_code (stmt
) != GIMPLE_CALL
)
1536 callee
= gimple_call_fn (stmt
);
1538 if (TREE_CODE (callee
) == FUNCTION_DECL
)
1541 VEC_reserve (histogram_value
, heap
, *values
, 3);
1543 VEC_quick_push (histogram_value
, *values
,
1544 gimple_alloc_histogram_value (cfun
, HIST_TYPE_INDIR_CALL
,
1550 /* Find values inside STMT for that we want to measure histograms for
1551 string operations. */
1553 gimple_stringops_values_to_profile (gimple stmt
, histogram_values
*values
)
1558 enum built_in_function fcode
;
1560 if (gimple_code (stmt
) != GIMPLE_CALL
)
1562 fndecl
= gimple_call_fndecl (stmt
);
1565 fcode
= DECL_FUNCTION_CODE (fndecl
);
1567 if (!interesting_stringop_to_profile_p (fndecl
, stmt
))
1570 dest
= gimple_call_arg (stmt
, 0);
1571 if (fcode
== BUILT_IN_BZERO
)
1572 blck_size
= gimple_call_arg (stmt
, 1);
1574 blck_size
= gimple_call_arg (stmt
, 2);
1576 if (TREE_CODE (blck_size
) != INTEGER_CST
)
1578 VEC_safe_push (histogram_value
, heap
, *values
,
1579 gimple_alloc_histogram_value (cfun
, HIST_TYPE_SINGLE_VALUE
,
1581 VEC_safe_push (histogram_value
, heap
, *values
,
1582 gimple_alloc_histogram_value (cfun
, HIST_TYPE_AVERAGE
,
1585 if (TREE_CODE (blck_size
) != INTEGER_CST
)
1586 VEC_safe_push (histogram_value
, heap
, *values
,
1587 gimple_alloc_histogram_value (cfun
, HIST_TYPE_IOR
,
1591 /* Find values inside STMT for that we want to measure histograms and adds
1592 them to list VALUES. */
1595 gimple_values_to_profile (gimple stmt
, histogram_values
*values
)
1597 if (flag_value_profile_transformations
)
1599 gimple_divmod_values_to_profile (stmt
, values
);
1600 gimple_stringops_values_to_profile (stmt
, values
);
1601 gimple_indirect_call_to_profile (stmt
, values
);
1606 gimple_find_values_to_profile (histogram_values
*values
)
1609 gimple_stmt_iterator gsi
;
1611 histogram_value hist
= NULL
;
1615 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1616 gimple_values_to_profile (gsi_stmt (gsi
), values
);
1618 for (i
= 0; VEC_iterate (histogram_value
, *values
, i
, hist
); i
++)
1622 case HIST_TYPE_INTERVAL
:
1623 hist
->n_counters
= hist
->hdata
.intvl
.steps
+ 2;
1626 case HIST_TYPE_POW2
:
1627 hist
->n_counters
= 2;
1630 case HIST_TYPE_SINGLE_VALUE
:
1631 hist
->n_counters
= 3;
1634 case HIST_TYPE_CONST_DELTA
:
1635 hist
->n_counters
= 4;
1638 case HIST_TYPE_INDIR_CALL
:
1639 hist
->n_counters
= 3;
1642 case HIST_TYPE_AVERAGE
:
1643 hist
->n_counters
= 2;
1647 hist
->n_counters
= 1;
1655 fprintf (dump_file
, "Stmt ");
1656 print_gimple_stmt (dump_file
, hist
->hvalue
.stmt
, 0, TDF_SLIM
);
1657 dump_histogram_value (dump_file
, hist
);
1662 static struct value_prof_hooks gimple_value_prof_hooks
= {
1663 gimple_find_values_to_profile
,
1664 gimple_value_profile_transformations
1668 gimple_register_value_prof_hooks (void)
1670 gcc_assert (current_ir_type () == IR_GIMPLE
);
1671 value_prof_hooks
= &gimple_value_prof_hooks
;
1674 /* IR-independent entry points. */
1676 find_values_to_profile (histogram_values
*values
)
1678 (value_prof_hooks
->find_values_to_profile
) (values
);
1682 value_profile_transformations (void)
1684 return (value_prof_hooks
->value_profile_transformations
) ();