]> gcc.gnu.org Git - gcc.git/blob - gcc/print-rtl-function.c
Move MEMMODEL_* from coretypes.h to memmodel.h
[gcc.git] / gcc / print-rtl-function.c
1 /* Print RTL functions for GCC.
2 Copyright (C) 2016 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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/>. */
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"
34 #include "memmodel.h"
35 #include "emit-rtl.h"
36
37 extern bool flag_compact;
38
39 /* Print an "(edge-from)" or "(edge-to)" directive describing E
40 to OUTFILE. */
41
42 static void
43 print_edge (FILE *outfile, edge e, bool from)
44 {
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)
49 {
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;
59 }
60
61 /* Express edge flags as a string with " | " separator.
62 e.g. (flags "FALLTHRU | DFS_BACK"). */
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
77
78 fprintf (outfile, "\"))\n");
79 }
80
81 /* If BB is non-NULL, print the start of a "(block)" directive for it
82 to OUTFILE, otherwise do nothing. */
83
84 static void
85 begin_any_block (FILE *outfile, basic_block bb)
86 {
87 if (!bb)
88 return;
89
90 edge e;
91 edge_iterator ei;
92
93 fprintf (outfile, " (block %i\n", bb->index);
94 FOR_EACH_EDGE (e, ei, bb->preds)
95 print_edge (outfile, e, true);
96 }
97
98 /* If BB is non-NULL, print the end of a "(block)" directive for it
99 to OUTFILE, otherwise do nothing. */
100
101 static void
102 end_any_block (FILE *outfile, basic_block bb)
103 {
104 if (!bb)
105 return;
106
107 edge e;
108 edge_iterator ei;
109
110 FOR_EACH_EDGE (e, ei, bb->succs)
111 print_edge (outfile, e, false);
112 fprintf (outfile, " ) ;; block %i\n", bb->index);
113 }
114
115 /* Determine if INSN is of a kind that can have a basic block. */
116
117 static bool
118 can_have_basic_block_p (const rtx_insn *insn)
119 {
120 rtx_code code = GET_CODE (insn);
121 if (code == BARRIER)
122 return false;
123 gcc_assert (GET_RTX_FORMAT (code)[2] == 'B');
124 return true;
125 }
126
127 /* Write FN to OUTFILE in a form suitable for parsing, with indentation
128 and comments to make the structure easy for a human to grok. Track
129 the basic blocks of insns in the chain, wrapping those that are within
130 blocks within "(block)" directives.
131
132 If COMPACT, then instructions are printed in a compact form:
133 - INSN_UIDs are omitted, except for jumps and CODE_LABELs,
134 - INSN_CODEs are omitted,
135 - register numbers are omitted for hard and virtual regs
136 - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc)
137
138 Example output (with COMPACT==true):
139
140 (function "times_two"
141 (insn-chain
142 (cnote NOTE_INSN_DELETED)
143 (block 2
144 (edge-from entry (flags "FALLTHRU"))
145 (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
146 (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
147 (const_int -4)) [1 i+0 S4 A32])
148 (reg:SI di [ i ])) "t.c":2
149 (nil))
150 (cnote NOTE_INSN_FUNCTION_BEG)
151 (cinsn (set (reg:SI 89)
152 (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
153 (const_int -4)) [1 i+0 S4 A32])) "t.c":3
154 (nil))
155 (cinsn (parallel [
156 (set (reg:SI 87 [ _2 ])
157 (ashift:SI (reg:SI 89)
158 (const_int 1)))
159 (clobber (reg:CC flags))
160 ]) "t.c":3
161 (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
162 (const_int -4)) [1 i+0 S4 A32])
163 (const_int 1))
164 (nil)))
165 (cinsn (set (reg:SI 88 [ <retval> ])
166 (reg:SI 87 [ _2 ])) "t.c":3
167 (nil))
168 (cinsn (set (reg/i:SI ax)
169 (reg:SI 88 [ <retval> ])) "t.c":4
170 (nil))
171 (cinsn (use (reg/i:SI ax)) "t.c":4
172 (nil))
173 (edge-to exit (flags "FALLTHRU"))
174 ) ;; block 2
175 ) ;; insn-chain
176 (crtl
177 (return_rtx
178 (reg/i:SI ax)
179 ) ;; return_rtx
180 ) ;; crtl
181 ) ;; function "times_two"
182 */
183
184 DEBUG_FUNCTION void
185 print_rtx_function (FILE *outfile, function *fn, bool compact)
186 {
187 flag_compact = compact;
188
189 tree fdecl = fn->decl;
190
191 const char *dname = lang_hooks.decl_printable_name (fdecl, 2);
192
193 fprintf (outfile, "(function \"%s\"\n", dname);
194
195 /* The instruction chain. */
196 fprintf (outfile, " (insn-chain\n");
197 basic_block curr_bb = NULL;
198 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
199 {
200 basic_block insn_bb;
201 if (can_have_basic_block_p (insn))
202 insn_bb = BLOCK_FOR_INSN (insn);
203 else
204 insn_bb = NULL;
205 if (curr_bb != insn_bb)
206 {
207 end_any_block (outfile, curr_bb);
208 curr_bb = insn_bb;
209 begin_any_block (outfile, curr_bb);
210 }
211 print_rtl_single_with_indent (outfile, insn, curr_bb ? 6 : 4);
212 }
213 end_any_block (outfile, curr_bb);
214 fprintf (outfile, " ) ;; insn-chain\n");
215
216 /* Additional RTL state. */
217 fprintf (outfile, " (crtl\n");
218 fprintf (outfile, " (return_rtx \n");
219 print_rtl_single_with_indent (outfile, crtl->return_rtx, 6);
220 fprintf (outfile, " ) ;; return_rtx\n");
221 fprintf (outfile, " ) ;; crtl\n");
222
223 fprintf (outfile, ") ;; function \"%s\"\n", dname);
224
225 flag_compact = false;
226 }
This page took 0.045642 seconds and 5 git commands to generate.