From 742ee135dbc0a61fb3b12ef30dfeb049f809b475 Mon Sep 17 00:00:00 2001
From: amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 30 May 2002 18:58:31 +0000
Subject: 	* lcm.c (output.h): #include. 	(compute_earliest): Remove
 hack to treat renumbered EXIT_BLOCK 	as an ordinary block. 
 (optimize_mode_switching): Don't pretend that the exit block is 	an
 ordinary block, or handle sucessors of entry block specially. 	Instead, split
 edges from entry block and to exit block, and 	put a computing definition on
 the thus gained post-entry-block, 	and a need on the pre-exit-block.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54064 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog |  11 ++++
 gcc/lcm.c     | 159 +++++++++++++++++++---------------------------------------
 2 files changed, 63 insertions(+), 107 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fbbe1f21fe3..b38f8e30a6f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+Thu May 30 19:54:30 2002  J"orn Rennecke <joern.rennecke@superh.com>
+
+	* lcm.c (output.h): #include.
+	(compute_earliest): Remove hack to treat renumbered EXIT_BLOCK
+	as an ordinary block.
+	(optimize_mode_switching): Don't pretend that the exit block is
+	an ordinary block, or handle sucessors of entry block specially.
+	Instead, split edges from entry block and to exit block, and
+	put a computing definition on the thus gained post-entry-block,
+	and a need on the pre-exit-block.
+
 Thu May 30 20:28:01 CEST 2002  Jan Hubicka  <jh@suse.cz>
 
 	* gengenrtl.c (type_from_format, accessor_from_format): Support 'B'.
diff --git a/gcc/lcm.c b/gcc/lcm.c
index 2630cf317dc..783c70f7f0a 100644
--- a/gcc/lcm.c
+++ b/gcc/lcm.c
@@ -59,6 +59,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "insn-config.h"
 #include "recog.h"
 #include "basic-block.h"
+#include "output.h"
 #include "tm_p.h"
 
 /* We want target macros for the mode switching code to be able to refer
@@ -207,11 +208,7 @@ compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest)
 	sbitmap_copy (earliest[x], antin[succ->index]);
       else
         {
-	  /* We refer to the EXIT_BLOCK index, instead of testing for
-	     EXIT_BLOCK_PTR, so that EXIT_BLOCK_PTR's index can be
-	     changed so as to pretend it's a regular block, so that
-	     its antin can be taken into account.  */
-	  if (succ->index == EXIT_BLOCK)
+	  if (succ == EXIT_BLOCK_PTR)
 	    sbitmap_zero (earliest[x]);
 	  else
 	    {
@@ -1027,43 +1024,54 @@ optimize_mode_switching (file)
   int n_entities;
   int max_num_modes = 0;
   bool emited = false;
+  basic_block post_entry, pre_exit ATTRIBUTE_UNUSED;
 
   clear_bb_flags ();
-#ifdef NORMAL_MODE
-  /* Increment last_basic_block before allocating bb_info.  */
-  last_basic_block++;
-#endif
 
   for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--)
     if (OPTIMIZE_MODE_SWITCHING (e))
       {
-	/* Create the list of segments within each basic block.  */
+	int entry_exit_extra = 0;
+
+	/* Create the list of segments within each basic block.
+	   If NORMAL_MODE is defined, allow for two extra
+	   blocks split from the entry and exit block. */
+#ifdef NORMAL_MODE
+	entry_exit_extra = 2;
+#endif
 	bb_info[n_entities]
-	  = (struct bb_info *) xcalloc (last_basic_block, sizeof **bb_info);
+	  = (struct bb_info *) xcalloc (last_basic_block + entry_exit_extra,
+					sizeof **bb_info);
 	entity_map[n_entities++] = e;
 	if (num_modes[e] > max_num_modes)
 	  max_num_modes = num_modes[e];
       }
 
-#ifdef NORMAL_MODE
-  /* Decrement it back in case we return below.  */
-  last_basic_block--;
-#endif
-
   if (! n_entities)
     return 0;
 
 #ifdef NORMAL_MODE
-  /* We're going to pretend the EXIT_BLOCK is a regular basic block,
-     so that switching back to normal mode when entering the
-     EXIT_BLOCK isn't optimized away.  We do this by incrementing the
-     basic block count, growing the VARRAY of basic_block_info and
-     appending the EXIT_BLOCK_PTR to it.  */
-  last_basic_block++;
-  if (VARRAY_SIZE (basic_block_info) < last_basic_block)
-    VARRAY_GROW (basic_block_info, last_basic_block);
-  BASIC_BLOCK (last_basic_block - 1) = EXIT_BLOCK_PTR;
-  EXIT_BLOCK_PTR->index = last_basic_block - 1;
+  {
+    /* Split the edge from the entry block and the fallthrough edge to the
+       exit block, so that we can note that there NORMAL_MODE is supplied /
+       required.  */
+    edge eg;
+    post_entry = split_edge (ENTRY_BLOCK_PTR->succ);
+    /* The only non-call predecessor at this stage is a block with a
+       fallthrough edge; there can be at most one, but there could be
+       none at all, e.g. when exit is called.  */
+    for (pre_exit = 0, eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next)
+      if (eg->flags & EDGE_FALLTHRU)
+	{
+	  regset live_at_end = eg->src->global_live_at_end;
+
+	  if (pre_exit)
+	    abort ();
+	  pre_exit = split_edge (eg);
+	  COPY_REG_SET (pre_exit->global_live_at_start, live_at_end);
+	  COPY_REG_SET (pre_exit->global_live_at_end, live_at_end);
+	}
+  }
 #endif
 
   /* Create the bitmap vectors.  */
@@ -1124,7 +1132,7 @@ optimize_mode_switching (file)
 	  /* Check for blocks without ANY mode requirements.  */
 	  if (last_mode == no_mode)
 	    {
-	      ptr = new_seginfo (no_mode, insn, bb->index, live_now);
+	      ptr = new_seginfo (no_mode, bb->end, bb->index, live_now);
 	      add_seginfo (info + bb->index, ptr);
 	    }
 	}
@@ -1134,36 +1142,21 @@ optimize_mode_switching (file)
 
 	if (mode != no_mode)
 	  {
-	    edge eg;
+	    bb = post_entry;
 
-	    for (eg = ENTRY_BLOCK_PTR->succ; eg; eg = eg->succ_next)
-	      {
-		bb = eg->dest;
-
-	        /* By always making this nontransparent, we save
-		   an extra check in make_preds_opaque.  We also
-		   need this to avoid confusing pre_edge_lcm when
-		   antic is cleared but transp and comp are set.  */
-		RESET_BIT (transp[bb->index], j);
-
-		/* If the block already has MODE, pretend it
-		   has none (because we don't need to set it),
-		   but retain whatever mode it computes.  */
-		if (info[bb->index].seginfo->mode == mode)
-		  info[bb->index].seginfo->mode = no_mode;
-
-		/* Insert a fake computing definition of MODE into entry
-		   blocks which compute no mode. This represents the mode on
-		   entry.  */
-		else if (info[bb->index].computing == no_mode)
-		  {
-		    info[bb->index].computing = mode;
-		    info[bb->index].seginfo->mode = no_mode;
-		  }
-	      }
+	    /* By always making this nontransparent, we save
+	       an extra check in make_preds_opaque.  We also
+	       need this to avoid confusing pre_edge_lcm when
+	       antic is cleared but transp and comp are set.  */
+	    RESET_BIT (transp[bb->index], j);
 
-	    bb = EXIT_BLOCK_PTR;
-	    info[bb->index].seginfo->mode = mode;
+	    /* Insert a fake computing definition of MODE into entry
+	       blocks which compute no mode. This represents the mode on
+	       entry.  */
+	    info[bb->index].computing = mode;
+
+	    if (pre_exit)
+	      info[pre_exit->index].seginfo->mode = mode;
 	  }
       }
 #endif /* NORMAL_MODE */
@@ -1288,63 +1281,11 @@ optimize_mode_switching (file)
       free_edge_list (edge_list);
     }
 
-#ifdef NORMAL_MODE
-  /* Restore the special status of EXIT_BLOCK.  */
-  last_basic_block--;
-  VARRAY_POP (basic_block_info);
-  EXIT_BLOCK_PTR->index = EXIT_BLOCK;
-#endif
-
   /* Now output the remaining mode sets in all the segments.  */
   for (j = n_entities - 1; j >= 0; j--)
     {
       int no_mode = num_modes[entity_map[j]];
 
-#ifdef NORMAL_MODE
-      if (bb_info[j][last_basic_block].seginfo->mode != no_mode)
-	{
-	  edge eg;
-	  struct seginfo *ptr = bb_info[j][last_basic_block].seginfo;
-
-	  for (eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next)
-	    {
-	      rtx mode_set;
-
-	      if (bb_info[j][eg->src->index].computing == ptr->mode)
-		continue;
-
-	      start_sequence ();
-	      EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
-	      mode_set = gen_sequence ();
-	      end_sequence ();
-
-	      /* Do not bother to insert empty sequence.  */
-	      if (GET_CODE (mode_set) == SEQUENCE
-		  && !XVECLEN (mode_set, 0))
-		continue;
-
-	      /* If this is an abnormal edge, we'll insert at the end of the
-		 previous block.  */
-	      if (eg->flags & EDGE_ABNORMAL)
-		{
-		  emited = true;
-		  if (GET_CODE (eg->src->end) == JUMP_INSN)
-		    emit_insn_before (mode_set, eg->src->end);
-		  else if (GET_CODE (eg->src->end) == INSN)
-		    emit_insn_after (mode_set, eg->src->end);
-		  else
-		    abort ();
-		}
-	      else
-		{
-		  need_commit = 1;
-		  insert_insn_on_edge (mode_set, eg);
-		}
-	    }
-
-	}
-#endif
-
       FOR_EACH_BB_REVERSE (bb)
 	{
 	  struct seginfo *ptr, *next;
@@ -1393,8 +1334,12 @@ optimize_mode_switching (file)
   if (need_commit)
     commit_edge_insertions ();
 
+#ifdef NORMAL_MODE
+  cleanup_cfg (CLEANUP_NO_INSN_DEL);
+#else
   if (!need_commit && !emited)
     return 0;
+#endif
 
   max_regno = max_reg_num ();
   allocate_reg_info (max_regno, FALSE, FALSE);
-- 
cgit v1.2.1