diff options
author | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-02-03 00:24:52 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-02-03 00:24:52 +0000 |
commit | 390675c87ddc147b6d1982824b329e119ae5148b (patch) | |
tree | 76bd028dd2a79384d67f52b8ff5e5cbe8b093dfa /gcc/ipa-devirt.c | |
parent | 06fcf6c19c42b104bb0e8598c9f9f8cbd4a8b8c7 (diff) | |
download | gcc-390675c87ddc147b6d1982824b329e119ae5148b.zip gcc-390675c87ddc147b6d1982824b329e119ae5148b.tar.gz gcc-390675c87ddc147b6d1982824b329e119ae5148b.tar.bz2 |
ipa-devirt.c (subbinfo_with_vtable_at_offset, [...]): New functions.
* ipa-devirt.c (subbinfo_with_vtable_at_offset,
vtable_pointer_value_to_binfo): New functions.
* ipa-utils.h (vtable_pointer_value_to_binfo): Declare.
* ipa-prop.c (extr_type_from_vtbl_ptr_store): Use it.
* g++.dg/ipa/devirt-23.C: New testcase.
* g++.dg/ipa/devirt-20.C: Fix template.
From-SVN: r207413
Diffstat (limited to 'gcc/ipa-devirt.c')
-rw-r--r-- | gcc/ipa-devirt.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index fb03dd2..dcaebdf 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -972,6 +972,70 @@ contains_type_p (tree outer_type, HOST_WIDE_INT offset, return get_class_context (&context, otr_type); } +/* Lookup base of BINFO that has virtual table VTABLE with OFFSET. */ + +static tree +subbinfo_with_vtable_at_offset (tree binfo, tree offset, tree vtable) +{ + tree v = BINFO_VTABLE (binfo); + int i; + tree base_binfo; + + gcc_assert (!v || TREE_CODE (v) == POINTER_PLUS_EXPR); + + if (v && tree_int_cst_equal (TREE_OPERAND (v, 1), offset) + && TREE_OPERAND (TREE_OPERAND (v, 0), 0) == vtable) + return binfo; + for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + if (polymorphic_type_binfo_p (base_binfo)) + { + base_binfo = subbinfo_with_vtable_at_offset (base_binfo, offset, vtable); + if (base_binfo) + return base_binfo; + } + return NULL; +} + +/* T is known constant value of virtual table pointer. Return BINFO of the + instance type. */ + +tree +vtable_pointer_value_to_binfo (tree t) +{ + /* We expect &MEM[(void *)&virtual_table + 16B]. + We obtain object's BINFO from the context of the virtual table. + This one contains pointer to virtual table represented via + POINTER_PLUS_EXPR. Verify that this pointer match to what + we propagated through. + + In the case of virtual inheritance, the virtual tables may + be nested, i.e. the offset may be different from 16 and we may + need to dive into the type representation. */ + if (t && TREE_CODE (t) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (t, 0)) == MEM_REF + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == INTEGER_CST + && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 0)) + == VAR_DECL) + && DECL_VIRTUAL_P (TREE_OPERAND (TREE_OPERAND + (TREE_OPERAND (t, 0), 0), 0))) + { + tree vtable = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 0); + tree offset = TREE_OPERAND (TREE_OPERAND (t, 0), 1); + tree binfo = TYPE_BINFO (DECL_CONTEXT (vtable)); + + binfo = subbinfo_with_vtable_at_offset (binfo, offset, vtable); + + /* FIXME: for stores of construction vtables we return NULL, + because we do not have BINFO for those. Eventually we should fix + our representation to allow this case to be handled, too. + In the case we see store of BINFO we however may assume + that standard folding will be ale to cope with it. */ + return binfo; + } + return NULL; +} + /* Given REF call in FNDECL, determine class of the polymorphic call (OTR_TYPE), its token (OTR_TOKEN) and CONTEXT. Return pointer to object described by the context */ |