1 /* Print RTL functions for GCC.
2 Copyright (C) 2016-2021 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
22 #include "coretypes.h"
30 #include "basic-block.h"
31 #include "print-rtl.h"
32 #include "langhooks.h"
37 /* Print an "(edge-from)" or "(edge-to)" directive describing E
41 print_edge (FILE *outfile
, edge e
, bool from
)
43 fprintf (outfile
, " (%s ", from
? "edge-from" : "edge-to");
44 basic_block bb
= from
? e
->src
: e
->dest
;
49 fprintf (outfile
, "entry");
52 fprintf (outfile
, "exit");
55 fprintf (outfile
, "%i", bb
->index
);
59 /* Express edge flags as a string with " | " separator.
60 e.g. (flags "FALLTHRU | DFS_BACK"). */
63 fprintf (outfile
, " (flags \"");
64 bool seen_flag
= false;
65 #define DEF_EDGE_FLAG(NAME,IDX) \
67 if (e->flags & EDGE_##NAME) \
70 fprintf (outfile, " | "); \
71 fprintf (outfile, "%s", (#NAME)); \
75 #include "cfg-flags.def"
78 fprintf (outfile
, "\")");
81 fprintf (outfile
, ")\n");
84 /* If BB is non-NULL, print the start of a "(block)" directive for it
85 to OUTFILE, otherwise do nothing. */
88 begin_any_block (FILE *outfile
, basic_block bb
)
96 fprintf (outfile
, " (block %i\n", bb
->index
);
97 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
98 print_edge (outfile
, e
, true);
101 /* If BB is non-NULL, print the end of a "(block)" directive for it
102 to OUTFILE, otherwise do nothing. */
105 end_any_block (FILE *outfile
, basic_block bb
)
113 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
114 print_edge (outfile
, e
, false);
115 fprintf (outfile
, " ) ;; block %i\n", bb
->index
);
118 /* Determine if INSN is of a kind that can have a basic block. */
121 can_have_basic_block_p (const rtx_insn
*insn
)
123 rtx_code code
= GET_CODE (insn
);
126 gcc_assert (GET_RTX_FORMAT (code
)[2] == 'B');
130 /* Subroutine of print_param. Write the name of ARG, if any, to OUTFILE. */
133 print_any_param_name (FILE *outfile
, tree arg
)
136 fprintf (outfile
, " \"%s\"", IDENTIFIER_POINTER (DECL_NAME (arg
)));
139 /* Print a "(param)" directive for ARG to OUTFILE. */
142 print_param (FILE *outfile
, rtx_writer
&w
, tree arg
)
144 fprintf (outfile
, " (param");
145 print_any_param_name (outfile
, arg
);
146 fprintf (outfile
, "\n");
148 /* Print the value of DECL_RTL (without lazy-evaluation). */
149 fprintf (outfile
, " (DECL_RTL ");
150 w
.print_rtx (DECL_RTL_IF_SET (arg
));
151 w
.finish_directive ();
153 /* Print DECL_INCOMING_RTL. */
154 fprintf (outfile
, " (DECL_RTL_INCOMING ");
155 w
.print_rtx (DECL_INCOMING_RTL (arg
));
156 fprintf (outfile
, ")");
158 w
.finish_directive ();
161 /* Write FN to OUTFILE in a form suitable for parsing, with indentation
162 and comments to make the structure easy for a human to grok. Track
163 the basic blocks of insns in the chain, wrapping those that are within
164 blocks within "(block)" directives.
166 If COMPACT, then instructions are printed in a compact form:
167 - INSN_UIDs are omitted, except for jumps and CODE_LABELs,
168 - INSN_CODEs are omitted,
169 - register numbers are omitted for hard and virtual regs, and
170 non-virtual pseudos are offset relative to the first such reg, and
171 printed with a '%' sigil e.g. "%0" for (LAST_VIRTUAL_REGISTER + 1),
172 - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc)
174 Example output (with COMPACT==true):
176 (function "times_two"
178 (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
179 (const_int -4)) [1 i+0 S4 A32]))
180 (DECL_RTL_INCOMING (reg:SI di [ i ])))
182 (cnote 1 NOTE_INSN_DELETED)
184 (edge-from entry (flags "FALLTHRU"))
185 (cnote 4 [bb 2] NOTE_INSN_BASIC_BLOCK)
186 (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
187 (const_int -4)) [1 i+0 S4 A32])
188 (reg:SI di [ i ])) "t.c":2)
189 (cnote 3 NOTE_INSN_FUNCTION_BEG)
190 (cinsn 6 (set (reg:SI <2>)
191 (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
192 (const_int -4)) [1 i+0 S4 A32])) "t.c":3)
194 (set (reg:SI <0> [ _2 ])
195 (ashift:SI (reg:SI <2>)
197 (clobber (reg:CC flags))
199 (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
200 (const_int -4)) [1 i+0 S4 A32])
202 (cinsn 10 (set (reg:SI <1> [ <retval> ])
203 (reg:SI <0> [ _2 ])) "t.c":3)
204 (cinsn 14 (set (reg/i:SI ax)
205 (reg:SI <1> [ <retval> ])) "t.c":4)
206 (cinsn 15 (use (reg/i:SI ax)) "t.c":4)
207 (edge-to exit (flags "FALLTHRU"))
215 ) ;; function "times_two"
219 print_rtx_function (FILE *outfile
, function
*fn
, bool compact
)
222 rtx_writer
w (outfile
, 0, false, compact
, &r
);
224 /* Support "reuse_rtx" in the dump. */
225 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
228 tree fdecl
= fn
->decl
;
230 const char *dname
= lang_hooks
.decl_printable_name (fdecl
, 1);
232 fprintf (outfile
, "(function \"%s\"\n", dname
);
235 for (tree arg
= DECL_ARGUMENTS (fdecl
); arg
; arg
= DECL_CHAIN (arg
))
236 print_param (outfile
, w
, arg
);
238 /* The instruction chain. */
239 fprintf (outfile
, " (insn-chain\n");
240 basic_block curr_bb
= NULL
;
241 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
244 if (can_have_basic_block_p (insn
))
245 insn_bb
= BLOCK_FOR_INSN (insn
);
248 if (curr_bb
!= insn_bb
)
250 end_any_block (outfile
, curr_bb
);
252 begin_any_block (outfile
, curr_bb
);
254 w
.print_rtl_single_with_indent (insn
, curr_bb
? 6 : 4);
256 end_any_block (outfile
, curr_bb
);
257 fprintf (outfile
, " ) ;; insn-chain\n");
259 /* Additional RTL state. */
260 fprintf (outfile
, " (crtl\n");
261 fprintf (outfile
, " (return_rtx \n");
262 w
.print_rtl_single_with_indent (crtl
->return_rtx
, 6);
263 fprintf (outfile
, " ) ;; return_rtx\n");
264 fprintf (outfile
, " ) ;; crtl\n");
266 fprintf (outfile
, ") ;; function \"%s\"\n", dname
);