Coverage Report

Created: 2019-07-24 05:18

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