aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-02-08 00:26:39 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2014-02-07 23:26:39 +0000
commit8c311b50d191ce5aa3574264d4e0cbe604cdcbc7 (patch)
tree4cf6c8e79aad80187b4c85a925b5b93037ecafd3 /gcc
parent63e6247dfe1fb16b2c179d1b1e04b7ca0efb506d (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/gimple-fold.c31
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