#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "toplev.h"
#include "hashtab.h"
#include "pointer-set.h"
#include "tree.h"
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);
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++;
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;
}
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)
and find the ultimate containing object. */
while (1)
{
+ base_type = TREE_TYPE (exp);
+
switch (TREE_CODE (exp))
{
case BIT_FIELD_REF:
}
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;
}
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))
{
&& 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
}
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;
}