summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/dynamic-cast-hint.cpp
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2013-02-03 19:59:25 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2013-02-03 19:59:25 +0000
commitae3f7608756eb90d8dd5d014238437fcbf1c7de7 (patch)
tree71b4b0fe84f291930c0e6badc2e11bc77f3076cd /test/CodeGenCXX/dynamic-cast-hint.cpp
parent922cec29a9366f70d593d6225aea01dcd3daf8cf (diff)
CodeGen: Implement hint values for dynamic_cast as described in the Itanium C++ ABI.
This can yield dramatic speedups of dynamic_cast for simple inheritance trees, at least with libsupc++. Neither libcxxabi nor libcxxrt make use of this hint currently, it was never implemented because clang didn't support it. There was some concern about the number of class hierarchy walks this change introduces. If it turns out to be an issue we can add caching either at the cast pair level or even deeper, but we also do a lot of walks in Sema so this codepath is probably fairly optimized already. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174293 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/dynamic-cast-hint.cpp')
-rw-r--r--test/CodeGenCXX/dynamic-cast-hint.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/test/CodeGenCXX/dynamic-cast-hint.cpp b/test/CodeGenCXX/dynamic-cast-hint.cpp
new file mode 100644
index 0000000000..bfbae4e623
--- /dev/null
+++ b/test/CodeGenCXX/dynamic-cast-hint.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - %s | FileCheck %s
+
+class A { virtual ~A() {} };
+class B { virtual ~B() {} };
+
+class C : A { char x; };
+class D : public A { short y; };
+class E : public A, public B { int z; };
+class F : public virtual A { long long w; };
+class G : virtual A { long long w; };
+
+class H : public E { int a; };
+class I : public F { char b; };
+
+class J : public H { char q; };
+class K : public C, public B { char q; };
+
+class XA : public A { };
+class XB : public A { };
+class XC : public virtual A { };
+class X : public XA, public XB, public XC { };
+
+void test(A *a, B *b) {
+ volatile C *ac = dynamic_cast<C *>(a);
+// CHECK: call i8* @__dynamic_cast(i8* %2, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* @_ZTI1C to i8*), i64 -2)
+ volatile D *ad = dynamic_cast<D *>(a);
+// CHECK: call i8* @__dynamic_cast(i8* %8, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1D to i8*), i64 0)
+ volatile E *ae = dynamic_cast<E *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }* @_ZTI1E to i8*), i64 0)
+ volatile F *af = dynamic_cast<F *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* @_ZTI1F to i8*), i64 -1)
+ volatile G *ag = dynamic_cast<G *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* @_ZTI1G to i8*), i64 -2)
+ volatile H *ah = dynamic_cast<H *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1H to i8*), i64 0)
+ volatile I *ai = dynamic_cast<I *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1I to i8*), i64 -1)
+ volatile J *aj = dynamic_cast<J *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1J to i8*), i64 0)
+ volatile K *ak = dynamic_cast<K *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }* @_ZTI1K to i8*), i64 -2)
+ volatile X *ax = dynamic_cast<X *>(a);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64, i8*, i64 }* @_ZTI1X to i8*), i64 -1)
+
+ volatile E *be = dynamic_cast<E *>(b);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1B to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }* @_ZTI1E to i8*), i64 8)
+ volatile G *bg = dynamic_cast<G *>(b);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1B to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64 }* @_ZTI1G to i8*), i64 -2)
+ volatile J *bj = dynamic_cast<J *>(b);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1B to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1J to i8*), i64 8)
+ volatile K *bk = dynamic_cast<K *>(b);
+// CHECK: i8* bitcast ({ i8*, i8* }* @_ZTI1B to i8*), i8* bitcast ({ i8*, i8*, i32, i32, i8*, i64, i8*, i64 }* @_ZTI1K to i8*), i64 16)
+}