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