Coverage Report

Created: 2019-07-24 05:18

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