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:
parent
63e6247dfe
commit
8c311b50d1
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue