OSDN Git Service

* godump.c (go_format_type): Check for invalid type names, pointer
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-im.c
index 6aaeaa0..778edd4 100644 (file)
@@ -197,9 +197,10 @@ static bool ref_indep_loop_p (struct loop *, mem_ref_p);
 /* Minimum cost of an expensive expression.  */
 #define LIM_EXPENSIVE ((unsigned) PARAM_VALUE (PARAM_LIM_EXPENSIVE))
 
-/* The outermost loop for that execution of the header guarantees that the
+/* The outermost loop for which execution of the header guarantees that the
    block will be executed.  */
 #define ALWAYS_EXECUTED_IN(BB) ((struct loop *) (BB)->aux)
+#define SET_ALWAYS_EXECUTED_IN(BB, VAL) ((BB)->aux = (void *) (VAL))
 
 static struct lim_aux_data *
 init_lim_data (gimple stmt)
@@ -272,8 +273,6 @@ for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
        case SSA_NAME:
          return cbck (*addr_p, addr_p, data);
 
-       case MISALIGNED_INDIRECT_REF:
-       case ALIGN_INDIRECT_REF:
        case MEM_REF:
          nxt = &TREE_OPERAND (*addr_p, 0);
          return cbck (*addr_p, nxt, data);
@@ -328,6 +327,10 @@ for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
          if (*idx
              && !cbck (*addr_p, idx, data))
            return false;
+         idx = &TMR_INDEX2 (*addr_p);
+         if (*idx
+             && !cbck (*addr_p, idx, data))
+           return false;
          return true;
 
        default:
@@ -674,31 +677,38 @@ extract_true_false_args_from_phi (basic_block dom, gimple phi,
      by the true edge of the predicate block and the other edge
      dominated by the false edge.  This ensures that the PHI argument
      we are going to take is completely determined by the path we
-     take from the predicate block.  */
+     take from the predicate block.
+     We can only use BB dominance checks below if the destination of
+     the true/false edges are dominated by their edge, thus only
+     have a single predecessor.  */
   extract_true_false_edges_from_block (dom, &true_edge, &false_edge);
   tem = EDGE_PRED (bb, 0);
   if (tem == true_edge
-      || tem->src == true_edge->dest
-      || dominated_by_p (CDI_DOMINATORS,
-                        tem->src, true_edge->dest))
+      || (single_pred_p (true_edge->dest)
+         && (tem->src == true_edge->dest
+             || dominated_by_p (CDI_DOMINATORS,
+                                tem->src, true_edge->dest))))
     arg0 = PHI_ARG_DEF (phi, tem->dest_idx);
   else if (tem == false_edge
-          || tem->src == false_edge->dest
-          || dominated_by_p (CDI_DOMINATORS,
-                             tem->src, false_edge->dest))
+          || (single_pred_p (false_edge->dest)
+              && (tem->src == false_edge->dest
+                  || dominated_by_p (CDI_DOMINATORS,
+                                     tem->src, false_edge->dest))))
     arg1 = PHI_ARG_DEF (phi, tem->dest_idx);
   else
     return false;
   tem = EDGE_PRED (bb, 1);
   if (tem == true_edge
-      || tem->src == true_edge->dest
-      || dominated_by_p (CDI_DOMINATORS,
-                        tem->src, true_edge->dest))
+      || (single_pred_p (true_edge->dest)
+         && (tem->src == true_edge->dest
+             || dominated_by_p (CDI_DOMINATORS,
+                                tem->src, true_edge->dest))))
     arg0 = PHI_ARG_DEF (phi, tem->dest_idx);
   else if (tem == false_edge
-          || tem->src == false_edge->dest
-          || dominated_by_p (CDI_DOMINATORS,
-                             tem->src, false_edge->dest))
+          || (single_pred_p (false_edge->dest)
+              && (tem->src == false_edge->dest
+                  || dominated_by_p (CDI_DOMINATORS,
+                                     tem->src, false_edge->dest))))
     arg1 = PHI_ARG_DEF (phi, tem->dest_idx);
   else
     return false;
@@ -908,19 +918,7 @@ rewrite_reciprocal (gimple_stmt_iterator *bsi)
   add_referenced_var (var);
   DECL_GIMPLE_REG_P (var) = 1;
 
-  /* For vectors, create a VECTOR_CST full of 1's.  */
-  if (TREE_CODE (type) == VECTOR_TYPE)
-    {
-      int i, len;
-      tree list = NULL_TREE;
-      real_one = build_real (TREE_TYPE (type), dconst1);
-      len = TYPE_VECTOR_SUBPARTS (type);
-      for (i = 0; i < len; i++)
-       list = tree_cons (NULL, real_one, list);
-      real_one = build_vector (type, list);
-    }
-  else
-    real_one = build_real (type, dconst1);
+  real_one = build_one_cst (type);
 
   stmt1 = gimple_build_assign_with_ops (RDIV_EXPR,
                var, real_one, gimple_assign_rhs2 (stmt));
@@ -1443,7 +1441,7 @@ free_mem_ref_locs (mem_ref_locs_p accs)
   if (!accs)
     return;
 
-  for (i = 0; VEC_iterate (mem_ref_loc_p, accs->locs, i, loc); i++)
+  FOR_EACH_VEC_ELT (mem_ref_loc_p, accs->locs, i, loc)
     free (loc);
   VEC_free (mem_ref_loc_p, heap, accs->locs);
   free (accs);
@@ -1464,7 +1462,7 @@ memref_free (void *obj)
   BITMAP_FREE (mem->indep_ref);
   BITMAP_FREE (mem->dep_ref);
 
-  for (i = 0; VEC_iterate (mem_ref_locs_p, mem->accesses_in_loop, i, accs); i++)
+  FOR_EACH_VEC_ELT (mem_ref_locs_p, mem->accesses_in_loop, i, accs)
     free_mem_ref_locs (accs);
   VEC_free (mem_ref_locs_p, heap, mem->accesses_in_loop);
 
@@ -1930,7 +1928,7 @@ get_all_locs_in_loop (struct loop *loop, mem_ref_p ref,
       accs = VEC_index (mem_ref_locs_p, ref->accesses_in_loop, loop->num);
       if (accs)
        {
-         for (i = 0; VEC_iterate (mem_ref_loc_p, accs->locs, i, loc); i++)
+         FOR_EACH_VEC_ELT (mem_ref_loc_p, accs->locs, i, loc)
            VEC_safe_push (mem_ref_loc_p, heap, *locs, loc);
        }
     }
@@ -1949,7 +1947,7 @@ rewrite_mem_refs (struct loop *loop, mem_ref_p ref, tree tmp_var)
   VEC (mem_ref_loc_p, heap) *locs = NULL;
 
   get_all_locs_in_loop (loop, ref, &locs);
-  for (i = 0; VEC_iterate (mem_ref_loc_p, locs, i, loc); i++)
+  FOR_EACH_VEC_ELT (mem_ref_loc_p, locs, i, loc)
     rewrite_mem_ref_loc (loc, tmp_var);
   VEC_free (mem_ref_loc_p, heap, locs);
 }
@@ -1983,8 +1981,6 @@ gen_lsm_tmp_name (tree ref)
 
   switch (TREE_CODE (ref))
     {
-    case MISALIGNED_INDIRECT_REF:
-    case ALIGN_INDIRECT_REF:
     case MEM_REF:
       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
       lsm_tmp_name_add ("_");
@@ -2115,7 +2111,7 @@ execute_sm (struct loop *loop, VEC (edge, heap) *exits, mem_ref_p ref)
      all dependencies.  */
   gsi_insert_on_edge (loop_latch_edge (loop), load);
 
-  for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
+  FOR_EACH_VEC_ELT (edge, exits, i, ex)
     {
       store = gimple_build_assign (unshare_expr (ref->mem), tmp_var);
       gsi_insert_on_edge (ex, store);
@@ -2159,7 +2155,7 @@ ref_always_accessed_p (struct loop *loop, mem_ref_p ref, bool stored_p)
     base = TREE_OPERAND (base, 0);
 
   get_all_locs_in_loop (loop, ref, &locs);
-  for (i = 0; VEC_iterate (mem_ref_loc_p, locs, i, loc); i++)
+  FOR_EACH_VEC_ELT (mem_ref_loc_p, locs, i, loc)
     {
       if (!get_lim_data (loc->stmt))
        continue;
@@ -2330,6 +2326,10 @@ can_sm_ref_p (struct loop *loop, mem_ref_p ref)
       || !for_each_index (&ref->mem, may_move_till, loop))
     return false;
 
+  /* If it can throw fail, we do not properly update EH info.  */
+  if (tree_could_throw_p (ref->mem))
+    return false;
+
   /* If it can trap, it must be always executed in LOOP.
      Readonly memory locations may trap when storing to them, but
      tree_could_trap_p is a predicate for rvalues, so check that
@@ -2380,8 +2380,8 @@ loop_suitable_for_sm (struct loop *loop ATTRIBUTE_UNUSED,
   unsigned i;
   edge ex;
 
-  for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
-    if (ex->flags & EDGE_ABNORMAL)
+  FOR_EACH_VEC_ELT (edge, exits, i, ex)
+    if (ex->flags & (EDGE_ABNORMAL | EDGE_EH))
       return false;
 
   return true;
@@ -2441,7 +2441,7 @@ fill_always_executed_in (struct loop *loop, sbitmap contains_call)
   edge e;
   struct loop *inn_loop = loop;
 
-  if (!loop->header->aux)
+  if (ALWAYS_EXECUTED_IN (loop->header) == NULL)
     {
       bbs = get_loop_body_in_dom_order (loop);
 
@@ -2483,7 +2483,7 @@ fill_always_executed_in (struct loop *loop, sbitmap contains_call)
 
       while (1)
        {
-         last->aux = loop;
+         SET_ALWAYS_EXECUTED_IN (last, loop);
          if (last == loop->header)
            break;
          last = get_immediate_dominator (CDI_DOMINATORS, last);
@@ -2538,28 +2538,26 @@ tree_ssa_lim_finalize (void)
   htab_t h;
 
   FOR_EACH_BB (bb)
-    {
-      bb->aux = NULL;
-    }
+    SET_ALWAYS_EXECUTED_IN (bb, NULL);
 
   pointer_map_destroy (lim_aux_data_map);
 
   VEC_free (mem_ref_p, heap, memory_accesses.refs_list);
   htab_delete (memory_accesses.refs);
 
-  for (i = 0; VEC_iterate (bitmap, memory_accesses.refs_in_loop, i, b); i++)
+  FOR_EACH_VEC_ELT (bitmap, memory_accesses.refs_in_loop, i, b)
     BITMAP_FREE (b);
   VEC_free (bitmap, heap, memory_accesses.refs_in_loop);
 
-  for (i = 0; VEC_iterate (bitmap, memory_accesses.all_refs_in_loop, i, b); i++)
+  FOR_EACH_VEC_ELT (bitmap, memory_accesses.all_refs_in_loop, i, b)
     BITMAP_FREE (b);
   VEC_free (bitmap, heap, memory_accesses.all_refs_in_loop);
 
-  for (i = 0; VEC_iterate (bitmap, memory_accesses.clobbered_vops, i, b); i++)
+  FOR_EACH_VEC_ELT (bitmap, memory_accesses.clobbered_vops, i, b)
     BITMAP_FREE (b);
   VEC_free (bitmap, heap, memory_accesses.clobbered_vops);
 
-  for (i = 0; VEC_iterate (htab_t, memory_accesses.vop_ref_map, i, h); i++)
+  FOR_EACH_VEC_ELT (htab_t, memory_accesses.vop_ref_map, i, h)
     htab_delete (h);
   VEC_free (htab_t, heap, memory_accesses.vop_ref_map);