Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
Line
Count
Source (jump to first uncovered line)
1
//===-- llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h -----*- 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
// This file contains some helper functions which try to cleanup artifacts
9
// such as G_TRUNCs/G_[ZSA]EXTENDS that were created during legalization to make
10
// the types match. This file also contains some combines of merges that happens
11
// at the end of the legalization.
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
15
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
16
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
17
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
18
#include "llvm/CodeGen/GlobalISel/Utils.h"
19
#include "llvm/CodeGen/MachineRegisterInfo.h"
20
#include "llvm/Support/Debug.h"
21
22
#define DEBUG_TYPE "legalizer"
23
using namespace llvm::MIPatternMatch;
24
25
namespace llvm {
26
class LegalizationArtifactCombiner {
27
  MachineIRBuilder &Builder;
28
  MachineRegisterInfo &MRI;
29
  const LegalizerInfo &LI;
30
31
4.24k
  static bool isArtifactCast(unsigned Opc) {
32
4.24k
    switch (Opc) {
33
4.24k
    case TargetOpcode::G_TRUNC:
34
1.00k
    case TargetOpcode::G_SEXT:
35
1.00k
    case TargetOpcode::G_ZEXT:
36
1.00k
    case TargetOpcode::G_ANYEXT:
37
1.00k
      return true;
38
3.24k
    default:
39
3.24k
      return false;
40
4.24k
    }
41
4.24k
  }
42
43
public:
44
  LegalizationArtifactCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI,
45
                    const LegalizerInfo &LI)
46
240k
      : Builder(B), MRI(MRI), LI(LI) {}
47
48
  bool tryCombineAnyExt(MachineInstr &MI,
49
317k
                        SmallVectorImpl<MachineInstr *> &DeadInsts) {
50
317k
    if (MI.getOpcode() != TargetOpcode::G_ANYEXT)
51
0
      return false;
52
317k
53
317k
    Builder.setInstr(MI);
54
317k
    Register DstReg = MI.getOperand(0).getReg();
55
317k
    Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
56
317k
57
317k
    // aext(trunc x) - > aext/copy/trunc x
58
317k
    Register TruncSrc;
59
317k
    if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
60
184k
      LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
61
184k
      Builder.buildAnyExtOrTrunc(DstReg, TruncSrc);
62
184k
      markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
63
184k
      return true;
64
184k
    }
65
132k
66
132k
    // aext([asz]ext x) -> [asz]ext x
67
132k
    Register ExtSrc;
68
132k
    MachineInstr *ExtMI;
69
132k
    if (mi_match(SrcReg, MRI,
70
132k
                 m_all_of(m_MInstr(ExtMI), m_any_of(m_GAnyExt(m_Reg(ExtSrc)),
71
132k
                                                    m_GSExt(m_Reg(ExtSrc)),
72
132k
                                                    m_GZExt(m_Reg(ExtSrc)))))) {
73
203
      Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc});
74
203
      markInstAndDefDead(MI, *ExtMI, DeadInsts);
75
203
      return true;
76
203
    }
77
132k
78
132k
    // Try to fold aext(g_constant) when the larger constant type is legal.
79
132k
    // Can't use MIPattern because we don't have a specific constant in mind.
80
132k
    auto *SrcMI = MRI.getVRegDef(SrcReg);
81
132k
    if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
82
93.6k
      const LLT &DstTy = MRI.getType(DstReg);
83
93.6k
      if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
84
93.6k
        auto &CstVal = SrcMI->getOperand(1);
85
93.6k
        Builder.buildConstant(
86
93.6k
            DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits()));
87
93.6k
        markInstAndDefDead(MI, *SrcMI, DeadInsts);
88
93.6k
        return true;
89
93.6k
      }
90
38.8k
    }
91
38.8k
    return tryFoldImplicitDef(MI, DeadInsts);
92
38.8k
  }
93
94
  bool tryCombineZExt(MachineInstr &MI,
95
331k
                      SmallVectorImpl<MachineInstr *> &DeadInsts) {
96
331k
97
331k
    if (MI.getOpcode() != TargetOpcode::G_ZEXT)
98
0
      return false;
99
331k
100
331k
    Builder.setInstr(MI);
101
331k
    Register DstReg = MI.getOperand(0).getReg();
102
331k
    Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
103
331k
104
331k
    // zext(trunc x) - > and (aext/copy/trunc x), mask
105
331k
    Register TruncSrc;
106
331k
    if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
107
54.9k
      LLT DstTy = MRI.getType(DstReg);
108
54.9k
      if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) ||
109
54.9k
          isConstantUnsupported(DstTy))
110
0
        return false;
111
54.9k
      LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
112
54.9k
      LLT SrcTy = MRI.getType(SrcReg);
113
54.9k
      APInt Mask = APInt::getAllOnesValue(SrcTy.getScalarSizeInBits());
114
54.9k
      auto MIBMask = Builder.buildConstant(DstTy, Mask.getZExtValue());
115
54.9k
      Builder.buildAnd(DstReg, Builder.buildAnyExtOrTrunc(DstTy, TruncSrc),
116
54.9k
                       MIBMask);
117
54.9k
      markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
118
54.9k
      return true;
119
54.9k
    }
120
276k
121
276k
    // Try to fold zext(g_constant) when the larger constant type is legal.
122
276k
    // Can't use MIPattern because we don't have a specific constant in mind.
123
276k
    auto *SrcMI = MRI.getVRegDef(SrcReg);
124
276k
    if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
125
124k
      const LLT &DstTy = MRI.getType(DstReg);
126
124k
      if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
127
124k
        auto &CstVal = SrcMI->getOperand(1);
128
124k
        Builder.buildConstant(
129
124k
            DstReg, CstVal.getCImm()->getValue().zext(DstTy.getSizeInBits()));
130
124k
        markInstAndDefDead(MI, *SrcMI, DeadInsts);
131
124k
        return true;
132
124k
      }
133
151k
    }
134
151k
    return tryFoldImplicitDef(MI, DeadInsts);
135
151k
  }
136
137
  bool tryCombineSExt(MachineInstr &MI,
138
114k
                      SmallVectorImpl<MachineInstr *> &DeadInsts) {
139
114k
140
114k
    if (MI.getOpcode() != TargetOpcode::G_SEXT)
141
0
      return false;
142
114k
143
114k
    Builder.setInstr(MI);
144
114k
    Register DstReg = MI.getOperand(0).getReg();
145
114k
    Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
146
114k
147
114k
    // sext(trunc x) - > ashr (shl (aext/copy/trunc x), c), c
148
114k
    Register TruncSrc;
149
114k
    if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
150
14.1k
      LLT DstTy = MRI.getType(DstReg);
151
14.1k
      // Guess on the RHS shift amount type, which should be re-legalized if
152
14.1k
      // applicable.
153
14.1k
      if (isInstUnsupported({TargetOpcode::G_SHL, {DstTy, DstTy}}) ||
154
14.1k
          isInstUnsupported({TargetOpcode::G_ASHR, {DstTy, DstTy}}) ||
155
14.1k
          
isConstantUnsupported(DstTy)14.1k
)
156
2
        return false;
157
14.1k
      LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
158
14.1k
      LLT SrcTy = MRI.getType(SrcReg);
159
14.1k
      unsigned ShAmt = DstTy.getScalarSizeInBits() - SrcTy.getScalarSizeInBits();
160
14.1k
      auto MIBShAmt = Builder.buildConstant(DstTy, ShAmt);
161
14.1k
      auto MIBShl = Builder.buildInstr(
162
14.1k
          TargetOpcode::G_SHL, {DstTy},
163
14.1k
          {Builder.buildAnyExtOrTrunc(DstTy, TruncSrc), MIBShAmt});
164
14.1k
      Builder.buildInstr(TargetOpcode::G_ASHR, {DstReg}, {MIBShl, MIBShAmt});
165
14.1k
      markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
166
14.1k
      return true;
167
14.1k
    }
168
100k
    return tryFoldImplicitDef(MI, DeadInsts);
169
100k
  }
170
171
  /// Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF).
172
  bool tryFoldImplicitDef(MachineInstr &MI,
173
290k
                          SmallVectorImpl<MachineInstr *> &DeadInsts) {
174
290k
    unsigned Opcode = MI.getOpcode();
175
290k
    if (Opcode != TargetOpcode::G_ANYEXT && 
Opcode != TargetOpcode::G_ZEXT251k
&&
176
290k
        
Opcode != TargetOpcode::G_SEXT100k
)
177
0
      return false;
178
290k
179
290k
    if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF,
180
29
                                           MI.getOperand(1).getReg(), MRI)) {
181
29
      Builder.setInstr(MI);
182
29
      Register DstReg = MI.getOperand(0).getReg();
183
29
      LLT DstTy = MRI.getType(DstReg);
184
29
185
29
      if (Opcode == TargetOpcode::G_ANYEXT) {
186
19
        // G_ANYEXT (G_IMPLICIT_DEF) -> G_IMPLICIT_DEF
187
19
        if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
188
0
          return false;
189
19
        LLVM_DEBUG(dbgs() << ".. Combine G_ANYEXT(G_IMPLICIT_DEF): " << MI;);
190
19
        Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, {DstReg}, {});
191
19
      } else {
192
10
        // G_[SZ]EXT (G_IMPLICIT_DEF) -> G_CONSTANT 0 because the top
193
10
        // bits will be 0 for G_ZEXT and 0/1 for the G_SEXT.
194
10
        if (isConstantUnsupported(DstTy))
195
0
          return false;
196
10
        LLVM_DEBUG(dbgs() << ".. Combine G_[SZ]EXT(G_IMPLICIT_DEF): " << MI;);
197
10
        Builder.buildConstant(DstReg, 0);
198
10
      }
199
29
200
29
      markInstAndDefDead(MI, *DefMI, DeadInsts);
201
29
      return true;
202
290k
    }
203
290k
    return false;
204
290k
  }
205
206
4.24k
  static unsigned getMergeOpcode(LLT OpTy, LLT DestTy) {
207
4.24k
    if (OpTy.isVector() && 
DestTy.isVector()3.35k
)
208
201
      return TargetOpcode::G_CONCAT_VECTORS;
209
4.04k
210
4.04k
    if (OpTy.isVector() && 
!DestTy.isVector()3.15k
)
211
3.15k
      return TargetOpcode::G_BUILD_VECTOR;
212
891
213
891
    return TargetOpcode::G_MERGE_VALUES;
214
891
  }
215
216
  bool tryCombineMerges(MachineInstr &MI,
217
4.24k
                        SmallVectorImpl<MachineInstr *> &DeadInsts) {
218
4.24k
219
4.24k
    if (MI.getOpcode() != TargetOpcode::G_UNMERGE_VALUES)
220
0
      return false;
221
4.24k
222
4.24k
    unsigned NumDefs = MI.getNumOperands() - 1;
223
4.24k
    MachineInstr *SrcDef =
224
4.24k
        getDefIgnoringCopies(MI.getOperand(NumDefs).getReg(), MRI);
225
4.24k
    if (!SrcDef)
226
0
      return false;
227
4.24k
228
4.24k
    LLT OpTy = MRI.getType(MI.getOperand(NumDefs).getReg());
229
4.24k
    LLT DestTy = MRI.getType(MI.getOperand(0).getReg());
230
4.24k
    MachineInstr *MergeI = SrcDef;
231
4.24k
    unsigned ConvertOp = 0;
232
4.24k
233
4.24k
    // Handle intermediate conversions
234
4.24k
    unsigned SrcOp = SrcDef->getOpcode();
235
4.24k
    if (isArtifactCast(SrcOp)) {
236
1.00k
      ConvertOp = SrcOp;
237
1.00k
      MergeI = getDefIgnoringCopies(SrcDef->getOperand(1).getReg(), MRI);
238
1.00k
    }
239
4.24k
240
4.24k
    // FIXME: Handle scalarizing concat_vectors (scalar result type with vector
241
4.24k
    // source)
242
4.24k
    unsigned MergingOpcode = getMergeOpcode(OpTy, DestTy);
243
4.24k
    if (!MergeI || MergeI->getOpcode() != MergingOpcode)
244
3.00k
      return false;
245
1.24k
246
1.24k
    const unsigned NumMergeRegs = MergeI->getNumOperands() - 1;
247
1.24k
248
1.24k
    if (NumMergeRegs < NumDefs) {
249
11
      if (ConvertOp != 0 || NumDefs % NumMergeRegs != 0)
250
0
        return false;
251
11
252
11
      Builder.setInstr(MI);
253
11
      // Transform to UNMERGEs, for example
254
11
      //   %1 = G_MERGE_VALUES %4, %5
255
11
      //   %9, %10, %11, %12 = G_UNMERGE_VALUES %1
256
11
      // to
257
11
      //   %9, %10 = G_UNMERGE_VALUES %4
258
11
      //   %11, %12 = G_UNMERGE_VALUES %5
259
11
260
11
      const unsigned NewNumDefs = NumDefs / NumMergeRegs;
261
33
      for (unsigned Idx = 0; Idx < NumMergeRegs; 
++Idx22
) {
262
22
        SmallVector<Register, 2> DstRegs;
263
70
        for (unsigned j = 0, DefIdx = Idx * NewNumDefs; j < NewNumDefs;
264
48
             ++j, ++DefIdx)
265
48
          DstRegs.push_back(MI.getOperand(DefIdx).getReg());
266
22
267
22
        Builder.buildUnmerge(DstRegs, MergeI->getOperand(Idx + 1).getReg());
268
22
      }
269
11
270
1.23k
    } else if (NumMergeRegs > NumDefs) {
271
7
      if (ConvertOp != 0 || 
NumMergeRegs % NumDefs != 05
)
272
2
        return false;
273
5
274
5
      Builder.setInstr(MI);
275
5
      // Transform to MERGEs
276
5
      //   %6 = G_MERGE_VALUES %17, %18, %19, %20
277
5
      //   %7, %8 = G_UNMERGE_VALUES %6
278
5
      // to
279
5
      //   %7 = G_MERGE_VALUES %17, %18
280
5
      //   %8 = G_MERGE_VALUES %19, %20
281
5
282
5
      const unsigned NumRegs = NumMergeRegs / NumDefs;
283
15
      for (unsigned DefIdx = 0; DefIdx < NumDefs; 
++DefIdx10
) {
284
10
        SmallVector<Register, 2> Regs;
285
30
        for (unsigned j = 0, Idx = NumRegs * DefIdx + 1; j < NumRegs;
286
20
             ++j, ++Idx)
287
20
          Regs.push_back(MergeI->getOperand(Idx).getReg());
288
10
289
10
        Builder.buildMerge(MI.getOperand(DefIdx).getReg(), Regs);
290
10
      }
291
5
292
1.23k
    } else {
293
1.23k
      LLT MergeSrcTy = MRI.getType(MergeI->getOperand(1).getReg());
294
1.23k
      if (ConvertOp) {
295
20
        Builder.setInstr(MI);
296
20
297
69
        for (unsigned Idx = 0; Idx < NumDefs; 
++Idx49
) {
298
49
          Register MergeSrc = MergeI->getOperand(Idx + 1).getReg();
299
49
          Builder.buildInstr(ConvertOp, {MI.getOperand(Idx).getReg()},
300
49
                             {MergeSrc});
301
49
        }
302
20
303
20
        markInstAndDefDead(MI, *MergeI, DeadInsts);
304
20
        return true;
305
20
      }
306
1.21k
      // FIXME: is a COPY appropriate if the types mismatch? We know both
307
1.21k
      // registers are allocatable by now.
308
1.21k
      if (DestTy != MergeSrcTy)
309
0
        return false;
310
1.21k
311
4.60k
      
for (unsigned Idx = 0; 1.21k
Idx < NumDefs;
++Idx3.39k
)
312
3.39k
        MRI.replaceRegWith(MI.getOperand(Idx).getReg(),
313
3.39k
                           MergeI->getOperand(Idx + 1).getReg());
314
1.21k
    }
315
1.24k
316
1.24k
    markInstAndDefDead(MI, *MergeI, DeadInsts);
317
1.22k
    return true;
318
1.24k
  }
319
320
526
  static bool isMergeLikeOpcode(unsigned Opc) {
321
526
    switch (Opc) {
322
526
    case TargetOpcode::G_MERGE_VALUES:
323
44
    case TargetOpcode::G_BUILD_VECTOR:
324
44
    case TargetOpcode::G_CONCAT_VECTORS:
325
44
      return true;
326
482
    default:
327
482
      return false;
328
526
    }
329
526
  }
330
331
  bool tryCombineExtract(MachineInstr &MI,
332
526
                         SmallVectorImpl<MachineInstr *> &DeadInsts) {
333
526
    assert(MI.getOpcode() == TargetOpcode::G_EXTRACT);
334
526
335
526
    // Try to use the source registers from a G_MERGE_VALUES
336
526
    //
337
526
    // %2 = G_MERGE_VALUES %0, %1
338
526
    // %3 = G_EXTRACT %2, N
339
526
    // =>
340
526
    //
341
526
    // for N < %2.getSizeInBits() / 2
342
526
    //     %3 = G_EXTRACT %0, N
343
526
    //
344
526
    // for N >= %2.getSizeInBits() / 2
345
526
    //    %3 = G_EXTRACT %1, (N - %0.getSizeInBits()
346
526
347
526
    unsigned Src = lookThroughCopyInstrs(MI.getOperand(1).getReg());
348
526
    MachineInstr *MergeI = MRI.getVRegDef(Src);
349
526
    if (!MergeI || !isMergeLikeOpcode(MergeI->getOpcode()))
350
482
      return false;
351
44
352
44
    LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
353
44
    LLT SrcTy = MRI.getType(Src);
354
44
355
44
    // TODO: Do we need to check if the resulting extract is supported?
356
44
    unsigned ExtractDstSize = DstTy.getSizeInBits();
357
44
    unsigned Offset = MI.getOperand(2).getImm();
358
44
    unsigned NumMergeSrcs = MergeI->getNumOperands() - 1;
359
44
    unsigned MergeSrcSize = SrcTy.getSizeInBits() / NumMergeSrcs;
360
44
    unsigned MergeSrcIdx = Offset / MergeSrcSize;
361
44
362
44
    // Compute the offset of the last bit the extract needs.
363
44
    unsigned EndMergeSrcIdx = (Offset + ExtractDstSize - 1) / MergeSrcSize;
364
44
365
44
    // Can't handle the case where the extract spans multiple inputs.
366
44
    if (MergeSrcIdx != EndMergeSrcIdx)
367
13
      return false;
368
31
369
31
    // TODO: We could modify MI in place in most cases.
370
31
    Builder.setInstr(MI);
371
31
    Builder.buildExtract(
372
31
      MI.getOperand(0).getReg(),
373
31
      MergeI->getOperand(MergeSrcIdx + 1).getReg(),
374
31
      Offset - MergeSrcIdx * MergeSrcSize);
375
31
    markInstAndDefDead(MI, *MergeI, DeadInsts);
376
31
    return true;
377
31
  }
378
379
  /// Try to combine away MI.
380
  /// Returns true if it combined away the MI.
381
  /// Adds instructions that are dead as a result of the combine
382
  /// into DeadInsts, which can include MI.
383
  bool tryCombineInstruction(MachineInstr &MI,
384
                             SmallVectorImpl<MachineInstr *> &DeadInsts,
385
3.24M
                             GISelObserverWrapper &WrapperObserver) {
386
3.24M
    // This might be a recursive call, and we might have DeadInsts already
387
3.24M
    // populated. To avoid bad things happening later with multiple vreg defs
388
3.24M
    // etc, process the dead instructions now if any.
389
3.24M
    if (!DeadInsts.empty())
390
25.9k
      deleteMarkedDeadInsts(DeadInsts, WrapperObserver);
391
3.24M
    switch (MI.getOpcode()) {
392
3.24M
    default:
393
1.18M
      return false;
394
3.24M
    case TargetOpcode::G_ANYEXT:
395
317k
      return tryCombineAnyExt(MI, DeadInsts);
396
3.24M
    case TargetOpcode::G_ZEXT:
397
331k
      return tryCombineZExt(MI, DeadInsts);
398
3.24M
    case TargetOpcode::G_SEXT:
399
114k
      return tryCombineSExt(MI, DeadInsts);
400
3.24M
    case TargetOpcode::G_UNMERGE_VALUES:
401
4.18k
      return tryCombineMerges(MI, DeadInsts);
402
3.24M
    case TargetOpcode::G_EXTRACT:
403
526
      return tryCombineExtract(MI, DeadInsts);
404
3.24M
    case TargetOpcode::G_TRUNC: {
405
1.29M
      bool Changed = false;
406
1.29M
      for (auto &Use : MRI.use_instructions(MI.getOperand(0).getReg()))
407
1.36M
        Changed |= tryCombineInstruction(Use, DeadInsts, WrapperObserver);
408
1.29M
      return Changed;
409
3.24M
    }
410
3.24M
    }
411
3.24M
  }
412
413
private:
414
415
482k
  static unsigned getArtifactSrcReg(const MachineInstr &MI) {
416
482k
    switch (MI.getOpcode()) {
417
482k
    case TargetOpcode::COPY:
418
482k
    case TargetOpcode::G_TRUNC:
419
482k
    case TargetOpcode::G_ZEXT:
420
482k
    case TargetOpcode::G_ANYEXT:
421
482k
    case TargetOpcode::G_SEXT:
422
482k
    case TargetOpcode::G_UNMERGE_VALUES:
423
482k
      return MI.getOperand(MI.getNumOperands() - 1).getReg();
424
482k
    case TargetOpcode::G_EXTRACT:
425
31
      return MI.getOperand(1).getReg();
426
482k
    default:
427
0
      llvm_unreachable("Not a legalization artifact happen");
428
482k
    }
429
482k
  }
430
431
  /// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be
432
  /// dead due to MI being killed, then mark DefMI as dead too.
433
  /// Some of the combines (extends(trunc)), try to walk through redundant
434
  /// copies in between the extends and the truncs, and this attempts to collect
435
  /// the in between copies if they're dead.
436
  void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI,
437
473k
                          SmallVectorImpl<MachineInstr *> &DeadInsts) {
438
473k
    DeadInsts.push_back(&MI);
439
473k
440
473k
    // Collect all the copy instructions that are made dead, due to deleting
441
473k
    // this instruction. Collect all of them until the Trunc(DefMI).
442
473k
    // Eg,
443
473k
    // %1(s1) = G_TRUNC %0(s32)
444
473k
    // %2(s1) = COPY %1(s1)
445
473k
    // %3(s1) = COPY %2(s1)
446
473k
    // %4(s32) = G_ANYEXT %3(s1)
447
473k
    // In this case, we would have replaced %4 with a copy of %0,
448
473k
    // and as a result, %3, %2, %1 are dead.
449
473k
    MachineInstr *PrevMI = &MI;
450
782k
    while (PrevMI != &DefMI) {
451
482k
      unsigned PrevRegSrc = getArtifactSrcReg(*PrevMI);
452
482k
453
482k
      MachineInstr *TmpDef = MRI.getVRegDef(PrevRegSrc);
454
482k
      if (MRI.hasOneUse(PrevRegSrc)) {
455
309k
        if (TmpDef != &DefMI) {
456
8.98k
          assert((TmpDef->getOpcode() == TargetOpcode::COPY ||
457
8.98k
                  isArtifactCast(TmpDef->getOpcode())) &&
458
8.98k
                 "Expecting copy or artifact cast here");
459
8.98k
460
8.98k
          DeadInsts.push_back(TmpDef);
461
8.98k
        }
462
309k
      } else
463
173k
        break;
464
309k
      PrevMI = TmpDef;
465
309k
    }
466
473k
    if (PrevMI == &DefMI && 
MRI.hasOneUse(DefMI.getOperand(0).getReg())300k
)
467
300k
      DeadInsts.push_back(&DefMI);
468
473k
  }
469
470
  /// Erase the dead instructions in the list and call the observer hooks.
471
  /// Normally the Legalizer will deal with erasing instructions that have been
472
  /// marked dead. However, for the trunc(ext(x)) cases we can end up trying to
473
  /// process instructions which have been marked dead, but otherwise break the
474
  /// MIR by introducing multiple vreg defs. For those cases, allow the combines
475
  /// to explicitly delete the instructions before we run into trouble.
476
  void deleteMarkedDeadInsts(SmallVectorImpl<MachineInstr *> &DeadInsts,
477
25.9k
                             GISelObserverWrapper &WrapperObserver) {
478
26.1k
    for (auto *DeadMI : DeadInsts) {
479
26.1k
      LLVM_DEBUG(dbgs() << *DeadMI << "Is dead, eagerly deleting\n");
480
26.1k
      WrapperObserver.erasingInstr(*DeadMI);
481
26.1k
      DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
482
26.1k
    }
483
25.9k
    DeadInsts.clear();
484
25.9k
  }
485
486
  /// Checks if the target legalizer info has specified anything about the
487
  /// instruction, or if unsupported.
488
152k
  bool isInstUnsupported(const LegalityQuery &Query) const {
489
152k
    using namespace LegalizeActions;
490
152k
    auto Step = LI.getAction(Query);
491
152k
    return Step.Action == Unsupported || 
Step.Action == NotFound152k
;
492
152k
  }
493
494
218k
  bool isInstLegal(const LegalityQuery &Query) const {
495
218k
    return LI.getAction(Query).Action == LegalizeActions::Legal;
496
218k
  }
497
498
69.1k
  bool isConstantUnsupported(LLT Ty) const {
499
69.1k
    if (!Ty.isVector())
500
69.0k
      return isInstUnsupported({TargetOpcode::G_CONSTANT, {Ty}});
501
86
502
86
    LLT EltTy = Ty.getElementType();
503
86
    return isInstUnsupported({TargetOpcode::G_CONSTANT, {EltTy}}) ||
504
86
           isInstUnsupported({TargetOpcode::G_BUILD_VECTOR, {Ty, EltTy}});
505
86
  }
506
507
  /// Looks through copy instructions and returns the actual
508
  /// source register.
509
763k
  unsigned lookThroughCopyInstrs(Register Reg) {
510
763k
    Register TmpReg;
511
772k
    while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg)))) {
512
68.3k
      if (MRI.getType(TmpReg).isValid())
513
8.97k
        Reg = TmpReg;
514
59.3k
      else
515
59.3k
        break;
516
68.3k
    }
517
763k
    return Reg;
518
763k
  }
519
};
520
521
} // namespace llvm