X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-dfa.c;h=2dacd44b1a4fb81cf6a871cdae51f402ff5e5c9a;hb=e21b444cfb76b8d67c9ad45766f55730901b6957;hp=37e15bf7ee23f5452373911c9203c48e919a07f3;hpb=1767a056f10a2ccbc900df04d01193da73a3d272;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 37e15bf7ee2..2dacd44b1a4 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -23,7 +23,6 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" -#include "toplev.h" #include "hashtab.h" #include "pointer-set.h" #include "tree.h" @@ -219,7 +218,7 @@ dump_referenced_vars (FILE *file) fprintf (file, "\nReferenced variables in %s: %u\n\n", get_name (current_function_decl), (unsigned) num_referenced_vars); - FOR_EACH_REFERENCED_VAR (var, rvi) + FOR_EACH_REFERENCED_VAR (cfun, var, rvi) { fprintf (file, "Variable: "); dump_variable (file, var); @@ -401,7 +400,7 @@ collect_dfa_stats (struct dfa_stats_d *dfa_stats_p ATTRIBUTE_UNUSED) memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d)); /* Count all the variable annotations. */ - FOR_EACH_REFERENCED_VAR (var, vi) + FOR_EACH_REFERENCED_VAR (cfun, var, vi) if (var_ann (var)) dfa_stats_p->num_var_anns++; @@ -489,13 +488,12 @@ find_referenced_vars_in (gimple stmt) variable. */ tree -referenced_var_lookup (unsigned int uid) +referenced_var_lookup (struct function *fn, unsigned int uid) { tree h; struct tree_decl_minimal in; in.uid = uid; - h = (tree) htab_find_with_hash (gimple_referenced_vars (cfun), &in, uid); - gcc_assert (h || uid == 0); + h = (tree) htab_find_with_hash (gimple_referenced_vars (fn), &in, uid); return h; } @@ -711,6 +709,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, tree size_tree = NULL_TREE; HOST_WIDE_INT bit_offset = 0; bool seen_variable_array_ref = false; + tree base_type; /* First get the final access size from just the outermost expression. */ if (TREE_CODE (exp) == COMPONENT_REF) @@ -741,6 +740,8 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, and find the ultimate containing object. */ while (1) { + base_type = TREE_TYPE (exp); + switch (TREE_CODE (exp)) { case BIT_FIELD_REF: @@ -879,6 +880,38 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, } goto done; + case TARGET_MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR) + { + /* Via the variable index or index2 we can reach the + whole object. */ + if (TMR_INDEX (exp) || TMR_INDEX2 (exp)) + { + exp = TREE_OPERAND (TMR_BASE (exp), 0); + bit_offset = 0; + maxsize = -1; + goto done; + } + if (integer_zerop (TMR_OFFSET (exp))) + exp = TREE_OPERAND (TMR_BASE (exp), 0); + else + { + double_int off = mem_ref_offset (exp); + off = double_int_lshift (off, + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); + off = double_int_add (off, shwi_to_double_int (bit_offset)); + if (double_int_fits_in_shwi_p (off)) + { + bit_offset = double_int_to_shwi (off); + exp = TREE_OPERAND (TMR_BASE (exp), 0); + } + } + } + goto done; + default: goto done; } @@ -896,9 +929,16 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, the array. The simplest way to conservatively deal with this is to punt in the case that offset + maxsize reaches the base type boundary. This needs to include possible trailing padding - that is there for alignment purposes. + that is there for alignment purposes. */ + + if (seen_variable_array_ref + && maxsize != -1 + && (!host_integerp (TYPE_SIZE (base_type), 1) + || (bit_offset + maxsize + == (signed) TREE_INT_CST_LOW (TYPE_SIZE (base_type))))) + maxsize = -1; - That is of course only true if the base object is not a decl. */ + /* In case of a decl or constant base object we can do better. */ if (DECL_P (exp)) { @@ -908,12 +948,14 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, && host_integerp (DECL_SIZE (exp), 1)) maxsize = TREE_INT_CST_LOW (DECL_SIZE (exp)) - bit_offset; } - else if (seen_variable_array_ref - && maxsize != -1 - && (!host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1) - || (bit_offset + maxsize - == (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp)))))) - maxsize = -1; + else if (CONSTANT_CLASS_P (exp)) + { + /* If maxsize is unknown adjust it according to the size of the + base type constant. */ + if (maxsize == -1 + && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)) + maxsize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))) - bit_offset; + } /* ??? Due to negative offsets in ARRAY_REF we can end up with negative bit_offset here. We might want to store a zero offset @@ -1011,6 +1053,22 @@ get_addr_base_and_unit_offset (tree exp, HOST_WIDE_INT *poffset) } goto done; + case TARGET_MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR) + { + if (TMR_INDEX (exp) || TMR_INDEX2 (exp)) + return NULL_TREE; + if (!integer_zerop (TMR_OFFSET (exp))) + { + double_int off = mem_ref_offset (exp); + gcc_assert (off.high == -1 || off.high == 0); + byte_offset += double_int_to_shwi (off); + } + exp = TREE_OPERAND (TMR_BASE (exp), 0); + } + goto done; + default: goto done; }