* es.po: Update.
[official-gcc.git] / gcc / print-rtl-function.c
blob88422263bbd16343ad70e144dd4a3097a9eb5a8f
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"
36 #include "varasm.h"
38 /* Print an "(edge-from)" or "(edge-to)" directive describing E
39 to OUTFILE. */
41 static void
42 print_edge (FILE *outfile, edge e, bool from)
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)
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;
60 /* Express edge flags as a string with " | " separator.
61 e.g. (flags "FALLTHRU | DFS_BACK"). */
62 if (e->flags)
64 fprintf (outfile, " (flags \"");
65 bool seen_flag = false;
66 #define DEF_EDGE_FLAG(NAME,IDX) \
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
79 fprintf (outfile, "\")");
82 fprintf (outfile, ")\n");
85 /* If BB is non-NULL, print the start of a "(block)" directive for it
86 to OUTFILE, otherwise do nothing. */
88 static void
89 begin_any_block (FILE *outfile, basic_block bb)
91 if (!bb)
92 return;
94 edge e;
95 edge_iterator ei;
97 fprintf (outfile, " (block %i\n", bb->index);
98 FOR_EACH_EDGE (e, ei, bb->preds)
99 print_edge (outfile, e, true);
102 /* If BB is non-NULL, print the end of a "(block)" directive for it
103 to OUTFILE, otherwise do nothing. */
105 static void
106 end_any_block (FILE *outfile, basic_block bb)
108 if (!bb)
109 return;
111 edge e;
112 edge_iterator ei;
114 FOR_EACH_EDGE (e, ei, bb->succs)
115 print_edge (outfile, e, false);
116 fprintf (outfile, " ) ;; block %i\n", bb->index);
119 /* Determine if INSN is of a kind that can have a basic block. */
121 static bool
122 can_have_basic_block_p (const rtx_insn *insn)
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;
131 /* Subroutine of print_param. Write the name of ARG, if any, to OUTFILE. */
133 static void
134 print_any_param_name (FILE *outfile, tree arg)
136 if (DECL_NAME (arg))
137 fprintf (outfile, " \"%s\"", IDENTIFIER_POINTER (DECL_NAME (arg)));
140 /* Print a "(param)" directive for ARG to OUTFILE. */
142 static void
143 print_param (FILE *outfile, rtx_writer &w, tree arg)
145 fprintf (outfile, " (param");
146 print_any_param_name (outfile, arg);
147 fprintf (outfile, "\n");
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 ();
154 /* Print DECL_INCOMING_RTL. */
155 fprintf (outfile, " (DECL_RTL_INCOMING ");
156 w.print_rtx (DECL_INCOMING_RTL (arg));
157 fprintf (outfile, ")");
159 w.finish_directive ();
162 /* Write FN to OUTFILE in a form suitable for parsing, with indentation
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.
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,
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),
173 - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc)
175 Example output (with COMPACT==true):
177 (function "times_two"
178 (insn-chain
179 (cnote NOTE_INSN_DELETED)
180 (block 2
181 (edge-from entry (flags "FALLTHRU"))
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)
188 (cinsn (set (reg:SI %2)
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 [
193 (set (reg:SI %0 [ _2 ])
194 (ashift:SI (reg:SI %2)
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)))
202 (cinsn (set (reg:SI %1 [ <retval> ])
203 (reg:SI %0 [ _2 ])) "t.c":3
204 (nil))
205 (cinsn (set (reg/i:SI ax)
206 (reg:SI %1 [ <retval> ])) "t.c":4
207 (nil))
208 (cinsn (use (reg/i:SI ax)) "t.c":4
209 (nil))
210 (edge-to exit (flags "FALLTHRU"))
211 ) ;; block 2
212 ) ;; insn-chain
213 (crtl
214 (return_rtx
215 (reg/i:SI ax)
216 ) ;; return_rtx
217 ) ;; crtl
218 ) ;; function "times_two"
221 DEBUG_FUNCTION void
222 print_rtx_function (FILE *outfile, function *fn, bool compact)
224 rtx_writer w (outfile, 0, false, compact);
226 tree fdecl = fn->decl;
228 const char *dname = lang_hooks.decl_printable_name (fdecl, 2);
230 fprintf (outfile, "(function \"%s\"\n", dname);
232 /* Params. */
233 for (tree arg = DECL_ARGUMENTS (fdecl); arg; arg = DECL_CHAIN (arg))
234 print_param (outfile, w, arg);
236 /* The instruction chain. */
237 fprintf (outfile, " (insn-chain\n");
238 basic_block curr_bb = NULL;
239 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
241 basic_block insn_bb;
242 if (can_have_basic_block_p (insn))
243 insn_bb = BLOCK_FOR_INSN (insn);
244 else
245 insn_bb = NULL;
246 if (curr_bb != insn_bb)
248 end_any_block (outfile, curr_bb);
249 curr_bb = insn_bb;
250 begin_any_block (outfile, curr_bb);
252 w.print_rtl_single_with_indent (insn, curr_bb ? 6 : 4);
254 end_any_block (outfile, curr_bb);
255 fprintf (outfile, " ) ;; insn-chain\n");
257 /* Additional RTL state. */
258 fprintf (outfile, " (crtl\n");
259 fprintf (outfile, " (return_rtx \n");
260 w.print_rtl_single_with_indent (crtl->return_rtx, 6);
261 fprintf (outfile, " ) ;; return_rtx\n");
262 fprintf (outfile, " ) ;; crtl\n");
264 fprintf (outfile, ") ;; function \"%s\"\n", dname);