LLVM  9.0.0svn
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 
20 #include "llvm/Support/Debug.h"
21 
22 #define DEBUG_TYPE "legalizer"
23 using namespace llvm::MIPatternMatch;
24 
25 namespace llvm {
27  MachineIRBuilder &Builder;
29  const LegalizerInfo &LI;
30 
31 public:
33  const LegalizerInfo &LI)
34  : Builder(B), MRI(MRI), LI(LI) {}
35 
38  if (MI.getOpcode() != TargetOpcode::G_ANYEXT)
39  return false;
40 
41  Builder.setInstr(MI);
42  Register DstReg = MI.getOperand(0).getReg();
43  Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
44 
45  // aext(trunc x) - > aext/copy/trunc x
46  Register TruncSrc;
47  if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
48  LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
49  Builder.buildAnyExtOrTrunc(DstReg, TruncSrc);
50  markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
51  return true;
52  }
53 
54  // aext([asz]ext x) -> [asz]ext x
55  Register ExtSrc;
56  MachineInstr *ExtMI;
57  if (mi_match(SrcReg, MRI,
58  m_all_of(m_MInstr(ExtMI), m_any_of(m_GAnyExt(m_Reg(ExtSrc)),
59  m_GSExt(m_Reg(ExtSrc)),
60  m_GZExt(m_Reg(ExtSrc)))))) {
61  Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc});
62  markInstAndDefDead(MI, *ExtMI, DeadInsts);
63  return true;
64  }
65 
66  // Try to fold aext(g_constant) when the larger constant type is legal.
67  // Can't use MIPattern because we don't have a specific constant in mind.
68  auto *SrcMI = MRI.getVRegDef(SrcReg);
69  if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
70  const LLT &DstTy = MRI.getType(DstReg);
71  if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
72  auto CstVal = SrcMI->getOperand(1);
73  APInt Val = CstVal.isImm()
74  ? APInt(DstTy.getSizeInBits(), CstVal.getImm())
75  : CstVal.getCImm()->getValue();
76  Val = Val.sext(DstTy.getSizeInBits());
77  Builder.buildConstant(DstReg, Val);
78  markInstAndDefDead(MI, *SrcMI, DeadInsts);
79  return true;
80  }
81  }
82  return tryFoldImplicitDef(MI, DeadInsts);
83  }
84 
87 
88  if (MI.getOpcode() != TargetOpcode::G_ZEXT)
89  return false;
90 
91  Builder.setInstr(MI);
92  Register DstReg = MI.getOperand(0).getReg();
93  Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
94 
95  // zext(trunc x) - > and (aext/copy/trunc x), mask
96  Register TruncSrc;
97  if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
98  LLT DstTy = MRI.getType(DstReg);
99  if (isInstUnsupported({TargetOpcode::G_AND, {DstTy}}) ||
100  isConstantUnsupported(DstTy))
101  return false;
102  LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
103  LLT SrcTy = MRI.getType(SrcReg);
104  APInt Mask = APInt::getAllOnesValue(SrcTy.getScalarSizeInBits());
105  auto MIBMask = Builder.buildConstant(DstTy, Mask.getZExtValue());
106  Builder.buildAnd(DstReg, Builder.buildAnyExtOrTrunc(DstTy, TruncSrc),
107  MIBMask);
108  markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
109  return true;
110  }
111  return tryFoldImplicitDef(MI, DeadInsts);
112  }
113 
115  SmallVectorImpl<MachineInstr *> &DeadInsts) {
116 
117  if (MI.getOpcode() != TargetOpcode::G_SEXT)
118  return false;
119 
120  Builder.setInstr(MI);
121  Register DstReg = MI.getOperand(0).getReg();
122  Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
123 
124  // sext(trunc x) - > ashr (shl (aext/copy/trunc x), c), c
125  Register TruncSrc;
126  if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
127  LLT DstTy = MRI.getType(DstReg);
128  // Guess on the RHS shift amount type, which should be re-legalized if
129  // applicable.
130  if (isInstUnsupported({TargetOpcode::G_SHL, {DstTy, DstTy}}) ||
131  isInstUnsupported({TargetOpcode::G_ASHR, {DstTy, DstTy}}) ||
132  isConstantUnsupported(DstTy))
133  return false;
134  LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;);
135  LLT SrcTy = MRI.getType(SrcReg);
136  unsigned ShAmt = DstTy.getScalarSizeInBits() - SrcTy.getScalarSizeInBits();
137  auto MIBShAmt = Builder.buildConstant(DstTy, ShAmt);
138  auto MIBShl = Builder.buildInstr(
139  TargetOpcode::G_SHL, {DstTy},
140  {Builder.buildAnyExtOrTrunc(DstTy, TruncSrc), MIBShAmt});
141  Builder.buildInstr(TargetOpcode::G_ASHR, {DstReg}, {MIBShl, MIBShAmt});
142  markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
143  return true;
144  }
145  return tryFoldImplicitDef(MI, DeadInsts);
146  }
147 
148  /// Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF).
150  SmallVectorImpl<MachineInstr *> &DeadInsts) {
151  unsigned Opcode = MI.getOpcode();
152  if (Opcode != TargetOpcode::G_ANYEXT && Opcode != TargetOpcode::G_ZEXT &&
153  Opcode != TargetOpcode::G_SEXT)
154  return false;
155 
156  if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF,
157  MI.getOperand(1).getReg(), MRI)) {
158  Builder.setInstr(MI);
159  Register DstReg = MI.getOperand(0).getReg();
160  LLT DstTy = MRI.getType(DstReg);
161 
162  if (Opcode == TargetOpcode::G_ANYEXT) {
163  // G_ANYEXT (G_IMPLICIT_DEF) -> G_IMPLICIT_DEF
164  if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
165  return false;
166  LLVM_DEBUG(dbgs() << ".. Combine G_ANYEXT(G_IMPLICIT_DEF): " << MI;);
167  Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, {DstReg}, {});
168  } else {
169  // G_[SZ]EXT (G_IMPLICIT_DEF) -> G_CONSTANT 0 because the top
170  // bits will be 0 for G_ZEXT and 0/1 for the G_SEXT.
171  if (isConstantUnsupported(DstTy))
172  return false;
173  LLVM_DEBUG(dbgs() << ".. Combine G_[SZ]EXT(G_IMPLICIT_DEF): " << MI;);
174  Builder.buildConstant(DstReg, 0);
175  }
176 
177  markInstAndDefDead(MI, *DefMI, DeadInsts);
178  return true;
179  }
180  return false;
181  }
182 
183  static unsigned getMergeOpcode(LLT OpTy, LLT DestTy) {
184  if (OpTy.isVector() && DestTy.isVector())
185  return TargetOpcode::G_CONCAT_VECTORS;
186 
187  if (OpTy.isVector() && !DestTy.isVector())
188  return TargetOpcode::G_BUILD_VECTOR;
189 
190  return TargetOpcode::G_MERGE_VALUES;
191  }
192 
194  SmallVectorImpl<MachineInstr *> &DeadInsts) {
195 
196  if (MI.getOpcode() != TargetOpcode::G_UNMERGE_VALUES)
197  return false;
198 
199  unsigned NumDefs = MI.getNumOperands() - 1;
200 
201  LLT OpTy = MRI.getType(MI.getOperand(NumDefs).getReg());
202  LLT DestTy = MRI.getType(MI.getOperand(0).getReg());
203 
204  unsigned MergingOpcode = getMergeOpcode(OpTy, DestTy);
205  MachineInstr *MergeI =
206  getOpcodeDef(MergingOpcode, MI.getOperand(NumDefs).getReg(), MRI);
207 
208  if (!MergeI)
209  return false;
210 
211  const unsigned NumMergeRegs = MergeI->getNumOperands() - 1;
212 
213  if (NumMergeRegs < NumDefs) {
214  if (NumDefs % NumMergeRegs != 0)
215  return false;
216 
217  Builder.setInstr(MI);
218  // Transform to UNMERGEs, for example
219  // %1 = G_MERGE_VALUES %4, %5
220  // %9, %10, %11, %12 = G_UNMERGE_VALUES %1
221  // to
222  // %9, %10 = G_UNMERGE_VALUES %4
223  // %11, %12 = G_UNMERGE_VALUES %5
224 
225  const unsigned NewNumDefs = NumDefs / NumMergeRegs;
226  for (unsigned Idx = 0; Idx < NumMergeRegs; ++Idx) {
227  SmallVector<Register, 2> DstRegs;
228  for (unsigned j = 0, DefIdx = Idx * NewNumDefs; j < NewNumDefs;
229  ++j, ++DefIdx)
230  DstRegs.push_back(MI.getOperand(DefIdx).getReg());
231 
232  Builder.buildUnmerge(DstRegs, MergeI->getOperand(Idx + 1).getReg());
233  }
234 
235  } else if (NumMergeRegs > NumDefs) {
236  if (NumMergeRegs % NumDefs != 0)
237  return false;
238 
239  Builder.setInstr(MI);
240  // Transform to MERGEs
241  // %6 = G_MERGE_VALUES %17, %18, %19, %20
242  // %7, %8 = G_UNMERGE_VALUES %6
243  // to
244  // %7 = G_MERGE_VALUES %17, %18
245  // %8 = G_MERGE_VALUES %19, %20
246 
247  const unsigned NumRegs = NumMergeRegs / NumDefs;
248  for (unsigned DefIdx = 0; DefIdx < NumDefs; ++DefIdx) {
250  for (unsigned j = 0, Idx = NumRegs * DefIdx + 1; j < NumRegs;
251  ++j, ++Idx)
252  Regs.push_back(MergeI->getOperand(Idx).getReg());
253 
254  Builder.buildMerge(MI.getOperand(DefIdx).getReg(), Regs);
255  }
256 
257  } else {
258  // FIXME: is a COPY appropriate if the types mismatch? We know both
259  // registers are allocatable by now.
260  if (MRI.getType(MI.getOperand(0).getReg()) !=
261  MRI.getType(MergeI->getOperand(1).getReg()))
262  return false;
263 
264  for (unsigned Idx = 0; Idx < NumDefs; ++Idx)
265  MRI.replaceRegWith(MI.getOperand(Idx).getReg(),
266  MergeI->getOperand(Idx + 1).getReg());
267  }
268 
269  markInstAndDefDead(MI, *MergeI, DeadInsts);
270  return true;
271  }
272 
273  static bool isMergeLikeOpcode(unsigned Opc) {
274  switch (Opc) {
275  case TargetOpcode::G_MERGE_VALUES:
276  case TargetOpcode::G_BUILD_VECTOR:
277  case TargetOpcode::G_CONCAT_VECTORS:
278  return true;
279  default:
280  return false;
281  }
282  }
283 
285  SmallVectorImpl<MachineInstr *> &DeadInsts) {
286  assert(MI.getOpcode() == TargetOpcode::G_EXTRACT);
287 
288  // Try to use the source registers from a G_MERGE_VALUES
289  //
290  // %2 = G_MERGE_VALUES %0, %1
291  // %3 = G_EXTRACT %2, N
292  // =>
293  //
294  // for N < %2.getSizeInBits() / 2
295  // %3 = G_EXTRACT %0, N
296  //
297  // for N >= %2.getSizeInBits() / 2
298  // %3 = G_EXTRACT %1, (N - %0.getSizeInBits()
299 
300  unsigned Src = lookThroughCopyInstrs(MI.getOperand(1).getReg());
301  MachineInstr *MergeI = MRI.getVRegDef(Src);
302  if (!MergeI || !isMergeLikeOpcode(MergeI->getOpcode()))
303  return false;
304 
305  LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
306  LLT SrcTy = MRI.getType(Src);
307 
308  // TODO: Do we need to check if the resulting extract is supported?
309  unsigned ExtractDstSize = DstTy.getSizeInBits();
310  unsigned Offset = MI.getOperand(2).getImm();
311  unsigned NumMergeSrcs = MergeI->getNumOperands() - 1;
312  unsigned MergeSrcSize = SrcTy.getSizeInBits() / NumMergeSrcs;
313  unsigned MergeSrcIdx = Offset / MergeSrcSize;
314 
315  // Compute the offset of the last bit the extract needs.
316  unsigned EndMergeSrcIdx = (Offset + ExtractDstSize - 1) / MergeSrcSize;
317 
318  // Can't handle the case where the extract spans multiple inputs.
319  if (MergeSrcIdx != EndMergeSrcIdx)
320  return false;
321 
322  // TODO: We could modify MI in place in most cases.
323  Builder.setInstr(MI);
324  Builder.buildExtract(
325  MI.getOperand(0).getReg(),
326  MergeI->getOperand(MergeSrcIdx + 1).getReg(),
327  Offset - MergeSrcIdx * MergeSrcSize);
328  markInstAndDefDead(MI, *MergeI, DeadInsts);
329  return true;
330  }
331 
332  /// Try to combine away MI.
333  /// Returns true if it combined away the MI.
334  /// Adds instructions that are dead as a result of the combine
335  /// into DeadInsts, which can include MI.
338  GISelObserverWrapper &WrapperObserver) {
339  // This might be a recursive call, and we might have DeadInsts already
340  // populated. To avoid bad things happening later with multiple vreg defs
341  // etc, process the dead instructions now if any.
342  if (!DeadInsts.empty())
343  deleteMarkedDeadInsts(DeadInsts, WrapperObserver);
344  switch (MI.getOpcode()) {
345  default:
346  return false;
347  case TargetOpcode::G_ANYEXT:
348  return tryCombineAnyExt(MI, DeadInsts);
349  case TargetOpcode::G_ZEXT:
350  return tryCombineZExt(MI, DeadInsts);
351  case TargetOpcode::G_SEXT:
352  return tryCombineSExt(MI, DeadInsts);
353  case TargetOpcode::G_UNMERGE_VALUES:
354  return tryCombineMerges(MI, DeadInsts);
355  case TargetOpcode::G_EXTRACT:
356  return tryCombineExtract(MI, DeadInsts);
357  case TargetOpcode::G_TRUNC: {
358  bool Changed = false;
359  for (auto &Use : MRI.use_instructions(MI.getOperand(0).getReg()))
360  Changed |= tryCombineInstruction(Use, DeadInsts, WrapperObserver);
361  return Changed;
362  }
363  }
364  }
365 
366 private:
367 
368  static unsigned getArtifactSrcReg(const MachineInstr &MI) {
369  switch (MI.getOpcode()) {
370  case TargetOpcode::COPY:
371  case TargetOpcode::G_TRUNC:
372  case TargetOpcode::G_ZEXT:
373  case TargetOpcode::G_ANYEXT:
374  case TargetOpcode::G_SEXT:
375  case TargetOpcode::G_UNMERGE_VALUES:
376  return MI.getOperand(MI.getNumOperands() - 1).getReg();
377  case TargetOpcode::G_EXTRACT:
378  return MI.getOperand(1).getReg();
379  default:
380  llvm_unreachable("Not a legalization artifact happen");
381  }
382  }
383 
384  /// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be
385  /// dead due to MI being killed, then mark DefMI as dead too.
386  /// Some of the combines (extends(trunc)), try to walk through redundant
387  /// copies in between the extends and the truncs, and this attempts to collect
388  /// the in between copies if they're dead.
389  void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI,
390  SmallVectorImpl<MachineInstr *> &DeadInsts) {
391  DeadInsts.push_back(&MI);
392 
393  // Collect all the copy instructions that are made dead, due to deleting
394  // this instruction. Collect all of them until the Trunc(DefMI).
395  // Eg,
396  // %1(s1) = G_TRUNC %0(s32)
397  // %2(s1) = COPY %1(s1)
398  // %3(s1) = COPY %2(s1)
399  // %4(s32) = G_ANYEXT %3(s1)
400  // In this case, we would have replaced %4 with a copy of %0,
401  // and as a result, %3, %2, %1 are dead.
402  MachineInstr *PrevMI = &MI;
403  while (PrevMI != &DefMI) {
404  unsigned PrevRegSrc = getArtifactSrcReg(*PrevMI);
405 
406  MachineInstr *TmpDef = MRI.getVRegDef(PrevRegSrc);
407  if (MRI.hasOneUse(PrevRegSrc)) {
408  if (TmpDef != &DefMI) {
409  assert(TmpDef->getOpcode() == TargetOpcode::COPY &&
410  "Expecting copy here");
411  DeadInsts.push_back(TmpDef);
412  }
413  } else
414  break;
415  PrevMI = TmpDef;
416  }
417  if (PrevMI == &DefMI && MRI.hasOneUse(DefMI.getOperand(0).getReg()))
418  DeadInsts.push_back(&DefMI);
419  }
420 
421  /// Erase the dead instructions in the list and call the observer hooks.
422  /// Normally the Legalizer will deal with erasing instructions that have been
423  /// marked dead. However, for the trunc(ext(x)) cases we can end up trying to
424  /// process instructions which have been marked dead, but otherwise break the
425  /// MIR by introducing multiple vreg defs. For those cases, allow the combines
426  /// to explicitly delete the instructions before we run into trouble.
427  void deleteMarkedDeadInsts(SmallVectorImpl<MachineInstr *> &DeadInsts,
428  GISelObserverWrapper &WrapperObserver) {
429  for (auto *DeadMI : DeadInsts) {
430  LLVM_DEBUG(dbgs() << *DeadMI << "Is dead, eagerly deleting\n");
431  WrapperObserver.erasingInstr(*DeadMI);
432  DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
433  }
434  DeadInsts.clear();
435  }
436 
437  /// Checks if the target legalizer info has specified anything about the
438  /// instruction, or if unsupported.
439  bool isInstUnsupported(const LegalityQuery &Query) const {
440  using namespace LegalizeActions;
441  auto Step = LI.getAction(Query);
442  return Step.Action == Unsupported || Step.Action == NotFound;
443  }
444 
445  bool isInstLegal(const LegalityQuery &Query) const {
446  return LI.getAction(Query).Action == LegalizeActions::Legal;
447  }
448 
449  bool isConstantUnsupported(LLT Ty) const {
450  if (!Ty.isVector())
451  return isInstUnsupported({TargetOpcode::G_CONSTANT, {Ty}});
452 
453  LLT EltTy = Ty.getElementType();
454  return isInstUnsupported({TargetOpcode::G_CONSTANT, {EltTy}}) ||
455  isInstUnsupported({TargetOpcode::G_BUILD_VECTOR, {Ty, EltTy}});
456  }
457 
458  /// Looks through copy instructions and returns the actual
459  /// source register.
460  unsigned lookThroughCopyInstrs(Register Reg) {
461  Register TmpReg;
462  while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg)))) {
463  if (MRI.getType(TmpReg).isValid())
464  Reg = TmpReg;
465  else
466  break;
467  }
468  return Reg;
469  }
470 };
471 
472 } // namespace llvm
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1562
APInt sext(unsigned width) const
Sign extend to a new width.
Definition: APInt.cpp:833
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
Definition: APInt.h:561
UnaryOp_match< SrcTy, TargetOpcode::G_ANYEXT > m_GAnyExt(const SrcTy &Src)
static unsigned getMergeOpcode(LLT OpTy, LLT DestTy)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
unsigned getScalarSizeInBits() const
The LegalityQuery object bundles together all the information that&#39;s needed to decide whether a given...
bool tryCombineMerges(MachineInstr &MI, SmallVectorImpl< MachineInstr *> &DeadInsts)
unsigned Reg
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
void erasingInstr(MachineInstr &MI) override
An instruction is about to be erased.
MachineInstrBuilder buildExtract(const DstOp &Res, const SrcOp &Src, uint64_t Index)
Build and insert `Res0, ...
bool tryCombineInstruction(MachineInstr &MI, SmallVectorImpl< MachineInstr *> &DeadInsts, GISelObserverWrapper &WrapperObserver)
Try to combine away MI.
Or< Preds... > m_any_of(Preds &&... preds)
bool isVector() const
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:413
A Use represents the edge between a Value definition and its users.
Definition: Use.h:55
MachineInstrBuilder buildAnyExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Res = COPY Op depending on the differing sizes of Res and Op.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:410
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:85
LLT getElementType() const
Returns the vector&#39;s element type. Only valid for vector types.
bool tryCombineAnyExt(MachineInstr &MI, SmallVectorImpl< MachineInstr *> &DeadInsts)
bool mi_match(Reg R, MachineRegisterInfo &MRI, Pattern &&P)
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
And< Preds... > m_all_of(Preds &&... preds)
MachineInstr * getOpcodeDef(unsigned Opcode, unsigned Reg, const MachineRegisterInfo &MRI)
See if Reg is defined by an single def instruction that is Opcode.
Definition: Utils.cpp:284
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
Sentinel value for when no action was found in the specified table.
Definition: LegalizerInfo.h:88
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
Helper class to build MachineInstr.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
bool isValid() const
LegalizationArtifactCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI, const LegalizerInfo &LI)
bool tryFoldImplicitDef(MachineInstr &MI, SmallVectorImpl< MachineInstr *> &DeadInsts)
Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF).
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
int64_t getImm() const
This file declares the MachineIRBuilder class.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Class for arbitrary precision integers.
Definition: APInt.h:69
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
UnaryOp_match< SrcTy, TargetOpcode::G_SEXT > m_GSExt(const SrcTy &Src)
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:63
bool tryCombineSExt(MachineInstr &MI, SmallVectorImpl< MachineInstr *> &DeadInsts)
LegalizeAction Action
The action to take or the final answer.
bool hasOneUse(unsigned RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
bool tryCombineZExt(MachineInstr &MI, SmallVectorImpl< MachineInstr *> &DeadInsts)
iterator_range< use_instr_iterator > use_instructions(unsigned Reg) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
operand_type_match m_Reg()
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:80
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
IRTranslator LLVM IR MI
Simple wrapper observer that takes several observers, and calls each one for each event...
Register getReg() const
getReg - Returns the register number.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:415
bool tryCombineExtract(MachineInstr &MI, SmallVectorImpl< MachineInstr *> &DeadInsts)
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:47
Wrapper class representing virtual and physical registers.
Definition: Register.h:18