Commit 8bb46326 by Dorit Nuzman

tree-ssanames.c (duplicate_ssa_name_ptr_info): New function.

        * tree-ssanames.c (duplicate_ssa_name_ptr_info): New function.
        (duplicate_ssa_name): Call duplicate_ssa_name_ptr_info.
        * tree-vect-analyze.c (vect_object_analysis): additional parm
        pass back a "struct ptr_info_def *" with the points-to info.
        (vect_analyze_data_refs): set the STMT_VINFO_PTR_INFO for the
        statement using info returned from vect_object_analysis.
        * tree-vect-transform.c (update_vuses_to_preheader): New function.
        (vect_create_data_ref_ptr): Remove updates to vars_to_rename
        for virtual uses and defs when creating a replacement vector
        reference.  Call duplicate_ssa_name_ptr_info to define points-to
        info for vector pointer replacement using STMT_VINFO_PTR_INFO.
        (vectorizable_store): copy_virtual_operands and update
        definition statements.
        (vectorizable_load): copy_virtual_operands.  Remove call to
        mark_call_clobbered_vars_to_rename for call to "const" builtin.
        * tree-vectorizer.c (vectorize_loops): Remove calls to
        rewrite_into_ssa and bitmap_clear (vars_to_rename).
        (new_stmt_vec_info): initialize STMT_VINFO_PTR_INFO for stmt.
        * tree-vectorizer.h (_stmt_vec_info): add field ptr_info and
        define macro STMT_VINFO_PTR_INFO for use in accessing.
        * tree.h add export of duplicate_ssa_name_ptr_info.
        * rs6000.c (altivec_init_builtins): Declare builtin function
        __builtin_altivec_mask_for_load to be "const".

From-SVN: r97164
parent 1a612e0a
2005-03-29 Keith Besaw <kbesaw@us.ibm.com>
* tree-ssanames.c (duplicate_ssa_name_ptr_info): New function.
(duplicate_ssa_name): Call duplicate_ssa_name_ptr_info.
* tree-vect-analyze.c (vect_object_analysis): additional parm
pass back a "struct ptr_info_def *" with the points-to info.
(vect_analyze_data_refs): set the STMT_VINFO_PTR_INFO for the
statement using info returned from vect_object_analysis.
* tree-vect-transform.c (update_vuses_to_preheader): New function.
(vect_create_data_ref_ptr): Remove updates to vars_to_rename
for virtual uses and defs when creating a replacement vector
reference. Call duplicate_ssa_name_ptr_info to define points-to
info for vector pointer replacement using STMT_VINFO_PTR_INFO.
(vectorizable_store): copy_virtual_operands and update
definition statements.
(vectorizable_load): copy_virtual_operands. Remove call to
mark_call_clobbered_vars_to_rename for call to "const" builtin.
* tree-vectorizer.c (vectorize_loops): Remove calls to
rewrite_into_ssa and bitmap_clear (vars_to_rename).
(new_stmt_vec_info): initialize STMT_VINFO_PTR_INFO for stmt.
* tree-vectorizer.h (_stmt_vec_info): add field ptr_info and
define macro STMT_VINFO_PTR_INFO for use in accessing.
* tree.h add export of duplicate_ssa_name_ptr_info.
* rs6000.c (altivec_init_builtins): Declare builtin function
__builtin_altivec_mask_for_load to be "const".
2005-03-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/20622
......
......@@ -7665,9 +7665,11 @@ altivec_init_builtins (void)
targetm.vectorize.builtin_mask_for_load. */
decl = lang_hooks.builtin_function ("__builtin_altivec_mask_for_load",
v16qi_ftype_long_pcvoid,
ALTIVEC_BUILTIN_MASK_FOR_LOAD,
BUILT_IN_MD, NULL, NULL_TREE);
v16qi_ftype_long_pcvoid,
ALTIVEC_BUILTIN_MASK_FOR_LOAD,
BUILT_IN_MD, NULL,
tree_cons (get_identifier ("const"),
NULL_TREE, NULL_TREE));
/* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
altivec_builtin_mask_for_load = decl;
}
......
2005-03-29 Keith Besaw <kbesaw@us.ibm.com>
* f95-lang.c (builtin_function): Process the attrs parameter
and apply the "const" attribute to the builtin if found.
2005-03-27 Steven G. Kargl <kargls@comcast.net>
* intrinsic.texi: Document AIMAG, AINT, ALL
......
......@@ -680,7 +680,7 @@ builtin_function (const char *name,
int function_code,
enum built_in_class class,
const char *library_name,
tree attrs ATTRIBUTE_UNUSED)
tree attrs)
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
......@@ -691,6 +691,17 @@ builtin_function (const char *name,
pushdecl (decl);
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = function_code;
/* Possibly apply some default attributes to this built-in function. */
if (attrs)
{
/* FORNOW the only supported attribute is "const". If others need
to be supported then see the more general solution in procedure
builtin_function in c-decl.c */
if (lookup_attribute ( "const", attrs ))
TREE_READONLY (decl) = 1;
}
return decl;
}
......
2005-03-29 Dorit Naishlos <dorit@il.ibm.com>
* gfortran.dg/vect: New directory.
* gfortran.dg/vect/vect.exp: New.
* gfortran.dg/vect/vect-1.f90: New test.
* gfortran.dg/vect/vect-2.f90: New test.
* gfortran.dg/vect/vect-3.f90: New test.
* gfortran.dg/vect/vect-4.f90: New test.
* gfortran.dg/vect/vect-5.f90: New test.
2005-03-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/20622
......
! { dg-do compile }
! { dg-require-effective-target vect_float }
DIMENSION A(1000000), B(1000000), C(1000000)
READ*, X, Y
A = LOG(X); B = LOG(Y); C = A + B
PRINT*, C(500000)
END
! { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } }
! { dg-do compile }
! { dg-require-effective-target vect_float }
SUBROUTINE FOO(A, B, C)
DIMENSION A(1000000), B(1000000), C(1000000)
READ*, X, Y
A = LOG(X); B = LOG(Y); C = A + B
PRINT*, C(500000)
END
! { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_align } } }
! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail vect_no_align } } }
! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } }
! { dg-do compile }
! { dg-require-effective-target vect_float }
SUBROUTINE SAXPY(X, Y, A, N)
DIMENSION X(N), Y(N)
Y = Y + A * X
END
! fail to vectorize due to failure to compute number of iterations (PR tree-optimization/18527)
! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail *-*-* } } }
! { dg-do compile }
! { dg-require-effective-target vect_float }
SUBROUTINE SAXPY(X, Y, A)
DIMENSION X(64), Y(64)
Y = Y + A * X
END
! fail to vectorize until the patch that ignores dependence-distance 0 is
! brought from autovect.
! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail *-*-* } } }
! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail *-*-* } } }
! { dg-require-effective-target vect_int }
Subroutine foo (N, M)
Integer N
Integer M
integer A(8,16)
integer B(8)
B = (/ 2, 3, 5, 7, 11, 13, 17, 23 /)
! Unknown loop bound. J depends on I.
do I = 1, N
do J = I, M
A(J,2) = B(J)
end do
end do
do I = 1, N
do J = I, M
if (A(J,2) /= B(J)) then
call abort ()
endif
end do
end do
Return
end
program main
Call foo (16, 8)
stop
end
! { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } }
! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } }
! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } }
# Copyright (C) 1997, 2004 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# GCC testsuite that uses the `dg.exp' driver.
# Load support procs.
load_lib gfortran-dg.exp
load_lib target-supports.exp
# Set up flags used for tests that don't specify options.
set DEFAULT_VECTCFLAGS ""
# These flags are used for all targets.
lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" \
"-ftree-vectorizer-verbose=3" "-fdump-tree-vect-stats"
# If the target system supports vector instructions, the default action
# for a test is 'run', otherwise it's 'compile'. Save current default.
# Executing vector instructions on a system without hardware vector support
# is also disabled by a call to check_vect, but disabling execution here is
# more efficient.
global dg-do-what-default
set save-dg-do-what-default ${dg-do-what-default}
# Skip these tests for targets that do not support generating vector
# code. Set additional target-dependent vector flags, which can be
# overridden by using dg-options in individual tests.
if [istarget "powerpc*-*-*"] {
# If there are powerpc targets to skip, do it here.
lappend DEFAULT_VECTCFLAGS "-maltivec"
if [check_vmx_hw_available] {
set dg-do-what-default run
} else {
if [is-effective-target ilp32] {
# Specify a cpu that supports VMX for compile-only tests.
lappend DEFAULT_VECTCFLAGS "-mcpu=7400"
}
set dg-do-what-default compile
}
} elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
lappend DEFAULT_VECTCFLAGS "-msse2"
set dg-do-what-default run
} elseif [istarget "mipsisa64*-*-*"] {
lappend DEFAULT_VECTCFLAGS "-mpaired-single"
set dg-do-what-default run
} elseif [istarget "sparc*-*-*"] {
lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis"
set dg-do-what-default run
} elseif [istarget "alpha*-*-*"] {
lappend DEFAULT_VECTCFLAGS "-mmax"
if [check_alpha_max_hw_available] {
set dg-do-what-default run
} else {
set dg-do-what-default compile
}
} elseif [istarget "ia64-*-*"] {
set dg-do-what-default run
} else {
return
}
# Return 1 if the effective target is LP64 or if the effective target
# does not support a vector alignment mechanism.
proc check_effective_target_lp64_or_vect_no_align { } {
if { [is-effective-target lp64]
|| [is-effective-target vect_no_align] } {
set answer 1
} else {
set answer 0
}
return $answer
}
# Initialize `dg'.
dg-init
# Main loop.
gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95} ]] $DEFAULT_VECTCFLAGS
# Clean up.
set dg-do-what-default ${save-dg-do-what-default}
# All done.
dg-finish
......@@ -279,22 +279,38 @@ duplicate_ssa_name (tree name, tree stmt)
{
tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
if (old_ptr_info)
duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
return new_name;
}
/* Creates a duplicate of the ptr_info_def at PTR_INFO for use by
the ssa name NAME. */
void
duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
{
struct ptr_info_def *new_ptr_info;
if (!old_ptr_info)
return new_name;
gcc_assert (POINTER_TYPE_P (TREE_TYPE (name)));
gcc_assert (!SSA_NAME_PTR_INFO (name));
if (!ptr_info)
return;
new_ptr_info = ggc_alloc (sizeof (struct ptr_info_def));
*new_ptr_info = *old_ptr_info;
*new_ptr_info = *ptr_info;
if (old_ptr_info->pt_vars)
if (ptr_info->pt_vars)
{
new_ptr_info->pt_vars = BITMAP_GGC_ALLOC ();
bitmap_copy (new_ptr_info->pt_vars, old_ptr_info->pt_vars);
bitmap_copy (new_ptr_info->pt_vars, ptr_info->pt_vars);
}
SSA_NAME_PTR_INFO (new_name) = new_ptr_info;
return new_name;
SSA_NAME_PTR_INFO (name) = new_ptr_info;
}
......
......@@ -71,7 +71,8 @@ static bool vect_base_addr_differ_p (struct data_reference *,
struct data_reference *drb, bool *);
static tree vect_object_analysis (tree, tree, bool, tree,
struct data_reference **, tree *, tree *,
tree *, bool *, tree *, subvar_t *);
tree *, bool *, tree *, struct ptr_info_def **,
subvar_t *);
static tree vect_address_analysis (tree, tree, bool, tree,
struct data_reference *, tree *, tree *,
tree *, bool *);
......@@ -1476,6 +1477,7 @@ vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype,
tree oprnd0, oprnd1, base_address, offset_expr, base_addr0, base_addr1;
tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
tree dummy;
struct ptr_info_def *dummy1;
subvar_t dummy2;
switch (TREE_CODE (expr))
......@@ -1529,7 +1531,7 @@ vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype,
base_address = vect_object_analysis (TREE_OPERAND (expr, 0), stmt,
is_read, vectype, &dr, offset,
misalign, step, base_aligned,
&dummy, &dummy2);
&dummy, &dummy1, &dummy2);
return base_address;
case SSA_NAME:
......@@ -1608,6 +1610,7 @@ vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype,
STEP - evolution of the DR_REF in the loop
BASE_ALIGNED - indicates if BASE is aligned
MEMTAG - memory tag for aliasing purposes
PTR_INFO - NULL or points-to aliasing info from a pointer SSA_NAME
SUBVAR - Sub-variables of the variable
If something unexpected is encountered (an unsupported form of data-ref),
......@@ -1618,7 +1621,7 @@ vect_object_analysis (tree memref, tree stmt, bool is_read,
tree vectype, struct data_reference **dr,
tree *offset, tree *misalign, tree *step,
bool *base_aligned, tree *memtag,
subvar_t *subvars)
struct ptr_info_def **ptr_info, subvar_t *subvars)
{
tree base = NULL_TREE, base_address = NULL_TREE;
tree object_offset = ssize_int (0), object_misalign = ssize_int (0);
......@@ -1635,6 +1638,8 @@ vect_object_analysis (tree memref, tree stmt, bool is_read,
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
struct data_reference *ptr_dr = NULL;
tree access_fn, evolution_part, address_to_analyze;
*ptr_info = NULL;
/* Part 1: */
/* Case 1. handled_component_p refs. */
......@@ -1722,9 +1727,13 @@ vect_object_analysis (tree memref, tree stmt, bool is_read,
/* Part 1: Case 3. INDIRECT_REFs. */
else if (TREE_CODE (memref) == INDIRECT_REF)
{
{
tree ptr_ref = TREE_OPERAND (memref, 0);
if (TREE_CODE (ptr_ref) == SSA_NAME)
*ptr_info = SSA_NAME_PTR_INFO (ptr_ref);
/* 3.1 get the access function. */
access_fn = analyze_scalar_evolution (loop, TREE_OPERAND (memref, 0));
access_fn = analyze_scalar_evolution (loop, ptr_ref);
if (!access_fn)
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
......@@ -1849,7 +1858,7 @@ vect_object_analysis (tree memref, tree stmt, bool is_read,
Call get_inner_reference for refs handled in this function.
Call vect_addr_analysis(addr) to analyze pointer type expressions.
Set ref_stmt.base, ref_stmt.initial_offset, ref_stmt.alignment,
ref_stmt.memtag and ref_stmt.step accordingly.
ref_stmt.memtag, ref_stmt.ptr_info and ref_stmt.step accordingly.
2- vect_analyze_dependences(): apply dependence testing using ref_stmt.DR
3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
......@@ -1887,6 +1896,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
tree memref = NULL;
tree scalar_type, vectype;
tree base, offset, misalign, step, tag;
struct ptr_info_def *ptr_info;
bool base_aligned;
subvar_t subvars = NULL;
......@@ -1952,7 +1962,8 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
dr = NULL;
base = vect_object_analysis (memref, stmt, is_read, vectype, &dr,
&offset, &misalign, &step,
&base_aligned, &tag, &subvars);
&base_aligned, &tag, &ptr_info,
&subvars);
if (!base)
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
......@@ -1969,6 +1980,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
STMT_VINFO_VECT_MISALIGNMENT (stmt_info) = misalign;
STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info) = base_aligned;
STMT_VINFO_MEMTAG (stmt_info) = tag;
STMT_VINFO_PTR_INFO (stmt_info) = ptr_info;
STMT_VINFO_SUBVARS (stmt_info) = subvars;
STMT_VINFO_VECTYPE (stmt_info) = vectype;
VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
......
......@@ -57,6 +57,7 @@ static tree vect_get_vec_def_for_operand (tree, tree);
static tree vect_init_vector (tree, tree);
static void vect_finish_stmt_generation
(tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
static void update_vuses_to_preheader (tree, struct loop*);
/* Utility function dealing with loop peeling (not peeling itself). */
static void vect_generate_tmps_on_preheader
......@@ -304,11 +305,6 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
tree vect_ptr_type;
tree vect_ptr;
tree tag;
v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
vuse_optype vuses = STMT_VUSE_OPS (stmt);
int nvuses, nv_may_defs, nv_must_defs;
int i;
tree new_temp;
tree vec_stmt;
tree new_stmt_list = NULL_TREE;
......@@ -348,38 +344,14 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
add_referenced_tmp_var (vect_ptr);
/** (2) Handle aliasing information of the new vector-pointer: **/
/** (2) Add aliasing information to the new vector-pointer:
(The points-to info (SSA_NAME_PTR_INFO) may be defined later.) **/
tag = STMT_VINFO_MEMTAG (stmt_info);
gcc_assert (tag);
get_var_ann (vect_ptr)->type_mem_tag = tag;
get_var_ann (vect_ptr)->subvars = STMT_VINFO_SUBVARS (stmt_info);
/* Mark for renaming all aliased variables
(i.e, the may-aliases of the type-mem-tag). */
nvuses = NUM_VUSES (vuses);
nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
for (i = 0; i < nvuses; i++)
{
tree use = VUSE_OP (vuses, i);
if (TREE_CODE (use) == SSA_NAME)
bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (use))->uid);
}
for (i = 0; i < nv_may_defs; i++)
{
tree def = V_MAY_DEF_RESULT (v_may_defs, i);
if (TREE_CODE (def) == SSA_NAME)
bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
}
for (i = 0; i < nv_must_defs; i++)
{
tree def = V_MUST_DEF_RESULT (v_must_defs, i);
if (TREE_CODE (def) == SSA_NAME)
bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
}
/** (3) Calculate the initial address the vector-pointer, and set
the vector-pointer to point to it before the loop: **/
......@@ -405,7 +377,13 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
/** (4) Handle the updating of the vector-pointer inside the loop: **/
if (only_init) /* No update in loop is required. */
return vect_ptr_init;
{
/* Copy the points-to information if it exists. */
if (STMT_VINFO_PTR_INFO (stmt_info))
duplicate_ssa_name_ptr_info (vect_ptr_init,
STMT_VINFO_PTR_INFO (stmt_info));
return vect_ptr_init;
}
idx = vect_create_index_for_vector_ref (loop_vinfo);
......@@ -436,6 +414,9 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
data_ref_ptr = TREE_OPERAND (vec_stmt, 0);
/* Copy the points-to information if it exists. */
if (STMT_VINFO_PTR_INFO (stmt_info))
duplicate_ssa_name_ptr_info (data_ref_ptr, STMT_VINFO_PTR_INFO (stmt_info));
return data_ref_ptr;
}
......@@ -865,6 +846,8 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
enum machine_mode vec_mode;
tree dummy;
enum dr_alignment_support alignment_support_cheme;
v_may_def_optype v_may_defs;
int nv_may_defs, i;
/* Is vectorizable store? */
......@@ -922,6 +905,20 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
*vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1);
vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
/* Copy the V_MAY_DEFS representing the aliasing of the original array
element's definition to the vector's definition then update the
defining statement. The original is being deleted so the same
SSA_NAMEs can be used. */
copy_virtual_operands (*vec_stmt, stmt);
v_may_defs = STMT_V_MAY_DEF_OPS (*vec_stmt);
nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
for (i = 0; i < nv_may_defs; i++)
{
tree ssa_name = V_MAY_DEF_RESULT (v_may_defs, i);
SSA_NAME_DEF_STMT (ssa_name) = *vec_stmt;
}
return true;
}
......@@ -1023,6 +1020,7 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
new_temp = make_ssa_name (vec_dest, new_stmt);
TREE_OPERAND (new_stmt, 0) = new_temp;
vect_finish_stmt_generation (stmt, new_stmt, bsi);
copy_virtual_operands (new_stmt, stmt);
}
else if (alignment_support_cheme == dr_unaligned_software_pipeline)
{
......@@ -1060,6 +1058,8 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
gcc_assert (!new_bb);
msq_init = TREE_OPERAND (new_stmt, 0);
copy_virtual_operands (new_stmt, stmt);
update_vuses_to_preheader (new_stmt, loop);
/* <2> Create lsq = *(floor(p2')) in the loop */
......@@ -1074,6 +1074,7 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
TREE_OPERAND (new_stmt, 0) = new_temp;
vect_finish_stmt_generation (stmt, new_stmt, bsi);
lsq = TREE_OPERAND (new_stmt, 0);
copy_virtual_operands (new_stmt, stmt);
/* <3> */
......@@ -1092,9 +1093,12 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
gcc_assert (!new_bb);
magic = TREE_OPERAND (new_stmt, 0);
/* Since we have just created a CALL_EXPR, we may need to
rename call-clobbered variables. */
mark_call_clobbered_vars_to_rename ();
/* The result of the CALL_EXPR to this builtin is determined from
the value of the parameter and no global variables are touched
which makes the builtin a "const" function. Requiring the
builtin to have the "const" attribute makes it unnecessary
to call mark_call_clobbered_vars_to_rename. */
gcc_assert (TREE_READONLY (builtin_decl));
}
else
{
......@@ -1268,6 +1272,84 @@ vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo,
}
/* Function update_vuses_to_preheader.
Input:
STMT - a statement with potential VUSEs.
LOOP - the loop whose preheader will contain STMT.
It's possible to vectorize a loop even though an SSA_NAME from a VUSE
appears to be defined in a V_MAY_DEF in another statement in a loop.
One such case is when the VUSE is at the dereference of a __restricted__
pointer in a load and the V_MAY_DEF is at the dereference of a different
__restricted__ pointer in a store. Vectorization may result in
copy_virtual_uses being called to copy the problematic VUSE to a new
statement that is being inserted in the loop preheader. This procedure
is called to change the SSA_NAME in the new statement's VUSE from the
SSA_NAME updated in the loop to the related SSA_NAME available on the
path entering the loop.
When this function is called, we have the following situation:
# vuse <name1>
S1: vload
do {
# name1 = phi < name0 , name2>
# vuse <name1>
S2: vload
# name2 = vdef <name1>
S3: vstore
}while...
Stmt S1 was created in the loop preheader block as part of misaligned-load
handling. This function fixes the name of the vuse of S1 from 'name1' to
'name0'. */
static void
update_vuses_to_preheader (tree stmt, struct loop *loop)
{
basic_block header_bb = loop->header;
edge preheader_e = loop_preheader_edge (loop);
vuse_optype vuses = STMT_VUSE_OPS (stmt);
int nvuses = NUM_VUSES (vuses);
int i;
for (i = 0; i < nvuses; i++)
{
tree ssa_name = VUSE_OP (vuses, i);
tree def_stmt = SSA_NAME_DEF_STMT (ssa_name);
tree name_var = SSA_NAME_VAR (ssa_name);
basic_block bb = bb_for_stmt (def_stmt);
/* For a use before any definitions, def_stmt is a NOP_EXPR. */
if (!IS_EMPTY_STMT (def_stmt)
&& flow_bb_inside_loop_p (loop, bb))
{
/* If the block containing the statement defining the SSA_NAME
is in the loop then it's necessary to find the definition
outside the loop using the PHI nodes of the header. */
tree phi;
bool updated = false;
for (phi = phi_nodes (header_bb); phi; phi = TREE_CHAIN (phi))
{
if (SSA_NAME_VAR (PHI_RESULT (phi)) == name_var)
{
SET_VUSE_OP (vuses, i,
PHI_ARG_DEF (phi, preheader_e->dest_idx));
updated = true;
break;
}
}
gcc_assert (updated);
}
}
}
/* Function vect_update_ivs_after_vectorizer.
"Advance" the induction variables of LOOP to the value they should take
......
......@@ -1167,6 +1167,7 @@ new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
STMT_VINFO_VEC_STMT (res) = NULL;
STMT_VINFO_DATA_REF (res) = NULL;
STMT_VINFO_MEMTAG (res) = NULL;
STMT_VINFO_PTR_INFO (res) = NULL;
STMT_VINFO_SUBVARS (res) = NULL;
STMT_VINFO_VECT_DR_BASE_ADDRESS (res) = NULL;
STMT_VINFO_VECT_INIT_OFFSET (res) = NULL_TREE;
......@@ -1618,7 +1619,5 @@ vectorize_loops (struct loops *loops)
loop->aux = NULL;
}
rewrite_into_ssa (false);
rewrite_into_loop_closed_ssa (NULL); /* FORNOW */
bitmap_clear (vars_to_rename);
}
......@@ -178,6 +178,7 @@ typedef struct _stmt_vec_info {
/* Aliasing information. */
tree memtag;
struct ptr_info_def *ptr_info;
subvar_t subvars;
/** The following fields are used to store the information about
......@@ -220,7 +221,8 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt
#define STMT_VINFO_DATA_REF(S) (S)->data_ref_info
#define STMT_VINFO_MEMTAG(S) (S)->memtag
#define STMT_VINFO_SUBVARS(S) (S)->subvars
#define STMT_VINFO_PTR_INFO(S) (S)->ptr_info
#define STMT_VINFO_SUBVARS(S) (S)->subvars
#define STMT_VINFO_VECT_DR_BASE_ADDRESS(S)(S)->base_address
#define STMT_VINFO_VECT_INIT_OFFSET(S) (S)->initial_offset
#define STMT_VINFO_VECT_STEP(S) (S)->step
......
......@@ -2801,6 +2801,7 @@ extern void init_ssanames (void);
extern void fini_ssanames (void);
extern tree make_ssa_name (tree, tree);
extern tree duplicate_ssa_name (tree, tree);
extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
extern void release_ssa_name (tree);
extern void release_defs (tree);
extern void replace_ssa_name_symbol (tree, tree);
......
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