tree-scalar-evolution.c (resolve_mixers): Exported.

* tree-scalar-evolution.c (resolve_mixers): Exported.
	* tree-scalar-evolution.h (resolve_mixers): Declare.
	* tree-data-ref.c (object_analysis, ptr_decl_may_alias_p,
	ptr_ptr_may_alias_p, may_alias_p, record_ptr_differ_p,
	record_record_differ_p, record_array_differ_p, array_ptr_differ_p,
	base_object_differ_p, base_addr_differ_p, analyze_array_indexes,
	init_array_ref, init_pointer_ref, analyze_indirect_ref,
	strip_conversion, analyze_offset_expr, address_analysis,
	object_analysis, analyze_offset): Removed.
	(dr_analyze_innermost, dr_analyze_indices, dr_analyze_alias,
	split_constant_offset, canonicalize_base_object_address,
	object_address_invariant_in_loop_p, disjoint_objects_p,
	dr_may_alias_p, dr_address_invariant_p): New functions.
	(create_data_ref): Use dr_analyze_innermost, dr_analyze_indices
	and dr_analyze_alias.
	(initialize_data_dependence_relation): Use dr_may_alias_p
	and object_address_invariant_in_loop_p.
	(compute_self_dependence): Handle the case when DDR_ARE_DEPENDENT (ddr)
	is chrec_dont_know.
	(find_data_references_in_stmt): Restrict the analysis of data references
	to the given loop nest.
	(find_data_references_in_loop): Made static.  Pass loop nest to
	find_data_references_in_stmt.
	(compute_data_dependences_for_loop): Use DR_VOPS.
	(free_data_ref): Free DR_VOPS.
	* tree-data-ref.h (struct first_location_in_loop): Replaced by ...
	(struct innermost_loop_behavior): ... new.
	(struct base_object_info): Replaced by ...
	(struct indices): ... new.
	(struct dr_alias): New.
	(enum data_ref_type): Removed.
	(struct data_reference): Consist of struct innermost_loop_behavior,
	struct indices and struct dr_alias.
	(DR_SET_ACCESS_FNS, DR_FREE_ACCESS_FNS): Removed.
	(DR_MEMTAG): Renamed to ...
	(DR_SYMBOL_TAG): ... this.
	(find_data_references_in_loop): Declaration removed.
	* tree-vect-analyze.c (vect_compute_data_ref_alignment): Use DR_INIT
	instead of DR_OFFSET_MISALIGNMENT.  DR_ALIGNED_TO is never NULL.
	(vect_analyze_data_refs): Use DR_SYMBOL_TAG instead of DR_MEMTAG.
	* tree-vect-transform.c (vect_create_data_ref_ptr): Ditto.

	* gcc.dg/vect/no-section-anchors-vect-69.c: Fix outcome.
	* gcc.dg/tree-ssa/loop-30.c: New test.

From-SVN: r124655
This commit is contained in:
Zdenek Dvorak 2007-05-13 19:32:06 +02:00 committed by Zdenek Dvorak
parent de5e4138e5
commit 3cb960c703
10 changed files with 611 additions and 1678 deletions

View File

@ -1,3 +1,47 @@
2007-05-13 Zdenek Dvorak <dvorakz@suse.cz>
* tree-scalar-evolution.c (resolve_mixers): Exported.
* tree-scalar-evolution.h (resolve_mixers): Declare.
* tree-data-ref.c (object_analysis, ptr_decl_may_alias_p,
ptr_ptr_may_alias_p, may_alias_p, record_ptr_differ_p,
record_record_differ_p, record_array_differ_p, array_ptr_differ_p,
base_object_differ_p, base_addr_differ_p, analyze_array_indexes,
init_array_ref, init_pointer_ref, analyze_indirect_ref,
strip_conversion, analyze_offset_expr, address_analysis,
object_analysis, analyze_offset): Removed.
(dr_analyze_innermost, dr_analyze_indices, dr_analyze_alias,
split_constant_offset, canonicalize_base_object_address,
object_address_invariant_in_loop_p, disjoint_objects_p,
dr_may_alias_p, dr_address_invariant_p): New functions.
(create_data_ref): Use dr_analyze_innermost, dr_analyze_indices
and dr_analyze_alias.
(initialize_data_dependence_relation): Use dr_may_alias_p
and object_address_invariant_in_loop_p.
(compute_self_dependence): Handle the case when DDR_ARE_DEPENDENT (ddr)
is chrec_dont_know.
(find_data_references_in_stmt): Restrict the analysis of data references
to the given loop nest.
(find_data_references_in_loop): Made static. Pass loop nest to
find_data_references_in_stmt.
(compute_data_dependences_for_loop): Use DR_VOPS.
(free_data_ref): Free DR_VOPS.
* tree-data-ref.h (struct first_location_in_loop): Replaced by ...
(struct innermost_loop_behavior): ... new.
(struct base_object_info): Replaced by ...
(struct indices): ... new.
(struct dr_alias): New.
(enum data_ref_type): Removed.
(struct data_reference): Consist of struct innermost_loop_behavior,
struct indices and struct dr_alias.
(DR_SET_ACCESS_FNS, DR_FREE_ACCESS_FNS): Removed.
(DR_MEMTAG): Renamed to ...
(DR_SYMBOL_TAG): ... this.
(find_data_references_in_loop): Declaration removed.
* tree-vect-analyze.c (vect_compute_data_ref_alignment): Use DR_INIT
instead of DR_OFFSET_MISALIGNMENT. DR_ALIGNED_TO is never NULL.
(vect_analyze_data_refs): Use DR_SYMBOL_TAG instead of DR_MEMTAG.
* tree-vect-transform.c (vect_create_data_ref_ptr): Ditto.
2007-05-13 Revital Eres <eres@il.ibm.com>
* tree-ssa-dse.c (get_use_of_stmt_lhs): New function

View File

@ -1,3 +1,8 @@
2007-05-13 Zdenek Dvorak <dvorakz@suse.cz>
* gcc.dg/vect/no-section-anchors-vect-69.c: Fix outcome.
* gcc.dg/tree-ssa/loop-30.c: New test.
2007-05-13 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/pr17141-1.c: Scan in forwprop2, xfail

View File

@ -0,0 +1,14 @@
/* PR 25371 */
/* { dg-do compile } */
/* { dg-options "-O2 -ftree-vectorize" } */
void
slow_close(int n)
{
int i;
double *mm;
for (i=0;i<2*n;i++)
for (i=0;i<2*n;i++)
*(mm+i*2*n+i) = 0;
}

View File

@ -50,7 +50,7 @@ int main1 ()
abort ();
}
/* 2. aligned on 8-bytes */
/* 2. aligned */
for (i = 3; i < N-1; i++)
{
tmp1[2].a.n[1][2][i] = 6;
@ -63,7 +63,7 @@ int main1 ()
abort ();
}
/* 3. aligned on 16-bytes */
/* 3. aligned */
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
@ -113,8 +113,5 @@ int main (void)
/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
/* Loops 1,2,4 are unaligned on targets that require 16-byte alignment.
Loops 1,4 are unaligned on targets that require 8-byte alignment (ia64). */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail ia64-*-* } } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target ia64-*-* } } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */

File diff suppressed because it is too large Load Diff

View File

@ -26,48 +26,73 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "omega.h"
/*
The first location accessed by data-ref in the loop is the address of data-ref's
base (BASE_ADDRESS) plus the initial offset from the base. We divide the initial offset
into two parts: loop invariant offset (OFFSET) and constant offset (INIT).
STEP is the stride of data-ref in the loop in bytes.
innermost_loop_behavior describes the evolution of the address of the memory
reference in the innermost enclosing loop. The address is expressed as
BASE + STEP * # of iteration, and base is further decomposed as the base
pointer (BASE_ADDRESS), loop invariant offset (OFFSET) and
constant offset (INIT). Examples, in loop nest
for (i = 0; i < 100; i++)
for (j = 3; j < 100; j++)
Example 1 Example 2
data-ref a[j].b[i][j] a + x + 16B (a is int*)
data-ref a[j].b[i][j] *(p + x + 16B + 4B * j)
First location info:
base_address &a a
offset j_0*D_j + i_0*D_i x
init C_b + C_a 16
innermost_loop_behavior
base_address &a p
offset i * D_i x
init 3 * D_j + offsetof (b) 28
step D_j 4
access_fn NULL {16, +, 1}
Base object info:
base_object a NULL
access_fn <access_fns of indexes of b> NULL
*/
struct first_location_in_loop
struct innermost_loop_behavior
{
tree base_address;
tree offset;
tree init;
tree step;
/* Access function related to first location in the loop. */
VEC(tree,heap) *access_fns;
/* Alignment information. ALIGNED_TO is set to the largest power of two
that divides OFFSET. */
tree aligned_to;
};
struct base_object_info
/* Describes the evolutions of indices of the memory reference. The indices
are indices of the ARRAY_REFs and the operands of INDIRECT_REFs.
For ARRAY_REFs, BASE_OBJECT is the reference with zeroed indices
(note that this reference does not have to be valid, if zero does not
belong to the range of the array; hence it is not recommended to use
BASE_OBJECT in any code generation). For INDIRECT_REFs, the address is
set to the loop-invariant part of the address of the object, except for
the constant offset. For the examples above,
base_object: a[0].b[0][0] *(p + x + 4B * j_0)
indices: {j_0, +, 1}_2 {16, +, 4}_2
{i_0, +, 1}_1
{j_0, +, 1}_2
*/
struct indices
{
/* The object. */
tree base_object;
/* A list of chrecs. Access functions related to BASE_OBJECT. */
/* A list of chrecs. Access functions of the indices. */
VEC(tree,heap) *access_fns;
};
enum data_ref_type {
ARRAY_REF_TYPE,
POINTER_REF_TYPE
struct dr_alias
{
/* The alias information that should be used for new pointers to this
location. SYMBOL_TAG is either a DECL or a SYMBOL_MEMORY_TAG. */
tree symbol_tag;
subvar_t subvars;
struct ptr_info_def *ptr_info;
/* The set of virtual operands corresponding to this memory reference,
serving as a description of the alias information for the memory
reference. This could be eliminated if we had alias oracle. */
bitmap vops;
};
struct data_reference
@ -75,7 +100,7 @@ struct data_reference
/* A pointer to the statement that contains this DR. */
tree stmt;
/* A pointer to the ARRAY_REF node. */
/* A pointer to the memory reference. */
tree ref;
/* Auxiliary info specific to a pass. */
@ -84,58 +109,14 @@ struct data_reference
/* True when the data reference is in RHS of a stmt. */
bool is_read;
/* First location accessed by the data-ref in the loop. */
struct first_location_in_loop first_location;
/* Behavior of the memory reference in the innermost loop. */
struct innermost_loop_behavior innermost;
/* Base object related info. */
struct base_object_info object_info;
/* Decomposition to indices for alias analysis. */
struct indices indices;
/* Aliasing information. This field represents the symbol that
should be aliased by a pointer holding the address of this data
reference. If the original data reference was a pointer
dereference, then this field contains the memory tag that should
be used by the new vector-pointer. */
tree memtag;
struct ptr_info_def *ptr_info;
subvar_t subvars;
/* Alignment information.
MISALIGNMENT is the offset of the data-reference from its base in bytes.
ALIGNED_TO is the maximum data-ref's alignment.
Example 1,
for i
for (j = 3; j < N; j++)
a[j].b[i][j] = 0;
For a[j].b[i][j], the offset from base (calculated in get_inner_reference()
will be 'i * C_i + j * C_j + C'.
We try to substitute the variables of the offset expression
with initial_condition of the corresponding access_fn in the loop.
'i' cannot be substituted, since its access_fn in the inner loop is i. 'j'
will be substituted with 3.
Example 2
for (j = 3; j < N; j++)
a[j].b[5][j] = 0;
Here the offset expression (j * C_j + C) will not contain variables after
substitution of j=3 (3*C_j + C).
Misalignment can be calculated only if all the variables can be
substituted with constants, otherwise, we record maximum possible alignment
in ALIGNED_TO. In Example 1, since 'i' cannot be substituted,
MISALIGNMENT will be NULL_TREE, and the biggest divider of C_i (a power of
2) will be recorded in ALIGNED_TO.
In Example 2, MISALIGNMENT will be the value of 3*C_j + C in bytes, and
ALIGNED_TO will be NULL_TREE.
*/
tree misalignment;
tree aligned_to;
/* The type of the data-ref. */
enum data_ref_type type;
/* Alias information for the data reference. */
struct dr_alias alias;
};
typedef struct data_reference *data_reference_p;
@ -144,37 +125,20 @@ DEF_VEC_ALLOC_P (data_reference_p, heap);
#define DR_STMT(DR) (DR)->stmt
#define DR_REF(DR) (DR)->ref
#define DR_BASE_OBJECT(DR) (DR)->object_info.base_object
#define DR_TYPE(DR) (DR)->type
#define DR_ACCESS_FNS(DR)\
(DR_TYPE(DR) == ARRAY_REF_TYPE ? \
(DR)->object_info.access_fns : (DR)->first_location.access_fns)
#define DR_BASE_OBJECT(DR) (DR)->indices.base_object
#define DR_ACCESS_FNS(DR) (DR)->indices.access_fns
#define DR_ACCESS_FN(DR, I) VEC_index (tree, DR_ACCESS_FNS (DR), I)
#define DR_NUM_DIMENSIONS(DR) VEC_length (tree, DR_ACCESS_FNS (DR))
#define DR_IS_READ(DR) (DR)->is_read
#define DR_BASE_ADDRESS(DR) (DR)->first_location.base_address
#define DR_OFFSET(DR) (DR)->first_location.offset
#define DR_INIT(DR) (DR)->first_location.init
#define DR_STEP(DR) (DR)->first_location.step
#define DR_MEMTAG(DR) (DR)->memtag
#define DR_ALIGNED_TO(DR) (DR)->aligned_to
#define DR_OFFSET_MISALIGNMENT(DR) (DR)->misalignment
#define DR_PTR_INFO(DR) (DR)->ptr_info
#define DR_SUBVARS(DR) (DR)->subvars
#define DR_SET_ACCESS_FNS(DR, ACC_FNS) \
{ \
if (DR_TYPE(DR) == ARRAY_REF_TYPE) \
(DR)->object_info.access_fns = ACC_FNS; \
else \
(DR)->first_location.access_fns = ACC_FNS; \
}
#define DR_FREE_ACCESS_FNS(DR) \
{ \
if (DR_TYPE(DR) == ARRAY_REF_TYPE) \
VEC_free (tree, heap, (DR)->object_info.access_fns); \
else \
VEC_free (tree, heap, (DR)->first_location.access_fns); \
}
#define DR_BASE_ADDRESS(DR) (DR)->innermost.base_address
#define DR_OFFSET(DR) (DR)->innermost.offset
#define DR_INIT(DR) (DR)->innermost.init
#define DR_STEP(DR) (DR)->innermost.step
#define DR_SYMBOL_TAG(DR) (DR)->alias.symbol_tag
#define DR_PTR_INFO(DR) (DR)->alias.ptr_info
#define DR_SUBVARS(DR) (DR)->alias.subvars
#define DR_VOPS(DR) (DR)->alias.vops
#define DR_ALIGNED_TO(DR) (DR)->innermost.aligned_to
enum data_dependence_direction {
dir_positive,
@ -335,8 +299,6 @@ DEF_VEC_O (data_ref_loc);
DEF_VEC_ALLOC_O (data_ref_loc, heap);
bool get_references_in_stmt (tree, VEC (data_ref_loc, heap) **);
extern tree find_data_references_in_loop (struct loop *,
VEC (data_reference_p, heap) **);
extern void compute_data_dependences_for_loop (struct loop *, bool,
VEC (data_reference_p, heap) **,
VEC (ddr_p, heap) **);

View File

@ -254,7 +254,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "params.h"
static tree analyze_scalar_evolution_1 (struct loop *, tree, tree);
static tree resolve_mixers (struct loop *, tree);
/* The cached information about a ssa name VAR, claiming that inside LOOP,
the value of VAR can be expressed as CHREC. */
@ -2408,7 +2407,7 @@ instantiate_parameters (struct loop *loop,
care about causing overflows, as long as they do not affect value
of an expression. */
static tree
tree
resolve_mixers (struct loop *loop, tree chrec)
{
htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);

View File

@ -31,6 +31,7 @@ extern void scev_reset (void);
extern void scev_finalize (void);
extern tree analyze_scalar_evolution (struct loop *, tree);
extern tree instantiate_parameters (struct loop *, tree);
extern tree resolve_mixers (struct loop *, tree);
extern void gather_stats_on_scev_database (void);
extern void scev_analysis (void);
unsigned int scev_const_prop (void);

View File

@ -1130,15 +1130,14 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
/* Initialize misalignment to unknown. */
DR_MISALIGNMENT (dr) = -1;
misalign = DR_OFFSET_MISALIGNMENT (dr);
misalign = DR_INIT (dr);
aligned_to = DR_ALIGNED_TO (dr);
base_addr = DR_BASE_ADDRESS (dr);
base = build_fold_indirect_ref (base_addr);
vectype = STMT_VINFO_VECTYPE (stmt_info);
alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
|| !misalign)
if (tree_int_cst_compare (aligned_to, alignment) < 0)
{
if (vect_print_dump_info (REPORT_DETAILS))
{
@ -2044,7 +2043,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
}
return false;
}
if (!DR_MEMTAG (dr))
if (!DR_SYMBOL_TAG (dr))
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
{

View File

@ -298,7 +298,7 @@ vect_create_data_ref_ptr (tree stmt,
/** (2) Add aliasing information to the new vector-pointer:
(The points-to info (DR_PTR_INFO) may be defined later.) **/
tag = DR_MEMTAG (dr);
tag = DR_SYMBOL_TAG (dr);
gcc_assert (tag);
/* If tag is a variable (and NOT_A_TAG) than a new symbol memory