Skip to content

Commit 679c0b4

Browse files
Lancernldionne
authored andcommitted
[libc++abi] Refactor around __dynamic_cast
This commit contains refactorings around __dynamic_cast without changing its behavior. Some important changes include: - Refactor __dynamic_cast into various small helper functions; - Move dynamic_cast_stress.pass.cpp to libcxx/benchmarks and refactor it into a benchmark. The benchmark performance numbers are updated as well. Differential Revision: https://reviews.llvm.org/D138006
1 parent 08de650 commit 679c0b4

File tree

4 files changed

+349
-233
lines changed

4 files changed

+349
-233
lines changed

libcxx/benchmarks/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ set(BENCHMARK_TESTS
183183
algorithms/sort_heap.bench.cpp
184184
algorithms/stable_sort.bench.cpp
185185
libcxxabi/dynamic_cast.bench.cpp
186+
libcxxabi/dynamic_cast_old_stress.bench.cpp
186187
allocation.bench.cpp
187188
deque.bench.cpp
188189
deque_iterator.bench.cpp
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <cassert>
10+
#include <cstddef>
11+
#include <utility>
12+
13+
#include "benchmark/benchmark.h"
14+
15+
template <std::size_t Indx, std::size_t Depth>
16+
struct C : public virtual C<Indx, Depth - 1>, public virtual C<Indx + 1, Depth - 1> {
17+
virtual ~C() {}
18+
};
19+
20+
template <std::size_t Indx>
21+
struct C<Indx, 0> {
22+
virtual ~C() {}
23+
};
24+
25+
template <std::size_t Indx, std::size_t Depth>
26+
struct B : public virtual C<Indx, Depth - 1>, public virtual C<Indx + 1, Depth - 1> {};
27+
28+
template <class Indx, std::size_t Depth>
29+
struct makeB;
30+
31+
template <std::size_t... Indx, std::size_t Depth>
32+
struct makeB<std::index_sequence<Indx...>, Depth> : public B<Indx, Depth>... {};
33+
34+
template <std::size_t Width, std::size_t Depth>
35+
struct A : public makeB<std::make_index_sequence<Width>, Depth> {};
36+
37+
constexpr std::size_t Width = 10;
38+
constexpr std::size_t Depth = 5;
39+
40+
template <typename Destination>
41+
void CastTo(benchmark::State& state) {
42+
A<Width, Depth> a;
43+
auto base = static_cast<C<Width / 2, 0>*>(&a);
44+
45+
Destination* b = nullptr;
46+
for (auto _ : state) {
47+
b = dynamic_cast<Destination*>(base);
48+
benchmark::DoNotOptimize(b);
49+
}
50+
51+
assert(b != 0);
52+
}
53+
54+
BENCHMARK(CastTo<B<Width / 2, Depth>>);
55+
BENCHMARK(CastTo<A<Width, Depth>>);
56+
57+
BENCHMARK_MAIN();
58+
59+
/**
60+
* Benchmark results: (release builds)
61+
*
62+
* libcxxabi:
63+
* ----------------------------------------------------------------------
64+
* Benchmark Time CPU Iterations
65+
* ----------------------------------------------------------------------
66+
* CastTo<B<Width / 2, Depth>> 1997 ns 1997 ns 349247
67+
* CastTo<A<Width, Depth>> 256 ns 256 ns 2733871
68+
*
69+
* libsupc++:
70+
* ----------------------------------------------------------------------
71+
* Benchmark Time CPU Iterations
72+
* ----------------------------------------------------------------------
73+
* CastTo<B<Width / 2, Depth>> 5240 ns 5240 ns 133091
74+
* CastTo<A<Width, Depth>> 866 ns 866 ns 808600
75+
*
76+
*
77+
*/

0 commit comments

Comments
 (0)