LLVM  14.0.0git
PointerLikeTypeTraits.h
Go to the documentation of this file.
1 //===- llvm/Support/PointerLikeTypeTraits.h - Pointer Traits ----*- C++ -*-===//
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 // This file defines the PointerLikeTypeTraits class. This allows data
10 // structures to reason about pointers and other things that are pointer sized.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
15 #define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
16 
17 #include "llvm/Support/DataTypes.h"
18 #include <cassert>
19 #include <type_traits>
20 
21 namespace llvm {
22 
23 /// A traits type that is used to handle pointer types and things that are just
24 /// wrappers for pointers as a uniform entity.
25 template <typename T> struct PointerLikeTypeTraits;
26 
27 namespace detail {
28 /// A tiny meta function to compute the log2 of a compile time constant.
29 template <size_t N>
31  : std::integral_constant<size_t, ConstantLog2<N / 2>::value + 1> {};
32 template <> struct ConstantLog2<1> : std::integral_constant<size_t, 0> {};
33 
34 // Provide a trait to check if T is pointer-like.
35 template <typename T, typename U = void> struct HasPointerLikeTypeTraits {
36  static const bool value = false;
37 };
38 
39 // sizeof(T) is valid only for a complete T.
40 template <typename T>
42  T, decltype((sizeof(PointerLikeTypeTraits<T>) + sizeof(T)), void())> {
43  static const bool value = true;
44 };
45 
46 template <typename T> struct IsPointerLike {
48 };
49 
50 template <typename T> struct IsPointerLike<T *> {
51  static const bool value = true;
52 };
53 } // namespace detail
54 
55 // Provide PointerLikeTypeTraits for non-cvr pointers.
56 template <typename T> struct PointerLikeTypeTraits<T *> {
57  static inline void *getAsVoidPointer(T *P) { return P; }
58  static inline T *getFromVoidPointer(void *P) { return static_cast<T *>(P); }
59 
60  static constexpr int NumLowBitsAvailable =
61  detail::ConstantLog2<alignof(T)>::value;
62 };
63 
64 template <> struct PointerLikeTypeTraits<void *> {
65  static inline void *getAsVoidPointer(void *P) { return P; }
66  static inline void *getFromVoidPointer(void *P) { return P; }
67 
68  /// Note, we assume here that void* is related to raw malloc'ed memory and
69  /// that malloc returns objects at least 4-byte aligned. However, this may be
70  /// wrong, or pointers may be from something other than malloc. In this case,
71  /// you should specify a real typed pointer or avoid this template.
72  ///
73  /// All clients should use assertions to do a run-time check to ensure that
74  /// this is actually true.
75  static constexpr int NumLowBitsAvailable = 2;
76 };
77 
78 // Provide PointerLikeTypeTraits for const things.
79 template <typename T> struct PointerLikeTypeTraits<const T> {
81 
82  static inline const void *getAsVoidPointer(const T P) {
83  return NonConst::getAsVoidPointer(P);
84  }
85  static inline const T getFromVoidPointer(const void *P) {
86  return NonConst::getFromVoidPointer(const_cast<void *>(P));
87  }
88  static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
89 };
90 
91 // Provide PointerLikeTypeTraits for const pointers.
92 template <typename T> struct PointerLikeTypeTraits<const T *> {
94 
95  static inline const void *getAsVoidPointer(const T *P) {
96  return NonConst::getAsVoidPointer(const_cast<T *>(P));
97  }
98  static inline const T *getFromVoidPointer(const void *P) {
99  return NonConst::getFromVoidPointer(const_cast<void *>(P));
100  }
101  static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
102 };
103 
104 // Provide PointerLikeTypeTraits for uintptr_t.
105 template <> struct PointerLikeTypeTraits<uintptr_t> {
106  static inline void *getAsVoidPointer(uintptr_t P) {
107  return reinterpret_cast<void *>(P);
108  }
109  static inline uintptr_t getFromVoidPointer(void *P) {
110  return reinterpret_cast<uintptr_t>(P);
111  }
112  // No bits are available!
113  static constexpr int NumLowBitsAvailable = 0;
114 };
115 
116 /// Provide suitable custom traits struct for function pointers.
117 ///
118 /// Function pointers can't be directly given these traits as functions can't
119 /// have their alignment computed with `alignof` and we need different casting.
120 ///
121 /// To rely on higher alignment for a specialized use, you can provide a
122 /// customized form of this template explicitly with higher alignment, and
123 /// potentially use alignment attributes on functions to satisfy that.
124 template <int Alignment, typename FunctionPointerT>
126  static constexpr int NumLowBitsAvailable =
128  static inline void *getAsVoidPointer(FunctionPointerT P) {
129  assert((reinterpret_cast<uintptr_t>(P) &
130  ~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 &&
131  "Alignment not satisfied for an actual function pointer!");
132  return reinterpret_cast<void *>(P);
133  }
134  static inline FunctionPointerT getFromVoidPointer(void *P) {
135  return reinterpret_cast<FunctionPointerT>(P);
136  }
137 };
138 
139 /// Provide a default specialization for function pointers that assumes 4-byte
140 /// alignment.
141 ///
142 /// We assume here that functions used with this are always at least 4-byte
143 /// aligned. This means that, for example, thumb functions won't work or systems
144 /// with weird unaligned function pointers won't work. But all practical systems
145 /// we support satisfy this requirement.
146 template <typename ReturnT, typename... ParamTs>
147 struct PointerLikeTypeTraits<ReturnT (*)(ParamTs...)>
148  : FunctionPointerLikeTypeTraits<4, ReturnT (*)(ParamTs...)> {};
149 
150 } // end namespace llvm
151 
152 #endif
llvm::PointerLikeTypeTraits< uintptr_t >::getAsVoidPointer
static void * getAsVoidPointer(uintptr_t P)
Definition: PointerLikeTypeTraits.h:106
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::detail::ConstantLog2
A tiny meta function to compute the log2 of a compile time constant.
Definition: PointerLikeTypeTraits.h:30
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::PointerLikeTypeTraits< void * >::getAsVoidPointer
static void * getAsVoidPointer(void *P)
Definition: PointerLikeTypeTraits.h:65
llvm::PointerLikeTypeTraits< const T * >::getAsVoidPointer
static const void * getAsVoidPointer(const T *P)
Definition: PointerLikeTypeTraits.h:95
llvm::PointerLikeTypeTraits< const T >::getFromVoidPointer
static const T getFromVoidPointer(const void *P)
Definition: PointerLikeTypeTraits.h:85
llvm::detail::IsPointerLike::value
static const bool value
Definition: PointerLikeTypeTraits.h:47
llvm::PointerLikeTypeTraits< T * >
Definition: PointerLikeTypeTraits.h:56
llvm::FunctionPointerLikeTypeTraits::NumLowBitsAvailable
static constexpr int NumLowBitsAvailable
Definition: PointerLikeTypeTraits.h:126
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::FunctionPointerLikeTypeTraits::getAsVoidPointer
static void * getAsVoidPointer(FunctionPointerT P)
Definition: PointerLikeTypeTraits.h:128
llvm::PointerLikeTypeTraits< const T >::getAsVoidPointer
static const void * getAsVoidPointer(const T P)
Definition: PointerLikeTypeTraits.h:82
llvm::detail::IsPointerLike
Definition: PointerLikeTypeTraits.h:46
llvm::PointerLikeTypeTraits< const T * >::NonConst
PointerLikeTypeTraits< T * > NonConst
Definition: PointerLikeTypeTraits.h:93
llvm::detail::HasPointerLikeTypeTraits::value
static const bool value
Definition: PointerLikeTypeTraits.h:36
llvm::FunctionPointerLikeTypeTraits::getFromVoidPointer
static FunctionPointerT getFromVoidPointer(void *P)
Definition: PointerLikeTypeTraits.h:134
llvm::PointerLikeTypeTraits< const T * >::getFromVoidPointer
static const T * getFromVoidPointer(const void *P)
Definition: PointerLikeTypeTraits.h:98
llvm::PointerLikeTypeTraits< uintptr_t >::getFromVoidPointer
static uintptr_t getFromVoidPointer(void *P)
Definition: PointerLikeTypeTraits.h:109
llvm::PointerLikeTypeTraits
A traits type that is used to handle pointer types and things that are just wrappers for pointers as ...
Definition: PointerLikeTypeTraits.h:25
llvm::PointerLikeTypeTraits< const T >::NonConst
PointerLikeTypeTraits< T > NonConst
Definition: PointerLikeTypeTraits.h:80
llvm::PointerLikeTypeTraits< T * >::getAsVoidPointer
static void * getAsVoidPointer(T *P)
Definition: PointerLikeTypeTraits.h:57
DataTypes.h
llvm::PointerLikeTypeTraits< void * >::getFromVoidPointer
static void * getFromVoidPointer(void *P)
Definition: PointerLikeTypeTraits.h:66
llvm::detail::HasPointerLikeTypeTraits
Definition: PointerLikeTypeTraits.h:35
llvm::FunctionPointerLikeTypeTraits
Provide suitable custom traits struct for function pointers.
Definition: PointerLikeTypeTraits.h:125
llvm::PointerLikeTypeTraits< T * >::getFromVoidPointer
static T * getFromVoidPointer(void *P)
Definition: PointerLikeTypeTraits.h:58