LLVM: include/llvm/Support/TrailingObjects.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46#ifndef LLVM_SUPPORT_TRAILINGOBJECTS_H

47#define LLVM_SUPPORT_TRAILINGOBJECTS_H

48

54#include

55#include <type_traits>

56

57namespace llvm {

58

59namespace trailing_objects_internal {

60

61

63private:

64 enum {

65 FirstAlignment = alignof(First),

67 };

68

69public:

70 enum {

71 Alignment = FirstAlignment > RestAlignment ? FirstAlignment : RestAlignment

72 };

73};

74

76public:

77 enum { Alignment = alignof(First) };

78};

79

80

82protected:

83

84

85

86

87

89};

90

91

92

93

96};

97

98

99

100

101

102

103

104

105

106template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy,

107 typename... MoreTys>

109

110

111};

112

113template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy,

114 typename NextTy, typename... MoreTys>

116 MoreTys...>

118 MoreTys...> {

119

122

123 struct RequiresRealignment {

124 static const bool value = alignof(PrevTy) < alignof(NextTy);

125 };

126

127 static constexpr bool requiresRealignment() {

128 return RequiresRealignment::value;

129 }

130

131protected:

132

133 using ParentType::getTrailingObjectsImpl;

134

135

136

137

138

139

140

141

142

143

144 static const NextTy *

147 auto *Ptr = TopTrailingObj::getTrailingObjectsImpl(

149 TopTrailingObj::callNumTrailingObjects(

151

152 if (requiresRealignment())

153 return reinterpret_cast<const NextTy *>(

155 else

156 return reinterpret_cast<const NextTy *>(Ptr);

157 }

158

159 static NextTy *

162 auto *Ptr = TopTrailingObj::getTrailingObjectsImpl(

164 TopTrailingObj::callNumTrailingObjects(

166

167 if (requiresRealignment())

168 return reinterpret_cast<NextTy *>(alignAddr(Ptr, Align::Of()));

169 else

170 return reinterpret_cast<NextTy *>(Ptr);

171 }

172

173

174

175

177 size_t SizeSoFar, size_t Count1,

179 return ParentType::additionalSizeToAllocImpl(

180 (requiresRealignment() ? llvm::alignTo<alignof(NextTy)>(SizeSoFar)

181 : SizeSoFar) +

182 sizeof(NextTy) * Count1,

183 MoreCounts...);

184 }

185};

186

187

188

189template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy>

192protected:

193

194

195

197

199 return SizeSoFar;

200 }

201

203};

204

205}

206

207

208

209

210

211template <typename BaseTy, typename... TrailingTys>

213 trailing_objects_internal::AlignmentCalcHelper<

214 TrailingTys...>::Alignment,

215 BaseTy, TrailingObjects<BaseTy, TrailingTys...>,

216 BaseTy, TrailingTys...> {

217

218 template <int A, typename B, typename T, typename P, typename... M>

220

221 template <typename... Tys> class Foo {};

222

226 ParentType;

228

229 using ParentType::getTrailingObjectsImpl;

230

231

232

233

234

235 static void verifyTrailingObjectsAssertions() {

236 static_assert(std::is_final(), "BaseTy must be final.");

237 }

238

239

240 static const BaseTy *

241 getTrailingObjectsImpl(const BaseTy *Obj,

242 TrailingObjectsBase::OverloadToken) {

243 return Obj;

244 }

245

247 getTrailingObjectsImpl(BaseTy *Obj,

248 TrailingObjectsBase::OverloadToken) {

249 return Obj;

250 }

251

252

253

254

255

256

257

258

259 static size_t

260 callNumTrailingObjects(const BaseTy *Obj,

261 TrailingObjectsBase::OverloadToken) {

262 return 1;

263 }

264

265 template

266 static size_t callNumTrailingObjects(const BaseTy *Obj,

267 TrailingObjectsBase::OverloadToken) {

268 return Obj->numTrailingObjects(TrailingObjectsBase::OverloadToken());

269 }

270

271public:

272

273#ifndef _MSC_VER

274 using ParentType::OverloadToken;

275#else

276

277

278 template

279 using OverloadToken = typename ParentType::template OverloadToken;

280#endif

281

282

283

284

286 verifyTrailingObjectsAssertions();

287

288

289 return this->getTrailingObjectsImpl(

290 static_cast<const BaseTy *>(this),

292 }

293

294

295

296

298 verifyTrailingObjectsAssertions();

299

300

301 return this->getTrailingObjectsImpl(

303 }

304

305

306

307

308

309

310

311 template <typename... Tys>

312 static constexpr std::enable_if_t<

313 std::is_same_v<Foo<TrailingTys...>, Foo<Tys...>>, size_t>

315 TrailingTys, size_t>::type... Counts) {

316 return ParentType::additionalSizeToAllocImpl(0, Counts...);

317 }

318

319

320

321

322

323 template <typename... Tys>

324 static constexpr std::enable_if_t<

325 std::is_same_v<Foo<TrailingTys...>, Foo<Tys...>>, size_t>

327 TrailingTys, size_t>::type... Counts) {

328 return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...);

329 }

330

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

354 enum { Size = totalSizeToAlloc<Tys...>(Counts...) };

357 };

358 };

359 };

360

361

363 public:

366 assert(p && "FixedSizeStorageOwner owns null?");

367 p->~BaseTy();

368 }

369

372

373 private:

378

380 };

381};

382

383}

384

385#endif

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

Given that RA is a live value

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

A type that acts as the owner for an object placed into fixed storage.

FixedSizeStorageOwner(BaseTy *p)

const BaseTy * get() const

See the file comment for details on the usage of the TrailingObjects type.

TrailingObjects & operator=(TrailingObjects &&)=delete

static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)

Returns the total size of an object if it were allocated with the given trailing object counts.

TrailingObjects & operator=(const TrailingObjects &)=delete

static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > additionalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)

Returns the size of the trailing data, if an object were allocated with the given counts (The counts ...

TrailingObjects(TrailingObjects &&)=delete

T * getTrailingObjects()

Returns a pointer to the trailing object array of the given type (which must be one of those specifie...

const T * getTrailingObjects() const

Returns a pointer to the trailing object array of the given type (which must be one of those specifie...

TrailingObjects()=default

TrailingObjects(const TrailingObjects &)=delete

Helper template to calculate the max alignment requirement for a set of objects.

The base class for TrailingObjects* classes.

static const NextTy * getTrailingObjectsImpl(const BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)

static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar, size_t Count1, typename ExtractSecondType< MoreTys, size_t >::type... MoreCounts)

static NextTy * getTrailingObjectsImpl(BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)

static void getTrailingObjectsImpl()

static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar)

static void verifyTrailingObjectsAlignment()

This is an optimization pass for GlobalISel generic memory operations.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

uintptr_t alignAddr(const void *Addr, Align Alignment)

Aligns Addr to Alignment bytes, rounding up.

This struct is a compact representation of a valid (non-zero power of two) alignment.

A type where its ::with_counts template member has a ::type member suitable for use as uninitialized ...

OverloadToken's purpose is to allow specifying function overloads for different types,...