xref: /aosp_15_r20/external/pytorch/c10/util/AlignOf.h (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker //===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
2*da0073e9SAndroid Build Coastguard Worker //
3*da0073e9SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*da0073e9SAndroid Build Coastguard Worker //
5*da0073e9SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*da0073e9SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*da0073e9SAndroid Build Coastguard Worker //
8*da0073e9SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*da0073e9SAndroid Build Coastguard Worker //
10*da0073e9SAndroid Build Coastguard Worker // This file defines the AlignedCharArray and AlignedCharArrayUnion classes.
11*da0073e9SAndroid Build Coastguard Worker //
12*da0073e9SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*da0073e9SAndroid Build Coastguard Worker 
14*da0073e9SAndroid Build Coastguard Worker // ATen: modified from llvm::AlignOf
15*da0073e9SAndroid Build Coastguard Worker // replaced LLVM_ALIGNAS with alignas
16*da0073e9SAndroid Build Coastguard Worker 
17*da0073e9SAndroid Build Coastguard Worker #pragma once
18*da0073e9SAndroid Build Coastguard Worker 
19*da0073e9SAndroid Build Coastguard Worker #include <cstddef>
20*da0073e9SAndroid Build Coastguard Worker 
21*da0073e9SAndroid Build Coastguard Worker namespace c10 {
22*da0073e9SAndroid Build Coastguard Worker 
23*da0073e9SAndroid Build Coastguard Worker /// \struct AlignedCharArray
24*da0073e9SAndroid Build Coastguard Worker /// \brief Helper for building an aligned character array type.
25*da0073e9SAndroid Build Coastguard Worker ///
26*da0073e9SAndroid Build Coastguard Worker /// This template is used to explicitly build up a collection of aligned
27*da0073e9SAndroid Build Coastguard Worker /// character array types. We have to build these up using a macro and explicit
28*da0073e9SAndroid Build Coastguard Worker /// specialization to cope with MSVC (at least till 2015) where only an
29*da0073e9SAndroid Build Coastguard Worker /// integer literal can be used to specify an alignment constraint. Once built
30*da0073e9SAndroid Build Coastguard Worker /// up here, we can then begin to indirect between these using normal C++
31*da0073e9SAndroid Build Coastguard Worker /// template parameters.
32*da0073e9SAndroid Build Coastguard Worker 
33*da0073e9SAndroid Build Coastguard Worker // MSVC requires special handling here.
34*da0073e9SAndroid Build Coastguard Worker #ifndef _MSC_VER
35*da0073e9SAndroid Build Coastguard Worker 
36*da0073e9SAndroid Build Coastguard Worker template <size_t Alignment, size_t Size>
37*da0073e9SAndroid Build Coastguard Worker struct AlignedCharArray {
38*da0073e9SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(*c-arrays)
39*da0073e9SAndroid Build Coastguard Worker   alignas(Alignment) char buffer[Size];
40*da0073e9SAndroid Build Coastguard Worker };
41*da0073e9SAndroid Build Coastguard Worker 
42*da0073e9SAndroid Build Coastguard Worker #else // _MSC_VER
43*da0073e9SAndroid Build Coastguard Worker 
44*da0073e9SAndroid Build Coastguard Worker /// \brief Create a type with an aligned char buffer.
45*da0073e9SAndroid Build Coastguard Worker template <size_t Alignment, size_t Size>
46*da0073e9SAndroid Build Coastguard Worker struct AlignedCharArray;
47*da0073e9SAndroid Build Coastguard Worker 
48*da0073e9SAndroid Build Coastguard Worker // We provide special variations of this template for the most common
49*da0073e9SAndroid Build Coastguard Worker // alignments because __declspec(align(...)) doesn't actually work when it is
50*da0073e9SAndroid Build Coastguard Worker // a member of a by-value function argument in MSVC, even if the alignment
51*da0073e9SAndroid Build Coastguard Worker // request is something reasonably like 8-byte or 16-byte. Note that we can't
52*da0073e9SAndroid Build Coastguard Worker // even include the declspec with the union that forces the alignment because
53*da0073e9SAndroid Build Coastguard Worker // MSVC warns on the existence of the declspec despite the union member forcing
54*da0073e9SAndroid Build Coastguard Worker // proper alignment.
55*da0073e9SAndroid Build Coastguard Worker 
56*da0073e9SAndroid Build Coastguard Worker template <size_t Size>
57*da0073e9SAndroid Build Coastguard Worker struct AlignedCharArray<1, Size> {
58*da0073e9SAndroid Build Coastguard Worker   union {
59*da0073e9SAndroid Build Coastguard Worker     char aligned;
60*da0073e9SAndroid Build Coastguard Worker     char buffer[Size];
61*da0073e9SAndroid Build Coastguard Worker   };
62*da0073e9SAndroid Build Coastguard Worker };
63*da0073e9SAndroid Build Coastguard Worker 
64*da0073e9SAndroid Build Coastguard Worker template <size_t Size>
65*da0073e9SAndroid Build Coastguard Worker struct AlignedCharArray<2, Size> {
66*da0073e9SAndroid Build Coastguard Worker   union {
67*da0073e9SAndroid Build Coastguard Worker     short aligned;
68*da0073e9SAndroid Build Coastguard Worker     char buffer[Size];
69*da0073e9SAndroid Build Coastguard Worker   };
70*da0073e9SAndroid Build Coastguard Worker };
71*da0073e9SAndroid Build Coastguard Worker 
72*da0073e9SAndroid Build Coastguard Worker template <size_t Size>
73*da0073e9SAndroid Build Coastguard Worker struct AlignedCharArray<4, Size> {
74*da0073e9SAndroid Build Coastguard Worker   union {
75*da0073e9SAndroid Build Coastguard Worker     int aligned;
76*da0073e9SAndroid Build Coastguard Worker     char buffer[Size];
77*da0073e9SAndroid Build Coastguard Worker   };
78*da0073e9SAndroid Build Coastguard Worker };
79*da0073e9SAndroid Build Coastguard Worker 
80*da0073e9SAndroid Build Coastguard Worker template <size_t Size>
81*da0073e9SAndroid Build Coastguard Worker struct AlignedCharArray<8, Size> {
82*da0073e9SAndroid Build Coastguard Worker   union {
83*da0073e9SAndroid Build Coastguard Worker     double aligned;
84*da0073e9SAndroid Build Coastguard Worker     char buffer[Size];
85*da0073e9SAndroid Build Coastguard Worker   };
86*da0073e9SAndroid Build Coastguard Worker };
87*da0073e9SAndroid Build Coastguard Worker 
88*da0073e9SAndroid Build Coastguard Worker // The rest of these are provided with a __declspec(align(...)) and we simply
89*da0073e9SAndroid Build Coastguard Worker // can't pass them by-value as function arguments on MSVC.
90*da0073e9SAndroid Build Coastguard Worker 
91*da0073e9SAndroid Build Coastguard Worker #define AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
92*da0073e9SAndroid Build Coastguard Worker   template <size_t Size>                          \
93*da0073e9SAndroid Build Coastguard Worker   struct AlignedCharArray<x, Size> {              \
94*da0073e9SAndroid Build Coastguard Worker     __declspec(align(x)) char buffer[Size];       \
95*da0073e9SAndroid Build Coastguard Worker   };
96*da0073e9SAndroid Build Coastguard Worker 
97*da0073e9SAndroid Build Coastguard Worker AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
98*da0073e9SAndroid Build Coastguard Worker AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
99*da0073e9SAndroid Build Coastguard Worker AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
100*da0073e9SAndroid Build Coastguard Worker AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
101*da0073e9SAndroid Build Coastguard Worker 
102*da0073e9SAndroid Build Coastguard Worker #undef AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
103*da0073e9SAndroid Build Coastguard Worker 
104*da0073e9SAndroid Build Coastguard Worker #endif // _MSC_VER
105*da0073e9SAndroid Build Coastguard Worker 
106*da0073e9SAndroid Build Coastguard Worker namespace detail {
107*da0073e9SAndroid Build Coastguard Worker template <
108*da0073e9SAndroid Build Coastguard Worker     typename T1,
109*da0073e9SAndroid Build Coastguard Worker     typename T2 = char,
110*da0073e9SAndroid Build Coastguard Worker     typename T3 = char,
111*da0073e9SAndroid Build Coastguard Worker     typename T4 = char,
112*da0073e9SAndroid Build Coastguard Worker     typename T5 = char,
113*da0073e9SAndroid Build Coastguard Worker     typename T6 = char,
114*da0073e9SAndroid Build Coastguard Worker     typename T7 = char,
115*da0073e9SAndroid Build Coastguard Worker     typename T8 = char,
116*da0073e9SAndroid Build Coastguard Worker     typename T9 = char,
117*da0073e9SAndroid Build Coastguard Worker     typename T10 = char>
118*da0073e9SAndroid Build Coastguard Worker class AlignerImpl {
119*da0073e9SAndroid Build Coastguard Worker   T1 t1;
120*da0073e9SAndroid Build Coastguard Worker   T2 t2;
121*da0073e9SAndroid Build Coastguard Worker   T3 t3;
122*da0073e9SAndroid Build Coastguard Worker   T4 t4;
123*da0073e9SAndroid Build Coastguard Worker   T5 t5;
124*da0073e9SAndroid Build Coastguard Worker   T6 t6;
125*da0073e9SAndroid Build Coastguard Worker   T7 t7;
126*da0073e9SAndroid Build Coastguard Worker   T8 t8;
127*da0073e9SAndroid Build Coastguard Worker   T9 t9;
128*da0073e9SAndroid Build Coastguard Worker   T10 t10;
129*da0073e9SAndroid Build Coastguard Worker 
130*da0073e9SAndroid Build Coastguard Worker  public:
131*da0073e9SAndroid Build Coastguard Worker   AlignerImpl() = delete;
132*da0073e9SAndroid Build Coastguard Worker };
133*da0073e9SAndroid Build Coastguard Worker 
134*da0073e9SAndroid Build Coastguard Worker template <
135*da0073e9SAndroid Build Coastguard Worker     typename T1,
136*da0073e9SAndroid Build Coastguard Worker     typename T2 = char,
137*da0073e9SAndroid Build Coastguard Worker     typename T3 = char,
138*da0073e9SAndroid Build Coastguard Worker     typename T4 = char,
139*da0073e9SAndroid Build Coastguard Worker     typename T5 = char,
140*da0073e9SAndroid Build Coastguard Worker     typename T6 = char,
141*da0073e9SAndroid Build Coastguard Worker     typename T7 = char,
142*da0073e9SAndroid Build Coastguard Worker     typename T8 = char,
143*da0073e9SAndroid Build Coastguard Worker     typename T9 = char,
144*da0073e9SAndroid Build Coastguard Worker     typename T10 = char>
145*da0073e9SAndroid Build Coastguard Worker union SizerImpl {
146*da0073e9SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(*c-arrays)
147*da0073e9SAndroid Build Coastguard Worker   char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
148*da0073e9SAndroid Build Coastguard Worker       arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
149*da0073e9SAndroid Build Coastguard Worker       arr9[sizeof(T9)], arr10[sizeof(T10)];
150*da0073e9SAndroid Build Coastguard Worker };
151*da0073e9SAndroid Build Coastguard Worker } // end namespace detail
152*da0073e9SAndroid Build Coastguard Worker 
153*da0073e9SAndroid Build Coastguard Worker /// \brief This union template exposes a suitably aligned and sized character
154*da0073e9SAndroid Build Coastguard Worker /// array member which can hold elements of any of up to ten types.
155*da0073e9SAndroid Build Coastguard Worker ///
156*da0073e9SAndroid Build Coastguard Worker /// These types may be arrays, structs, or any other types. The goal is to
157*da0073e9SAndroid Build Coastguard Worker /// expose a char array buffer member which can be used as suitable storage for
158*da0073e9SAndroid Build Coastguard Worker /// a placement new of any of these types. Support for more than ten types can
159*da0073e9SAndroid Build Coastguard Worker /// be added at the cost of more boilerplate.
160*da0073e9SAndroid Build Coastguard Worker template <
161*da0073e9SAndroid Build Coastguard Worker     typename T1,
162*da0073e9SAndroid Build Coastguard Worker     typename T2 = char,
163*da0073e9SAndroid Build Coastguard Worker     typename T3 = char,
164*da0073e9SAndroid Build Coastguard Worker     typename T4 = char,
165*da0073e9SAndroid Build Coastguard Worker     typename T5 = char,
166*da0073e9SAndroid Build Coastguard Worker     typename T6 = char,
167*da0073e9SAndroid Build Coastguard Worker     typename T7 = char,
168*da0073e9SAndroid Build Coastguard Worker     typename T8 = char,
169*da0073e9SAndroid Build Coastguard Worker     typename T9 = char,
170*da0073e9SAndroid Build Coastguard Worker     typename T10 = char>
171*da0073e9SAndroid Build Coastguard Worker struct AlignedCharArrayUnion
172*da0073e9SAndroid Build Coastguard Worker     : AlignedCharArray<
173*da0073e9SAndroid Build Coastguard Worker           alignof(detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>),
174*da0073e9SAndroid Build Coastguard Worker           sizeof(::c10::detail::
175*da0073e9SAndroid Build Coastguard Worker                      SizerImpl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>)> {};
176*da0073e9SAndroid Build Coastguard Worker } // end namespace c10
177