OSDN Git Service

* dwarf2out.c (gen_compile_unit_die): Use DW_LANG_Go for Go.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-prefetch.c
index 008f2ce..264d97b 100644 (file)
@@ -1,5 +1,6 @@
 /* Array prefetching.
-   Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -37,7 +38,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-chrec.h"
 #include "tree-scalar-evolution.h"
 #include "diagnostic-core.h"
-#include "toplev.h"
 #include "params.h"
 #include "langhooks.h"
 #include "tree-inline.h"
@@ -80,7 +80,7 @@ along with GCC; see the file COPYING3.  If not see
        (2) has PREFETCH_MOD 64
        (3) has PREFETCH_MOD 4
        (4) has PREFETCH_MOD 1.  We do not set PREFETCH_BEFORE here, since
-           the cache line accessed by (4) is the same with probability only
+           the cache line accessed by (5) is the same with probability only
           7/32.
        (5) has PREFETCH_MOD 1 as well.
 
@@ -423,9 +423,6 @@ idx_analyze_ref (tree base, tree *index, void *data)
   HOST_WIDE_INT idelta = 0, imult = 1;
   affine_iv iv;
 
-  if (TREE_CODE (base) == MISALIGNED_INDIRECT_REF)
-    return false;
-
   if (!simple_iv (ar_data->loop, loop_containing_stmt (ar_data->stmt),
                  *index, &iv, true))
     return false;
@@ -486,10 +483,18 @@ analyze_ref (struct loop *loop, tree *ref_p, tree *base,
   *step = NULL_TREE;
   *delta = 0;
 
-  /* First strip off the component references.  Ignore bitfields.  */
-  if (TREE_CODE (ref) == COMPONENT_REF
-      && DECL_NONADDRESSABLE_P (TREE_OPERAND (ref, 1)))
-    ref = TREE_OPERAND (ref, 0);
+  /* First strip off the component references.  Ignore bitfields.
+     Also strip off the real and imagine parts of a complex, so that
+     they can have the same base.  */
+  if (TREE_CODE (ref) == REALPART_EXPR
+      || TREE_CODE (ref) == IMAGPART_EXPR
+      || (TREE_CODE (ref) == COMPONENT_REF
+          && DECL_NONADDRESSABLE_P (TREE_OPERAND (ref, 1))))
+    {
+      if (TREE_CODE (ref) == IMAGPART_EXPR)
+        *delta += int_size_in_bytes (TREE_TYPE (ref));
+      ref = TREE_OPERAND (ref, 0);
+    }
 
   *ref_p = ref;
 
@@ -531,6 +536,10 @@ gather_memory_references_ref (struct loop *loop, struct mem_ref_group **refs,
   if (step == NULL_TREE)
     return false;
 
+  /* Stop if the address of BASE could not be taken.  */
+  if (may_be_nonaddressable_p (base))
+    return false;
+
   /* Limit non-constant step prefetching only to the innermost loops.  */
   if (!cst_and_fits_in_hwi (step) && loop->inner != NULL)
     return false;
@@ -786,7 +795,7 @@ prune_ref_by_group_reuse (struct mem_ref *ref, struct mem_ref *by,
       prefetch_before = (hit_from - delta_r + step - 1) / step;
 
       /* Do not reduce prefetch_before if we meet beyond cache size.  */
-      if (prefetch_before > (unsigned) abs (L2_CACHE_SIZE_BYTES / step))
+      if (prefetch_before > absu_hwi (L2_CACHE_SIZE_BYTES / step))
         prefetch_before = PREFETCH_ALL;
       if (prefetch_before < ref->prefetch_before)
        ref->prefetch_before = prefetch_before;
@@ -1083,7 +1092,7 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
   addr_base = force_gimple_operand_gsi (&bsi, unshare_expr (addr_base),
                                        true, NULL, true, GSI_SAME_STMT);
   write_p = ref->write_p ? integer_one_node : integer_zero_node;
-  local = build_int_cst (integer_type_node, nontemporal ? 0 : 3);
+  local = nontemporal ? integer_zero_node : integer_three_node;
 
   for (ap = 0; ap < n_prefetches; ap++)
     {
@@ -1092,8 +1101,7 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
           /* Determine the address to prefetch.  */
           delta = (ahead + ap * ref->prefetch_mod) *
                   int_cst_value (ref->group->step);
-          addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
-                              addr_base, size_int (delta));
+          addr = fold_build_pointer_plus_hwi (addr_base, delta);
           addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, NULL,
                                            true, GSI_SAME_STMT);
         }
@@ -1104,13 +1112,12 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
           forward = fold_build2 (MULT_EXPR, sizetype,
                                  fold_convert (sizetype, ref->group->step),
                                  fold_convert (sizetype, size_int (ahead)));
-          addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr_base,
-                             forward);
+          addr = fold_build_pointer_plus (addr_base, forward);
           addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true,
                                           NULL, true, GSI_SAME_STMT);
       }
       /* Create the prefetch instruction.  */
-      prefetch = gimple_build_call (built_in_decls[BUILT_IN_PREFETCH],
+      prefetch = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH),
                                    3, addr, write_p, local);
       gsi_insert_before (&bsi, prefetch, GSI_SAME_STMT);
     }
@@ -1188,7 +1195,7 @@ emit_mfence_after_loop (struct loop *loop)
   gimple_stmt_iterator bsi;
   unsigned i;
 
-  for (i = 0; VEC_iterate (edge, exits, i, exit); i++)
+  FOR_EACH_VEC_ELT (edge, exits, i, exit)
     {
       call = gimple_build_call (FENCE_FOLLOWING_MOVNT, 0);
 
@@ -1225,7 +1232,7 @@ may_use_storent_in_loop_p (struct loop *loop)
       unsigned i;
       edge exit;
 
-      for (i = 0; VEC_iterate (edge, exits, i, exit); i++)
+      FOR_EACH_VEC_ELT (edge, exits, i, exit)
        if ((exit->flags & EDGE_ABNORMAL)
            && exit->dest == EXIT_BLOCK_PTR)
          ret = false;
@@ -1444,7 +1451,7 @@ self_reuse_distance (data_reference_p dr, unsigned *loop_sizes, unsigned n,
   strides = XCNEWVEC (HOST_WIDE_INT, n);
   access_fns = DR_ACCESS_FNS (dr);
 
-  for (i = 0; VEC_iterate (tree, access_fns, i, access_fn); i++)
+  FOR_EACH_VEC_ELT (tree, access_fns, i, access_fn)
     {
       /* Keep track of the reference corresponding to the subscript, so that we
         know its stride.  */
@@ -1541,7 +1548,7 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
        continue;
 
       aloop = VEC_index (loop_p, vloops, i);
-      vol = estimated_loop_iterations_int (aloop, false);
+      vol = max_stmt_executions_int (aloop, false);
       if (vol < 0)
        vol = expected_loop_iterations (aloop);
       volume *= vol;
@@ -1554,7 +1561,8 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
   for (gr = refs; gr; gr = gr->next)
     for (ref = gr->refs; ref; ref = ref->next)
       {
-       dr = create_data_ref (nest, ref->mem, ref->stmt, !ref->write_p);
+       dr = create_data_ref (nest, loop_containing_stmt (ref->stmt),
+                             ref->mem, ref->stmt, !ref->write_p);
 
        if (dr)
          {
@@ -1566,7 +1574,7 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
          no_other_refs = false;
       }
 
-  for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
+  FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, dr)
     {
       dist = self_reuse_distance (dr, loop_data_size, n, loop);
       ref = (struct mem_ref *) dr->aux;
@@ -1579,7 +1587,7 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
 
   compute_all_dependences (datarefs, &dependences, vloops, true);
 
-  for (i = 0; VEC_iterate (ddr_p, dependences, i, dep); i++)
+  FOR_EACH_VEC_ELT (ddr_p, dependences, i, dep)
     {
       if (DDR_ARE_DEPENDENT (dep) == chrec_known)
        continue;
@@ -1792,7 +1800,7 @@ loop_prefetch_arrays (struct loop *loop)
     return false;
 
   ahead = (PREFETCH_LATENCY + time - 1) / time;
-  est_niter = estimated_loop_iterations_int (loop, false);
+  est_niter = max_stmt_executions_int (loop, false);
 
   /* Prefetching is not likely to be profitable if the trip count to ahead
      ratio is too small.  */
@@ -1901,17 +1909,15 @@ tree_ssa_prefetch_arrays (void)
 
   initialize_original_copy_tables ();
 
-  if (!built_in_decls[BUILT_IN_PREFETCH])
+  if (!builtin_decl_explicit_p (BUILT_IN_PREFETCH))
     {
-      tree type = build_function_type (void_type_node,
-                                      tree_cons (NULL_TREE,
-                                                 const_ptr_type_node,
-                                                 NULL_TREE));
+      tree type = build_function_type_list (void_type_node,
+                                           const_ptr_type_node, NULL_TREE);
       tree decl = add_builtin_function ("__builtin_prefetch", type,
                                        BUILT_IN_PREFETCH, BUILT_IN_NORMAL,
                                        NULL, NULL_TREE);
       DECL_IS_NOVOPS (decl) = true;
-      built_in_decls[BUILT_IN_PREFETCH] = decl;
+      set_builtin_decl (BUILT_IN_PREFETCH, decl, false);
     }
 
   /* We assume that size of cache line is a power of two, so verify this