summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-prefetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-loop-prefetch.c')
-rw-r--r--gcc/tree-ssa-loop-prefetch.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index c054c60203..339eeafcfe 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -1,5 +1,5 @@
/* Array prefetching.
- Copyright (C) 2005-2016 Free Software Foundation, Inc.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
This file is part of GCC.
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h"
+#include "ssa.h"
#include "tree-into-ssa.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
@@ -46,10 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "tree-inline.h"
#include "tree-data-ref.h"
-
-
-/* FIXME: Needed for optabs, but this should all be moved to a TBD interface
- between the GIMPLE and RTL worlds. */
+#include "diagnostic-core.h"
/* This pass inserts prefetch instructions to optimize cache usage during
accesses to arrays in loops. It processes loops sequentially and:
@@ -233,7 +231,7 @@ struct mem_ref_group
/* Assigned to PREFETCH_BEFORE when all iterations are to be prefetched. */
-#define PREFETCH_ALL (~(unsigned HOST_WIDE_INT) 0)
+#define PREFETCH_ALL HOST_WIDE_INT_M1U
/* Do not generate a prefetch if the unroll factor is significantly less
than what is required by the prefetch. This is to avoid redundant
@@ -631,6 +629,9 @@ gather_memory_references (struct loop *loop, bool *no_other_refs, unsigned *ref_
continue;
}
+ if (! gimple_vuse (stmt))
+ continue;
+
lhs = gimple_assign_lhs (stmt);
rhs = gimple_assign_rhs1 (stmt);
@@ -700,9 +701,9 @@ ddown (HOST_WIDE_INT x, unsigned HOST_WIDE_INT by)
gcc_assert (by > 0);
if (x >= 0)
- return x / by;
+ return x / (HOST_WIDE_INT) by;
else
- return (x + by - 1) / by;
+ return (x + (HOST_WIDE_INT) by - 1) / (HOST_WIDE_INT) by;
}
/* Given a CACHE_LINE_SIZE and two inductive memory references
@@ -1157,6 +1158,18 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true,
NULL, true, GSI_SAME_STMT);
}
+
+ if (addr_base != addr
+ && TREE_CODE (addr_base) == SSA_NAME
+ && TREE_CODE (addr) == SSA_NAME)
+ {
+ duplicate_ssa_name_ptr_info (addr, SSA_NAME_PTR_INFO (addr_base));
+ /* As this isn't a plain copy we have to reset alignment
+ information. */
+ if (SSA_NAME_PTR_INFO (addr))
+ mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (addr));
+ }
+
/* Create the prefetch instruction. */
prefetch = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH),
3, addr, write_p, local);
@@ -1546,7 +1559,7 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
vec<ddr_p> dependences = vNULL;
struct mem_ref_group *gr;
struct mem_ref *ref, *refb;
- vec<loop_p> vloops = vNULL;
+ auto_vec<loop_p> vloops;
unsigned *loop_data_size;
unsigned i, j, n;
unsigned volume, dist, adist;
@@ -1845,7 +1858,7 @@ loop_prefetch_arrays (struct loop *loop)
ahead = (PREFETCH_LATENCY + time - 1) / time;
est_niter = estimated_stmt_executions_int (loop);
if (est_niter == -1)
- est_niter = max_stmt_executions_int (loop);
+ est_niter = likely_max_stmt_executions_int (loop);
/* Prefetching is not likely to be profitable if the trip count to ahead
ratio is too small. */
@@ -1965,10 +1978,6 @@ tree_ssa_prefetch_arrays (void)
set_builtin_decl (BUILT_IN_PREFETCH, decl, false);
}
- /* We assume that size of cache line is a power of two, so verify this
- here. */
- gcc_assert ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) == 0);
-
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2026,6 +2035,20 @@ pass_loop_prefetch::execute (function *fun)
if (number_of_loops (fun) <= 1)
return 0;
+ if ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) != 0)
+ {
+ static bool warned = false;
+
+ if (!warned)
+ {
+ warning (OPT_Wdisabled_optimization,
+ "%<l1-cache-size%> parameter is not a power of two %d",
+ PREFETCH_BLOCK);
+ warned = true;
+ }
+ return 0;
+ }
+
return tree_ssa_prefetch_arrays ();
}