Add super fast _IsSame trait for internal use.

Clang provides __is_same that doesn't produce any instantiations
and just returns a bool. It's a lot faster than using std::is_same

I'll follow up with a patch to actually start using it.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@364148 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/type_traits b/include/type_traits
index 05405c9..def01d4 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -542,6 +542,26 @@
 template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
 #endif
 
+// is_same
+
+template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same           : public false_type {};
+template <class _Tp>            struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {};
+
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp, class _Up>
+_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v
+    = is_same<_Tp, _Up>::value;
+#endif
+
+template <class _Tp, class _Up>
+using _IsSame = _BoolConstant<
+#ifdef __clang__
+    __is_same(_Tp, _Up)
+#else
+    _VSTD::is_same<_Tp, _Up>::value
+#endif
+>;
+
 // addressof
 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
 
@@ -933,17 +953,6 @@
     = is_class<_Tp>::value;
 #endif
 
-// is_same
-
-template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same           : public false_type {};
-template <class _Tp>            struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {};
-
-#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
-template <class _Tp, class _Up>
-_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v
-    = is_same<_Tp, _Up>::value;
-#endif
-
 // is_function
 
 namespace __libcpp_is_function_imp
diff --git a/test/libcxx/utilities/meta/stress_tests/stress_test_is_same.sh.cpp b/test/libcxx/utilities/meta/stress_tests/stress_test_is_same.sh.cpp
new file mode 100644
index 0000000..8e3f0d1
--- /dev/null
+++ b/test/libcxx/utilities/meta/stress_tests/stress_test_is_same.sh.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a dummy feature that prevents this test from running by default.
+
+
+// The table below compares the compile time and object size for each of the
+// variants listed in the RUN script.
+//
+//  Impl          Compile Time    Object Size
+// -------------------------------------------
+// std::_IsSame:    689.634 ms     356 K
+// std::is_same:  8,129.180 ms     560 K
+//
+// RUN: %cxx %flags %compile_flags -c %s -o %S/orig.o -ggdb  -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17
+// RUN: %cxx %flags %compile_flags -c %s -o %S/new.o -ggdb  -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17 -DTEST_NEW
+
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "template_cost_testing.h"
+
+template <int N> struct Arg { enum { value = 1 }; };
+
+#ifdef TEST_NEW
+#define IS_SAME  std::_IsSame
+#else
+#define IS_SAME std::is_same
+#endif
+
+#define TEST_CASE_NOP() IS_SAME < Arg< __COUNTER__ >, Arg < __COUNTER__ > >::value,
+#define TEST_CASE_TYPE() IS_SAME < Arg< __COUNTER__ >, Arg < __COUNTER__ > >,
+
+int sink(...);
+
+int x = sink(
+  REPEAT_10000(TEST_CASE_NOP)
+  REPEAT_10000(TEST_CASE_NOP) 42
+);
+
+void Foo( REPEAT_1000(TEST_CASE_TYPE) int) { }
+
+static_assert(__COUNTER__ > 10000, "");
+
+void escape() {
+
+sink(&x);
+sink(&Foo);
+}
+
+