From 7fe65d691dcce550d53ec9310913aab67ab6d654 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 27 Mar 2013 16:43:11 +0000 Subject: [PATCH] Cleanup the simplify_type implementation. As far as simplify_type is concerned, there are 3 kinds of smart pointers: * const correct: A 'const MyPtr &' produces a 'const int*'. A 'MyPtr &' produces a 'int *'. * always const: Even a 'MyPtr &' produces a 'const int*'. * no const: Even a 'const MyPtr &' produces a 'int*'. This patch then does the following: * Removes the unused specializations. Since they are unused, it is hard to know which kind should be implemented. * Make sure we don't drop const. * Fix the default forwarding so that const correct pointer only need one specialization. * Simplifies the existing specializations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178147 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/IntrusiveRefCntPtr.h | 4 +- include/llvm/ADT/Optional.h | 14 ------- include/llvm/ADT/ilist.h | 4 +- include/llvm/CodeGen/SelectionDAGNodes.h | 18 +++------ include/llvm/IR/Use.h | 8 ++-- include/llvm/IR/User.h | 20 +++------- include/llvm/Support/Casting.h | 48 ++++++++++++------------ include/llvm/Support/ValueHandle.h | 45 ++-------------------- include/llvm/Support/type_traits.h | 20 ++++++++++ 9 files changed, 67 insertions(+), 114 deletions(-) diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index 9e5ab021a50..b8b88619957 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -226,13 +226,13 @@ namespace llvm { template struct simplify_type > { typedef T* SimpleType; - static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr& Val) { + static SimpleType getSimplifiedValue(IntrusiveRefCntPtr& Val) { return Val.getPtr(); } }; template struct simplify_type > { - typedef T* SimpleType; + typedef /*const*/ T* SimpleType; static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr& Val) { return Val.getPtr(); } diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index 81d73ed8b99..194e53fac21 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -128,20 +128,6 @@ public: #endif }; -template struct simplify_type; - -template -struct simplify_type > { - typedef const T* SimpleType; - static SimpleType getSimplifiedValue(const Optional &Val) { - return Val.getPointer(); - } -}; - -template -struct simplify_type > - : public simplify_type > {}; - template struct isPodLike; template struct isPodLike > { // An Optional is pod-like if T is. diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index aeb78484c61..71dab2ef551 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -274,12 +274,12 @@ template struct simplify_type; template struct simplify_type > { typedef NodeTy* SimpleType; - static SimpleType getSimplifiedValue(const ilist_iterator &Node) { + static SimpleType getSimplifiedValue(ilist_iterator &Node) { return &*Node; } }; template struct simplify_type > { - typedef NodeTy* SimpleType; + typedef /*const*/ NodeTy* SimpleType; static SimpleType getSimplifiedValue(const ilist_iterator &Node) { return &*Node; diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 05f3b1494fa..fef567f56bc 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -196,14 +196,14 @@ template <> struct isPodLike { static const bool value = true; }; /// SDValues as if they were SDNode*'s. template<> struct simplify_type { typedef SDNode* SimpleType; - static SimpleType getSimplifiedValue(const SDValue &Val) { - return static_cast(Val.getNode()); + static SimpleType getSimplifiedValue(SDValue &Val) { + return Val.getNode(); } }; template<> struct simplify_type { - typedef SDNode* SimpleType; + typedef /*const*/ SDNode* SimpleType; static SimpleType getSimplifiedValue(const SDValue &Val) { - return static_cast(Val.getNode()); + return Val.getNode(); } }; @@ -295,14 +295,8 @@ private: /// SDValues as if they were SDNode*'s. template<> struct simplify_type { typedef SDNode* SimpleType; - static SimpleType getSimplifiedValue(const SDUse &Val) { - return static_cast(Val.getNode()); - } -}; -template<> struct simplify_type { - typedef SDNode* SimpleType; - static SimpleType getSimplifiedValue(const SDUse &Val) { - return static_cast(Val.getNode()); + static SimpleType getSimplifiedValue(SDUse &Val) { + return Val.getNode(); } }; diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 33a69c46866..4bc7ce50005 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -149,14 +149,14 @@ private: // casting operators. template<> struct simplify_type { typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const Use &Val) { - return static_cast(Val.get()); + static SimpleType getSimplifiedValue(Use &Val) { + return Val.get(); } }; template<> struct simplify_type { - typedef Value* SimpleType; + typedef /*const*/ Value* SimpleType; static SimpleType getSimplifiedValue(const Use &Val) { - return static_cast(Val.get()); + return Val.get(); } }; diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index a4d0a5d7df0..505bdeb178e 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -183,27 +183,17 @@ public: template<> struct simplify_type { typedef Value* SimpleType; - - static SimpleType getSimplifiedValue(const User::op_iterator &Val) { - return static_cast(Val->get()); + static SimpleType getSimplifiedValue(User::op_iterator &Val) { + return Val->get(); } }; - -template<> struct simplify_type - : public simplify_type {}; - template<> struct simplify_type { - typedef Value* SimpleType; - - static SimpleType getSimplifiedValue(const User::const_op_iterator &Val) { - return static_cast(Val->get()); + typedef /*const*/ Value* SimpleType; + static SimpleType getSimplifiedValue(User::const_op_iterator &Val) { + return Val->get(); } }; -template<> struct simplify_type - : public simplify_type {}; - - // value_use_iterator::getOperandNo - Requires the definition of the User class. template unsigned value_use_iterator::getOperandNo() const { diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index 80f09db4f7a..0d2d6c92fdb 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -36,9 +36,13 @@ template struct simplify_type { }; template struct simplify_type { - typedef const From SimpleType; - static SimpleType &getSimplifiedValue(const From &Val) { - return simplify_type::getSimplifiedValue(static_cast(Val)); + typedef typename simplify_type::SimpleType NonConstSimpleType; + typedef typename add_const_past_pointer::type + SimpleType; + typedef typename add_lvalue_reference_if_not_pointer::type + RetType; + static RetType getSimplifiedValue(const From& Val) { + return simplify_type::getSimplifiedValue(const_cast(Val)); } }; @@ -81,6 +85,13 @@ template struct isa_impl_cl { } }; +template struct isa_impl_cl { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl::doit(*Val); + } +}; + template struct isa_impl_cl { static inline bool doit(const From *Val) { assert(Val && "isa<> used on a null pointer"); @@ -102,7 +113,7 @@ struct isa_impl_wrap { static bool doit(const From &Val) { return isa_impl_wrap::SimpleType>::doit( - simplify_type::getSimplifiedValue(Val)); + simplify_type::getSimplifiedValue(Val)); } }; @@ -121,7 +132,8 @@ struct isa_impl_wrap { // template inline bool isa(const Y &Val) { - return isa_impl_wrap::SimpleType>::doit(Val); + return isa_impl_wrap::SimpleType>::doit(Val); } //===----------------------------------------------------------------------===// @@ -178,7 +190,7 @@ struct cast_retty { // template struct cast_convert_val { // This is not a simple type, use the template to simplify it... - static typename cast_retty::ret_type doit(const From &Val) { + static typename cast_retty::ret_type doit(From &Val) { return cast_convert_val::SimpleType>::doit( simplify_type::getSimplifiedValue(Val)); @@ -204,20 +216,14 @@ template struct cast_convert_val { // cast(myVal)->getParent() // template -inline typename enable_if_c< - !is_same::SimpleType>::value, - typename cast_retty::ret_type ->::type cast(const Y &Val) { +inline typename cast_retty::ret_type cast(const Y &Val) { assert(isa(Val) && "cast() argument of incompatible type!"); - return cast_convert_val::SimpleType>::doit(Val); + return cast_convert_val::SimpleType>::doit(Val); } template -inline typename enable_if< - is_same::SimpleType>, - typename cast_retty::ret_type ->::type cast(Y &Val) { +inline typename cast_retty::ret_type cast(Y &Val) { assert(isa(Val) && "cast() argument of incompatible type!"); return cast_convert_val::SimpleType>::doit(Val); @@ -253,18 +259,12 @@ inline typename cast_retty::ret_type cast_or_null(Y *Val) { // template -inline typename enable_if_c< - !is_same::SimpleType>::value, - typename cast_retty::ret_type ->::type dyn_cast(const Y &Val) { +inline typename cast_retty::ret_type dyn_cast(const Y &Val) { return isa(Val) ? cast(Val) : 0; } template -inline typename enable_if< - is_same::SimpleType>, - typename cast_retty::ret_type ->::type dyn_cast(Y &Val) { +inline typename cast_retty::ret_type dyn_cast(Y &Val) { return isa(Val) ? cast(Val) : 0; } diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h index db44995d95b..b49341c3ffb 100644 --- a/include/llvm/Support/ValueHandle.h +++ b/include/llvm/Support/ValueHandle.h @@ -20,6 +20,7 @@ namespace llvm { class ValueHandleBase; +template struct simplify_type; // ValueHandleBase** is only 4-byte aligned. template<> @@ -162,14 +163,12 @@ public: // Specialize simplify_type to allow WeakVH to participate in // dyn_cast, isa, etc. -template struct simplify_type; -template<> struct simplify_type { +template<> struct simplify_type { typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const WeakVH &WVH) { - return static_cast(WVH); + static SimpleType getSimplifiedValue(WeakVH &WVH) { + return WVH; } }; -template<> struct simplify_type : public simplify_type {}; /// AssertingVH - This is a Value Handle that points to a value and asserts out /// if the value is destroyed while the handle is still live. This is very @@ -236,18 +235,6 @@ public: ValueTy &operator*() const { return *getValPtr(); } }; -// Specialize simplify_type to allow AssertingVH to participate in -// dyn_cast, isa, etc. -template struct simplify_type; -template<> struct simplify_type > { - typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const AssertingVH &AVH) { - return static_cast(AVH); - } -}; -template<> struct simplify_type > - : public simplify_type > {}; - // Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap. template struct DenseMapInfo > { @@ -345,18 +332,6 @@ public: ValueTy &operator*() const { return *getValPtr(); } }; -// Specialize simplify_type to allow TrackingVH to participate in -// dyn_cast, isa, etc. -template struct simplify_type; -template<> struct simplify_type > { - typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const TrackingVH &AVH) { - return static_cast(AVH); - } -}; -template<> struct simplify_type > - : public simplify_type > {}; - /// CallbackVH - This is a value handle that allows subclasses to define /// callbacks that run when the underlying Value has RAUW called on it or is /// destroyed. This class can be used as the key of a map, as long as the user @@ -399,18 +374,6 @@ public: virtual void allUsesReplacedWith(Value *); }; -// Specialize simplify_type to allow CallbackVH to participate in -// dyn_cast, isa, etc. -template struct simplify_type; -template<> struct simplify_type { - typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const CallbackVH &CVH) { - return static_cast(CVH); - } -}; -template<> struct simplify_type - : public simplify_type {}; - } // End llvm namespace #endif diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index db43ccfece1..906e97c91fb 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -209,6 +209,26 @@ template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; +// If T is a pointer, just return it. If it is not, return T&. +template +struct add_lvalue_reference_if_not_pointer { typedef T &type; }; + +template +struct add_lvalue_reference_if_not_pointer >::type> { + typedef T type; +}; + +// If T is a pointer to X, return a pointer to const X. If it is not, return +// const T. +template +struct add_const_past_pointer { typedef const T type; }; + +template +struct add_const_past_pointer >::type> { + typedef const typename remove_pointer::type *type; +}; + template struct conditional { typedef T type; };