aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-10-08 19:10:00 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-10-08 17:10:00 +0000
commit1184bb7825fa52042b4243b73ca16769033f10e3 (patch)
treeeb288703f5f812013a51e2ee02fed77547fb203c /gcc
parent9a7451a5a502f5a2714b06677ce61ecef23539d0 (diff)
downloadgcc-1184bb7825fa52042b4243b73ca16769033f10e3.zip
gcc-1184bb7825fa52042b4243b73ca16769033f10e3.tar.gz
gcc-1184bb7825fa52042b4243b73ca16769033f10e3.tar.bz2
ipa-polymorphic-call.c (extr_type_from_vtbl_store): Do better pattern matching of MEM_REF.
* ipa-polymorphic-call.c (extr_type_from_vtbl_store): Do better pattern matching of MEM_REF. (check_stmt_for_type_change): Update. From-SVN: r216010
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/ipa-polymorphic-call.c50
2 files changed, 42 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5c91c38..eefb8fc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-10-07 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-polymorphic-call.c (extr_type_from_vtbl_store): Do better
+ pattern matching of MEM_REF.
+ (check_stmt_for_type_change): Update.
+
2014-10-08 Steve Ellcey <sellcey@mips.com>
* config/mips/linux64.h: Remove.
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 3e4aa04..51c6709 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -1140,7 +1140,8 @@ noncall_stmt_may_be_vtbl_ptr_store (gimple stmt)
/* If STMT can be proved to be an assignment to the virtual method table
pointer of ANALYZED_OBJ and the type associated with the new table
- identified, return the type. Otherwise return NULL_TREE. */
+ identified, return the type. Otherwise return NULL_TREE if type changes
+ in unknown way or ERROR_MARK_NODE if type is unchanged. */
static tree
extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci,
@@ -1167,15 +1168,6 @@ extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci,
else
{
base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
- if (offset != tci->offset
- || size != POINTER_SIZE
- || max_size != POINTER_SIZE)
- {
- if (dump_file)
- fprintf (dump_file, " wrong offset %i!=%i or size %i\n",
- (int)offset, (int)tci->offset, (int)size);
- return NULL_TREE;
- }
if (DECL_P (tci->instance))
{
if (base != tci->instance)
@@ -1193,19 +1185,35 @@ extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci,
}
else if (TREE_CODE (base) == MEM_REF)
{
- if (!operand_equal_p (tci->instance, TREE_OPERAND (base, 0), 0)
- || !integer_zerop (TREE_OPERAND (base, 1)))
+ if (!operand_equal_p (tci->instance, TREE_OPERAND (base, 0), 0))
{
if (dump_file)
{
fprintf (dump_file, " base mem ref:");
print_generic_expr (dump_file, base, TDF_SLIM);
- fprintf (dump_file, " has nonzero offset or does not match instance:");
+ fprintf (dump_file, " does not match instance:");
print_generic_expr (dump_file, tci->instance, TDF_SLIM);
fprintf (dump_file, "\n");
}
return NULL_TREE;
}
+ if (!integer_zerop (TREE_OPERAND (base, 1)))
+ {
+ if (!tree_fits_shwi_p (TREE_OPERAND (base, 1)))
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, " base mem ref:");
+ print_generic_expr (dump_file, base, TDF_SLIM);
+ fprintf (dump_file, " has non-representable offset:");
+ print_generic_expr (dump_file, tci->instance, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+ return NULL_TREE;
+ }
+ else
+ offset += tree_to_shwi (TREE_OPERAND (base, 1)) * BITS_PER_UNIT;
+ }
}
else if (!operand_equal_p (tci->instance, base, 0)
|| tci->offset)
@@ -1218,7 +1226,19 @@ extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci,
print_generic_expr (dump_file, tci->instance, TDF_SLIM);
fprintf (dump_file, " with offset %i\n", (int)tci->offset);
}
- return NULL_TREE;
+ return tci->offset > GET_MODE_BITSIZE (Pmode) ? error_mark_node : NULL_TREE;
+ }
+ if (offset != tci->offset
+ || size != POINTER_SIZE
+ || max_size != POINTER_SIZE)
+ {
+ if (dump_file)
+ fprintf (dump_file, " wrong offset %i!=%i or size %i\n",
+ (int)offset, (int)tci->offset, (int)size);
+ return offset + GET_MODE_BITSIZE (Pmode) <= offset
+ || (max_size != -1
+ && tci->offset + GET_MODE_BITSIZE (Pmode) > offset + max_size)
+ ? error_mark_node : NULL;
}
}
@@ -1405,6 +1425,8 @@ check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
type = extr_type_from_vtbl_ptr_store (stmt, tci, &offset);
gcc_assert (!type || TYPE_MAIN_VARIANT (type) == type);
+ if (type == error_mark_node)
+ return false;
if (!type)
{
if (dump_file)