Coverage Report

Created: 2019-02-21 13:17

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ----*- 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
/// \file
9
/// This file declares the IRTranslator pass.
10
/// This pass is responsible for translating LLVM IR into MachineInstr.
11
/// It uses target hooks to lower the ABI but aside from that, the pass
12
/// generated code is generic. This is the default translator used for
13
/// GlobalISel.
14
///
15
/// \todo Replace the comments with actual doxygen comments.
16
//===----------------------------------------------------------------------===//
17
18
#ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
19
#define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
20
21
#include "llvm/ADT/DenseMap.h"
22
#include "llvm/ADT/SmallVector.h"
23
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
24
#include "llvm/CodeGen/GlobalISel/Types.h"
25
#include "llvm/CodeGen/MachineFunctionPass.h"
26
#include "llvm/IR/Intrinsics.h"
27
#include "llvm/Support/Allocator.h"
28
#include <memory>
29
#include <utility>
30
31
namespace llvm {
32
33
class AllocaInst;
34
class BasicBlock;
35
class CallInst;
36
class CallLowering;
37
class Constant;
38
class DataLayout;
39
class Instruction;
40
class MachineBasicBlock;
41
class MachineFunction;
42
class MachineInstr;
43
class MachineRegisterInfo;
44
class OptimizationRemarkEmitter;
45
class PHINode;
46
class TargetPassConfig;
47
class User;
48
class Value;
49
50
// Technically the pass should run on an hypothetical MachineModule,
51
// since it should translate Global into some sort of MachineGlobal.
52
// The MachineGlobal should ultimately just be a transfer of ownership of
53
// the interesting bits that are relevant to represent a global value.
54
// That being said, we could investigate what would it cost to just duplicate
55
// the information from the LLVM IR.
56
// The idea is that ultimately we would be able to free up the memory used
57
// by the LLVM IR as soon as the translation is over.
58
class IRTranslator : public MachineFunctionPass {
59
public:
60
  static char ID;
61
62
private:
63
  /// Interface used to lower the everything related to calls.
64
  const CallLowering *CLI;
65
66
  /// This class contains the mapping between the Values to vreg related data.
67
  class ValueToVRegInfo {
68
  public:
69
6.89k
    ValueToVRegInfo() = default;
70
71
    using VRegListT = SmallVector<unsigned, 1>;
72
    using OffsetListT = SmallVector<uint64_t, 1>;
73
74
    using const_vreg_iterator =
75
        DenseMap<const Value *, VRegListT *>::const_iterator;
76
    using const_offset_iterator =
77
        DenseMap<const Value *, OffsetListT *>::const_iterator;
78
79
27.2M
    inline const_vreg_iterator vregs_end() const { return ValToVRegs.end(); }
80
81
12.1M
    VRegListT *getVRegs(const Value &V) {
82
12.1M
      auto It = ValToVRegs.find(&V);
83
12.1M
      if (It != ValToVRegs.end())
84
42.9k
        return It->second;
85
12.1M
86
12.1M
      return insertVRegs(V);
87
12.1M
    }
88
89
16.8M
    OffsetListT *getOffsets(const Value &V) {
90
16.8M
      auto It = TypeToOffsets.find(V.getType());
91
16.8M
      if (It != TypeToOffsets.end())
92
15.0M
        return It->second;
93
1.79M
94
1.79M
      return insertOffsets(V);
95
1.79M
    }
96
97
27.2M
    const_vreg_iterator findVRegs(const Value &V) const {
98
27.2M
      return ValToVRegs.find(&V);
99
27.2M
    }
100
101
0
    bool contains(const Value &V) const {
102
0
      return ValToVRegs.find(&V) != ValToVRegs.end();
103
0
    }
104
105
236k
    void reset() {
106
236k
      ValToVRegs.clear();
107
236k
      TypeToOffsets.clear();
108
236k
      VRegAlloc.DestroyAll();
109
236k
      OffsetAlloc.DestroyAll();
110
236k
    }
111
112
  private:
113
12.1M
    VRegListT *insertVRegs(const Value &V) {
114
12.1M
      assert(ValToVRegs.find(&V) == ValToVRegs.end() && "Value already exists");
115
12.1M
116
12.1M
      // We placement new using our fast allocator since we never try to free
117
12.1M
      // the vectors until translation is finished.
118
12.1M
      auto *VRegList = new (VRegAlloc.Allocate()) VRegListT();
119
12.1M
      ValToVRegs[&V] = VRegList;
120
12.1M
      return VRegList;
121
12.1M
    }
122
123
1.79M
    OffsetListT *insertOffsets(const Value &V) {
124
1.79M
      assert(TypeToOffsets.find(V.getType()) == TypeToOffsets.end() &&
125
1.79M
             "Type already exists");
126
1.79M
127
1.79M
      auto *OffsetList = new (OffsetAlloc.Allocate()) OffsetListT();
128
1.79M
      TypeToOffsets[V.getType()] = OffsetList;
129
1.79M
      return OffsetList;
130
1.79M
    }
131
    SpecificBumpPtrAllocator<VRegListT> VRegAlloc;
132
    SpecificBumpPtrAllocator<OffsetListT> OffsetAlloc;
133
134
    // We store pointers to vectors here since references may be invalidated
135
    // while we hold them if we stored the vectors directly.
136
    DenseMap<const Value *, VRegListT*> ValToVRegs;
137
    DenseMap<const Type *, OffsetListT*> TypeToOffsets;
138
  };
139
140
  /// Mapping of the values of the current LLVM IR function to the related
141
  /// virtual registers and offsets.
142
  ValueToVRegInfo VMap;
143
144
  // N.b. it's not completely obvious that this will be sufficient for every
145
  // LLVM IR construct (with "invoke" being the obvious candidate to mess up our
146
  // lives.
147
  DenseMap<const BasicBlock *, MachineBasicBlock *> BBToMBB;
148
149
  // One BasicBlock can be translated to multiple MachineBasicBlocks.  For such
150
  // BasicBlocks translated to multiple MachineBasicBlocks, MachinePreds retains
151
  // a mapping between the edges arriving at the BasicBlock to the corresponding
152
  // created MachineBasicBlocks. Some BasicBlocks that get translated to a
153
  // single MachineBasicBlock may also end up in this Map.
154
  using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
155
  DenseMap<CFGEdge, SmallVector<MachineBasicBlock *, 1>> MachinePreds;
156
157
  // List of stubbed PHI instructions, for values and basic blocks to be filled
158
  // in once all MachineBasicBlocks have been created.
159
  SmallVector<std::pair<const PHINode *, SmallVector<MachineInstr *, 1>>, 4>
160
      PendingPHIs;
161
162
  /// Record of what frame index has been allocated to specified allocas for
163
  /// this function.
164
  DenseMap<const AllocaInst *, int> FrameIndices;
165
166
  /// \name Methods for translating form LLVM IR to MachineInstr.
167
  /// \see ::translate for general information on the translate methods.
168
  /// @{
169
170
  /// Translate \p Inst into its corresponding MachineInstr instruction(s).
171
  /// Insert the newly translated instruction(s) right where the CurBuilder
172
  /// is set.
173
  ///
174
  /// The general algorithm is:
175
  /// 1. Look for a virtual register for each operand or
176
  ///    create one.
177
  /// 2 Update the VMap accordingly.
178
  /// 2.alt. For constant arguments, if they are compile time constants,
179
  ///   produce an immediate in the right operand and do not touch
180
  ///   ValToReg. Actually we will go with a virtual register for each
181
  ///   constants because it may be expensive to actually materialize the
182
  ///   constant. Moreover, if the constant spans on several instructions,
183
  ///   CSE may not catch them.
184
  ///   => Update ValToVReg and remember that we saw a constant in Constants.
185
  ///   We will materialize all the constants in finalize.
186
  /// Note: we would need to do something so that we can recognize such operand
187
  ///       as constants.
188
  /// 3. Create the generic instruction.
189
  ///
190
  /// \return true if the translation succeeded.
191
  bool translate(const Instruction &Inst);
192
193
  /// Materialize \p C into virtual-register \p Reg. The generic instructions
194
  /// performing this materialization will be inserted into the entry block of
195
  /// the function.
196
  ///
197
  /// \return true if the materialization succeeded.
198
  bool translate(const Constant &C, unsigned Reg);
199
200
  /// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is
201
  /// emitted.
202
  bool translateBitCast(const User &U, MachineIRBuilder &MIRBuilder);
203
204
  /// Translate an LLVM load instruction into generic IR.
205
  bool translateLoad(const User &U, MachineIRBuilder &MIRBuilder);
206
207
  /// Translate an LLVM store instruction into generic IR.
208
  bool translateStore(const User &U, MachineIRBuilder &MIRBuilder);
209
210
  /// Translate an LLVM string intrinsic (memcpy, memset, ...).
211
  bool translateMemfunc(const CallInst &CI, MachineIRBuilder &MIRBuilder,
212
                        unsigned ID);
213
214
  void getStackGuard(unsigned DstReg, MachineIRBuilder &MIRBuilder);
215
216
  bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
217
                                  MachineIRBuilder &MIRBuilder);
218
219
  /// Helper function for translateSimpleIntrinsic.
220
  /// \return The generic opcode for \p IntrinsicID if \p IntrinsicID is a
221
  /// simple intrinsic (ceil, fabs, etc.). Otherwise, returns
222
  /// Intrinsic::not_intrinsic.
223
  unsigned getSimpleIntrinsicOpcode(Intrinsic::ID ID);
224
225
  /// Translates the intrinsics defined in getSimpleIntrinsicOpcode.
226
  /// \return true if the translation succeeded.
227
  bool translateSimpleIntrinsic(const CallInst &CI, Intrinsic::ID ID,
228
                                MachineIRBuilder &MIRBuilder);
229
230
  bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
231
                               MachineIRBuilder &MIRBuilder);
232
233
  bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder);
234
235
  // FIXME: temporary function to expose previous interface to call lowering
236
  // until it is refactored.
237
  /// Combines all component registers of \p V into a single scalar with size
238
  /// "max(Offsets) + last size".
239
  unsigned packRegs(const Value &V, MachineIRBuilder &MIRBuilder);
240
241
  void unpackRegs(const Value &V, unsigned Src, MachineIRBuilder &MIRBuilder);
242
243
  /// Returns true if the value should be split into multiple LLTs.
244
  /// If \p Offsets is given then the split type's offsets will be stored in it.
245
  /// If \p Offsets is not empty it will be cleared first.
246
  bool valueIsSplit(const Value &V,
247
                    SmallVectorImpl<uint64_t> *Offsets = nullptr);
248
249
  /// Translate call instruction.
250
  /// \pre \p U is a call instruction.
251
  bool translateCall(const User &U, MachineIRBuilder &MIRBuilder);
252
253
  bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder);
254
255
  bool translateCallBr(const User &U, MachineIRBuilder &MIRBuilder);
256
257
  bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder);
258
259
  /// Translate one of LLVM's cast instructions into MachineInstrs, with the
260
  /// given generic Opcode.
261
  bool translateCast(unsigned Opcode, const User &U,
262
                     MachineIRBuilder &MIRBuilder);
263
264
  /// Translate a phi instruction.
265
  bool translatePHI(const User &U, MachineIRBuilder &MIRBuilder);
266
267
  /// Translate a comparison (icmp or fcmp) instruction or constant.
268
  bool translateCompare(const User &U, MachineIRBuilder &MIRBuilder);
269
270
  /// Translate an integer compare instruction (or constant).
271
1.04M
  bool translateICmp(const User &U, MachineIRBuilder &MIRBuilder) {
272
1.04M
    return translateCompare(U, MIRBuilder);
273
1.04M
  }
274
275
  /// Translate a floating-point compare instruction (or constant).
276
17.2k
  bool translateFCmp(const User &U, MachineIRBuilder &MIRBuilder) {
277
17.2k
    return translateCompare(U, MIRBuilder);
278
17.2k
  }
279
280
  /// Add remaining operands onto phis we've translated. Executed after all
281
  /// MachineBasicBlocks for the function have been created.
282
  void finishPendingPhis();
283
284
  /// Translate \p Inst into a binary operation \p Opcode.
285
  /// \pre \p U is a binary operation.
286
  bool translateBinaryOp(unsigned Opcode, const User &U,
287
                         MachineIRBuilder &MIRBuilder);
288
289
  /// Translate branch (br) instruction.
290
  /// \pre \p U is a branch instruction.
291
  bool translateBr(const User &U, MachineIRBuilder &MIRBuilder);
292
293
  bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder);
294
295
  bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder);
296
297
  bool translateExtractValue(const User &U, MachineIRBuilder &MIRBuilder);
298
299
  bool translateInsertValue(const User &U, MachineIRBuilder &MIRBuilder);
300
301
  bool translateSelect(const User &U, MachineIRBuilder &MIRBuilder);
302
303
  bool translateGetElementPtr(const User &U, MachineIRBuilder &MIRBuilder);
304
305
  bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder);
306
307
  /// Translate return (ret) instruction.
308
  /// The target needs to implement CallLowering::lowerReturn for
309
  /// this to succeed.
310
  /// \pre \p U is a return instruction.
311
  bool translateRet(const User &U, MachineIRBuilder &MIRBuilder);
312
313
  bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder);
314
315
  bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder);
316
317
371k
  bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
318
371k
    return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
319
371k
  }
320
90.8k
  bool translateSub(const User &U, MachineIRBuilder &MIRBuilder) {
321
90.8k
    return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
322
90.8k
  }
323
105k
  bool translateAnd(const User &U, MachineIRBuilder &MIRBuilder) {
324
105k
    return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
325
105k
  }
326
82.3k
  bool translateMul(const User &U, MachineIRBuilder &MIRBuilder) {
327
82.3k
    return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
328
82.3k
  }
329
38.8k
  bool translateOr(const User &U, MachineIRBuilder &MIRBuilder) {
330
38.8k
    return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
331
38.8k
  }
332
10.5k
  bool translateXor(const User &U, MachineIRBuilder &MIRBuilder) {
333
10.5k
    return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
334
10.5k
  }
335
336
7.61k
  bool translateUDiv(const User &U, MachineIRBuilder &MIRBuilder) {
337
7.61k
    return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
338
7.61k
  }
339
10.2k
  bool translateSDiv(const User &U, MachineIRBuilder &MIRBuilder) {
340
10.2k
    return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
341
10.2k
  }
342
1.18k
  bool translateURem(const User &U, MachineIRBuilder &MIRBuilder) {
343
1.18k
    return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
344
1.18k
  }
345
2.57k
  bool translateSRem(const User &U, MachineIRBuilder &MIRBuilder) {
346
2.57k
    return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
347
2.57k
  }
348
36.7k
  bool translateIntToPtr(const User &U, MachineIRBuilder &MIRBuilder) {
349
36.7k
    return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
350
36.7k
  }
351
69.1k
  bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) {
352
69.1k
    return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
353
69.1k
  }
354
169k
  bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
355
169k
    return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
356
169k
  }
357
4.06k
  bool translateFPTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
358
4.06k
    return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
359
4.06k
  }
360
12.8k
  bool translateFPExt(const User &U, MachineIRBuilder &MIRBuilder) {
361
12.8k
    return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
362
12.8k
  }
363
3.27k
  bool translateFPToUI(const User &U, MachineIRBuilder &MIRBuilder) {
364
3.27k
    return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
365
3.27k
  }
366
2.61k
  bool translateFPToSI(const User &U, MachineIRBuilder &MIRBuilder) {
367
2.61k
    return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
368
2.61k
  }
369
14.8k
  bool translateUIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
370
14.8k
    return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
371
14.8k
  }
372
29.7k
  bool translateSIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
373
29.7k
    return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
374
29.7k
  }
375
14.3k
  bool translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder) {
376
14.3k
    return true;
377
14.3k
  }
378
162k
  bool translateSExt(const User &U, MachineIRBuilder &MIRBuilder) {
379
162k
    return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
380
162k
  }
381
382
105k
  bool translateZExt(const User &U, MachineIRBuilder &MIRBuilder) {
383
105k
    return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
384
105k
  }
385
386
64.4k
  bool translateShl(const User &U, MachineIRBuilder &MIRBuilder) {
387
64.4k
    return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
388
64.4k
  }
389
38.4k
  bool translateLShr(const User &U, MachineIRBuilder &MIRBuilder) {
390
38.4k
    return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
391
38.4k
  }
392
15.1k
  bool translateAShr(const User &U, MachineIRBuilder &MIRBuilder) {
393
15.1k
    return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
394
15.1k
  }
395
396
51.7k
  bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) {
397
51.7k
    return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
398
51.7k
  }
399
48.3k
  bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) {
400
48.3k
    return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
401
48.3k
  }
402
37.0k
  bool translateFDiv(const User &U, MachineIRBuilder &MIRBuilder) {
403
37.0k
    return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
404
37.0k
  }
405
38
  bool translateFRem(const User &U, MachineIRBuilder &MIRBuilder) {
406
38
    return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
407
38
  }
408
409
  bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);
410
411
  bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder);
412
413
  bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
414
415
  bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder);
416
417
  bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder);
418
  bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder);
419
420
  // Stubs to keep the compiler happy while we implement the rest of the
421
  // translation.
422
0
  bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) {
423
0
    return false;
424
0
  }
425
0
  bool translateCleanupRet(const User &U, MachineIRBuilder &MIRBuilder) {
426
0
    return false;
427
0
  }
428
0
  bool translateCatchRet(const User &U, MachineIRBuilder &MIRBuilder) {
429
0
    return false;
430
0
  }
431
0
  bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) {
432
0
    return false;
433
0
  }
434
1.39k
  bool translateFence(const User &U, MachineIRBuilder &MIRBuilder) {
435
1.39k
    return false;
436
1.39k
  }
437
4
  bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) {
438
4
    return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
439
4
  }
440
0
  bool translateCleanupPad(const User &U, MachineIRBuilder &MIRBuilder) {
441
0
    return false;
442
0
  }
443
0
  bool translateCatchPad(const User &U, MachineIRBuilder &MIRBuilder) {
444
0
    return false;
445
0
  }
446
0
  bool translateUserOp1(const User &U, MachineIRBuilder &MIRBuilder) {
447
0
    return false;
448
0
  }
449
0
  bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
450
0
    return false;
451
0
  }
452
453
  /// @}
454
455
  // Builder for machine instruction a la IRBuilder.
456
  // I.e., compared to regular MIBuilder, this one also inserts the instruction
457
  // in the current block, it can creates block, etc., basically a kind of
458
  // IRBuilder, but for Machine IR.
459
  // CSEMIRBuilder CurBuilder;
460
  std::unique_ptr<MachineIRBuilder> CurBuilder;
461
462
  // Builder set to the entry block (just after ABI lowering instructions). Used
463
  // as a convenient location for Constants.
464
  // CSEMIRBuilder EntryBuilder;
465
  std::unique_ptr<MachineIRBuilder> EntryBuilder;
466
467
  // The MachineFunction currently being translated.
468
  MachineFunction *MF;
469
470
  /// MachineRegisterInfo used to create virtual registers.
471
  MachineRegisterInfo *MRI = nullptr;
472
473
  const DataLayout *DL;
474
475
  /// Current target configuration. Controls how the pass handles errors.
476
  const TargetPassConfig *TPC;
477
478
  /// Current optimization remark emitter. Used to report failures.
479
  std::unique_ptr<OptimizationRemarkEmitter> ORE;
480
481
  // * Insert all the code needed to materialize the constants
482
  // at the proper place. E.g., Entry block or dominator block
483
  // of each constant depending on how fancy we want to be.
484
  // * Clear the different maps.
485
  void finalizeFunction();
486
487
  /// Get the VRegs that represent \p Val.
488
  /// Non-aggregate types have just one corresponding VReg and the list can be
489
  /// used as a single "unsigned". Aggregates get flattened. If such VRegs do
490
  /// not exist, they are created.
491
  ArrayRef<unsigned> getOrCreateVRegs(const Value &Val);
492
493
19.8M
  unsigned getOrCreateVReg(const Value &Val) {
494
19.8M
    auto Regs = getOrCreateVRegs(Val);
495
19.8M
    if (Regs.empty())
496
368k
      return 0;
497
19.4M
    assert(Regs.size() == 1 &&
498
19.4M
           "attempt to get single VReg for aggregate or void");
499
19.4M
    return Regs[0];
500
19.4M
  }
501
502
  /// Allocate some vregs and offsets in the VMap. Then populate just the
503
  /// offsets while leaving the vregs empty.
504
  ValueToVRegInfo::VRegListT &allocateVRegs(const Value &Val);
505
506
  /// Get the frame index that represents \p Val.
507
  /// If such VReg does not exist, it is created.
508
  int getOrCreateFrameIndex(const AllocaInst &AI);
509
510
  /// Get the alignment of the given memory operation instruction. This will
511
  /// either be the explicitly specified value or the ABI-required alignment for
512
  /// the type being accessed (according to the Module's DataLayout).
513
  unsigned getMemOpAlignment(const Instruction &I);
514
515
  /// Get the MachineBasicBlock that represents \p BB. Specifically, the block
516
  /// returned will be the head of the translated block (suitable for branch
517
  /// destinations).
518
  MachineBasicBlock &getMBB(const BasicBlock &BB);
519
520
  /// Record \p NewPred as a Machine predecessor to `Edge.second`, corresponding
521
  /// to `Edge.first` at the IR level. This is used when IRTranslation creates
522
  /// multiple MachineBasicBlocks for a given IR block and the CFG is no longer
523
  /// represented simply by the IR-level CFG.
524
  void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
525
526
  /// Returns the Machine IR predecessors for the given IR CFG edge. Usually
527
  /// this is just the single MachineBasicBlock corresponding to the predecessor
528
  /// in the IR. More complex lowering can result in multiple MachineBasicBlocks
529
  /// preceding the original though (e.g. switch instructions).
530
1.26M
  SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
531
1.26M
    auto RemappedEdge = MachinePreds.find(Edge);
532
1.26M
    if (RemappedEdge != MachinePreds.end())
533
11.1k
      return RemappedEdge->second;
534
1.25M
    return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
535
1.25M
  }
536
537
public:
538
  // Ctor, nothing fancy.
539
  IRTranslator();
540
541
6.89k
  StringRef getPassName() const override { return "IRTranslator"; }
542
543
  void getAnalysisUsage(AnalysisUsage &AU) const override;
544
545
  // Algo:
546
  //   CallLowering = MF.subtarget.getCallLowering()
547
  //   F = MF.getParent()
548
  //   MIRBuilder.reset(MF)
549
  //   getMBB(F.getEntryBB())
550
  //   CallLowering->translateArguments(MIRBuilder, F, ValToVReg)
551
  //   for each bb in F
552
  //     getMBB(bb)
553
  //     for each inst in bb
554
  //       if (!translate(MIRBuilder, inst, ValToVReg, ConstantToSequence))
555
  //         report_fatal_error("Don't know how to translate input");
556
  //   finalize()
557
  bool runOnMachineFunction(MachineFunction &MF) override;
558
};
559
560
} // end namespace llvm
561
562
#endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H