]>
Commit | Line | Data |
---|---|---|
6de9cd9a DN |
1 | /* Calculate branch probabilities, and basic block execution counts. |
2 | Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, | |
3 | 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | |
4 | Contributed by James E. Wilson, UC Berkeley/Cygnus Support; | |
5 | based on some ideas from Dain Samples of UC Berkeley. | |
6 | Further mangling by Bob Manson, Cygnus Support. | |
7 | Converted to use trees by Dale Johannesen, Apple Computer. | |
8 | ||
9 | This file is part of GCC. | |
10 | ||
11 | GCC is free software; you can redistribute it and/or modify it under | |
12 | the terms of the GNU General Public License as published by the Free | |
13 | Software Foundation; either version 2, or (at your option) any later | |
14 | version. | |
15 | ||
16 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
17 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
18 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
19 | for more details. | |
20 | ||
21 | You should have received a copy of the GNU General Public License | |
22 | along with GCC; see the file COPYING. If not, write to the Free | |
23 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
24 | 02111-1307, USA. */ | |
25 | ||
26 | /* Generate basic block profile instrumentation and auxiliary files. | |
27 | Profile generation is optimized, so that not all arcs in the basic | |
28 | block graph need instrumenting. First, the BB graph is closed with | |
29 | one entry (function start), and one exit (function exit). Any | |
30 | ABNORMAL_EDGE cannot be instrumented (because there is no control | |
31 | path to place the code). We close the graph by inserting fake | |
32 | EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal | |
33 | edges that do not go to the exit_block. We ignore such abnormal | |
34 | edges. Naturally these fake edges are never directly traversed, | |
35 | and so *cannot* be directly instrumented. Some other graph | |
36 | massaging is done. To optimize the instrumentation we generate the | |
37 | BB minimal span tree, only edges that are not on the span tree | |
38 | (plus the entry point) need instrumenting. From that information | |
39 | all other edge counts can be deduced. By construction all fake | |
40 | edges must be on the spanning tree. We also attempt to place | |
41 | EDGE_CRITICAL edges on the spanning tree. | |
42 | ||
43 | The auxiliary file generated is <dumpbase>.bbg. The format is | |
44 | described in full in gcov-io.h. */ | |
45 | ||
46 | /* ??? Register allocation should use basic block execution counts to | |
47 | give preference to the most commonly executed blocks. */ | |
48 | ||
49 | /* ??? Should calculate branch probabilities before instrumenting code, since | |
50 | then we can use arc counts to help decide which arcs to instrument. */ | |
51 | ||
52 | #include "config.h" | |
53 | #include "system.h" | |
54 | #include "coretypes.h" | |
55 | #include "tm.h" | |
56 | #include "rtl.h" | |
57 | #include "flags.h" | |
58 | #include "output.h" | |
59 | #include "regs.h" | |
60 | #include "expr.h" | |
61 | #include "function.h" | |
62 | #include "toplev.h" | |
63 | #include "coverage.h" | |
64 | #include "tree.h" | |
65 | #include "tree-flow.h" | |
66 | #include "tree-dump.h" | |
67 | #include "tree-pass.h" | |
68 | #include "timevar.h" | |
69 | #include "value-prof.h" | |
70 | ||
71 | \f | |
72 | /* Output instructions as GIMPLE trees to increment the edge | |
73 | execution count, and insert them on E. We rely on | |
74 | bsi_insert_on_edge to preserve the order. */ | |
75 | ||
76 | static void | |
77 | tree_gen_edge_profiler (int edgeno, edge e) | |
78 | { | |
79 | tree tmp1 = create_tmp_var (GCOV_TYPE_NODE, "PROF"); | |
80 | tree tmp2 = create_tmp_var (GCOV_TYPE_NODE, "PROF"); | |
81 | tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno); | |
82 | tree stmt1 = build (MODIFY_EXPR, GCOV_TYPE_NODE, tmp1, ref); | |
83 | tree stmt2 = build (MODIFY_EXPR, GCOV_TYPE_NODE, tmp2, | |
84 | build (PLUS_EXPR, GCOV_TYPE_NODE, | |
85 | tmp1, integer_one_node)); | |
86 | tree stmt3 = build (MODIFY_EXPR, GCOV_TYPE_NODE, ref, tmp2); | |
87 | bsi_insert_on_edge (e, stmt1); | |
88 | bsi_insert_on_edge (e, stmt2); | |
89 | bsi_insert_on_edge (e, stmt3); | |
90 | } | |
91 | ||
92 | /* Output instructions as GIMPLE trees to increment the interval histogram | |
93 | counter. VALUE is the expression whose value is profiled. TAG is the | |
94 | tag of the section for counters, BASE is offset of the counter position. */ | |
95 | ||
96 | static void | |
97 | tree_gen_interval_profiler (struct histogram_value *value ATTRIBUTE_UNUSED, | |
98 | unsigned tag ATTRIBUTE_UNUSED, | |
99 | unsigned base ATTRIBUTE_UNUSED) | |
100 | { | |
101 | /* FIXME implement this. */ | |
102 | abort (); | |
103 | } | |
104 | ||
105 | /* Output instructions as GIMPLE trees to increment the power of two histogram | |
106 | counter. VALUE is the expression whose value is profiled. TAG is the tag | |
107 | of the section for counters, BASE is offset of the counter position. */ | |
108 | ||
109 | static void | |
110 | tree_gen_pow2_profiler (struct histogram_value *value ATTRIBUTE_UNUSED, | |
111 | unsigned tag ATTRIBUTE_UNUSED, | |
112 | unsigned base ATTRIBUTE_UNUSED) | |
113 | { | |
114 | /* FIXME implement this. */ | |
115 | abort (); | |
116 | } | |
117 | ||
118 | /* Output instructions as GIMPLE trees for code to find the most common value. | |
119 | VALUE is the expression whose value is profiled. TAG is the tag of the | |
120 | section for counters, BASE is offset of the counter position. */ | |
121 | ||
122 | static void | |
123 | tree_gen_one_value_profiler (struct histogram_value *value ATTRIBUTE_UNUSED, | |
124 | unsigned tag ATTRIBUTE_UNUSED, | |
125 | unsigned base ATTRIBUTE_UNUSED) | |
126 | { | |
127 | /* FIXME implement this. */ | |
128 | abort (); | |
129 | } | |
130 | ||
131 | /* Output instructions as GIMPLE trees for code to find the most common value | |
132 | of a difference between two evaluations of an expression. | |
133 | VALUE is the expression whose value is profiled. TAG is the tag of the | |
134 | section for counters, BASE is offset of the counter position. */ | |
135 | ||
136 | static void | |
137 | tree_gen_const_delta_profiler (struct histogram_value *value ATTRIBUTE_UNUSED, | |
138 | unsigned tag ATTRIBUTE_UNUSED, | |
139 | unsigned base ATTRIBUTE_UNUSED) | |
140 | { | |
141 | /* FIXME implement this. */ | |
142 | abort (); | |
143 | } | |
144 | ||
145 | /* Return 1 if tree-based profiling is in effect, else 0. | |
146 | If it is, set up hooks for tree-based profiling. | |
147 | Gate for pass_tree_profile. */ | |
148 | ||
149 | static bool do_tree_profiling (void) { | |
150 | if (flag_tree_based_profiling) | |
151 | { | |
152 | tree_register_profile_hooks (); | |
153 | tree_register_value_prof_hooks (); | |
154 | } | |
155 | return flag_tree_based_profiling; | |
156 | } | |
157 | ||
158 | /* Return the file on which profile dump output goes, if any. */ | |
159 | ||
160 | static FILE *tree_profile_dump_file (void) { | |
161 | return dump_file; | |
162 | } | |
163 | ||
164 | struct tree_opt_pass pass_tree_profile = | |
165 | { | |
166 | "tree_profile", /* name */ | |
167 | do_tree_profiling, /* gate */ | |
168 | branch_prob, /* execute */ | |
169 | NULL, /* sub */ | |
170 | NULL, /* next */ | |
171 | 0, /* static_pass_number */ | |
172 | TV_BRANCH_PROB, /* tv_id */ | |
173 | PROP_gimple_leh | PROP_cfg, /* properties_required */ | |
174 | PROP_gimple_leh | PROP_cfg, /* properties_provided */ | |
175 | 0, /* properties_destroyed */ | |
176 | 0, /* todo_flags_start */ | |
177 | TODO_verify_stmts /* todo_flags_finish */ | |
178 | }; | |
179 | ||
180 | struct profile_hooks tree_profile_hooks = | |
181 | { | |
182 | tree_gen_edge_profiler, /* gen_edge_profiler */ | |
183 | tree_gen_interval_profiler, /* gen_interval_profiler */ | |
184 | tree_gen_pow2_profiler, /* gen_pow2_profiler */ | |
185 | tree_gen_one_value_profiler, /* gen_one_value_profiler */ | |
186 | tree_gen_const_delta_profiler,/* gen_const_delta_profiler */ | |
187 | tree_profile_dump_file /* profile_dump_file */ | |
188 | }; |