summaryrefslogtreecommitdiff
path: root/gcc/tree-dfa.c
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2009-03-30 13:06:52 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2009-03-30 13:06:52 +0000
commitba3a7ba09d49083f5a2cd9284aa249993a705b21 (patch)
treea998017d535126ebe28c42696a5e141a4c23b459 /gcc/tree-dfa.c
parenta3cad4e45e03b201be558abc0b2d7e3d974491f6 (diff)
downloadgcc-ba3a7ba09d49083f5a2cd9284aa249993a705b21.tar.gz
2009-03-30 Martin Jambor <mjambor@suse.cz>
* ipa-prop.h (jump_func_type): Rename IPA_UNKNOWN, IPA_CONST, IPA_CONST_MEMBER_PTR, and IPA_PASS_THROUGH to IPA_JF_UNKNOWN, IPA_JF_CONST, IPA_JF_CONST_MEMBER_PTR, and IPA_JF_PASS_THROUGH respectively. * tree-dfa.c (get_ref_base_and_extent): Return -1 maxsize if seen_variable_array_ref while also traversing a union. * tree-inline.c (optimize_inline_calls): Do not call cgraph_node_remove_callees. * cgraphbuild.c (remove_cgraph_callee_edges): New function. (pass_remove_cgraph_callee_edges): New variable. * passes.c (init_optimization_passes): Add pass_remove_cgraph_callee_edges after early inlining and before all late intraprocedural passes. * omp-low.c (expand_omp_taskreg): Always set current_function_decl. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145291 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-dfa.c')
-rw-r--r--gcc/tree-dfa.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 5241e64c929..082ac082bf3 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -801,6 +801,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;
+ bool seen_union = false;
gcc_assert (!SSA_VAR_P (exp));
@@ -844,6 +845,9 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
tree field = TREE_OPERAND (exp, 1);
tree this_offset = component_ref_field_offset (exp);
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == UNION_TYPE)
+ seen_union = true;
+
if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
{
HOST_WIDE_INT hthis_offset = tree_low_cst (this_offset, 0);
@@ -934,12 +938,22 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
where we do not know maxsize for variable index accesses to
the array. The simplest way to conservatively deal with this
is to punt in the case that offset + maxsize reaches the
- base type boundary. */
+ base type boundary.
+
+ Unfortunately this is difficult to determine reliably when unions are
+ involved and so we are conservative in such cases.
+
+ FIXME: This approach may be too conservative, we probably want to at least
+ check that the union is the last field/element at its level or even
+ propagate the calculated offsets back up the access chain and check
+ there. */
+
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))))
+ && (seen_union
+ || (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;
/* ??? Due to negative offsets in ARRAY_REF we can end up with