diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-02-08 00:26:39 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-02-07 23:26:39 +0000 |
commit | 8c311b50d191ce5aa3574264d4e0cbe604cdcbc7 (patch) | |
tree | 4cf6c8e79aad80187b4c85a925b5b93037ecafd3 /gcc | |
parent | 63e6247dfe1fb16b2c179d1b1e04b7ca0efb506d (diff) | |
download | gcc-8c311b50d191ce5aa3574264d4e0cbe604cdcbc7.zip gcc-8c311b50d191ce5aa3574264d4e0cbe604cdcbc7.tar.gz gcc-8c311b50d191ce5aa3574264d4e0cbe604cdcbc7.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 31 |
2 files changed, 32 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1237904..a0ae188 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> PR target/40977 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fc36e15..fd25939 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -3179,6 +3179,8 @@ gimple_get_virt_method_for_vtable (HOST_WIDE_INT token, { tree vtable = v, init, fn; 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. */ 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 += token * size; - /* Do not pass from_decl here, we want to know even about values we can - not use and will check can_refer_decl_in_current_unit_p ourselves. */ - fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init, - offset, size, NULL); + /* Lookup the value in the constructor that is assumed to be array. + This is equivalent to + fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init, + 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 in virtual table that does not contain TOKEN entries. We may overrun |