Coverage Report

Created: 2021-09-21 08:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/CodeGen/CGBuilder.h
Line
Count
Source (jump to first uncovered line)
1
//===-- CGBuilder.h - Choose IRBuilder implementation  ----------*- 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
#ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
10
#define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
11
12
#include "llvm/IR/DataLayout.h"
13
#include "llvm/IR/IRBuilder.h"
14
#include "Address.h"
15
#include "CodeGenTypeCache.h"
16
17
namespace clang {
18
namespace CodeGen {
19
20
class CodeGenFunction;
21
22
/// This is an IRBuilder insertion helper that forwards to
23
/// CodeGenFunction::InsertHelper, which adds necessary metadata to
24
/// instructions.
25
class CGBuilderInserter final : public llvm::IRBuilderDefaultInserter {
26
public:
27
2.13k
  CGBuilderInserter() = default;
28
378k
  explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {}
29
30
  /// This forwards to CodeGenFunction::InsertHelper.
31
  void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
32
                    llvm::BasicBlock *BB,
33
                    llvm::BasicBlock::iterator InsertPt) const override;
34
private:
35
  CodeGenFunction *CGF = nullptr;
36
};
37
38
typedef CGBuilderInserter CGBuilderInserterTy;
39
40
typedef llvm::IRBuilder<llvm::ConstantFolder, CGBuilderInserterTy>
41
    CGBuilderBaseTy;
42
43
class CGBuilderTy : public CGBuilderBaseTy {
44
  /// Storing a reference to the type cache here makes it a lot easier
45
  /// to build natural-feeling, target-specific IR.
46
  const CodeGenTypeCache &TypeCache;
47
public:
48
  CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C)
49
310
    : CGBuilderBaseTy(C), TypeCache(TypeCache) {}
50
  CGBuilderTy(const CodeGenTypeCache &TypeCache,
51
              llvm::LLVMContext &C, const llvm::ConstantFolder &F,
52
              const CGBuilderInserterTy &Inserter)
53
378k
    : CGBuilderBaseTy(C, F, Inserter), TypeCache(TypeCache) {}
54
  CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::Instruction *I)
55
177
    : CGBuilderBaseTy(I), TypeCache(TypeCache) {}
56
  CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::BasicBlock *BB)
57
1.65k
    : CGBuilderBaseTy(BB), TypeCache(TypeCache) {}
58
59
111k
  llvm::ConstantInt *getSize(CharUnits N) {
60
111k
    return llvm::ConstantInt::get(TypeCache.SizeTy, N.getQuantity());
61
111k
  }
62
108k
  llvm::ConstantInt *getSize(uint64_t N) {
63
108k
    return llvm::ConstantInt::get(TypeCache.SizeTy, N);
64
108k
  }
65
66
  // Note that we intentionally hide the CreateLoad APIs that don't
67
  // take an alignment.
68
89.8k
  llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") {
69
89.8k
    return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
70
89.8k
                             Addr.getAlignment().getAsAlign(), Name);
71
89.8k
  }
72
120k
  llvm::LoadInst *CreateLoad(Address Addr, const char *Name) {
73
    // This overload is required to prevent string literals from
74
    // ending up in the IsVolatile overload.
75
120k
    return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
76
120k
                             Addr.getAlignment().getAsAlign(), Name);
77
120k
  }
78
  llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile,
79
1.62M
                             const llvm::Twine &Name = "") {
80
1.62M
    return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
81
1.62M
                             Addr.getAlignment().getAsAlign(), IsVolatile,
82
1.62M
                             Name);
83
1.62M
  }
84
85
  using CGBuilderBaseTy::CreateAlignedLoad;
86
  llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr,
87
                                    CharUnits Align,
88
26.7k
                                    const llvm::Twine &Name = "") {
89
26.7k
    assert(Addr->getType()->getPointerElementType() == Ty);
90
0
    return CreateAlignedLoad(Ty, Addr, Align.getAsAlign(), Name);
91
26.7k
  }
92
93
  // Note that we intentionally hide the CreateStore APIs that don't
94
  // take an alignment.
95
  llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr,
96
1.66M
                               bool IsVolatile = false) {
97
1.66M
    return CreateAlignedStore(Val, Addr.getPointer(),
98
1.66M
                              Addr.getAlignment().getAsAlign(), IsVolatile);
99
1.66M
  }
100
101
  using CGBuilderBaseTy::CreateAlignedStore;
102
  llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr,
103
6.68k
                                      CharUnits Align, bool IsVolatile = false) {
104
6.68k
    return CreateAlignedStore(Val, Addr, Align.getAsAlign(), IsVolatile);
105
6.68k
  }
106
107
  // FIXME: these "default-aligned" APIs should be removed,
108
  // but I don't feel like fixing all the builtin code right now.
109
  llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val,
110
                                             llvm::Value *Addr,
111
971
                                             bool IsVolatile = false) {
112
971
    return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile);
113
971
  }
114
115
  /// Emit a load from an i1 flag variable.
116
  llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr,
117
231
                                 const llvm::Twine &Name = "") {
118
231
    assert(Addr->getType()->getPointerElementType() == getInt1Ty());
119
0
    return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name);
120
231
  }
121
122
  /// Emit a store to an i1 flag variable.
123
235
  llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) {
124
235
    assert(Addr->getType()->getPointerElementType() == getInt1Ty());
125
0
    return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One());
126
235
  }
127
128
  // Temporarily use old signature; clang will be updated to an Address overload
129
  // in a subsequent patch.
130
  llvm::AtomicCmpXchgInst *
131
  CreateAtomicCmpXchg(llvm::Value *Ptr, llvm::Value *Cmp, llvm::Value *New,
132
                      llvm::AtomicOrdering SuccessOrdering,
133
                      llvm::AtomicOrdering FailureOrdering,
134
577
                      llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
135
577
    return CGBuilderBaseTy::CreateAtomicCmpXchg(
136
577
        Ptr, Cmp, New, llvm::MaybeAlign(), SuccessOrdering, FailureOrdering,
137
577
        SSID);
138
577
  }
139
140
  // Temporarily use old signature; clang will be updated to an Address overload
141
  // in a subsequent patch.
142
  llvm::AtomicRMWInst *
143
  CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op, llvm::Value *Ptr,
144
                  llvm::Value *Val, llvm::AtomicOrdering Ordering,
145
2.30k
                  llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
146
2.30k
    return CGBuilderBaseTy::CreateAtomicRMW(Op, Ptr, Val, llvm::MaybeAlign(),
147
2.30k
                                            Ordering, SSID);
148
2.30k
  }
149
150
  using CGBuilderBaseTy::CreateBitCast;
151
  Address CreateBitCast(Address Addr, llvm::Type *Ty,
152
552k
                        const llvm::Twine &Name = "") {
153
552k
    return Address(CreateBitCast(Addr.getPointer(), Ty, Name),
154
552k
                   Addr.getAlignment());
155
552k
  }
156
157
  using CGBuilderBaseTy::CreateAddrSpaceCast;
158
  Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty,
159
5
                              const llvm::Twine &Name = "") {
160
5
    return Address(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name),
161
5
                   Addr.getAlignment());
162
5
  }
163
164
  /// Cast the element type of the given address to a different type,
165
  /// preserving information like the alignment and address space.
166
  Address CreateElementBitCast(Address Addr, llvm::Type *Ty,
167
492k
                               const llvm::Twine &Name = "") {
168
492k
    auto PtrTy = Ty->getPointerTo(Addr.getAddressSpace());
169
492k
    return CreateBitCast(Addr, PtrTy, Name);
170
492k
  }
171
172
  using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
173
  Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty,
174
2.03k
                                              const llvm::Twine &Name = "") {
175
2.03k
    llvm::Value *Ptr =
176
2.03k
      CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name);
177
2.03k
    return Address(Ptr, Addr.getAlignment());
178
2.03k
  }
179
180
  /// Given
181
  ///   %addr = {T1, T2...}* ...
182
  /// produce
183
  ///   %name = getelementptr inbounds %addr, i32 0, i32 index
184
  ///
185
  /// This API assumes that drilling into a struct like this is always an
186
  /// inbounds operation.
187
  using CGBuilderBaseTy::CreateStructGEP;
188
  Address CreateStructGEP(Address Addr, unsigned Index,
189
269k
                          const llvm::Twine &Name = "") {
190
269k
    llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
191
269k
    const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
192
269k
    const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
193
269k
    auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
194
195
269k
    return Address(CreateStructGEP(Addr.getElementType(),
196
269k
                                   Addr.getPointer(), Index, Name),
197
269k
                   Addr.getAlignment().alignmentAtOffset(Offset));
198
269k
  }
199
200
  /// Given
201
  ///   %addr = [n x T]* ...
202
  /// produce
203
  ///   %name = getelementptr inbounds %addr, i64 0, i64 index
204
  /// where i64 is actually the target word size.
205
  ///
206
  /// This API assumes that drilling into an array like this is always
207
  /// an inbounds operation.
208
  Address CreateConstArrayGEP(Address Addr, uint64_t Index,
209
107k
                              const llvm::Twine &Name = "") {
210
107k
    llvm::ArrayType *ElTy = cast<llvm::ArrayType>(Addr.getElementType());
211
107k
    const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
212
107k
    CharUnits EltSize =
213
107k
        CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
214
215
107k
    return Address(
216
107k
        CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
217
107k
                          {getSize(CharUnits::Zero()), getSize(Index)}, Name),
218
107k
        Addr.getAlignment().alignmentAtOffset(Index * EltSize));
219
107k
  }
220
221
  /// Given
222
  ///   %addr = T* ...
223
  /// produce
224
  ///   %name = getelementptr inbounds %addr, i64 index
225
  /// where i64 is actually the target word size.
226
  Address CreateConstInBoundsGEP(Address Addr, uint64_t Index,
227
349
                                 const llvm::Twine &Name = "") {
228
349
    llvm::Type *ElTy = Addr.getElementType();
229
349
    const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
230
349
    CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
231
232
349
    return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
233
349
                                     getSize(Index), Name),
234
349
                   Addr.getAlignment().alignmentAtOffset(Index * EltSize));
235
349
  }
236
237
  /// Given
238
  ///   %addr = T* ...
239
  /// produce
240
  ///   %name = getelementptr inbounds %addr, i64 index
241
  /// where i64 is actually the target word size.
242
  Address CreateConstGEP(Address Addr, uint64_t Index,
243
1.12k
                         const llvm::Twine &Name = "") {
244
1.12k
    const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
245
1.12k
    CharUnits EltSize =
246
1.12k
        CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
247
248
1.12k
    return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
249
1.12k
                             getSize(Index), Name),
250
1.12k
                   Addr.getAlignment().alignmentAtOffset(Index * EltSize));
251
1.12k
  }
252
253
  /// Given a pointer to i8, adjust it by a given constant offset.
254
  Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
255
3.48k
                                     const llvm::Twine &Name = "") {
256
3.48k
    assert(Addr.getElementType() == TypeCache.Int8Ty);
257
0
    return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
258
3.48k
                                     getSize(Offset), Name),
259
3.48k
                   Addr.getAlignment().alignmentAtOffset(Offset));
260
3.48k
  }
261
  Address CreateConstByteGEP(Address Addr, CharUnits Offset,
262
616
                             const llvm::Twine &Name = "") {
263
616
    assert(Addr.getElementType() == TypeCache.Int8Ty);
264
0
    return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
265
616
                             getSize(Offset), Name),
266
616
                   Addr.getAlignment().alignmentAtOffset(Offset));
267
616
  }
268
269
  using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
270
  Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1,
271
193
                                     const llvm::Twine &Name = "") {
272
193
    const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
273
274
193
    auto *GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32(
275
193
        Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name));
276
193
    llvm::APInt Offset(
277
193
        DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0,
278
193
        /*isSigned=*/true);
279
193
    if (!GEP->accumulateConstantOffset(DL, Offset))
280
0
      llvm_unreachable("offset of GEP with constants is always computable");
281
193
    return Address(GEP, Addr.getAlignment().alignmentAtOffset(
282
193
                            CharUnits::fromQuantity(Offset.getSExtValue())));
283
193
  }
284
285
  using CGBuilderBaseTy::CreateMemCpy;
286
  llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size,
287
14.6k
                               bool IsVolatile = false) {
288
14.6k
    return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
289
14.6k
                        Src.getPointer(), Src.getAlignment().getAsAlign(), Size,
290
14.6k
                        IsVolatile);
291
14.6k
  }
292
  llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size,
293
351
                               bool IsVolatile = false) {
294
351
    return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
295
351
                        Src.getPointer(), Src.getAlignment().getAsAlign(), Size,
296
351
                        IsVolatile);
297
351
  }
298
299
  using CGBuilderBaseTy::CreateMemCpyInline;
300
4
  llvm::CallInst *CreateMemCpyInline(Address Dest, Address Src, uint64_t Size) {
301
4
    return CreateMemCpyInline(
302
4
        Dest.getPointer(), Dest.getAlignment().getAsAlign(), Src.getPointer(),
303
4
        Src.getAlignment().getAsAlign(), getInt64(Size));
304
4
  }
305
306
  using CGBuilderBaseTy::CreateMemMove;
307
  llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size,
308
13
                                bool IsVolatile = false) {
309
13
    return CreateMemMove(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
310
13
                         Src.getPointer(), Src.getAlignment().getAsAlign(),
311
13
                         Size, IsVolatile);
312
13
  }
313
314
  using CGBuilderBaseTy::CreateMemSet;
315
  llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value,
316
2.50k
                               llvm::Value *Size, bool IsVolatile = false) {
317
2.50k
    return CreateMemSet(Dest.getPointer(), Value, Size,
318
2.50k
                        Dest.getAlignment().getAsAlign(), IsVolatile);
319
2.50k
  }
320
321
  using CGBuilderBaseTy::CreatePreserveStructAccessIndex;
322
  Address CreatePreserveStructAccessIndex(Address Addr,
323
                                          unsigned Index,
324
                                          unsigned FieldIndex,
325
38
                                          llvm::MDNode *DbgInfo) {
326
38
    llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
327
38
    const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
328
38
    const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
329
38
    auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
330
331
38
    return Address(CreatePreserveStructAccessIndex(ElTy, Addr.getPointer(),
332
38
                                                   Index, FieldIndex, DbgInfo),
333
38
                   Addr.getAlignment().alignmentAtOffset(Offset));
334
38
  }
335
};
336
337
}  // end namespace CodeGen
338
}  // end namespace clang
339
340
#endif