1 /* Code for GIMPLE range trace and debugging related routines.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by Andrew MacLeod <amacleod@redhat.com>
4 and Aldy Hernandez <aldyh@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
29 #include "gimple-pretty-print.h"
30 #include "gimple-iterator.h"
32 #include "fold-const.h"
35 #include "tree-scalar-evolution.h"
36 #include "gimple-range.h"
39 // Breakpoint to trap at a specific index. From GDB, this provides a simple
40 // place to put a breakpoint to stop at a given trace line.
41 // ie. b range_tracer::breakpoint if index == 45678
44 range_tracer::breakpoint (unsigned index ATTRIBUTE_UNUSED
)
48 // Construct a range_tracer with component NAME.
50 range_tracer::range_tracer (const char *name
)
52 gcc_checking_assert (strlen(name
) < name_len
-1);
53 strcpy (component
, name
);
58 // This routine does the initial line spacing/indenting for a trace.
59 // If BLANKS is false, then IDX is printed, otherwise spaces.
62 range_tracer::print_prefix (unsigned idx
, bool blanks
)
64 // Print counter index as well as INDENT spaces.
66 fprintf (dump_file
, "%-7u ", idx
);
68 fprintf (dump_file
, " ");
69 fprintf (dump_file
, "%s ", component
);
71 for (x
= 0; x
< indent
; x
++)
72 fputc (' ', dump_file
);
75 // If dumping, return the next call index and print the prefix for the next
76 // output line. If not, return 0.
77 // Counter is static to monotonically increase across the compilation unit.
80 range_tracer::do_header (const char *str
)
82 static unsigned trace_count
= 0;
84 unsigned idx
= ++trace_count
;
85 print_prefix (idx
, false);
86 fprintf (dump_file
, "%s", str
);
92 // Print a line without starting or ending a trace.
95 range_tracer::print (unsigned counter
, const char *str
)
97 print_prefix (counter
, true);
98 fprintf (dump_file
, "%s", str
);
101 // End a trace and print the CALLER, NAME, and RESULT and range R,
104 range_tracer::trailer (unsigned counter
, const char *caller
, bool result
,
105 tree name
, const vrange
&r
)
107 gcc_checking_assert (tracing
&& counter
!= 0);
110 print_prefix (counter
, true);
111 fputs(result
? "TRUE : " : "FALSE : ", dump_file
);
112 fprintf (dump_file
, "(%u) ", counter
);
113 fputs (caller
, dump_file
);
114 fputs (" (",dump_file
);
116 print_generic_expr (dump_file
, name
, TDF_SLIM
);
117 fputs (") ",dump_file
);
121 fputc('\n', dump_file
);
124 fputc('\n', dump_file
);
127 // =========================================
128 // Debugging helpers.
129 // =========================================
131 // Query all statements in the IL to precalculate computable ranges in RANGER.
134 debug_seed_ranger (gimple_ranger
&ranger
)
136 // Recalculate SCEV to make sure the dump lists everything.
137 if (scev_initialized_p ())
144 gimple_stmt_iterator gsi
;
145 FOR_EACH_BB_FN (bb
, cfun
)
146 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
148 gimple
*stmt
= gsi_stmt (gsi
);
150 if (is_gimple_debug (stmt
))
153 if (tree type
= gimple_range_type (stmt
))
155 Value_Range
r (type
);
156 ranger
.range_of_stmt (r
, stmt
);
161 // Change the current dump_file and dump_flags to F and FLAGS while
162 // saving them for later restoring.
164 push_dump_file::push_dump_file (FILE *f
, dump_flags_t flags
)
166 old_dump_file
= dump_file
;
167 old_dump_flags
= dump_flags
;
172 // Restore saved dump_file and dump_flags.
174 push_dump_file::~push_dump_file ()
176 dump_file
= old_dump_file
;
177 dump_flags
= old_dump_flags
;
180 // Dump all that ranger knows for the current function.
183 dump_ranger (FILE *out
)
185 push_dump_file
save (out
, dump_flags
);
186 gimple_ranger ranger
;
188 fprintf (out
, ";; Function ");
189 print_generic_expr (out
, current_function_decl
);
192 debug_seed_ranger (ranger
);
199 dump_ranger (stderr
);
202 // Dump all that ranger knows on a path of BBs.
204 // Note that the blocks are in reverse order, thus the exit block is
208 dump_ranger (FILE *dump_file
, const vec
<basic_block
> &path
)
210 if (path
.length () == 0)
212 fprintf (dump_file
, "empty\n");
216 gimple_ranger ranger
;
217 debug_seed_ranger (ranger
);
219 unsigned i
= path
.length ();
223 ranger
.dump_bb (dump_file
, path
[i
]);
229 debug_ranger (const vec
<basic_block
> &path
)
231 dump_ranger (stderr
, path
);
234 #include "gimple-range-tests.cc"