Coverage Report

Created: 2018-09-19 08:35

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