diff options
author | Ira Rosen <irar@il.ibm.com> | 2004-12-29 13:11:58 +0000 |
---|---|---|
committer | Dorit Nuzman <dorit@gcc.gnu.org> | 2004-12-29 13:11:58 +0000 |
commit | 6e611d9276d1c7d278be5a47c09d3cab6b34fbf8 (patch) | |
tree | 40c4ff29ae30e8df4b47dd1e6b7ca71e616c731f | |
parent | 5249b4b0ce7cccf9299f7911eb8919b3006f90a1 (diff) | |
download | gcc-6e611d9276d1c7d278be5a47c09d3cab6b34fbf8.zip gcc-6e611d9276d1c7d278be5a47c09d3cab6b34fbf8.tar.gz gcc-6e611d9276d1c7d278be5a47c09d3cab6b34fbf8.tar.bz2 |
re PR tree-optimization/18179 (vectorizer: wrong alignment/step/initial-address computed for struct accesses)
2004-12-29 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/18179
* tree-vectorizer.c (vect_get_symbl_and_dr): Reorganize. Add memtag
retrieval.
(vect_analyze_data_refs): Remove memtag retrieval.
From-SVN: r92700
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/tree-vectorizer.c | 280 |
2 files changed, 116 insertions, 171 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d89c892..984db9a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-12-29 Ira Rosen <irar@il.ibm.com> + + PR tree-optimization/18179 + * tree-vectorizer.c (vect_get_symbl_and_dr): Reorganize. Add memtag + retrieval. + (vect_analyze_data_refs): Remove memtag retrieval. + 2004-12-28 Richard Henderson <rth@redhat.com> PR inline-asm/15740 diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 9da3966..ab9acf7 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -4763,6 +4763,23 @@ vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read) memory tag (for aliasing purposes). Also data reference structure DR is created. + This function handles three kinds of MEMREF: + + It is called from vect_analyze_data_refs with a MEMREF that is either an + ARRAY_REF or an INDIRECT_REF (this is category 1 - "recursion begins"). + It builds a DR for them using vect_get_base_and_bit_offset, and calls itself + recursively to retrieve the relevant memtag for the MEMREF, "peeling" the + MEMREF along the way. During the recursive calls, the function may be called + with a MEMREF for which the recursion has to continue - PLUS_EXPR, + MINUS_EXPR, INDIRECT_REF (category 2 - "recursion continues"), + and/or with a MEMREF for which a memtag can be trivially obtained - VAR_DECL + and SSA_NAME (this is category 3 - "recursion stop condition"). + + When the MEMREF falls into category 1 there is still no data reference struct + (DR) available. It is created by this function, and then, along the recursion, + MEMREF will fall into category 2 or 3, in which case a DR will have already + been created, but the analysis continues to retrieve the MEMTAG. + Input: MEMREF - data reference in STMT IS_READ - TRUE if STMT reads from MEMREF, FALSE if writes to MEMREF @@ -4780,118 +4797,118 @@ vect_get_symbl_and_dr (tree memref, tree stmt, bool is_read, tree symbl, oprnd0, oprnd1; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); tree offset; - tree array_base, base; + tree tag; struct data_reference *new_dr; bool base_aligned_p; - *dr = NULL; - switch (TREE_CODE (memref)) + if (*dr) { - case INDIRECT_REF: - new_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read); - if (! new_dr) - return NULL_TREE; - *dr = new_dr; - symbl = DR_BASE_NAME (new_dr); - STMT_VINFO_VECT_DR_BASE (stmt_info) = symbl; - - switch (TREE_CODE (symbl)) - { - case PLUS_EXPR: - case MINUS_EXPR: - oprnd0 = TREE_OPERAND (symbl, 0); - oprnd1 = TREE_OPERAND (symbl, 1); - - STRIP_NOPS(oprnd1); - /* Only {address_base + offset} expressions are supported, - where address_base can be POINTER_TYPE or ARRAY_TYPE and - offset can be anything but POINTER_TYPE or ARRAY_TYPE. - TODO: swap operands if {offset + address_base}. */ - if ((TREE_CODE (TREE_TYPE (oprnd1)) == POINTER_TYPE - && TREE_CODE (oprnd1) != INTEGER_CST) - || TREE_CODE (TREE_TYPE (oprnd1)) == ARRAY_TYPE) - return NULL_TREE; - - if (TREE_CODE (TREE_TYPE (oprnd0)) == POINTER_TYPE) - symbl = oprnd0; - else - symbl = vect_get_symbl_and_dr (oprnd0, stmt, is_read, - loop_vinfo, &new_dr); + /* Category 3: recursion stop condition. */ + /* (1) A DR already exists. We only need to get the relevant memtag for + MEMREF, the rest of the data was already initialized. */ + switch (TREE_CODE (memref)) + { + /* (1.1) Stop condition: find the relevant memtag and return. */ case SSA_NAME: - case ADDR_EXPR: - /* symbl remains unchanged. */ - break; - - default: - if (vect_debug_details (NULL)) + symbl = SSA_NAME_VAR (memref); + tag = get_var_ann (symbl)->type_mem_tag; + if (!tag) { - fprintf (dump_file, "unhandled data ref: "); - print_generic_expr (dump_file, memref, TDF_SLIM); - fprintf (dump_file, " (symbl "); - print_generic_expr (dump_file, symbl, TDF_SLIM); - fprintf (dump_file, ") in stmt "); - print_generic_expr (dump_file, stmt, TDF_SLIM); + tree ptr = TREE_OPERAND (DR_REF ((*dr)), 0); + if (TREE_CODE (ptr) == SSA_NAME) + tag = get_var_ann (SSA_NAME_VAR (ptr))->type_mem_tag; } - return NULL_TREE; - } - break; - - case ARRAY_REF: - offset = size_zero_node; - - /* Store the array base in the stmt info. - For one dimensional array ref a[i], the base is a, - for multidimensional a[i1][i2]..[iN], the base is - a[i1][i2]..[iN-1]. */ - array_base = TREE_OPERAND (memref, 0); - STMT_VINFO_VECT_DR_BASE (stmt_info) = array_base; - - new_dr = analyze_array (stmt, memref, is_read); - *dr = new_dr; + if (!tag) + { + if (vect_debug_details (NULL)) + fprintf (dump_file, "not vectorized: no memtag for ref."); + return NULL_TREE; + } + return tag; - /* Find the relevant symbol for aliasing purposes. */ - base = DR_BASE_NAME (new_dr); - switch (TREE_CODE (base)) - { case VAR_DECL: - symbl = base; - break; + case PARM_DECL: + return memref; + /* Category 2: recursion continues. */ + /* (1.2) A recursive call to find the relevant memtag is required. */ case INDIRECT_REF: - symbl = TREE_OPERAND (base, 0); - break; + symbl = TREE_OPERAND (memref, 0); + break; /* For recursive call. */ case COMPONENT_REF: /* Could have recorded more accurate information - i.e, the actual FIELD_DECL that is being referenced - - but later passes expect VAR_DECL as the nmt. */ - symbl = vect_get_base_and_bit_offset (new_dr, base, NULL_TREE, + but later passes expect VAR_DECL as the nmt. */ + /* Fall through. */ + + case ADDR_EXPR: + symbl = vect_get_base_and_bit_offset ((*dr), memref, NULL_TREE, loop_vinfo, &offset, &base_aligned_p); - if (symbl) - break; - /* fall through */ + break; /* For recursive call. */ + + case PLUS_EXPR: + case MINUS_EXPR: + /* Although DR exists, we have to call the function recursively to + build MEMTAG for such expression. This is handled below. */ + oprnd0 = TREE_OPERAND (memref, 0); + oprnd1 = TREE_OPERAND (memref, 1); + + STRIP_NOPS (oprnd1); + /* Supported plus/minus expressions are of the form + {address_base + offset}, such that address_base is of type + POINTER/ARRAY, and offset is either an INTEGER_CST of type POINTER, + or it's not of type POINTER/ARRAY. + TODO: swap operands if {offset + address_base}. */ + if ((TREE_CODE (TREE_TYPE (oprnd1)) == POINTER_TYPE + && TREE_CODE (oprnd1) != INTEGER_CST) + || TREE_CODE (TREE_TYPE (oprnd1)) == ARRAY_TYPE) + return NULL_TREE; + + symbl = oprnd0; + break; /* For recursive call. */ + default: - if (vect_debug_details (NULL)) - { - fprintf (dump_file, "unhandled struct/class field access "); - print_generic_expr (dump_file, stmt, TDF_SLIM); - } return NULL_TREE; } - break; + } + else + { + /* Category 1: recursion begins. */ + /* (2) A DR does not exist yet and must be built, followed by a + recursive call to get the relevant memtag for MEMREF. */ - default: - if (vect_debug_details (NULL)) - { - fprintf (dump_file, "unhandled data ref: "); - print_generic_expr (dump_file, memref, TDF_SLIM); - fprintf (dump_file, " in stmt "); - print_generic_expr (dump_file, stmt, TDF_SLIM); - } - return NULL_TREE; + switch (TREE_CODE (memref)) + { + case INDIRECT_REF: + new_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read); + if (!new_dr) + return NULL_TREE; + *dr = new_dr; + symbl = DR_BASE_NAME (new_dr); + STMT_VINFO_VECT_DR_BASE (stmt_info) = symbl; + break; + + case ARRAY_REF: + new_dr = analyze_array (stmt, memref, is_read); + *dr = new_dr; + symbl = DR_BASE_NAME (new_dr); + STMT_VINFO_VECT_DR_BASE (stmt_info) = TREE_OPERAND (memref, 0); + break; + + default: + /* TODO: Support data-refs of form a[i].p for unions and single + field structures. */ + return NULL_TREE; + } } - return symbl; + + if (!symbl) + return NULL_TREE; + /* Recursive call to retrieve the relevant memtag. */ + tag = vect_get_symbl_and_dr (symbl, stmt, is_read, loop_vinfo, dr); + return tag; } @@ -4912,10 +4929,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo) block_stmt_iterator si; int j; struct data_reference *dr; - tree tag; - tree address_base; - bool base_aligned_p; - tree offset; if (vect_debug_details (NULL)) fprintf (dump_file, "\n<<vect_analyze_data_refs>>\n"); @@ -4982,6 +4995,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo) /* Analyze MEMREF. If it is of a supported form, build data_reference struct for it (DR) and find the relevant symbol for aliasing purposes. */ + dr = NULL; symbl = vect_get_symbl_and_dr (memref, stmt, is_read, loop_vinfo, &dr); if (!symbl) @@ -4993,83 +5007,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo) } return false; } - - /* Find and record the memtag assigned to this data-ref. */ - switch (TREE_CODE (symbl)) - { - case VAR_DECL: - STMT_VINFO_MEMTAG (stmt_info) = symbl; - break; - - case SSA_NAME: - symbl = SSA_NAME_VAR (symbl); - tag = get_var_ann (symbl)->type_mem_tag; - if (!tag) - { - tree ptr = TREE_OPERAND (memref, 0); - if (TREE_CODE (ptr) == SSA_NAME) - tag = get_var_ann (SSA_NAME_VAR (ptr))->type_mem_tag; - } - if (!tag) - { - if (vect_debug_stats (loop) || vect_debug_details (loop)) - fprintf (dump_file, "not vectorized: no memtag for ref."); - return false; - } - STMT_VINFO_MEMTAG (stmt_info) = tag; - break; - - case ADDR_EXPR: - address_base = TREE_OPERAND (symbl, 0); - - switch (TREE_CODE (address_base)) - { - case ARRAY_REF: - { - struct data_reference *tmp_dr; - - tmp_dr = analyze_array (stmt, TREE_OPERAND (symbl, 0), - DR_IS_READ (dr)); - tag = vect_get_base_and_bit_offset - (tmp_dr, DR_BASE_NAME (tmp_dr), - NULL_TREE, loop_vinfo, &offset, &base_aligned_p); - if (!tag) - { - if (vect_debug_stats (loop) - || vect_debug_details (loop)) - fprintf (dump_file, - "not vectorized: no memtag for ref."); - return false; - } - STMT_VINFO_MEMTAG (stmt_info) = tag; - } - - break; - - case VAR_DECL: - STMT_VINFO_MEMTAG (stmt_info) = address_base; - break; - - default: - if (vect_debug_stats (loop) || vect_debug_details (loop)) - { - fprintf (dump_file, - "not vectorized: unhandled address expr: "); - print_generic_expr (dump_file, stmt, TDF_SLIM); - } - return false; - } - break; - - default: - if (vect_debug_stats (loop) || vect_debug_details (loop)) - { - fprintf (dump_file, "not vectorized: unsupported data-ref: "); - print_generic_expr (dump_file, memref, TDF_SLIM); - } - return false; - } - + STMT_VINFO_MEMTAG (stmt_info) = symbl; VARRAY_PUSH_GENERIC_PTR (*datarefs, dr); STMT_VINFO_DATA_REF (stmt_info) = dr; } |