diff gcc/sel-sched-ir.h @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
line wrap: on
line diff
--- a/gcc/sel-sched-ir.h	Sun Feb 07 18:28:00 2010 +0900
+++ b/gcc/sel-sched-ir.h	Fri Feb 12 23:39:51 2010 +0900
@@ -1,6 +1,6 @@
 /* Instruction scheduling pass.  This file contains definitions used
    internally in the scheduler.
-   Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -68,7 +68,7 @@
 #define ILIST_INSN(L) (_XLIST_X (L))
 #define ILIST_NEXT(L) (_XLIST_NEXT (L))
 
-/* This lists possible transformations that done locally, i.e. in 
+/* This lists possible transformations that done locally, i.e. in
    moveup_expr.  */
 enum local_trans_type
   {
@@ -76,7 +76,7 @@
     TRANS_SPECULATION
   };
 
-/* This struct is used to record the history of expression's 
+/* This struct is used to record the history of expression's
    transformations.  */
 struct expr_history_def_1
 {
@@ -114,8 +114,8 @@
      control on scheduling.  */
   int spec;
 
-  /* Degree of speculativeness measured as probability of executing 
-     instruction's original basic block given relative to 
+  /* Degree of speculativeness measured as probability of executing
+     instruction's original basic block given relative to
      the current scheduling point.  */
   int usefulness;
 
@@ -128,7 +128,7 @@
   /* Number of times the insn was scheduled.  */
   int sched_times;
 
-  /* A basic block index this was originated from.  Zero when there is 
+  /* A basic block index this was originated from.  Zero when there is
      more than one originator.  */
   int orig_bb_index;
 
@@ -140,23 +140,23 @@
      (used only during move_op ()).  */
   ds_t spec_to_check_ds;
 
-  /* Cycle on which original insn was scheduled.  Zero when it has not yet 
+  /* Cycle on which original insn was scheduled.  Zero when it has not yet
      been scheduled or more than one originator.  */
   int orig_sched_cycle;
 
   /* This vector contains the history of insn's transformations.  */
   VEC(expr_history_def, heap) *history_of_changes;
 
-  /* True (1) when original target (register or memory) of this instruction 
+  /* True (1) when original target (register or memory) of this instruction
      is available for scheduling, false otherwise.  -1 means we're not sure;
      please run find_used_regs to clarify.  */
   signed char target_available;
 
-  /* True when this expression needs a speculation check to be scheduled.  
+  /* True when this expression needs a speculation check to be scheduled.
      This is used during find_used_regs.  */
   BOOL_BITFIELD needs_spec_check_p : 1;
 
-  /* True when the expression was substituted.  Used for statistical 
+  /* True when the expression was substituted.  Used for statistical
      purposes.  */
   BOOL_BITFIELD was_substituted : 1;
 
@@ -195,7 +195,7 @@
 #define EXPR_CANT_MOVE(EXPR) ((EXPR)->cant_move)
 
 #define EXPR_WAS_CHANGED(EXPR) (VEC_length (expr_history_def, \
-                                            EXPR_HISTORY_OF_CHANGES (EXPR)) > 0) 
+                                            EXPR_HISTORY_OF_CHANGES (EXPR)) > 0)
 
 /* Insn definition for list of original insns in find_used_regs.  */
 struct _def
@@ -204,7 +204,7 @@
 
   /* FIXME: Get rid of CROSSES_CALL in each def, since if we're moving up
      rhs from two different places, but only one of the code motion paths
-     crosses a call, we can't use any of the call_used_regs, no matter which 
+     crosses a call, we can't use any of the call_used_regs, no matter which
      path or whether all paths crosses a call.  Thus we should move CROSSES_CALL
      to static params.  */
   bool crosses_call;
@@ -232,7 +232,7 @@
 
   /* This set moved to the fence.  */
   av_set_t av1;
-  
+
   /* Deps context at this boundary.  As long as we have one boundary per fence,
      this is just a pointer to the same deps context as in the corresponding
      fence.  */
@@ -286,7 +286,7 @@
   /* A vector of insns that are scheduled but not yet completed.  */
   VEC (rtx,gc) *executing_insns;
 
-  /* A vector indexed by UIDs that caches the earliest cycle on which 
+  /* A vector indexed by UIDs that caches the earliest cycle on which
      an insn can be scheduled on this fence.  */
   int *ready_ticks;
 
@@ -464,7 +464,7 @@
 #define _FOR_EACH_1(TYPE, ELEM, I, LP)                              \
   for (_list_iter_start (&(I), (LP), true);                         \
        _list_iter_cond_##TYPE (*(I).lp, &(ELEM));                   \
-       _list_iter_next (&(I))) 
+       _list_iter_next (&(I)))
 
 
 /* _xlist_t functions.  */
@@ -666,7 +666,7 @@
 #define VINSN_MAY_TRAP_P(VI) ((VI)->may_trap_p)
 
 
-/* An entry of the hashtable describing transformations happened when 
+/* An entry of the hashtable describing transformations happened when
    moving up through an insn.  */
 struct transformed_insns
 {
@@ -709,18 +709,18 @@
   /* An INSN_UID bit is set when deps analysis result is already known.  */
   bitmap analyzed_deps;
 
-  /* An INSN_UID bit is set when a hard dep was found, not set when 
+  /* An INSN_UID bit is set when a hard dep was found, not set when
      no dependence is found.  This is meaningful only when the analyzed_deps
      bitmap has its bit set.  */
   bitmap found_deps;
 
-  /* An INSN_UID bit is set when this is a bookkeeping insn generated from 
+  /* An INSN_UID bit is set when this is a bookkeeping insn generated from
      a parent with this uid.  */
   bitmap originators;
 
   /* A hashtable caching the result of insn transformations through this one.  */
   htab_t transformed_insns;
-  
+
   /* A context incapsulating this insn.  */
   struct deps deps_context;
 
@@ -767,8 +767,8 @@
 #define INSN_ASM_P(INSN) (SID (INSN)->asm_p)
 #define INSN_SCHED_NEXT(INSN) (SID (INSN)->sched_next)
 #define INSN_ANALYZED_DEPS(INSN) (SID (INSN)->analyzed_deps)
-#define INSN_FOUND_DEPS(INSN) (SID (INSN)->found_deps) 
-#define INSN_DEPS_CONTEXT(INSN) (SID (INSN)->deps_context) 
+#define INSN_FOUND_DEPS(INSN) (SID (INSN)->found_deps)
+#define INSN_DEPS_CONTEXT(INSN) (SID (INSN)->deps_context)
 #define INSN_ORIGINATORS(INSN) (SID (INSN)->originators)
 #define INSN_ORIGINATORS_BY_UID(UID) (SID_BY_UID (UID)->originators)
 #define INSN_TRANSFORMED_INSNS(INSN) (SID (INSN)->transformed_insns)
@@ -898,7 +898,7 @@
 #define BB_LV_SET_VALID_P(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set_valid_p)
 
 /* Per basic block data for the region.  */
-typedef struct 
+typedef struct
 {
   /* This insn stream is constructed in such a way that it should be
      traversed by PREV_INSN field - (*not* NEXT_INSN).  */
@@ -947,11 +947,11 @@
 extern bool enable_moveup_set_path_p;
 extern bool pipelining_p;
 extern bool bookkeeping_p;
-extern int max_insns_to_rename;  
+extern int max_insns_to_rename;
 extern bool preheader_removed;
 
 /* Software lookahead window size.
-   According to the results in Nakatani and Ebcioglu [1993], window size of 16 
+   According to the results in Nakatani and Ebcioglu [1993], window size of 16
    is enough to extract most ILP in integer code.  */
 #define MAX_WS (PARAM_VALUE (PARAM_SELSCHED_MAX_LOOKAHEAD))
 
@@ -969,7 +969,7 @@
 
   /* The previous edge saved after skipping empty blocks.  */
   edge e2;
-  
+
   /* Edge iterator used when there are successors in other basic blocks.  */
   edge_iterator ei;
 
@@ -979,8 +979,8 @@
   /* Flags that are passed to the iterator.  We return only successors
      that comply to these flags.  */
   short flags;
-  
-  /* When flags include SUCCS_ALL, this will be set to the exact type 
+
+  /* When flags include SUCCS_ALL, this will be set to the exact type
      of the sucessor we're traversing now.  */
   short current_flags;
 
@@ -998,7 +998,7 @@
   /* Successors that correspond to the flags.  */
   insn_vec_t succs_ok;
 
-  /* Their probabilities.  As of now, we don't need this for other 
+  /* Their probabilities.  As of now, we don't need this for other
      successors.  */
   VEC(int,heap) *probs_ok;
 
@@ -1019,6 +1019,7 @@
 extern basic_block after_recovery;
 
 extern insn_t sel_bb_head (basic_block);
+extern insn_t sel_bb_end (basic_block);
 extern bool sel_bb_empty_p (basic_block);
 extern bool in_current_region_p (basic_block);
 
@@ -1026,7 +1027,7 @@
 static inline bool
 inner_loop_header_p (basic_block bb)
 {
-  struct loop *inner_loop; 
+  struct loop *inner_loop;
 
   if (!current_loop_nest)
     return false;
@@ -1047,7 +1048,7 @@
       return true;
     }
 
-  return false;  
+  return false;
 }
 
 /* Return exit edges of LOOP, filtering out edges with the same dest bb.  */
@@ -1065,7 +1066,7 @@
       int i;
       edge e;
       bool was_dest = false;
-      
+
       for (i = 0; VEC_iterate (edge, edges, i, e); i++)
         if (e->dest == exit->e->dest)
           {
@@ -1079,10 +1080,31 @@
   return edges;
 }
 
-/* Collect all loop exits recursively, skipping empty BBs between them.  
+static bool
+sel_bb_empty_or_nop_p (basic_block bb)
+{
+  insn_t first = sel_bb_head (bb), last;
+
+  if (first == NULL_RTX)
+    return true;
+
+  if (!INSN_NOP_P (first))
+    return false;
+
+  if (bb == EXIT_BLOCK_PTR)
+    return false;
+
+  last = sel_bb_end (bb);
+  if (first != last)
+    return false;
+
+  return true;
+}
+
+/* Collect all loop exits recursively, skipping empty BBs between them.
    E.g. if BB is a loop header which has several loop exits,
    traverse all of them and if any of them turns out to be another loop header
-   (after skipping empty BBs), add its loop exits to the resulting vector 
+   (after skipping empty BBs), add its loop exits to the resulting vector
    as well.  */
 static inline VEC(edge, heap) *
 get_all_loop_exits (basic_block bb)
@@ -1091,7 +1113,7 @@
 
   /* If bb is empty, and we're skipping to loop exits, then
      consider bb as a possible gate to the inner loop now.  */
-  while (sel_bb_empty_p (bb) 
+  while (sel_bb_empty_or_nop_p (bb)
 	 && in_current_region_p (bb))
     {
       bb = single_succ (bb);
@@ -1107,12 +1129,12 @@
       struct loop *pred_loop = NULL;
       int i;
       edge e;
-      
+
       for (this_loop = bb->loop_father;
            this_loop && this_loop != current_loop_nest;
            this_loop = loop_outer (this_loop))
         pred_loop = this_loop;
-      
+
       this_loop = pred_loop;
       gcc_assert (this_loop != NULL);
 
@@ -1123,17 +1145,17 @@
 	if (in_current_region_p (e->dest))
 	  {
 	    VEC(edge, heap) *next_exits = get_all_loop_exits (e->dest);
-  
+
 	    if (next_exits)
 	      {
 		int j;
 		edge ne;
-  
+
 		/* Add all loop exits for the current edge into the
 		   resulting vector.  */
 		for (j = 0; VEC_iterate (edge, next_exits, j, ne); j++)
 		  VEC_safe_push (edge, heap, exits, ne);
-  
+
 		/* Remove the original edge.  */
 		VEC_ordered_remove (edge, exits, i);
 
@@ -1159,7 +1181,7 @@
 /* Include successors that are outside of the current region.  */
 #define SUCCS_OUT (4)
 
-/* When pipelining of the outer loops is enabled, skip innermost loops 
+/* When pipelining of the outer loops is enabled, skip innermost loops
    to their exits.  */
 #define SUCCS_SKIP_TO_LOOP_EXITS (8)
 
@@ -1222,7 +1244,7 @@
     }
   else
     {
-      while (1) 
+      while (1)
         {
           edge e_tmp = NULL;
 
@@ -1231,12 +1253,12 @@
             {
               do
                 {
-                  VEC_iterate (edge, ip->loop_exits, 
+                  VEC_iterate (edge, ip->loop_exits,
                                ip->current_exit, e_tmp);
                   ip->current_exit++;
                 }
 	      while (e_tmp && !check (e_tmp, ip));
-              
+
               if (!e_tmp)
                 VEC_free (edge, heap, ip->loop_exits);
             }
@@ -1256,8 +1278,8 @@
               /* Consider bb as a possible loop header.  */
               if ((ip->flags & SUCCS_SKIP_TO_LOOP_EXITS)
                   && flag_sel_sched_pipelining_outer_loops
-		  && (!in_current_region_p (bb) 
-		      || BLOCK_TO_BB (ip->bb->index) 
+		  && (!in_current_region_p (bb)
+		      || BLOCK_TO_BB (ip->bb->index)
 			 < BLOCK_TO_BB (bb->index)))
                 {
 		  /* Get all loop exits recursively.  */
@@ -1266,7 +1288,7 @@
 		  if (ip->loop_exits)
 		    {
   		      ip->current_exit = 0;
-		      /* Move the iterator now, because we won't do 
+		      /* Move the iterator now, because we won't do
 			 succ_iter_next until loop exits will end.  */
 		      ei_next (&(ip->ei));
 		      break;
@@ -1350,35 +1372,51 @@
   while (1)
     {
       if (!sel_bb_empty_p (bb))
-        break;
-        
-      if (!in_current_region_p (bb) 
+	{
+	  edge ne;
+	  basic_block nbb;
+
+	  if (!sel_bb_empty_or_nop_p (bb))
+	    break;
+
+	  ne = EDGE_SUCC (bb, 0);
+	  nbb = ne->dest;
+
+	  if (!in_current_region_p (nbb)
+	      && !(flags & SUCCS_OUT))
+	    break;
+
+	  e2 = ne;
+	  bb = nbb;
+	  continue;
+	}
+
+      if (!in_current_region_p (bb)
           && !(flags & SUCCS_OUT))
         return false;
 
+      if (EDGE_COUNT (bb->succs) == 0)
+	return false;
+
       e2 = EDGE_SUCC (bb, 0);
       bb = e2->dest;
-      
-      /* This couldn't happen inside a region.  */
-      gcc_assert (! in_current_region_p (bb)
-                  || (flags & SUCCS_OUT));
     }
-  
+
   /* Save the second edge for later checks.  */
   ip->e2 = e2;
 
   if (in_current_region_p (bb))
     {
-      /* BLOCK_TO_BB sets topological order of the region here.  
-         It is important to use real predecessor here, which is ip->bb, 
-         as we may well have e1->src outside current region, 
+      /* BLOCK_TO_BB sets topological order of the region here.
+         It is important to use real predecessor here, which is ip->bb,
+         as we may well have e1->src outside current region,
          when skipping to loop exits.  */
       bool succeeds_in_top_order = (BLOCK_TO_BB (ip->bb->index)
 				    < BLOCK_TO_BB (bb->index));
 
       /* This is true for the all cases except the last one.  */
       ip->current_flags = SUCCS_NORMAL;
-      
+
       /* We are advancing forward in the region, as usual.  */
       if (succeeds_in_top_order)
         {
@@ -1388,9 +1426,9 @@
           return !!(flags & SUCCS_NORMAL);
         }
 
-      /* This is a back edge.  During pipelining we ignore back edges, 
+      /* This is a back edge.  During pipelining we ignore back edges,
          but only when it leads to the same loop.  It can lead to the header
-         of the outer loop, which will also be the preheader of 
+         of the outer loop, which will also be the preheader of
          the current loop.  */
       if (pipelining_p
            && e1->src->loop_father == bb->loop_father)
@@ -1425,12 +1463,12 @@
     case 0:
       return bb->next_bb;
 
-    case 1: 
+    case 1:
       return single_succ (bb);
 
     case 2:
       return FALLTHRU_EDGE (bb)->dest;
-      
+
     default:
       return bb->next_bb;
     }
@@ -1474,7 +1512,7 @@
 extern void free_regset_pool (void);
 
 extern insn_t get_nop_from_pool (insn_t);
-extern void return_nop_to_pool (insn_t);
+extern void return_nop_to_pool (insn_t, bool);
 extern void free_nop_pool (void);
 
 /* Vinsns functions.  */
@@ -1498,11 +1536,11 @@
 extern void merge_expr (expr_t, expr_t, insn_t);
 extern void clear_expr (expr_t);
 extern unsigned expr_dest_regno (expr_t);
-extern rtx expr_dest_reg (expr_t); 
-extern int find_in_history_vect (VEC(expr_history_def, heap) *, 
+extern rtx expr_dest_reg (expr_t);
+extern int find_in_history_vect (VEC(expr_history_def, heap) *,
                                  rtx, vinsn_t, bool);
-extern void insert_in_history_vect (VEC(expr_history_def, heap) **, 
-                                    unsigned, enum local_trans_type, 
+extern void insert_in_history_vect (VEC(expr_history_def, heap) **,
+                                    unsigned, enum local_trans_type,
                                     vinsn_t, vinsn_t, ds_t);
 extern void mark_unavailable_targets (av_set_t, av_set_t, regset);
 extern int speculate_expr (expr_t, ds_t);
@@ -1584,7 +1622,6 @@
 extern void sel_init_pipelining (void);
 extern void sel_finish_pipelining (void);
 extern void sel_sched_region (int);
-extern void sel_find_rgns (void);
 extern loop_p get_loop_nest_for_rgn (unsigned int);
 extern bool considered_for_pipelining_p (struct loop *);
 extern void make_region_from_loop_preheader (VEC(basic_block, heap) **);
@@ -1609,6 +1646,7 @@
 extern void free_lv_sets (void);
 extern void setup_nop_and_exit_insns (void);
 extern void free_nop_and_exit_insns (void);
+extern void free_data_for_scheduled_insn (insn_t);
 extern void setup_nop_vinsn (void);
 extern void free_nop_vinsn (void);
 extern void sel_set_sched_flags (void);