OSDN Git Service

PR testsuite/34168
[pf3gnuchains/gcc-fork.git] / gcc / tree-flow-inline.h
index 992aad0..d8593bd 100644 (file)
@@ -151,13 +151,8 @@ next_htab_element (htab_iterator *hti)
 static inline tree
 first_referenced_var (referenced_var_iterator *iter)
 {
-  struct int_tree_map *itm;
-  itm = (struct int_tree_map *) first_htab_element (&iter->hti,
-                                                    gimple_referenced_vars
-                                                   (cfun));
-  if (!itm) 
-    return NULL;
-  return itm->to;
+  return (tree) first_htab_element (&iter->hti,
+                                   gimple_referenced_vars (cfun));
 }
 
 /* Return true if we have hit the end of the referenced variables ITER is
@@ -175,11 +170,7 @@ end_referenced_vars_p (const referenced_var_iterator *iter)
 static inline tree
 next_referenced_var (referenced_var_iterator *iter)
 {
-  struct int_tree_map *itm;
-  itm = (struct int_tree_map *) next_htab_element (&iter->hti);
-  if (!itm) 
-    return NULL;
-  return itm->to;
+  return (tree) next_htab_element (&iter->hti);
 } 
 
 /* Fill up VEC with the variables in the referenced vars hashtable.  */
@@ -199,23 +190,28 @@ fill_referenced_var_vec (VEC (tree, heap) **vec)
 static inline var_ann_t
 var_ann (const_tree t)
 {
-  gcc_assert (t);
-  gcc_assert (DECL_P (t));
-  gcc_assert (TREE_CODE (t) != FUNCTION_DECL);
-  if (!MTAG_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+  var_ann_t ann;
+
+  if (!MTAG_P (t)
+      && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     {
       struct static_var_ann_d *sann
         = ((struct static_var_ann_d *)
           htab_find_with_hash (gimple_var_anns (cfun), t, DECL_UID (t)));
       if (!sann)
        return NULL;
-      gcc_assert (sann->ann.common.type == VAR_ANN);
-      return &sann->ann;
+      ann = &sann->ann;
     }
-  gcc_assert (!t->base.ann
-             || t->base.ann->common.type == VAR_ANN);
+  else
+    {
+      if (!t->base.ann)
+       return NULL;
+      ann = (var_ann_t) t->base.ann;
+    }
+
+  gcc_assert (ann->common.type == VAR_ANN);
 
-  return (var_ann_t) t->base.ann;
+  return ann;
 }
 
 /* Return the variable annotation for T, which must be a _DECL node.
@@ -313,7 +309,7 @@ may_aliases (const_tree var)
 /* Return the line number for EXPR, or return -1 if we have no line
    number information for it.  */
 static inline int
-get_lineno (tree expr)
+get_lineno (const_tree expr)
 {
   if (expr == NULL_TREE)
     return -1;
@@ -506,8 +502,8 @@ next_readonly_imm_use (imm_use_iterator *imm)
   use_operand_p old = imm->imm_use;
 
 #ifdef ENABLE_CHECKING
-  /* If this assertion fails, it indicates the 'next' pointer has changed 
-     since we the last bump.  This indicates that the list is being modified
+  /* If this assertion fails, it indicates the 'next' pointer has changed
+     since the last bump.  This indicates that the list is being modified
      via stmt changes, or SET_USE, or somesuch thing, and you need to be
      using the SAFE version of the iterator.  */
   gcc_assert (imm->iter_node.next == old->next);
@@ -516,7 +512,7 @@ next_readonly_imm_use (imm_use_iterator *imm)
 
   imm->imm_use = old->next;
   if (end_readonly_imm_use_p (imm))
-    return old;
+    return NULL_USE_OPERAND_P;
   return imm->imm_use;
 }
 
@@ -611,7 +607,7 @@ addresses_taken (tree stmt)
 /* Return the PHI nodes for basic block BB, or NULL if there are no
    PHI nodes.  */
 static inline tree
-phi_nodes (basic_block bb)
+phi_nodes (const_basic_block bb)
 {
   gcc_assert (!(bb->flags & BB_RTL));
   if (!bb->il.tree)
@@ -745,21 +741,6 @@ bsi_start (basic_block bb)
   return bsi;
 }
 
-static inline const_block_stmt_iterator
-cbsi_start (const_basic_block bb)
-{
-  const_block_stmt_iterator bsi;
-  if (bb->index < NUM_FIXED_BLOCKS)
-    {
-      bsi.tsi.ptr = NULL;
-      bsi.tsi.container = NULL;
-    }
-  else
-    bsi.tsi = ctsi_start (bb_stmt_list (bb));
-  bsi.bb = bb;
-  return bsi;
-}
-
 /* Return a block statement iterator that points to the first non-label
    statement in block BB.  */
 
@@ -792,22 +773,6 @@ bsi_last (basic_block bb)
   return bsi;
 }
 
-static inline const_block_stmt_iterator
-cbsi_last (const_basic_block bb)
-{
-  const_block_stmt_iterator bsi;
-
-  if (bb->index < NUM_FIXED_BLOCKS)
-    {
-      bsi.tsi.ptr = NULL;
-      bsi.tsi.container = NULL;
-    }
-  else
-    bsi.tsi = ctsi_last (bb_stmt_list (bb));
-  bsi.bb = bb;
-  return bsi;
-}
-
 /* Return true if block statement iterator I has reached the end of
    the basic block.  */
 static inline bool
@@ -816,12 +781,6 @@ bsi_end_p (block_stmt_iterator i)
   return tsi_end_p (i.tsi);
 }
 
-static inline bool
-cbsi_end_p (const_block_stmt_iterator i)
-{
-  return ctsi_end_p (i.tsi);
-}
-
 /* Modify block statement iterator I so that it is at the next
    statement in the basic block.  */
 static inline void
@@ -830,12 +789,6 @@ bsi_next (block_stmt_iterator *i)
   tsi_next (&i->tsi);
 }
 
-static inline void
-cbsi_next (const_block_stmt_iterator *i)
-{
-  ctsi_next (&i->tsi);
-}
-
 /* Modify block statement iterator I so that it is at the previous
    statement in the basic block.  */
 static inline void
@@ -844,12 +797,6 @@ bsi_prev (block_stmt_iterator *i)
   tsi_prev (&i->tsi);
 }
 
-static inline void
-cbsi_prev (const_block_stmt_iterator *i)
-{
-  ctsi_prev (&i->tsi);
-}
-
 /* Return the statement that block statement iterator I is currently
    at.  */
 static inline tree
@@ -858,12 +805,6 @@ bsi_stmt (block_stmt_iterator i)
   return tsi_stmt (i.tsi);
 }
 
-static inline const_tree
-cbsi_stmt (const_block_stmt_iterator i)
-{
-  return ctsi_stmt (i.tsi);
-}
-
 /* Return a pointer to the statement that block statement iterator I
    is currently at.  */
 static inline tree *
@@ -1673,15 +1614,89 @@ get_subvars_for_var (tree var)
 static inline tree
 get_subvar_at (tree var, unsigned HOST_WIDE_INT offset)
 {
-  subvar_t sv;
+  subvar_t sv = get_subvars_for_var (var);
+  int low, high;
 
-  for (sv = get_subvars_for_var (var); sv; sv = sv->next)
-    if (SFT_OFFSET (sv->var) == offset)
-      return sv->var;
+  low = 0;
+  high = VEC_length (tree, sv) - 1;
+  while (low <= high)
+    {
+      int mid = (low + high) / 2;
+      tree subvar = VEC_index (tree, sv, mid);
+      if (SFT_OFFSET (subvar) == offset)
+       return subvar;
+      else if (SFT_OFFSET (subvar) < offset)
+       low = mid + 1;
+      else
+       high = mid - 1;
+    }
 
   return NULL_TREE;
 }
 
+
+/* Return the first subvariable in SV that overlaps [offset, offset + size[.
+   NULL_TREE is returned, if there is no overlapping subvariable, else *I
+   is set to the index in the SV vector of the first overlap.  */
+
+static inline tree
+get_first_overlapping_subvar (subvar_t sv, unsigned HOST_WIDE_INT offset,
+                             unsigned HOST_WIDE_INT size, unsigned int *i)
+{
+  int low = 0;
+  int high = VEC_length (tree, sv) - 1;
+  int mid;
+  tree subvar;
+
+  if (low > high)
+    return NULL_TREE;
+
+  /* Binary search for offset.  */
+  do
+    {
+      mid = (low + high) / 2;
+      subvar = VEC_index (tree, sv, mid);
+      if (SFT_OFFSET (subvar) == offset)
+       {
+         *i = mid;
+         return subvar;
+       }
+      else if (SFT_OFFSET (subvar) < offset)
+       low = mid + 1;
+      else
+       high = mid - 1;
+    }
+  while (low <= high);
+
+  /* As we didn't find a subvar with offset, adjust to return the
+     first overlapping one.  */
+  if (SFT_OFFSET (subvar) < offset
+      && SFT_OFFSET (subvar) + SFT_SIZE (subvar) <= offset)
+    {
+      mid += 1;
+      if ((unsigned)mid >= VEC_length (tree, sv))
+       return NULL_TREE;
+      subvar = VEC_index (tree, sv, mid);
+    }
+  else if (SFT_OFFSET (subvar) > offset
+          && size <= SFT_OFFSET (subvar) - offset)
+    {
+      mid -= 1;
+      if (mid < 0)
+       return NULL_TREE;
+      subvar = VEC_index (tree, sv, mid);
+    }
+
+  if (overlap_subvar (offset, size, subvar, NULL))
+    {
+      *i = mid;
+      return subvar;
+    }
+
+  return NULL_TREE;
+}
+
+
 /* Return true if V is a tree that we can have subvars for.
    Normally, this is any aggregate type.  Also complex
    types which are not gimple registers can have subvars.  */
@@ -1710,7 +1725,30 @@ var_can_have_subvars (const_tree v)
   return false;
 }
 
-  
+
+/* Return true, if the two ranges [POS1, SIZE1] and [POS2, SIZE2]
+   overlap.  SIZE1 and/or SIZE2 can be (unsigned)-1 in which case the
+   range is open-ended.  Otherwise return false.  */
+
+static inline bool
+ranges_overlap_p (unsigned HOST_WIDE_INT pos1,
+                 unsigned HOST_WIDE_INT size1,
+                 unsigned HOST_WIDE_INT pos2,
+                 unsigned HOST_WIDE_INT size2)
+{
+  if (pos1 >= pos2
+      && (size2 == (unsigned HOST_WIDE_INT)-1
+         || pos1 < (pos2 + size2)))
+    return true;
+  if (pos2 >= pos1
+      && (size1 == (unsigned HOST_WIDE_INT)-1
+         || pos2 < (pos1 + size1)))
+    return true;
+
+  return false;
+}
+
+
 /* Return true if OFFSET and SIZE define a range that overlaps with some
    portion of the range of SV, a subvar.  If there was an exact overlap,
    *EXACT will be set to true upon return. */
@@ -1827,4 +1865,20 @@ gimple_mem_ref_stats (const struct function *fn)
 {
   return &fn->gimple_df->mem_ref_stats;
 }
+
+/* Given an edge_var_map V, return the PHI arg definition.  */
+
+static inline tree
+redirect_edge_var_map_def (edge_var_map *v)
+{
+  return v->def;
+}
+
+/* Given an edge_var_map V, return the PHI result.  */
+
+static inline tree
+redirect_edge_var_map_result (edge_var_map *v)
+{
+  return v->result;
+}
 #endif /* _TREE_FLOW_INLINE_H  */