Commit 18caa34e by Bin Cheng Committed by Bin Cheng

tree-if-conv.c (tree-ssa-loop.h): Include header file.

	* tree-if-conv.c (tree-ssa-loop.h): Include header file.
	(tree-ssa-loop-niter.h): Ditto.
	(idx_within_array_bound, ref_within_array_bound): New functions.
	(ifcvt_memrefs_wont_trap): Check if array ref is within bound.
	Factor out check on writable base object to ...
	(base_object_writable): ... here.

	gcc/testsuite/
	* gcc.dg/tree-ssa/ifc-9.c: New test.
	* gcc.dg/tree-ssa/ifc-10.c: New test.
	* gcc.dg/tree-ssa/ifc-11.c: New test.
	* gcc.dg/tree-ssa/ifc-12.c: New test.
	* gcc.dg/vect/pr61194.c: Remove XFAIL.
	* gcc.dg/vect/vect-23.c: Remove XFAIL.
	* gcc.dg/vect/vect-mask-store-move-1.c: Revise test check.

From-SVN: r236026
parent fb334765
2016-05-09 Bin Cheng <bin.cheng@arm.com>
* tree-if-conv.c (tree-ssa-loop.h): Include header file.
(tree-ssa-loop-niter.h): Ditto.
(idx_within_array_bound, ref_within_array_bound): New functions.
(ifcvt_memrefs_wont_trap): Check if array ref is within bound.
Factor out check on writable base object to ...
(base_object_writable): ... here.
2016-05-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.md (probe_stack): Add modes to set source
......
2016-05-09 Bin Cheng <bin.cheng@arm.com>
* gcc.dg/tree-ssa/ifc-9.c: New test.
* gcc.dg/tree-ssa/ifc-10.c: New test.
* gcc.dg/tree-ssa/ifc-11.c: New test.
* gcc.dg/tree-ssa/ifc-12.c: New test.
* gcc.dg/vect/pr61194.c: Remove XFAIL.
* gcc.dg/vect/vect-23.c: Remove XFAIL.
* gcc.dg/vect/vect-mask-store-move-1.c: Revise test check.
2016-05-09 Richard Biener <rguenther@suse.de>
PR fortran/70937
......
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-ifcvt-stats" } */
/* { dg-require-visibility "" } */
int b[256] = {0}, y;
void bar (int *);
int foo (int x, int n)
{
int i;
int a[128];
for (i = 0; i < n; i++)
{
a[i] = i;
if (x > i)
b[i] = y;
}
bar (a);
return 0;
}
/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-ifcvt-stats" } */
/* { dg-require-visibility "" } */
int a[1024] = {0.0};
int b[1024] = {0.0};
int c[1024] = {0.0};
int foo (float *x)
{
int i = 0;
for (i = 0; i < 1024; i++)
{
c[i] = (x[i] > 0.0) ? a[i] : b[i];
}
return 0;
}
/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-ifcvt-stats" } */
/* { dg-require-visibility "" } */
struct st
{
int a[1024];
int b[1024];
};
struct st s = {0};
int foo (int x)
{
int i;
struct st *p = &s;
for (i = 0; i < 1024; i++)
{
if (x > i)
p->a[i] = p->b[i];
}
return 0;
}
/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-ifcvt-stats" } */
/* { dg-require-visibility "" } */
extern int b[256], y;
void bar (int *, int);
int foo (int x, int n)
{
int i;
int a[128];
for (i = 0; i < n; i++)
{
a[i] = i;
if (x > i)
y = b[i];
}
bar (a, y);
return 0;
}
/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
......@@ -38,4 +38,4 @@ int main()
return 0;
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
......@@ -123,5 +123,5 @@ int main (void)
return main1 ();
}
/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
......@@ -15,4 +15,4 @@ void foo (int n)
}
}
/* { dg-final { scan-tree-dump-times "Move stmt to created bb" 6 "vect" { target { i?86-*-* x86_64-*-* } } } } */
/* { dg-final { scan-tree-dump-times "Move stmt to created bb" 4 "vect" { target { i?86-*-* x86_64-*-* } } } } */
......@@ -106,6 +106,8 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-loop.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-address.h"
#include "dbgcnt.h"
......@@ -718,6 +720,105 @@ hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a)
}
}
/* Return TRUE if can prove the index IDX of an array reference REF is
within array bound. Return false otherwise. */
static bool
idx_within_array_bound (tree ref, tree *idx, void *dta)
{
bool overflow;
widest_int niter, valid_niter, delta, wi_step;
tree ev, init, step;
tree low, high;
struct loop *loop = (struct loop*) dta;
/* Only support within-bound access for array references. */
if (TREE_CODE (ref) != ARRAY_REF)
return false;
/* For arrays at the end of the structure, we are not guaranteed that they
do not really extend over their declared size. However, for arrays of
size greater than one, this is unlikely to be intended. */
if (array_at_struct_end_p (ref))
return false;
ev = analyze_scalar_evolution (loop, *idx);
ev = instantiate_parameters (loop, ev);
init = initial_condition (ev);
step = evolution_part_in_loop_num (ev, loop->num);
if (!init || TREE_CODE (init) != INTEGER_CST
|| (step && TREE_CODE (step) != INTEGER_CST))
return false;
low = array_ref_low_bound (ref);
high = array_ref_up_bound (ref);
/* The case of nonconstant bounds could be handled, but it would be
complicated. */
if (TREE_CODE (low) != INTEGER_CST
|| !high || TREE_CODE (high) != INTEGER_CST)
return false;
/* Check if the intial idx is within bound. */
if (wi::to_widest (init) < wi::to_widest (low)
|| wi::to_widest (init) > wi::to_widest (high))
return false;
/* The idx is always within bound. */
if (!step || integer_zerop (step))
return true;
if (!max_loop_iterations (loop, &niter))
return false;
if (wi::to_widest (step) < 0)
{
delta = wi::to_widest (init) - wi::to_widest (low);
wi_step = -wi::to_widest (step);
}
else
{
delta = wi::to_widest (high) - wi::to_widest (init);
wi_step = wi::to_widest (step);
}
valid_niter = wi::div_floor (delta, wi_step, SIGNED, &overflow);
/* The iteration space of idx is within array bound. */
if (!overflow && niter <= valid_niter)
return true;
return false;
}
/* Return TRUE if ref is a within bound array reference. */
static bool
ref_within_array_bound (gimple *stmt, tree ref)
{
struct loop *loop = loop_containing_stmt (stmt);
gcc_assert (loop != NULL);
return for_each_index (&ref, idx_within_array_bound, loop);
}
/* Given a memory reference expression T, return TRUE if base object
it refers to is writable. The base object of a memory reference
is the main object being referenced, which is returned by function
get_base_address. */
static bool
base_object_writable (tree ref)
{
tree base_tree = get_base_address (ref);
return (base_tree
&& DECL_P (base_tree)
&& decl_binds_to_current_def_p (base_tree)
&& !TREE_READONLY (base_tree));
}
/* Return true when the memory references of STMT won't trap in the
if-converted code. There are two things that we have to check for:
......@@ -765,8 +866,13 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
if (DR_W_UNCONDITIONALLY (*master_dr))
return true;
/* If a is unconditionally accessed then ... */
if (DR_RW_UNCONDITIONALLY (*master_dr))
/* If a is unconditionally accessed then ...
Even a is conditional access, we can treat it as an unconditional
one if it's an array reference and all its index are within array
bound. */
if (DR_RW_UNCONDITIONALLY (*master_dr)
|| ref_within_array_bound (stmt, DR_REF (a)))
{
/* an unconditional read won't trap. */
if (DR_IS_READ (a))
......@@ -777,16 +883,11 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
if (base_master_dr
&& DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES);
else
{
/* or the base is know to be not readonly. */
tree base_tree = get_base_address (DR_REF (a));
if (DECL_P (base_tree)
&& decl_binds_to_current_def_p (base_tree)
&& ! TREE_READONLY (base_tree))
return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES);
}
/* or the base is known to be not readonly. */
else if (base_object_writable (DR_REF (a)))
return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES);
}
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment