aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2013-12-18 00:43:22 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2013-12-17 23:43:22 +0000
commitbdf37f7a71501642d6238bf267125242e33eff51 (patch)
tree102d2244405f3842e5f8a8d552db499e50f617ef
parenta4fff37a46aae55c975a7445cd9950bab1f34347 (diff)
downloadgcc-bdf37f7a71501642d6238bf267125242e33eff51.zip
gcc-bdf37f7a71501642d6238bf267125242e33eff51.tar.gz
gcc-bdf37f7a71501642d6238bf267125242e33eff51.tar.bz2
re PR middle-end/35545 (tracer pass is run too late)
PR middle-end/35535 * gimple-fold.c (fold_gimple_assign): Attempt to devirtualize OBJ_TYPE_REF. (gimple_fold_stmt_to_constant_1): Bypass OBJ_TYPE_REF wrappers. From-SVN: r206074
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gimple-fold.c31
2 files changed, 38 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6ce6a60..2441b10 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,13 @@
2013-12-17 Jan Hubicka <hubicka@ucw.cz>
PR middle-end/35535
+ * gimple-fold.c (fold_gimple_assign): Attempt to devirtualize
+ OBJ_TYPE_REF.
+ (gimple_fold_stmt_to_constant_1): Bypass OBJ_TYPE_REF wrappers.
+
+2013-12-17 Jan Hubicka <hubicka@ucw.cz>
+
+ PR middle-end/35535
* tree-vrp.c (extract_range_from_unary_expr_1): Handle OBJ_TYPE_REF.
2013-12-17 Teresa Johnson <tejohnson@google.com>
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 767c869..3b6fc57 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -374,6 +374,30 @@ fold_gimple_assign (gimple_stmt_iterator *si)
if (REFERENCE_CLASS_P (rhs))
return maybe_fold_reference (rhs, false);
+ else if (TREE_CODE (rhs) == OBJ_TYPE_REF)
+ {
+ tree val = OBJ_TYPE_REF_EXPR (rhs);
+ if (is_gimple_min_invariant (val))
+ return val;
+ else if (flag_devirtualize && virtual_method_call_p (val))
+ {
+ bool final;
+ vec <cgraph_node *>targets
+ = possible_polymorphic_call_targets (val, &final);
+ if (final && targets.length () <= 1)
+ {
+ tree fndecl;
+ if (targets.length () == 1)
+ fndecl = targets[0]->decl;
+ else
+ fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
+ val = fold_convert (TREE_TYPE (val), fndecl);
+ STRIP_USELESS_TYPE_CONVERSION (val);
+ return val;
+ }
+ }
+
+ }
else if (TREE_CODE (rhs) == ADDR_EXPR)
{
tree ref = TREE_OPERAND (rhs, 0);
@@ -2525,6 +2549,13 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
return build_vector (TREE_TYPE (rhs), vec);
}
+ if (subcode == OBJ_TYPE_REF)
+ {
+ tree val = (*valueize) (OBJ_TYPE_REF_EXPR (rhs));
+ /* If callee is constant, we can fold away the wrapper. */
+ if (is_gimple_min_invariant (val))
+ return val;
+ }
if (kind == tcc_reference)
{