OSDN Git Service

Fix a bug in tilegx_fixup_pcrel_references, to properly match and
[pf3gnuchains/gcc-fork.git] / gcc / cfgloop.h
index 4c33c9c..510bc10 100644 (file)
@@ -1,12 +1,12 @@
 /* Natural loop functions
-   Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #ifndef GCC_CFGLOOP_H
 #define GCC_CFGLOOP_H
@@ -28,6 +27,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "vecprim.h"
 #include "double-int.h"
 
+#include "bitmap.h"
+#include "sbitmap.h"
+
 /* Structure to hold decision about unrolling/peeling.  */
 enum lpt_dec
 {
@@ -39,18 +41,16 @@ enum lpt_dec
   LPT_UNROLL_STUPID
 };
 
-struct lpt_decision
-{
+struct GTY (()) lpt_decision {
   enum lpt_dec decision;
   unsigned times;
 };
 
 /* The structure describing a bound on number of iterations of a loop.  */
 
-struct nb_iter_bound
-{
+struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
   /* The statement STMT is executed at most ...  */
-  tree stmt;
+  gimple stmt;
 
   /* ... BOUND + 1 times (BOUND must be an unsigned constant).
      The + 1 is added for the following reasons:
@@ -61,7 +61,7 @@ struct nb_iter_bound
      b) it is consistent with the result of number_of_iterations_exit.  */
   double_int bound;
 
-  /* True if the statement will cause the loop to be leaved the (at most) 
+  /* True if the statement will cause the loop to be leaved the (at most)
      BOUND + 1-st time it is executed, that is, all the statements after it
      are executed at most BOUND times.  */
   bool is_exit;
@@ -72,10 +72,9 @@ struct nb_iter_bound
 
 /* Description of the loop exit.  */
 
-struct loop_exit
-{
+struct GTY (()) loop_exit {
   /* The exit edge.  */
-  edge e;
+  struct edge_def *e;
 
   /* Previous and next exit in the list of the exits of the loop.  */
   struct loop_exit *prev;
@@ -88,25 +87,35 @@ struct loop_exit
 typedef struct loop *loop_p;
 DEF_VEC_P (loop_p);
 DEF_VEC_ALLOC_P (loop_p, heap);
+DEF_VEC_ALLOC_P (loop_p, gc);
 
-/* Structure to hold information for each natural loop.  */
-struct loop
+/* An integer estimation of the number of iterations.  Estimate_state
+   describes what is the state of the estimation.  */
+enum loop_estimation
 {
+  /* Estimate was not computed yet.  */
+  EST_NOT_COMPUTED,
+  /* Estimate is ready.  */
+  EST_AVAILABLE
+};
+
+/* Structure to hold information for each natural loop.  */
+struct GTY ((chain_next ("%h.next"))) loop {
   /* Index into loops array.  */
   int num;
 
+  /* Number of loop insns.  */
+  unsigned ninsns;
+
   /* Basic block of loop header.  */
-  basic_block header;
+  struct basic_block_def *header;
 
   /* Basic block of loop latch.  */
-  basic_block latch;
+  struct basic_block_def *latch;
 
   /* For loop unrolling/peeling decision.  */
   struct lpt_decision lpt_decision;
 
-  /* Number of loop insns.  */
-  unsigned ninsns;
-
   /* Average number of executed insns per iteration.  */
   unsigned av_ninsns;
 
@@ -114,7 +123,7 @@ struct loop
   unsigned num_nodes;
 
   /* Superloops of the loop, starting with the outermost loop.  */
-  VEC (loop_p, heap) *superloops;
+  VEC (loop_p, gc) *superloops;
 
   /* The first inner (child) loop or NULL if innermost loop.  */
   struct loop *inner;
@@ -122,43 +131,42 @@ struct loop
   /* Link to the next (sibling) loop.  */
   struct loop *next;
 
-  /* Loop that is copy of this loop.  */
-  struct loop *copy;
-
   /* Auxiliary info specific to a pass.  */
-  void *aux;
+  PTR GTY ((skip (""))) aux;
+
+  /* The number of times the latch of the loop is executed.  This can be an
+     INTEGER_CST, or a symbolic expression representing the number of
+     iterations like "N - 1", or a COND_EXPR containing the runtime
+     conditions under which the number of iterations is non zero.
 
-  /* The number of times the latch of the loop is executed.
-     This is an INTEGER_CST or an expression containing symbolic
-     names.  Don't access this field directly:
-     number_of_latch_executions computes and caches the computed
-     information in this field.  */
+     Don't access this field directly: number_of_latch_executions
+     computes and caches the computed information in this field.  */
   tree nb_iterations;
 
-  /* An integer estimation of the number of iterations.  Estimate_state
-     describes what is the state of the estimation.  */
-  enum
-    {
-      /* Estimate was not computed yet.  */
-      EST_NOT_COMPUTED,
-      /* Estimate is ready.  */
-      EST_AVAILABLE
-    } estimate_state;
-
-  /* An integer guaranteed to bound the number of iterations of the loop
-     from above.  */
-  bool any_upper_bound;
+  /* An integer guaranteed to be greater or equal to nb_iterations.  Only
+     valid if any_upper_bound is true.  */
   double_int nb_iterations_upper_bound;
 
-  /* An integer giving the expected number of iterations of the loop.  */
-  bool any_estimate;
+  /* An integer giving an estimate on nb_iterations.  Unlike
+     nb_iterations_upper_bound, there is no guarantee that it is at least
+     nb_iterations.  */
   double_int nb_iterations_estimate;
 
+  bool any_upper_bound;
+  bool any_estimate;
+
+  /* True if the loop can be parallel.  */
+  bool can_be_parallel;
+
+  /* An integer estimation of the number of iterations.  Estimate_state
+     describes what is the state of the estimation.  */
+  enum loop_estimation estimate_state;
+
   /* Upper bound on number of iterations of a loop.  */
   struct nb_iter_bound *bounds;
 
   /* Head of the cyclic list of the exits of the loop.  */
-  struct loop_exit exits;
+  struct loop_exit *exits;
 };
 
 /* Flags for state of loop structure.  */
@@ -169,7 +177,9 @@ enum
   LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4,
   LOOPS_HAVE_RECORDED_EXITS = 8,
   LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16,
-  LOOP_CLOSED_SSA = 32
+  LOOP_CLOSED_SSA = 32,
+  LOOPS_NEED_FIXUP = 64,
+  LOOPS_HAVE_FALLTHRU_PREHEADERS = 128
 };
 
 #define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
@@ -177,18 +187,17 @@ enum
 #define AVOID_CFG_MODIFICATIONS (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
 
 /* Structure to hold CFG information about natural loops within a function.  */
-struct loops
-{
+struct GTY (()) loops {
   /* State of loops.  */
   int state;
 
   /* Array of the loops.  */
-  VEC (loop_p, heap) *larray;
+  VEC (loop_p, gc) *larray;
 
   /* Maps edges to the list of their descriptions as loop exits.  Edges
      whose sources or destinations have loop_father == NULL (which may
      happen during the cfg manipulations) should not appear in EXITS.  */
-  htab_t exits;
+  htab_t GTY((param_is (struct loop_exit))) exits;
 
   /* Pointer to root of loop hierarchy tree.  */
   struct loop *tree_root;
@@ -206,7 +215,7 @@ struct loop *alloc_loop (void);
 extern void flow_loop_free (struct loop *);
 int flow_loop_nodes_find (basic_block, struct loop *);
 void fix_loop_structure (bitmap changed_bbs);
-void mark_irreducible_loops (void);
+bool mark_irreducible_loops (void);
 void release_recorded_exits (void);
 void record_loop_exits (void);
 void rescan_loop_exit (edge, bool, bool);
@@ -216,15 +225,17 @@ extern void flow_loop_tree_node_add (struct loop *, struct loop *);
 extern void flow_loop_tree_node_remove (struct loop *);
 extern void add_loop (struct loop *, struct loop *);
 extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
-extern bool flow_bb_inside_loop_p (const struct loop *, const basic_block);
+extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block);
 extern struct loop * find_common_loop (struct loop *, struct loop *);
 struct loop *superloop_at_depth (struct loop *, unsigned);
 struct eni_weights_d;
 extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights_d *);
-extern int num_loop_insns (struct loop *);
-extern int average_num_loop_insns (struct loop *);
+extern int num_loop_insns (const struct loop *);
+extern int average_num_loop_insns (const struct loop *);
 extern unsigned get_loop_level (const struct loop *);
-extern bool loop_exit_edge_p (const struct loop *, edge);
+extern bool loop_exit_edge_p (const struct loop *, const_edge);
+extern bool loop_exits_to_bb_p (struct loop *, basic_block);
+extern bool loop_exits_from_bb_p (struct loop *, basic_block);
 extern void mark_loop_exit_edges (void);
 
 /* Loops & cfg manipulation.  */
@@ -233,6 +244,9 @@ extern unsigned get_loop_body_with_size (const struct loop *, basic_block *,
                                         unsigned);
 extern basic_block *get_loop_body_in_dom_order (const struct loop *);
 extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
+extern basic_block *get_loop_body_in_custom_order (const struct loop *,
+                              int (*) (const void *, const void *));
+
 extern VEC (edge, heap) *get_loop_exit_edges (const struct loop *);
 edge single_exit (const struct loop *);
 extern unsigned num_loop_branches (const struct loop *);
@@ -248,26 +262,30 @@ extern void delete_loop (struct loop *);
 
 enum
 {
-  CP_SIMPLE_PREHEADERS = 1
+  CP_SIMPLE_PREHEADERS = 1,
+  CP_FALLTHRU_PREHEADERS = 2
 };
 
+basic_block create_preheader (struct loop *, int);
 extern void create_preheaders (int);
 extern void force_single_succ_latches (void);
 
 extern void verify_loop_structure (void);
 
 /* Loop analysis.  */
-extern bool just_once_each_iteration_p (const struct loop *, basic_block);
+extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
 gcov_type expected_loop_iterations_unbounded (const struct loop *);
 extern unsigned expected_loop_iterations (const struct loop *);
 extern rtx doloop_condition_get (rtx);
 
-void estimate_numbers_of_iterations_loop (struct loop *);
+void estimate_numbers_of_iterations_loop (struct loop *, bool);
 HOST_WIDE_INT estimated_loop_iterations_int (struct loop *, bool);
+HOST_WIDE_INT max_stmt_executions_int (struct loop *, bool);
 bool estimated_loop_iterations (struct loop *, bool, double_int *);
+bool max_stmt_executions (struct loop *, bool, double_int *);
 
 /* Loop manipulation.  */
-extern bool can_duplicate_loop_p (struct loop *loop);
+extern bool can_duplicate_loop_p (const struct loop *loop);
 
 #define DLTHE_FLAG_UPDATE_FREQ 1       /* Update frequencies in
                                           duplicate_loop_to_header_edge.  */
@@ -276,8 +294,12 @@ extern bool can_duplicate_loop_p (struct loop *loop);
 #define DLTHE_FLAG_COMPLETTE_PEEL 4    /* Update frequencies expecting
                                           a complete peeling.  */
 
+extern edge create_empty_if_region_on_edge (edge, tree);
+extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
+                                              tree *, tree *, struct loop *);
 extern struct loop * duplicate_loop (struct loop *, struct loop *);
-extern bool duplicate_loop_to_header_edge (struct loop *, edge, 
+extern void duplicate_subloops (struct loop *, struct loop *);
+extern bool duplicate_loop_to_header_edge (struct loop *, edge,
                                           unsigned, sbitmap, edge,
                                           VEC (edge, heap) **, int);
 extern struct loop *loopify (edge, edge,
@@ -383,7 +405,6 @@ extern rtx get_iv_value (struct rtx_iv *, rtx);
 extern bool biv_p (rtx, rtx);
 extern void find_simple_exit (struct loop *, struct niter_desc *);
 extern void iv_analysis_done (void);
-extern struct df *iv_current_loop_df (void);
 
 extern struct niter_desc *get_simple_loop_desc (struct loop *loop);
 extern void free_simple_loop_desc (struct loop *loop);
@@ -426,9 +447,17 @@ loop_outer (const struct loop *loop)
   return VEC_index (loop_p, loop->superloops, n - 1);
 }
 
+/* Returns true if LOOP has at least one exit edge.  */
+
+static inline bool
+loop_has_exit_edges (const struct loop *loop)
+{
+  return loop->exits->next->e != NULL;
+}
+
 /* Returns the list of loops in current_loops.  */
 
-static inline VEC (loop_p, heap) *
+static inline VEC (loop_p, gc) *
 get_loops (void)
 {
   if (!current_loops)
@@ -449,6 +478,33 @@ number_of_loops (void)
   return VEC_length (loop_p, current_loops->larray);
 }
 
+/* Returns true if state of the loops satisfies all properties
+   described by FLAGS.  */
+
+static inline bool
+loops_state_satisfies_p (unsigned flags)
+{
+  return (current_loops->state & flags) == flags;
+}
+
+/* Sets FLAGS to the loops state.  */
+
+static inline void
+loops_state_set (unsigned flags)
+{
+  current_loops->state |= flags;
+}
+
+/* Clears FLAGS from the loops state.  */
+
+static inline void
+loops_state_clear (unsigned flags)
+{
+  if (!current_loops)
+    return;
+  current_loops->state &= ~flags;
+}
+
 /* Loop iterators.  */
 
 /* Flags for loop iteration.  */
@@ -578,15 +634,45 @@ fel_init (loop_iterator *li, loop_p *loop, unsigned flags)
   }
 
 /* The properties of the target.  */
+struct target_cfgloop {
+  /* Number of available registers.  */
+  unsigned x_target_avail_regs;
+
+  /* Number of available registers that are call-clobbered.  */
+  unsigned x_target_clobbered_regs;
+
+  /* Number of registers reserved for temporary expressions.  */
+  unsigned x_target_res_regs;
+
+  /* The cost for register when there still is some reserve, but we are
+     approaching the number of available registers.  */
+  unsigned x_target_reg_cost[2];
+
+  /* The cost for register when we need to spill.  */
+  unsigned x_target_spill_cost[2];
+};
 
-extern unsigned target_avail_regs;
-extern unsigned target_res_regs;
-extern unsigned target_reg_cost;
-extern unsigned target_spill_cost;
+extern struct target_cfgloop default_target_cfgloop;
+#if SWITCHABLE_TARGET
+extern struct target_cfgloop *this_target_cfgloop;
+#else
+#define this_target_cfgloop (&default_target_cfgloop)
+#endif
+
+#define target_avail_regs \
+  (this_target_cfgloop->x_target_avail_regs)
+#define target_clobbered_regs \
+  (this_target_cfgloop->x_target_clobbered_regs)
+#define target_res_regs \
+  (this_target_cfgloop->x_target_res_regs)
+#define target_reg_cost \
+  (this_target_cfgloop->x_target_reg_cost)
+#define target_spill_cost \
+  (this_target_cfgloop->x_target_spill_cost)
 
 /* Register pressure estimation for induction variable optimizations & loop
    invariant motion.  */
-extern unsigned estimate_reg_pressure_cost (unsigned, unsigned);
+extern unsigned estimate_reg_pressure_cost (unsigned, unsigned, bool, bool);
 extern void init_set_costs (void);
 
 /* Loop optimizer initialization.  */
@@ -606,5 +692,6 @@ enum
 extern void unroll_and_peel_loops (int);
 extern void doloop_optimize_loops (void);
 extern void move_loop_invariants (void);
+extern bool finite_loop_p (struct loop *);
 
 #endif /* GCC_CFGLOOP_H */