[ree] PR rtl-optimization/78038: Handle global register dataflow definitions in ree
[official-gcc.git] / gcc / print-rtl-function.c
blobf46304bf944ad07982c3651e54f643f6c28b6db4
1 /* Print RTL functions for GCC.
2 Copyright (C) 2016 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
9 version.
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
14 for more details.
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/>. */
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"
34 #include "memmodel.h"
35 #include "emit-rtl.h"
37 extern bool flag_compact;
39 /* Print an "(edge-from)" or "(edge-to)" directive describing E
40 to OUTFILE. */
42 static void
43 print_edge (FILE *outfile, edge e, bool from)
45 fprintf (outfile, " (%s ", from ? "edge-from" : "edge-to");
46 basic_block bb = from ? e->src : e->dest;
47 gcc_assert (bb);
48 switch (bb->index)
50 case ENTRY_BLOCK:
51 fprintf (outfile, "entry");
52 break;
53 case EXIT_BLOCK:
54 fprintf (outfile, "exit");
55 break;
56 default:
57 fprintf (outfile, "%i", bb->index);
58 break;
61 /* Express edge flags as a string with " | " separator.
62 e.g. (flags "FALLTHRU | DFS_BACK"). */
63 if (e->flags)
65 fprintf (outfile, " (flags \"");
66 bool seen_flag = false;
67 #define DEF_EDGE_FLAG(NAME,IDX) \
68 do { \
69 if (e->flags & EDGE_##NAME) \
70 { \
71 if (seen_flag) \
72 fprintf (outfile, " | "); \
73 fprintf (outfile, "%s", (#NAME)); \
74 seen_flag = true; \
75 } \
76 } while (0);
77 #include "cfg-flags.def"
78 #undef DEF_EDGE_FLAG
80 fprintf (outfile, "\")");
83 fprintf (outfile, ")\n");
86 /* If BB is non-NULL, print the start of a "(block)" directive for it
87 to OUTFILE, otherwise do nothing. */
89 static void
90 begin_any_block (FILE *outfile, basic_block bb)
92 if (!bb)
93 return;
95 edge e;
96 edge_iterator ei;
98 fprintf (outfile, " (block %i\n", bb->index);
99 FOR_EACH_EDGE (e, ei, bb->preds)
100 print_edge (outfile, e, true);
103 /* If BB is non-NULL, print the end of a "(block)" directive for it
104 to OUTFILE, otherwise do nothing. */
106 static void
107 end_any_block (FILE *outfile, basic_block bb)
109 if (!bb)
110 return;
112 edge e;
113 edge_iterator ei;
115 FOR_EACH_EDGE (e, ei, bb->succs)
116 print_edge (outfile, e, false);
117 fprintf (outfile, " ) ;; block %i\n", bb->index);
120 /* Determine if INSN is of a kind that can have a basic block. */
122 static bool
123 can_have_basic_block_p (const rtx_insn *insn)
125 rtx_code code = GET_CODE (insn);
126 if (code == BARRIER)
127 return false;
128 gcc_assert (GET_RTX_FORMAT (code)[2] == 'B');
129 return true;
132 /* Write FN to OUTFILE in a form suitable for parsing, with indentation
133 and comments to make the structure easy for a human to grok. Track
134 the basic blocks of insns in the chain, wrapping those that are within
135 blocks within "(block)" directives.
137 If COMPACT, then instructions are printed in a compact form:
138 - INSN_UIDs are omitted, except for jumps and CODE_LABELs,
139 - INSN_CODEs are omitted,
140 - register numbers are omitted for hard and virtual regs, and
141 non-virtual pseudos are offset relative to the first such reg, and
142 printed with a '%' sigil e.g. "%0" for (LAST_VIRTUAL_REGISTER + 1),
143 - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc)
145 Example output (with COMPACT==true):
147 (function "times_two"
148 (insn-chain
149 (cnote NOTE_INSN_DELETED)
150 (block 2
151 (edge-from entry (flags "FALLTHRU"))
152 (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
153 (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
154 (const_int -4)) [1 i+0 S4 A32])
155 (reg:SI di [ i ])) "t.c":2
156 (nil))
157 (cnote NOTE_INSN_FUNCTION_BEG)
158 (cinsn (set (reg:SI %2)
159 (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
160 (const_int -4)) [1 i+0 S4 A32])) "t.c":3
161 (nil))
162 (cinsn (parallel [
163 (set (reg:SI %0 [ _2 ])
164 (ashift:SI (reg:SI %2)
165 (const_int 1)))
166 (clobber (reg:CC flags))
167 ]) "t.c":3
168 (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
169 (const_int -4)) [1 i+0 S4 A32])
170 (const_int 1))
171 (nil)))
172 (cinsn (set (reg:SI %1 [ <retval> ])
173 (reg:SI %0 [ _2 ])) "t.c":3
174 (nil))
175 (cinsn (set (reg/i:SI ax)
176 (reg:SI %1 [ <retval> ])) "t.c":4
177 (nil))
178 (cinsn (use (reg/i:SI ax)) "t.c":4
179 (nil))
180 (edge-to exit (flags "FALLTHRU"))
181 ) ;; block 2
182 ) ;; insn-chain
183 (crtl
184 (return_rtx
185 (reg/i:SI ax)
186 ) ;; return_rtx
187 ) ;; crtl
188 ) ;; function "times_two"
191 DEBUG_FUNCTION void
192 print_rtx_function (FILE *outfile, function *fn, bool compact)
194 flag_compact = compact;
196 tree fdecl = fn->decl;
198 const char *dname = lang_hooks.decl_printable_name (fdecl, 2);
200 fprintf (outfile, "(function \"%s\"\n", dname);
202 /* The instruction chain. */
203 fprintf (outfile, " (insn-chain\n");
204 basic_block curr_bb = NULL;
205 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
207 basic_block insn_bb;
208 if (can_have_basic_block_p (insn))
209 insn_bb = BLOCK_FOR_INSN (insn);
210 else
211 insn_bb = NULL;
212 if (curr_bb != insn_bb)
214 end_any_block (outfile, curr_bb);
215 curr_bb = insn_bb;
216 begin_any_block (outfile, curr_bb);
218 print_rtl_single_with_indent (outfile, insn, curr_bb ? 6 : 4);
220 end_any_block (outfile, curr_bb);
221 fprintf (outfile, " ) ;; insn-chain\n");
223 /* Additional RTL state. */
224 fprintf (outfile, " (crtl\n");
225 fprintf (outfile, " (return_rtx \n");
226 print_rtl_single_with_indent (outfile, crtl->return_rtx, 6);
227 fprintf (outfile, " ) ;; return_rtx\n");
228 fprintf (outfile, " ) ;; crtl\n");
230 fprintf (outfile, ") ;; function \"%s\"\n", dname);
232 flag_compact = false;