This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Extend mode-switching to support toggle


Respin of a long standing forgotten patch
(http://gcc.gnu.org/ml/gcc-patches/2006-12/msg01562.html).

This patch extends the mode-switching pass to toggle on/off a control
register status bit instead of setting the value. e.g on the SH4a to
support the FPCHG instruction used to switch FPU precision mode.

The idea is to use the AVOUT/AVIN information computed by LCM for each
mode on the CFG edges. When 2 modes for a given entity conflict, a
regular mode set is emitted. Elsewhere the same mode is set is for all
outgoing/incoming edges, a toggle is possible. The only important
general change is that we have to postpone the mode toggling (or
setting) after the modes have been computed for each edges.

bootstrapped/regtested for x86_64-unknown-linux-gnu and
sh-none-elf/sh-linux with for -m4a, and -m4

Comments appreciated. If OK go for trunk/stage1 ?

many thanks,







2014-04-02  Christian Bruel  <christian.bruel@st.com>

	* basic-block.h (pre_edge_lcm_avs): Declare.
	* doc/tm.texi (EMIT_MODE_TOGGLE): Document.
	* doc/tm.texi.in (EMIT_MODE_TOGGLE): Idem.
	* config/sh/sh.h (EMIT_MODE_TOGGLE): Define.
	* config/sh/sh-protos.h	(emit_fpu_toggle): Declare
	* config/sh/sh.c (emit_fpu_toggle): New function.
	* config/sh/sh.md (toggle_pr): Defined for TARGET_SH4_300 and
	TARGET_SH4A_FP.
	(in_delay_slot): fpscr_toggle don't go in delay slot.
	* lcm.c (pre_edge_lcm_avs): Renamed from pre_edge_lcm.
	Call clear_aux_for_edges. Fix comments.
	(pre_edge_lcm): New wrapper function to call pre_edge_lcm_avs.
	(pre_edge_rev_lcm): Idem.
	* mode-switching.c (init_modes_infos): New function.
	(free_modes_infos): Idem.
	(init_modes_infos): Idem
	(add_mode_set): Idem.
	(get_mode): Idem.
	(commit_mode_sets): Idem.
	(merge_modes): Idem.
	(set_flip_status): Idem
	(test_flip_status): Idem.
	(optimize_mode_switching): Add support to toggle modes.

2014-04-02  Christian Bruel  <christian.bruel@st.com>

	* gcc.target/sh/fpchg1.c: New test.

Index: gcc/basic-block.h
===================================================================
--- gcc/basic-block.h	(revision 208956)
+++ gcc/basic-block.h	(working copy)
@@ -711,6 +711,9 @@ extern void bitmap_union_of_preds (sbitmap, sbitma
 extern struct edge_list *pre_edge_lcm (int, sbitmap *, sbitmap *,
 				       sbitmap *, sbitmap *, sbitmap **,
 				       sbitmap **);
+extern struct edge_list *pre_edge_lcm_avs (int, sbitmap *, sbitmap *,
+					   sbitmap *, sbitmap *, sbitmap *,
+					   sbitmap *, sbitmap **, sbitmap **);
 extern struct edge_list *pre_edge_rev_lcm (int, sbitmap *,
 					   sbitmap *, sbitmap *,
 					   sbitmap *, sbitmap **,
Index: gcc/config/sh/sh-protos.h
===================================================================
--- gcc/config/sh/sh-protos.h	(revision 208956)
+++ gcc/config/sh/sh-protos.h	(working copy)
@@ -210,6 +210,7 @@ extern bool check_use_sfunc_addr (rtx, rtx);
 #ifdef HARD_CONST
 extern void fpscr_set_from_mem (int, HARD_REG_SET);
 #endif
+extern bool emit_fpu_toggle (int);
 
 extern void sh_pr_interrupt (struct cpp_reader *);
 extern void sh_pr_trapa (struct cpp_reader *);
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	(revision 208956)
+++ gcc/config/sh/sh.c	(working copy)
@@ -10042,6 +10042,17 @@ get_free_reg (HARD_REG_SET regs_live)
   return gen_rtx_REG (Pmode, 7);
 }
 
+/* This function switches the fpscr.  */
+bool
+emit_fpu_toggle (int e ATTRIBUTE_UNUSED)
+{
+  emit_insn (gen_toggle_pr ());
+  if (TARGET_FMOVD)
+    emit_insn (gen_toggle_sz ());
+
+  return true;
+}
+
 /* This function will set the fpscr from memory.
    MODE is the mode we are setting it to.  */
 void
Index: gcc/config/sh/sh.h
===================================================================
--- gcc/config/sh/sh.h	(revision 208956)
+++ gcc/config/sh/sh.h	(working copy)
@@ -2259,6 +2259,9 @@ extern int current_function_interrupt;
 #define MODE_PRIORITY_TO_MODE(ENTITY, N) \
   ((TARGET_FPU_SINGLE != 0) ^ (N) ? FP_MODE_SINGLE : FP_MODE_DOUBLE)
 
+#define EMIT_MODE_TOGGLE(ENTITY, MODE) \
+  ((TARGET_SH4A_FP || TARGET_SH4_300) ? emit_fpu_toggle (ENTITY) : false)
+
 #define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
   fpscr_set_from_mem ((MODE), (HARD_REGS_LIVE))
 
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 208956)
+++ gcc/config/sh/sh.md	(working copy)
@@ -504,6 +504,7 @@
 (define_attr "in_delay_slot" "yes,no"
   (cond [(eq_attr "type" "cbranch") (const_string "no")
 	 (eq_attr "type" "pcload,pcload_si") (const_string "no")
+	 (eq_attr "type" "fpscr_toggle") (const_string "no")
 	 (eq_attr "needs_delay_slot" "yes") (const_string "no")
 	 (eq_attr "length" "2") (const_string "yes")
 	 ] (const_string "no")))
@@ -12182,15 +12183,10 @@ label:
   "fschg"
   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
 
-;; There's no way we can use it today, since optimize mode switching
-;; doesn't enable us to know from which mode we're switching to the
-;; mode it requests, to tell whether we can use a relative mode switch
-;; (like toggle_pr) or an absolute switch (like loading fpscr from
-;; memory).
 (define_insn "toggle_pr"
   [(set (reg:PSI FPSCR_REG)
 	(xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
-  "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
+   "(TARGET_SH4A_FP || TARGET_SH4_300)"
   "fpchg"
   [(set_attr "type" "fpscr_toggle")])
 
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 208956)
+++ gcc/doc/tm.texi	(working copy)
@@ -9723,6 +9723,11 @@ If you define this macro, you also have to define
 are optional.
 @end defmac
 
+@defmac EMIT_MODE_TOGGLE (@var{entity}, @var{mode})
+Generates one or more insns to toggle @var{entity}. Return true if entity supports
+toggle. EMIT_MODE_SET is used instead.
+@end defmac
+
 @defmac NUM_MODES_FOR_MODE_SWITCHING
 If you define @code{OPTIMIZE_MODE_SWITCHING}, you have to define this as
 initializer for an array of integers.  Each initializer element
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 208956)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -7392,6 +7392,11 @@ If you define this macro, you also have to define
 are optional.
 @end defmac
 
+@defmac EMIT_MODE_TOGGLE (@var{entity}, @var{mode})
+Generates one or more insns to toggle @var{entity}. Return true if entity supports
+toggle. EMIT_MODE_SET is used instead.
+@end defmac
+
 @defmac NUM_MODES_FOR_MODE_SWITCHING
 If you define @code{OPTIMIZE_MODE_SWITCHING}, you have to define this as
 initializer for an array of integers.  Each initializer element
Index: gcc/lcm.c
===================================================================
--- gcc/lcm.c	(revision 208956)
+++ gcc/lcm.c	(working copy)
@@ -377,17 +377,17 @@ compute_insert_delete (struct edge_list *edge_list
     }
 }
 
-/* Given local properties TRANSP, ANTLOC, AVOUT, KILL return the insert and
-   delete vectors for edge based LCM.  Returns an edgelist which is used to
+/* Given local properties TRANSP, ANTLOC, AVLOC, KILL return the insert and
+   delete vectors for edge based LCM  and return the AVIN, AVOUT bitmap.
    map the insert vector to what edge an expression should be inserted on.  */
 
 struct edge_list *
-pre_edge_lcm (int n_exprs, sbitmap *transp,
+pre_edge_lcm_avs (int n_exprs, sbitmap *transp,
 	      sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
+	      sbitmap *avin, sbitmap *avout,
 	      sbitmap **insert, sbitmap **del)
 {
   sbitmap *antin, *antout, *earliest;
-  sbitmap *avin, *avout;
   sbitmap *later, *laterin;
   struct edge_list *edge_list;
   int num_edges;
@@ -413,10 +413,7 @@ struct edge_list *
 #endif
 
   /* Compute global availability.  */
-  avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
-  avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
   compute_available (avloc, kill, avout, avin);
-  sbitmap_vector_free (avin);
 
   /* Compute global anticipatability.  */
   antin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
@@ -444,7 +441,6 @@ struct edge_list *
 
   sbitmap_vector_free (antout);
   sbitmap_vector_free (antin);
-  sbitmap_vector_free (avout);
 
   later = sbitmap_vector_alloc (num_edges, n_exprs);
 
@@ -485,6 +481,28 @@ struct edge_list *
   return edge_list;
 }
 
+/* Wrapper to allocate avin/avout and call pre_edge_lcm_avs.  */
+
+struct edge_list *
+pre_edge_lcm (int n_exprs, sbitmap *transp,
+	      sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
+	      sbitmap **insert, sbitmap **del)
+{
+  struct edge_list *edge_list;
+  sbitmap *avin, *avout;
+
+  avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
+  avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
+
+  edge_list = pre_edge_lcm_avs (n_exprs, transp, avloc, antloc, kill,
+				 avin, avout, insert, del);
+
+  sbitmap_vector_free (avout);
+  sbitmap_vector_free (avin);
+
+  return edge_list;
+}
+
 /* Compute the AVIN and AVOUT vectors from the AVLOC and KILL vectors.
    Return the number of passes we performed to iterate to a solution.  */
 
Index: gcc/mode-switching.c
===================================================================
--- gcc/mode-switching.c	(revision 208956)
+++ gcc/mode-switching.c	(working copy)
@@ -95,6 +95,178 @@ static void reg_becomes_live (rtx, const_rtx, void
 static void make_preds_opaque (basic_block, int);
 
 
+/* To support mode switching, the algorithm cannot set the modes after
+   the insert and delete bitmaps are computed by pre_edge_lcm, because
+   'avin' is computed iteratively for each possible modes for each entity.
+   The mode emission will be done after all mode are processed.
+   (see commit_mode_sets).  */
+
+static int **modes_needed;  /* modes needs to be inserted on this edge.  */
+
+static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
+
+#ifdef EMIT_MODE_TOGGLE
+
+/* Bitmap to compute mode flipping.  */
+
+static sbitmap *mode_in_flip;  /* flip in mode status for each basic blocks.  */
+static sbitmap *mode_out_flip; /* flip out mode status for each basic blocks.  */
+
+/* Test avin modes.
+   if 'out' is 1 we want to know if the mode out of the basic block
+   can be flipped. If 'in' is 1 we want to know if the mode entering the
+   basic block can be flipped.
+   If result is 0, we need to reset the mode.  */
+
+static bool
+test_flip_status(int entity, basic_block bb, bool out)
+{
+  if (out)
+    return bitmap_bit_p (mode_out_flip[bb->index], entity);
+  else
+    return bitmap_bit_p (mode_in_flip[bb->index], entity);
+}
+
+/* Merges the avin modes.  */
+
+static void
+set_flip_status (sbitmap *avin, sbitmap *avout)
+{
+  basic_block bb;
+
+  FOR_EACH_BB_FN (bb, cfun)
+    {
+      int i = bb->index;
+
+      /* Merge modes for each entity for each bb.
+	 If multiple avin modes are set for the same bb, they are not
+	 exclusive and a flip may not be emitted.  */
+      if (! bb_has_eh_pred (bb))
+	bitmap_xor (mode_in_flip[i], mode_in_flip[i], avin[i]);
+      bitmap_xor (mode_out_flip[i], mode_out_flip[i], avout[i]);
+    }
+}
+#endif /* EMIT_MODE_TOGGLE */
+
+/* Allocates and initializes modes_infos.  */
+
+static void
+init_modes_infos (int n_entities, int *entity_map)
+{
+  int num_edges = 0;
+  basic_block bb;
+
+  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
+		  EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
+    num_edges += EDGE_COUNT (bb->succs);
+
+  modes_needed = XNEWVEC (int *, n_entities);
+
+  for (int j = 0; j < n_entities; j++)
+    {
+      int e = entity_map[j];
+      int no_mode = num_modes[e];
+
+      modes_needed[j] = XNEWVEC (int, num_edges);
+      for (int ed = 0; ed < num_edges; ed++)
+	modes_needed[j][ed] = no_mode;
+    }
+
+  /* Allocates bitmaps for modes.  */
+#ifdef EMIT_MODE_TOGGLE
+  mode_in_flip = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
+				       n_entities);
+  mode_out_flip = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
+					n_entities);
+  bitmap_vector_clear (mode_in_flip, last_basic_block_for_fn (cfun));
+  bitmap_vector_clear (mode_out_flip, last_basic_block_for_fn (cfun));
+#endif
+}
+
+/* frees memory used to hold the modes information.  */
+
+static void
+free_modes_infos (int n_entities)
+{
+  int j;
+
+  for (j = 0; j < n_entities; j++)
+    free (modes_needed[j]);
+
+  free (modes_needed);
+#ifdef EMIT_MODE_TOGGLE
+  sbitmap_vector_free (mode_in_flip);
+  sbitmap_vector_free (mode_out_flip);
+#endif
+}
+
+/* records the mode associated with edge e for entity j.  */
+
+static void
+add_mode_set (int j, int e, int mode)
+{
+  modes_needed[j][e] = mode;
+}
+
+/* returns the mode needed on edge e for entity j. -1 if none.  */
+
+static int
+get_mode (int j, int e)
+{
+  return modes_needed[j][e];
+}
+
+/* Finally, after all the modes after been inserted after lcm, we can
+   process with the mode emission.  */
+
+static bool
+commit_mode_sets (struct edge_list *edge_list, int j, int *entity_map)
+{
+  bool need_commit = false;
+
+  for (int ed = NUM_EDGES (edge_list) - 1; ed >= 0; ed--)
+    {
+      int mode;
+      int e = entity_map[j];
+      int no_mode = num_modes[e];
+
+      if ((mode = get_mode (j, ed)) != no_mode)
+	{
+	  HARD_REG_SET live_at_edge;
+	  edge eg = INDEX_EDGE (edge_list, ed);
+	  basic_block src_bb = eg->src;
+	  rtx mode_set;
+
+	  REG_SET_TO_HARD_REG_SET (live_at_edge, df_get_live_out (src_bb));
+
+	  rtl_profile_for_edge (eg);
+	  start_sequence ();
+
+#ifdef EMIT_MODE_TOGGLE
+	  if (! test_flip_status (j, src_bb, true) ||
+	      ! EMIT_MODE_TOGGLE (entity_map[j], mode))
+#endif
+	  EMIT_MODE_SET (entity_map[j], mode, live_at_edge);
+
+	  mode_set = get_insns ();
+	  end_sequence ();
+	  default_rtl_profile ();
+
+	  /* Do not bother to insert empty sequence.  */
+	  if (mode_set == NULL_RTX)
+	    continue;
+
+	  /* We should not get an abnormal edge here.  */
+	  gcc_assert (! (eg->flags & EDGE_ABNORMAL));
+
+	  need_commit = true;
+	  insert_insn_on_edge (mode_set, eg);
+	}
+    }
+
+  return need_commit;
+}
+
 /* This function will allocate a new BBINFO structure, initialized
    with the MODE, INSN, and basic block BB parameters.  */
 
@@ -201,7 +373,7 @@ reg_becomes_live (rtx reg, const_rtx setter ATTRIB
    inserted before the exit block.  Otherwise return null.  */
 
 static basic_block
-create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
+create_pre_exit (int n_entities, int *entity_map)
 {
   edge eg;
   edge_iterator ei;
@@ -455,10 +627,8 @@ optimize_mode_switching (void)
   rtx insn;
   int e;
   basic_block bb;
-  int need_commit = 0;
+  bool need_commit = false;
   sbitmap *kill;
-  struct edge_list *edge_list;
-  static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
 #define N_ENTITIES ARRAY_SIZE (num_modes)
   int entity_map[N_ENTITIES];
   struct bb_info *bb_info[N_ENTITIES];
@@ -467,6 +637,8 @@ optimize_mode_switching (void)
   int max_num_modes = 0;
   bool emitted ATTRIBUTE_UNUSED = false;
   basic_block post_entry ATTRIBUTE_UNUSED, pre_exit ATTRIBUTE_UNUSED;
+  sbitmap *avin, *avout;
+  struct edge_list *edge_list = 0;
 
   for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--)
     if (OPTIMIZE_MODE_SWITCHING (e))
@@ -494,7 +666,7 @@ optimize_mode_switching (void)
   /* Split the edge from the entry block, so that we can note that
      there NORMAL_MODE is supplied.  */
   post_entry = split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
-  pre_exit = create_pre_exit (n_entities, entity_map, num_modes);
+  pre_exit = create_pre_exit (n_entities, entity_map);
 #endif
 
   df_analyze ();
@@ -504,6 +676,8 @@ optimize_mode_switching (void)
   antic = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_entities);
   transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_entities);
   comp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_entities);
+  avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_entities);
+  avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_entities);
 
   bitmap_vector_ones (transp, last_basic_block_for_fn (cfun));
 
@@ -610,6 +784,9 @@ optimize_mode_switching (void)
     }
 
   kill = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_entities);
+
+  init_modes_infos (n_entities, entity_map);
+
   for (i = 0; i < max_num_modes; i++)
     {
       int current_mode[N_ENTITIES];
@@ -639,9 +816,14 @@ optimize_mode_switching (void)
 
       FOR_EACH_BB_FN (bb, cfun)
 	bitmap_not (kill[bb->index], transp[bb->index]);
-      edge_list = pre_edge_lcm (n_entities, transp, comp, antic,
-				kill, &insert, &del);
+      edge_list = pre_edge_lcm_avs (n_entities, transp, comp, antic,
+				    kill, avin, avout, &insert, &del);
 
+#ifdef EMIT_MODE_TOGGLE
+      /* Merge modes for all entities.  */
+      set_flip_status (avin, avout);
+#endif
+
       for (j = n_entities - 1; j >= 0; j--)
 	{
 	  /* Insert all mode sets that have been inserted by lcm.  */
@@ -657,10 +839,6 @@ optimize_mode_switching (void)
 	  for (e = NUM_EDGES (edge_list) - 1; e >= 0; e--)
 	    {
 	      edge eg = INDEX_EDGE (edge_list, e);
-	      int mode;
-	      basic_block src_bb;
-	      HARD_REG_SET live_at_edge;
-	      rtx mode_set;
 
 	      eg->aux = 0;
 
@@ -669,27 +847,8 @@ optimize_mode_switching (void)
 
 	      eg->aux = (void *)1;
 
-	      mode = current_mode[j];
-	      src_bb = eg->src;
-
-	      REG_SET_TO_HARD_REG_SET (live_at_edge, df_get_live_out (src_bb));
-
-	      rtl_profile_for_edge (eg);
-	      start_sequence ();
-	      EMIT_MODE_SET (entity_map[j], mode, live_at_edge);
-	      mode_set = get_insns ();
-	      end_sequence ();
-	      default_rtl_profile ();
-
-	      /* Do not bother to insert empty sequence.  */
-	      if (mode_set == NULL_RTX)
-		continue;
-
-	      /* We should not get an abnormal edge here.  */
-	      gcc_assert (! (eg->flags & EDGE_ABNORMAL));
-
-	      need_commit = 1;
-	      insert_insn_on_edge (mode_set, eg);
+	      /* Remember we need to emit it.  */
+	      add_mode_set(j, e, current_mode[j]);
 	    }
 
 	  FOR_EACH_BB_REVERSE_FN (bb, cfun)
@@ -704,7 +863,10 @@ optimize_mode_switching (void)
       sbitmap_vector_free (del);
       sbitmap_vector_free (insert);
       clear_aux_for_edges ();
-      free_edge_list (edge_list);
+
+      /* Keep an edge_list for later.  */
+      if (i != max_num_modes - 1)
+	free_edge_list (edge_list);
     }
 
   /* Now output the remaining mode sets in all the segments.  */
@@ -712,9 +874,18 @@ optimize_mode_switching (void)
     {
       int no_mode = num_modes[entity_map[j]];
 
+      /* In case there was no mode inserted. the mode information on the edge
+	 might not be complete.
+	 Update mode info on edges and commit pending mode sets.  */
+      need_commit |= commit_mode_sets (edge_list, j, entity_map);
+
       FOR_EACH_BB_REVERSE_FN (bb, cfun)
 	{
 	  struct seginfo *ptr, *next;
+#ifdef EMIT_MODE_TOGGLE
+	  bool toggle_p = test_flip_status (j, bb, false);
+#endif
+
 	  for (ptr = bb_info[j][bb->index].seginfo; ptr; ptr = next)
 	    {
 	      next = ptr->next;
@@ -724,7 +895,17 @@ optimize_mode_switching (void)
 
 		  rtl_profile_for_bb (bb);
 		  start_sequence ();
+
+#ifdef EMIT_MODE_TOGGLE
+		  if (! toggle_p ||
+		      ! EMIT_MODE_TOGGLE (entity_map[j], ptr->mode))
+#endif
 		  EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
+
+#ifdef EMIT_MODE_TOGGLE
+		  toggle_p = true;
+#endif
+
 		  mode_set = get_insns ();
 		  end_sequence ();
 
@@ -748,11 +929,16 @@ optimize_mode_switching (void)
       free (bb_info[j]);
     }
 
+  free_edge_list (edge_list);
+  free_modes_infos (n_entities);
+
   /* Finished. Free up all the things we've allocated.  */
   sbitmap_vector_free (kill);
   sbitmap_vector_free (antic);
   sbitmap_vector_free (transp);
   sbitmap_vector_free (comp);
+  sbitmap_vector_free (avin);
+  sbitmap_vector_free (avout);
 
   if (need_commit)
     commit_edge_insertions ();
Index: gcc/testsuite/gcc.target/sh/fpchg1.c
===================================================================
--- gcc/testsuite/gcc.target/sh/fpchg1.c	(revision 0)
+++ gcc/testsuite/gcc.target/sh/fpchg1.c	(working copy)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "" } { "-m4a" "-m4-300" } }
+
+/* Make sure that fpchg is used.  */
+/* { dg-final { scan-assembler "fpchg" } } */
+/* { dg-final { scan-assembler-not "fpscr" } } */
+
+extern float c;
+
+void
+foo(int j)
+{
+  while (j--)
+    c++;
+
+}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]