gimple-fold.c (gimple_get_virt_method_for_vtable): Do O(1) lookup in the vtable constructor.

* gimple-fold.c (gimple_get_virt_method_for_vtable): Do O(1)
	lookup in the vtable constructor.

From-SVN: r207616
This commit is contained in:
Jan Hubicka 2014-02-08 00:26:39 +01:00 committed by Jan Hubicka
parent 63e6247dfe
commit 8c311b50d1
2 changed files with 32 additions and 4 deletions

View File

@ -1,3 +1,8 @@
2014-02-07 Jan Hubicka <hubicka@ucw.cz>
* gimple-fold.c (gimple_get_virt_method_for_vtable): Do O(1)
lookup in the vtable constructor.
2014-02-07 Jeff Law <law@redhat.com> 2014-02-07 Jeff Law <law@redhat.com>
PR target/40977 PR target/40977

View File

@ -3179,6 +3179,8 @@ gimple_get_virt_method_for_vtable (HOST_WIDE_INT token,
{ {
tree vtable = v, init, fn; tree vtable = v, init, fn;
unsigned HOST_WIDE_INT size; unsigned HOST_WIDE_INT size;
unsigned HOST_WIDE_INT elt_size, access_index;
tree domain_type;
/* First of all double check we have virtual table. */ /* First of all double check we have virtual table. */
if (TREE_CODE (v) != VAR_DECL if (TREE_CODE (v) != VAR_DECL
@ -3202,10 +3204,31 @@ gimple_get_virt_method_for_vtable (HOST_WIDE_INT token,
offset *= BITS_PER_UNIT; offset *= BITS_PER_UNIT;
offset += token * size; offset += token * size;
/* Do not pass from_decl here, we want to know even about values we can /* Lookup the value in the constructor that is assumed to be array.
not use and will check can_refer_decl_in_current_unit_p ourselves. */ This is equivalent to
fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init, fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init,
offset, size, NULL); offset, size, NULL);
but in a constant time. We expect that frontend produced a simple
array without indexed initializers. */
gcc_checking_assert (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
domain_type = TYPE_DOMAIN (TREE_TYPE (init));
gcc_checking_assert (integer_zerop (TYPE_MIN_VALUE (domain_type)));
elt_size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));
access_index = offset / BITS_PER_UNIT / elt_size;
gcc_checking_assert (offset % (elt_size * BITS_PER_UNIT) == 0);
/* This code makes an assumption that there are no
indexed fileds produced by C++ FE, so we can directly index the array. */
if (access_index < CONSTRUCTOR_NELTS (init))
{
fn = CONSTRUCTOR_ELT (init, access_index)->value;
gcc_checking_assert (!CONSTRUCTOR_ELT (init, access_index)->index);
STRIP_NOPS (fn);
}
else
fn = NULL;
/* For type inconsistent program we may end up looking up virtual method /* For type inconsistent program we may end up looking up virtual method
in virtual table that does not contain TOKEN entries. We may overrun in virtual table that does not contain TOKEN entries. We may overrun