[cfe-commits] [libcxxabi] r148246 - in /libcxxabi/trunk: src/private_typeinfo.cpp test/dynamic_cast_stress.cpp www/spec.html

Howard Hinnant hhinnant at apple.com
Mon Jan 16 10:21:05 PST 2012


Author: hhinnant
Date: Mon Jan 16 12:21:05 2012
New Revision: 148246

URL: http://llvm.org/viewvc/llvm-project?rev=148246&view=rev
Log:
One more small optimization:  Where possible, for loops that do a search and then try to break out of the loop early, eliminate the attempt to break out of the loop after the last search.  And with that, I'm declaring __dynamic_cast done.  Though if anyone sees any problems, has suggestions for improvements, or wants to contribute some test cases, that is certainly welcome feedback.

Modified:
    libcxxabi/trunk/src/private_typeinfo.cpp
    libcxxabi/trunk/test/dynamic_cast_stress.cpp
    libcxxabi/trunk/www/spec.html

Modified: libcxxabi/trunk/src/private_typeinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.cpp?rev=148246&r1=148245&r2=148246&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.cpp (original)
+++ libcxxabi/trunk/src/private_typeinfo.cpp Mon Jan 16 12:21:05 2012
@@ -282,12 +282,8 @@
                                                  const void* current_ptr,
                                                  int path_below) const
 {
-    // Record that we found a static_type
-    info->found_any_static_type = true;  // TODO: Consider removing, no one is currently listening
     if (current_ptr == info->static_ptr)
     {
-        // Record that we found (static_ptr, static_type)
-        info->found_our_static_ptr = true;  // TODO: Consider removing, no one is currently listening
         // Record the most public path from (dynamic_ptr, dynamic_type) to
         //                                  (static_ptr, static_type)
         if (info->path_dynamic_ptr_to_static_ptr != public_path)
@@ -424,59 +420,64 @@
     {
         // This is not a static_type and not a dst_type.
         const Iter e = __base_info + __base_count;
-        if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1)
+        Iter p = __base_info;
+        p->search_below_dst(info, current_ptr, path_below);
+        if (++p < e)
         {
-            // If there are multiple paths to a base above from here, or if
-            //    a dst_type pointing to (static_ptr, static_type) has been found,
-            //    then there is no way to break out of this loop early unless
-            //    something below detects the search is done.
-            for (Iter p = __base_info; p < e; ++p)
+            if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1)
             {
-                p->search_below_dst(info, current_ptr, path_below);
-                if (info->search_done)
-                    break;
+                // If there are multiple paths to a base above from here, or if
+                //    a dst_type pointing to (static_ptr, static_type) has been found,
+                //    then there is no way to break out of this loop early unless
+                //    something below detects the search is done.
+                do
+                {
+                    if (info->search_done)
+                        break;
+                    p->search_below_dst(info, current_ptr, path_below);
+                } while (++p < e);
             }
-        }
-        else if (__flags & __non_diamond_repeat_mask)
-        {
-            // There are not multiple paths to any base class from here and a
-            //   dst_type pointing to (static_ptr, static_type) has not yet been
-            //   found.
-            for (Iter p = __base_info; p < e; ++p)
+            else if (__flags & __non_diamond_repeat_mask)
             {
-                p->search_below_dst(info, current_ptr, path_below);
-                if (info->search_done)
-                    break;
-                // If we just found a dst_type with a public path to (static_ptr, static_type),
-                //    then the only reason to continue the search is to make sure
-                //    no other dst_type points to (static_ptr, static_type).
-                //    If !diamond, then we don't need to search here.
-                if (info->number_to_static_ptr == 1 &&
-                          info->path_dst_ptr_to_static_ptr == public_path)
-                    break;
+                // There are not multiple paths to any base class from here and a
+                //   dst_type pointing to (static_ptr, static_type) has not yet been
+                //   found.
+                do
+                {
+                    if (info->search_done)
+                        break;
+                    // If we just found a dst_type with a public path to (static_ptr, static_type),
+                    //    then the only reason to continue the search is to make sure
+                    //    no other dst_type points to (static_ptr, static_type).
+                    //    If !diamond, then we don't need to search here.
+                    if (info->number_to_static_ptr == 1 &&
+                              info->path_dst_ptr_to_static_ptr == public_path)
+                        break;
+                    p->search_below_dst(info, current_ptr, path_below);
+                } while (++p < e);
             }
-        }
-        else
-        {
-            // There are no repeated types above this node.
-            // There are no nodes with multiple parents above this node.
-            // no dst_type has been found to (static_ptr, static_type)
-            for (Iter p = __base_info; p < e; ++p)
+            else
             {
-                p->search_below_dst(info, current_ptr, path_below);
-                if (info->search_done)
-                    break;
-                // If we just found a dst_type with a public path to (static_ptr, static_type),
-                //    then the only reason to continue the search is to make sure sure
-                //    no other dst_type points to (static_ptr, static_type).
-                //    If !diamond, then we don't need to search here.
-                // if we just found a dst_type with a private path to (static_ptr, static_type),
-                //    then we're only looking for a public path to (static_ptr, static_type)
-                //    and to check for other dst_types.
-                //    If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type)
-                //    and not a dst_type under here.
-                if (info->number_to_static_ptr == 1)
-                    break;
+                // There are no repeated types above this node.
+                // There are no nodes with multiple parents above this node.
+                // no dst_type has been found to (static_ptr, static_type)
+                do
+                {
+                    if (info->search_done)
+                        break;
+                    // If we just found a dst_type with a public path to (static_ptr, static_type),
+                    //    then the only reason to continue the search is to make sure sure
+                    //    no other dst_type points to (static_ptr, static_type).
+                    //    If !diamond, then we don't need to search here.
+                    // if we just found a dst_type with a private path to (static_ptr, static_type),
+                    //    then we're only looking for a public path to (static_ptr, static_type)
+                    //    and to check for other dst_types.
+                    //    If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type)
+                    //    and not a dst_type under here.
+                    if (info->number_to_static_ptr == 1)
+                        break;
+                    p->search_below_dst(info, current_ptr, path_below);
+                } while (++p < e);
             }
         }
     }
@@ -640,33 +641,41 @@
         //    3.  We can prove that there is no public path to (static_ptr, static_type)
         //        above here.
         const Iter e = __base_info + __base_count;
-        for (Iter p = __base_info; p < e; ++p)
+        Iter p = __base_info;
+        // Zero out found flags
+        info->found_our_static_ptr = false;
+        info->found_any_static_type = false;
+        p->search_above_dst(info, dst_ptr, current_ptr, path_below);
+        if (++p < e)
         {
-            // Zero out found flags
-            info->found_our_static_ptr = false;
-            info->found_any_static_type = false;
-            p->search_above_dst(info, dst_ptr, current_ptr, path_below);
-            if (info->search_done)
-                break;
-            if (info->found_our_static_ptr)
-            {
-                // If we found what we're looking for, stop looking above.
-                if (info->path_dst_ptr_to_static_ptr == public_path)
-                    break;
-                // We found a private path to (static_ptr, static_type)
-                //   If there is no diamond then there is only one path
-                //   to (static_ptr, static_type) from here and we just found it.
-                if (!(__flags & __diamond_shaped_mask))
-                    break;
-            }
-            else if (info->found_any_static_type)
+            do
             {
-                // If we found a static_type that isn't the one we're looking
-                //    for, and if there are no repeated types above here,
-                //    then stop looking.
-                if (!(__flags & __non_diamond_repeat_mask))
+                if (info->search_done)
                     break;
-            }
+                if (info->found_our_static_ptr)
+                {
+                    // If we found what we're looking for, stop looking above.
+                    if (info->path_dst_ptr_to_static_ptr == public_path)
+                        break;
+                    // We found a private path to (static_ptr, static_type)
+                    //   If there is no diamond then there is only one path
+                    //   to (static_ptr, static_type) from here and we just found it.
+                    if (!(__flags & __diamond_shaped_mask))
+                        break;
+                }
+                else if (info->found_any_static_type)
+                {
+                    // If we found a static_type that isn't the one we're looking
+                    //    for, and if there are no repeated types above here,
+                    //    then stop looking.
+                    if (!(__flags & __non_diamond_repeat_mask))
+                        break;
+                }
+                // Zero out found flags
+                info->found_our_static_ptr = false;
+                info->found_any_static_type = false;
+                p->search_above_dst(info, dst_ptr, current_ptr, path_below);
+            } while (++p < e);
         }
         // Restore flags
         info->found_our_static_ptr = found_our_static_ptr;

Modified: libcxxabi/trunk/test/dynamic_cast_stress.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/dynamic_cast_stress.cpp?rev=148246&r1=148245&r2=148246&view=diff
==============================================================================
--- libcxxabi/trunk/test/dynamic_cast_stress.cpp (original)
+++ libcxxabi/trunk/test/dynamic_cast_stress.cpp Mon Jan 16 12:21:05 2012
@@ -73,9 +73,9 @@
 Timing results I'm seeing (median of 3 microseconds):
 
                           libc++abi    gcc's dynamic_cast
-B<Width/2, Depth> -O3      50.694         93.190           libc++abi 84% faster
-B<Width/2, Depth> -Os      55.235         94.103           libc++abi 70% faster
-A<Width, Depth>   -O3      14.895         33.134           libc++abi 122% faster
-A<Width, Depth>   -Os      16.515         31.553           libc++abi 91% faster
+B<Width/2, Depth> -O3      48.334         93.190           libc++abi 93% faster
+B<Width/2, Depth> -Os      58.535         94.103           libc++abi 61% faster
+A<Width, Depth>   -O3      11.515         33.134           libc++abi 188% faster
+A<Width, Depth>   -Os      12.631         31.553           libc++abi 150% faster
 
 */

Modified: libcxxabi/trunk/www/spec.html
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/www/spec.html?rev=148246&r1=148245&r2=148246&view=diff
==============================================================================
--- libcxxabi/trunk/www/spec.html (original)
+++ libcxxabi/trunk/www/spec.html Mon Jan 16 12:21:05 2012
@@ -824,9 +824,9 @@
 </p>
 </blockquote>
 </td>
-<td></td>
-<td></td>
-<td></td>
+<td>✓</td>
+<td>✓</td>
+<td>✓</td>
 </tr>
 
 </table>





More information about the cfe-commits mailing list