libgo: minor Makefile improvements
[official-gcc.git] / gcc / print-rtl-function.c
blobf37e1b7dbc50e8eec8f76203208f44d36b84be97
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 /* Print an "(edge-from)" or "(edge-to)" directive describing E
38 to OUTFILE. */
40 static void
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;
45 gcc_assert (bb);
46 switch (bb->index)
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;
59 /* Express edge flags as a string with " | " separator.
60 e.g. (flags "FALLTHRU | DFS_BACK"). */
61 if (e->flags)
63 fprintf (outfile, " (flags \"");
64 bool seen_flag = false;
65 #define DEF_EDGE_FLAG(NAME,IDX) \
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
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. */
87 static void
88 begin_any_block (FILE *outfile, basic_block bb)
90 if (!bb)
91 return;
93 edge e;
94 edge_iterator ei;
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. */
104 static void
105 end_any_block (FILE *outfile, basic_block bb)
107 if (!bb)
108 return;
110 edge e;
111 edge_iterator ei;
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. */
120 static bool
121 can_have_basic_block_p (const rtx_insn *insn)
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;
130 /* Write FN to OUTFILE in a form suitable for parsing, with indentation
131 and comments to make the structure easy for a human to grok. Track
132 the basic blocks of insns in the chain, wrapping those that are within
133 blocks within "(block)" directives.
135 If COMPACT, then instructions are printed in a compact form:
136 - INSN_UIDs are omitted, except for jumps and CODE_LABELs,
137 - INSN_CODEs are omitted,
138 - register numbers are omitted for hard and virtual regs, and
139 non-virtual pseudos are offset relative to the first such reg, and
140 printed with a '%' sigil e.g. "%0" for (LAST_VIRTUAL_REGISTER + 1),
141 - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc)
143 Example output (with COMPACT==true):
145 (function "times_two"
146 (insn-chain
147 (cnote NOTE_INSN_DELETED)
148 (block 2
149 (edge-from entry (flags "FALLTHRU"))
150 (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
151 (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
152 (const_int -4)) [1 i+0 S4 A32])
153 (reg:SI di [ i ])) "t.c":2
154 (nil))
155 (cnote NOTE_INSN_FUNCTION_BEG)
156 (cinsn (set (reg:SI %2)
157 (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
158 (const_int -4)) [1 i+0 S4 A32])) "t.c":3
159 (nil))
160 (cinsn (parallel [
161 (set (reg:SI %0 [ _2 ])
162 (ashift:SI (reg:SI %2)
163 (const_int 1)))
164 (clobber (reg:CC flags))
165 ]) "t.c":3
166 (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
167 (const_int -4)) [1 i+0 S4 A32])
168 (const_int 1))
169 (nil)))
170 (cinsn (set (reg:SI %1 [ <retval> ])
171 (reg:SI %0 [ _2 ])) "t.c":3
172 (nil))
173 (cinsn (set (reg/i:SI ax)
174 (reg:SI %1 [ <retval> ])) "t.c":4
175 (nil))
176 (cinsn (use (reg/i:SI ax)) "t.c":4
177 (nil))
178 (edge-to exit (flags "FALLTHRU"))
179 ) ;; block 2
180 ) ;; insn-chain
181 (crtl
182 (return_rtx
183 (reg/i:SI ax)
184 ) ;; return_rtx
185 ) ;; crtl
186 ) ;; function "times_two"
189 DEBUG_FUNCTION void
190 print_rtx_function (FILE *outfile, function *fn, bool compact)
192 rtx_writer w (outfile, 0, false, compact);
194 tree fdecl = fn->decl;
196 const char *dname = lang_hooks.decl_printable_name (fdecl, 2);
198 fprintf (outfile, "(function \"%s\"\n", dname);
200 /* The instruction chain. */
201 fprintf (outfile, " (insn-chain\n");
202 basic_block curr_bb = NULL;
203 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
205 basic_block insn_bb;
206 if (can_have_basic_block_p (insn))
207 insn_bb = BLOCK_FOR_INSN (insn);
208 else
209 insn_bb = NULL;
210 if (curr_bb != insn_bb)
212 end_any_block (outfile, curr_bb);
213 curr_bb = insn_bb;
214 begin_any_block (outfile, curr_bb);
216 w.print_rtl_single_with_indent (insn, curr_bb ? 6 : 4);
218 end_any_block (outfile, curr_bb);
219 fprintf (outfile, " ) ;; insn-chain\n");
221 /* Additional RTL state. */
222 fprintf (outfile, " (crtl\n");
223 fprintf (outfile, " (return_rtx \n");
224 w.print_rtl_single_with_indent (crtl->return_rtx, 6);
225 fprintf (outfile, " ) ;; return_rtx\n");
226 fprintf (outfile, " ) ;; crtl\n");
228 fprintf (outfile, ") ;; function \"%s\"\n", dname);