aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2010-12-22 13:56:54 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2010-12-22 13:56:54 +0100
commit32aa622ca800f92d7250e1ab4be08d3e174ef953 (patch)
treea1cfc1bdd186a3e0990698cbae0cf216e7ac85d0 /gcc/gimple-fold.c
parent5eeac8330cbea6aa8d170473b7eab105734fb1d8 (diff)
downloadgcc-32aa622ca800f92d7250e1ab4be08d3e174ef953.zip
gcc-32aa622ca800f92d7250e1ab4be08d3e174ef953.tar.gz
gcc-32aa622ca800f92d7250e1ab4be08d3e174ef953.tar.bz2
re PR tree-optimization/45934 (g++.old-deja/g++.other/dtor5.C FAILs with -finline-small-functions)
2010-12-22 Martin Jambor <mjambor@suse.cz> PR tree-optimization/45934 PR tree-optimization/46302 PR tree-optimization/46987 * gimple-fold.c (get_base_binfo_for_type): Removed. (gimple_get_relevant_ref_binfo): Likewise. (gimple_fold_obj_type_ref_call): Dumb down to 4.5 functionality, removed parameter inplace, updated the caller. * gimple.h (gimple_get_relevant_ref_binfo): Remove declaration. * ipa-cp.c (ipcp_propagate_types): Do not derive types from constants. (ipcp_discover_new_direct_edges): Do not do devirtualization based on constants. * ipa-prop.c (compute_known_type_jump_func): Use get_ref_base_and_extent and get_binfo_at_offset instead of gimple_get_relevant_ref_binfo. (compute_known_type_jump_func): Likewise. (update_jump_functions_after_inlining): Do not derive types from constants. (try_make_edge_direct_virtual_call): Likewise. * tree.c (get_binfo_at_offset): Get type from non-artificial fields. * testsuite/g++.dg/ipa/ipcp-ivi-1.C: Removed. * testsuite/g++.dg/ipa/ivinline-6.C: Likewise. * testsuite/g++.dg/otr-fold-1.C: Likewise. * testsuite/g++.dg/otr-fold-2.C: Likewise. * testsuite/g++.dg/tree-ssa/pr43411.C: Xfail dump scan. * testsuite/g++.dg/tree-ssa/pr45605.C: Likewise. * testsuite/g++.dg/tree-ssa/pr46987.C: New test. From-SVN: r168168
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r--gcc/gimple-fold.c110
1 files changed, 11 insertions, 99 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index b6c06fc..16a2092 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1364,88 +1364,6 @@ gimple_fold_builtin (gimple stmt)
return result;
}
-/* Search for a base binfo of BINFO that corresponds to TYPE and return it if
- it is found or NULL_TREE if it is not. */
-
-static tree
-get_base_binfo_for_type (tree binfo, tree type)
-{
- int i;
- tree base_binfo;
- tree res = NULL_TREE;
-
- for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
- if (TREE_TYPE (base_binfo) == type)
- {
- gcc_assert (!res);
- res = base_binfo;
- }
-
- return res;
-}
-
-/* Return a binfo describing the part of object referenced by expression REF.
- Return NULL_TREE if it cannot be determined. REF can consist of a series of
- COMPONENT_REFs of a declaration or of an INDIRECT_REF or it can also be just
- a simple declaration, indirect reference or an SSA_NAME. If the function
- discovers an INDIRECT_REF or an SSA_NAME, it will assume that the
- encapsulating type is described by KNOWN_BINFO, if it is not NULL_TREE.
- Otherwise the first non-artificial field declaration or the base declaration
- will be examined to get the encapsulating type. */
-
-tree
-gimple_get_relevant_ref_binfo (tree ref, tree known_binfo)
-{
- while (true)
- {
- if (TREE_CODE (ref) == COMPONENT_REF)
- {
- tree par_type;
- tree binfo;
- tree field = TREE_OPERAND (ref, 1);
-
- if (!DECL_ARTIFICIAL (field))
- {
- tree type = TREE_TYPE (field);
- if (TREE_CODE (type) == RECORD_TYPE)
- return TYPE_BINFO (type);
- else
- return NULL_TREE;
- }
-
- par_type = TREE_TYPE (TREE_OPERAND (ref, 0));
- binfo = TYPE_BINFO (par_type);
- if (!binfo
- || BINFO_N_BASE_BINFOS (binfo) == 0)
- return NULL_TREE;
-
- /* Offset 0 indicates the primary base, whose vtable contents are
- represented in the binfo for the derived class. */
- if (int_bit_position (field) != 0)
- {
- tree d_binfo;
-
- /* Get descendant binfo. */
- d_binfo = gimple_get_relevant_ref_binfo (TREE_OPERAND (ref, 0),
- known_binfo);
- if (!d_binfo)
- return NULL_TREE;
- return get_base_binfo_for_type (d_binfo, TREE_TYPE (field));
- }
-
- ref = TREE_OPERAND (ref, 0);
- }
- else if (DECL_P (ref) && TREE_CODE (TREE_TYPE (ref)) == RECORD_TYPE)
- return TYPE_BINFO (TREE_TYPE (ref));
- else if (known_binfo
- && (TREE_CODE (ref) == SSA_NAME
- || TREE_CODE (ref) == MEM_REF))
- return known_binfo;
- else
- return NULL_TREE;
- }
-}
-
/* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
KNOWN_BINFO carries the binfo describing the true type of
@@ -1529,7 +1447,7 @@ gimple_adjust_this_by_delta (gimple_stmt_iterator *gsi, tree delta)
INPLACE is false. Return true iff the statement was changed. */
static bool
-gimple_fold_obj_type_ref_call (gimple_stmt_iterator *gsi, bool inplace)
+gimple_fold_obj_type_ref_call (gimple_stmt_iterator *gsi)
{
gimple stmt = gsi_stmt (*gsi);
tree ref = gimple_call_fn (stmt);
@@ -1537,27 +1455,21 @@ gimple_fold_obj_type_ref_call (gimple_stmt_iterator *gsi, bool inplace)
tree binfo, fndecl, delta;
HOST_WIDE_INT token;
- if (TREE_CODE (obj) == ADDR_EXPR)
- obj = TREE_OPERAND (obj, 0);
- else
+ if (TREE_CODE (obj) != ADDR_EXPR)
return false;
-
- binfo = gimple_get_relevant_ref_binfo (obj, NULL_TREE);
+ obj = TREE_OPERAND (obj, 0);
+ if (!DECL_P (obj)
+ || TREE_CODE (TREE_TYPE (obj)) != RECORD_TYPE)
+ return false;
+ binfo = TYPE_BINFO (TREE_TYPE (obj));
if (!binfo)
return false;
+
token = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1);
- fndecl = gimple_get_virt_mehtod_for_binfo (token, binfo, &delta,
- !DECL_P (obj));
+ fndecl = gimple_get_virt_mehtod_for_binfo (token, binfo, &delta, false);
if (!fndecl)
return false;
-
- if (integer_nonzerop (delta))
- {
- if (inplace)
- return false;
- gimple_adjust_this_by_delta (gsi, delta);
- }
-
+ gcc_assert (integer_zerop (delta));
gimple_call_set_fndecl (stmt, fndecl);
return true;
}
@@ -1595,7 +1507,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
here where we can just smash the call operand. */
callee = gimple_call_fn (stmt);
if (TREE_CODE (callee) == OBJ_TYPE_REF)
- return gimple_fold_obj_type_ref_call (gsi, inplace);
+ return gimple_fold_obj_type_ref_call (gsi);
}
return false;