]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/print-rtl-function.c
Update copyright years.
[thirdparty/gcc.git] / gcc / print-rtl-function.c
CommitLineData
dd4b238a 1/* Print RTL functions for GCC.
8d9254fc 2 Copyright (C) 2016-2020 Free Software Foundation, Inc.
dd4b238a
DM
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 "tm.h"
24#include "rtl.h"
25#include "alias.h"
26#include "tree.h"
dd4b238a
DM
27#include "flags.h"
28#include "predict.h"
29#include "function.h"
30#include "basic-block.h"
31#include "print-rtl.h"
32#include "langhooks.h"
4d0cdd0c 33#include "memmodel.h"
dd4b238a 34#include "emit-rtl.h"
677aa9b4 35#include "varasm.h"
dd4b238a 36
4b77ac40
DM
37/* Print an "(edge-from)" or "(edge-to)" directive describing E
38 to OUTFILE. */
39
40static void
41print_edge (FILE *outfile, edge e, bool from)
42{
43 fprintf (outfile, " (%s ", from ? "edge-from" : "edge-to");
44 basic_block bb = from ? e->src : e->dest;
45 gcc_assert (bb);
46 switch (bb->index)
47 {
48 case ENTRY_BLOCK:
49 fprintf (outfile, "entry");
50 break;
51 case EXIT_BLOCK:
52 fprintf (outfile, "exit");
53 break;
54 default:
55 fprintf (outfile, "%i", bb->index);
56 break;
57 }
58
59 /* Express edge flags as a string with " | " separator.
60 e.g. (flags "FALLTHRU | DFS_BACK"). */
983496fe
DM
61 if (e->flags)
62 {
63 fprintf (outfile, " (flags \"");
64 bool seen_flag = false;
65#define DEF_EDGE_FLAG(NAME,IDX) \
4b77ac40
DM
66 do { \
67 if (e->flags & EDGE_##NAME) \
68 { \
69 if (seen_flag) \
70 fprintf (outfile, " | "); \
71 fprintf (outfile, "%s", (#NAME)); \
72 seen_flag = true; \
73 } \
74 } while (0);
75#include "cfg-flags.def"
76#undef DEF_EDGE_FLAG
77
983496fe
DM
78 fprintf (outfile, "\")");
79 }
80
81 fprintf (outfile, ")\n");
4b77ac40
DM
82}
83
84/* If BB is non-NULL, print the start of a "(block)" directive for it
85 to OUTFILE, otherwise do nothing. */
86
87static void
88begin_any_block (FILE *outfile, basic_block bb)
89{
90 if (!bb)
91 return;
92
93 edge e;
94 edge_iterator ei;
95
96 fprintf (outfile, " (block %i\n", bb->index);
97 FOR_EACH_EDGE (e, ei, bb->preds)
98 print_edge (outfile, e, true);
99}
100
101/* If BB is non-NULL, print the end of a "(block)" directive for it
102 to OUTFILE, otherwise do nothing. */
103
104static void
105end_any_block (FILE *outfile, basic_block bb)
106{
107 if (!bb)
108 return;
109
110 edge e;
111 edge_iterator ei;
112
113 FOR_EACH_EDGE (e, ei, bb->succs)
114 print_edge (outfile, e, false);
115 fprintf (outfile, " ) ;; block %i\n", bb->index);
116}
117
118/* Determine if INSN is of a kind that can have a basic block. */
119
120static bool
121can_have_basic_block_p (const rtx_insn *insn)
122{
123 rtx_code code = GET_CODE (insn);
124 if (code == BARRIER)
125 return false;
126 gcc_assert (GET_RTX_FORMAT (code)[2] == 'B');
127 return true;
128}
129
677aa9b4
DM
130/* Subroutine of print_param. Write the name of ARG, if any, to OUTFILE. */
131
132static void
133print_any_param_name (FILE *outfile, tree arg)
134{
135 if (DECL_NAME (arg))
136 fprintf (outfile, " \"%s\"", IDENTIFIER_POINTER (DECL_NAME (arg)));
137}
138
139/* Print a "(param)" directive for ARG to OUTFILE. */
140
141static void
142print_param (FILE *outfile, rtx_writer &w, tree arg)
143{
144 fprintf (outfile, " (param");
145 print_any_param_name (outfile, arg);
146 fprintf (outfile, "\n");
147
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 ();
152
153 /* Print DECL_INCOMING_RTL. */
154 fprintf (outfile, " (DECL_RTL_INCOMING ");
155 w.print_rtx (DECL_INCOMING_RTL (arg));
156 fprintf (outfile, ")");
157
158 w.finish_directive ();
159}
160
dd4b238a 161/* Write FN to OUTFILE in a form suitable for parsing, with indentation
4b77ac40
DM
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.
dd4b238a 165
7810c4eb
DM
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,
983496fe
DM
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),
7810c4eb
DM
172 - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc)
173
174 Example output (with COMPACT==true):
dd4b238a 175
4b77ac40 176 (function "times_two"
f4077222
DM
177 (param "i"
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 ])))
4b77ac40 181 (insn-chain
f4077222 182 (cnote 1 NOTE_INSN_DELETED)
4b77ac40
DM
183 (block 2
184 (edge-from entry (flags "FALLTHRU"))
f4077222
DM
185 (cnote 4 [bb 2] NOTE_INSN_BASIC_BLOCK)
186 (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
7810c4eb 187 (const_int -4)) [1 i+0 S4 A32])
f4077222
DM
188 (reg:SI di [ i ])) "t.c":2)
189 (cnote 3 NOTE_INSN_FUNCTION_BEG)
190 (cinsn 6 (set (reg:SI <2>)
7810c4eb 191 (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
f4077222
DM
192 (const_int -4)) [1 i+0 S4 A32])) "t.c":3)
193 (cinsn 7 (parallel [
194 (set (reg:SI <0> [ _2 ])
195 (ashift:SI (reg:SI <2>)
7810c4eb
DM
196 (const_int 1)))
197 (clobber (reg:CC flags))
198 ]) "t.c":3
f4077222 199 (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
7810c4eb 200 (const_int -4)) [1 i+0 S4 A32])
f4077222
DM
201 (const_int 1))))
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)
4b77ac40
DM
207 (edge-to exit (flags "FALLTHRU"))
208 ) ;; block 2
209 ) ;; insn-chain
210 (crtl
211 (return_rtx
7810c4eb 212 (reg/i:SI ax)
4b77ac40
DM
213 ) ;; return_rtx
214 ) ;; crtl
215 ) ;; function "times_two"
dd4b238a
DM
216*/
217
218DEBUG_FUNCTION void
7810c4eb 219print_rtx_function (FILE *outfile, function *fn, bool compact)
dd4b238a 220{
00439aef
DM
221 rtx_reuse_manager r;
222 rtx_writer w (outfile, 0, false, compact, &r);
223
224 /* Support "reuse_rtx" in the dump. */
225 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
226 r.preprocess (insn);
7810c4eb 227
dd4b238a
DM
228 tree fdecl = fn->decl;
229
60591d4e 230 const char *dname = lang_hooks.decl_printable_name (fdecl, 1);
dd4b238a
DM
231
232 fprintf (outfile, "(function \"%s\"\n", dname);
233
677aa9b4
DM
234 /* Params. */
235 for (tree arg = DECL_ARGUMENTS (fdecl); arg; arg = DECL_CHAIN (arg))
236 print_param (outfile, w, arg);
237
dd4b238a
DM
238 /* The instruction chain. */
239 fprintf (outfile, " (insn-chain\n");
4b77ac40 240 basic_block curr_bb = NULL;
dd4b238a 241 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
4b77ac40
DM
242 {
243 basic_block insn_bb;
244 if (can_have_basic_block_p (insn))
245 insn_bb = BLOCK_FOR_INSN (insn);
246 else
247 insn_bb = NULL;
248 if (curr_bb != insn_bb)
249 {
250 end_any_block (outfile, curr_bb);
251 curr_bb = insn_bb;
252 begin_any_block (outfile, curr_bb);
253 }
36cd856f 254 w.print_rtl_single_with_indent (insn, curr_bb ? 6 : 4);
4b77ac40
DM
255 }
256 end_any_block (outfile, curr_bb);
dd4b238a
DM
257 fprintf (outfile, " ) ;; insn-chain\n");
258
dd4b238a
DM
259 /* Additional RTL state. */
260 fprintf (outfile, " (crtl\n");
261 fprintf (outfile, " (return_rtx \n");
36cd856f 262 w.print_rtl_single_with_indent (crtl->return_rtx, 6);
dd4b238a
DM
263 fprintf (outfile, " ) ;; return_rtx\n");
264 fprintf (outfile, " ) ;; crtl\n");
265
266 fprintf (outfile, ") ;; function \"%s\"\n", dname);
267}