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