]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: small dynamic_cast optimization
authorJason Merrill <jason@redhat.com>
Tue, 6 Sep 2022 14:35:21 +0000 (10:35 -0400)
committerJason Merrill <jason@redhat.com>
Wed, 7 Sep 2022 14:11:54 +0000 (10:11 -0400)
This change speeds up the simple benchmark below by about 40%.

struct A { virtual ~A() {} };
struct B: A { } b;
A* ap = &b;
void *sink;
int main()
{
  for (long i = 0; i < 4000000000L; ++i)
    sink = dynamic_cast<B*>(ap);
}

libstdc++-v3/ChangeLog:

* libsupc++/dyncast.cc (__dynamic_cast): Avoid virtual function
call in simple success case.

libstdc++-v3/libsupc++/dyncast.cc

index 853c911a4cf93beed17598f5c336b8c91c91b240..616e4c05766e159cdbce7c5906ada02e7b33ba9b 100644 (file)
@@ -71,6 +71,12 @@ __dynamic_cast (const void *src_ptr,    // object started from
   if (whole_prefix->whole_type != whole_type)
     return NULL;
 
+  // Avoid virtual function call in the simple success case.
+  if (src2dst >= 0
+      && src2dst == -prefix->whole_object
+      && *whole_type == *dst_type)
+    return const_cast <void *> (whole_ptr);
+
   whole_type->__do_dyncast (src2dst, __class_type_info::__contained_public,
                             dst_type, whole_ptr, src_type, src_ptr, result);
   if (!result.dst_ptr)