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