LLVM  14.0.0git
LegalizationArtifactCombiner.h
Go to the documentation of this file.
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 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H
15 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H
16 
26 #include "llvm/Support/Debug.h"
27 
28 #define DEBUG_TYPE "legalizer"
29 using namespace llvm::MIPatternMatch;
30 
31 namespace llvm {
35  const LegalizerInfo &LI;
36 
37  static bool isArtifactCast(unsigned Opc) {
38  switch (Opc) {
39  case TargetOpcode::G_TRUNC:
40  case TargetOpcode::G_SEXT:
41  case TargetOpcode::G_ZEXT:
42  case TargetOpcode::G_ANYEXT:
43  return true;
44  default:
45  return false;
46  }
47  }
48 
49 public:
51  const LegalizerInfo &LI)
52  : Builder(B), MRI(MRI), LI(LI) {}
53 
56  SmallVectorImpl<Register> &UpdatedDefs) {
57  assert(MI.getOpcode() == TargetOpcode::G_ANYEXT);
58 
59  Builder.setInstrAndDebugLoc(MI);
60  Register DstReg = MI.getOperand(0).getReg();
61  Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
62 
63  // aext(trunc x) - > aext/copy/trunc x
64  Register TruncSrc;
65  if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
66  LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
67  Builder.buildAnyExtOrTrunc(DstReg, TruncSrc);
68  UpdatedDefs.push_back(DstReg);
69  markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
70  return true;
71  }
72 
73  // aext([asz]ext x) -> [asz]ext x
74  Register ExtSrc;
75  MachineInstr *ExtMI;
76  if (mi_match(SrcReg, MRI,
77  m_all_of(m_MInstr(ExtMI), m_any_of(m_GAnyExt(m_Reg(ExtSrc)),
78  m_GSExt(m_Reg(ExtSrc)),
79  m_GZExt(m_Reg(ExtSrc)))))) {
80  Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc});
81  UpdatedDefs.push_back(DstReg);
82  markInstAndDefDead(MI, *ExtMI, DeadInsts);
83  return true;
84  }
85 
86  // Try to fold aext(g_constant) when the larger constant type is legal.
87  auto *SrcMI = MRI.getVRegDef(SrcReg);
88  if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
89  const LLT DstTy = MRI.getType(DstReg);
90  if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
91  auto &CstVal = SrcMI->getOperand(1);
92  Builder.buildConstant(
93  DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits()));
94  UpdatedDefs.push_back(DstReg);
95  markInstAndDefDead(MI, *SrcMI, DeadInsts);
96  return true;
97  }
98  }
99  return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs);
100  }
101 
104  SmallVectorImpl<Register> &UpdatedDefs,
105  GISelObserverWrapper &Observer) {
106  assert(MI.getOpcode() == TargetOpcode::G_ZEXT);
107 
108  Builder.setInstrAndDebugLoc(MI);
109  Register DstReg = MI.getOperand(0).getReg();
110  Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
111 
112  // zext(trunc x) - > and (aext/copy/trunc x), mask
113  // zext(sext x) -> and (sext x), mask
114  Register TruncSrc;
115  Register SextSrc;
116  if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc))) ||
117  mi_match(SrcReg, MRI, m_GSExt(m_Reg(SextSrc)))) {
118  LLT DstTy = MRI.getType(DstReg);
119  if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) ||
120  isConstantUnsupported(DstTy))
121  return false;
122  LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
123  LLT SrcTy = MRI.getType(SrcReg);
124  APInt MaskVal = APInt::getAllOnesValue(SrcTy.getScalarSizeInBits());
125  auto Mask = Builder.buildConstant(
126  DstTy, MaskVal.zext(DstTy.getScalarSizeInBits()));
127  auto Extended = SextSrc ? Builder.buildSExtOrTrunc(DstTy, SextSrc) :
128  Builder.buildAnyExtOrTrunc(DstTy, TruncSrc);
129  Builder.buildAnd(DstReg, Extended, Mask);
130  markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
131  return true;
132  }
133 
134  // zext(zext x) -> (zext x)
135  Register ZextSrc;
136  if (mi_match(SrcReg, MRI, m_GZExt(m_Reg(ZextSrc)))) {
137  LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI);
138  Observer.changingInstr(MI);
139  MI.getOperand(1).setReg(ZextSrc);
140  Observer.changedInstr(MI);
141  UpdatedDefs.push_back(DstReg);
142  markDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
143  return true;
144  }
145 
146  // Try to fold zext(g_constant) when the larger constant type is legal.
147  auto *SrcMI = MRI.getVRegDef(SrcReg);
148  if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
149  const LLT DstTy = MRI.getType(DstReg);
150  if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
151  auto &CstVal = SrcMI->getOperand(1);
152  Builder.buildConstant(
153  DstReg, CstVal.getCImm()->getValue().zext(DstTy.getSizeInBits()));
154  UpdatedDefs.push_back(DstReg);
155  markInstAndDefDead(MI, *SrcMI, DeadInsts);
156  return true;
157  }
158  }
159  return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs);
160  }
161 
164  SmallVectorImpl<Register> &UpdatedDefs) {
165  assert(MI.getOpcode() == TargetOpcode::G_SEXT);
166 
167  Builder.setInstrAndDebugLoc(MI);
168  Register DstReg = MI.getOperand(0).getReg();
169  Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
170 
171  // sext(trunc x) - > (sext_inreg (aext/copy/trunc x), c)
172  Register TruncSrc;
173  if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
174  LLT DstTy = MRI.getType(DstReg);
175  if (isInstUnsupported({TargetOpcode::G_SEXT_INREG, {DstTy}}))
176  return false;
177  LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
178  LLT SrcTy = MRI.getType(SrcReg);
179  uint64_t SizeInBits = SrcTy.getScalarSizeInBits();
180  Builder.buildInstr(
181  TargetOpcode::G_SEXT_INREG, {DstReg},
182  {Builder.buildAnyExtOrTrunc(DstTy, TruncSrc), SizeInBits});
183  markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
184  return true;
185  }
186 
187  // sext(zext x) -> (zext x)
188  // sext(sext x) -> (sext x)
189  Register ExtSrc;
190  MachineInstr *ExtMI;
191  if (mi_match(SrcReg, MRI,
192  m_all_of(m_MInstr(ExtMI), m_any_of(m_GZExt(m_Reg(ExtSrc)),
193  m_GSExt(m_Reg(ExtSrc)))))) {
194  LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI);
195  Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc});
196  UpdatedDefs.push_back(DstReg);
197  markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
198  return true;
199  }
200 
201  // Try to fold sext(g_constant) when the larger constant type is legal.
202  auto *SrcMI = MRI.getVRegDef(SrcReg);
203  if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
204  const LLT DstTy = MRI.getType(DstReg);
205  if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
206  auto &CstVal = SrcMI->getOperand(1);
207  Builder.buildConstant(
208  DstReg, CstVal.getCImm()->getValue().sext(DstTy.getSizeInBits()));
209  UpdatedDefs.push_back(DstReg);
210  markInstAndDefDead(MI, *SrcMI, DeadInsts);
211  return true;
212  }
213  }
214 
215  return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs);
216  }
217 
220  SmallVectorImpl<Register> &UpdatedDefs,
221  GISelObserverWrapper &Observer) {
222  assert(MI.getOpcode() == TargetOpcode::G_TRUNC);
223 
224  Builder.setInstr(MI);
225  Register DstReg = MI.getOperand(0).getReg();
226  Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
227 
228  // Try to fold trunc(g_constant) when the smaller constant type is legal.
229  auto *SrcMI = MRI.getVRegDef(SrcReg);
230  if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
231  const LLT DstTy = MRI.getType(DstReg);
232  if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
233  auto &CstVal = SrcMI->getOperand(1);
234  Builder.buildConstant(
235  DstReg, CstVal.getCImm()->getValue().trunc(DstTy.getSizeInBits()));
236  UpdatedDefs.push_back(DstReg);
237  markInstAndDefDead(MI, *SrcMI, DeadInsts);
238  return true;
239  }
240  }
241 
242  // Try to fold trunc(merge) to directly use the source of the merge.
243  // This gets rid of large, difficult to legalize, merges
244  if (auto *SrcMerge = dyn_cast<GMerge>(SrcMI)) {
245  const Register MergeSrcReg = SrcMerge->getSourceReg(0);
246  const LLT MergeSrcTy = MRI.getType(MergeSrcReg);
247  const LLT DstTy = MRI.getType(DstReg);
248 
249  // We can only fold if the types are scalar
250  const unsigned DstSize = DstTy.getSizeInBits();
251  const unsigned MergeSrcSize = MergeSrcTy.getSizeInBits();
252  if (!DstTy.isScalar() || !MergeSrcTy.isScalar())
253  return false;
254 
255  if (DstSize < MergeSrcSize) {
256  // When the merge source is larger than the destination, we can just
257  // truncate the merge source directly
258  if (isInstUnsupported({TargetOpcode::G_TRUNC, {DstTy, MergeSrcTy}}))
259  return false;
260 
261  LLVM_DEBUG(dbgs() << "Combining G_TRUNC(G_MERGE_VALUES) to G_TRUNC: "
262  << MI);
263 
264  Builder.buildTrunc(DstReg, MergeSrcReg);
265  UpdatedDefs.push_back(DstReg);
266  } else if (DstSize == MergeSrcSize) {
267  // If the sizes match we can simply try to replace the register
268  LLVM_DEBUG(
269  dbgs() << "Replacing G_TRUNC(G_MERGE_VALUES) with merge input: "
270  << MI);
271  replaceRegOrBuildCopy(DstReg, MergeSrcReg, MRI, Builder, UpdatedDefs,
272  Observer);
273  } else if (DstSize % MergeSrcSize == 0) {
274  // If the trunc size is a multiple of the merge source size we can use
275  // a smaller merge instead
276  if (isInstUnsupported(
277  {TargetOpcode::G_MERGE_VALUES, {DstTy, MergeSrcTy}}))
278  return false;
279 
280  LLVM_DEBUG(
281  dbgs() << "Combining G_TRUNC(G_MERGE_VALUES) to G_MERGE_VALUES: "
282  << MI);
283 
284  const unsigned NumSrcs = DstSize / MergeSrcSize;
285  assert(NumSrcs < SrcMI->getNumOperands() - 1 &&
286  "trunc(merge) should require less inputs than merge");
287  SmallVector<Register, 8> SrcRegs(NumSrcs);
288  for (unsigned i = 0; i < NumSrcs; ++i)
289  SrcRegs[i] = SrcMerge->getSourceReg(i);
290 
291  Builder.buildMerge(DstReg, SrcRegs);
292  UpdatedDefs.push_back(DstReg);
293  } else {
294  // Unable to combine
295  return false;
296  }
297 
298  markInstAndDefDead(MI, *SrcMerge, DeadInsts);
299  return true;
300  }
301 
302  // trunc(trunc) -> trunc
303  Register TruncSrc;
304  if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
305  // Always combine trunc(trunc) since the eventual resulting trunc must be
306  // legal anyway as it must be legal for all outputs of the consumer type
307  // set.
308  LLVM_DEBUG(dbgs() << ".. Combine G_TRUNC(G_TRUNC): " << MI);
309 
310  Builder.buildTrunc(DstReg, TruncSrc);
311  UpdatedDefs.push_back(DstReg);
312  markInstAndDefDead(MI, *MRI.getVRegDef(TruncSrc), DeadInsts);
313  return true;
314  }
315 
316  return false;
317  }
318 
319  /// Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF).
322  SmallVectorImpl<Register> &UpdatedDefs) {
323  unsigned Opcode = MI.getOpcode();
324  assert(Opcode == TargetOpcode::G_ANYEXT || Opcode == TargetOpcode::G_ZEXT ||
325  Opcode == TargetOpcode::G_SEXT);
326 
327  if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF,
328  MI.getOperand(1).getReg(), MRI)) {
329  Builder.setInstr(MI);
330  Register DstReg = MI.getOperand(0).getReg();
331  LLT DstTy = MRI.getType(DstReg);
332 
333  if (Opcode == TargetOpcode::G_ANYEXT) {
334  // G_ANYEXT (G_IMPLICIT_DEF) -> G_IMPLICIT_DEF
335  if (!isInstLegal({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
336  return false;
337  LLVM_DEBUG(dbgs() << ".. Combine G_ANYEXT(G_IMPLICIT_DEF): " << MI;);
338  Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, {DstReg}, {});
339  UpdatedDefs.push_back(DstReg);
340  } else {
341  // G_[SZ]EXT (G_IMPLICIT_DEF) -> G_CONSTANT 0 because the top
342  // bits will be 0 for G_ZEXT and 0/1 for the G_SEXT.
343  if (isConstantUnsupported(DstTy))
344  return false;
345  LLVM_DEBUG(dbgs() << ".. Combine G_[SZ]EXT(G_IMPLICIT_DEF): " << MI;);
346  Builder.buildConstant(DstReg, 0);
347  UpdatedDefs.push_back(DstReg);
348  }
349 
350  markInstAndDefDead(MI, *DefMI, DeadInsts);
351  return true;
352  }
353  return false;
354  }
355 
358  SmallVectorImpl<Register> &UpdatedDefs) {
359 
360  assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
361 
362  const unsigned CastOpc = CastMI.getOpcode();
363 
364  if (!isArtifactCast(CastOpc))
365  return false;
366 
367  const unsigned NumDefs = MI.getNumOperands() - 1;
368 
369  const Register CastSrcReg = CastMI.getOperand(1).getReg();
370  const LLT CastSrcTy = MRI.getType(CastSrcReg);
371  const LLT DestTy = MRI.getType(MI.getOperand(0).getReg());
372  const LLT SrcTy = MRI.getType(MI.getOperand(NumDefs).getReg());
373 
374  const unsigned CastSrcSize = CastSrcTy.getSizeInBits();
375  const unsigned DestSize = DestTy.getSizeInBits();
376 
377  if (CastOpc == TargetOpcode::G_TRUNC) {
378  if (SrcTy.isVector() && SrcTy.getScalarType() == DestTy.getScalarType()) {
379  // %1:_(<4 x s8>) = G_TRUNC %0(<4 x s32>)
380  // %2:_(s8), %3:_(s8), %4:_(s8), %5:_(s8) = G_UNMERGE_VALUES %1
381  // =>
382  // %6:_(s32), %7:_(s32), %8:_(s32), %9:_(s32) = G_UNMERGE_VALUES %0
383  // %2:_(s8) = G_TRUNC %6
384  // %3:_(s8) = G_TRUNC %7
385  // %4:_(s8) = G_TRUNC %8
386  // %5:_(s8) = G_TRUNC %9
387 
388  unsigned UnmergeNumElts =
389  DestTy.isVector() ? CastSrcTy.getNumElements() / NumDefs : 1;
390  LLT UnmergeTy = CastSrcTy.changeElementCount(
391  ElementCount::getFixed(UnmergeNumElts));
392 
393  if (isInstUnsupported(
394  {TargetOpcode::G_UNMERGE_VALUES, {UnmergeTy, CastSrcTy}}))
395  return false;
396 
397  Builder.setInstr(MI);
398  auto NewUnmerge = Builder.buildUnmerge(UnmergeTy, CastSrcReg);
399 
400  for (unsigned I = 0; I != NumDefs; ++I) {
401  Register DefReg = MI.getOperand(I).getReg();
402  UpdatedDefs.push_back(DefReg);
403  Builder.buildTrunc(DefReg, NewUnmerge.getReg(I));
404  }
405 
406  markInstAndDefDead(MI, CastMI, DeadInsts);
407  return true;
408  }
409 
410  if (CastSrcTy.isScalar() && SrcTy.isScalar() && !DestTy.isVector()) {
411  // %1:_(s16) = G_TRUNC %0(s32)
412  // %2:_(s8), %3:_(s8) = G_UNMERGE_VALUES %1
413  // =>
414  // %2:_(s8), %3:_(s8), %4:_(s8), %5:_(s8) = G_UNMERGE_VALUES %0
415 
416  // Unmerge(trunc) can be combined if the trunc source size is a multiple
417  // of the unmerge destination size
418  if (CastSrcSize % DestSize != 0)
419  return false;
420 
421  // Check if the new unmerge is supported
422  if (isInstUnsupported(
423  {TargetOpcode::G_UNMERGE_VALUES, {DestTy, CastSrcTy}}))
424  return false;
425 
426  // Gather the original destination registers and create new ones for the
427  // unused bits
428  const unsigned NewNumDefs = CastSrcSize / DestSize;
429  SmallVector<Register, 8> DstRegs(NewNumDefs);
430  for (unsigned Idx = 0; Idx < NewNumDefs; ++Idx) {
431  if (Idx < NumDefs)
432  DstRegs[Idx] = MI.getOperand(Idx).getReg();
433  else
434  DstRegs[Idx] = MRI.createGenericVirtualRegister(DestTy);
435  }
436 
437  // Build new unmerge
438  Builder.setInstr(MI);
439  Builder.buildUnmerge(DstRegs, CastSrcReg);
440  UpdatedDefs.append(DstRegs.begin(), DstRegs.begin() + NewNumDefs);
441  markInstAndDefDead(MI, CastMI, DeadInsts);
442  return true;
443  }
444  }
445 
446  // TODO: support combines with other casts as well
447  return false;
448  }
449 
450  static bool canFoldMergeOpcode(unsigned MergeOp, unsigned ConvertOp,
451  LLT OpTy, LLT DestTy) {
452  // Check if we found a definition that is like G_MERGE_VALUES.
453  switch (MergeOp) {
454  default:
455  return false;
456  case TargetOpcode::G_BUILD_VECTOR:
457  case TargetOpcode::G_MERGE_VALUES:
458  // The convert operation that we will need to insert is
459  // going to convert the input of that type of instruction (scalar)
460  // to the destination type (DestTy).
461  // The conversion needs to stay in the same domain (scalar to scalar
462  // and vector to vector), so if we were to allow to fold the merge
463  // we would need to insert some bitcasts.
464  // E.g.,
465  // <2 x s16> = build_vector s16, s16
466  // <2 x s32> = zext <2 x s16>
467  // <2 x s16>, <2 x s16> = unmerge <2 x s32>
468  //
469  // As is the folding would produce:
470  // <2 x s16> = zext s16 <-- scalar to vector
471  // <2 x s16> = zext s16 <-- scalar to vector
472  // Which is invalid.
473  // Instead we would want to generate:
474  // s32 = zext s16
475  // <2 x s16> = bitcast s32
476  // s32 = zext s16
477  // <2 x s16> = bitcast s32
478  //
479  // That is not done yet.
480  if (ConvertOp == 0)
481  return true;
482  return !DestTy.isVector() && OpTy.isVector();
483  case TargetOpcode::G_CONCAT_VECTORS: {
484  if (ConvertOp == 0)
485  return true;
486  if (!DestTy.isVector())
487  return false;
488 
489  const unsigned OpEltSize = OpTy.getElementType().getSizeInBits();
490 
491  // Don't handle scalarization with a cast that isn't in the same
492  // direction as the vector cast. This could be handled, but it would
493  // require more intermediate unmerges.
494  if (ConvertOp == TargetOpcode::G_TRUNC)
495  return DestTy.getSizeInBits() <= OpEltSize;
496  return DestTy.getSizeInBits() >= OpEltSize;
497  }
498  }
499  }
500 
501  /// Try to replace DstReg with SrcReg or build a COPY instruction
502  /// depending on the register constraints.
503  static void replaceRegOrBuildCopy(Register DstReg, Register SrcReg,
506  SmallVectorImpl<Register> &UpdatedDefs,
507  GISelChangeObserver &Observer) {
508  if (!llvm::canReplaceReg(DstReg, SrcReg, MRI)) {
509  Builder.buildCopy(DstReg, SrcReg);
510  UpdatedDefs.push_back(DstReg);
511  return;
512  }
514  // Get the users and notify the observer before replacing.
515  for (auto &UseMI : MRI.use_instructions(DstReg)) {
516  UseMIs.push_back(&UseMI);
517  Observer.changingInstr(UseMI);
518  }
519  // Replace the registers.
520  MRI.replaceRegWith(DstReg, SrcReg);
521  UpdatedDefs.push_back(SrcReg);
522  // Notify the observer that we changed the instructions.
523  for (auto *UseMI : UseMIs)
524  Observer.changedInstr(*UseMI);
525  }
526 
527  /// Return the operand index in \p MI that defines \p Def
528  static unsigned getDefIndex(const MachineInstr &MI, Register SearchDef) {
529  unsigned DefIdx = 0;
530  for (const MachineOperand &Def : MI.defs()) {
531  if (Def.getReg() == SearchDef)
532  break;
533  ++DefIdx;
534  }
535 
536  return DefIdx;
537  }
538 
539  /// This class provides utilities for finding source registers of specific
540  /// bit ranges in an artifact. The routines can look through the source
541  /// registers if they're other artifacts to try to find a non-artifact source
542  /// of a value.
545  MachineIRBuilder &MIB;
546  const LegalizerInfo &LI;
547 
548  private:
549  /// Given an concat_vector op \p Concat and a start bit and size, try to
550  /// find the origin of the value defined by that start position and size.
551  ///
552  /// \returns A register if a value can be found, otherwise an empty
553  /// Register.
554  Register findValueFromConcat(GConcatVectors &Concat, unsigned StartBit,
555  unsigned Size) {
556  assert(Size > 0);
557 
558  // Find the source operand that provides the bits requested.
559  Register Src1Reg = Concat.getSourceReg(0);
560  unsigned SrcSize = MRI.getType(Src1Reg).getSizeInBits();
561 
562  // Operand index of the source that provides the start of the bit range.
563  unsigned StartSrcIdx = (StartBit / SrcSize) + 1;
564  // Offset into the source at which the bit range starts.
565  unsigned InRegOffset = StartBit % SrcSize;
566  // Check that the bits don't span multiple sources.
567  // FIXME: we might be able return multiple sources? Or create an
568  // appropriate concat to make it fit.
569  if (InRegOffset + Size > SrcSize)
570  return Register();
571 
572  // If the bits exactly cover a single source, then return the operand as
573  // our value reg.
574  Register SrcReg = Concat.getReg(StartSrcIdx);
575  if (InRegOffset == 0 && Size == SrcSize)
576  return SrcReg; // A source operand matches exactly.
577 
578  return findValueFromDef(SrcReg, InRegOffset, Size);
579  }
580 
581  /// Given an build_vector op \p BV and a start bit and size, try to find
582  /// the origin of the value defined by that start position and size.
583  ///
584  /// \returns A register if a value can be found, otherwise an empty
585  /// Register.
586  Register findValueFromBuildVector(GBuildVector &BV, unsigned StartBit,
587  unsigned Size) {
588  assert(Size > 0);
589 
590  // Find the source operand that provides the bits requested.
591  Register Src1Reg = BV.getSourceReg(0);
592  unsigned SrcSize = MRI.getType(Src1Reg).getSizeInBits();
593 
594  // Operand index of the source that provides the start of the bit range.
595  unsigned StartSrcIdx = (StartBit / SrcSize) + 1;
596  // Offset into the source at which the bit range starts.
597  unsigned InRegOffset = StartBit % SrcSize;
598 
599  if (InRegOffset != 0)
600  return Register(); // Give up, bits don't start at a scalar source.
601  if (Size < SrcSize)
602  return Register(); // Scalar source is too large for requested bits.
603 
604  // If the bits cover multiple sources evenly, then create a new
605  // build_vector to synthesize the required size, if that's been requested.
606  if (Size > SrcSize) {
607  if (Size % SrcSize > 0)
608  return Register(); // Isn't covered exactly by sources.
609 
610  unsigned NumSrcsUsed = Size / SrcSize;
611  LLT SrcTy = MRI.getType(Src1Reg);
612  LLT NewBVTy = LLT::fixed_vector(NumSrcsUsed, SrcTy);
613 
614  // Check if the resulting build vector would be legal.
615  LegalizeActionStep ActionStep =
616  LI.getAction({TargetOpcode::G_BUILD_VECTOR, {NewBVTy, SrcTy}});
617  if (ActionStep.Action != LegalizeActions::Legal)
618  return Register();
619 
620  SmallVector<Register> NewSrcs;
621  for (unsigned SrcIdx = StartSrcIdx; SrcIdx < StartSrcIdx + NumSrcsUsed;
622  ++SrcIdx)
623  NewSrcs.push_back(BV.getReg(SrcIdx));
624  MIB.setInstrAndDebugLoc(BV);
625  return MIB.buildBuildVector(NewBVTy, NewSrcs).getReg(0);
626  }
627  // A single source is requested, just return it.
628  return BV.getReg(StartSrcIdx);
629  }
630 
631  /// Given an G_INSERT op \p MI and a start bit and size, try to find
632  /// the origin of the value defined by that start position and size.
633  ///
634  /// \returns A register if a value can be found, otherwise an empty
635  /// Register.
636  Register findValueFromInsert(MachineInstr &MI, unsigned StartBit,
637  unsigned Size) {
638  assert(MI.getOpcode() == TargetOpcode::G_INSERT);
639  assert(Size > 0);
640 
641  Register ContainerSrcReg = MI.getOperand(1).getReg();
642  Register InsertedReg = MI.getOperand(2).getReg();
643  LLT InsertedRegTy = MRI.getType(InsertedReg);
644  unsigned InsertOffset = MI.getOperand(3).getImm();
645 
646  // There are 4 possible container/insertreg + requested bit-range layouts
647  // that the instruction and query could be representing.
648  // For: %_ = G_INSERT %CONTAINER, %INS, InsOff (abbrev. to 'IO')
649  // and a start bit 'SB', with size S, giving an end bit 'EB', we could
650  // have...
651  // Scenario A:
652  // --------------------------
653  // | INS | CONTAINER |
654  // --------------------------
655  // | |
656  // SB EB
657  //
658  // Scenario B:
659  // --------------------------
660  // | INS | CONTAINER |
661  // --------------------------
662  // | |
663  // SB EB
664  //
665  // Scenario C:
666  // --------------------------
667  // | CONTAINER | INS |
668  // --------------------------
669  // | |
670  // SB EB
671  //
672  // Scenario D:
673  // --------------------------
674  // | CONTAINER | INS |
675  // --------------------------
676  // | |
677  // SB EB
678  //
679  // So therefore, A and D are requesting data from the INS operand, while
680  // B and C are requesting from the container operand.
681 
682  unsigned InsertedEndBit = InsertOffset + InsertedRegTy.getSizeInBits();
683  unsigned EndBit = StartBit + Size;
684  unsigned NewStartBit;
685  Register SrcRegToUse;
686  if (EndBit <= InsertOffset || InsertedEndBit <= StartBit) {
687  SrcRegToUse = ContainerSrcReg;
688  NewStartBit = StartBit;
689  return findValueFromDef(SrcRegToUse, NewStartBit, Size);
690  }
691  if (InsertOffset <= StartBit && EndBit <= InsertedEndBit) {
692  SrcRegToUse = InsertedReg;
693  NewStartBit = StartBit - InsertOffset;
694  return findValueFromDef(SrcRegToUse, NewStartBit, Size);
695  }
696  // The bit range spans both the inserted and container regions.
697  return Register();
698  }
699 
700  public:
702  const LegalizerInfo &Info)
703  : MRI(Mri), MIB(Builder), LI(Info) {}
704 
705  /// Try to find a source of the value defined in the def \p DefReg, starting
706  /// at position \p StartBit with size \p Size.
707  /// \returns an empty Register if no value could be found, or \p DefReg if
708  /// if that was the best we could do.
709  Register findValueFromDef(Register DefReg, unsigned StartBit,
710  unsigned Size) {
712  // If the instruction has a single def, then simply delegate the search.
713  // For unmerge however with multiple defs, we need to compute the offset
714  // into the source of the unmerge.
715  switch (Def->getOpcode()) {
716  case TargetOpcode::G_CONCAT_VECTORS:
717  return findValueFromConcat(cast<GConcatVectors>(*Def), StartBit, Size);
718  case TargetOpcode::G_UNMERGE_VALUES: {
719  unsigned DefStartBit = 0;
720  unsigned DefSize = MRI.getType(DefReg).getSizeInBits();
721  for (const auto &MO : Def->defs()) {
722  if (MO.getReg() == DefReg)
723  break;
724  DefStartBit += DefSize;
725  }
726  Register SrcReg = Def->getOperand(Def->getNumOperands() - 1).getReg();
727  Register SrcOriginReg =
728  findValueFromDef(SrcReg, StartBit + DefStartBit, Size);
729  if (SrcOriginReg)
730  return SrcOriginReg;
731  // Failed to find a further value. If the StartBit and Size perfectly
732  // covered the requested DefReg, return that since it's better than
733  // nothing.
734  if (StartBit == 0 && Size == DefSize)
735  return DefReg;
736  return Register();
737  }
738  case TargetOpcode::G_BUILD_VECTOR:
739  return findValueFromBuildVector(cast<GBuildVector>(*Def), StartBit,
740  Size);
741  case TargetOpcode::G_INSERT:
742  return findValueFromInsert(*Def, StartBit, Size);
743  default:
744  return Register();
745  }
746  }
747 
748  /// Try to combine the defs of an unmerge \p MI by attempting to find
749  /// values that provides the bits for each def reg.
750  /// \returns true if all the defs of the unmerge have been made dead.
752  SmallVectorImpl<Register> &UpdatedDefs) {
753  unsigned NumDefs = MI.getNumDefs();
754  LLT DestTy = MRI.getType(MI.getReg(0));
755 
756  SmallBitVector DeadDefs(NumDefs);
757  for (unsigned DefIdx = 0; DefIdx < NumDefs; ++DefIdx) {
758  Register DefReg = MI.getReg(DefIdx);
759  if (MRI.use_nodbg_empty(DefReg)) {
760  DeadDefs[DefIdx] = true;
761  continue;
762  }
763  Register FoundVal =
764  findValueFromDef(DefReg, 0, DestTy.getSizeInBits());
765  if (!FoundVal || FoundVal == DefReg)
766  continue;
767  if (MRI.getType(FoundVal) != DestTy)
768  continue;
769 
770  replaceRegOrBuildCopy(DefReg, FoundVal, MRI, MIB, UpdatedDefs,
771  Observer);
772  // We only want to replace the uses, not the def of the old reg.
773  Observer.changingInstr(MI);
774  MI.getOperand(DefIdx).setReg(DefReg);
775  Observer.changedInstr(MI);
776  DeadDefs[DefIdx] = true;
777  }
778  return DeadDefs.all();
779  }
780  };
781 
784  SmallVectorImpl<Register> &UpdatedDefs,
785  GISelChangeObserver &Observer) {
786  unsigned NumDefs = MI.getNumDefs();
787  Register SrcReg = MI.getSourceReg();
788  MachineInstr *SrcDef = getDefIgnoringCopies(SrcReg, MRI);
789  if (!SrcDef)
790  return false;
791 
792  LLT OpTy = MRI.getType(SrcReg);
793  LLT DestTy = MRI.getType(MI.getReg(0));
794  unsigned SrcDefIdx = getDefIndex(*SrcDef, SrcReg);
795 
796  Builder.setInstrAndDebugLoc(MI);
797 
798  if (auto *SrcUnmerge = dyn_cast<GUnmerge>(SrcDef)) {
799  // %0:_(<4 x s16>) = G_FOO
800  // %1:_(<2 x s16>), %2:_(<2 x s16>) = G_UNMERGE_VALUES %0
801  // %3:_(s16), %4:_(s16) = G_UNMERGE_VALUES %1
802  //
803  // %3:_(s16), %4:_(s16), %5:_(s16), %6:_(s16) = G_UNMERGE_VALUES %0
804  Register SrcUnmergeSrc = SrcUnmerge->getSourceReg();
805  LLT SrcUnmergeSrcTy = MRI.getType(SrcUnmergeSrc);
806 
807  // If we need to decrease the number of vector elements in the result type
808  // of an unmerge, this would involve the creation of an equivalent unmerge
809  // to copy back to the original result registers.
810  LegalizeActionStep ActionStep = LI.getAction(
811  {TargetOpcode::G_UNMERGE_VALUES, {OpTy, SrcUnmergeSrcTy}});
812  switch (ActionStep.Action) {
815  break;
818  if (ActionStep.TypeIdx == 1)
819  return false;
820  break;
821  default: {
822  ArtifactValueFinder Finder(MRI, Builder, LI);
823  if (Finder.tryCombineUnmergeDefs(MI, Observer, UpdatedDefs)) {
824  markInstAndDefDead(MI, *SrcDef, DeadInsts, SrcDefIdx);
825  return true;
826  }
827  return false;
828  }
829  }
830 
831  auto NewUnmerge = Builder.buildUnmerge(DestTy, SrcUnmergeSrc);
832 
833  // TODO: Should we try to process out the other defs now? If the other
834  // defs of the source unmerge are also unmerged, we end up with a separate
835  // unmerge for each one.
836  for (unsigned I = 0; I != NumDefs; ++I) {
837  Register Def = MI.getReg(I);
838  replaceRegOrBuildCopy(Def, NewUnmerge.getReg(SrcDefIdx * NumDefs + I),
839  MRI, Builder, UpdatedDefs, Observer);
840  }
841 
842  markInstAndDefDead(MI, *SrcUnmerge, DeadInsts, SrcDefIdx);
843  return true;
844  }
845 
846  MachineInstr *MergeI = SrcDef;
847  unsigned ConvertOp = 0;
848 
849  // Handle intermediate conversions
850  unsigned SrcOp = SrcDef->getOpcode();
851  if (isArtifactCast(SrcOp)) {
852  ConvertOp = SrcOp;
853  MergeI = getDefIgnoringCopies(SrcDef->getOperand(1).getReg(), MRI);
854  }
855 
856  if (!MergeI || !canFoldMergeOpcode(MergeI->getOpcode(),
857  ConvertOp, OpTy, DestTy)) {
858  // We might have a chance to combine later by trying to combine
859  // unmerge(cast) first
860  if (tryFoldUnmergeCast(MI, *SrcDef, DeadInsts, UpdatedDefs))
861  return true;
862 
863  // Try using the value finder.
864  ArtifactValueFinder Finder(MRI, Builder, LI);
865  if (Finder.tryCombineUnmergeDefs(MI, Observer, UpdatedDefs)) {
866  markInstAndDefDead(MI, *SrcDef, DeadInsts, SrcDefIdx);
867  return true;
868  }
869  return false;
870  }
871 
872  const unsigned NumMergeRegs = MergeI->getNumOperands() - 1;
873 
874  if (NumMergeRegs < NumDefs) {
875  if (NumDefs % NumMergeRegs != 0)
876  return false;
877 
878  Builder.setInstr(MI);
879  // Transform to UNMERGEs, for example
880  // %1 = G_MERGE_VALUES %4, %5
881  // %9, %10, %11, %12 = G_UNMERGE_VALUES %1
882  // to
883  // %9, %10 = G_UNMERGE_VALUES %4
884  // %11, %12 = G_UNMERGE_VALUES %5
885 
886  const unsigned NewNumDefs = NumDefs / NumMergeRegs;
887  for (unsigned Idx = 0; Idx < NumMergeRegs; ++Idx) {
888  SmallVector<Register, 8> DstRegs;
889  for (unsigned j = 0, DefIdx = Idx * NewNumDefs; j < NewNumDefs;
890  ++j, ++DefIdx)
891  DstRegs.push_back(MI.getReg(DefIdx));
892 
893  if (ConvertOp) {
894  LLT MergeSrcTy = MRI.getType(MergeI->getOperand(1).getReg());
895 
896  // This is a vector that is being split and casted. Extract to the
897  // element type, and do the conversion on the scalars (or smaller
898  // vectors).
899  LLT MergeEltTy = MergeSrcTy.divide(NewNumDefs);
900 
901  // Handle split to smaller vectors, with conversions.
902  // %2(<8 x s8>) = G_CONCAT_VECTORS %0(<4 x s8>), %1(<4 x s8>)
903  // %3(<8 x s16>) = G_SEXT %2
904  // %4(<2 x s16>), %5(<2 x s16>), %6(<2 x s16>), %7(<2 x s16>) = G_UNMERGE_VALUES %3
905  //
906  // =>
907  //
908  // %8(<2 x s8>), %9(<2 x s8>) = G_UNMERGE_VALUES %0
909  // %10(<2 x s8>), %11(<2 x s8>) = G_UNMERGE_VALUES %1
910  // %4(<2 x s16>) = G_SEXT %8
911  // %5(<2 x s16>) = G_SEXT %9
912  // %6(<2 x s16>) = G_SEXT %10
913  // %7(<2 x s16>)= G_SEXT %11
914 
915  SmallVector<Register, 4> TmpRegs(NewNumDefs);
916  for (unsigned k = 0; k < NewNumDefs; ++k)
917  TmpRegs[k] = MRI.createGenericVirtualRegister(MergeEltTy);
918 
919  Builder.buildUnmerge(TmpRegs, MergeI->getOperand(Idx + 1).getReg());
920 
921  for (unsigned k = 0; k < NewNumDefs; ++k)
922  Builder.buildInstr(ConvertOp, {DstRegs[k]}, {TmpRegs[k]});
923  } else {
924  Builder.buildUnmerge(DstRegs, MergeI->getOperand(Idx + 1).getReg());
925  }
926  UpdatedDefs.append(DstRegs.begin(), DstRegs.end());
927  }
928 
929  } else if (NumMergeRegs > NumDefs) {
930  if (ConvertOp != 0 || NumMergeRegs % NumDefs != 0)
931  return false;
932 
933  Builder.setInstr(MI);
934  // Transform to MERGEs
935  // %6 = G_MERGE_VALUES %17, %18, %19, %20
936  // %7, %8 = G_UNMERGE_VALUES %6
937  // to
938  // %7 = G_MERGE_VALUES %17, %18
939  // %8 = G_MERGE_VALUES %19, %20
940 
941  const unsigned NumRegs = NumMergeRegs / NumDefs;
942  for (unsigned DefIdx = 0; DefIdx < NumDefs; ++DefIdx) {
944  for (unsigned j = 0, Idx = NumRegs * DefIdx + 1; j < NumRegs;
945  ++j, ++Idx)
946  Regs.push_back(MergeI->getOperand(Idx).getReg());
947 
948  Register DefReg = MI.getReg(DefIdx);
949  Builder.buildMerge(DefReg, Regs);
950  UpdatedDefs.push_back(DefReg);
951  }
952 
953  } else {
954  LLT MergeSrcTy = MRI.getType(MergeI->getOperand(1).getReg());
955 
956  if (!ConvertOp && DestTy != MergeSrcTy)
957  ConvertOp = TargetOpcode::G_BITCAST;
958 
959  if (ConvertOp) {
960  Builder.setInstr(MI);
961 
962  for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
963  Register MergeSrc = MergeI->getOperand(Idx + 1).getReg();
964  Register DefReg = MI.getOperand(Idx).getReg();
965  Builder.buildInstr(ConvertOp, {DefReg}, {MergeSrc});
966  UpdatedDefs.push_back(DefReg);
967  }
968 
969  markInstAndDefDead(MI, *MergeI, DeadInsts);
970  return true;
971  }
972 
973  assert(DestTy == MergeSrcTy &&
974  "Bitcast and the other kinds of conversions should "
975  "have happened earlier");
976 
977  Builder.setInstr(MI);
978  for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
979  Register DstReg = MI.getOperand(Idx).getReg();
980  Register SrcReg = MergeI->getOperand(Idx + 1).getReg();
981  replaceRegOrBuildCopy(DstReg, SrcReg, MRI, Builder, UpdatedDefs,
982  Observer);
983  }
984  }
985 
986  markInstAndDefDead(MI, *MergeI, DeadInsts);
987  return true;
988  }
989 
992  SmallVectorImpl<Register> &UpdatedDefs) {
993  assert(MI.getOpcode() == TargetOpcode::G_EXTRACT);
994 
995  // Try to use the source registers from a G_MERGE_VALUES
996  //
997  // %2 = G_MERGE_VALUES %0, %1
998  // %3 = G_EXTRACT %2, N
999  // =>
1000  //
1001  // for N < %2.getSizeInBits() / 2
1002  // %3 = G_EXTRACT %0, N
1003  //
1004  // for N >= %2.getSizeInBits() / 2
1005  // %3 = G_EXTRACT %1, (N - %0.getSizeInBits()
1006 
1007  Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
1008  MachineInstr *MergeI = MRI.getVRegDef(SrcReg);
1009  if (!MergeI || !isa<GMergeLikeOp>(MergeI))
1010  return false;
1011 
1012  Register DstReg = MI.getOperand(0).getReg();
1013  LLT DstTy = MRI.getType(DstReg);
1014  LLT SrcTy = MRI.getType(SrcReg);
1015 
1016  // TODO: Do we need to check if the resulting extract is supported?
1017  unsigned ExtractDstSize = DstTy.getSizeInBits();
1018  unsigned Offset = MI.getOperand(2).getImm();
1019  unsigned NumMergeSrcs = MergeI->getNumOperands() - 1;
1020  unsigned MergeSrcSize = SrcTy.getSizeInBits() / NumMergeSrcs;
1021  unsigned MergeSrcIdx = Offset / MergeSrcSize;
1022 
1023  // Compute the offset of the last bit the extract needs.
1024  unsigned EndMergeSrcIdx = (Offset + ExtractDstSize - 1) / MergeSrcSize;
1025 
1026  // Can't handle the case where the extract spans multiple inputs.
1027  if (MergeSrcIdx != EndMergeSrcIdx)
1028  return false;
1029 
1030  // TODO: We could modify MI in place in most cases.
1031  Builder.setInstr(MI);
1032  Builder.buildExtract(DstReg, MergeI->getOperand(MergeSrcIdx + 1).getReg(),
1033  Offset - MergeSrcIdx * MergeSrcSize);
1034  UpdatedDefs.push_back(DstReg);
1035  markInstAndDefDead(MI, *MergeI, DeadInsts);
1036  return true;
1037  }
1038 
1039  /// Try to combine away MI.
1040  /// Returns true if it combined away the MI.
1041  /// Adds instructions that are dead as a result of the combine
1042  /// into DeadInsts, which can include MI.
1045  GISelObserverWrapper &WrapperObserver) {
1046  // This might be a recursive call, and we might have DeadInsts already
1047  // populated. To avoid bad things happening later with multiple vreg defs
1048  // etc, process the dead instructions now if any.
1049  if (!DeadInsts.empty())
1050  deleteMarkedDeadInsts(DeadInsts, WrapperObserver);
1051 
1052  // Put here every vreg that was redefined in such a way that it's at least
1053  // possible that one (or more) of its users (immediate or COPY-separated)
1054  // could become artifact combinable with the new definition (or the
1055  // instruction reachable from it through a chain of copies if any).
1056  SmallVector<Register, 4> UpdatedDefs;
1057  bool Changed = false;
1058  switch (MI.getOpcode()) {
1059  default:
1060  return false;
1061  case TargetOpcode::G_ANYEXT:
1062  Changed = tryCombineAnyExt(MI, DeadInsts, UpdatedDefs);
1063  break;
1064  case TargetOpcode::G_ZEXT:
1065  Changed = tryCombineZExt(MI, DeadInsts, UpdatedDefs, WrapperObserver);
1066  break;
1067  case TargetOpcode::G_SEXT:
1068  Changed = tryCombineSExt(MI, DeadInsts, UpdatedDefs);
1069  break;
1070  case TargetOpcode::G_UNMERGE_VALUES:
1071  Changed = tryCombineUnmergeValues(cast<GUnmerge>(MI), DeadInsts,
1072  UpdatedDefs, WrapperObserver);
1073  break;
1074  case TargetOpcode::G_MERGE_VALUES:
1075  case TargetOpcode::G_BUILD_VECTOR:
1076  case TargetOpcode::G_CONCAT_VECTORS:
1077  // If any of the users of this merge are an unmerge, then add them to the
1078  // artifact worklist in case there's folding that can be done looking up.
1079  for (MachineInstr &U : MRI.use_instructions(MI.getOperand(0).getReg())) {
1080  if (U.getOpcode() == TargetOpcode::G_UNMERGE_VALUES ||
1081  U.getOpcode() == TargetOpcode::G_TRUNC) {
1082  UpdatedDefs.push_back(MI.getOperand(0).getReg());
1083  break;
1084  }
1085  }
1086  break;
1087  case TargetOpcode::G_EXTRACT:
1088  Changed = tryCombineExtract(MI, DeadInsts, UpdatedDefs);
1089  break;
1090  case TargetOpcode::G_TRUNC:
1091  Changed = tryCombineTrunc(MI, DeadInsts, UpdatedDefs, WrapperObserver);
1092  if (!Changed) {
1093  // Try to combine truncates away even if they are legal. As all artifact
1094  // combines at the moment look only "up" the def-use chains, we achieve
1095  // that by throwing truncates' users (with look through copies) into the
1096  // ArtifactList again.
1097  UpdatedDefs.push_back(MI.getOperand(0).getReg());
1098  }
1099  break;
1100  }
1101  // If the main loop through the ArtifactList found at least one combinable
1102  // pair of artifacts, not only combine it away (as done above), but also
1103  // follow the def-use chain from there to combine everything that can be
1104  // combined within this def-use chain of artifacts.
1105  while (!UpdatedDefs.empty()) {
1106  Register NewDef = UpdatedDefs.pop_back_val();
1107  assert(NewDef.isVirtual() && "Unexpected redefinition of a physreg");
1108  for (MachineInstr &Use : MRI.use_instructions(NewDef)) {
1109  switch (Use.getOpcode()) {
1110  // Keep this list in sync with the list of all artifact combines.
1111  case TargetOpcode::G_ANYEXT:
1112  case TargetOpcode::G_ZEXT:
1113  case TargetOpcode::G_SEXT:
1114  case TargetOpcode::G_UNMERGE_VALUES:
1115  case TargetOpcode::G_EXTRACT:
1116  case TargetOpcode::G_TRUNC:
1117  // Adding Use to ArtifactList.
1118  WrapperObserver.changedInstr(Use);
1119  break;
1120  case TargetOpcode::COPY: {
1121  Register Copy = Use.getOperand(0).getReg();
1122  if (Copy.isVirtual())
1123  UpdatedDefs.push_back(Copy);
1124  break;
1125  }
1126  default:
1127  // If we do not have an artifact combine for the opcode, there is no
1128  // point in adding it to the ArtifactList as nothing interesting will
1129  // be done to it anyway.
1130  break;
1131  }
1132  }
1133  }
1134  return Changed;
1135  }
1136 
1137 private:
1138  static Register getArtifactSrcReg(const MachineInstr &MI) {
1139  switch (MI.getOpcode()) {
1140  case TargetOpcode::COPY:
1141  case TargetOpcode::G_TRUNC:
1142  case TargetOpcode::G_ZEXT:
1143  case TargetOpcode::G_ANYEXT:
1144  case TargetOpcode::G_SEXT:
1145  case TargetOpcode::G_EXTRACT:
1146  return MI.getOperand(1).getReg();
1147  case TargetOpcode::G_UNMERGE_VALUES:
1148  return MI.getOperand(MI.getNumOperands() - 1).getReg();
1149  default:
1150  llvm_unreachable("Not a legalization artifact happen");
1151  }
1152  }
1153 
1154  /// Mark a def of one of MI's original operands, DefMI, as dead if changing MI
1155  /// (either by killing it or changing operands) results in DefMI being dead
1156  /// too. In-between COPYs or artifact-casts are also collected if they are
1157  /// dead.
1158  /// MI is not marked dead.
1159  void markDefDead(MachineInstr &MI, MachineInstr &DefMI,
1160  SmallVectorImpl<MachineInstr *> &DeadInsts,
1161  unsigned DefIdx = 0) {
1162  // Collect all the copy instructions that are made dead, due to deleting
1163  // this instruction. Collect all of them until the Trunc(DefMI).
1164  // Eg,
1165  // %1(s1) = G_TRUNC %0(s32)
1166  // %2(s1) = COPY %1(s1)
1167  // %3(s1) = COPY %2(s1)
1168  // %4(s32) = G_ANYEXT %3(s1)
1169  // In this case, we would have replaced %4 with a copy of %0,
1170  // and as a result, %3, %2, %1 are dead.
1171  MachineInstr *PrevMI = &MI;
1172  while (PrevMI != &DefMI) {
1173  Register PrevRegSrc = getArtifactSrcReg(*PrevMI);
1174 
1175  MachineInstr *TmpDef = MRI.getVRegDef(PrevRegSrc);
1176  if (MRI.hasOneUse(PrevRegSrc)) {
1177  if (TmpDef != &DefMI) {
1178  assert((TmpDef->getOpcode() == TargetOpcode::COPY ||
1179  isArtifactCast(TmpDef->getOpcode())) &&
1180  "Expecting copy or artifact cast here");
1181 
1182  DeadInsts.push_back(TmpDef);
1183  }
1184  } else
1185  break;
1186  PrevMI = TmpDef;
1187  }
1188 
1189  if (PrevMI == &DefMI) {
1190  unsigned I = 0;
1191  bool IsDead = true;
1192  for (MachineOperand &Def : DefMI.defs()) {
1193  if (I != DefIdx) {
1194  if (!MRI.use_empty(Def.getReg())) {
1195  IsDead = false;
1196  break;
1197  }
1198  } else {
1199  if (!MRI.hasOneUse(DefMI.getOperand(DefIdx).getReg()))
1200  break;
1201  }
1202 
1203  ++I;
1204  }
1205 
1206  if (IsDead)
1207  DeadInsts.push_back(&DefMI);
1208  }
1209  }
1210 
1211  /// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be
1212  /// dead due to MI being killed, then mark DefMI as dead too.
1213  /// Some of the combines (extends(trunc)), try to walk through redundant
1214  /// copies in between the extends and the truncs, and this attempts to collect
1215  /// the in between copies if they're dead.
1216  void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI,
1217  SmallVectorImpl<MachineInstr *> &DeadInsts,
1218  unsigned DefIdx = 0) {
1219  DeadInsts.push_back(&MI);
1220  markDefDead(MI, DefMI, DeadInsts, DefIdx);
1221  }
1222 
1223  /// Erase the dead instructions in the list and call the observer hooks.
1224  /// Normally the Legalizer will deal with erasing instructions that have been
1225  /// marked dead. However, for the trunc(ext(x)) cases we can end up trying to
1226  /// process instructions which have been marked dead, but otherwise break the
1227  /// MIR by introducing multiple vreg defs. For those cases, allow the combines
1228  /// to explicitly delete the instructions before we run into trouble.
1229  void deleteMarkedDeadInsts(SmallVectorImpl<MachineInstr *> &DeadInsts,
1230  GISelObserverWrapper &WrapperObserver) {
1231  for (auto *DeadMI : DeadInsts) {
1232  LLVM_DEBUG(dbgs() << *DeadMI << "Is dead, eagerly deleting\n");
1233  WrapperObserver.erasingInstr(*DeadMI);
1234  DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
1235  }
1236  DeadInsts.clear();
1237  }
1238 
1239  /// Checks if the target legalizer info has specified anything about the
1240  /// instruction, or if unsupported.
1241  bool isInstUnsupported(const LegalityQuery &Query) const {
1242  using namespace LegalizeActions;
1243  auto Step = LI.getAction(Query);
1244  return Step.Action == Unsupported || Step.Action == NotFound;
1245  }
1246 
1247  bool isInstLegal(const LegalityQuery &Query) const {
1248  return LI.getAction(Query).Action == LegalizeActions::Legal;
1249  }
1250 
1251  bool isConstantUnsupported(LLT Ty) const {
1252  if (!Ty.isVector())
1253  return isInstUnsupported({TargetOpcode::G_CONSTANT, {Ty}});
1254 
1255  LLT EltTy = Ty.getElementType();
1256  return isInstUnsupported({TargetOpcode::G_CONSTANT, {EltTy}}) ||
1257  isInstUnsupported({TargetOpcode::G_BUILD_VECTOR, {Ty, EltTy}});
1258  }
1259 
1260  /// Looks through copy instructions and returns the actual
1261  /// source register.
1262  Register lookThroughCopyInstrs(Register Reg) {
1263  Register TmpReg;
1264  while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg)))) {
1265  if (MRI.getType(TmpReg).isValid())
1266  Reg = TmpReg;
1267  else
1268  break;
1269  }
1270  return Reg;
1271  }
1272 };
1273 
1274 } // namespace llvm
1275 
1276 #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZATIONARTIFACTCOMBINER_H
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
i
i
Definition: README.txt:29
MIPatternMatch.h
IsDead
bool IsDead
Definition: SILowerControlFlow.cpp:158
llvm::getDefIgnoringCopies
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
Definition: Utils.cpp:404
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
llvm::GBuildVector
Represents a G_BUILD_VECTOR.
Definition: GenericMachineInstrs.h:191
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:102
llvm::LLT::getScalarSizeInBits
unsigned getScalarSizeInBits() const
Definition: LowLevelTypeImpl.h:213
llvm::LegalizationArtifactCombiner::tryCombineAnyExt
bool tryCombineAnyExt(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs)
Definition: LegalizationArtifactCombiner.h:54
llvm::LegalizationArtifactCombiner::tryCombineExtract
bool tryCombineExtract(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs)
Definition: LegalizationArtifactCombiner.h:990
llvm::MIPatternMatch::m_Reg
operand_type_match m_Reg()
Definition: MIPatternMatch.h:127
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::LegalizeActionStep::Action
LegalizeAction Action
The action to take or the final answer.
Definition: LegalizerInfo.h:136
llvm::LegalizationArtifactCombiner::ArtifactValueFinder::ArtifactValueFinder
ArtifactValueFinder(MachineRegisterInfo &Mri, MachineIRBuilder &Builder, const LegalizerInfo &Info)
Definition: LegalizationArtifactCombiner.h:701
llvm::getOpcodeDef
MachineInstr * getOpcodeDef(unsigned Opcode, Register Reg, const MachineRegisterInfo &MRI)
See if Reg is defined by an single def instruction that is Opcode.
Definition: Utils.cpp:418
llvm::LegalizeActionStep
The result of a query.
Definition: LegalizerInfo.h:134
llvm::LegalizationArtifactCombiner::ArtifactValueFinder
This class provides utilities for finding source registers of specific bit ranges in an artifact.
Definition: LegalizationArtifactCombiner.h:543
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::LegalizeActions::NarrowScalar
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
Definition: LegalizerInfo.h:54
llvm::MIPatternMatch::m_GTrunc
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
Definition: MIPatternMatch.h:424
llvm::LegalizationArtifactCombiner::ArtifactValueFinder::findValueFromDef
Register findValueFromDef(Register DefReg, unsigned StartBit, unsigned Size)
Try to find a source of the value defined in the def DefReg, starting at position StartBit with size ...
Definition: LegalizationArtifactCombiner.h:709
llvm::LegalizationArtifactCombiner::tryCombineZExt
bool tryCombineZExt(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs, GISelObserverWrapper &Observer)
Definition: LegalizationArtifactCombiner.h:102
llvm::LLT::getScalarType
LLT getScalarType() const
Definition: LowLevelTypeImpl.h:168
llvm::LegalizationArtifactCombiner::tryFoldUnmergeCast
bool tryFoldUnmergeCast(MachineInstr &MI, MachineInstr &CastMI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs)
Definition: LegalizationArtifactCombiner.h:356
llvm::LegalizationArtifactCombiner::canFoldMergeOpcode
static bool canFoldMergeOpcode(unsigned MergeOp, unsigned ConvertOp, LLT OpTy, LLT DestTy)
Definition: LegalizationArtifactCombiner.h:450
GenericMachineInstrs.h
llvm::LLT::changeElementCount
LLT changeElementCount(ElementCount EC) const
Return a vector or scalar with the same element type and the new element count.
Definition: LowLevelTypeImpl.h:190
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MachineIRBuilder::buildBuildVector
MachineInstrBuilder buildBuildVector(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
Definition: MachineIRBuilder.cpp:632
MachineIRBuilder.h
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
LegalizerInfo.h
llvm::BitmaskEnumDetail::Mask
std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
MachineRegisterInfo.h
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::SmallBitVector
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
Definition: SmallBitVector.h:34
llvm::LLT::fixed_vector
static LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelTypeImpl.h:75
llvm::MIPatternMatch::m_GSExt
UnaryOp_match< SrcTy, TargetOpcode::G_SEXT > m_GSExt(const SrcTy &Src)
Definition: MIPatternMatch.h:409
llvm::LegalizationArtifactCombiner::tryCombineSExt
bool tryCombineSExt(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs)
Definition: LegalizationArtifactCombiner.h:162
llvm::MIPatternMatch::m_GZExt
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
Definition: MIPatternMatch.h:414
llvm::SmallVectorImpl::append
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:648
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:499
llvm::LLT::getSizeInBits
TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:153
llvm::GISelObserverWrapper::changingInstr
void changingInstr(MachineInstr &MI) override
This instruction is about to be mutated in some way.
Definition: GISelChangeObserver.h:92
Utils.h
llvm::LegalizationArtifactCombiner::getDefIndex
static unsigned getDefIndex(const MachineInstr &MI, Register SearchDef)
Return the operand index in MI that defines Def.
Definition: LegalizationArtifactCombiner.h:528
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::SmallBitVector::all
bool all() const
Returns true if all bits are set.
Definition: SmallBitVector.h:213
Concat
static constexpr int Concat[]
Definition: X86InterleavedAccess.cpp:239
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::GISelChangeObserver::changingInstr
virtual void changingInstr(MachineInstr &MI)=0
This instruction is about to be mutated in some way.
llvm::MIPatternMatch::m_MInstr
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
Definition: MIPatternMatch.h:227
llvm::LegalizationArtifactCombiner::tryCombineUnmergeValues
bool tryCombineUnmergeValues(GUnmerge &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs, GISelChangeObserver &Observer)
Definition: LegalizationArtifactCombiner.h:782
llvm::LegalizeActions::Legal
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:49
llvm::LinearPolySize< ElementCount >::getFixed
static ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:284
llvm::MachineInstrBuilder::getReg
Register getReg(unsigned Idx) const
Get the register for the operand index.
Definition: MachineInstrBuilder.h:94
llvm::GISelObserverWrapper::changedInstr
void changedInstr(MachineInstr &MI) override
This instruction was mutated in some way.
Definition: GISelChangeObserver.h:96
llvm::MIPatternMatch::m_GAnyExt
UnaryOp_match< SrcTy, TargetOpcode::G_ANYEXT > m_GAnyExt(const SrcTy &Src)
Definition: MIPatternMatch.h:404
llvm::LegalizationArtifactCombiner::replaceRegOrBuildCopy
static void replaceRegOrBuildCopy(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI, MachineIRBuilder &Builder, SmallVectorImpl< Register > &UpdatedDefs, GISelChangeObserver &Observer)
Try to replace DstReg with SrcReg or build a COPY instruction depending on the register constraints.
Definition: LegalizationArtifactCombiner.h:503
llvm::GISelChangeObserver::changedInstr
virtual void changedInstr(MachineInstr &MI)=0
This instruction was mutated in some way.
llvm::Register::isVirtual
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
llvm::ISD::Register
@ Register
Definition: ISDOpcodes.h:74
llvm::LLT::divide
LLT divide(int Factor) const
Return a type that is Factor times smaller.
Definition: LowLevelTypeImpl.h:197
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:212
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::GMergeLikeOp::getSourceReg
Register getSourceReg(unsigned I) const
Returns the I'th source register.
Definition: GenericMachineInstrs.h:160
llvm::MachineIRBuilder::setInstrAndDebugLoc
void setInstrAndDebugLoc(MachineInstr &MI)
Set the insertion point to before MI, and set the debug loc to MI's loc.
Definition: MachineIRBuilder.h:342
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::LLT::isVector
bool isVector() const
Definition: LowLevelTypeImpl.h:123
llvm::LLT::getNumElements
uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelTypeImpl.h:127
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::LegalizerInfo::getAction
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
Definition: LegalizerInfo.cpp:321
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::LLT::isScalar
bool isScalar() const
Definition: LowLevelTypeImpl.h:119
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:70
llvm::GConcatVectors
Represents a G_CONCAT_VECTORS.
Definition: GenericMachineInstrs.h:183
llvm::APInt::getAllOnesValue
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
Definition: APInt.h:567
llvm::LegalizationArtifactCombiner::tryFoldImplicitDef
bool tryFoldImplicitDef(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs)
Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF).
Definition: LegalizationArtifactCombiner.h:320
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:489
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::LegalizationArtifactCombiner::tryCombineTrunc
bool tryCombineTrunc(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, SmallVectorImpl< Register > &UpdatedDefs, GISelObserverWrapper &Observer)
Definition: LegalizationArtifactCombiner.h:218
llvm::MIPatternMatch::m_any_of
Or< Preds... > m_any_of(Preds &&... preds)
Definition: MIPatternMatch.h:171
llvm::GenericMachineInstr::getReg
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
Definition: GenericMachineInstrs.h:31
llvm::GISelChangeObserver
Abstract class that contains various methods for clients to notify about changes.
Definition: GISelChangeObserver.h:29
llvm::MIPatternMatch::m_Copy
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
Definition: MIPatternMatch.h:463
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::GUnmerge
Represents a G_UNMERGE_VALUES.
Definition: GenericMachineInstrs.h:140
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::APInt::zext
APInt zext(unsigned width) const
Zero extend to a new width.
Definition: APInt.cpp:934
j
return j(j<< 16)
llvm::canReplaceReg
bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)
Check if DstReg can be replaced with SrcReg depending on the register constraints.
Definition: Utils.cpp:180
llvm::LegalizeActions::FewerElements
@ FewerElements
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Definition: LegalizerInfo.h:64
llvm::LegacyLegalizeActions::Unsupported
@ Unsupported
This operation is completely unsupported on the target.
Definition: LegacyLegalizerInfo.h:71
Legalizer.h
llvm::LegalizationArtifactCombiner::ArtifactValueFinder::tryCombineUnmergeDefs
bool tryCombineUnmergeDefs(GUnmerge &MI, GISelChangeObserver &Observer, SmallVectorImpl< Register > &UpdatedDefs)
Try to combine the defs of an unmerge MI by attempting to find values that provides the bits for each...
Definition: LegalizationArtifactCombiner.h:751
llvm::LegalizationArtifactCombiner
Definition: LegalizationArtifactCombiner.h:32
llvm::LegalizeActionStep::TypeIdx
unsigned TypeIdx
If describing an action, the type index to change. Otherwise zero.
Definition: LegalizerInfo.h:138
SmallBitVector.h
llvm::MIPatternMatch
Definition: MIPatternMatch.h:21
DefMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Definition: AArch64ExpandPseudoInsts.cpp:103
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:492
llvm::LegalizationArtifactCombiner::tryCombineInstruction
bool tryCombineInstruction(MachineInstr &MI, SmallVectorImpl< MachineInstr * > &DeadInsts, GISelObserverWrapper &WrapperObserver)
Try to combine away MI.
Definition: LegalizationArtifactCombiner.h:1043
llvm::LegalizeActions::Unsupported
@ Unsupported
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:90
llvm::SmallVectorImpl< MachineInstr * >
llvm::GISelObserverWrapper
Simple wrapper observer that takes several observers, and calls each one for each event.
Definition: GISelChangeObserver.h:66
llvm::LegalizerInfo
Definition: LegalizerInfo.h:1083
llvm::MIPatternMatch::m_all_of
And< Preds... > m_all_of(Preds &&... preds)
Definition: MIPatternMatch.h:167
llvm::MIPatternMatch::mi_match
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
Definition: MIPatternMatch.h:24
GISelChangeObserver.h
llvm::LLT::getElementType
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
Definition: LowLevelTypeImpl.h:237
llvm::LegalizeActions::Lower
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
Definition: LegalizerInfo.h:77
llvm::LegacyLegalizeActions::NotFound
@ NotFound
Sentinel value for when no action was found in the specified table.
Definition: LegacyLegalizerInfo.h:74
Debug.h
llvm::SrcOp
Definition: MachineIRBuilder.h:119
llvm::LegalizationArtifactCombiner::LegalizationArtifactCombiner
LegalizationArtifactCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI, const LegalizerInfo &LI)
Definition: LegalizationArtifactCombiner.h:50
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::LLT
Definition: LowLevelTypeImpl.h:40