LLVM  6.0.0svn
SIFoldOperands.cpp
Go to the documentation of this file.
1 //===-- SIFoldOperands.cpp - Fold operands --- ----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 /// \file
9 //===----------------------------------------------------------------------===//
10 //
11 
12 #include "AMDGPU.h"
13 #include "AMDGPUSubtarget.h"
14 #include "SIInstrInfo.h"
15 #include "SIMachineFunctionInfo.h"
21 #include "llvm/Support/Debug.h"
24 
25 #define DEBUG_TYPE "si-fold-operands"
26 using namespace llvm;
27 
28 namespace {
29 
30 struct FoldCandidate {
32  union {
33  MachineOperand *OpToFold;
34  uint64_t ImmToFold;
35  int FrameIndexToFold;
36  };
37  unsigned char UseOpNo;
39  bool Commuted;
40 
41  FoldCandidate(MachineInstr *MI, unsigned OpNo, MachineOperand *FoldOp,
42  bool Commuted_ = false) :
43  UseMI(MI), OpToFold(nullptr), UseOpNo(OpNo), Kind(FoldOp->getType()),
44  Commuted(Commuted_) {
45  if (FoldOp->isImm()) {
46  ImmToFold = FoldOp->getImm();
47  } else if (FoldOp->isFI()) {
48  FrameIndexToFold = FoldOp->getIndex();
49  } else {
50  assert(FoldOp->isReg());
51  OpToFold = FoldOp;
52  }
53  }
54 
55  bool isFI() const {
56  return Kind == MachineOperand::MO_FrameIndex;
57  }
58 
59  bool isImm() const {
60  return Kind == MachineOperand::MO_Immediate;
61  }
62 
63  bool isReg() const {
64  return Kind == MachineOperand::MO_Register;
65  }
66 
67  bool isCommuted() const {
68  return Commuted;
69  }
70 };
71 
72 class SIFoldOperands : public MachineFunctionPass {
73 public:
74  static char ID;
76  const SIInstrInfo *TII;
77  const SIRegisterInfo *TRI;
78  const SISubtarget *ST;
79 
80  void foldOperand(MachineOperand &OpToFold,
82  unsigned UseOpIdx,
84  SmallVectorImpl<MachineInstr *> &CopiesToReplace) const;
85 
86  void foldInstOperand(MachineInstr &MI, MachineOperand &OpToFold) const;
87 
88  const MachineOperand *isClamp(const MachineInstr &MI) const;
89  bool tryFoldClamp(MachineInstr &MI);
90 
91  std::pair<const MachineOperand *, int> isOMod(const MachineInstr &MI) const;
92  bool tryFoldOMod(MachineInstr &MI);
93 
94 public:
95  SIFoldOperands() : MachineFunctionPass(ID) {
97  }
98 
99  bool runOnMachineFunction(MachineFunction &MF) override;
100 
101  StringRef getPassName() const override { return "SI Fold Operands"; }
102 
103  void getAnalysisUsage(AnalysisUsage &AU) const override {
104  AU.setPreservesCFG();
106  }
107 };
108 
109 } // End anonymous namespace.
110 
111 INITIALIZE_PASS(SIFoldOperands, DEBUG_TYPE,
112  "SI Fold Operands", false, false)
113 
114 char SIFoldOperands::ID = 0;
115 
117 
118 // Wrapper around isInlineConstant that understands special cases when
119 // instruction types are replaced during operand folding.
121  const MachineInstr &UseMI,
122  unsigned OpNo,
123  const MachineOperand &OpToFold) {
124  if (TII->isInlineConstant(UseMI, OpNo, OpToFold))
125  return true;
126 
127  unsigned Opc = UseMI.getOpcode();
128  switch (Opc) {
129  case AMDGPU::V_MAC_F32_e64:
130  case AMDGPU::V_MAC_F16_e64: {
131  // Special case for mac. Since this is replaced with mad when folded into
132  // src2, we need to check the legality for the final instruction.
133  int Src2Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2);
134  if (static_cast<int>(OpNo) == Src2Idx) {
135  bool IsF32 = Opc == AMDGPU::V_MAC_F32_e64;
136  const MCInstrDesc &MadDesc
137  = TII->get(IsF32 ? AMDGPU::V_MAD_F32 : AMDGPU::V_MAD_F16);
138  return TII->isInlineConstant(OpToFold, MadDesc.OpInfo[OpNo].OperandType);
139  }
140  return false;
141  }
142  default:
143  return false;
144  }
145 }
146 
148  return new SIFoldOperands();
149 }
150 
151 static bool updateOperand(FoldCandidate &Fold,
152  const TargetRegisterInfo &TRI) {
153  MachineInstr *MI = Fold.UseMI;
154  MachineOperand &Old = MI->getOperand(Fold.UseOpNo);
155  assert(Old.isReg());
156 
157  if (Fold.isImm()) {
158  Old.ChangeToImmediate(Fold.ImmToFold);
159  return true;
160  }
161 
162  if (Fold.isFI()) {
163  Old.ChangeToFrameIndex(Fold.FrameIndexToFold);
164  return true;
165  }
166 
167  MachineOperand *New = Fold.OpToFold;
170  Old.substVirtReg(New->getReg(), New->getSubReg(), TRI);
171 
172  Old.setIsUndef(New->isUndef());
173  return true;
174  }
175 
176  // FIXME: Handle physical registers.
177 
178  return false;
179 }
180 
182  const MachineInstr *MI) {
183  for (auto Candidate : FoldList) {
184  if (Candidate.UseMI == MI)
185  return true;
186  }
187  return false;
188 }
189 
191  MachineInstr *MI, unsigned OpNo,
192  MachineOperand *OpToFold,
193  const SIInstrInfo *TII) {
194  if (!TII->isOperandLegal(*MI, OpNo, OpToFold)) {
195 
196  // Special case for v_mac_{f16, f32}_e64 if we are trying to fold into src2
197  unsigned Opc = MI->getOpcode();
198  if ((Opc == AMDGPU::V_MAC_F32_e64 || Opc == AMDGPU::V_MAC_F16_e64) &&
199  (int)OpNo == AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2)) {
200  bool IsF32 = Opc == AMDGPU::V_MAC_F32_e64;
201 
202  // Check if changing this to a v_mad_{f16, f32} instruction will allow us
203  // to fold the operand.
204  MI->setDesc(TII->get(IsF32 ? AMDGPU::V_MAD_F32 : AMDGPU::V_MAD_F16));
205  bool FoldAsMAD = tryAddToFoldList(FoldList, MI, OpNo, OpToFold, TII);
206  if (FoldAsMAD) {
207  MI->untieRegOperand(OpNo);
208  return true;
209  }
210  MI->setDesc(TII->get(Opc));
211  }
212 
213  // Special case for s_setreg_b32
214  if (Opc == AMDGPU::S_SETREG_B32 && OpToFold->isImm()) {
215  MI->setDesc(TII->get(AMDGPU::S_SETREG_IMM32_B32));
216  FoldList.push_back(FoldCandidate(MI, OpNo, OpToFold));
217  return true;
218  }
219 
220  // If we are already folding into another operand of MI, then
221  // we can't commute the instruction, otherwise we risk making the
222  // other fold illegal.
223  if (isUseMIInFoldList(FoldList, MI))
224  return false;
225 
226  // Operand is not legal, so try to commute the instruction to
227  // see if this makes it possible to fold.
228  unsigned CommuteIdx0 = TargetInstrInfo::CommuteAnyOperandIndex;
229  unsigned CommuteIdx1 = TargetInstrInfo::CommuteAnyOperandIndex;
230  bool CanCommute = TII->findCommutedOpIndices(*MI, CommuteIdx0, CommuteIdx1);
231 
232  if (CanCommute) {
233  if (CommuteIdx0 == OpNo)
234  OpNo = CommuteIdx1;
235  else if (CommuteIdx1 == OpNo)
236  OpNo = CommuteIdx0;
237  }
238 
239  // One of operands might be an Imm operand, and OpNo may refer to it after
240  // the call of commuteInstruction() below. Such situations are avoided
241  // here explicitly as OpNo must be a register operand to be a candidate
242  // for memory folding.
243  if (CanCommute && (!MI->getOperand(CommuteIdx0).isReg() ||
244  !MI->getOperand(CommuteIdx1).isReg()))
245  return false;
246 
247  if (!CanCommute ||
248  !TII->commuteInstruction(*MI, false, CommuteIdx0, CommuteIdx1))
249  return false;
250 
251  if (!TII->isOperandLegal(*MI, OpNo, OpToFold)) {
252  TII->commuteInstruction(*MI, false, CommuteIdx0, CommuteIdx1);
253  return false;
254  }
255 
256  FoldList.push_back(FoldCandidate(MI, OpNo, OpToFold, true));
257  return true;
258  }
259 
260  FoldList.push_back(FoldCandidate(MI, OpNo, OpToFold));
261  return true;
262 }
263 
264 // If the use operand doesn't care about the value, this may be an operand only
265 // used for register indexing, in which case it is unsafe to fold.
266 static bool isUseSafeToFold(const SIInstrInfo *TII,
267  const MachineInstr &MI,
268  const MachineOperand &UseMO) {
269  return !UseMO.isUndef() && !TII->isSDWA(MI);
270  //return !MI.hasRegisterImplicitUseOperand(UseMO.getReg());
271 }
272 
273 void SIFoldOperands::foldOperand(
274  MachineOperand &OpToFold,
276  unsigned UseOpIdx,
278  SmallVectorImpl<MachineInstr *> &CopiesToReplace) const {
279  const MachineOperand &UseOp = UseMI->getOperand(UseOpIdx);
280 
281  if (!isUseSafeToFold(TII, *UseMI, UseOp))
282  return;
283 
284  // FIXME: Fold operands with subregs.
285  if (UseOp.isReg() && OpToFold.isReg()) {
286  if (UseOp.isImplicit() || UseOp.getSubReg() != AMDGPU::NoSubRegister)
287  return;
288 
289  // Don't fold subregister extracts into tied operands, only if it is a full
290  // copy since a subregister use tied to a full register def doesn't really
291  // make sense. e.g. don't fold:
292  //
293  // %vreg1 = COPY %vreg0:sub1
294  // %vreg2<tied3> = V_MAC_{F16, F32} %vreg3, %vreg4, %vreg1<tied0>
295  //
296  // into
297  // %vreg2<tied3> = V_MAC_{F16, F32} %vreg3, %vreg4, %vreg0:sub1<tied0>
298  if (UseOp.isTied() && OpToFold.getSubReg() != AMDGPU::NoSubRegister)
299  return;
300  }
301 
302  // Special case for REG_SEQUENCE: We can't fold literals into
303  // REG_SEQUENCE instructions, so we have to fold them into the
304  // uses of REG_SEQUENCE.
305  if (UseMI->isRegSequence()) {
306  unsigned RegSeqDstReg = UseMI->getOperand(0).getReg();
307  unsigned RegSeqDstSubReg = UseMI->getOperand(UseOpIdx + 1).getImm();
308 
310  RSUse = MRI->use_begin(RegSeqDstReg), RSE = MRI->use_end();
311  RSUse != RSE; ++RSUse) {
312 
313  MachineInstr *RSUseMI = RSUse->getParent();
314  if (RSUse->getSubReg() != RegSeqDstSubReg)
315  continue;
316 
317  foldOperand(OpToFold, RSUseMI, RSUse.getOperandNo(), FoldList,
318  CopiesToReplace);
319  }
320 
321  return;
322  }
323 
324 
325  bool FoldingImm = OpToFold.isImm();
326 
327  // In order to fold immediates into copies, we need to change the
328  // copy to a MOV.
329  if (FoldingImm && UseMI->isCopy()) {
330  unsigned DestReg = UseMI->getOperand(0).getReg();
331  const TargetRegisterClass *DestRC
333  MRI->getRegClass(DestReg) :
334  TRI->getPhysRegClass(DestReg);
335 
336  unsigned MovOp = TII->getMovOpcode(DestRC);
337  if (MovOp == AMDGPU::COPY)
338  return;
339 
340  UseMI->setDesc(TII->get(MovOp));
341  CopiesToReplace.push_back(UseMI);
342  } else {
343  const MCInstrDesc &UseDesc = UseMI->getDesc();
344 
345  // Don't fold into target independent nodes. Target independent opcodes
346  // don't have defined register classes.
347  if (UseDesc.isVariadic() ||
348  UseDesc.OpInfo[UseOpIdx].RegClass == -1)
349  return;
350  }
351 
352  if (!FoldingImm) {
353  tryAddToFoldList(FoldList, UseMI, UseOpIdx, &OpToFold, TII);
354 
355  // FIXME: We could try to change the instruction from 64-bit to 32-bit
356  // to enable more folding opportunites. The shrink operands pass
357  // already does this.
358  return;
359  }
360 
361 
362  const MCInstrDesc &FoldDesc = OpToFold.getParent()->getDesc();
363  const TargetRegisterClass *FoldRC =
364  TRI->getRegClass(FoldDesc.OpInfo[0].RegClass);
365 
366 
367  // Split 64-bit constants into 32-bits for folding.
368  if (UseOp.getSubReg() && AMDGPU::getRegBitWidth(FoldRC->getID()) == 64) {
369  unsigned UseReg = UseOp.getReg();
370  const TargetRegisterClass *UseRC
372  MRI->getRegClass(UseReg) :
373  TRI->getPhysRegClass(UseReg);
374 
375  if (AMDGPU::getRegBitWidth(UseRC->getID()) != 64)
376  return;
377 
378  APInt Imm(64, OpToFold.getImm());
379  if (UseOp.getSubReg() == AMDGPU::sub0) {
380  Imm = Imm.getLoBits(32);
381  } else {
382  assert(UseOp.getSubReg() == AMDGPU::sub1);
383  Imm = Imm.getHiBits(32);
384  }
385 
386  MachineOperand ImmOp = MachineOperand::CreateImm(Imm.getSExtValue());
387  tryAddToFoldList(FoldList, UseMI, UseOpIdx, &ImmOp, TII);
388  return;
389  }
390 
391 
392 
393  tryAddToFoldList(FoldList, UseMI, UseOpIdx, &OpToFold, TII);
394 }
395 
396 static bool evalBinaryInstruction(unsigned Opcode, int32_t &Result,
397  uint32_t LHS, uint32_t RHS) {
398  switch (Opcode) {
399  case AMDGPU::V_AND_B32_e64:
400  case AMDGPU::V_AND_B32_e32:
401  case AMDGPU::S_AND_B32:
402  Result = LHS & RHS;
403  return true;
404  case AMDGPU::V_OR_B32_e64:
405  case AMDGPU::V_OR_B32_e32:
406  case AMDGPU::S_OR_B32:
407  Result = LHS | RHS;
408  return true;
409  case AMDGPU::V_XOR_B32_e64:
410  case AMDGPU::V_XOR_B32_e32:
411  case AMDGPU::S_XOR_B32:
412  Result = LHS ^ RHS;
413  return true;
414  case AMDGPU::V_LSHL_B32_e64:
415  case AMDGPU::V_LSHL_B32_e32:
416  case AMDGPU::S_LSHL_B32:
417  // The instruction ignores the high bits for out of bounds shifts.
418  Result = LHS << (RHS & 31);
419  return true;
420  case AMDGPU::V_LSHLREV_B32_e64:
421  case AMDGPU::V_LSHLREV_B32_e32:
422  Result = RHS << (LHS & 31);
423  return true;
424  case AMDGPU::V_LSHR_B32_e64:
425  case AMDGPU::V_LSHR_B32_e32:
426  case AMDGPU::S_LSHR_B32:
427  Result = LHS >> (RHS & 31);
428  return true;
429  case AMDGPU::V_LSHRREV_B32_e64:
430  case AMDGPU::V_LSHRREV_B32_e32:
431  Result = RHS >> (LHS & 31);
432  return true;
433  case AMDGPU::V_ASHR_I32_e64:
434  case AMDGPU::V_ASHR_I32_e32:
435  case AMDGPU::S_ASHR_I32:
436  Result = static_cast<int32_t>(LHS) >> (RHS & 31);
437  return true;
438  case AMDGPU::V_ASHRREV_I32_e64:
439  case AMDGPU::V_ASHRREV_I32_e32:
440  Result = static_cast<int32_t>(RHS) >> (LHS & 31);
441  return true;
442  default:
443  return false;
444  }
445 }
446 
447 static unsigned getMovOpc(bool IsScalar) {
448  return IsScalar ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
449 }
450 
451 /// Remove any leftover implicit operands from mutating the instruction. e.g.
452 /// if we replace an s_and_b32 with a copy, we don't need the implicit scc def
453 /// anymore.
455  const MCInstrDesc &Desc = MI.getDesc();
456  unsigned NumOps = Desc.getNumOperands() +
457  Desc.getNumImplicitUses() +
458  Desc.getNumImplicitDefs();
459 
460  for (unsigned I = MI.getNumOperands() - 1; I >= NumOps; --I)
461  MI.RemoveOperand(I);
462 }
463 
464 static void mutateCopyOp(MachineInstr &MI, const MCInstrDesc &NewDesc) {
465  MI.setDesc(NewDesc);
467 }
468 
470  MachineOperand &Op) {
471  if (Op.isReg()) {
472  // If this has a subregister, it obviously is a register source.
473  if (Op.getSubReg() != AMDGPU::NoSubRegister)
474  return &Op;
475 
476  MachineInstr *Def = MRI.getVRegDef(Op.getReg());
477  if (Def && Def->isMoveImmediate()) {
478  MachineOperand &ImmSrc = Def->getOperand(1);
479  if (ImmSrc.isImm())
480  return &ImmSrc;
481  }
482  }
483 
484  return &Op;
485 }
486 
487 // Try to simplify operations with a constant that may appear after instruction
488 // selection.
489 // TODO: See if a frame index with a fixed offset can fold.
491  const SIInstrInfo *TII,
492  MachineInstr *MI,
493  MachineOperand *ImmOp) {
494  unsigned Opc = MI->getOpcode();
495  if (Opc == AMDGPU::V_NOT_B32_e64 || Opc == AMDGPU::V_NOT_B32_e32 ||
496  Opc == AMDGPU::S_NOT_B32) {
497  MI->getOperand(1).ChangeToImmediate(~ImmOp->getImm());
498  mutateCopyOp(*MI, TII->get(getMovOpc(Opc == AMDGPU::S_NOT_B32)));
499  return true;
500  }
501 
502  int Src1Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1);
503  if (Src1Idx == -1)
504  return false;
505 
506  int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
507  MachineOperand *Src0 = getImmOrMaterializedImm(MRI, MI->getOperand(Src0Idx));
508  MachineOperand *Src1 = getImmOrMaterializedImm(MRI, MI->getOperand(Src1Idx));
509 
510  if (!Src0->isImm() && !Src1->isImm())
511  return false;
512 
513  // and k0, k1 -> v_mov_b32 (k0 & k1)
514  // or k0, k1 -> v_mov_b32 (k0 | k1)
515  // xor k0, k1 -> v_mov_b32 (k0 ^ k1)
516  if (Src0->isImm() && Src1->isImm()) {
517  int32_t NewImm;
518  if (!evalBinaryInstruction(Opc, NewImm, Src0->getImm(), Src1->getImm()))
519  return false;
520 
521  const SIRegisterInfo &TRI = TII->getRegisterInfo();
522  bool IsSGPR = TRI.isSGPRReg(MRI, MI->getOperand(0).getReg());
523 
524  // Be careful to change the right operand, src0 may belong to a different
525  // instruction.
526  MI->getOperand(Src0Idx).ChangeToImmediate(NewImm);
527  MI->RemoveOperand(Src1Idx);
528  mutateCopyOp(*MI, TII->get(getMovOpc(IsSGPR)));
529  return true;
530  }
531 
532  if (!MI->isCommutable())
533  return false;
534 
535  if (Src0->isImm() && !Src1->isImm()) {
536  std::swap(Src0, Src1);
537  std::swap(Src0Idx, Src1Idx);
538  }
539 
540  int32_t Src1Val = static_cast<int32_t>(Src1->getImm());
541  if (Opc == AMDGPU::V_OR_B32_e64 ||
542  Opc == AMDGPU::V_OR_B32_e32 ||
543  Opc == AMDGPU::S_OR_B32) {
544  if (Src1Val == 0) {
545  // y = or x, 0 => y = copy x
546  MI->RemoveOperand(Src1Idx);
547  mutateCopyOp(*MI, TII->get(AMDGPU::COPY));
548  } else if (Src1Val == -1) {
549  // y = or x, -1 => y = v_mov_b32 -1
550  MI->RemoveOperand(Src1Idx);
551  mutateCopyOp(*MI, TII->get(getMovOpc(Opc == AMDGPU::S_OR_B32)));
552  } else
553  return false;
554 
555  return true;
556  }
557 
558  if (MI->getOpcode() == AMDGPU::V_AND_B32_e64 ||
559  MI->getOpcode() == AMDGPU::V_AND_B32_e32 ||
560  MI->getOpcode() == AMDGPU::S_AND_B32) {
561  if (Src1Val == 0) {
562  // y = and x, 0 => y = v_mov_b32 0
563  MI->RemoveOperand(Src0Idx);
564  mutateCopyOp(*MI, TII->get(getMovOpc(Opc == AMDGPU::S_AND_B32)));
565  } else if (Src1Val == -1) {
566  // y = and x, -1 => y = copy x
567  MI->RemoveOperand(Src1Idx);
568  mutateCopyOp(*MI, TII->get(AMDGPU::COPY));
570  } else
571  return false;
572 
573  return true;
574  }
575 
576  if (MI->getOpcode() == AMDGPU::V_XOR_B32_e64 ||
577  MI->getOpcode() == AMDGPU::V_XOR_B32_e32 ||
578  MI->getOpcode() == AMDGPU::S_XOR_B32) {
579  if (Src1Val == 0) {
580  // y = xor x, 0 => y = copy x
581  MI->RemoveOperand(Src1Idx);
582  mutateCopyOp(*MI, TII->get(AMDGPU::COPY));
583  return true;
584  }
585  }
586 
587  return false;
588 }
589 
590 // Try to fold an instruction into a simpler one
591 static bool tryFoldInst(const SIInstrInfo *TII,
592  MachineInstr *MI) {
593  unsigned Opc = MI->getOpcode();
594 
595  if (Opc == AMDGPU::V_CNDMASK_B32_e32 ||
596  Opc == AMDGPU::V_CNDMASK_B32_e64 ||
597  Opc == AMDGPU::V_CNDMASK_B64_PSEUDO) {
598  const MachineOperand *Src0 = TII->getNamedOperand(*MI, AMDGPU::OpName::src0);
599  const MachineOperand *Src1 = TII->getNamedOperand(*MI, AMDGPU::OpName::src1);
600  if (Src1->isIdenticalTo(*Src0)) {
601  DEBUG(dbgs() << "Folded " << *MI << " into ");
602  int Src2Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2);
603  if (Src2Idx != -1)
604  MI->RemoveOperand(Src2Idx);
605  MI->RemoveOperand(AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1));
606  mutateCopyOp(*MI, TII->get(Src0->isReg() ? (unsigned)AMDGPU::COPY
607  : getMovOpc(false)));
608  DEBUG(dbgs() << *MI << '\n');
609  return true;
610  }
611  }
612 
613  return false;
614 }
615 
616 void SIFoldOperands::foldInstOperand(MachineInstr &MI,
617  MachineOperand &OpToFold) const {
618  // We need mutate the operands of new mov instructions to add implicit
619  // uses of EXEC, but adding them invalidates the use_iterator, so defer
620  // this.
621  SmallVector<MachineInstr *, 4> CopiesToReplace;
623  MachineOperand &Dst = MI.getOperand(0);
624 
625  bool FoldingImm = OpToFold.isImm() || OpToFold.isFI();
626  if (FoldingImm) {
627  unsigned NumLiteralUses = 0;
628  MachineOperand *NonInlineUse = nullptr;
629  int NonInlineUseOpNo = -1;
630 
633  Use = MRI->use_begin(Dst.getReg()), E = MRI->use_end();
634  Use != E; Use = NextUse) {
635  NextUse = std::next(Use);
636  MachineInstr *UseMI = Use->getParent();
637  unsigned OpNo = Use.getOperandNo();
638 
639  // Folding the immediate may reveal operations that can be constant
640  // folded or replaced with a copy. This can happen for example after
641  // frame indices are lowered to constants or from splitting 64-bit
642  // constants.
643  //
644  // We may also encounter cases where one or both operands are
645  // immediates materialized into a register, which would ordinarily not
646  // be folded due to multiple uses or operand constraints.
647 
648  if (OpToFold.isImm() && tryConstantFoldOp(*MRI, TII, UseMI, &OpToFold)) {
649  DEBUG(dbgs() << "Constant folded " << *UseMI <<'\n');
650 
651  // Some constant folding cases change the same immediate's use to a new
652  // instruction, e.g. and x, 0 -> 0. Make sure we re-visit the user
653  // again. The same constant folded instruction could also have a second
654  // use operand.
655  NextUse = MRI->use_begin(Dst.getReg());
656  FoldList.clear();
657  continue;
658  }
659 
660  // Try to fold any inline immediate uses, and then only fold other
661  // constants if they have one use.
662  //
663  // The legality of the inline immediate must be checked based on the use
664  // operand, not the defining instruction, because 32-bit instructions
665  // with 32-bit inline immediate sources may be used to materialize
666  // constants used in 16-bit operands.
667  //
668  // e.g. it is unsafe to fold:
669  // s_mov_b32 s0, 1.0 // materializes 0x3f800000
670  // v_add_f16 v0, v1, s0 // 1.0 f16 inline immediate sees 0x00003c00
671 
672  // Folding immediates with more than one use will increase program size.
673  // FIXME: This will also reduce register usage, which may be better
674  // in some cases. A better heuristic is needed.
675  if (isInlineConstantIfFolded(TII, *UseMI, OpNo, OpToFold)) {
676  foldOperand(OpToFold, UseMI, OpNo, FoldList, CopiesToReplace);
677  } else {
678  if (++NumLiteralUses == 1) {
679  NonInlineUse = &*Use;
680  NonInlineUseOpNo = OpNo;
681  }
682  }
683  }
684 
685  if (NumLiteralUses == 1) {
686  MachineInstr *UseMI = NonInlineUse->getParent();
687  foldOperand(OpToFold, UseMI, NonInlineUseOpNo, FoldList, CopiesToReplace);
688  }
689  } else {
690  // Folding register.
692  Use = MRI->use_begin(Dst.getReg()), E = MRI->use_end();
693  Use != E; ++Use) {
694  MachineInstr *UseMI = Use->getParent();
695 
696  foldOperand(OpToFold, UseMI, Use.getOperandNo(),
697  FoldList, CopiesToReplace);
698  }
699  }
700 
701  MachineFunction *MF = MI.getParent()->getParent();
702  // Make sure we add EXEC uses to any new v_mov instructions created.
703  for (MachineInstr *Copy : CopiesToReplace)
704  Copy->addImplicitDefUseOperands(*MF);
705 
706  for (FoldCandidate &Fold : FoldList) {
707  if (updateOperand(Fold, *TRI)) {
708  // Clear kill flags.
709  if (Fold.isReg()) {
710  assert(Fold.OpToFold && Fold.OpToFold->isReg());
711  // FIXME: Probably shouldn't bother trying to fold if not an
712  // SGPR. PeepholeOptimizer can eliminate redundant VGPR->VGPR
713  // copies.
714  MRI->clearKillFlags(Fold.OpToFold->getReg());
715  }
716  DEBUG(dbgs() << "Folded source from " << MI << " into OpNo " <<
717  static_cast<int>(Fold.UseOpNo) << " of " << *Fold.UseMI << '\n');
718  tryFoldInst(TII, Fold.UseMI);
719  } else if (Fold.isCommuted()) {
720  // Restoring instruction's original operand order if fold has failed.
721  TII->commuteInstruction(*Fold.UseMI, false);
722  }
723  }
724 }
725 
726 // Clamp patterns are canonically selected to v_max_* instructions, so only
727 // handle them.
728 const MachineOperand *SIFoldOperands::isClamp(const MachineInstr &MI) const {
729  unsigned Op = MI.getOpcode();
730  switch (Op) {
731  case AMDGPU::V_MAX_F32_e64:
732  case AMDGPU::V_MAX_F16_e64:
733  case AMDGPU::V_MAX_F64:
734  case AMDGPU::V_PK_MAX_F16: {
735  if (!TII->getNamedOperand(MI, AMDGPU::OpName::clamp)->getImm())
736  return nullptr;
737 
738  // Make sure sources are identical.
739  const MachineOperand *Src0 = TII->getNamedOperand(MI, AMDGPU::OpName::src0);
740  const MachineOperand *Src1 = TII->getNamedOperand(MI, AMDGPU::OpName::src1);
741  if (!Src0->isReg() || !Src1->isReg() ||
742  Src0->getReg() != Src1->getReg() ||
743  Src0->getSubReg() != Src1->getSubReg() ||
744  Src0->getSubReg() != AMDGPU::NoSubRegister)
745  return nullptr;
746 
747  // Can't fold up if we have modifiers.
748  if (TII->hasModifiersSet(MI, AMDGPU::OpName::omod))
749  return nullptr;
750 
751  unsigned Src0Mods
752  = TII->getNamedOperand(MI, AMDGPU::OpName::src0_modifiers)->getImm();
753  unsigned Src1Mods
754  = TII->getNamedOperand(MI, AMDGPU::OpName::src1_modifiers)->getImm();
755 
756  // Having a 0 op_sel_hi would require swizzling the output in the source
757  // instruction, which we can't do.
758  unsigned UnsetMods = (Op == AMDGPU::V_PK_MAX_F16) ? SISrcMods::OP_SEL_1 : 0;
759  if (Src0Mods != UnsetMods && Src1Mods != UnsetMods)
760  return nullptr;
761  return Src0;
762  }
763  default:
764  return nullptr;
765  }
766 }
767 
768 // We obviously have multiple uses in a clamp since the register is used twice
769 // in the same instruction.
770 static bool hasOneNonDBGUseInst(const MachineRegisterInfo &MRI, unsigned Reg) {
771  int Count = 0;
772  for (auto I = MRI.use_instr_nodbg_begin(Reg), E = MRI.use_instr_nodbg_end();
773  I != E; ++I) {
774  if (++Count > 1)
775  return false;
776  }
777 
778  return true;
779 }
780 
781 // FIXME: Clamp for v_mad_mixhi_f16 handled during isel.
782 bool SIFoldOperands::tryFoldClamp(MachineInstr &MI) {
783  const MachineOperand *ClampSrc = isClamp(MI);
784  if (!ClampSrc || !hasOneNonDBGUseInst(*MRI, ClampSrc->getReg()))
785  return false;
786 
787  MachineInstr *Def = MRI->getVRegDef(ClampSrc->getReg());
788 
789  // The type of clamp must be compatible.
790  if (TII->getClampMask(*Def) != TII->getClampMask(MI))
791  return false;
792 
793  MachineOperand *DefClamp = TII->getNamedOperand(*Def, AMDGPU::OpName::clamp);
794  if (!DefClamp)
795  return false;
796 
797  DEBUG(dbgs() << "Folding clamp " << *DefClamp << " into " << *Def << '\n');
798 
799  // Clamp is applied after omod, so it is OK if omod is set.
800  DefClamp->setImm(1);
801  MRI->replaceRegWith(MI.getOperand(0).getReg(), Def->getOperand(0).getReg());
802  MI.eraseFromParent();
803  return true;
804 }
805 
806 static int getOModValue(unsigned Opc, int64_t Val) {
807  switch (Opc) {
808  case AMDGPU::V_MUL_F32_e64: {
809  switch (static_cast<uint32_t>(Val)) {
810  case 0x3f000000: // 0.5
811  return SIOutMods::DIV2;
812  case 0x40000000: // 2.0
813  return SIOutMods::MUL2;
814  case 0x40800000: // 4.0
815  return SIOutMods::MUL4;
816  default:
817  return SIOutMods::NONE;
818  }
819  }
820  case AMDGPU::V_MUL_F16_e64: {
821  switch (static_cast<uint16_t>(Val)) {
822  case 0x3800: // 0.5
823  return SIOutMods::DIV2;
824  case 0x4000: // 2.0
825  return SIOutMods::MUL2;
826  case 0x4400: // 4.0
827  return SIOutMods::MUL4;
828  default:
829  return SIOutMods::NONE;
830  }
831  }
832  default:
833  llvm_unreachable("invalid mul opcode");
834  }
835 }
836 
837 // FIXME: Does this really not support denormals with f16?
838 // FIXME: Does this need to check IEEE mode bit? SNaNs are generally not
839 // handled, so will anything other than that break?
840 std::pair<const MachineOperand *, int>
841 SIFoldOperands::isOMod(const MachineInstr &MI) const {
842  unsigned Op = MI.getOpcode();
843  switch (Op) {
844  case AMDGPU::V_MUL_F32_e64:
845  case AMDGPU::V_MUL_F16_e64: {
846  // If output denormals are enabled, omod is ignored.
847  if ((Op == AMDGPU::V_MUL_F32_e64 && ST->hasFP32Denormals()) ||
848  (Op == AMDGPU::V_MUL_F16_e64 && ST->hasFP16Denormals()))
849  return std::make_pair(nullptr, SIOutMods::NONE);
850 
851  const MachineOperand *RegOp = nullptr;
852  const MachineOperand *ImmOp = nullptr;
853  const MachineOperand *Src0 = TII->getNamedOperand(MI, AMDGPU::OpName::src0);
854  const MachineOperand *Src1 = TII->getNamedOperand(MI, AMDGPU::OpName::src1);
855  if (Src0->isImm()) {
856  ImmOp = Src0;
857  RegOp = Src1;
858  } else if (Src1->isImm()) {
859  ImmOp = Src1;
860  RegOp = Src0;
861  } else
862  return std::make_pair(nullptr, SIOutMods::NONE);
863 
864  int OMod = getOModValue(Op, ImmOp->getImm());
865  if (OMod == SIOutMods::NONE ||
866  TII->hasModifiersSet(MI, AMDGPU::OpName::src0_modifiers) ||
867  TII->hasModifiersSet(MI, AMDGPU::OpName::src1_modifiers) ||
868  TII->hasModifiersSet(MI, AMDGPU::OpName::omod) ||
869  TII->hasModifiersSet(MI, AMDGPU::OpName::clamp))
870  return std::make_pair(nullptr, SIOutMods::NONE);
871 
872  return std::make_pair(RegOp, OMod);
873  }
874  case AMDGPU::V_ADD_F32_e64:
875  case AMDGPU::V_ADD_F16_e64: {
876  // If output denormals are enabled, omod is ignored.
877  if ((Op == AMDGPU::V_ADD_F32_e64 && ST->hasFP32Denormals()) ||
878  (Op == AMDGPU::V_ADD_F16_e64 && ST->hasFP16Denormals()))
879  return std::make_pair(nullptr, SIOutMods::NONE);
880 
881  // Look through the DAGCombiner canonicalization fmul x, 2 -> fadd x, x
882  const MachineOperand *Src0 = TII->getNamedOperand(MI, AMDGPU::OpName::src0);
883  const MachineOperand *Src1 = TII->getNamedOperand(MI, AMDGPU::OpName::src1);
884 
885  if (Src0->isReg() && Src1->isReg() && Src0->getReg() == Src1->getReg() &&
886  Src0->getSubReg() == Src1->getSubReg() &&
887  !TII->hasModifiersSet(MI, AMDGPU::OpName::src0_modifiers) &&
888  !TII->hasModifiersSet(MI, AMDGPU::OpName::src1_modifiers) &&
889  !TII->hasModifiersSet(MI, AMDGPU::OpName::clamp) &&
890  !TII->hasModifiersSet(MI, AMDGPU::OpName::omod))
891  return std::make_pair(Src0, SIOutMods::MUL2);
892 
893  return std::make_pair(nullptr, SIOutMods::NONE);
894  }
895  default:
896  return std::make_pair(nullptr, SIOutMods::NONE);
897  }
898 }
899 
900 // FIXME: Does this need to check IEEE bit on function?
901 bool SIFoldOperands::tryFoldOMod(MachineInstr &MI) {
902  const MachineOperand *RegOp;
903  int OMod;
904  std::tie(RegOp, OMod) = isOMod(MI);
905  if (OMod == SIOutMods::NONE || !RegOp->isReg() ||
906  RegOp->getSubReg() != AMDGPU::NoSubRegister ||
907  !hasOneNonDBGUseInst(*MRI, RegOp->getReg()))
908  return false;
909 
910  MachineInstr *Def = MRI->getVRegDef(RegOp->getReg());
911  MachineOperand *DefOMod = TII->getNamedOperand(*Def, AMDGPU::OpName::omod);
912  if (!DefOMod || DefOMod->getImm() != SIOutMods::NONE)
913  return false;
914 
915  // Clamp is applied after omod. If the source already has clamp set, don't
916  // fold it.
917  if (TII->hasModifiersSet(*Def, AMDGPU::OpName::clamp))
918  return false;
919 
920  DEBUG(dbgs() << "Folding omod " << MI << " into " << *Def << '\n');
921 
922  DefOMod->setImm(OMod);
923  MRI->replaceRegWith(MI.getOperand(0).getReg(), Def->getOperand(0).getReg());
924  MI.eraseFromParent();
925  return true;
926 }
927 
928 bool SIFoldOperands::runOnMachineFunction(MachineFunction &MF) {
929  if (skipFunction(*MF.getFunction()))
930  return false;
931 
932  MRI = &MF.getRegInfo();
933  ST = &MF.getSubtarget<SISubtarget>();
934  TII = ST->getInstrInfo();
935  TRI = &TII->getRegisterInfo();
936 
938 
939  // omod is ignored by hardware if IEEE bit is enabled. omod also does not
940  // correctly handle signed zeros.
941  //
942  // TODO: Check nsz on instructions when fast math flags are preserved to MI
943  // level.
944  bool IsIEEEMode = ST->enableIEEEBit(MF) || !MFI->hasNoSignedZerosFPMath();
945 
946  for (MachineBasicBlock *MBB : depth_first(&MF)) {
948  for (I = MBB->begin(); I != MBB->end(); I = Next) {
949  Next = std::next(I);
950  MachineInstr &MI = *I;
951 
952  tryFoldInst(TII, &MI);
953 
954  if (!TII->isFoldableCopy(MI)) {
955  if (IsIEEEMode || !tryFoldOMod(MI))
956  tryFoldClamp(MI);
957  continue;
958  }
959 
960  MachineOperand &OpToFold = MI.getOperand(1);
961  bool FoldingImm = OpToFold.isImm() || OpToFold.isFI();
962 
963  // FIXME: We could also be folding things like TargetIndexes.
964  if (!FoldingImm && !OpToFold.isReg())
965  continue;
966 
967  if (OpToFold.isReg() &&
969  continue;
970 
971  // Prevent folding operands backwards in the function. For example,
972  // the COPY opcode must not be replaced by 1 in this example:
973  //
974  // %vreg3<def> = COPY %VGPR0; VGPR_32:%vreg3
975  // ...
976  // %VGPR0<def> = V_MOV_B32_e32 1, %EXEC<imp-use>
977  MachineOperand &Dst = MI.getOperand(0);
978  if (Dst.isReg() &&
980  continue;
981 
982  foldInstOperand(MI, OpToFold);
983  }
984  }
985  return false;
986 }
static bool isReg(const MCInst &MI, unsigned OpNo)
unsigned getNumImplicitUses() const
Return the number of implicit uses this instruction has.
Definition: MCInstrDesc.h:515
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AMDGPU specific subclass of TargetSubtarget.
unsigned getNumImplicitDefs() const
Return the number of implicit defs this instruct has.
Definition: MCInstrDesc.h:537
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
static bool isUseMIInFoldList(ArrayRef< FoldCandidate > FoldList, const MachineInstr *MI)
bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx, const MachineOperand *MO=nullptr) const
Check if MO is a legal operand if it was the OpIdx Operand for MI.
static bool isUseSafeToFold(const SIInstrInfo *TII, const MachineInstr &MI, const MachineOperand &UseMO)
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
unsigned getReg() const
getReg - Returns the register number.
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
Definition: MachineInstr.h:384
void setIsUndef(bool Val=true)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned getSubReg() const
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
bool isRegSequence() const
Definition: MachineInstr.h:849
void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo &)
substVirtReg - Substitute the current register with the virtual subregister Reg:SubReg.
bool isInlineConstant(const APInt &Imm) const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const SIRegisterInfo & getRegisterInfo() const
Definition: SIInstrInfo.h:146
bool isMoveImmediate(QueryType Type=IgnoreBundle) const
Return true if this instruction is a move immediate (including conditional moves) instruction...
Definition: MachineInstr.h:525
static unsigned getMovOpc(bool IsScalar)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
Definition: APInt.cpp:515
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:210
const HexagonInstrInfo * TII
bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:293
static bool hasOneNonDBGUseInst(const MachineRegisterInfo &MRI, unsigned Reg)
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
static bool tryAddToFoldList(SmallVectorImpl< FoldCandidate > &FoldList, MachineInstr *MI, unsigned OpNo, MachineOperand *OpToFold, const SIInstrInfo *TII)
static bool updateOperand(FoldCandidate &Fold, const TargetRegisterInfo &TRI)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
static MachineOperand * getImmOrMaterializedImm(MachineRegisterInfo &MRI, MachineOperand &Op)
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:290
unsigned getID() const
Return the register class ID number.
static int getOModValue(unsigned Opc, int64_t Val)
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:82
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:287
LLVM_READONLY MachineOperand * getNamedOperand(MachineInstr &MI, unsigned OperandName) const
Returns the operand named Op.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
void untieRegOperand(unsigned OpIdx)
Break any tie involving OpIdx.
unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition: Use.cpp:48
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static const unsigned CommuteAnyOperandIndex
unsigned const MachineRegisterInfo * MRI
static void mutateCopyOp(MachineInstr &MI, const MCInstrDesc &NewDesc)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool isVariadic() const
Return true if this instruction can have a variable number of operands.
Definition: MCInstrDesc.h:234
MachineInstrBuilder & UseMI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
bool isCopy() const
Definition: MachineInstr.h:857
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define DEBUG_TYPE
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:34
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
const SIRegisterInfo * getRegisterInfo() const override
MachineOperand class - Representation of each machine instruction operand.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:285
static bool tryFoldInst(const SIInstrInfo *TII, MachineInstr *MI)
int64_t getImm() const
static void stripExtraCopyOperands(MachineInstr &MI)
Remove any leftover implicit operands from mutating the instruction.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:923
Class for arbitrary precision integers.
Definition: APInt.h:69
static bool evalBinaryInstruction(unsigned Opcode, int32_t &Result, uint32_t LHS, uint32_t RHS)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:139
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:59
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void initializeSIFoldOperandsPass(PassRegistry &)
char & SIFoldOperandsID
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:76
FunctionPass * createSIFoldOperandsPass()
static unsigned UseReg(const MachineOperand &MO)
static MachineOperand CreateImm(int64_t Val)
#define I(x, y, z)
Definition: MD5.cpp:58
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
static bool isInlineConstantIfFolded(const SIInstrInfo *TII, const MachineInstr &UseMI, unsigned OpNo, const MachineOperand &OpToFold)
Abstract Stack Frame Index.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< df_iterator< T > > depth_first(const T &G)
const unsigned Kind
static use_instr_nodbg_iterator use_instr_nodbg_end()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
use_instr_nodbg_iterator use_instr_nodbg_begin(unsigned RegNo) const
static bool isSDWA(const MachineInstr &MI)
Definition: SIInstrInfo.h:379
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:174
void ChangeToFrameIndex(int Idx)
Replace this operand with a frame index.
#define DEBUG(X)
Definition: Debug.h:118
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static bool tryConstantFoldOp(MachineRegisterInfo &MRI, const SIInstrInfo *TII, MachineInstr *MI, MachineOperand *ImmOp)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:295
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
bool isCommutable(QueryType Type=IgnoreBundle) const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z, ..."), which produces the same result if Y and Z are exchanged.
Definition: MachineInstr.h:667
bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool isImplicit() const