Commit c49bdb2e by Jan Hubicka Committed by Jan Hubicka

gimple-fold.c (gimple_extract_devirt_binfo_from_cst): Add new arugment expected_type.


	* gimple-fold.c (gimple_extract_devirt_binfo_from_cst): Add new
	arugment expected_type.
	(gimple_fold_call): Use it.
	* gimple.h (gimple_extract_devirt_binfo_from_cst): Update prototype.
	* ipa-cp.c (ipa_get_indirect_edge_target_1): Update.
	* ipa-prop.c (ipa_analyze_virtual_call_uses): Use
	obj_type_ref_class.
	(try_make_edge_direct_virtual_call): Likewise.
	* tree.c (obj_type_ref_class): New.
	* tree.h (obj_type_ref_class): Use it.

From-SVN: r201789
parent 4042dca9
2013-08-16 Jan Hubicka <jh@suse.cz>
* gimple-fold.c (gimple_extract_devirt_binfo_from_cst): Add new
arugment expected_type.
(gimple_fold_call): Use it.
* gimple.h (gimple_extract_devirt_binfo_from_cst): Update prototype.
* ipa-cp.c (ipa_get_indirect_edge_target_1): Update.
* ipa-prop.c (ipa_analyze_virtual_call_uses): Use
obj_type_ref_class.
(try_make_edge_direct_virtual_call): Likewise.
* tree.c (obj_type_ref_class): New.
* tree.h (obj_type_ref_class): Use it.
2013-08-16 Gabriel Dos Reis <gdr@integrable-solutions.net> 2013-08-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
* sched-vis.c (rtl_slim_pp_initialized): Remove. * sched-vis.c (rtl_slim_pp_initialized): Remove.
......
...@@ -1007,13 +1007,14 @@ gimple_fold_builtin (gimple stmt) ...@@ -1007,13 +1007,14 @@ gimple_fold_builtin (gimple stmt)
represented by a declaration (i.e. a global or automatically allocated one) represented by a declaration (i.e. a global or automatically allocated one)
or NULL if it cannot be found or is not safe. CST is expected to be an or NULL if it cannot be found or is not safe. CST is expected to be an
ADDR_EXPR of such object or the function will return NULL. Currently it is ADDR_EXPR of such object or the function will return NULL. Currently it is
safe to use such binfo only if it has no base binfo (i.e. no ancestors). */ safe to use such binfo only if it has no base binfo (i.e. no ancestors)
EXPECTED_TYPE is type of the class virtual belongs to. */
tree tree
gimple_extract_devirt_binfo_from_cst (tree cst) gimple_extract_devirt_binfo_from_cst (tree cst, tree expected_type)
{ {
HOST_WIDE_INT offset, size, max_size; HOST_WIDE_INT offset, size, max_size;
tree base, type, expected_type, binfo; tree base, type, binfo;
bool last_artificial = false; bool last_artificial = false;
if (!flag_devirtualize if (!flag_devirtualize
...@@ -1022,7 +1023,6 @@ gimple_extract_devirt_binfo_from_cst (tree cst) ...@@ -1022,7 +1023,6 @@ gimple_extract_devirt_binfo_from_cst (tree cst)
return NULL_TREE; return NULL_TREE;
cst = TREE_OPERAND (cst, 0); cst = TREE_OPERAND (cst, 0);
expected_type = TREE_TYPE (cst);
base = get_ref_base_and_extent (cst, &offset, &size, &max_size); base = get_ref_base_and_extent (cst, &offset, &size, &max_size);
type = TREE_TYPE (base); type = TREE_TYPE (base);
if (!DECL_P (base) if (!DECL_P (base)
...@@ -1108,7 +1108,8 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) ...@@ -1108,7 +1108,8 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
else else
{ {
tree obj = OBJ_TYPE_REF_OBJECT (callee); tree obj = OBJ_TYPE_REF_OBJECT (callee);
tree binfo = gimple_extract_devirt_binfo_from_cst (obj); tree binfo = gimple_extract_devirt_binfo_from_cst
(obj, obj_type_ref_class (callee));
if (binfo) if (binfo)
{ {
HOST_WIDE_INT token HOST_WIDE_INT token
......
...@@ -854,7 +854,7 @@ unsigned get_gimple_rhs_num_ops (enum tree_code); ...@@ -854,7 +854,7 @@ unsigned get_gimple_rhs_num_ops (enum tree_code);
gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL); gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
const char *gimple_decl_printable_name (tree, int); const char *gimple_decl_printable_name (tree, int);
tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree); tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree);
tree gimple_extract_devirt_binfo_from_cst (tree); tree gimple_extract_devirt_binfo_from_cst (tree, tree);
/* Returns true iff T is a scalar register variable. */ /* Returns true iff T is a scalar register variable. */
extern bool is_gimple_reg (tree); extern bool is_gimple_reg (tree);
......
...@@ -1541,7 +1541,8 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, ...@@ -1541,7 +1541,8 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
if (TREE_CODE (t) != TREE_BINFO) if (TREE_CODE (t) != TREE_BINFO)
{ {
tree binfo; tree binfo;
binfo = gimple_extract_devirt_binfo_from_cst (t); binfo = gimple_extract_devirt_binfo_from_cst
(t, ie->indirect_info->otr_type);
if (!binfo) if (!binfo)
return NULL_TREE; return NULL_TREE;
binfo = get_binfo_at_offset (binfo, anc_offset, otr_type); binfo = get_binfo_at_offset (binfo, anc_offset, otr_type);
......
...@@ -1903,7 +1903,7 @@ ipa_analyze_virtual_call_uses (struct cgraph_node *node, ...@@ -1903,7 +1903,7 @@ ipa_analyze_virtual_call_uses (struct cgraph_node *node,
ii = cs->indirect_info; ii = cs->indirect_info;
ii->offset = anc_offset; ii->offset = anc_offset;
ii->otr_token = tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1); ii->otr_token = tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1);
ii->otr_type = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (target))); ii->otr_type = obj_type_ref_class (target);
ii->polymorphic = 1; ii->polymorphic = 1;
} }
...@@ -2453,7 +2453,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, ...@@ -2453,7 +2453,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
if (TREE_CODE (binfo) != TREE_BINFO) if (TREE_CODE (binfo) != TREE_BINFO)
{ {
binfo = gimple_extract_devirt_binfo_from_cst (binfo); binfo = gimple_extract_devirt_binfo_from_cst
(binfo, ie->indirect_info->otr_type);
if (!binfo) if (!binfo)
return NULL; return NULL;
} }
......
...@@ -11864,6 +11864,21 @@ types_same_for_odr (tree type1, tree type2) ...@@ -11864,6 +11864,21 @@ types_same_for_odr (tree type1, tree type2)
return true; return true;
} }
/* REF is OBJ_TYPE_REF, return the class the ref corresponds to. */
tree
obj_type_ref_class (tree ref)
{
gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF);
ref = TREE_TYPE (ref);
gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
ref = TREE_TYPE (ref);
gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE);
ref = TREE_VALUE (TYPE_ARG_TYPES (ref));
gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
return TREE_TYPE (ref);
}
/* Try to find a base info of BINFO that would have its field decl at offset /* Try to find a base info of BINFO that would have its field decl at offset
OFFSET within the BINFO type and which is of EXPECTED_TYPE. If it can be OFFSET within the BINFO type and which is of EXPECTED_TYPE. If it can be
found, return, otherwise return NULL_TREE. */ found, return, otherwise return NULL_TREE. */
......
...@@ -5974,6 +5974,7 @@ extern location_t tree_nonartificial_location (tree); ...@@ -5974,6 +5974,7 @@ extern location_t tree_nonartificial_location (tree);
extern tree block_ultimate_origin (const_tree); extern tree block_ultimate_origin (const_tree);
extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree); extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
extern tree obj_type_ref_class (tree ref);
extern bool types_same_for_odr (tree type1, tree type2); extern bool types_same_for_odr (tree type1, tree type2);
extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *, extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
HOST_WIDE_INT *, HOST_WIDE_INT *); HOST_WIDE_INT *, HOST_WIDE_INT *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment