re PR rtl-optimization/57968 (MODE_EXIT switches inserted too early)
[platform/upstream/gcc.git] / gcc / mode-switching.c
1 /* CPU mode switching
2    Copyright (C) 1998-2013 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "flags.h"
29 #include "insn-config.h"
30 #include "recog.h"
31 #include "basic-block.h"
32 #include "tm_p.h"
33 #include "function.h"
34 #include "tree-pass.h"
35 #include "df.h"
36 #include "emit-rtl.h"
37
38 /* We want target macros for the mode switching code to be able to refer
39    to instruction attribute values.  */
40 #include "insn-attr.h"
41
42 #ifdef OPTIMIZE_MODE_SWITCHING
43
44 /* The algorithm for setting the modes consists of scanning the insn list
45    and finding all the insns which require a specific mode.  Each insn gets
46    a unique struct seginfo element.  These structures are inserted into a list
47    for each basic block.  For each entity, there is an array of bb_info over
48    the flow graph basic blocks (local var 'bb_info'), and contains a list
49    of all insns within that basic block, in the order they are encountered.
50
51    For each entity, any basic block WITHOUT any insns requiring a specific
52    mode are given a single entry, without a mode.  (Each basic block
53    in the flow graph must have at least one entry in the segment table.)
54
55    The LCM algorithm is then run over the flow graph to determine where to
56    place the sets to the highest-priority value in respect of first the first
57    insn in any one block.  Any adjustments required to the transparency
58    vectors are made, then the next iteration starts for the next-lower
59    priority mode, till for each entity all modes are exhausted.
60
61    More details are located in the code for optimize_mode_switching().  */
62 \f
63 /* This structure contains the information for each insn which requires
64    either single or double mode to be set.
65    MODE is the mode this insn must be executed in.
66    INSN_PTR is the insn to be executed (may be the note that marks the
67    beginning of a basic block).
68    BBNUM is the flow graph basic block this insn occurs in.
69    NEXT is the next insn in the same basic block.  */
70 struct seginfo
71 {
72   int mode;
73   rtx insn_ptr;
74   int bbnum;
75   struct seginfo *next;
76   HARD_REG_SET regs_live;
77 };
78
79 struct bb_info
80 {
81   struct seginfo *seginfo;
82   int computing;
83 };
84
85 /* These bitmaps are used for the LCM algorithm.  */
86
87 static sbitmap *antic;
88 static sbitmap *transp;
89 static sbitmap *comp;
90
91 static struct seginfo * new_seginfo (int, rtx, int, HARD_REG_SET);
92 static void add_seginfo (struct bb_info *, struct seginfo *);
93 static void reg_dies (rtx, HARD_REG_SET *);
94 static void reg_becomes_live (rtx, const_rtx, void *);
95 static void make_preds_opaque (basic_block, int);
96 \f
97
98 /* This function will allocate a new BBINFO structure, initialized
99    with the MODE, INSN, and basic block BB parameters.  */
100
101 static struct seginfo *
102 new_seginfo (int mode, rtx insn, int bb, HARD_REG_SET regs_live)
103 {
104   struct seginfo *ptr;
105   ptr = XNEW (struct seginfo);
106   ptr->mode = mode;
107   ptr->insn_ptr = insn;
108   ptr->bbnum = bb;
109   ptr->next = NULL;
110   COPY_HARD_REG_SET (ptr->regs_live, regs_live);
111   return ptr;
112 }
113
114 /* Add a seginfo element to the end of a list.
115    HEAD is a pointer to the list beginning.
116    INFO is the structure to be linked in.  */
117
118 static void
119 add_seginfo (struct bb_info *head, struct seginfo *info)
120 {
121   struct seginfo *ptr;
122
123   if (head->seginfo == NULL)
124     head->seginfo = info;
125   else
126     {
127       ptr = head->seginfo;
128       while (ptr->next != NULL)
129         ptr = ptr->next;
130       ptr->next = info;
131     }
132 }
133
134 /* Make all predecessors of basic block B opaque, recursively, till we hit
135    some that are already non-transparent, or an edge where aux is set; that
136    denotes that a mode set is to be done on that edge.
137    J is the bit number in the bitmaps that corresponds to the entity that
138    we are currently handling mode-switching for.  */
139
140 static void
141 make_preds_opaque (basic_block b, int j)
142 {
143   edge e;
144   edge_iterator ei;
145
146   FOR_EACH_EDGE (e, ei, b->preds)
147     {
148       basic_block pb = e->src;
149
150       if (e->aux || ! bitmap_bit_p (transp[pb->index], j))
151         continue;
152
153       bitmap_clear_bit (transp[pb->index], j);
154       make_preds_opaque (pb, j);
155     }
156 }
157
158 /* Record in LIVE that register REG died.  */
159
160 static void
161 reg_dies (rtx reg, HARD_REG_SET *live)
162 {
163   int regno;
164
165   if (!REG_P (reg))
166     return;
167
168   regno = REGNO (reg);
169   if (regno < FIRST_PSEUDO_REGISTER)
170     remove_from_hard_reg_set (live, GET_MODE (reg), regno);
171 }
172
173 /* Record in LIVE that register REG became live.
174    This is called via note_stores.  */
175
176 static void
177 reg_becomes_live (rtx reg, const_rtx setter ATTRIBUTE_UNUSED, void *live)
178 {
179   int regno;
180
181   if (GET_CODE (reg) == SUBREG)
182     reg = SUBREG_REG (reg);
183
184   if (!REG_P (reg))
185     return;
186
187   regno = REGNO (reg);
188   if (regno < FIRST_PSEUDO_REGISTER)
189     add_to_hard_reg_set ((HARD_REG_SET *) live, GET_MODE (reg), regno);
190 }
191
192 /* Make sure if MODE_ENTRY is defined the MODE_EXIT is defined
193    and vice versa.  */
194 #if defined (MODE_ENTRY) != defined (MODE_EXIT)
195  #error "Both MODE_ENTRY and MODE_EXIT must be defined"
196 #endif
197
198 #if defined (MODE_ENTRY) && defined (MODE_EXIT)
199 /* Split the fallthrough edge to the exit block, so that we can note
200    that there NORMAL_MODE is required.  Return the new block if it's
201    inserted before the exit block.  Otherwise return null.  */
202
203 static basic_block
204 create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
205 {
206   edge eg;
207   edge_iterator ei;
208   basic_block pre_exit;
209
210   /* The only non-call predecessor at this stage is a block with a
211      fallthrough edge; there can be at most one, but there could be
212      none at all, e.g. when exit is called.  */
213   pre_exit = 0;
214   FOR_EACH_EDGE (eg, ei, EXIT_BLOCK_PTR->preds)
215     if (eg->flags & EDGE_FALLTHRU)
216       {
217         basic_block src_bb = eg->src;
218         rtx last_insn, ret_reg;
219
220         gcc_assert (!pre_exit);
221         /* If this function returns a value at the end, we have to
222            insert the final mode switch before the return value copy
223            to its hard register.  */
224         if (EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 1
225             && NONJUMP_INSN_P ((last_insn = BB_END (src_bb)))
226             && GET_CODE (PATTERN (last_insn)) == USE
227             && GET_CODE ((ret_reg = XEXP (PATTERN (last_insn), 0))) == REG)
228           {
229             int ret_start = REGNO (ret_reg);
230             int nregs = hard_regno_nregs[ret_start][GET_MODE (ret_reg)];
231             int ret_end = ret_start + nregs;
232             int short_block = 0;
233             int maybe_builtin_apply = 0;
234             int forced_late_switch = 0;
235             rtx before_return_copy;
236
237             do
238               {
239                 rtx return_copy = PREV_INSN (last_insn);
240                 rtx return_copy_pat, copy_reg;
241                 int copy_start, copy_num;
242                 int j;
243
244                 if (NONDEBUG_INSN_P (return_copy))
245                   {
246                     /* When using SJLJ exceptions, the call to the
247                        unregister function is inserted between the
248                        clobber of the return value and the copy.
249                        We do not want to split the block before this
250                        or any other call; if we have not found the
251                        copy yet, the copy must have been deleted.  */
252                     if (CALL_P (return_copy))
253                       {
254                         short_block = 1;
255                         break;
256                       }
257                     return_copy_pat = PATTERN (return_copy);
258                     switch (GET_CODE (return_copy_pat))
259                       {
260                       case USE:
261                         /* Skip __builtin_apply pattern.  */
262                         if (GET_CODE (XEXP (return_copy_pat, 0)) == REG
263                             && (targetm.calls.function_value_regno_p
264                                 (REGNO (XEXP (return_copy_pat, 0)))))
265                           {
266                             maybe_builtin_apply = 1;
267                             last_insn = return_copy;
268                             continue;
269                           }
270                         break;
271
272                       case ASM_OPERANDS:
273                         /* Skip barrier insns.  */
274                         if (!MEM_VOLATILE_P (return_copy_pat))
275                           break;
276
277                         /* Fall through.  */
278
279                       case ASM_INPUT:
280                       case UNSPEC_VOLATILE:
281                         last_insn = return_copy;
282                         continue;
283
284                       default:
285                         break;
286                       }
287
288                     /* If the return register is not (in its entirety)
289                        likely spilled, the return copy might be
290                        partially or completely optimized away.  */
291                     return_copy_pat = single_set (return_copy);
292                     if (!return_copy_pat)
293                       {
294                         return_copy_pat = PATTERN (return_copy);
295                         if (GET_CODE (return_copy_pat) != CLOBBER)
296                           break;
297                         else if (!optimize)
298                           {
299                             /* This might be (clobber (reg [<result>]))
300                                when not optimizing.  Then check if
301                                the previous insn is the clobber for
302                                the return register.  */
303                             copy_reg = SET_DEST (return_copy_pat);
304                             if (GET_CODE (copy_reg) == REG
305                                 && !HARD_REGISTER_NUM_P (REGNO (copy_reg)))
306                               {
307                                 if (INSN_P (PREV_INSN (return_copy)))
308                                   {
309                                     return_copy = PREV_INSN (return_copy);
310                                     return_copy_pat = PATTERN (return_copy);
311                                     if (GET_CODE (return_copy_pat) != CLOBBER)
312                                       break;
313                                   }
314                               }
315                           }
316                       }
317                     copy_reg = SET_DEST (return_copy_pat);
318                     if (GET_CODE (copy_reg) == REG)
319                       copy_start = REGNO (copy_reg);
320                     else if (GET_CODE (copy_reg) == SUBREG
321                              && GET_CODE (SUBREG_REG (copy_reg)) == REG)
322                       copy_start = REGNO (SUBREG_REG (copy_reg));
323                     else
324                       {
325                         /* When control reaches end of non-void function,
326                            there are no return copy insns at all.  This
327                            avoids an ice on that invalid function.  */
328                         if (ret_start + nregs == ret_end)
329                           short_block = 1;
330                         break;
331                       }
332                     if (!targetm.calls.function_value_regno_p (copy_start))
333                       copy_num = 0;
334                     else
335                       copy_num
336                         = hard_regno_nregs[copy_start][GET_MODE (copy_reg)];
337
338                     /* If the return register is not likely spilled, - as is
339                        the case for floating point on SH4 - then it might
340                        be set by an arithmetic operation that needs a
341                        different mode than the exit block.  */
342                     for (j = n_entities - 1; j >= 0; j--)
343                       {
344                         int e = entity_map[j];
345                         int mode = MODE_NEEDED (e, return_copy);
346
347                         if (mode != num_modes[e] && mode != MODE_EXIT (e))
348                           break;
349                       }
350                     if (j >= 0)
351                       {
352                         /* __builtin_return emits a sequence of loads to all
353                            return registers.  One of them might require
354                            another mode than MODE_EXIT, even if it is
355                            unrelated to the return value, so we want to put
356                            the final mode switch after it.  */
357                         if (maybe_builtin_apply
358                             && targetm.calls.function_value_regno_p
359                                 (copy_start))
360                           forced_late_switch = 1;
361
362                         /* For the SH4, floating point loads depend on fpscr,
363                            thus we might need to put the final mode switch
364                            after the return value copy.  That is still OK,
365                            because a floating point return value does not
366                            conflict with address reloads.  */
367                         if (copy_start >= ret_start
368                             && copy_start + copy_num <= ret_end
369                             && OBJECT_P (SET_SRC (return_copy_pat)))
370                           forced_late_switch = 1;
371                         break;
372                       }
373                     if (copy_num == 0)
374                       {
375                         last_insn = return_copy;
376                         continue;
377                       }
378
379                     if (copy_start >= ret_start
380                         && copy_start + copy_num <= ret_end)
381                       nregs -= copy_num;
382                     else if (!maybe_builtin_apply
383                              || !targetm.calls.function_value_regno_p
384                                  (copy_start))
385                       break;
386                     last_insn = return_copy;
387                   }
388                 /* ??? Exception handling can lead to the return value
389                    copy being already separated from the return value use,
390                    as in  unwind-dw2.c .
391                    Similarly, conditionally returning without a value,
392                    and conditionally using builtin_return can lead to an
393                    isolated use.  */
394                 if (return_copy == BB_HEAD (src_bb))
395                   {
396                     short_block = 1;
397                     break;
398                   }
399                 last_insn = return_copy;
400               }
401             while (nregs);
402
403             /* If we didn't see a full return value copy, verify that there
404                is a plausible reason for this.  If some, but not all of the
405                return register is likely spilled, we can expect that there
406                is a copy for the likely spilled part.  */
407             gcc_assert (!nregs
408                         || forced_late_switch
409                         || short_block
410                         || !(targetm.class_likely_spilled_p
411                              (REGNO_REG_CLASS (ret_start)))
412                         || (nregs
413                             != hard_regno_nregs[ret_start][GET_MODE (ret_reg)])
414                         /* For multi-hard-register floating point
415                            values, sometimes the likely-spilled part
416                            is ordinarily copied first, then the other
417                            part is set with an arithmetic operation.
418                            This doesn't actually cause reload
419                            failures, so let it pass.  */
420                         || (GET_MODE_CLASS (GET_MODE (ret_reg)) != MODE_INT
421                             && nregs != 1));
422
423             if (INSN_P (last_insn))
424               {
425                 before_return_copy
426                   = emit_note_before (NOTE_INSN_DELETED, last_insn);
427                 /* Instructions preceding LAST_INSN in the same block might
428                    require a different mode than MODE_EXIT, so if we might
429                    have such instructions, keep them in a separate block
430                    from pre_exit.  */
431                 if (last_insn != BB_HEAD (src_bb))
432                   src_bb = split_block (src_bb,
433                                         PREV_INSN (before_return_copy))->dest;
434               }
435             else
436               before_return_copy = last_insn;
437             pre_exit = split_block (src_bb, before_return_copy)->src;
438           }
439         else
440           {
441             pre_exit = split_edge (eg);
442           }
443       }
444
445   return pre_exit;
446 }
447 #endif
448
449 /* Find all insns that need a particular mode setting, and insert the
450    necessary mode switches.  Return true if we did work.  */
451
452 static int
453 optimize_mode_switching (void)
454 {
455   rtx insn;
456   int e;
457   basic_block bb;
458   int need_commit = 0;
459   sbitmap *kill;
460   struct edge_list *edge_list;
461   static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
462 #define N_ENTITIES ARRAY_SIZE (num_modes)
463   int entity_map[N_ENTITIES];
464   struct bb_info *bb_info[N_ENTITIES];
465   int i, j;
466   int n_entities;
467   int max_num_modes = 0;
468   bool emitted ATTRIBUTE_UNUSED = false;
469   basic_block post_entry ATTRIBUTE_UNUSED, pre_exit ATTRIBUTE_UNUSED;
470
471   for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--)
472     if (OPTIMIZE_MODE_SWITCHING (e))
473       {
474         int entry_exit_extra = 0;
475
476         /* Create the list of segments within each basic block.
477            If NORMAL_MODE is defined, allow for two extra
478            blocks split from the entry and exit block.  */
479 #if defined (MODE_ENTRY) && defined (MODE_EXIT)
480         entry_exit_extra = 3;
481 #endif
482         bb_info[n_entities]
483           = XCNEWVEC (struct bb_info, last_basic_block + entry_exit_extra);
484         entity_map[n_entities++] = e;
485         if (num_modes[e] > max_num_modes)
486           max_num_modes = num_modes[e];
487       }
488
489   if (! n_entities)
490     return 0;
491
492 #if defined (MODE_ENTRY) && defined (MODE_EXIT)
493   /* Split the edge from the entry block, so that we can note that
494      there NORMAL_MODE is supplied.  */
495   post_entry = split_edge (single_succ_edge (ENTRY_BLOCK_PTR));
496   pre_exit = create_pre_exit (n_entities, entity_map, num_modes);
497 #endif
498
499   df_analyze ();
500
501   /* Create the bitmap vectors.  */
502
503   antic = sbitmap_vector_alloc (last_basic_block, n_entities);
504   transp = sbitmap_vector_alloc (last_basic_block, n_entities);
505   comp = sbitmap_vector_alloc (last_basic_block, n_entities);
506
507   bitmap_vector_ones (transp, last_basic_block);
508
509   for (j = n_entities - 1; j >= 0; j--)
510     {
511       int e = entity_map[j];
512       int no_mode = num_modes[e];
513       struct bb_info *info = bb_info[j];
514
515       /* Determine what the first use (if any) need for a mode of entity E is.
516          This will be the mode that is anticipatable for this block.
517          Also compute the initial transparency settings.  */
518       FOR_EACH_BB (bb)
519         {
520           struct seginfo *ptr;
521           int last_mode = no_mode;
522           bool any_set_required = false;
523           HARD_REG_SET live_now;
524
525           REG_SET_TO_HARD_REG_SET (live_now, df_get_live_in (bb));
526
527           /* Pretend the mode is clobbered across abnormal edges.  */
528           {
529             edge_iterator ei;
530             edge e;
531             FOR_EACH_EDGE (e, ei, bb->preds)
532               if (e->flags & EDGE_COMPLEX)
533                 break;
534             if (e)
535               {
536                 ptr = new_seginfo (no_mode, BB_HEAD (bb), bb->index, live_now);
537                 add_seginfo (info + bb->index, ptr);
538                 bitmap_clear_bit (transp[bb->index], j);
539               }
540           }
541
542           FOR_BB_INSNS (bb, insn)
543             {
544               if (INSN_P (insn))
545                 {
546                   int mode = MODE_NEEDED (e, insn);
547                   rtx link;
548
549                   if (mode != no_mode && mode != last_mode)
550                     {
551                       any_set_required = true;
552                       last_mode = mode;
553                       ptr = new_seginfo (mode, insn, bb->index, live_now);
554                       add_seginfo (info + bb->index, ptr);
555                       bitmap_clear_bit (transp[bb->index], j);
556                     }
557 #ifdef MODE_AFTER
558                   last_mode = MODE_AFTER (e, last_mode, insn);
559 #endif
560                   /* Update LIVE_NOW.  */
561                   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
562                     if (REG_NOTE_KIND (link) == REG_DEAD)
563                       reg_dies (XEXP (link, 0), &live_now);
564
565                   note_stores (PATTERN (insn), reg_becomes_live, &live_now);
566                   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
567                     if (REG_NOTE_KIND (link) == REG_UNUSED)
568                       reg_dies (XEXP (link, 0), &live_now);
569                 }
570             }
571
572           info[bb->index].computing = last_mode;
573           /* Check for blocks without ANY mode requirements.
574              N.B. because of MODE_AFTER, last_mode might still be different
575              from no_mode.  */
576           if (!any_set_required)
577             {
578               ptr = new_seginfo (no_mode, BB_END (bb), bb->index, live_now);
579               add_seginfo (info + bb->index, ptr);
580             }
581         }
582 #if defined (MODE_ENTRY) && defined (MODE_EXIT)
583       {
584         int mode = MODE_ENTRY (e);
585
586         if (mode != no_mode)
587           {
588             bb = post_entry;
589
590             /* By always making this nontransparent, we save
591                an extra check in make_preds_opaque.  We also
592                need this to avoid confusing pre_edge_lcm when
593                antic is cleared but transp and comp are set.  */
594             bitmap_clear_bit (transp[bb->index], j);
595
596             /* Insert a fake computing definition of MODE into entry
597                blocks which compute no mode. This represents the mode on
598                entry.  */
599             info[bb->index].computing = mode;
600
601             if (pre_exit)
602               info[pre_exit->index].seginfo->mode = MODE_EXIT (e);
603           }
604       }
605 #endif /* NORMAL_MODE */
606     }
607
608   kill = sbitmap_vector_alloc (last_basic_block, n_entities);
609   for (i = 0; i < max_num_modes; i++)
610     {
611       int current_mode[N_ENTITIES];
612       sbitmap *del;
613       sbitmap *insert;
614
615       /* Set the anticipatable and computing arrays.  */
616       bitmap_vector_clear (antic, last_basic_block);
617       bitmap_vector_clear (comp, last_basic_block);
618       for (j = n_entities - 1; j >= 0; j--)
619         {
620           int m = current_mode[j] = MODE_PRIORITY_TO_MODE (entity_map[j], i);
621           struct bb_info *info = bb_info[j];
622
623           FOR_EACH_BB (bb)
624             {
625               if (info[bb->index].seginfo->mode == m)
626                 bitmap_set_bit (antic[bb->index], j);
627
628               if (info[bb->index].computing == m)
629                 bitmap_set_bit (comp[bb->index], j);
630             }
631         }
632
633       /* Calculate the optimal locations for the
634          placement mode switches to modes with priority I.  */
635
636       FOR_EACH_BB (bb)
637         bitmap_not (kill[bb->index], transp[bb->index]);
638       edge_list = pre_edge_lcm (n_entities, transp, comp, antic,
639                                 kill, &insert, &del);
640
641       for (j = n_entities - 1; j >= 0; j--)
642         {
643           /* Insert all mode sets that have been inserted by lcm.  */
644           int no_mode = num_modes[entity_map[j]];
645
646           /* Wherever we have moved a mode setting upwards in the flow graph,
647              the blocks between the new setting site and the now redundant
648              computation ceases to be transparent for any lower-priority
649              mode of the same entity.  First set the aux field of each
650              insertion site edge non-transparent, then propagate the new
651              non-transparency from the redundant computation upwards till
652              we hit an insertion site or an already non-transparent block.  */
653           for (e = NUM_EDGES (edge_list) - 1; e >= 0; e--)
654             {
655               edge eg = INDEX_EDGE (edge_list, e);
656               int mode;
657               basic_block src_bb;
658               HARD_REG_SET live_at_edge;
659               rtx mode_set;
660
661               eg->aux = 0;
662
663               if (! bitmap_bit_p (insert[e], j))
664                 continue;
665
666               eg->aux = (void *)1;
667
668               mode = current_mode[j];
669               src_bb = eg->src;
670
671               REG_SET_TO_HARD_REG_SET (live_at_edge, df_get_live_out (src_bb));
672
673               rtl_profile_for_edge (eg);
674               start_sequence ();
675               EMIT_MODE_SET (entity_map[j], mode, live_at_edge);
676               mode_set = get_insns ();
677               end_sequence ();
678               default_rtl_profile ();
679
680               /* Do not bother to insert empty sequence.  */
681               if (mode_set == NULL_RTX)
682                 continue;
683
684               /* We should not get an abnormal edge here.  */
685               gcc_assert (! (eg->flags & EDGE_ABNORMAL));
686
687               need_commit = 1;
688               insert_insn_on_edge (mode_set, eg);
689             }
690
691           FOR_EACH_BB_REVERSE (bb)
692             if (bitmap_bit_p (del[bb->index], j))
693               {
694                 make_preds_opaque (bb, j);
695                 /* Cancel the 'deleted' mode set.  */
696                 bb_info[j][bb->index].seginfo->mode = no_mode;
697               }
698         }
699
700       sbitmap_vector_free (del);
701       sbitmap_vector_free (insert);
702       clear_aux_for_edges ();
703       free_edge_list (edge_list);
704     }
705
706   /* Now output the remaining mode sets in all the segments.  */
707   for (j = n_entities - 1; j >= 0; j--)
708     {
709       int no_mode = num_modes[entity_map[j]];
710
711       FOR_EACH_BB_REVERSE (bb)
712         {
713           struct seginfo *ptr, *next;
714           for (ptr = bb_info[j][bb->index].seginfo; ptr; ptr = next)
715             {
716               next = ptr->next;
717               if (ptr->mode != no_mode)
718                 {
719                   rtx mode_set;
720
721                   rtl_profile_for_bb (bb);
722                   start_sequence ();
723                   EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
724                   mode_set = get_insns ();
725                   end_sequence ();
726
727                   /* Insert MODE_SET only if it is nonempty.  */
728                   if (mode_set != NULL_RTX)
729                     {
730                       emitted = true;
731                       if (NOTE_INSN_BASIC_BLOCK_P (ptr->insn_ptr))
732                         emit_insn_after (mode_set, ptr->insn_ptr);
733                       else
734                         emit_insn_before (mode_set, ptr->insn_ptr);
735                     }
736
737                   default_rtl_profile ();
738                 }
739
740               free (ptr);
741             }
742         }
743
744       free (bb_info[j]);
745     }
746
747   /* Finished. Free up all the things we've allocated.  */
748   sbitmap_vector_free (kill);
749   sbitmap_vector_free (antic);
750   sbitmap_vector_free (transp);
751   sbitmap_vector_free (comp);
752
753   if (need_commit)
754     commit_edge_insertions ();
755
756 #if defined (MODE_ENTRY) && defined (MODE_EXIT)
757   cleanup_cfg (CLEANUP_NO_INSN_DEL);
758 #else
759   if (!need_commit && !emitted)
760     return 0;
761 #endif
762
763   return 1;
764 }
765
766 #endif /* OPTIMIZE_MODE_SWITCHING */
767 \f
768 static bool
769 gate_mode_switching (void)
770 {
771 #ifdef OPTIMIZE_MODE_SWITCHING
772   return true;
773 #else
774   return false;
775 #endif
776 }
777
778 static unsigned int
779 rest_of_handle_mode_switching (void)
780 {
781 #ifdef OPTIMIZE_MODE_SWITCHING
782   optimize_mode_switching ();
783 #endif /* OPTIMIZE_MODE_SWITCHING */
784   return 0;
785 }
786
787
788 struct rtl_opt_pass pass_mode_switching =
789 {
790  {
791   RTL_PASS,
792   "mode_sw",                            /* name */
793   OPTGROUP_NONE,                        /* optinfo_flags */
794   gate_mode_switching,                  /* gate */
795   rest_of_handle_mode_switching,        /* execute */
796   NULL,                                 /* sub */
797   NULL,                                 /* next */
798   0,                                    /* static_pass_number */
799   TV_MODE_SWITCH,                       /* tv_id */
800   0,                                    /* properties_required */
801   0,                                    /* properties_provided */
802   0,                                    /* properties_destroyed */
803   0,                                    /* todo_flags_start */
804   TODO_df_finish | TODO_verify_rtl_sharing |
805   0                                     /* todo_flags_finish */
806  }
807 };