mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-22 21:51:36 +08:00
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:
parent
de5e4138e5
commit
3cb960c703
@ -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
|
||||
|
@ -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
|
||||
|
14
gcc/testsuite/gcc.dg/tree-ssa/loop-30.c
Normal file
14
gcc/testsuite/gcc.dg/tree-ssa/loop-30.c
Normal 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;
|
||||
}
|
@ -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" } } */
|
||||
|
2036
gcc/tree-data-ref.c
2036
gcc/tree-data-ref.c
File diff suppressed because it is too large
Load Diff
@ -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) **);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user