[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / libcxx / benchmarks / libcxxabi / dynamic_cast.bench.cpp
blob439eea81d9a19c704384bd7ed03ffad3bad78354
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 //===----------------------------------------------------------------------===//
9 #include <cstddef>
11 #include "benchmark/benchmark.h"
13 template <std::size_t Depth>
14 struct Chain : Chain<Depth - 1> {};
16 template <>
17 struct Chain<0> {
18 virtual ~Chain() noexcept = default;
21 template <std::size_t Index, std::size_t Depth>
22 struct Dag : Dag<Index, Depth - 1>, Dag<Index + 1, Depth - 1> {};
24 template <std::size_t Index>
25 struct Dag<Index, 0> {
26 virtual ~Dag() noexcept = default;
29 template <std::size_t Depth>
30 struct VChain : virtual VChain<Depth - 1> {};
32 template <>
33 struct VChain<0> {
34 virtual ~VChain() noexcept = default;
37 template <std::size_t Index, std::size_t Depth>
38 struct VDag : virtual VDag<Index, Depth - 1>, virtual VDag<Index + 1, Depth - 1> {};
40 template <std::size_t Index>
41 struct VDag<Index, 0> {
42 virtual ~VDag() noexcept = default;
45 template <typename Dyn, typename From, typename To = Dyn>
46 static void DynCast(benchmark::State& state) {
47 Dyn obj;
48 From* from_ptr = &obj;
49 for (auto _ : state) {
50 To* to_ptr = dynamic_cast<To*>(from_ptr);
51 benchmark::DoNotOptimize(to_ptr);
55 static void StaticCast(benchmark::State& state) {
56 Chain<9> obj;
57 Chain<0>* from_ptr = &obj;
58 for (auto _ : state) {
59 Chain<9>* to_ptr = static_cast<Chain<9>*>(from_ptr);
60 benchmark::DoNotOptimize(to_ptr);
64 // Downcast along a chain from base to the most derived type
65 BENCHMARK(DynCast<Chain<1>, Chain<0>>)->Name("Chain, 1 level");
66 BENCHMARK(DynCast<Chain<2>, Chain<0>>)->Name("Chain, 2 levels");
67 BENCHMARK(DynCast<Chain<3>, Chain<0>>)->Name("Chain, 3 levels");
68 BENCHMARK(DynCast<Chain<4>, Chain<0>>)->Name("Chain, 4 levels");
69 BENCHMARK(DynCast<Chain<5>, Chain<0>>)->Name("Chain, 5 levels");
70 BENCHMARK(DynCast<Chain<6>, Chain<0>>)->Name("Chain, 6 levels");
71 BENCHMARK(DynCast<Chain<7>, Chain<0>>)->Name("Chain, 7 levels");
72 BENCHMARK(DynCast<Chain<8>, Chain<0>>)->Name("Chain, 8 levels");
73 BENCHMARK(DynCast<Chain<9>, Chain<0>>)->Name("Chain, 9 levels");
75 // Downcast along a chain from base to the middle of the chain
76 BENCHMARK(DynCast<Chain<2>, Chain<0>, Chain<1>>)->Name("Chain middle, 1 level");
77 BENCHMARK(DynCast<Chain<4>, Chain<0>, Chain<2>>)->Name("Chain middle, 2 levels");
78 BENCHMARK(DynCast<Chain<6>, Chain<0>, Chain<3>>)->Name("Chain middle, 3 levels");
79 BENCHMARK(DynCast<Chain<8>, Chain<0>, Chain<4>>)->Name("Chain middle, 4 levels");
81 // Downcast along a chain that fails
82 BENCHMARK(DynCast<Chain<1>, Chain<0>, Chain<9>>)->Name("Chain fail, 1 level");
83 BENCHMARK(DynCast<Chain<2>, Chain<0>, Chain<9>>)->Name("Chain fail, 2 levels");
84 BENCHMARK(DynCast<Chain<3>, Chain<0>, Chain<9>>)->Name("Chain fail, 3 levels");
85 BENCHMARK(DynCast<Chain<4>, Chain<0>, Chain<9>>)->Name("Chain fail, 4 levels");
86 BENCHMARK(DynCast<Chain<5>, Chain<0>, Chain<9>>)->Name("Chain fail, 5 levels");
87 BENCHMARK(DynCast<Chain<6>, Chain<0>, Chain<9>>)->Name("Chain fail, 6 levels");
88 BENCHMARK(DynCast<Chain<7>, Chain<0>, Chain<9>>)->Name("Chain fail, 7 levels");
89 BENCHMARK(DynCast<Chain<8>, Chain<0>, Chain<9>>)->Name("Chain fail, 8 levels");
91 // Downcast along a virtual inheritance chain from base to the most derived type
92 BENCHMARK(DynCast<VChain<1>, VChain<0>>)->Name("VChain, 1 level");
93 BENCHMARK(DynCast<VChain<2>, VChain<0>>)->Name("VChain, 2 levels");
94 BENCHMARK(DynCast<VChain<3>, VChain<0>>)->Name("VChain, 3 levels");
95 BENCHMARK(DynCast<VChain<4>, VChain<0>>)->Name("VChain, 4 levels");
96 BENCHMARK(DynCast<VChain<5>, VChain<0>>)->Name("VChain, 5 levels");
98 // Downcast along a virtual inheritance chain from base to the middle of the chain
99 BENCHMARK(DynCast<VChain<2>, VChain<0>, VChain<1>>)->Name("VChain middle, 1 level");
100 BENCHMARK(DynCast<VChain<4>, VChain<0>, VChain<2>>)->Name("VChain middle, 2 levels");
101 BENCHMARK(DynCast<VChain<6>, VChain<0>, VChain<3>>)->Name("VChain middle, 3 levels");
102 BENCHMARK(DynCast<VChain<8>, VChain<0>, VChain<4>>)->Name("VChain middle, 4 levels");
104 // Downcast along a virtual chain that fails
105 BENCHMARK(DynCast<VChain<1>, VChain<0>, VChain<8>>)->Name("VChain fail, 1 level");
106 BENCHMARK(DynCast<VChain<2>, VChain<0>, VChain<8>>)->Name("VChain fail, 2 levels");
107 BENCHMARK(DynCast<VChain<3>, VChain<0>, VChain<8>>)->Name("VChain fail, 3 levels");
108 BENCHMARK(DynCast<VChain<4>, VChain<0>, VChain<8>>)->Name("VChain fail, 4 levels");
109 BENCHMARK(DynCast<VChain<5>, VChain<0>, VChain<8>>)->Name("VChain fail, 5 levels");
111 // Downcast along a DAG from base to the most derived type
112 BENCHMARK(DynCast<Dag<0, 3>, Dag<3, 0>>)->Name("DAG rightmost, 3 levels");
113 BENCHMARK(DynCast<Dag<0, 4>, Dag<4, 0>>)->Name("DAG rightmost, 4 levels");
114 BENCHMARK(DynCast<Dag<0, 5>, Dag<5, 0>>)->Name("DAG rightmost, 5 levels");
115 BENCHMARK(DynCast<Dag<0, 3>, Dag<0, 0>>)->Name("DAG leftmost, 3 levels");
116 BENCHMARK(DynCast<Dag<0, 4>, Dag<0, 0>>)->Name("DAG leftmost, 4 levels");
117 BENCHMARK(DynCast<Dag<0, 5>, Dag<0, 0>>)->Name("DAG leftmost, 5 levels");
119 // Downcast along a DAG from base to the middle of the DAG
120 BENCHMARK(DynCast<Dag<0, 4>, Dag<4, 0>, Dag<3, 1>>)->Name("DAG rightmost middle, 1 level");
121 BENCHMARK(DynCast<Dag<0, 4>, Dag<4, 0>, Dag<2, 2>>)->Name("DAG rightmost middle, 2 levels");
122 BENCHMARK(DynCast<Dag<0, 4>, Dag<4, 0>, Dag<1, 3>>)->Name("DAG rightmost middle, 3 levels");
123 BENCHMARK(DynCast<Dag<0, 4>, Dag<0, 0>, Dag<0, 1>>)->Name("DAG leftmost middle, 1 level");
124 BENCHMARK(DynCast<Dag<0, 4>, Dag<0, 0>, Dag<0, 2>>)->Name("DAG leftmost middle, 2 levels");
125 BENCHMARK(DynCast<Dag<0, 4>, Dag<0, 0>, Dag<0, 3>>)->Name("DAG leftmost middle, 3 levels");
127 // Sidecast along a DAG
128 BENCHMARK(DynCast<Dag<0, 3>, Dag<3, 0>, Dag<0, 0>>)->Name("DAG sidecast, 3 levels");
129 BENCHMARK(DynCast<Dag<0, 3>, Dag<2, 1>, Dag<0, 1>>)->Name("DAG sidecast, 2 levels");
130 BENCHMARK(DynCast<Dag<0, 3>, Dag<1, 2>, Dag<0, 2>>)->Name("DAG sidecast, 1 level");
132 // Sidecast along a DAG that fails
133 BENCHMARK(DynCast<Dag<0, 3>, Dag<3, 0>, Dag<0, 4>>)->Name("DAG sidecast fail, 3 levels");
134 BENCHMARK(DynCast<Dag<0, 3>, Dag<2, 1>, Dag<0, 4>>)->Name("DAG sidecast fail, 2 levels");
135 BENCHMARK(DynCast<Dag<0, 3>, Dag<1, 2>, Dag<0, 4>>)->Name("DAG sidecast fail, 1 level");
137 // Downcast along a virtual inheritance DAG from base to the most derived type
138 BENCHMARK(DynCast<VDag<0, 3>, VDag<3, 0>>)->Name("VDAG rightmost, 3 levels");
139 BENCHMARK(DynCast<VDag<0, 4>, VDag<4, 0>>)->Name("VDAG rightmost, 4 levels");
140 BENCHMARK(DynCast<VDag<0, 5>, VDag<5, 0>>)->Name("VDAG rightmost, 5 levels");
141 BENCHMARK(DynCast<VDag<0, 3>, VDag<0, 0>>)->Name("VDAG leftmost, 3 levels");
142 BENCHMARK(DynCast<VDag<0, 4>, VDag<0, 0>>)->Name("VDAG leftmost, 4 levels");
143 BENCHMARK(DynCast<VDag<0, 5>, VDag<0, 0>>)->Name("VDAG leftmost, 5 levels");
145 // Downcast along a virtual inheritance DAG from base to the middle of the DAG
146 BENCHMARK(DynCast<VDag<0, 3>, VDag<3, 0>, VDag<2, 1>>)->Name("VDAG rightmost middle, 1 level");
147 BENCHMARK(DynCast<VDag<0, 4>, VDag<4, 0>, VDag<2, 2>>)->Name("VDAG rightmost middle, 2 levels");
148 BENCHMARK(DynCast<VDag<0, 5>, VDag<5, 0>, VDag<2, 3>>)->Name("VDAG rightmost middle, 3 levels");
149 BENCHMARK(DynCast<VDag<0, 3>, VDag<0, 0>, VDag<0, 1>>)->Name("VDAG leftmost middle, 1 level");
150 BENCHMARK(DynCast<VDag<0, 4>, VDag<0, 0>, VDag<0, 2>>)->Name("VDAG leftmost middle, 2 levels");
151 BENCHMARK(DynCast<VDag<0, 5>, VDag<0, 0>, VDag<0, 3>>)->Name("VDAG leftmost middle, 3 levels");
153 // Sidecast along a virtual inheritance DAG
154 BENCHMARK(DynCast<VDag<0, 3>, VDag<3, 0>, VDag<0, 0>>)->Name("VDAG sidecast, 3 levels");
155 BENCHMARK(DynCast<VDag<0, 3>, VDag<2, 1>, VDag<0, 1>>)->Name("VDAG sidecast, 2 levels");
156 BENCHMARK(DynCast<VDag<0, 3>, VDag<1, 2>, VDag<0, 2>>)->Name("VDAG sidecast, 1 level");
158 // Sidecast along a virtual inheritance DAG that fails
159 BENCHMARK(DynCast<VDag<0, 3>, VDag<3, 0>, VDag<0, 4>>)->Name("VDAG sidecast fail, 3 levels");
160 BENCHMARK(DynCast<VDag<0, 3>, VDag<2, 1>, VDag<0, 4>>)->Name("VDAG sidecast fail, 2 levels");
161 BENCHMARK(DynCast<VDag<0, 3>, VDag<1, 2>, VDag<0, 4>>)->Name("VDAG sidecast fail, 1 level");
163 // Cast to complete object pointer
164 BENCHMARK(DynCast<Chain<8>, Chain<0>, void>)->Name("Chain to complete");
165 BENCHMARK(DynCast<VChain<5>, VChain<0>, void>)->Name("VChain to complete");
166 BENCHMARK(DynCast<Dag<0, 3>, Dag<3, 0>, void>)->Name("DAG to complete");
167 BENCHMARK(DynCast<VDag<0, 3>, VDag<3, 0>, void>)->Name("VDAG to complete");
169 // Static cast as the baseline.
170 BENCHMARK(StaticCast)->Name("Static");
172 BENCHMARK_MAIN();