1 | /* This file contains the list of the debug counter for GCC. |
2 | Copyright (C) 2006-2023 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 | |
21 | /* A debug counter provides you a way to count an event |
22 | and return false after the counter has exceeded the threshold |
23 | specified by the option. |
24 | |
25 | What is it used for ? |
26 | |
27 | This is primarily used to speed up the search for the bad transformation |
28 | an optimization pass does. By doing a binary search on N, |
29 | you can quickly narrow down to one transformation |
30 | which is bad, or which triggers the bad behavior downstream |
31 | (usually in the form of the badly generated code). |
32 | |
33 | How does it work ? |
34 | |
35 | Every time dbg_cnt(named-counter) is called, |
36 | the counter is incremented for the named-counter. |
37 | And the incremented value is compared against the threshold (limit) |
38 | specified by the option. |
39 | dbg_cnt () returns true if it is at or below threshold, and false if above. |
40 | |
41 | How to add a new one ? |
42 | |
43 | To add a new counter, simply add an entry below with some descriptive name, |
44 | and add call(s) to dbg_cnt(your-counter-name) in appropriate places. |
45 | Usually, you want to control at the finest granularity |
46 | any particular transformation can happen. |
47 | e.g. for each instruction in a dead code elimination, |
48 | or for each copy instruction in register coalescing, |
49 | or constant-propagation for each insn, |
50 | or a block straightening, etc. |
51 | See dce.cc for an example. With the dbg_cnt () call in dce.cc, |
52 | now a developer can use -fdbg-cnt=dce:N |
53 | to stop doing the dead code elimination after N times. |
54 | |
55 | How to use it ? |
56 | |
57 | By default, all limits are UINT_MAX. |
58 | Since debug count is unsigned int, <= UINT_MAX returns true always. |
59 | i.e. dbg_cnt() returns true always regardless of the counter value |
60 | (although it still counts the event). |
61 | Use -fdbg-cnt=counter1:N,counter2:M,... |
62 | which sets the limit for counter1 to N, and the limit for counter2 to M, etc. |
63 | e.g. setting a limit to zero will make dbg_cnt () return false *always*. |
64 | |
65 | The following shell file can then be used to binary search for |
66 | exact transformation that causes the bug. A second shell script |
67 | should be written, say "tryTest", which exits with 1 if the |
68 | compiled program fails and exits with 0 if the program succeeds. |
69 | This shell script should take 1 parameter, the value to be passed |
70 | to set the counter of the compilation command in tryTest. Then, |
71 | assuming that the following script is called binarySearch, |
72 | the command: |
73 | |
74 | binarySearch tryTest |
75 | |
76 | will automatically find the highest value of the counter for which |
77 | the program fails. If tryTest never fails, binarySearch will |
78 | produce unpredictable results as it will try to find an upper bound |
79 | that does not exist. |
80 | |
81 | When dbgcnt does hits the limit, it writes a comment in the current |
82 | dump_file of the form: |
83 | |
84 | ***dbgcnt: limit reached for %s.*** |
85 | |
86 | Assuming that the dump file is logging the analysis/transformations |
87 | it is making, this pinpoints the exact position in the log file |
88 | where the problem transformation is being logged. |
89 | |
90 | ===================================== |
91 | #!/bin/bash |
92 | |
93 | while getopts "l:u:i:" opt |
94 | do |
95 | case $opt in |
96 | l) lb="$OPTARG";; |
97 | u) ub="$OPTARG";; |
98 | i) init="$OPTARG";; |
99 | ?) usage; exit 3;; |
100 | esac |
101 | done |
102 | |
103 | shift $(($OPTIND - 1)) |
104 | echo $@ |
105 | cmd=${1+"${@}"} |
106 | |
107 | lb=${lb:=0} |
108 | init=${init:=100} |
109 | |
110 | $cmd $lb |
111 | lb_val=$? |
112 | if [ -z "$ub" ]; then |
113 | # find the upper bound |
114 | ub=$(($init + $lb)) |
115 | true |
116 | while [ $? -eq $lb_val ]; do |
117 | ub=$(($ub * 10)) |
118 | #ub=`expr $ub \* 10` |
119 | $cmd $ub |
120 | done |
121 | fi |
122 | |
123 | echo command: $cmd |
124 | |
125 | true |
126 | while [ `expr $ub - $lb` -gt 1 ]; do |
127 | try=$(($lb + ( $ub - $lb ) / 2)) |
128 | $cmd $try |
129 | if [ $? -eq $lb_val ]; then |
130 | lb=$try |
131 | else |
132 | ub=$try |
133 | fi |
134 | done |
135 | |
136 | echo lbound: $lb |
137 | echo ubound: $ub |
138 | |
139 | ===================================== |
140 | |
141 | */ |
142 | |
143 | /* Debug counter definitions. |
144 | Please keep the list sorted in alphabetic order. */ |
145 | DEBUG_COUNTER (asan_use_after_scope) |
146 | DEBUG_COUNTER (auto_inc_dec) |
147 | DEBUG_COUNTER (back_thread1) |
148 | DEBUG_COUNTER (back_thread2) |
149 | DEBUG_COUNTER (back_threadfull1) |
150 | DEBUG_COUNTER (back_threadfull2) |
151 | DEBUG_COUNTER (ccp) |
152 | DEBUG_COUNTER (cfg_cleanup) |
153 | DEBUG_COUNTER (cprop) |
154 | DEBUG_COUNTER (cse2_move2add) |
155 | DEBUG_COUNTER (dce) |
156 | DEBUG_COUNTER (dce_fast) |
157 | DEBUG_COUNTER (dce_ud) |
158 | DEBUG_COUNTER (delete_trivial_dead) |
159 | DEBUG_COUNTER (devirt) |
160 | DEBUG_COUNTER (df_byte_scan) |
161 | DEBUG_COUNTER (dom_unreachable_edges) |
162 | DEBUG_COUNTER (dse) |
163 | DEBUG_COUNTER (dse1) |
164 | DEBUG_COUNTER (dse2) |
165 | DEBUG_COUNTER (form_fma) |
166 | DEBUG_COUNTER (gcse2_delete) |
167 | DEBUG_COUNTER (gimple_unroll) |
168 | DEBUG_COUNTER (global_alloc_at_func) |
169 | DEBUG_COUNTER (global_alloc_at_reg) |
170 | DEBUG_COUNTER (graphite_scop) |
171 | DEBUG_COUNTER (hoist) |
172 | DEBUG_COUNTER (hoist_insn) |
173 | DEBUG_COUNTER (ia64_sched2) |
174 | DEBUG_COUNTER (if_after_combine) |
175 | DEBUG_COUNTER (if_after_reload) |
176 | DEBUG_COUNTER (if_conversion) |
177 | DEBUG_COUNTER (if_conversion_tree) |
178 | DEBUG_COUNTER (if_to_switch) |
179 | DEBUG_COUNTER (ipa_attr) |
180 | DEBUG_COUNTER (ipa_cp_bits) |
181 | DEBUG_COUNTER (ipa_cp_values) |
182 | DEBUG_COUNTER (ipa_cp_vr) |
183 | DEBUG_COUNTER (ipa_mod_ref) |
184 | DEBUG_COUNTER (ipa_mod_ref_pta) |
185 | DEBUG_COUNTER (ipa_sra_params) |
186 | DEBUG_COUNTER (ipa_sra_retvalues) |
187 | DEBUG_COUNTER (ira_move) |
188 | DEBUG_COUNTER (ivopts_loop) |
189 | DEBUG_COUNTER (lim) |
190 | DEBUG_COUNTER (local_alloc_for_sched) |
191 | DEBUG_COUNTER (loop_unswitch) |
192 | DEBUG_COUNTER (match) |
193 | DEBUG_COUNTER (merged_ipa_icf) |
194 | DEBUG_COUNTER (phiopt_edge_range) |
195 | DEBUG_COUNTER (postreload_cse) |
196 | DEBUG_COUNTER (pre) |
197 | DEBUG_COUNTER (pre_insn) |
198 | DEBUG_COUNTER (prefetch) |
199 | DEBUG_COUNTER (registered_jump_thread) |
200 | DEBUG_COUNTER (sched2_func) |
201 | DEBUG_COUNTER (sched_block) |
202 | DEBUG_COUNTER (sched_breakdep) |
203 | DEBUG_COUNTER (sched_func) |
204 | DEBUG_COUNTER (sched_insn) |
205 | DEBUG_COUNTER (sched_region) |
206 | DEBUG_COUNTER (sel_sched_cnt) |
207 | DEBUG_COUNTER (sel_sched_insn_cnt) |
208 | DEBUG_COUNTER (sel_sched_region_cnt) |
209 | DEBUG_COUNTER (sms_sched_loop) |
210 | DEBUG_COUNTER (split_for_sched2) |
211 | DEBUG_COUNTER (store_merging) |
212 | DEBUG_COUNTER (store_motion) |
213 | DEBUG_COUNTER (stv_conversion) |
214 | DEBUG_COUNTER (tail_call) |
215 | DEBUG_COUNTER (tree_sra) |
216 | DEBUG_COUNTER (treepre_insert) |
217 | DEBUG_COUNTER (vect_loop) |
218 | DEBUG_COUNTER (vect_slp) |
219 | |