Commit be8c1c8c by Bin Cheng Committed by Bin Cheng

tree-ssa-loop-ivopts.c (alloc_iv): Lower address expressions.


	* tree-ssa-loop-ivopts.c (alloc_iv): Lower address expressions.
	* tree-affine.c (get_inner_reference_aff): Return base.
	* tree-affine.h (get_inner_reference_aff): Change prototype.

	* gcc.dg/tree-ssa/loop-2.c: Refine check condition.
	* gcc.dg/tree-ssa/ivopt_infer_2.c: Ditto.
	* gcc.dg/tree-ssa/ivopt_mult_3.c: Ditto.

From-SVN: r204497
parent 196bb323
2013-11-07 Bin Cheng <bin.cheng@arm.com>
* tree-ssa-loop-ivopts.c (alloc_iv): Lower address expressions.
* tree-affine.c (get_inner_reference_aff): Return base.
* tree-affine.h (get_inner_reference_aff): Change prototype.
2013-11-06 Tobias Burnus <burnus@net-b.de> 2013-11-06 Tobias Burnus <burnus@net-b.de>
* doc/invoke.texi (Wdate-time): Fix typo. * doc/invoke.texi (Wdate-time): Fix typo.
2013-11-07 Bin Cheng <bin.cheng@arm.com>
* gcc.dg/tree-ssa/loop-2.c: Refine check condition.
* gcc.dg/tree-ssa/ivopt_infer_2.c: Ditto.
* gcc.dg/tree-ssa/ivopt_mult_3.c: Ditto.
2013-11-06 DJ Delorie <dj@redhat.com> 2013-11-06 DJ Delorie <dj@redhat.com>
* gcc.dg/mismatch-decl-1.c: New test. * gcc.dg/mismatch-decl-1.c: New test.
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
extern char a[]; extern char a[];
/* Can not infer loop iteration from array -- exit test can not be replaced. */ /* Can not infer loop iteration from array -- exit test can not be
replaced by the array address. */
void foo (unsigned int i_width, TYPE dst) void foo (unsigned int i_width, TYPE dst)
{ {
unsigned long long i = 0; unsigned long long i = 0;
...@@ -21,5 +22,5 @@ void foo (unsigned int i_width, TYPE dst) ...@@ -21,5 +22,5 @@ void foo (unsigned int i_width, TYPE dst)
} }
} }
/* { dg-final { scan-tree-dump-times "Replacing" 0 "ivopts"} } */ /* { dg-final { scan-tree-dump-times "\[^:\]*if \\(.*j_\[0-9\]+.*\\)" 1 "ivopts"} } */
/* { dg-final { cleanup-tree-dump "ivopts" } } */ /* { dg-final { cleanup-tree-dump "ivopts" } } */
...@@ -18,5 +18,5 @@ long foo(long* p, long* p2, int N1, int N2) ...@@ -18,5 +18,5 @@ long foo(long* p, long* p2, int N1, int N2)
return s; return s;
} }
/* { dg-final { scan-tree-dump-times "Replacing" 1 "ivopts"} } */ /* { dg-final { scan-tree-dump-times "Replacing exit test: if \\(.*p2.*\\)" 1 "ivopts"} } */
/* { dg-final { cleanup-tree-dump "ivopts" } } */ /* { dg-final { cleanup-tree-dump "ivopts" } } */
...@@ -27,7 +27,7 @@ void xxx(void) ...@@ -27,7 +27,7 @@ void xxx(void)
/* { dg-final { scan-tree-dump-times " \\* \[^\\n\\r\]*=" 0 "optimized" } } */ /* { dg-final { scan-tree-dump-times " \\* \[^\\n\\r\]*=" 0 "optimized" } } */
/* { dg-final { scan-tree-dump-times "\[^\\n\\r\]*= \\* " 0 "optimized" } } */ /* { dg-final { scan-tree-dump-times "\[^\\n\\r\]*= \\* " 0 "optimized" } } */
/* { dg-final { scan-tree-dump-times "MEM" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "MEM\\\[base" 1 "optimized" } } */
/* 17 * iter should be strength reduced. */ /* 17 * iter should be strength reduced. */
......
...@@ -874,10 +874,11 @@ debug_aff (aff_tree *val) ...@@ -874,10 +874,11 @@ debug_aff (aff_tree *val)
fprintf (stderr, "\n"); fprintf (stderr, "\n");
} }
/* Returns address of the reference REF in ADDR. The size of the accessed /* Computes address of the reference REF in ADDR. The size of the accessed
location is stored to SIZE. */ location is stored to SIZE. Returns the ultimate containing object to
which REF refers. */
void tree
get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size) get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size)
{ {
HOST_WIDE_INT bitsize, bitpos; HOST_WIDE_INT bitsize, bitpos;
...@@ -904,6 +905,8 @@ get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size) ...@@ -904,6 +905,8 @@ get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size)
aff_combination_add (addr, &tmp); aff_combination_add (addr, &tmp);
*size = double_int::from_shwi ((bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT); *size = double_int::from_shwi ((bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
return base;
} }
/* Returns true if a region of size SIZE1 at position 0 and a region of /* Returns true if a region of size SIZE1 at position 0 and a region of
......
...@@ -74,7 +74,7 @@ bool aff_combination_constant_multiple_p (aff_tree *, aff_tree *, double_int *); ...@@ -74,7 +74,7 @@ bool aff_combination_constant_multiple_p (aff_tree *, aff_tree *, double_int *);
void aff_combination_expand (aff_tree *, struct pointer_map_t **); void aff_combination_expand (aff_tree *, struct pointer_map_t **);
void tree_to_aff_combination_expand (tree, tree, aff_tree *, void tree_to_aff_combination_expand (tree, tree, aff_tree *,
struct pointer_map_t **); struct pointer_map_t **);
void get_inner_reference_aff (tree, aff_tree *, double_int *); tree get_inner_reference_aff (tree, aff_tree *, double_int *);
void free_affine_expand_cache (struct pointer_map_t **); void free_affine_expand_cache (struct pointer_map_t **);
bool aff_comb_cannot_overlap_p (aff_tree *, double_int, double_int); bool aff_comb_cannot_overlap_p (aff_tree *, double_int, double_int);
......
...@@ -924,11 +924,30 @@ determine_base_object (tree expr) ...@@ -924,11 +924,30 @@ determine_base_object (tree expr)
static struct iv * static struct iv *
alloc_iv (tree base, tree step) alloc_iv (tree base, tree step)
{ {
tree base_object = base;
struct iv *iv = XCNEW (struct iv); struct iv *iv = XCNEW (struct iv);
gcc_assert (step != NULL_TREE); gcc_assert (step != NULL_TREE);
/* Lower all address expressions except ones with DECL_P as operand.
By doing this:
1) More accurate cost can be computed for address expressions;
2) Duplicate candidates won't be created for bases in different
forms, like &a[0] and &a. */
STRIP_NOPS (base_object);
if (TREE_CODE (base_object) == ADDR_EXPR
&& !DECL_P (TREE_OPERAND (base_object, 0)))
{
aff_tree comb;
double_int size;
base_object = get_inner_reference_aff (TREE_OPERAND (base_object, 0),
&comb, &size);
gcc_assert (base_object != NULL_TREE);
base_object = build_fold_addr_expr (base_object);
base = fold_convert (TREE_TYPE (base), aff_combination_to_tree (&comb));
}
iv->base = base; iv->base = base;
iv->base_object = determine_base_object (base); iv->base_object = determine_base_object (base_object);
iv->step = step; iv->step = step;
iv->biv_p = false; iv->biv_p = false;
iv->have_use_for = false; iv->have_use_for = 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