[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