]> gcc.gnu.org Git - gcc.git/blame - gcc/dumpfile.c
Update copyright years.
[gcc.git] / gcc / dumpfile.c
CommitLineData
b5f47924 1/* Dump infrastructure for optimizations and intermediate representation.
5624e564 2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
b5f47924
SS
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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 "diagnostic-core.h"
24#include "dumpfile.h"
b5f47924 25#include "tree.h"
cf2d1b38 26#include "gimple-pretty-print.h"
47e0da37 27#include "context.h"
b5f47924
SS
28
29/* If non-NULL, return one past-the-end of the matching SUBPART of
30 the WHOLE string. */
31#define skip_leading_substring(whole, part) \
32 (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
33
34static int pflags; /* current dump_flags */
35static int alt_flags; /* current opt_info flags */
b5f47924
SS
36
37static void dump_loc (int, FILE *, source_location);
b5f47924
SS
38static FILE *dump_open_alternate_stream (struct dump_file_info *);
39
73fbfcad
SS
40/* These are currently used for communicating between passes.
41 However, instead of accessing them directly, the passes can use
42 dump_printf () for dumps. */
43FILE *dump_file = NULL;
44FILE *alt_dump_file = NULL;
45const char *dump_file_name;
2b4e6bf1 46int dump_flags;
73fbfcad 47
b5f47924
SS
48/* Table of tree dump switches. This must be consistent with the
49 TREE_DUMP_INDEX enumeration in dumpfile.h. */
50static struct dump_file_info dump_files[TDI_end] =
51{
10fdd6e9 52 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, false},
b5f47924 53 {".cgraph", "ipa-cgraph", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
10fdd6e9 54 0, 0, 0, 0, 0, false},
eefe9a99 55 {".type-inheritance", "ipa-type-inheritance", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
10fdd6e9 56 0, 0, 0, 0, 0, false},
b5f47924 57 {".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
10fdd6e9 58 0, 0, 0, 0, 1, false},
b5f47924 59 {".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
10fdd6e9 60 0, 0, 0, 0, 2, false},
b5f47924 61 {".original", "tree-original", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
10fdd6e9 62 0, 0, 0, 0, 3, false},
b5f47924 63 {".gimple", "tree-gimple", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
10fdd6e9 64 0, 0, 0, 0, 4, false},
b5f47924 65 {".nested", "tree-nested", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
10fdd6e9 66 0, 0, 0, 0, 5, false},
af9acf91 67#define FIRST_AUTO_NUMBERED_DUMP 6
b5f47924
SS
68
69 {NULL, "tree-all", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
10fdd6e9 70 0, 0, 0, 0, 0, false},
b5f47924 71 {NULL, "rtl-all", NULL, NULL, NULL, NULL, NULL, TDF_RTL,
10fdd6e9 72 0, 0, 0, 0, 0, false},
b5f47924 73 {NULL, "ipa-all", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
10fdd6e9 74 0, 0, 0, 0, 0, false},
b5f47924
SS
75};
76
b5f47924
SS
77/* Define a name->number mapping for a dump flag value. */
78struct dump_option_value_info
79{
80 const char *const name; /* the name of the value */
81 const int value; /* the value of the name */
82};
83
84/* Table of dump options. This must be consistent with the TDF_* flags
85 in dumpfile.h and opt_info_options below. */
86static const struct dump_option_value_info dump_options[] =
87{
88 {"address", TDF_ADDRESS},
89 {"asmname", TDF_ASMNAME},
90 {"slim", TDF_SLIM},
91 {"raw", TDF_RAW},
92 {"graph", TDF_GRAPH},
93 {"details", (TDF_DETAILS | MSG_OPTIMIZED_LOCATIONS
94 | MSG_MISSED_OPTIMIZATION
95 | MSG_NOTE)},
96 {"cselib", TDF_CSELIB},
97 {"stats", TDF_STATS},
98 {"blocks", TDF_BLOCKS},
99 {"vops", TDF_VOPS},
100 {"lineno", TDF_LINENO},
101 {"uid", TDF_UID},
102 {"stmtaddr", TDF_STMTADDR},
103 {"memsyms", TDF_MEMSYMS},
104 {"verbose", TDF_VERBOSE},
105 {"eh", TDF_EH},
106 {"alias", TDF_ALIAS},
107 {"nouid", TDF_NOUID},
108 {"enumerate_locals", TDF_ENUMERATE_LOCALS},
109 {"scev", TDF_SCEV},
f14726bd
TJ
110 {"optimized", MSG_OPTIMIZED_LOCATIONS},
111 {"missed", MSG_MISSED_OPTIMIZATION},
112 {"note", MSG_NOTE},
113 {"optall", MSG_ALL},
b5f47924
SS
114 {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
115 | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
116 | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV)},
117 {NULL, 0}
118};
119
2b4e6bf1
SS
120/* A subset of the dump_options table which is used for -fopt-info
121 types. This must be consistent with the MSG_* flags in dumpfile.h.
b5f47924 122 */
2b4e6bf1 123static const struct dump_option_value_info optinfo_verbosity_options[] =
b5f47924
SS
124{
125 {"optimized", MSG_OPTIMIZED_LOCATIONS},
126 {"missed", MSG_MISSED_OPTIMIZATION},
127 {"note", MSG_NOTE},
2b4e6bf1
SS
128 {"all", MSG_ALL},
129 {NULL, 0}
130};
131
132/* Flags used for -fopt-info groups. */
133static const struct dump_option_value_info optgroup_options[] =
134{
135 {"ipa", OPTGROUP_IPA},
136 {"loop", OPTGROUP_LOOP},
137 {"inline", OPTGROUP_INLINE},
138 {"vec", OPTGROUP_VEC},
139 {"optall", OPTGROUP_ALL},
b5f47924
SS
140 {NULL, 0}
141};
142
47e0da37
DM
143gcc::dump_manager::dump_manager ():
144 m_next_dump (FIRST_AUTO_NUMBERED_DUMP),
145 m_extra_dump_files (NULL),
146 m_extra_dump_files_in_use (0),
147 m_extra_dump_files_alloced (0)
148{
149}
150
10fdd6e9
DM
151gcc::dump_manager::~dump_manager ()
152{
153 for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
154 {
155 dump_file_info *dfi = &m_extra_dump_files[i];
156 /* suffix, swtch, glob are statically allocated for the entries
157 in dump_files, and for statistics, but are dynamically allocated
158 for those for passes. */
159 if (dfi->owns_strings)
160 {
161 XDELETEVEC (const_cast <char *> (dfi->suffix));
162 XDELETEVEC (const_cast <char *> (dfi->swtch));
163 XDELETEVEC (const_cast <char *> (dfi->glob));
164 }
165 /* These, if non-NULL, are always dynamically allocated. */
166 XDELETEVEC (const_cast <char *> (dfi->pfilename));
167 XDELETEVEC (const_cast <char *> (dfi->alt_filename));
168 }
169 XDELETEVEC (m_extra_dump_files);
170}
171
b5f47924 172unsigned int
47e0da37 173gcc::dump_manager::
b5f47924 174dump_register (const char *suffix, const char *swtch, const char *glob,
10fdd6e9
DM
175 int flags, int optgroup_flags,
176 bool take_ownership)
b5f47924 177{
47e0da37 178 int num = m_next_dump++;
b5f47924 179
47e0da37 180 size_t count = m_extra_dump_files_in_use++;
b5f47924 181
47e0da37 182 if (count >= m_extra_dump_files_alloced)
b5f47924 183 {
47e0da37
DM
184 if (m_extra_dump_files_alloced == 0)
185 m_extra_dump_files_alloced = 32;
b5f47924 186 else
47e0da37
DM
187 m_extra_dump_files_alloced *= 2;
188 m_extra_dump_files = XRESIZEVEC (struct dump_file_info,
189 m_extra_dump_files,
190 m_extra_dump_files_alloced);
b5f47924
SS
191 }
192
47e0da37
DM
193 memset (&m_extra_dump_files[count], 0, sizeof (struct dump_file_info));
194 m_extra_dump_files[count].suffix = suffix;
195 m_extra_dump_files[count].swtch = swtch;
196 m_extra_dump_files[count].glob = glob;
197 m_extra_dump_files[count].pflags = flags;
198 m_extra_dump_files[count].optgroup_flags = optgroup_flags;
199 m_extra_dump_files[count].num = num;
10fdd6e9 200 m_extra_dump_files[count].owns_strings = take_ownership;
b5f47924
SS
201
202 return count + TDI_end;
203}
204
205
206/* Return the dump_file_info for the given phase. */
207
208struct dump_file_info *
47e0da37
DM
209gcc::dump_manager::
210get_dump_file_info (int phase) const
b5f47924
SS
211{
212 if (phase < TDI_end)
213 return &dump_files[phase];
47e0da37 214 else if ((size_t) (phase - TDI_end) >= m_extra_dump_files_in_use)
b5f47924
SS
215 return NULL;
216 else
47e0da37 217 return m_extra_dump_files + (phase - TDI_end);
b5f47924
SS
218}
219
799505ae
DM
220/* Locate the dump_file_info with swtch equal to SWTCH,
221 or return NULL if no such dump_file_info exists. */
222
223struct dump_file_info *
224gcc::dump_manager::
225get_dump_file_info_by_switch (const char *swtch) const
226{
227 for (unsigned i = 0; i < m_extra_dump_files_in_use; i++)
228 if (0 == strcmp (m_extra_dump_files[i].swtch, swtch))
229 return &m_extra_dump_files[i];
230
231 /* Not found. */
232 return NULL;
233}
234
b5f47924
SS
235
236/* Return the name of the dump file for the given phase.
799505ae
DM
237 The caller is responsible for calling free on the returned
238 buffer.
b5f47924
SS
239 If the dump is not enabled, returns NULL. */
240
241char *
47e0da37
DM
242gcc::dump_manager::
243get_dump_file_name (int phase) const
b5f47924 244{
b5f47924
SS
245 struct dump_file_info *dfi;
246
247 if (phase == TDI_none)
248 return NULL;
249
250 dfi = get_dump_file_info (phase);
799505ae
DM
251
252 return get_dump_file_name (dfi);
253}
254
255/* Return the name of the dump file for the given dump_file_info.
256 The caller is responsible for calling free on the returned
257 buffer.
258 If the dump is not enabled, returns NULL. */
259
260char *
261gcc::dump_manager::
262get_dump_file_name (struct dump_file_info *dfi) const
263{
264 char dump_id[10];
265
266 gcc_assert (dfi);
267
b5f47924
SS
268 if (dfi->pstate == 0)
269 return NULL;
270
271 /* If available, use the command line dump filename. */
272 if (dfi->pfilename)
273 return xstrdup (dfi->pfilename);
274
275 if (dfi->num < 0)
276 dump_id[0] = '\0';
277 else
278 {
279 char suffix;
280 if (dfi->pflags & TDF_TREE)
281 suffix = 't';
282 else if (dfi->pflags & TDF_IPA)
283 suffix = 'i';
284 else
285 suffix = 'r';
286
287 if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
288 dump_id[0] = '\0';
289 }
290
291 return concat (dump_base_name, dump_id, dfi->suffix, NULL);
292}
293
294/* For a given DFI, open an alternate dump filename (which could also
295 be a standard stream such as stdout/stderr). If the alternate dump
296 file cannot be opened, return NULL. */
297
298static FILE *
299dump_open_alternate_stream (struct dump_file_info *dfi)
300{
301 FILE *stream ;
302 if (!dfi->alt_filename)
303 return NULL;
304
305 if (dfi->alt_stream)
306 return dfi->alt_stream;
307
c3284718 308 stream = strcmp ("stderr", dfi->alt_filename) == 0
b5f47924 309 ? stderr
c3284718
RS
310 : strcmp ("stdout", dfi->alt_filename) == 0
311 ? stdout
b5f47924
SS
312 : fopen (dfi->alt_filename, dfi->alt_state < 0 ? "w" : "a");
313
314 if (!stream)
315 error ("could not open dump file %qs: %m", dfi->alt_filename);
316 else
317 dfi->alt_state = 1;
318
319 return stream;
320}
321
322/* Print source location on DFILE if enabled. */
323
324void
325dump_loc (int dump_kind, FILE *dfile, source_location loc)
326{
b5f47924
SS
327 if (dump_kind)
328 {
502498d5 329 if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
e645e942 330 fprintf (dfile, "%s:%d:%d: note: ", LOCATION_FILE (loc),
103ff0d6 331 LOCATION_LINE (loc), LOCATION_COLUMN (loc));
a3d7af04 332 else if (current_function_decl)
e645e942 333 fprintf (dfile, "%s:%d:%d: note: ",
b5f47924 334 DECL_SOURCE_FILE (current_function_decl),
103ff0d6
TJ
335 DECL_SOURCE_LINE (current_function_decl),
336 DECL_SOURCE_COLUMN (current_function_decl));
b5f47924
SS
337 }
338}
339
340/* Dump gimple statement GS with SPC indentation spaces and
341 EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
342
343void
344dump_gimple_stmt (int dump_kind, int extra_dump_flags, gimple gs, int spc)
345{
346 if (dump_file && (dump_kind & pflags))
347 print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
348
349 if (alt_dump_file && (dump_kind & alt_flags))
350 print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
351}
352
353/* Similar to dump_gimple_stmt, except additionally print source location. */
354
355void
356dump_gimple_stmt_loc (int dump_kind, source_location loc, int extra_dump_flags,
357 gimple gs, int spc)
358{
359 if (dump_file && (dump_kind & pflags))
360 {
361 dump_loc (dump_kind, dump_file, loc);
362 print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
363 }
364
365 if (alt_dump_file && (dump_kind & alt_flags))
366 {
367 dump_loc (dump_kind, alt_dump_file, loc);
368 print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
369 }
370}
371
372/* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
373 DUMP_KIND is enabled. */
374
375void
376dump_generic_expr (int dump_kind, int extra_dump_flags, tree t)
377{
378 if (dump_file && (dump_kind & pflags))
379 print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
380
381 if (alt_dump_file && (dump_kind & alt_flags))
382 print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
383}
384
385
386/* Similar to dump_generic_expr, except additionally print the source
387 location. */
388
389void
390dump_generic_expr_loc (int dump_kind, source_location loc,
391 int extra_dump_flags, tree t)
392{
393 if (dump_file && (dump_kind & pflags))
394 {
395 dump_loc (dump_kind, dump_file, loc);
396 print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
397 }
398
399 if (alt_dump_file && (dump_kind & alt_flags))
400 {
401 dump_loc (dump_kind, alt_dump_file, loc);
402 print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
403 }
404}
405
406/* Output a formatted message using FORMAT on appropriate dump streams. */
407
408void
409dump_printf (int dump_kind, const char *format, ...)
410{
411 if (dump_file && (dump_kind & pflags))
412 {
413 va_list ap;
414 va_start (ap, format);
415 vfprintf (dump_file, format, ap);
416 va_end (ap);
417 }
418
419 if (alt_dump_file && (dump_kind & alt_flags))
420 {
421 va_list ap;
422 va_start (ap, format);
423 vfprintf (alt_dump_file, format, ap);
424 va_end (ap);
425 }
426}
427
428/* Similar to dump_printf, except source location is also printed. */
429
430void
431dump_printf_loc (int dump_kind, source_location loc, const char *format, ...)
432{
433 if (dump_file && (dump_kind & pflags))
434 {
435 va_list ap;
436 dump_loc (dump_kind, dump_file, loc);
437 va_start (ap, format);
438 vfprintf (dump_file, format, ap);
439 va_end (ap);
440 }
441
442 if (alt_dump_file && (dump_kind & alt_flags))
443 {
444 va_list ap;
445 dump_loc (dump_kind, alt_dump_file, loc);
446 va_start (ap, format);
447 vfprintf (alt_dump_file, format, ap);
448 va_end (ap);
449 }
450}
451
452/* Start a dump for PHASE. Store user-supplied dump flags in
453 *FLAG_PTR. Return the number of streams opened. Set globals
454 DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
2b4e6bf1
SS
455 set dump_flags appropriately for both pass dump stream and
456 -fopt-info stream. */
b5f47924
SS
457
458int
47e0da37 459gcc::dump_manager::
b5f47924
SS
460dump_start (int phase, int *flag_ptr)
461{
462 int count = 0;
463 char *name;
464 struct dump_file_info *dfi;
465 FILE *stream;
74911c3c 466 if (phase == TDI_none || !dump_phase_enabled_p (phase))
b5f47924
SS
467 return 0;
468
469 dfi = get_dump_file_info (phase);
470 name = get_dump_file_name (phase);
471 if (name)
472 {
c3284718 473 stream = strcmp ("stderr", name) == 0
b5f47924 474 ? stderr
c3284718
RS
475 : strcmp ("stdout", name) == 0
476 ? stdout
b5f47924
SS
477 : fopen (name, dfi->pstate < 0 ? "w" : "a");
478 if (!stream)
479 error ("could not open dump file %qs: %m", name);
480 else
481 {
482 dfi->pstate = 1;
483 count++;
484 }
485 free (name);
486 dfi->pstream = stream;
487 dump_file = dfi->pstream;
488 /* Initialize current dump flags. */
489 pflags = dfi->pflags;
490 }
491
492 stream = dump_open_alternate_stream (dfi);
493 if (stream)
494 {
495 dfi->alt_stream = stream;
496 count++;
497 alt_dump_file = dfi->alt_stream;
2b4e6bf1 498 /* Initialize current -fopt-info flags. */
b5f47924
SS
499 alt_flags = dfi->alt_flags;
500 }
501
502 if (flag_ptr)
503 *flag_ptr = dfi->pflags;
504
505 return count;
506}
507
508/* Finish a tree dump for PHASE and close associated dump streams. Also
509 reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
510
511void
47e0da37 512gcc::dump_manager::
b5f47924
SS
513dump_finish (int phase)
514{
515 struct dump_file_info *dfi;
516
517 if (phase < 0)
518 return;
519 dfi = get_dump_file_info (phase);
71191083 520 if (dfi->pstream && (!dfi->pfilename
c3284718
RS
521 || (strcmp ("stderr", dfi->pfilename) != 0
522 && strcmp ("stdout", dfi->pfilename) != 0)))
b5f47924
SS
523 fclose (dfi->pstream);
524
c3284718
RS
525 if (dfi->alt_stream && strcmp ("stderr", dfi->alt_filename) != 0
526 && strcmp ("stdout", dfi->alt_filename) != 0)
b5f47924
SS
527 fclose (dfi->alt_stream);
528
529 dfi->alt_stream = NULL;
530 dfi->pstream = NULL;
531 dump_file = NULL;
532 alt_dump_file = NULL;
533 dump_flags = TDI_none;
534 alt_flags = 0;
535 pflags = 0;
536}
537
538/* Begin a tree dump for PHASE. Stores any user supplied flag in
539 *FLAG_PTR and returns a stream to write to. If the dump is not
540 enabled, returns NULL.
541 Multiple calls will reopen and append to the dump file. */
542
543FILE *
544dump_begin (int phase, int *flag_ptr)
47e0da37
DM
545{
546 return g->get_dumps ()->dump_begin (phase, flag_ptr);
547}
548
549FILE *
550gcc::dump_manager::
551dump_begin (int phase, int *flag_ptr)
b5f47924
SS
552{
553 char *name;
554 struct dump_file_info *dfi;
555 FILE *stream;
556
74911c3c 557 if (phase == TDI_none || !dump_phase_enabled_p (phase))
b5f47924
SS
558 return NULL;
559
560 name = get_dump_file_name (phase);
561 if (!name)
562 return NULL;
563 dfi = get_dump_file_info (phase);
564
c3284718 565 stream = strcmp ("stderr", name) == 0
b5f47924 566 ? stderr
c3284718
RS
567 : strcmp ("stdout", name) == 0
568 ? stdout
b5f47924
SS
569 : fopen (name, dfi->pstate < 0 ? "w" : "a");
570
571 if (!stream)
572 error ("could not open dump file %qs: %m", name);
573 else
574 dfi->pstate = 1;
575 free (name);
576
577 if (flag_ptr)
578 *flag_ptr = dfi->pflags;
579
580 /* Initialize current flags */
581 pflags = dfi->pflags;
582 return stream;
583}
584
585/* Returns nonzero if dump PHASE is enabled for at least one stream.
586 If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
587 any phase. */
588
47e0da37
DM
589int
590gcc::dump_manager::
591dump_phase_enabled_p (int phase) const
b5f47924
SS
592{
593 if (phase == TDI_tree_all)
594 {
595 size_t i;
596 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
597 if (dump_files[i].pstate || dump_files[i].alt_state)
598 return 1;
47e0da37
DM
599 for (i = 0; i < m_extra_dump_files_in_use; i++)
600 if (m_extra_dump_files[i].pstate || m_extra_dump_files[i].alt_state)
b5f47924
SS
601 return 1;
602 return 0;
603 }
604 else
605 {
606 struct dump_file_info *dfi = get_dump_file_info (phase);
607 return dfi->pstate || dfi->alt_state;
608 }
609}
610
611/* Returns nonzero if tree dump PHASE has been initialized. */
612
613int
47e0da37
DM
614gcc::dump_manager::
615dump_initialized_p (int phase) const
b5f47924
SS
616{
617 struct dump_file_info *dfi = get_dump_file_info (phase);
618 return dfi->pstate > 0 || dfi->alt_state > 0;
619}
620
621/* Returns the switch name of PHASE. */
622
623const char *
624dump_flag_name (int phase)
47e0da37
DM
625{
626 return g->get_dumps ()->dump_flag_name (phase);
627}
628
629const char *
630gcc::dump_manager::
631dump_flag_name (int phase) const
b5f47924
SS
632{
633 struct dump_file_info *dfi = get_dump_file_info (phase);
634 return dfi->swtch;
635}
636
637/* Finish a tree dump for PHASE. STREAM is the stream created by
638 dump_begin. */
639
640void
641dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
642{
643 if (stream != stderr && stream != stdout)
644 fclose (stream);
645}
646
647/* Enable all tree dumps with FLAGS on FILENAME. Return number of
648 enabled tree dumps. */
649
47e0da37
DM
650int
651gcc::dump_manager::
b5f47924
SS
652dump_enable_all (int flags, const char *filename)
653{
654 int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
655 int n = 0;
656 size_t i;
657
658 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
659 {
660 if ((dump_files[i].pflags & ir_dump_type))
661 {
662 const char *old_filename = dump_files[i].pfilename;
663 dump_files[i].pstate = -1;
664 dump_files[i].pflags |= flags;
665 n++;
666 /* Override the existing filename. */
667 if (filename)
668 {
669 dump_files[i].pfilename = xstrdup (filename);
670 /* Since it is a command-line provided file, which is
671 common to all the phases, use it in append mode. */
672 dump_files[i].pstate = 1;
673 }
674 if (old_filename && filename != old_filename)
675 free (CONST_CAST (char *, old_filename));
676 }
677 }
678
47e0da37 679 for (i = 0; i < m_extra_dump_files_in_use; i++)
b5f47924 680 {
47e0da37 681 if ((m_extra_dump_files[i].pflags & ir_dump_type))
b5f47924 682 {
47e0da37
DM
683 const char *old_filename = m_extra_dump_files[i].pfilename;
684 m_extra_dump_files[i].pstate = -1;
685 m_extra_dump_files[i].pflags |= flags;
b5f47924
SS
686 n++;
687 /* Override the existing filename. */
688 if (filename)
689 {
47e0da37 690 m_extra_dump_files[i].pfilename = xstrdup (filename);
b5f47924
SS
691 /* Since it is a command-line provided file, which is
692 common to all the phases, use it in append mode. */
47e0da37 693 m_extra_dump_files[i].pstate = 1;
b5f47924
SS
694 }
695 if (old_filename && filename != old_filename)
696 free (CONST_CAST (char *, old_filename));
697 }
698 }
699
700 return n;
701}
702
2b4e6bf1
SS
703/* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
704 Enable dumps with FLAGS on FILENAME. Return the number of enabled
705 dumps. */
b5f47924 706
47e0da37
DM
707int
708gcc::dump_manager::
2b4e6bf1 709opt_info_enable_passes (int optgroup_flags, int flags, const char *filename)
b5f47924
SS
710{
711 int n = 0;
712 size_t i;
713
714 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
715 {
2b4e6bf1 716 if ((dump_files[i].optgroup_flags & optgroup_flags))
b5f47924
SS
717 {
718 const char *old_filename = dump_files[i].alt_filename;
719 /* Since this file is shared among different passes, it
720 should be opened in append mode. */
721 dump_files[i].alt_state = 1;
722 dump_files[i].alt_flags |= flags;
723 n++;
724 /* Override the existing filename. */
725 if (filename)
726 dump_files[i].alt_filename = xstrdup (filename);
727 if (old_filename && filename != old_filename)
728 free (CONST_CAST (char *, old_filename));
729 }
730 }
731
47e0da37 732 for (i = 0; i < m_extra_dump_files_in_use; i++)
b5f47924 733 {
47e0da37 734 if ((m_extra_dump_files[i].optgroup_flags & optgroup_flags))
b5f47924 735 {
47e0da37 736 const char *old_filename = m_extra_dump_files[i].alt_filename;
b5f47924
SS
737 /* Since this file is shared among different passes, it
738 should be opened in append mode. */
47e0da37
DM
739 m_extra_dump_files[i].alt_state = 1;
740 m_extra_dump_files[i].alt_flags |= flags;
b5f47924
SS
741 n++;
742 /* Override the existing filename. */
743 if (filename)
47e0da37 744 m_extra_dump_files[i].alt_filename = xstrdup (filename);
b5f47924
SS
745 if (old_filename && filename != old_filename)
746 free (CONST_CAST (char *, old_filename));
747 }
748 }
749
750 return n;
751}
752
753/* Parse ARG as a dump switch. Return nonzero if it is, and store the
754 relevant details in the dump_files array. */
755
47e0da37
DM
756int
757gcc::dump_manager::
b5f47924
SS
758dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
759{
760 const char *option_value;
761 const char *ptr;
762 int flags;
763
764 if (doglob && !dfi->glob)
765 return 0;
766
767 option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
768 if (!option_value)
769 return 0;
770
771 if (*option_value && *option_value != '-' && *option_value != '=')
772 return 0;
773
774 ptr = option_value;
775 flags = 0;
776
777 while (*ptr)
778 {
779 const struct dump_option_value_info *option_ptr;
780 const char *end_ptr;
781 const char *eq_ptr;
782 unsigned length;
783
784 while (*ptr == '-')
785 ptr++;
786 end_ptr = strchr (ptr, '-');
787 eq_ptr = strchr (ptr, '=');
788
789 if (eq_ptr && !end_ptr)
790 end_ptr = eq_ptr;
791
792 if (!end_ptr)
793 end_ptr = ptr + strlen (ptr);
794 length = end_ptr - ptr;
795
796 for (option_ptr = dump_options; option_ptr->name; option_ptr++)
797 if (strlen (option_ptr->name) == length
798 && !memcmp (option_ptr->name, ptr, length))
799 {
800 flags |= option_ptr->value;
801 goto found;
802 }
803
804 if (*ptr == '=')
805 {
806 /* Interpret rest of the argument as a dump filename. This
807 filename overrides other command line filenames. */
808 if (dfi->pfilename)
809 free (CONST_CAST (char *, dfi->pfilename));
810 dfi->pfilename = xstrdup (ptr + 1);
811 break;
812 }
813 else
814 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
815 length, ptr, dfi->swtch);
816 found:;
817 ptr = end_ptr;
818 }
819
820 dfi->pstate = -1;
821 dfi->pflags |= flags;
822
823 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
824 known dumps. */
825 if (dfi->suffix == NULL)
826 dump_enable_all (dfi->pflags, dfi->pfilename);
827
828 return 1;
829}
830
831int
47e0da37 832gcc::dump_manager::
b5f47924
SS
833dump_switch_p (const char *arg)
834{
835 size_t i;
836 int any = 0;
837
838 for (i = TDI_none + 1; i != TDI_end; i++)
839 any |= dump_switch_p_1 (arg, &dump_files[i], false);
840
841 /* Don't glob if we got a hit already */
842 if (!any)
843 for (i = TDI_none + 1; i != TDI_end; i++)
844 any |= dump_switch_p_1 (arg, &dump_files[i], true);
845
47e0da37
DM
846 for (i = 0; i < m_extra_dump_files_in_use; i++)
847 any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], false);
b5f47924
SS
848
849 if (!any)
47e0da37
DM
850 for (i = 0; i < m_extra_dump_files_in_use; i++)
851 any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], true);
b5f47924
SS
852
853
854 return any;
855}
856
2b4e6bf1
SS
857/* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
858 and filename. Return non-zero if it is a recognized switch. */
b5f47924
SS
859
860static int
2b4e6bf1
SS
861opt_info_switch_p_1 (const char *arg, int *flags, int *optgroup_flags,
862 char **filename)
b5f47924
SS
863{
864 const char *option_value;
865 const char *ptr;
866
867 option_value = arg;
868 ptr = option_value;
869
870 *filename = NULL;
871 *flags = 0;
2b4e6bf1 872 *optgroup_flags = 0;
b5f47924
SS
873
874 if (!ptr)
2b4e6bf1 875 return 1; /* Handle '-fopt-info' without any additional options. */
b5f47924
SS
876
877 while (*ptr)
878 {
879 const struct dump_option_value_info *option_ptr;
880 const char *end_ptr;
881 const char *eq_ptr;
882 unsigned length;
883
884 while (*ptr == '-')
885 ptr++;
886 end_ptr = strchr (ptr, '-');
887 eq_ptr = strchr (ptr, '=');
888
889 if (eq_ptr && !end_ptr)
890 end_ptr = eq_ptr;
891
892 if (!end_ptr)
893 end_ptr = ptr + strlen (ptr);
894 length = end_ptr - ptr;
895
2b4e6bf1
SS
896 for (option_ptr = optinfo_verbosity_options; option_ptr->name;
897 option_ptr++)
b5f47924
SS
898 if (strlen (option_ptr->name) == length
899 && !memcmp (option_ptr->name, ptr, length))
900 {
901 *flags |= option_ptr->value;
902 goto found;
903 }
904
2b4e6bf1
SS
905 for (option_ptr = optgroup_options; option_ptr->name; option_ptr++)
906 if (strlen (option_ptr->name) == length
907 && !memcmp (option_ptr->name, ptr, length))
908 {
909 *optgroup_flags |= option_ptr->value;
910 goto found;
911 }
912
b5f47924
SS
913 if (*ptr == '=')
914 {
915 /* Interpret rest of the argument as a dump filename. This
916 filename overrides other command line filenames. */
917 *filename = xstrdup (ptr + 1);
918 break;
919 }
920 else
2b4e6bf1
SS
921 {
922 warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
923 length, ptr, arg);
924 return 0;
925 }
b5f47924
SS
926 found:;
927 ptr = end_ptr;
928 }
929
930 return 1;
931}
932
933/* Return non-zero if ARG is a recognized switch for
934 -fopt-info. Return zero otherwise. */
935
936int
937opt_info_switch_p (const char *arg)
938{
939 int flags;
2b4e6bf1 940 int optgroup_flags;
b5f47924 941 char *filename;
2b4e6bf1 942 static char *file_seen = NULL;
47e0da37 943 gcc::dump_manager *dumps = g->get_dumps ();
b5f47924 944
2b4e6bf1
SS
945 if (!opt_info_switch_p_1 (arg, &flags, &optgroup_flags, &filename))
946 return 0;
b5f47924
SS
947
948 if (!filename)
949 filename = xstrdup ("stderr");
2b4e6bf1
SS
950
951 /* Bail out if a different filename has been specified. */
952 if (file_seen && strcmp (file_seen, filename))
953 {
954 warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
955 arg);
956 return 1;
957 }
958
959 file_seen = xstrdup (filename);
b5f47924 960 if (!flags)
5d318fd4 961 flags = MSG_OPTIMIZED_LOCATIONS;
2b4e6bf1
SS
962 if (!optgroup_flags)
963 optgroup_flags = OPTGROUP_ALL;
b5f47924 964
47e0da37 965 return dumps->opt_info_enable_passes (optgroup_flags, flags, filename);
b5f47924
SS
966}
967
b5f47924
SS
968/* Print basic block on the dump streams. */
969
970void
971dump_basic_block (int dump_kind, basic_block bb, int indent)
972{
973 if (dump_file && (dump_kind & pflags))
974 dump_bb (dump_file, bb, indent, TDF_DETAILS);
975 if (alt_dump_file && (dump_kind & alt_flags))
976 dump_bb (alt_dump_file, bb, indent, TDF_DETAILS);
977}
978
979/* Print information from the combine pass on dump_file. */
980
981void
982print_combine_total_stats (void)
983{
984 if (dump_file)
985 dump_combine_total_stats (dump_file);
986}
987
988/* Enable RTL dump for all the RTL passes. */
989
990bool
991enable_rtl_dump_file (void)
992{
47e0da37
DM
993 gcc::dump_manager *dumps = g->get_dumps ();
994 int num_enabled =
995 dumps->dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS, NULL);
996 return num_enabled > 0;
b5f47924 997}
This page took 0.844589 seconds and 5 git commands to generate.