annotate gcc/shrink-wrap.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Shrink-wrapping related optimizations.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of GCC.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
9 version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
14 for more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 /* This file handles shrink-wrapping related optimizations. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #include "config.h"
kono
parents:
diff changeset
23 #include "system.h"
kono
parents:
diff changeset
24 #include "coretypes.h"
kono
parents:
diff changeset
25 #include "backend.h"
kono
parents:
diff changeset
26 #include "target.h"
kono
parents:
diff changeset
27 #include "rtl.h"
kono
parents:
diff changeset
28 #include "tree.h"
kono
parents:
diff changeset
29 #include "cfghooks.h"
kono
parents:
diff changeset
30 #include "df.h"
kono
parents:
diff changeset
31 #include "memmodel.h"
kono
parents:
diff changeset
32 #include "tm_p.h"
kono
parents:
diff changeset
33 #include "regs.h"
kono
parents:
diff changeset
34 #include "insn-config.h"
kono
parents:
diff changeset
35 #include "emit-rtl.h"
kono
parents:
diff changeset
36 #include "output.h"
kono
parents:
diff changeset
37 #include "tree-pass.h"
kono
parents:
diff changeset
38 #include "cfgrtl.h"
kono
parents:
diff changeset
39 #include "cfgbuild.h"
kono
parents:
diff changeset
40 #include "bb-reorder.h"
kono
parents:
diff changeset
41 #include "shrink-wrap.h"
kono
parents:
diff changeset
42 #include "regcprop.h"
kono
parents:
diff changeset
43 #include "rtl-iter.h"
kono
parents:
diff changeset
44 #include "valtrack.h"
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
45 #include "function-abi.h"
111
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 /* Return true if INSN requires the stack frame to be set up.
kono
parents:
diff changeset
48 PROLOGUE_USED contains the hard registers used in the function
kono
parents:
diff changeset
49 prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the
kono
parents:
diff changeset
50 prologue to set up for the function. */
kono
parents:
diff changeset
51 bool
kono
parents:
diff changeset
52 requires_stack_frame_p (rtx_insn *insn, HARD_REG_SET prologue_used,
kono
parents:
diff changeset
53 HARD_REG_SET set_up_by_prologue)
kono
parents:
diff changeset
54 {
kono
parents:
diff changeset
55 df_ref def, use;
kono
parents:
diff changeset
56 HARD_REG_SET hardregs;
kono
parents:
diff changeset
57 unsigned regno;
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 if (CALL_P (insn))
kono
parents:
diff changeset
60 return !SIBLING_CALL_P (insn);
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 /* We need a frame to get the unique CFA expected by the unwinder. */
kono
parents:
diff changeset
63 if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))
kono
parents:
diff changeset
64 return true;
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 CLEAR_HARD_REG_SET (hardregs);
kono
parents:
diff changeset
67 FOR_EACH_INSN_DEF (def, insn)
kono
parents:
diff changeset
68 {
kono
parents:
diff changeset
69 rtx dreg = DF_REF_REG (def);
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 if (!REG_P (dreg))
kono
parents:
diff changeset
72 continue;
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 add_to_hard_reg_set (&hardregs, GET_MODE (dreg), REGNO (dreg));
kono
parents:
diff changeset
75 }
kono
parents:
diff changeset
76 if (hard_reg_set_intersect_p (hardregs, prologue_used))
kono
parents:
diff changeset
77 return true;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
78 hardregs &= ~crtl->abi->full_reg_clobbers ();
111
kono
parents:
diff changeset
79 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
kono
parents:
diff changeset
80 if (TEST_HARD_REG_BIT (hardregs, regno)
kono
parents:
diff changeset
81 && df_regs_ever_live_p (regno))
kono
parents:
diff changeset
82 return true;
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 FOR_EACH_INSN_USE (use, insn)
kono
parents:
diff changeset
85 {
kono
parents:
diff changeset
86 rtx reg = DF_REF_REG (use);
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 if (!REG_P (reg))
kono
parents:
diff changeset
89 continue;
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 add_to_hard_reg_set (&hardregs, GET_MODE (reg),
kono
parents:
diff changeset
92 REGNO (reg));
kono
parents:
diff changeset
93 }
kono
parents:
diff changeset
94 if (hard_reg_set_intersect_p (hardregs, set_up_by_prologue))
kono
parents:
diff changeset
95 return true;
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 return false;
kono
parents:
diff changeset
98 }
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 /* See whether there has a single live edge from BB, which dest uses
kono
parents:
diff changeset
101 [REGNO, END_REGNO). Return the live edge if its dest bb has
kono
parents:
diff changeset
102 one or two predecessors. Otherwise return NULL. */
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 static edge
kono
parents:
diff changeset
105 live_edge_for_reg (basic_block bb, int regno, int end_regno)
kono
parents:
diff changeset
106 {
kono
parents:
diff changeset
107 edge e, live_edge;
kono
parents:
diff changeset
108 edge_iterator ei;
kono
parents:
diff changeset
109 bitmap live;
kono
parents:
diff changeset
110 int i;
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 live_edge = NULL;
kono
parents:
diff changeset
113 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
114 {
kono
parents:
diff changeset
115 live = df_get_live_in (e->dest);
kono
parents:
diff changeset
116 for (i = regno; i < end_regno; i++)
kono
parents:
diff changeset
117 if (REGNO_REG_SET_P (live, i))
kono
parents:
diff changeset
118 {
kono
parents:
diff changeset
119 if (live_edge && live_edge != e)
kono
parents:
diff changeset
120 return NULL;
kono
parents:
diff changeset
121 live_edge = e;
kono
parents:
diff changeset
122 }
kono
parents:
diff changeset
123 }
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 /* We can sometimes encounter dead code. Don't try to move it
kono
parents:
diff changeset
126 into the exit block. */
kono
parents:
diff changeset
127 if (!live_edge || live_edge->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents:
diff changeset
128 return NULL;
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 /* Reject targets of abnormal edges. This is needed for correctness
kono
parents:
diff changeset
131 on ports like Alpha and MIPS, whose pic_offset_table_rtx can die on
kono
parents:
diff changeset
132 exception edges even though it is generally treated as call-saved
kono
parents:
diff changeset
133 for the majority of the compilation. Moving across abnormal edges
kono
parents:
diff changeset
134 isn't going to be interesting for shrink-wrap usage anyway. */
kono
parents:
diff changeset
135 if (live_edge->flags & EDGE_ABNORMAL)
kono
parents:
diff changeset
136 return NULL;
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 /* When live_edge->dest->preds == 2, we can create a new block on
kono
parents:
diff changeset
139 the edge to make it meet the requirement. */
kono
parents:
diff changeset
140 if (EDGE_COUNT (live_edge->dest->preds) > 2)
kono
parents:
diff changeset
141 return NULL;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 return live_edge;
kono
parents:
diff changeset
144 }
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 /* Try to move INSN from BB to a successor. Return true on success.
kono
parents:
diff changeset
147 USES and DEFS are the set of registers that are used and defined
kono
parents:
diff changeset
148 after INSN in BB. SPLIT_P indicates whether a live edge from BB
kono
parents:
diff changeset
149 is splitted or not. */
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 static bool
kono
parents:
diff changeset
152 move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
153 const_hard_reg_set uses,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
154 const_hard_reg_set defs,
111
kono
parents:
diff changeset
155 bool *split_p,
kono
parents:
diff changeset
156 struct dead_debug_local *debug)
kono
parents:
diff changeset
157 {
kono
parents:
diff changeset
158 rtx set, src, dest;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159 bitmap live_out, live_in, bb_uses = NULL, bb_defs = NULL;
111
kono
parents:
diff changeset
160 unsigned int i, dregno, end_dregno;
kono
parents:
diff changeset
161 unsigned int sregno = FIRST_PSEUDO_REGISTER;
kono
parents:
diff changeset
162 unsigned int end_sregno = FIRST_PSEUDO_REGISTER;
kono
parents:
diff changeset
163 basic_block next_block;
kono
parents:
diff changeset
164 edge live_edge;
kono
parents:
diff changeset
165 rtx_insn *dinsn;
kono
parents:
diff changeset
166 df_ref def;
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 /* Look for a simple register assignment. We don't use single_set here
kono
parents:
diff changeset
169 because we can't deal with any CLOBBERs, USEs, or REG_UNUSED secondary
kono
parents:
diff changeset
170 destinations. */
kono
parents:
diff changeset
171 if (!INSN_P (insn))
kono
parents:
diff changeset
172 return false;
kono
parents:
diff changeset
173 set = PATTERN (insn);
kono
parents:
diff changeset
174 if (GET_CODE (set) != SET)
kono
parents:
diff changeset
175 return false;
kono
parents:
diff changeset
176 src = SET_SRC (set);
kono
parents:
diff changeset
177 dest = SET_DEST (set);
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 /* For the destination, we want only a register. Also disallow STACK
kono
parents:
diff changeset
180 or FRAME related adjustments. They are likely part of the prologue,
kono
parents:
diff changeset
181 so keep them in the entry block. */
kono
parents:
diff changeset
182 if (!REG_P (dest)
kono
parents:
diff changeset
183 || dest == stack_pointer_rtx
kono
parents:
diff changeset
184 || dest == frame_pointer_rtx
kono
parents:
diff changeset
185 || dest == hard_frame_pointer_rtx)
kono
parents:
diff changeset
186 return false;
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 /* For the source, we want one of:
kono
parents:
diff changeset
189 (1) A (non-overlapping) register
kono
parents:
diff changeset
190 (2) A constant,
kono
parents:
diff changeset
191 (3) An expression involving no more than one register.
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 That last point comes from the code following, which was originally
kono
parents:
diff changeset
194 written to handle only register move operations, and still only handles
kono
parents:
diff changeset
195 a single source register when checking for overlaps. Happily, the
kono
parents:
diff changeset
196 same checks can be applied to expressions like (plus reg const). */
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 if (CONSTANT_P (src))
kono
parents:
diff changeset
199 ;
kono
parents:
diff changeset
200 else if (!REG_P (src))
kono
parents:
diff changeset
201 {
kono
parents:
diff changeset
202 rtx src_inner = NULL_RTX;
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 if (can_throw_internal (insn))
kono
parents:
diff changeset
205 return false;
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 subrtx_var_iterator::array_type array;
kono
parents:
diff changeset
208 FOR_EACH_SUBRTX_VAR (iter, array, src, ALL)
kono
parents:
diff changeset
209 {
kono
parents:
diff changeset
210 rtx x = *iter;
kono
parents:
diff changeset
211 switch (GET_RTX_CLASS (GET_CODE (x)))
kono
parents:
diff changeset
212 {
kono
parents:
diff changeset
213 case RTX_CONST_OBJ:
kono
parents:
diff changeset
214 case RTX_COMPARE:
kono
parents:
diff changeset
215 case RTX_COMM_COMPARE:
kono
parents:
diff changeset
216 case RTX_BIN_ARITH:
kono
parents:
diff changeset
217 case RTX_COMM_ARITH:
kono
parents:
diff changeset
218 case RTX_UNARY:
kono
parents:
diff changeset
219 case RTX_TERNARY:
kono
parents:
diff changeset
220 /* Constant or expression. Continue. */
kono
parents:
diff changeset
221 break;
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 case RTX_OBJ:
kono
parents:
diff changeset
224 case RTX_EXTRA:
kono
parents:
diff changeset
225 switch (GET_CODE (x))
kono
parents:
diff changeset
226 {
kono
parents:
diff changeset
227 case UNSPEC:
kono
parents:
diff changeset
228 case SUBREG:
kono
parents:
diff changeset
229 case STRICT_LOW_PART:
kono
parents:
diff changeset
230 case PC:
kono
parents:
diff changeset
231 case LO_SUM:
kono
parents:
diff changeset
232 /* Ok. Continue. */
kono
parents:
diff changeset
233 break;
kono
parents:
diff changeset
234
kono
parents:
diff changeset
235 case REG:
kono
parents:
diff changeset
236 /* Fail if we see a second inner register. */
kono
parents:
diff changeset
237 if (src_inner != NULL)
kono
parents:
diff changeset
238 return false;
kono
parents:
diff changeset
239 src_inner = x;
kono
parents:
diff changeset
240 break;
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242 default:
kono
parents:
diff changeset
243 return false;
kono
parents:
diff changeset
244 }
kono
parents:
diff changeset
245 break;
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 default:
kono
parents:
diff changeset
248 return false;
kono
parents:
diff changeset
249 }
kono
parents:
diff changeset
250 }
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 if (src_inner != NULL)
kono
parents:
diff changeset
253 src = src_inner;
kono
parents:
diff changeset
254 }
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 /* Make sure that the source register isn't defined later in BB. */
kono
parents:
diff changeset
257 if (REG_P (src))
kono
parents:
diff changeset
258 {
kono
parents:
diff changeset
259 sregno = REGNO (src);
kono
parents:
diff changeset
260 end_sregno = END_REGNO (src);
kono
parents:
diff changeset
261 if (overlaps_hard_reg_set_p (defs, GET_MODE (src), sregno))
kono
parents:
diff changeset
262 return false;
kono
parents:
diff changeset
263 }
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 /* Make sure that the destination register isn't referenced later in BB. */
kono
parents:
diff changeset
266 dregno = REGNO (dest);
kono
parents:
diff changeset
267 end_dregno = END_REGNO (dest);
kono
parents:
diff changeset
268 if (overlaps_hard_reg_set_p (uses, GET_MODE (dest), dregno)
kono
parents:
diff changeset
269 || overlaps_hard_reg_set_p (defs, GET_MODE (dest), dregno))
kono
parents:
diff changeset
270 return false;
kono
parents:
diff changeset
271
kono
parents:
diff changeset
272 /* See whether there is a successor block to which we could move INSN. */
kono
parents:
diff changeset
273 live_edge = live_edge_for_reg (bb, dregno, end_dregno);
kono
parents:
diff changeset
274 if (!live_edge)
kono
parents:
diff changeset
275 return false;
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 next_block = live_edge->dest;
kono
parents:
diff changeset
278 /* Create a new basic block on the edge. */
kono
parents:
diff changeset
279 if (EDGE_COUNT (next_block->preds) == 2)
kono
parents:
diff changeset
280 {
kono
parents:
diff changeset
281 /* split_edge for a block with only one successor is meaningless. */
kono
parents:
diff changeset
282 if (EDGE_COUNT (bb->succs) == 1)
kono
parents:
diff changeset
283 return false;
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 /* If DF_LIVE doesn't exist, i.e. at -O1, just give up. */
kono
parents:
diff changeset
286 if (!df_live)
kono
parents:
diff changeset
287 return false;
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 basic_block old_dest = live_edge->dest;
kono
parents:
diff changeset
290 next_block = split_edge (live_edge);
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 /* We create a new basic block. Call df_grow_bb_info to make sure
kono
parents:
diff changeset
293 all data structures are allocated. */
kono
parents:
diff changeset
294 df_grow_bb_info (df_live);
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 bitmap_and (df_get_live_in (next_block), df_get_live_out (bb),
kono
parents:
diff changeset
297 df_get_live_in (old_dest));
kono
parents:
diff changeset
298 df_set_bb_dirty (next_block);
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 /* We should not split more than once for a function. */
kono
parents:
diff changeset
301 if (*split_p)
kono
parents:
diff changeset
302 return false;
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 *split_p = true;
kono
parents:
diff changeset
305 }
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 /* At this point we are committed to moving INSN, but let's try to
kono
parents:
diff changeset
308 move it as far as we can. */
kono
parents:
diff changeset
309 do
kono
parents:
diff changeset
310 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
311 if (MAY_HAVE_DEBUG_BIND_INSNS)
111
kono
parents:
diff changeset
312 {
kono
parents:
diff changeset
313 FOR_BB_INSNS_REVERSE (bb, dinsn)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
314 if (DEBUG_BIND_INSN_P (dinsn))
111
kono
parents:
diff changeset
315 {
kono
parents:
diff changeset
316 df_ref use;
kono
parents:
diff changeset
317 FOR_EACH_INSN_USE (use, dinsn)
kono
parents:
diff changeset
318 if (refers_to_regno_p (dregno, end_dregno,
kono
parents:
diff changeset
319 DF_REF_REG (use), (rtx *) NULL))
kono
parents:
diff changeset
320 dead_debug_add (debug, use, DF_REF_REGNO (use));
kono
parents:
diff changeset
321 }
kono
parents:
diff changeset
322 else if (dinsn == insn)
kono
parents:
diff changeset
323 break;
kono
parents:
diff changeset
324 }
kono
parents:
diff changeset
325 live_out = df_get_live_out (bb);
kono
parents:
diff changeset
326 live_in = df_get_live_in (next_block);
kono
parents:
diff changeset
327 bb = next_block;
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 /* Check whether BB uses DEST or clobbers DEST. We need to add
kono
parents:
diff changeset
330 INSN to BB if so. Either way, DEST is no longer live on entry,
kono
parents:
diff changeset
331 except for any part that overlaps SRC (next loop). */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
332 if (!*split_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
333 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
334 bb_uses = &DF_LR_BB_INFO (bb)->use;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 bb_defs = &DF_LR_BB_INFO (bb)->def;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 }
111
kono
parents:
diff changeset
337 if (df_live)
kono
parents:
diff changeset
338 {
kono
parents:
diff changeset
339 for (i = dregno; i < end_dregno; i++)
kono
parents:
diff changeset
340 {
kono
parents:
diff changeset
341 if (*split_p
kono
parents:
diff changeset
342 || REGNO_REG_SET_P (bb_uses, i)
kono
parents:
diff changeset
343 || REGNO_REG_SET_P (bb_defs, i)
kono
parents:
diff changeset
344 || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i))
kono
parents:
diff changeset
345 next_block = NULL;
kono
parents:
diff changeset
346 CLEAR_REGNO_REG_SET (live_out, i);
kono
parents:
diff changeset
347 CLEAR_REGNO_REG_SET (live_in, i);
kono
parents:
diff changeset
348 }
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 /* Check whether BB clobbers SRC. We need to add INSN to BB if so.
kono
parents:
diff changeset
351 Either way, SRC is now live on entry. */
kono
parents:
diff changeset
352 for (i = sregno; i < end_sregno; i++)
kono
parents:
diff changeset
353 {
kono
parents:
diff changeset
354 if (*split_p
kono
parents:
diff changeset
355 || REGNO_REG_SET_P (bb_defs, i)
kono
parents:
diff changeset
356 || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i))
kono
parents:
diff changeset
357 next_block = NULL;
kono
parents:
diff changeset
358 SET_REGNO_REG_SET (live_out, i);
kono
parents:
diff changeset
359 SET_REGNO_REG_SET (live_in, i);
kono
parents:
diff changeset
360 }
kono
parents:
diff changeset
361 }
kono
parents:
diff changeset
362 else
kono
parents:
diff changeset
363 {
kono
parents:
diff changeset
364 /* DF_LR_BB_INFO (bb)->def does not comprise the DF_REF_PARTIAL and
kono
parents:
diff changeset
365 DF_REF_CONDITIONAL defs. So if DF_LIVE doesn't exist, i.e.
kono
parents:
diff changeset
366 at -O1, just give up searching NEXT_BLOCK. */
kono
parents:
diff changeset
367 next_block = NULL;
kono
parents:
diff changeset
368 for (i = dregno; i < end_dregno; i++)
kono
parents:
diff changeset
369 {
kono
parents:
diff changeset
370 CLEAR_REGNO_REG_SET (live_out, i);
kono
parents:
diff changeset
371 CLEAR_REGNO_REG_SET (live_in, i);
kono
parents:
diff changeset
372 }
kono
parents:
diff changeset
373
kono
parents:
diff changeset
374 for (i = sregno; i < end_sregno; i++)
kono
parents:
diff changeset
375 {
kono
parents:
diff changeset
376 SET_REGNO_REG_SET (live_out, i);
kono
parents:
diff changeset
377 SET_REGNO_REG_SET (live_in, i);
kono
parents:
diff changeset
378 }
kono
parents:
diff changeset
379 }
kono
parents:
diff changeset
380
kono
parents:
diff changeset
381 /* If we don't need to add the move to BB, look for a single
kono
parents:
diff changeset
382 successor block. */
kono
parents:
diff changeset
383 if (next_block)
kono
parents:
diff changeset
384 {
kono
parents:
diff changeset
385 live_edge = live_edge_for_reg (next_block, dregno, end_dregno);
kono
parents:
diff changeset
386 if (!live_edge || EDGE_COUNT (live_edge->dest->preds) > 1)
kono
parents:
diff changeset
387 break;
kono
parents:
diff changeset
388 next_block = live_edge->dest;
kono
parents:
diff changeset
389 }
kono
parents:
diff changeset
390 }
kono
parents:
diff changeset
391 while (next_block);
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 /* For the new created basic block, there is no dataflow info at all.
kono
parents:
diff changeset
394 So skip the following dataflow update and check. */
kono
parents:
diff changeset
395 if (!(*split_p))
kono
parents:
diff changeset
396 {
kono
parents:
diff changeset
397 /* BB now defines DEST. It only uses the parts of DEST that overlap SRC
kono
parents:
diff changeset
398 (next loop). */
kono
parents:
diff changeset
399 for (i = dregno; i < end_dregno; i++)
kono
parents:
diff changeset
400 {
kono
parents:
diff changeset
401 CLEAR_REGNO_REG_SET (bb_uses, i);
kono
parents:
diff changeset
402 SET_REGNO_REG_SET (bb_defs, i);
kono
parents:
diff changeset
403 }
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 /* BB now uses SRC. */
kono
parents:
diff changeset
406 for (i = sregno; i < end_sregno; i++)
kono
parents:
diff changeset
407 SET_REGNO_REG_SET (bb_uses, i);
kono
parents:
diff changeset
408 }
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 /* Insert debug temps for dead REGs used in subsequent debug insns. */
kono
parents:
diff changeset
411 if (debug->used && !bitmap_empty_p (debug->used))
kono
parents:
diff changeset
412 FOR_EACH_INSN_DEF (def, insn)
kono
parents:
diff changeset
413 dead_debug_insert_temp (debug, DF_REF_REGNO (def), insn,
kono
parents:
diff changeset
414 DEBUG_TEMP_BEFORE_WITH_VALUE);
kono
parents:
diff changeset
415
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
416 rtx_insn *insn_copy = emit_insn_after (PATTERN (insn), bb_note (bb));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
417 /* Update the LABEL_NUSES count on any referenced labels. The ideal
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
418 solution here would be to actually move the instruction instead
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
419 of copying/deleting it as this loses some notations on the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
420 insn. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
421 mark_jump_label (PATTERN (insn), insn_copy, 0);
111
kono
parents:
diff changeset
422 delete_insn (insn);
kono
parents:
diff changeset
423 return true;
kono
parents:
diff changeset
424 }
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 /* Look for register copies in the first block of the function, and move
kono
parents:
diff changeset
427 them down into successor blocks if the register is used only on one
kono
parents:
diff changeset
428 path. This exposes more opportunities for shrink-wrapping. These
kono
parents:
diff changeset
429 kinds of sets often occur when incoming argument registers are moved
kono
parents:
diff changeset
430 to call-saved registers because their values are live across one or
kono
parents:
diff changeset
431 more calls during the function. */
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 static void
kono
parents:
diff changeset
434 prepare_shrink_wrap (basic_block entry_block)
kono
parents:
diff changeset
435 {
kono
parents:
diff changeset
436 rtx_insn *insn, *curr;
kono
parents:
diff changeset
437 rtx x;
kono
parents:
diff changeset
438 HARD_REG_SET uses, defs;
kono
parents:
diff changeset
439 df_ref def, use;
kono
parents:
diff changeset
440 bool split_p = false;
kono
parents:
diff changeset
441 unsigned int i;
kono
parents:
diff changeset
442 struct dead_debug_local debug;
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 if (JUMP_P (BB_END (entry_block)))
kono
parents:
diff changeset
445 {
kono
parents:
diff changeset
446 /* To have more shrink-wrapping opportunities, prepare_shrink_wrap tries
kono
parents:
diff changeset
447 to sink the copies from parameter to callee saved register out of
kono
parents:
diff changeset
448 entry block. copyprop_hardreg_forward_bb_without_debug_insn is called
kono
parents:
diff changeset
449 to release some dependences. */
kono
parents:
diff changeset
450 copyprop_hardreg_forward_bb_without_debug_insn (entry_block);
kono
parents:
diff changeset
451 }
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 dead_debug_local_init (&debug, NULL, NULL);
kono
parents:
diff changeset
454 CLEAR_HARD_REG_SET (uses);
kono
parents:
diff changeset
455 CLEAR_HARD_REG_SET (defs);
kono
parents:
diff changeset
456
kono
parents:
diff changeset
457 FOR_BB_INSNS_REVERSE_SAFE (entry_block, insn, curr)
kono
parents:
diff changeset
458 if (NONDEBUG_INSN_P (insn)
kono
parents:
diff changeset
459 && !move_insn_for_shrink_wrap (entry_block, insn, uses, defs,
kono
parents:
diff changeset
460 &split_p, &debug))
kono
parents:
diff changeset
461 {
kono
parents:
diff changeset
462 /* Add all defined registers to DEFs. */
kono
parents:
diff changeset
463 FOR_EACH_INSN_DEF (def, insn)
kono
parents:
diff changeset
464 {
kono
parents:
diff changeset
465 x = DF_REF_REG (def);
kono
parents:
diff changeset
466 if (REG_P (x) && HARD_REGISTER_P (x))
kono
parents:
diff changeset
467 for (i = REGNO (x); i < END_REGNO (x); i++)
kono
parents:
diff changeset
468 SET_HARD_REG_BIT (defs, i);
kono
parents:
diff changeset
469 }
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 /* Add all used registers to USESs. */
kono
parents:
diff changeset
472 FOR_EACH_INSN_USE (use, insn)
kono
parents:
diff changeset
473 {
kono
parents:
diff changeset
474 x = DF_REF_REG (use);
kono
parents:
diff changeset
475 if (REG_P (x) && HARD_REGISTER_P (x))
kono
parents:
diff changeset
476 for (i = REGNO (x); i < END_REGNO (x); i++)
kono
parents:
diff changeset
477 SET_HARD_REG_BIT (uses, i);
kono
parents:
diff changeset
478 }
kono
parents:
diff changeset
479 }
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 dead_debug_local_finish (&debug, NULL);
kono
parents:
diff changeset
482 }
kono
parents:
diff changeset
483
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
484 /* Return whether basic block PRO can get the prologue. It cannot if it
111
kono
parents:
diff changeset
485 has incoming complex edges that need a prologue inserted (we make a new
kono
parents:
diff changeset
486 block for the prologue, so those edges would need to be redirected, which
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
487 does not work). It also cannot if there exist registers live on entry
111
kono
parents:
diff changeset
488 to PRO that are clobbered by the prologue. */
kono
parents:
diff changeset
489
kono
parents:
diff changeset
490 static bool
kono
parents:
diff changeset
491 can_get_prologue (basic_block pro, HARD_REG_SET prologue_clobbered)
kono
parents:
diff changeset
492 {
kono
parents:
diff changeset
493 edge e;
kono
parents:
diff changeset
494 edge_iterator ei;
kono
parents:
diff changeset
495 FOR_EACH_EDGE (e, ei, pro->preds)
kono
parents:
diff changeset
496 if (e->flags & (EDGE_COMPLEX | EDGE_CROSSING)
kono
parents:
diff changeset
497 && !dominated_by_p (CDI_DOMINATORS, e->src, pro))
kono
parents:
diff changeset
498 return false;
kono
parents:
diff changeset
499
kono
parents:
diff changeset
500 HARD_REG_SET live;
kono
parents:
diff changeset
501 REG_SET_TO_HARD_REG_SET (live, df_get_live_in (pro));
kono
parents:
diff changeset
502 if (hard_reg_set_intersect_p (live, prologue_clobbered))
kono
parents:
diff changeset
503 return false;
kono
parents:
diff changeset
504
kono
parents:
diff changeset
505 return true;
kono
parents:
diff changeset
506 }
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 /* Return whether we can duplicate basic block BB for shrink wrapping. We
kono
parents:
diff changeset
509 cannot if the block cannot be duplicated at all, or if any of its incoming
kono
parents:
diff changeset
510 edges are complex and come from a block that does not require a prologue
kono
parents:
diff changeset
511 (we cannot redirect such edges), or if the block is too big to copy.
kono
parents:
diff changeset
512 PRO is the basic block before which we would put the prologue, MAX_SIZE is
kono
parents:
diff changeset
513 the maximum size block we allow to be copied. */
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 static bool
kono
parents:
diff changeset
516 can_dup_for_shrink_wrapping (basic_block bb, basic_block pro, unsigned max_size)
kono
parents:
diff changeset
517 {
kono
parents:
diff changeset
518 if (!can_duplicate_block_p (bb))
kono
parents:
diff changeset
519 return false;
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 edge e;
kono
parents:
diff changeset
522 edge_iterator ei;
kono
parents:
diff changeset
523 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents:
diff changeset
524 if (e->flags & (EDGE_COMPLEX | EDGE_CROSSING)
kono
parents:
diff changeset
525 && !dominated_by_p (CDI_DOMINATORS, e->src, pro))
kono
parents:
diff changeset
526 return false;
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 unsigned size = 0;
kono
parents:
diff changeset
529
kono
parents:
diff changeset
530 rtx_insn *insn;
kono
parents:
diff changeset
531 FOR_BB_INSNS (bb, insn)
kono
parents:
diff changeset
532 if (NONDEBUG_INSN_P (insn))
kono
parents:
diff changeset
533 {
kono
parents:
diff changeset
534 size += get_attr_min_length (insn);
kono
parents:
diff changeset
535 if (size > max_size)
kono
parents:
diff changeset
536 return false;
kono
parents:
diff changeset
537 }
kono
parents:
diff changeset
538
kono
parents:
diff changeset
539 return true;
kono
parents:
diff changeset
540 }
kono
parents:
diff changeset
541
kono
parents:
diff changeset
542 /* Do whatever needs to be done for exits that run without prologue.
kono
parents:
diff changeset
543 Sibcalls need nothing done. Normal exits get a simple_return inserted. */
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 static void
kono
parents:
diff changeset
546 handle_simple_exit (edge e)
kono
parents:
diff changeset
547 {
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 if (e->flags & EDGE_SIBCALL)
kono
parents:
diff changeset
550 {
kono
parents:
diff changeset
551 /* Tell function.c to take no further action on this edge. */
kono
parents:
diff changeset
552 e->flags |= EDGE_IGNORE;
kono
parents:
diff changeset
553
kono
parents:
diff changeset
554 e->flags &= ~EDGE_FALLTHRU;
kono
parents:
diff changeset
555 emit_barrier_after_bb (e->src);
kono
parents:
diff changeset
556 return;
kono
parents:
diff changeset
557 }
kono
parents:
diff changeset
558
kono
parents:
diff changeset
559 /* If the basic block the edge comes from has multiple successors,
kono
parents:
diff changeset
560 split the edge. */
kono
parents:
diff changeset
561 if (EDGE_COUNT (e->src->succs) > 1)
kono
parents:
diff changeset
562 {
kono
parents:
diff changeset
563 basic_block old_bb = e->src;
kono
parents:
diff changeset
564 rtx_insn *end = BB_END (old_bb);
kono
parents:
diff changeset
565 rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end);
kono
parents:
diff changeset
566 basic_block new_bb = create_basic_block (note, note, old_bb);
kono
parents:
diff changeset
567 BB_COPY_PARTITION (new_bb, old_bb);
kono
parents:
diff changeset
568 BB_END (old_bb) = end;
kono
parents:
diff changeset
569
kono
parents:
diff changeset
570 redirect_edge_succ (e, new_bb);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
571 new_bb->count = e->count ();
111
kono
parents:
diff changeset
572 e->flags |= EDGE_FALLTHRU;
kono
parents:
diff changeset
573
kono
parents:
diff changeset
574 e = make_single_succ_edge (new_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
kono
parents:
diff changeset
575 }
kono
parents:
diff changeset
576
kono
parents:
diff changeset
577 e->flags &= ~EDGE_FALLTHRU;
kono
parents:
diff changeset
578 rtx_jump_insn *ret = emit_jump_insn_after (targetm.gen_simple_return (),
kono
parents:
diff changeset
579 BB_END (e->src));
kono
parents:
diff changeset
580 JUMP_LABEL (ret) = simple_return_rtx;
kono
parents:
diff changeset
581 emit_barrier_after_bb (e->src);
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 if (dump_file)
kono
parents:
diff changeset
584 fprintf (dump_file, "Made simple_return with UID %d in bb %d\n",
kono
parents:
diff changeset
585 INSN_UID (ret), e->src->index);
kono
parents:
diff changeset
586 }
kono
parents:
diff changeset
587
kono
parents:
diff changeset
588 /* Try to perform a kind of shrink-wrapping, making sure the
kono
parents:
diff changeset
589 prologue/epilogue is emitted only around those parts of the
kono
parents:
diff changeset
590 function that require it.
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 There will be exactly one prologue, and it will be executed either
kono
parents:
diff changeset
593 zero or one time, on any path. Depending on where the prologue is
kono
parents:
diff changeset
594 placed, some of the basic blocks can be reached via both paths with
kono
parents:
diff changeset
595 and without a prologue. Such blocks will be duplicated here, and the
kono
parents:
diff changeset
596 edges changed to match.
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 Paths that go to the exit without going through the prologue will use
kono
parents:
diff changeset
599 a simple_return instead of the epilogue. We maximize the number of
kono
parents:
diff changeset
600 those, making sure to only duplicate blocks that can be duplicated.
kono
parents:
diff changeset
601 If the prologue can then still be placed in multiple locations, we
kono
parents:
diff changeset
602 place it as early as possible.
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 An example, where we duplicate blocks with control flow (legend:
kono
parents:
diff changeset
605 _B_egin, _R_eturn and _S_imple_return; edges without arrowhead should
kono
parents:
diff changeset
606 be taken to point down or to the right, to simplify the diagram; here,
kono
parents:
diff changeset
607 block 3 needs a prologue, the rest does not):
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609
kono
parents:
diff changeset
610 B B
kono
parents:
diff changeset
611 | |
kono
parents:
diff changeset
612 2 2
kono
parents:
diff changeset
613 |\ |\
kono
parents:
diff changeset
614 | 3 becomes | 3
kono
parents:
diff changeset
615 |/ | \
kono
parents:
diff changeset
616 4 7 4
kono
parents:
diff changeset
617 |\ |\ |\
kono
parents:
diff changeset
618 | 5 | 8 | 5
kono
parents:
diff changeset
619 |/ |/ |/
kono
parents:
diff changeset
620 6 9 6
kono
parents:
diff changeset
621 | | |
kono
parents:
diff changeset
622 R S R
kono
parents:
diff changeset
623
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 (bb 4 is duplicated to 7, and so on; the prologue is inserted on the
kono
parents:
diff changeset
626 edge 2->3).
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 Another example, where part of a loop is duplicated (again, bb 3 is
kono
parents:
diff changeset
629 the only block that needs a prologue):
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631
kono
parents:
diff changeset
632 B 3<-- B ->3<--
kono
parents:
diff changeset
633 | | | | | | |
kono
parents:
diff changeset
634 | v | becomes | | v |
kono
parents:
diff changeset
635 2---4--- 2---5-- 4---
kono
parents:
diff changeset
636 | | |
kono
parents:
diff changeset
637 R S R
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 (bb 4 is duplicated to 5; the prologue is inserted on the edge 5->3).
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 ENTRY_EDGE is the edge where the prologue will be placed, possibly
kono
parents:
diff changeset
643 changed by this function. PROLOGUE_SEQ is the prologue we will insert. */
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 void
kono
parents:
diff changeset
646 try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq)
kono
parents:
diff changeset
647 {
kono
parents:
diff changeset
648 /* If we cannot shrink-wrap, are told not to shrink-wrap, or it makes
kono
parents:
diff changeset
649 no sense to shrink-wrap: then do not shrink-wrap! */
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 if (!SHRINK_WRAPPING_ENABLED)
kono
parents:
diff changeset
652 return;
kono
parents:
diff changeset
653
kono
parents:
diff changeset
654 if (crtl->profile && !targetm.profile_before_prologue ())
kono
parents:
diff changeset
655 return;
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 if (crtl->calls_eh_return)
kono
parents:
diff changeset
658 return;
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 bool empty_prologue = true;
kono
parents:
diff changeset
661 for (rtx_insn *insn = prologue_seq; insn; insn = NEXT_INSN (insn))
kono
parents:
diff changeset
662 if (!(NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END))
kono
parents:
diff changeset
663 {
kono
parents:
diff changeset
664 empty_prologue = false;
kono
parents:
diff changeset
665 break;
kono
parents:
diff changeset
666 }
kono
parents:
diff changeset
667 if (empty_prologue)
kono
parents:
diff changeset
668 return;
kono
parents:
diff changeset
669
kono
parents:
diff changeset
670 /* Move some code down to expose more shrink-wrapping opportunities. */
kono
parents:
diff changeset
671
kono
parents:
diff changeset
672 basic_block entry = (*entry_edge)->dest;
kono
parents:
diff changeset
673 prepare_shrink_wrap (entry);
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 if (dump_file)
kono
parents:
diff changeset
676 fprintf (dump_file, "Attempting shrink-wrapping optimization.\n");
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 /* Compute the registers set and used in the prologue. */
kono
parents:
diff changeset
679
kono
parents:
diff changeset
680 HARD_REG_SET prologue_clobbered, prologue_used;
kono
parents:
diff changeset
681 CLEAR_HARD_REG_SET (prologue_clobbered);
kono
parents:
diff changeset
682 CLEAR_HARD_REG_SET (prologue_used);
kono
parents:
diff changeset
683 for (rtx_insn *insn = prologue_seq; insn; insn = NEXT_INSN (insn))
kono
parents:
diff changeset
684 if (NONDEBUG_INSN_P (insn))
kono
parents:
diff changeset
685 {
kono
parents:
diff changeset
686 HARD_REG_SET this_used;
kono
parents:
diff changeset
687 CLEAR_HARD_REG_SET (this_used);
kono
parents:
diff changeset
688 note_uses (&PATTERN (insn), record_hard_reg_uses, &this_used);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
689 this_used &= ~prologue_clobbered;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
690 prologue_used |= this_used;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
691 note_stores (insn, record_hard_reg_sets, &prologue_clobbered);
111
kono
parents:
diff changeset
692 }
kono
parents:
diff changeset
693 CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM);
kono
parents:
diff changeset
694 if (frame_pointer_needed)
kono
parents:
diff changeset
695 CLEAR_HARD_REG_BIT (prologue_clobbered, HARD_FRAME_POINTER_REGNUM);
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 /* Find out what registers are set up by the prologue; any use of these
kono
parents:
diff changeset
698 cannot happen before the prologue. */
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 struct hard_reg_set_container set_up_by_prologue;
kono
parents:
diff changeset
701 CLEAR_HARD_REG_SET (set_up_by_prologue.set);
kono
parents:
diff changeset
702 add_to_hard_reg_set (&set_up_by_prologue.set, Pmode, STACK_POINTER_REGNUM);
kono
parents:
diff changeset
703 add_to_hard_reg_set (&set_up_by_prologue.set, Pmode, ARG_POINTER_REGNUM);
kono
parents:
diff changeset
704 if (frame_pointer_needed)
kono
parents:
diff changeset
705 add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
kono
parents:
diff changeset
706 HARD_FRAME_POINTER_REGNUM);
kono
parents:
diff changeset
707 if (pic_offset_table_rtx
kono
parents:
diff changeset
708 && (unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
kono
parents:
diff changeset
709 add_to_hard_reg_set (&set_up_by_prologue.set, Pmode,
kono
parents:
diff changeset
710 PIC_OFFSET_TABLE_REGNUM);
kono
parents:
diff changeset
711 if (crtl->drap_reg)
kono
parents:
diff changeset
712 add_to_hard_reg_set (&set_up_by_prologue.set,
kono
parents:
diff changeset
713 GET_MODE (crtl->drap_reg),
kono
parents:
diff changeset
714 REGNO (crtl->drap_reg));
kono
parents:
diff changeset
715 if (targetm.set_up_by_prologue)
kono
parents:
diff changeset
716 targetm.set_up_by_prologue (&set_up_by_prologue);
kono
parents:
diff changeset
717
kono
parents:
diff changeset
718 /* We will insert the prologue before the basic block PRO. PRO should
kono
parents:
diff changeset
719 dominate all basic blocks that need the prologue to be executed
kono
parents:
diff changeset
720 before them. First, make PRO the "tightest wrap" possible. */
kono
parents:
diff changeset
721
kono
parents:
diff changeset
722 calculate_dominance_info (CDI_DOMINATORS);
kono
parents:
diff changeset
723
kono
parents:
diff changeset
724 basic_block pro = 0;
kono
parents:
diff changeset
725
kono
parents:
diff changeset
726 basic_block bb;
kono
parents:
diff changeset
727 edge e;
kono
parents:
diff changeset
728 edge_iterator ei;
kono
parents:
diff changeset
729 FOR_EACH_BB_FN (bb, cfun)
kono
parents:
diff changeset
730 {
kono
parents:
diff changeset
731 rtx_insn *insn;
kono
parents:
diff changeset
732 FOR_BB_INSNS (bb, insn)
kono
parents:
diff changeset
733 if (NONDEBUG_INSN_P (insn)
kono
parents:
diff changeset
734 && requires_stack_frame_p (insn, prologue_used,
kono
parents:
diff changeset
735 set_up_by_prologue.set))
kono
parents:
diff changeset
736 {
kono
parents:
diff changeset
737 if (dump_file)
kono
parents:
diff changeset
738 fprintf (dump_file, "Block %d needs the prologue.\n", bb->index);
kono
parents:
diff changeset
739 pro = nearest_common_dominator (CDI_DOMINATORS, pro, bb);
kono
parents:
diff changeset
740 break;
kono
parents:
diff changeset
741 }
kono
parents:
diff changeset
742 }
kono
parents:
diff changeset
743
kono
parents:
diff changeset
744 /* If nothing needs a prologue, just put it at the start. This really
kono
parents:
diff changeset
745 shouldn't happen, but we cannot fix it here. */
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 if (pro == 0)
kono
parents:
diff changeset
748 {
kono
parents:
diff changeset
749 if (dump_file)
kono
parents:
diff changeset
750 fprintf(dump_file, "Nothing needs a prologue, but it isn't empty; "
kono
parents:
diff changeset
751 "putting it at the start.\n");
kono
parents:
diff changeset
752 pro = entry;
kono
parents:
diff changeset
753 }
kono
parents:
diff changeset
754
kono
parents:
diff changeset
755 if (dump_file)
kono
parents:
diff changeset
756 fprintf (dump_file, "After wrapping required blocks, PRO is now %d\n",
kono
parents:
diff changeset
757 pro->index);
kono
parents:
diff changeset
758
kono
parents:
diff changeset
759 /* Now see if we can put the prologue at the start of PRO. Putting it
kono
parents:
diff changeset
760 there might require duplicating a block that cannot be duplicated,
kono
parents:
diff changeset
761 or in some cases we cannot insert the prologue there at all. If PRO
kono
parents:
diff changeset
762 wont't do, try again with the immediate dominator of PRO, and so on.
kono
parents:
diff changeset
763
kono
parents:
diff changeset
764 The blocks that need duplicating are those reachable from PRO but
kono
parents:
diff changeset
765 not dominated by it. We keep in BB_WITH a bitmap of the blocks
kono
parents:
diff changeset
766 reachable from PRO that we already found, and in VEC a stack of
kono
parents:
diff changeset
767 those we still need to consider (to find successors). */
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 auto_bitmap bb_with;
kono
parents:
diff changeset
770 bitmap_set_bit (bb_with, pro->index);
kono
parents:
diff changeset
771
kono
parents:
diff changeset
772 vec<basic_block> vec;
kono
parents:
diff changeset
773 vec.create (n_basic_blocks_for_fn (cfun));
kono
parents:
diff changeset
774 vec.quick_push (pro);
kono
parents:
diff changeset
775
kono
parents:
diff changeset
776 unsigned max_grow_size = get_uncond_jump_length ();
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
777 max_grow_size *= param_max_grow_copy_bb_insns;
111
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 while (!vec.is_empty () && pro != entry)
kono
parents:
diff changeset
780 {
kono
parents:
diff changeset
781 while (pro != entry && !can_get_prologue (pro, prologue_clobbered))
kono
parents:
diff changeset
782 {
kono
parents:
diff changeset
783 pro = get_immediate_dominator (CDI_DOMINATORS, pro);
kono
parents:
diff changeset
784
kono
parents:
diff changeset
785 if (bitmap_set_bit (bb_with, pro->index))
kono
parents:
diff changeset
786 vec.quick_push (pro);
kono
parents:
diff changeset
787 }
kono
parents:
diff changeset
788
kono
parents:
diff changeset
789 basic_block bb = vec.pop ();
kono
parents:
diff changeset
790 if (!can_dup_for_shrink_wrapping (bb, pro, max_grow_size))
kono
parents:
diff changeset
791 while (!dominated_by_p (CDI_DOMINATORS, bb, pro))
kono
parents:
diff changeset
792 {
kono
parents:
diff changeset
793 gcc_assert (pro != entry);
kono
parents:
diff changeset
794
kono
parents:
diff changeset
795 pro = get_immediate_dominator (CDI_DOMINATORS, pro);
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 if (bitmap_set_bit (bb_with, pro->index))
kono
parents:
diff changeset
798 vec.quick_push (pro);
kono
parents:
diff changeset
799 }
kono
parents:
diff changeset
800
kono
parents:
diff changeset
801 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
802 if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
kono
parents:
diff changeset
803 && bitmap_set_bit (bb_with, e->dest->index))
kono
parents:
diff changeset
804 vec.quick_push (e->dest);
kono
parents:
diff changeset
805 }
kono
parents:
diff changeset
806
kono
parents:
diff changeset
807 if (dump_file)
kono
parents:
diff changeset
808 fprintf (dump_file, "Avoiding non-duplicatable blocks, PRO is now %d\n",
kono
parents:
diff changeset
809 pro->index);
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 /* If we can move PRO back without having to duplicate more blocks, do so.
kono
parents:
diff changeset
812 We do this because putting the prologue earlier is better for scheduling.
kono
parents:
diff changeset
813
kono
parents:
diff changeset
814 We can move back to a block PRE if every path from PRE will eventually
kono
parents:
diff changeset
815 need a prologue, that is, PRO is a post-dominator of PRE. PRE needs
kono
parents:
diff changeset
816 to dominate every block reachable from itself. We keep in BB_TMP a
kono
parents:
diff changeset
817 bitmap of the blocks reachable from PRE that we already found, and in
kono
parents:
diff changeset
818 VEC a stack of those we still need to consider.
kono
parents:
diff changeset
819
kono
parents:
diff changeset
820 Any block reachable from PRE is also reachable from all predecessors
kono
parents:
diff changeset
821 of PRE, so if we find we need to move PRE back further we can leave
kono
parents:
diff changeset
822 everything not considered so far on the stack. Any block dominated
kono
parents:
diff changeset
823 by PRE is also dominated by all other dominators of PRE, so anything
kono
parents:
diff changeset
824 found good for some PRE does not need to be reconsidered later.
kono
parents:
diff changeset
825
kono
parents:
diff changeset
826 We don't need to update BB_WITH because none of the new blocks found
kono
parents:
diff changeset
827 can jump to a block that does not need the prologue. */
kono
parents:
diff changeset
828
kono
parents:
diff changeset
829 if (pro != entry)
kono
parents:
diff changeset
830 {
kono
parents:
diff changeset
831 calculate_dominance_info (CDI_POST_DOMINATORS);
kono
parents:
diff changeset
832
kono
parents:
diff changeset
833 auto_bitmap bb_tmp;
kono
parents:
diff changeset
834 bitmap_copy (bb_tmp, bb_with);
kono
parents:
diff changeset
835 basic_block last_ok = pro;
kono
parents:
diff changeset
836 vec.truncate (0);
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 while (pro != entry)
kono
parents:
diff changeset
839 {
kono
parents:
diff changeset
840 basic_block pre = get_immediate_dominator (CDI_DOMINATORS, pro);
kono
parents:
diff changeset
841 if (!dominated_by_p (CDI_POST_DOMINATORS, pre, pro))
kono
parents:
diff changeset
842 break;
kono
parents:
diff changeset
843
kono
parents:
diff changeset
844 if (bitmap_set_bit (bb_tmp, pre->index))
kono
parents:
diff changeset
845 vec.quick_push (pre);
kono
parents:
diff changeset
846
kono
parents:
diff changeset
847 bool ok = true;
kono
parents:
diff changeset
848 while (!vec.is_empty ())
kono
parents:
diff changeset
849 {
kono
parents:
diff changeset
850 if (!dominated_by_p (CDI_DOMINATORS, vec.last (), pre))
kono
parents:
diff changeset
851 {
kono
parents:
diff changeset
852 ok = false;
kono
parents:
diff changeset
853 break;
kono
parents:
diff changeset
854 }
kono
parents:
diff changeset
855
kono
parents:
diff changeset
856 basic_block bb = vec.pop ();
kono
parents:
diff changeset
857 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
858 if (bitmap_set_bit (bb_tmp, e->dest->index))
kono
parents:
diff changeset
859 vec.quick_push (e->dest);
kono
parents:
diff changeset
860 }
kono
parents:
diff changeset
861
kono
parents:
diff changeset
862 if (ok && can_get_prologue (pre, prologue_clobbered))
kono
parents:
diff changeset
863 last_ok = pre;
kono
parents:
diff changeset
864
kono
parents:
diff changeset
865 pro = pre;
kono
parents:
diff changeset
866 }
kono
parents:
diff changeset
867
kono
parents:
diff changeset
868 pro = last_ok;
kono
parents:
diff changeset
869
kono
parents:
diff changeset
870 free_dominance_info (CDI_POST_DOMINATORS);
kono
parents:
diff changeset
871 }
kono
parents:
diff changeset
872
kono
parents:
diff changeset
873 vec.release ();
kono
parents:
diff changeset
874
kono
parents:
diff changeset
875 if (dump_file)
kono
parents:
diff changeset
876 fprintf (dump_file, "Bumping back to anticipatable blocks, PRO is now %d\n",
kono
parents:
diff changeset
877 pro->index);
kono
parents:
diff changeset
878
kono
parents:
diff changeset
879 if (pro == entry)
kono
parents:
diff changeset
880 {
kono
parents:
diff changeset
881 free_dominance_info (CDI_DOMINATORS);
kono
parents:
diff changeset
882 return;
kono
parents:
diff changeset
883 }
kono
parents:
diff changeset
884
kono
parents:
diff changeset
885 /* Compute what fraction of the frequency and count of the blocks that run
kono
parents:
diff changeset
886 both with and without prologue are for running with prologue. This gives
kono
parents:
diff changeset
887 the correct answer for reducible flow graphs; for irreducible flow graphs
kono
parents:
diff changeset
888 our profile is messed up beyond repair anyway. */
kono
parents:
diff changeset
889
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890 profile_count num = profile_count::zero ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 profile_count den = profile_count::zero ();
111
kono
parents:
diff changeset
892
kono
parents:
diff changeset
893 FOR_EACH_EDGE (e, ei, pro->preds)
kono
parents:
diff changeset
894 if (!dominated_by_p (CDI_DOMINATORS, e->src, pro))
kono
parents:
diff changeset
895 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
896 if (e->count ().initialized_p ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
897 num += e->count ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
898 if (e->src->count.initialized_p ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
899 den += e->src->count;
111
kono
parents:
diff changeset
900 }
kono
parents:
diff changeset
901
kono
parents:
diff changeset
902 /* All is okay, so do it. */
kono
parents:
diff changeset
903
kono
parents:
diff changeset
904 crtl->shrink_wrapped = true;
kono
parents:
diff changeset
905 if (dump_file)
kono
parents:
diff changeset
906 fprintf (dump_file, "Performing shrink-wrapping.\n");
kono
parents:
diff changeset
907
kono
parents:
diff changeset
908 /* Copy the blocks that can run both with and without prologue. The
kono
parents:
diff changeset
909 originals run with prologue, the copies without. Store a pointer to
kono
parents:
diff changeset
910 the copy in the ->aux field of the original. */
kono
parents:
diff changeset
911
kono
parents:
diff changeset
912 FOR_EACH_BB_FN (bb, cfun)
kono
parents:
diff changeset
913 if (bitmap_bit_p (bb_with, bb->index)
kono
parents:
diff changeset
914 && !dominated_by_p (CDI_DOMINATORS, bb, pro))
kono
parents:
diff changeset
915 {
kono
parents:
diff changeset
916 basic_block dup = duplicate_block (bb, 0, 0);
kono
parents:
diff changeset
917
kono
parents:
diff changeset
918 bb->aux = dup;
kono
parents:
diff changeset
919
kono
parents:
diff changeset
920 if (JUMP_P (BB_END (dup)) && !any_condjump_p (BB_END (dup)))
kono
parents:
diff changeset
921 emit_barrier_after_bb (dup);
kono
parents:
diff changeset
922
kono
parents:
diff changeset
923 if (EDGE_COUNT (dup->succs) == 0)
kono
parents:
diff changeset
924 emit_barrier_after_bb (dup);
kono
parents:
diff changeset
925
kono
parents:
diff changeset
926 if (dump_file)
kono
parents:
diff changeset
927 fprintf (dump_file, "Duplicated %d to %d\n", bb->index, dup->index);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
928
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
929 if (num == profile_count::zero () || den.nonzero_p ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930 bb->count = bb->count.apply_scale (num, den);
111
kono
parents:
diff changeset
931 dup->count -= bb->count;
kono
parents:
diff changeset
932 }
kono
parents:
diff changeset
933
kono
parents:
diff changeset
934 /* Now change the edges to point to the copies, where appropriate. */
kono
parents:
diff changeset
935
kono
parents:
diff changeset
936 FOR_EACH_BB_FN (bb, cfun)
kono
parents:
diff changeset
937 if (!dominated_by_p (CDI_DOMINATORS, bb, pro))
kono
parents:
diff changeset
938 {
kono
parents:
diff changeset
939 basic_block src = bb;
kono
parents:
diff changeset
940 if (bitmap_bit_p (bb_with, bb->index))
kono
parents:
diff changeset
941 src = (basic_block) bb->aux;
kono
parents:
diff changeset
942
kono
parents:
diff changeset
943 FOR_EACH_EDGE (e, ei, src->succs)
kono
parents:
diff changeset
944 {
kono
parents:
diff changeset
945 if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents:
diff changeset
946 continue;
kono
parents:
diff changeset
947
kono
parents:
diff changeset
948 if (bitmap_bit_p (bb_with, e->dest->index)
kono
parents:
diff changeset
949 && !dominated_by_p (CDI_DOMINATORS, e->dest, pro))
kono
parents:
diff changeset
950 {
kono
parents:
diff changeset
951 if (dump_file)
kono
parents:
diff changeset
952 fprintf (dump_file, "Redirecting edge %d->%d to %d\n",
kono
parents:
diff changeset
953 e->src->index, e->dest->index,
kono
parents:
diff changeset
954 ((basic_block) e->dest->aux)->index);
kono
parents:
diff changeset
955 redirect_edge_and_branch_force (e, (basic_block) e->dest->aux);
kono
parents:
diff changeset
956 }
kono
parents:
diff changeset
957 else if (e->flags & EDGE_FALLTHRU
kono
parents:
diff changeset
958 && bitmap_bit_p (bb_with, bb->index))
kono
parents:
diff changeset
959 force_nonfallthru (e);
kono
parents:
diff changeset
960 }
kono
parents:
diff changeset
961 }
kono
parents:
diff changeset
962
kono
parents:
diff changeset
963 /* Also redirect the function entry edge if necessary. */
kono
parents:
diff changeset
964
kono
parents:
diff changeset
965 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
kono
parents:
diff changeset
966 if (bitmap_bit_p (bb_with, e->dest->index)
kono
parents:
diff changeset
967 && !dominated_by_p (CDI_DOMINATORS, e->dest, pro))
kono
parents:
diff changeset
968 {
kono
parents:
diff changeset
969 basic_block split_bb = split_edge (e);
kono
parents:
diff changeset
970 e = single_succ_edge (split_bb);
kono
parents:
diff changeset
971 redirect_edge_and_branch_force (e, (basic_block) e->dest->aux);
kono
parents:
diff changeset
972 }
kono
parents:
diff changeset
973
kono
parents:
diff changeset
974 /* Make a simple_return for those exits that run without prologue. */
kono
parents:
diff changeset
975
kono
parents:
diff changeset
976 FOR_EACH_BB_REVERSE_FN (bb, cfun)
kono
parents:
diff changeset
977 if (!bitmap_bit_p (bb_with, bb->index))
kono
parents:
diff changeset
978 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
979 if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents:
diff changeset
980 handle_simple_exit (e);
kono
parents:
diff changeset
981
kono
parents:
diff changeset
982 /* Finally, we want a single edge to put the prologue on. Make a new
kono
parents:
diff changeset
983 block before the PRO block; the edge beteen them is the edge we want.
kono
parents:
diff changeset
984 Then redirect those edges into PRO that come from blocks without the
kono
parents:
diff changeset
985 prologue, to point to the new block instead. The new prologue block
kono
parents:
diff changeset
986 is put at the end of the insn chain. */
kono
parents:
diff changeset
987
kono
parents:
diff changeset
988 basic_block new_bb = create_empty_bb (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
kono
parents:
diff changeset
989 BB_COPY_PARTITION (new_bb, pro);
kono
parents:
diff changeset
990 new_bb->count = profile_count::zero ();
kono
parents:
diff changeset
991 if (dump_file)
kono
parents:
diff changeset
992 fprintf (dump_file, "Made prologue block %d\n", new_bb->index);
kono
parents:
diff changeset
993
kono
parents:
diff changeset
994 for (ei = ei_start (pro->preds); (e = ei_safe_edge (ei)); )
kono
parents:
diff changeset
995 {
kono
parents:
diff changeset
996 if (bitmap_bit_p (bb_with, e->src->index)
kono
parents:
diff changeset
997 || dominated_by_p (CDI_DOMINATORS, e->src, pro))
kono
parents:
diff changeset
998 {
kono
parents:
diff changeset
999 ei_next (&ei);
kono
parents:
diff changeset
1000 continue;
kono
parents:
diff changeset
1001 }
kono
parents:
diff changeset
1002
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1003 new_bb->count += e->count ();
111
kono
parents:
diff changeset
1004
kono
parents:
diff changeset
1005 redirect_edge_and_branch_force (e, new_bb);
kono
parents:
diff changeset
1006 if (dump_file)
kono
parents:
diff changeset
1007 fprintf (dump_file, "Redirected edge from %d\n", e->src->index);
kono
parents:
diff changeset
1008 }
kono
parents:
diff changeset
1009
kono
parents:
diff changeset
1010 *entry_edge = make_single_succ_edge (new_bb, pro, EDGE_FALLTHRU);
kono
parents:
diff changeset
1011 force_nonfallthru (*entry_edge);
kono
parents:
diff changeset
1012
kono
parents:
diff changeset
1013 free_dominance_info (CDI_DOMINATORS);
kono
parents:
diff changeset
1014 }
kono
parents:
diff changeset
1015
kono
parents:
diff changeset
1016 /* Separate shrink-wrapping
kono
parents:
diff changeset
1017
kono
parents:
diff changeset
1018 Instead of putting all of the prologue and epilogue in one spot, we
kono
parents:
diff changeset
1019 can put parts of it in places where those components are executed less
kono
parents:
diff changeset
1020 frequently. The following code does this, for prologue and epilogue
kono
parents:
diff changeset
1021 components that can be put in more than one location, and where those
kono
parents:
diff changeset
1022 components can be executed more than once (the epilogue component will
kono
parents:
diff changeset
1023 always be executed before the prologue component is executed a second
kono
parents:
diff changeset
1024 time).
kono
parents:
diff changeset
1025
kono
parents:
diff changeset
1026 What exactly is a component is target-dependent. The more usual
kono
parents:
diff changeset
1027 components are simple saves/restores to/from the frame of callee-saved
kono
parents:
diff changeset
1028 registers. This code treats components abstractly (as an sbitmap),
kono
parents:
diff changeset
1029 letting the target handle all details.
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 Prologue components are placed in such a way that for every component
kono
parents:
diff changeset
1032 the prologue is executed as infrequently as possible. We do this by
kono
parents:
diff changeset
1033 walking the dominator tree, comparing the cost of placing a prologue
kono
parents:
diff changeset
1034 component before a block to the sum of costs determined for all subtrees
kono
parents:
diff changeset
1035 of that block.
kono
parents:
diff changeset
1036
kono
parents:
diff changeset
1037 From this placement, we then determine for each component all blocks
kono
parents:
diff changeset
1038 where at least one of this block's dominators (including itself) will
kono
parents:
diff changeset
1039 get a prologue inserted. That then is how the components are placed.
kono
parents:
diff changeset
1040 We could place the epilogue components a bit smarter (we can save a
kono
parents:
diff changeset
1041 bit of code size sometimes); this is a possible future improvement.
kono
parents:
diff changeset
1042
kono
parents:
diff changeset
1043 Prologues and epilogues are preferably placed into a block, either at
kono
parents:
diff changeset
1044 the beginning or end of it, if it is needed for all predecessor resp.
kono
parents:
diff changeset
1045 successor edges; or placed on the edge otherwise.
kono
parents:
diff changeset
1046
kono
parents:
diff changeset
1047 If the placement of any prologue/epilogue leads to a situation we cannot
kono
parents:
diff changeset
1048 handle (for example, an abnormal edge would need to be split, or some
kono
parents:
diff changeset
1049 targets want to use some specific registers that may not be available
kono
parents:
diff changeset
1050 where we want to put them), separate shrink-wrapping for the components
kono
parents:
diff changeset
1051 in that prologue/epilogue is aborted. */
kono
parents:
diff changeset
1052
kono
parents:
diff changeset
1053
kono
parents:
diff changeset
1054 /* Print the sbitmap COMPONENTS to the DUMP_FILE if not empty, with the
kono
parents:
diff changeset
1055 label LABEL. */
kono
parents:
diff changeset
1056 static void
kono
parents:
diff changeset
1057 dump_components (const char *label, sbitmap components)
kono
parents:
diff changeset
1058 {
kono
parents:
diff changeset
1059 if (bitmap_empty_p (components))
kono
parents:
diff changeset
1060 return;
kono
parents:
diff changeset
1061
kono
parents:
diff changeset
1062 fprintf (dump_file, " [%s", label);
kono
parents:
diff changeset
1063
kono
parents:
diff changeset
1064 for (unsigned int j = 0; j < components->n_bits; j++)
kono
parents:
diff changeset
1065 if (bitmap_bit_p (components, j))
kono
parents:
diff changeset
1066 fprintf (dump_file, " %u", j);
kono
parents:
diff changeset
1067
kono
parents:
diff changeset
1068 fprintf (dump_file, "]");
kono
parents:
diff changeset
1069 }
kono
parents:
diff changeset
1070
kono
parents:
diff changeset
1071 /* The data we collect for each bb. */
kono
parents:
diff changeset
1072 struct sw {
kono
parents:
diff changeset
1073 /* What components does this BB need? */
kono
parents:
diff changeset
1074 sbitmap needs_components;
kono
parents:
diff changeset
1075
kono
parents:
diff changeset
1076 /* What components does this BB have? This is the main decision this
kono
parents:
diff changeset
1077 pass makes. */
kono
parents:
diff changeset
1078 sbitmap has_components;
kono
parents:
diff changeset
1079
kono
parents:
diff changeset
1080 /* The components for which we placed code at the start of the BB (instead
kono
parents:
diff changeset
1081 of on all incoming edges). */
kono
parents:
diff changeset
1082 sbitmap head_components;
kono
parents:
diff changeset
1083
kono
parents:
diff changeset
1084 /* The components for which we placed code at the end of the BB (instead
kono
parents:
diff changeset
1085 of on all outgoing edges). */
kono
parents:
diff changeset
1086 sbitmap tail_components;
kono
parents:
diff changeset
1087
kono
parents:
diff changeset
1088 /* The frequency of executing the prologue for this BB, if a prologue is
kono
parents:
diff changeset
1089 placed on this BB. This is a pessimistic estimate (no prologue is
kono
parents:
diff changeset
1090 needed for edges from blocks that have the component under consideration
kono
parents:
diff changeset
1091 active already). */
kono
parents:
diff changeset
1092 gcov_type own_cost;
kono
parents:
diff changeset
1093
kono
parents:
diff changeset
1094 /* The frequency of executing the prologue for this BB and all BBs
kono
parents:
diff changeset
1095 dominated by it. */
kono
parents:
diff changeset
1096 gcov_type total_cost;
kono
parents:
diff changeset
1097 };
kono
parents:
diff changeset
1098
kono
parents:
diff changeset
1099 /* A helper function for accessing the pass-specific info. */
kono
parents:
diff changeset
1100 static inline struct sw *
kono
parents:
diff changeset
1101 SW (basic_block bb)
kono
parents:
diff changeset
1102 {
kono
parents:
diff changeset
1103 gcc_assert (bb->aux);
kono
parents:
diff changeset
1104 return (struct sw *) bb->aux;
kono
parents:
diff changeset
1105 }
kono
parents:
diff changeset
1106
kono
parents:
diff changeset
1107 /* Create the pass-specific data structures for separately shrink-wrapping
kono
parents:
diff changeset
1108 with components COMPONENTS. */
kono
parents:
diff changeset
1109 static void
kono
parents:
diff changeset
1110 init_separate_shrink_wrap (sbitmap components)
kono
parents:
diff changeset
1111 {
kono
parents:
diff changeset
1112 basic_block bb;
kono
parents:
diff changeset
1113 FOR_ALL_BB_FN (bb, cfun)
kono
parents:
diff changeset
1114 {
kono
parents:
diff changeset
1115 bb->aux = xcalloc (1, sizeof (struct sw));
kono
parents:
diff changeset
1116
kono
parents:
diff changeset
1117 SW (bb)->needs_components = targetm.shrink_wrap.components_for_bb (bb);
kono
parents:
diff changeset
1118
kono
parents:
diff changeset
1119 /* Mark all basic blocks without successor as needing all components.
kono
parents:
diff changeset
1120 This avoids problems in at least cfgcleanup, sel-sched, and
kono
parents:
diff changeset
1121 regrename (largely to do with all paths to such a block still
kono
parents:
diff changeset
1122 needing the same dwarf CFI info). */
kono
parents:
diff changeset
1123 if (EDGE_COUNT (bb->succs) == 0)
kono
parents:
diff changeset
1124 bitmap_copy (SW (bb)->needs_components, components);
kono
parents:
diff changeset
1125
kono
parents:
diff changeset
1126 if (dump_file)
kono
parents:
diff changeset
1127 {
kono
parents:
diff changeset
1128 fprintf (dump_file, "bb %d components:", bb->index);
kono
parents:
diff changeset
1129 dump_components ("has", SW (bb)->needs_components);
kono
parents:
diff changeset
1130 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1131 }
kono
parents:
diff changeset
1132
kono
parents:
diff changeset
1133 SW (bb)->has_components = sbitmap_alloc (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1134 SW (bb)->head_components = sbitmap_alloc (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1135 SW (bb)->tail_components = sbitmap_alloc (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1136 bitmap_clear (SW (bb)->has_components);
kono
parents:
diff changeset
1137 }
kono
parents:
diff changeset
1138 }
kono
parents:
diff changeset
1139
kono
parents:
diff changeset
1140 /* Destroy the pass-specific data. */
kono
parents:
diff changeset
1141 static void
kono
parents:
diff changeset
1142 fini_separate_shrink_wrap (void)
kono
parents:
diff changeset
1143 {
kono
parents:
diff changeset
1144 basic_block bb;
kono
parents:
diff changeset
1145 FOR_ALL_BB_FN (bb, cfun)
kono
parents:
diff changeset
1146 if (bb->aux)
kono
parents:
diff changeset
1147 {
kono
parents:
diff changeset
1148 sbitmap_free (SW (bb)->needs_components);
kono
parents:
diff changeset
1149 sbitmap_free (SW (bb)->has_components);
kono
parents:
diff changeset
1150 sbitmap_free (SW (bb)->head_components);
kono
parents:
diff changeset
1151 sbitmap_free (SW (bb)->tail_components);
kono
parents:
diff changeset
1152 free (bb->aux);
kono
parents:
diff changeset
1153 bb->aux = 0;
kono
parents:
diff changeset
1154 }
kono
parents:
diff changeset
1155 }
kono
parents:
diff changeset
1156
kono
parents:
diff changeset
1157 /* Place the prologue for component WHICH, in the basic blocks dominated
kono
parents:
diff changeset
1158 by HEAD. Do a DFS over the dominator tree, and set bit WHICH in the
kono
parents:
diff changeset
1159 HAS_COMPONENTS of a block if either the block has that bit set in
kono
parents:
diff changeset
1160 NEEDS_COMPONENTS, or it is cheaper to place the prologue here than in all
kono
parents:
diff changeset
1161 dominator subtrees separately. */
kono
parents:
diff changeset
1162 static void
kono
parents:
diff changeset
1163 place_prologue_for_one_component (unsigned int which, basic_block head)
kono
parents:
diff changeset
1164 {
kono
parents:
diff changeset
1165 /* The block we are currently dealing with. */
kono
parents:
diff changeset
1166 basic_block bb = head;
kono
parents:
diff changeset
1167 /* Is this the first time we visit this block, i.e. have we just gone
kono
parents:
diff changeset
1168 down the tree. */
kono
parents:
diff changeset
1169 bool first_visit = true;
kono
parents:
diff changeset
1170
kono
parents:
diff changeset
1171 /* Walk the dominator tree, visit one block per iteration of this loop.
kono
parents:
diff changeset
1172 Each basic block is visited twice: once before visiting any children
kono
parents:
diff changeset
1173 of the block, and once after visiting all of them (leaf nodes are
kono
parents:
diff changeset
1174 visited only once). As an optimization, we do not visit subtrees
kono
parents:
diff changeset
1175 that can no longer influence the prologue placement. */
kono
parents:
diff changeset
1176 for (;;)
kono
parents:
diff changeset
1177 {
kono
parents:
diff changeset
1178 /* First visit of a block: set the (children) cost accumulator to zero;
kono
parents:
diff changeset
1179 if the block does not have the component itself, walk down. */
kono
parents:
diff changeset
1180 if (first_visit)
kono
parents:
diff changeset
1181 {
kono
parents:
diff changeset
1182 /* Initialize the cost. The cost is the block execution frequency
kono
parents:
diff changeset
1183 that does not come from backedges. Calculating this by simply
kono
parents:
diff changeset
1184 adding the cost of all edges that aren't backedges does not
kono
parents:
diff changeset
1185 work: this does not always add up to the block frequency at
kono
parents:
diff changeset
1186 all, and even if it does, rounding error makes for bad
kono
parents:
diff changeset
1187 decisions. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1188 SW (bb)->own_cost = bb->count.to_frequency (cfun);
111
kono
parents:
diff changeset
1189
kono
parents:
diff changeset
1190 edge e;
kono
parents:
diff changeset
1191 edge_iterator ei;
kono
parents:
diff changeset
1192 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents:
diff changeset
1193 if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
kono
parents:
diff changeset
1194 {
kono
parents:
diff changeset
1195 if (SW (bb)->own_cost > EDGE_FREQUENCY (e))
kono
parents:
diff changeset
1196 SW (bb)->own_cost -= EDGE_FREQUENCY (e);
kono
parents:
diff changeset
1197 else
kono
parents:
diff changeset
1198 SW (bb)->own_cost = 0;
kono
parents:
diff changeset
1199 }
kono
parents:
diff changeset
1200
kono
parents:
diff changeset
1201 SW (bb)->total_cost = 0;
kono
parents:
diff changeset
1202
kono
parents:
diff changeset
1203 if (!bitmap_bit_p (SW (bb)->needs_components, which)
kono
parents:
diff changeset
1204 && first_dom_son (CDI_DOMINATORS, bb))
kono
parents:
diff changeset
1205 {
kono
parents:
diff changeset
1206 bb = first_dom_son (CDI_DOMINATORS, bb);
kono
parents:
diff changeset
1207 continue;
kono
parents:
diff changeset
1208 }
kono
parents:
diff changeset
1209 }
kono
parents:
diff changeset
1210
kono
parents:
diff changeset
1211 /* If this block does need the component itself, or it is cheaper to
kono
parents:
diff changeset
1212 put the prologue here than in all the descendants that need it,
kono
parents:
diff changeset
1213 mark it so. If this block's immediate post-dominator is dominated
kono
parents:
diff changeset
1214 by this block, and that needs the prologue, we can put it on this
kono
parents:
diff changeset
1215 block as well (earlier is better). */
kono
parents:
diff changeset
1216 if (bitmap_bit_p (SW (bb)->needs_components, which)
kono
parents:
diff changeset
1217 || SW (bb)->total_cost > SW (bb)->own_cost)
kono
parents:
diff changeset
1218 {
kono
parents:
diff changeset
1219 SW (bb)->total_cost = SW (bb)->own_cost;
kono
parents:
diff changeset
1220 bitmap_set_bit (SW (bb)->has_components, which);
kono
parents:
diff changeset
1221 }
kono
parents:
diff changeset
1222 else
kono
parents:
diff changeset
1223 {
kono
parents:
diff changeset
1224 basic_block kid = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
kono
parents:
diff changeset
1225 if (dominated_by_p (CDI_DOMINATORS, kid, bb)
kono
parents:
diff changeset
1226 && bitmap_bit_p (SW (kid)->has_components, which))
kono
parents:
diff changeset
1227 {
kono
parents:
diff changeset
1228 SW (bb)->total_cost = SW (bb)->own_cost;
kono
parents:
diff changeset
1229 bitmap_set_bit (SW (bb)->has_components, which);
kono
parents:
diff changeset
1230 }
kono
parents:
diff changeset
1231 }
kono
parents:
diff changeset
1232
kono
parents:
diff changeset
1233 /* We are back where we started, so we are done now. */
kono
parents:
diff changeset
1234 if (bb == head)
kono
parents:
diff changeset
1235 return;
kono
parents:
diff changeset
1236
kono
parents:
diff changeset
1237 /* We now know the cost of the subtree rooted at the current block.
kono
parents:
diff changeset
1238 Accumulate this cost in the parent. */
kono
parents:
diff changeset
1239 basic_block parent = get_immediate_dominator (CDI_DOMINATORS, bb);
kono
parents:
diff changeset
1240 SW (parent)->total_cost += SW (bb)->total_cost;
kono
parents:
diff changeset
1241
kono
parents:
diff changeset
1242 /* Don't walk the tree down unless necessary. */
kono
parents:
diff changeset
1243 if (next_dom_son (CDI_DOMINATORS, bb)
kono
parents:
diff changeset
1244 && SW (parent)->total_cost <= SW (parent)->own_cost)
kono
parents:
diff changeset
1245 {
kono
parents:
diff changeset
1246 bb = next_dom_son (CDI_DOMINATORS, bb);
kono
parents:
diff changeset
1247 first_visit = true;
kono
parents:
diff changeset
1248 }
kono
parents:
diff changeset
1249 else
kono
parents:
diff changeset
1250 {
kono
parents:
diff changeset
1251 bb = parent;
kono
parents:
diff changeset
1252 first_visit = false;
kono
parents:
diff changeset
1253 }
kono
parents:
diff changeset
1254 }
kono
parents:
diff changeset
1255 }
kono
parents:
diff changeset
1256
kono
parents:
diff changeset
1257 /* Set HAS_COMPONENTS in every block to the maximum it can be set to without
kono
parents:
diff changeset
1258 setting it on any path from entry to exit where it was not already set
kono
parents:
diff changeset
1259 somewhere (or, for blocks that have no path to the exit, consider only
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1260 paths from the entry to the block itself). Return whether any changes
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1261 were made to some HAS_COMPONENTS. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1262 static bool
111
kono
parents:
diff changeset
1263 spread_components (sbitmap components)
kono
parents:
diff changeset
1264 {
kono
parents:
diff changeset
1265 basic_block entry_block = ENTRY_BLOCK_PTR_FOR_FN (cfun);
kono
parents:
diff changeset
1266 basic_block exit_block = EXIT_BLOCK_PTR_FOR_FN (cfun);
kono
parents:
diff changeset
1267
kono
parents:
diff changeset
1268 /* A stack of all blocks left to consider, and a bitmap of all blocks
kono
parents:
diff changeset
1269 on that stack. */
kono
parents:
diff changeset
1270 vec<basic_block> todo;
kono
parents:
diff changeset
1271 todo.create (n_basic_blocks_for_fn (cfun));
kono
parents:
diff changeset
1272 auto_bitmap seen;
kono
parents:
diff changeset
1273
kono
parents:
diff changeset
1274 auto_sbitmap old (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1275
kono
parents:
diff changeset
1276 /* Find for every block the components that are *not* needed on some path
kono
parents:
diff changeset
1277 from the entry to that block. Do this with a flood fill from the entry
kono
parents:
diff changeset
1278 block. Every block can be visited at most as often as the number of
kono
parents:
diff changeset
1279 components (plus one), and usually much less often. */
kono
parents:
diff changeset
1280
kono
parents:
diff changeset
1281 if (dump_file)
kono
parents:
diff changeset
1282 fprintf (dump_file, "Spreading down...\n");
kono
parents:
diff changeset
1283
kono
parents:
diff changeset
1284 basic_block bb;
kono
parents:
diff changeset
1285 FOR_ALL_BB_FN (bb, cfun)
kono
parents:
diff changeset
1286 bitmap_clear (SW (bb)->head_components);
kono
parents:
diff changeset
1287
kono
parents:
diff changeset
1288 bitmap_copy (SW (entry_block)->head_components, components);
kono
parents:
diff changeset
1289
kono
parents:
diff changeset
1290 edge e;
kono
parents:
diff changeset
1291 edge_iterator ei;
kono
parents:
diff changeset
1292
kono
parents:
diff changeset
1293 todo.quick_push (single_succ (entry_block));
kono
parents:
diff changeset
1294 bitmap_set_bit (seen, single_succ (entry_block)->index);
kono
parents:
diff changeset
1295 while (!todo.is_empty ())
kono
parents:
diff changeset
1296 {
kono
parents:
diff changeset
1297 bb = todo.pop ();
kono
parents:
diff changeset
1298
kono
parents:
diff changeset
1299 bitmap_copy (old, SW (bb)->head_components);
kono
parents:
diff changeset
1300
kono
parents:
diff changeset
1301 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents:
diff changeset
1302 bitmap_ior (SW (bb)->head_components, SW (bb)->head_components,
kono
parents:
diff changeset
1303 SW (e->src)->head_components);
kono
parents:
diff changeset
1304
kono
parents:
diff changeset
1305 bitmap_and_compl (SW (bb)->head_components, SW (bb)->head_components,
kono
parents:
diff changeset
1306 SW (bb)->has_components);
kono
parents:
diff changeset
1307
kono
parents:
diff changeset
1308 if (!bitmap_equal_p (old, SW (bb)->head_components))
kono
parents:
diff changeset
1309 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
1310 if (bitmap_set_bit (seen, e->dest->index))
kono
parents:
diff changeset
1311 todo.quick_push (e->dest);
kono
parents:
diff changeset
1312
kono
parents:
diff changeset
1313 bitmap_clear_bit (seen, bb->index);
kono
parents:
diff changeset
1314 }
kono
parents:
diff changeset
1315
kono
parents:
diff changeset
1316 /* Find for every block the components that are *not* needed on some reverse
kono
parents:
diff changeset
1317 path from the exit to that block. */
kono
parents:
diff changeset
1318
kono
parents:
diff changeset
1319 if (dump_file)
kono
parents:
diff changeset
1320 fprintf (dump_file, "Spreading up...\n");
kono
parents:
diff changeset
1321
kono
parents:
diff changeset
1322 /* First, mark all blocks not reachable from the exit block as not needing
kono
parents:
diff changeset
1323 any component on any path to the exit. Mark everything, and then clear
kono
parents:
diff changeset
1324 again by a flood fill. */
kono
parents:
diff changeset
1325
kono
parents:
diff changeset
1326 FOR_ALL_BB_FN (bb, cfun)
kono
parents:
diff changeset
1327 bitmap_copy (SW (bb)->tail_components, components);
kono
parents:
diff changeset
1328
kono
parents:
diff changeset
1329 FOR_EACH_EDGE (e, ei, exit_block->preds)
kono
parents:
diff changeset
1330 {
kono
parents:
diff changeset
1331 todo.quick_push (e->src);
kono
parents:
diff changeset
1332 bitmap_set_bit (seen, e->src->index);
kono
parents:
diff changeset
1333 }
kono
parents:
diff changeset
1334
kono
parents:
diff changeset
1335 while (!todo.is_empty ())
kono
parents:
diff changeset
1336 {
kono
parents:
diff changeset
1337 bb = todo.pop ();
kono
parents:
diff changeset
1338
kono
parents:
diff changeset
1339 if (!bitmap_empty_p (SW (bb)->tail_components))
kono
parents:
diff changeset
1340 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents:
diff changeset
1341 if (bitmap_set_bit (seen, e->src->index))
kono
parents:
diff changeset
1342 todo.quick_push (e->src);
kono
parents:
diff changeset
1343
kono
parents:
diff changeset
1344 bitmap_clear (SW (bb)->tail_components);
kono
parents:
diff changeset
1345
kono
parents:
diff changeset
1346 bitmap_clear_bit (seen, bb->index);
kono
parents:
diff changeset
1347 }
kono
parents:
diff changeset
1348
kono
parents:
diff changeset
1349 /* And then, flood fill backwards to find for every block the components
kono
parents:
diff changeset
1350 not needed on some path to the exit. */
kono
parents:
diff changeset
1351
kono
parents:
diff changeset
1352 bitmap_copy (SW (exit_block)->tail_components, components);
kono
parents:
diff changeset
1353
kono
parents:
diff changeset
1354 FOR_EACH_EDGE (e, ei, exit_block->preds)
kono
parents:
diff changeset
1355 {
kono
parents:
diff changeset
1356 todo.quick_push (e->src);
kono
parents:
diff changeset
1357 bitmap_set_bit (seen, e->src->index);
kono
parents:
diff changeset
1358 }
kono
parents:
diff changeset
1359
kono
parents:
diff changeset
1360 while (!todo.is_empty ())
kono
parents:
diff changeset
1361 {
kono
parents:
diff changeset
1362 bb = todo.pop ();
kono
parents:
diff changeset
1363
kono
parents:
diff changeset
1364 bitmap_copy (old, SW (bb)->tail_components);
kono
parents:
diff changeset
1365
kono
parents:
diff changeset
1366 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
1367 bitmap_ior (SW (bb)->tail_components, SW (bb)->tail_components,
kono
parents:
diff changeset
1368 SW (e->dest)->tail_components);
kono
parents:
diff changeset
1369
kono
parents:
diff changeset
1370 bitmap_and_compl (SW (bb)->tail_components, SW (bb)->tail_components,
kono
parents:
diff changeset
1371 SW (bb)->has_components);
kono
parents:
diff changeset
1372
kono
parents:
diff changeset
1373 if (!bitmap_equal_p (old, SW (bb)->tail_components))
kono
parents:
diff changeset
1374 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents:
diff changeset
1375 if (bitmap_set_bit (seen, e->src->index))
kono
parents:
diff changeset
1376 todo.quick_push (e->src);
kono
parents:
diff changeset
1377
kono
parents:
diff changeset
1378 bitmap_clear_bit (seen, bb->index);
kono
parents:
diff changeset
1379 }
kono
parents:
diff changeset
1380
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1381 todo.release ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1382
111
kono
parents:
diff changeset
1383 /* Finally, mark everything not not needed both forwards and backwards. */
kono
parents:
diff changeset
1384
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1385 bool did_changes = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1386
111
kono
parents:
diff changeset
1387 FOR_EACH_BB_FN (bb, cfun)
kono
parents:
diff changeset
1388 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1389 bitmap_copy (old, SW (bb)->has_components);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1390
111
kono
parents:
diff changeset
1391 bitmap_and (SW (bb)->head_components, SW (bb)->head_components,
kono
parents:
diff changeset
1392 SW (bb)->tail_components);
kono
parents:
diff changeset
1393 bitmap_and_compl (SW (bb)->has_components, components,
kono
parents:
diff changeset
1394 SW (bb)->head_components);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1395
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1396 if (!did_changes && !bitmap_equal_p (old, SW (bb)->has_components))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1397 did_changes = true;
111
kono
parents:
diff changeset
1398 }
kono
parents:
diff changeset
1399
kono
parents:
diff changeset
1400 FOR_ALL_BB_FN (bb, cfun)
kono
parents:
diff changeset
1401 {
kono
parents:
diff changeset
1402 if (dump_file)
kono
parents:
diff changeset
1403 {
kono
parents:
diff changeset
1404 fprintf (dump_file, "bb %d components:", bb->index);
kono
parents:
diff changeset
1405 dump_components ("has", SW (bb)->has_components);
kono
parents:
diff changeset
1406 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1407 }
kono
parents:
diff changeset
1408 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1409
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1410 return did_changes;
111
kono
parents:
diff changeset
1411 }
kono
parents:
diff changeset
1412
kono
parents:
diff changeset
1413 /* If we cannot handle placing some component's prologues or epilogues where
kono
parents:
diff changeset
1414 we decided we should place them, unmark that component in COMPONENTS so
kono
parents:
diff changeset
1415 that it is not wrapped separately. */
kono
parents:
diff changeset
1416 static void
kono
parents:
diff changeset
1417 disqualify_problematic_components (sbitmap components)
kono
parents:
diff changeset
1418 {
kono
parents:
diff changeset
1419 auto_sbitmap pro (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1420 auto_sbitmap epi (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1421
kono
parents:
diff changeset
1422 basic_block bb;
kono
parents:
diff changeset
1423 FOR_EACH_BB_FN (bb, cfun)
kono
parents:
diff changeset
1424 {
kono
parents:
diff changeset
1425 edge e;
kono
parents:
diff changeset
1426 edge_iterator ei;
kono
parents:
diff changeset
1427 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
1428 {
kono
parents:
diff changeset
1429 /* Find which components we want pro/epilogues for here. */
kono
parents:
diff changeset
1430 bitmap_and_compl (epi, SW (e->src)->has_components,
kono
parents:
diff changeset
1431 SW (e->dest)->has_components);
kono
parents:
diff changeset
1432 bitmap_and_compl (pro, SW (e->dest)->has_components,
kono
parents:
diff changeset
1433 SW (e->src)->has_components);
kono
parents:
diff changeset
1434
kono
parents:
diff changeset
1435 /* Ask the target what it thinks about things. */
kono
parents:
diff changeset
1436 if (!bitmap_empty_p (epi))
kono
parents:
diff changeset
1437 targetm.shrink_wrap.disqualify_components (components, e, epi,
kono
parents:
diff changeset
1438 false);
kono
parents:
diff changeset
1439 if (!bitmap_empty_p (pro))
kono
parents:
diff changeset
1440 targetm.shrink_wrap.disqualify_components (components, e, pro,
kono
parents:
diff changeset
1441 true);
kono
parents:
diff changeset
1442
kono
parents:
diff changeset
1443 /* If this edge doesn't need splitting, we're fine. */
kono
parents:
diff changeset
1444 if (single_pred_p (e->dest)
kono
parents:
diff changeset
1445 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents:
diff changeset
1446 continue;
kono
parents:
diff changeset
1447
kono
parents:
diff changeset
1448 /* If the edge can be split, that is fine too. */
kono
parents:
diff changeset
1449 if ((e->flags & EDGE_ABNORMAL) == 0)
kono
parents:
diff changeset
1450 continue;
kono
parents:
diff changeset
1451
kono
parents:
diff changeset
1452 /* We also can handle sibcalls. */
kono
parents:
diff changeset
1453 if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents:
diff changeset
1454 {
kono
parents:
diff changeset
1455 gcc_assert (e->flags & EDGE_SIBCALL);
kono
parents:
diff changeset
1456 continue;
kono
parents:
diff changeset
1457 }
kono
parents:
diff changeset
1458
kono
parents:
diff changeset
1459 /* Remove from consideration those components we would need
kono
parents:
diff changeset
1460 pro/epilogues for on edges where we cannot insert them. */
kono
parents:
diff changeset
1461 bitmap_and_compl (components, components, epi);
kono
parents:
diff changeset
1462 bitmap_and_compl (components, components, pro);
kono
parents:
diff changeset
1463
kono
parents:
diff changeset
1464 if (dump_file && !bitmap_subset_p (epi, components))
kono
parents:
diff changeset
1465 {
kono
parents:
diff changeset
1466 fprintf (dump_file, " BAD epi %d->%d", e->src->index,
kono
parents:
diff changeset
1467 e->dest->index);
kono
parents:
diff changeset
1468 if (e->flags & EDGE_EH)
kono
parents:
diff changeset
1469 fprintf (dump_file, " for EH");
kono
parents:
diff changeset
1470 dump_components ("epi", epi);
kono
parents:
diff changeset
1471 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1472 }
kono
parents:
diff changeset
1473
kono
parents:
diff changeset
1474 if (dump_file && !bitmap_subset_p (pro, components))
kono
parents:
diff changeset
1475 {
kono
parents:
diff changeset
1476 fprintf (dump_file, " BAD pro %d->%d", e->src->index,
kono
parents:
diff changeset
1477 e->dest->index);
kono
parents:
diff changeset
1478 if (e->flags & EDGE_EH)
kono
parents:
diff changeset
1479 fprintf (dump_file, " for EH");
kono
parents:
diff changeset
1480 dump_components ("pro", pro);
kono
parents:
diff changeset
1481 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1482 }
kono
parents:
diff changeset
1483 }
kono
parents:
diff changeset
1484 }
kono
parents:
diff changeset
1485 }
kono
parents:
diff changeset
1486
kono
parents:
diff changeset
1487 /* Place code for prologues and epilogues for COMPONENTS where we can put
kono
parents:
diff changeset
1488 that code at the start of basic blocks. */
kono
parents:
diff changeset
1489 static void
kono
parents:
diff changeset
1490 emit_common_heads_for_components (sbitmap components)
kono
parents:
diff changeset
1491 {
kono
parents:
diff changeset
1492 auto_sbitmap pro (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1493 auto_sbitmap epi (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1494 auto_sbitmap tmp (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1495
kono
parents:
diff changeset
1496 basic_block bb;
kono
parents:
diff changeset
1497 FOR_ALL_BB_FN (bb, cfun)
kono
parents:
diff changeset
1498 bitmap_clear (SW (bb)->head_components);
kono
parents:
diff changeset
1499
kono
parents:
diff changeset
1500 FOR_EACH_BB_FN (bb, cfun)
kono
parents:
diff changeset
1501 {
kono
parents:
diff changeset
1502 /* Find which prologue resp. epilogue components are needed for all
kono
parents:
diff changeset
1503 predecessor edges to this block. */
kono
parents:
diff changeset
1504
kono
parents:
diff changeset
1505 /* First, select all possible components. */
kono
parents:
diff changeset
1506 bitmap_copy (epi, components);
kono
parents:
diff changeset
1507 bitmap_copy (pro, components);
kono
parents:
diff changeset
1508
kono
parents:
diff changeset
1509 edge e;
kono
parents:
diff changeset
1510 edge_iterator ei;
kono
parents:
diff changeset
1511 FOR_EACH_EDGE (e, ei, bb->preds)
kono
parents:
diff changeset
1512 {
kono
parents:
diff changeset
1513 if (e->flags & EDGE_ABNORMAL)
kono
parents:
diff changeset
1514 {
kono
parents:
diff changeset
1515 bitmap_clear (epi);
kono
parents:
diff changeset
1516 bitmap_clear (pro);
kono
parents:
diff changeset
1517 break;
kono
parents:
diff changeset
1518 }
kono
parents:
diff changeset
1519
kono
parents:
diff changeset
1520 /* Deselect those epilogue components that should not be inserted
kono
parents:
diff changeset
1521 for this edge. */
kono
parents:
diff changeset
1522 bitmap_and_compl (tmp, SW (e->src)->has_components,
kono
parents:
diff changeset
1523 SW (e->dest)->has_components);
kono
parents:
diff changeset
1524 bitmap_and (epi, epi, tmp);
kono
parents:
diff changeset
1525
kono
parents:
diff changeset
1526 /* Similar, for the prologue. */
kono
parents:
diff changeset
1527 bitmap_and_compl (tmp, SW (e->dest)->has_components,
kono
parents:
diff changeset
1528 SW (e->src)->has_components);
kono
parents:
diff changeset
1529 bitmap_and (pro, pro, tmp);
kono
parents:
diff changeset
1530 }
kono
parents:
diff changeset
1531
kono
parents:
diff changeset
1532 if (dump_file && !(bitmap_empty_p (epi) && bitmap_empty_p (pro)))
kono
parents:
diff changeset
1533 fprintf (dump_file, " bb %d", bb->index);
kono
parents:
diff changeset
1534
kono
parents:
diff changeset
1535 if (dump_file && !bitmap_empty_p (epi))
kono
parents:
diff changeset
1536 dump_components ("epi", epi);
kono
parents:
diff changeset
1537 if (dump_file && !bitmap_empty_p (pro))
kono
parents:
diff changeset
1538 dump_components ("pro", pro);
kono
parents:
diff changeset
1539
kono
parents:
diff changeset
1540 if (dump_file && !(bitmap_empty_p (epi) && bitmap_empty_p (pro)))
kono
parents:
diff changeset
1541 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1542
kono
parents:
diff changeset
1543 /* Place code after the BB note. */
kono
parents:
diff changeset
1544 if (!bitmap_empty_p (pro))
kono
parents:
diff changeset
1545 {
kono
parents:
diff changeset
1546 start_sequence ();
kono
parents:
diff changeset
1547 targetm.shrink_wrap.emit_prologue_components (pro);
kono
parents:
diff changeset
1548 rtx_insn *seq = get_insns ();
kono
parents:
diff changeset
1549 end_sequence ();
kono
parents:
diff changeset
1550 record_prologue_seq (seq);
kono
parents:
diff changeset
1551
kono
parents:
diff changeset
1552 emit_insn_after (seq, bb_note (bb));
kono
parents:
diff changeset
1553
kono
parents:
diff changeset
1554 bitmap_ior (SW (bb)->head_components, SW (bb)->head_components, pro);
kono
parents:
diff changeset
1555 }
kono
parents:
diff changeset
1556
kono
parents:
diff changeset
1557 if (!bitmap_empty_p (epi))
kono
parents:
diff changeset
1558 {
kono
parents:
diff changeset
1559 start_sequence ();
kono
parents:
diff changeset
1560 targetm.shrink_wrap.emit_epilogue_components (epi);
kono
parents:
diff changeset
1561 rtx_insn *seq = get_insns ();
kono
parents:
diff changeset
1562 end_sequence ();
kono
parents:
diff changeset
1563 record_epilogue_seq (seq);
kono
parents:
diff changeset
1564
kono
parents:
diff changeset
1565 emit_insn_after (seq, bb_note (bb));
kono
parents:
diff changeset
1566
kono
parents:
diff changeset
1567 bitmap_ior (SW (bb)->head_components, SW (bb)->head_components, epi);
kono
parents:
diff changeset
1568 }
kono
parents:
diff changeset
1569 }
kono
parents:
diff changeset
1570 }
kono
parents:
diff changeset
1571
kono
parents:
diff changeset
1572 /* Place code for prologues and epilogues for COMPONENTS where we can put
kono
parents:
diff changeset
1573 that code at the end of basic blocks. */
kono
parents:
diff changeset
1574 static void
kono
parents:
diff changeset
1575 emit_common_tails_for_components (sbitmap components)
kono
parents:
diff changeset
1576 {
kono
parents:
diff changeset
1577 auto_sbitmap pro (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1578 auto_sbitmap epi (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1579 auto_sbitmap tmp (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1580
kono
parents:
diff changeset
1581 basic_block bb;
kono
parents:
diff changeset
1582 FOR_ALL_BB_FN (bb, cfun)
kono
parents:
diff changeset
1583 bitmap_clear (SW (bb)->tail_components);
kono
parents:
diff changeset
1584
kono
parents:
diff changeset
1585 FOR_EACH_BB_FN (bb, cfun)
kono
parents:
diff changeset
1586 {
kono
parents:
diff changeset
1587 /* Find which prologue resp. epilogue components are needed for all
kono
parents:
diff changeset
1588 successor edges from this block. */
kono
parents:
diff changeset
1589 if (EDGE_COUNT (bb->succs) == 0)
kono
parents:
diff changeset
1590 continue;
kono
parents:
diff changeset
1591
kono
parents:
diff changeset
1592 /* First, select all possible components. */
kono
parents:
diff changeset
1593 bitmap_copy (epi, components);
kono
parents:
diff changeset
1594 bitmap_copy (pro, components);
kono
parents:
diff changeset
1595
kono
parents:
diff changeset
1596 edge e;
kono
parents:
diff changeset
1597 edge_iterator ei;
kono
parents:
diff changeset
1598 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
1599 {
kono
parents:
diff changeset
1600 if (e->flags & EDGE_ABNORMAL)
kono
parents:
diff changeset
1601 {
kono
parents:
diff changeset
1602 bitmap_clear (epi);
kono
parents:
diff changeset
1603 bitmap_clear (pro);
kono
parents:
diff changeset
1604 break;
kono
parents:
diff changeset
1605 }
kono
parents:
diff changeset
1606
kono
parents:
diff changeset
1607 /* Deselect those epilogue components that should not be inserted
kono
parents:
diff changeset
1608 for this edge, and also those that are already put at the head
kono
parents:
diff changeset
1609 of the successor block. */
kono
parents:
diff changeset
1610 bitmap_and_compl (tmp, SW (e->src)->has_components,
kono
parents:
diff changeset
1611 SW (e->dest)->has_components);
kono
parents:
diff changeset
1612 bitmap_and_compl (tmp, tmp, SW (e->dest)->head_components);
kono
parents:
diff changeset
1613 bitmap_and (epi, epi, tmp);
kono
parents:
diff changeset
1614
kono
parents:
diff changeset
1615 /* Similarly, for the prologue. */
kono
parents:
diff changeset
1616 bitmap_and_compl (tmp, SW (e->dest)->has_components,
kono
parents:
diff changeset
1617 SW (e->src)->has_components);
kono
parents:
diff changeset
1618 bitmap_and_compl (tmp, tmp, SW (e->dest)->head_components);
kono
parents:
diff changeset
1619 bitmap_and (pro, pro, tmp);
kono
parents:
diff changeset
1620 }
kono
parents:
diff changeset
1621
kono
parents:
diff changeset
1622 /* If the last insn of this block is a control flow insn we cannot
kono
parents:
diff changeset
1623 put anything after it. We can put our code before it instead,
kono
parents:
diff changeset
1624 but only if that jump insn is a simple jump. */
kono
parents:
diff changeset
1625 rtx_insn *last_insn = BB_END (bb);
kono
parents:
diff changeset
1626 if (control_flow_insn_p (last_insn) && !simplejump_p (last_insn))
kono
parents:
diff changeset
1627 {
kono
parents:
diff changeset
1628 bitmap_clear (epi);
kono
parents:
diff changeset
1629 bitmap_clear (pro);
kono
parents:
diff changeset
1630 }
kono
parents:
diff changeset
1631
kono
parents:
diff changeset
1632 if (dump_file && !(bitmap_empty_p (epi) && bitmap_empty_p (pro)))
kono
parents:
diff changeset
1633 fprintf (dump_file, " bb %d", bb->index);
kono
parents:
diff changeset
1634
kono
parents:
diff changeset
1635 if (dump_file && !bitmap_empty_p (epi))
kono
parents:
diff changeset
1636 dump_components ("epi", epi);
kono
parents:
diff changeset
1637 if (dump_file && !bitmap_empty_p (pro))
kono
parents:
diff changeset
1638 dump_components ("pro", pro);
kono
parents:
diff changeset
1639
kono
parents:
diff changeset
1640 if (dump_file && !(bitmap_empty_p (epi) && bitmap_empty_p (pro)))
kono
parents:
diff changeset
1641 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1642
kono
parents:
diff changeset
1643 /* Put the code at the end of the BB, but before any final jump. */
kono
parents:
diff changeset
1644 if (!bitmap_empty_p (epi))
kono
parents:
diff changeset
1645 {
kono
parents:
diff changeset
1646 start_sequence ();
kono
parents:
diff changeset
1647 targetm.shrink_wrap.emit_epilogue_components (epi);
kono
parents:
diff changeset
1648 rtx_insn *seq = get_insns ();
kono
parents:
diff changeset
1649 end_sequence ();
kono
parents:
diff changeset
1650 record_epilogue_seq (seq);
kono
parents:
diff changeset
1651
kono
parents:
diff changeset
1652 if (control_flow_insn_p (last_insn))
kono
parents:
diff changeset
1653 emit_insn_before (seq, last_insn);
kono
parents:
diff changeset
1654 else
kono
parents:
diff changeset
1655 emit_insn_after (seq, last_insn);
kono
parents:
diff changeset
1656
kono
parents:
diff changeset
1657 bitmap_ior (SW (bb)->tail_components, SW (bb)->tail_components, epi);
kono
parents:
diff changeset
1658 }
kono
parents:
diff changeset
1659
kono
parents:
diff changeset
1660 if (!bitmap_empty_p (pro))
kono
parents:
diff changeset
1661 {
kono
parents:
diff changeset
1662 start_sequence ();
kono
parents:
diff changeset
1663 targetm.shrink_wrap.emit_prologue_components (pro);
kono
parents:
diff changeset
1664 rtx_insn *seq = get_insns ();
kono
parents:
diff changeset
1665 end_sequence ();
kono
parents:
diff changeset
1666 record_prologue_seq (seq);
kono
parents:
diff changeset
1667
kono
parents:
diff changeset
1668 if (control_flow_insn_p (last_insn))
kono
parents:
diff changeset
1669 emit_insn_before (seq, last_insn);
kono
parents:
diff changeset
1670 else
kono
parents:
diff changeset
1671 emit_insn_after (seq, last_insn);
kono
parents:
diff changeset
1672
kono
parents:
diff changeset
1673 bitmap_ior (SW (bb)->tail_components, SW (bb)->tail_components, pro);
kono
parents:
diff changeset
1674 }
kono
parents:
diff changeset
1675 }
kono
parents:
diff changeset
1676 }
kono
parents:
diff changeset
1677
kono
parents:
diff changeset
1678 /* Place prologues and epilogues for COMPONENTS on edges, if we haven't already
kono
parents:
diff changeset
1679 placed them inside blocks directly. */
kono
parents:
diff changeset
1680 static void
kono
parents:
diff changeset
1681 insert_prologue_epilogue_for_components (sbitmap components)
kono
parents:
diff changeset
1682 {
kono
parents:
diff changeset
1683 auto_sbitmap pro (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1684 auto_sbitmap epi (SBITMAP_SIZE (components));
kono
parents:
diff changeset
1685
kono
parents:
diff changeset
1686 basic_block bb;
kono
parents:
diff changeset
1687 FOR_EACH_BB_FN (bb, cfun)
kono
parents:
diff changeset
1688 {
kono
parents:
diff changeset
1689 if (!bb->aux)
kono
parents:
diff changeset
1690 continue;
kono
parents:
diff changeset
1691
kono
parents:
diff changeset
1692 edge e;
kono
parents:
diff changeset
1693 edge_iterator ei;
kono
parents:
diff changeset
1694 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents:
diff changeset
1695 {
kono
parents:
diff changeset
1696 /* Find which pro/epilogue components are needed on this edge. */
kono
parents:
diff changeset
1697 bitmap_and_compl (epi, SW (e->src)->has_components,
kono
parents:
diff changeset
1698 SW (e->dest)->has_components);
kono
parents:
diff changeset
1699 bitmap_and_compl (pro, SW (e->dest)->has_components,
kono
parents:
diff changeset
1700 SW (e->src)->has_components);
kono
parents:
diff changeset
1701 bitmap_and (epi, epi, components);
kono
parents:
diff changeset
1702 bitmap_and (pro, pro, components);
kono
parents:
diff changeset
1703
kono
parents:
diff changeset
1704 /* Deselect those we already have put at the head or tail of the
kono
parents:
diff changeset
1705 edge's dest resp. src. */
kono
parents:
diff changeset
1706 bitmap_and_compl (epi, epi, SW (e->dest)->head_components);
kono
parents:
diff changeset
1707 bitmap_and_compl (pro, pro, SW (e->dest)->head_components);
kono
parents:
diff changeset
1708 bitmap_and_compl (epi, epi, SW (e->src)->tail_components);
kono
parents:
diff changeset
1709 bitmap_and_compl (pro, pro, SW (e->src)->tail_components);
kono
parents:
diff changeset
1710
kono
parents:
diff changeset
1711 if (!bitmap_empty_p (epi) || !bitmap_empty_p (pro))
kono
parents:
diff changeset
1712 {
kono
parents:
diff changeset
1713 if (dump_file)
kono
parents:
diff changeset
1714 {
kono
parents:
diff changeset
1715 fprintf (dump_file, " %d->%d", e->src->index,
kono
parents:
diff changeset
1716 e->dest->index);
kono
parents:
diff changeset
1717 dump_components ("epi", epi);
kono
parents:
diff changeset
1718 dump_components ("pro", pro);
kono
parents:
diff changeset
1719 if (e->flags & EDGE_SIBCALL)
kono
parents:
diff changeset
1720 fprintf (dump_file, " (SIBCALL)");
kono
parents:
diff changeset
1721 else if (e->flags & EDGE_ABNORMAL)
kono
parents:
diff changeset
1722 fprintf (dump_file, " (ABNORMAL)");
kono
parents:
diff changeset
1723 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1724 }
kono
parents:
diff changeset
1725
kono
parents:
diff changeset
1726 /* Put the epilogue components in place. */
kono
parents:
diff changeset
1727 start_sequence ();
kono
parents:
diff changeset
1728 targetm.shrink_wrap.emit_epilogue_components (epi);
kono
parents:
diff changeset
1729 rtx_insn *seq = get_insns ();
kono
parents:
diff changeset
1730 end_sequence ();
kono
parents:
diff changeset
1731 record_epilogue_seq (seq);
kono
parents:
diff changeset
1732
kono
parents:
diff changeset
1733 if (e->flags & EDGE_SIBCALL)
kono
parents:
diff changeset
1734 {
kono
parents:
diff changeset
1735 gcc_assert (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun));
kono
parents:
diff changeset
1736
kono
parents:
diff changeset
1737 rtx_insn *insn = BB_END (e->src);
kono
parents:
diff changeset
1738 gcc_assert (CALL_P (insn) && SIBLING_CALL_P (insn));
kono
parents:
diff changeset
1739 emit_insn_before (seq, insn);
kono
parents:
diff changeset
1740 }
kono
parents:
diff changeset
1741 else if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents:
diff changeset
1742 {
kono
parents:
diff changeset
1743 gcc_assert (e->flags & EDGE_FALLTHRU);
kono
parents:
diff changeset
1744 basic_block new_bb = split_edge (e);
kono
parents:
diff changeset
1745 emit_insn_after (seq, BB_END (new_bb));
kono
parents:
diff changeset
1746 }
kono
parents:
diff changeset
1747 else
kono
parents:
diff changeset
1748 insert_insn_on_edge (seq, e);
kono
parents:
diff changeset
1749
kono
parents:
diff changeset
1750 /* Put the prologue components in place. */
kono
parents:
diff changeset
1751 start_sequence ();
kono
parents:
diff changeset
1752 targetm.shrink_wrap.emit_prologue_components (pro);
kono
parents:
diff changeset
1753 seq = get_insns ();
kono
parents:
diff changeset
1754 end_sequence ();
kono
parents:
diff changeset
1755 record_prologue_seq (seq);
kono
parents:
diff changeset
1756
kono
parents:
diff changeset
1757 insert_insn_on_edge (seq, e);
kono
parents:
diff changeset
1758 }
kono
parents:
diff changeset
1759 }
kono
parents:
diff changeset
1760 }
kono
parents:
diff changeset
1761
kono
parents:
diff changeset
1762 commit_edge_insertions ();
kono
parents:
diff changeset
1763 }
kono
parents:
diff changeset
1764
kono
parents:
diff changeset
1765 /* The main entry point to this subpass. FIRST_BB is where the prologue
kono
parents:
diff changeset
1766 would be normally put. */
kono
parents:
diff changeset
1767 void
kono
parents:
diff changeset
1768 try_shrink_wrapping_separate (basic_block first_bb)
kono
parents:
diff changeset
1769 {
kono
parents:
diff changeset
1770 if (HAVE_cc0)
kono
parents:
diff changeset
1771 return;
kono
parents:
diff changeset
1772
kono
parents:
diff changeset
1773 if (!(SHRINK_WRAPPING_ENABLED
kono
parents:
diff changeset
1774 && flag_shrink_wrap_separate
kono
parents:
diff changeset
1775 && optimize_function_for_speed_p (cfun)
kono
parents:
diff changeset
1776 && targetm.shrink_wrap.get_separate_components))
kono
parents:
diff changeset
1777 return;
kono
parents:
diff changeset
1778
kono
parents:
diff changeset
1779 /* We don't handle "strange" functions. */
kono
parents:
diff changeset
1780 if (cfun->calls_alloca
kono
parents:
diff changeset
1781 || cfun->calls_setjmp
kono
parents:
diff changeset
1782 || cfun->can_throw_non_call_exceptions
kono
parents:
diff changeset
1783 || crtl->calls_eh_return
kono
parents:
diff changeset
1784 || crtl->has_nonlocal_goto
kono
parents:
diff changeset
1785 || crtl->saves_all_registers)
kono
parents:
diff changeset
1786 return;
kono
parents:
diff changeset
1787
kono
parents:
diff changeset
1788 /* Ask the target what components there are. If it returns NULL, don't
kono
parents:
diff changeset
1789 do anything. */
kono
parents:
diff changeset
1790 sbitmap components = targetm.shrink_wrap.get_separate_components ();
kono
parents:
diff changeset
1791 if (!components)
kono
parents:
diff changeset
1792 return;
kono
parents:
diff changeset
1793
kono
parents:
diff changeset
1794 /* We need LIVE info, not defining anything in the entry block and not
kono
parents:
diff changeset
1795 using anything in the exit block. A block then needs a component if
kono
parents:
diff changeset
1796 the register for that component is in the IN or GEN or KILL set for
kono
parents:
diff changeset
1797 that block. */
kono
parents:
diff changeset
1798 df_scan->local_flags |= DF_SCAN_EMPTY_ENTRY_EXIT;
kono
parents:
diff changeset
1799 df_update_entry_exit_and_calls ();
kono
parents:
diff changeset
1800 df_live_add_problem ();
kono
parents:
diff changeset
1801 df_live_set_all_dirty ();
kono
parents:
diff changeset
1802 df_analyze ();
kono
parents:
diff changeset
1803
kono
parents:
diff changeset
1804 calculate_dominance_info (CDI_DOMINATORS);
kono
parents:
diff changeset
1805 calculate_dominance_info (CDI_POST_DOMINATORS);
kono
parents:
diff changeset
1806
kono
parents:
diff changeset
1807 init_separate_shrink_wrap (components);
kono
parents:
diff changeset
1808
kono
parents:
diff changeset
1809 sbitmap_iterator sbi;
kono
parents:
diff changeset
1810 unsigned int j;
kono
parents:
diff changeset
1811 EXECUTE_IF_SET_IN_BITMAP (components, 0, j, sbi)
kono
parents:
diff changeset
1812 place_prologue_for_one_component (j, first_bb);
kono
parents:
diff changeset
1813
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1814 /* Try to minimize the number of saves and restores. Do this as long as
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1815 it changes anything. This does not iterate more than a few times. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1816 int spread_times = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1817 while (spread_components (components))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1818 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1819 spread_times++;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1820
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1821 if (dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1822 fprintf (dump_file, "Now spread %d times.\n", spread_times);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1823 }
111
kono
parents:
diff changeset
1824
kono
parents:
diff changeset
1825 disqualify_problematic_components (components);
kono
parents:
diff changeset
1826
kono
parents:
diff changeset
1827 /* Don't separately shrink-wrap anything where the "main" prologue will
kono
parents:
diff changeset
1828 go; the target code can often optimize things if it is presented with
kono
parents:
diff changeset
1829 all components together (say, if it generates store-multiple insns). */
kono
parents:
diff changeset
1830 bitmap_and_compl (components, components, SW (first_bb)->has_components);
kono
parents:
diff changeset
1831
kono
parents:
diff changeset
1832 if (bitmap_empty_p (components))
kono
parents:
diff changeset
1833 {
kono
parents:
diff changeset
1834 if (dump_file)
kono
parents:
diff changeset
1835 fprintf (dump_file, "Not wrapping anything separately.\n");
kono
parents:
diff changeset
1836 }
kono
parents:
diff changeset
1837 else
kono
parents:
diff changeset
1838 {
kono
parents:
diff changeset
1839 if (dump_file)
kono
parents:
diff changeset
1840 {
kono
parents:
diff changeset
1841 fprintf (dump_file, "The components we wrap separately are");
kono
parents:
diff changeset
1842 dump_components ("sep", components);
kono
parents:
diff changeset
1843 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1844
kono
parents:
diff changeset
1845 fprintf (dump_file, "... Inserting common heads...\n");
kono
parents:
diff changeset
1846 }
kono
parents:
diff changeset
1847
kono
parents:
diff changeset
1848 emit_common_heads_for_components (components);
kono
parents:
diff changeset
1849
kono
parents:
diff changeset
1850 if (dump_file)
kono
parents:
diff changeset
1851 fprintf (dump_file, "... Inserting common tails...\n");
kono
parents:
diff changeset
1852
kono
parents:
diff changeset
1853 emit_common_tails_for_components (components);
kono
parents:
diff changeset
1854
kono
parents:
diff changeset
1855 if (dump_file)
kono
parents:
diff changeset
1856 fprintf (dump_file, "... Inserting the more difficult ones...\n");
kono
parents:
diff changeset
1857
kono
parents:
diff changeset
1858 insert_prologue_epilogue_for_components (components);
kono
parents:
diff changeset
1859
kono
parents:
diff changeset
1860 if (dump_file)
kono
parents:
diff changeset
1861 fprintf (dump_file, "... Done.\n");
kono
parents:
diff changeset
1862
kono
parents:
diff changeset
1863 targetm.shrink_wrap.set_handled_components (components);
kono
parents:
diff changeset
1864
kono
parents:
diff changeset
1865 crtl->shrink_wrapped_separate = true;
kono
parents:
diff changeset
1866 }
kono
parents:
diff changeset
1867
kono
parents:
diff changeset
1868 fini_separate_shrink_wrap ();
kono
parents:
diff changeset
1869
kono
parents:
diff changeset
1870 sbitmap_free (components);
kono
parents:
diff changeset
1871 free_dominance_info (CDI_DOMINATORS);
kono
parents:
diff changeset
1872 free_dominance_info (CDI_POST_DOMINATORS);
kono
parents:
diff changeset
1873
kono
parents:
diff changeset
1874 /* All done. */
kono
parents:
diff changeset
1875 df_scan->local_flags &= ~DF_SCAN_EMPTY_ENTRY_EXIT;
kono
parents:
diff changeset
1876 df_update_entry_exit_and_calls ();
kono
parents:
diff changeset
1877 df_live_set_all_dirty ();
kono
parents:
diff changeset
1878 df_analyze ();
kono
parents:
diff changeset
1879 }