diff options
author | dorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-29 16:10:22 +0000 |
---|---|---|
committer | dorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-29 16:10:22 +0000 |
commit | abb91f0ba1e7b43d41e0b5f6668249d13556303f (patch) | |
tree | 3b6e04f8be928ef4cb17b708c1898650d3020a60 /gcc/tree-vect-transform.c | |
parent | f1c94b5580c2833b4e24cd14de9bcc246b209269 (diff) | |
download | gcc-abb91f0ba1e7b43d41e0b5f6668249d13556303f.tar.gz |
* 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".
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97164 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-transform.c')
-rw-r--r-- | gcc/tree-vect-transform.c | 152 |
1 files changed, 117 insertions, 35 deletions
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c index 5dd9efecdbc..4940f2d9419 100644 --- a/gcc/tree-vect-transform.c +++ b/gcc/tree-vect-transform.c @@ -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 |