1f9448bf3SDimitry Andric //===- lib/CodeGen/MachineInstr.cpp ---------------------------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // Methods common to all machine instructions.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14db17bf38SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
15f9448bf3SDimitry Andric #include "llvm/ADT/APFloat.h"
16f9448bf3SDimitry Andric #include "llvm/ADT/ArrayRef.h"
17139f7f9bSDimitry Andric #include "llvm/ADT/FoldingSet.h"
18139f7f9bSDimitry Andric #include "llvm/ADT/Hashing.h"
19f9448bf3SDimitry Andric #include "llvm/ADT/None.h"
20db17bf38SDimitry Andric #include "llvm/ADT/STLExtras.h"
212cab237bSDimitry Andric #include "llvm/ADT/SmallBitVector.h"
22f9448bf3SDimitry Andric #include "llvm/ADT/SmallString.h"
23f9448bf3SDimitry Andric #include "llvm/ADT/SmallVector.h"
24139f7f9bSDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
25edd7eaddSDimitry Andric #include "llvm/Analysis/Loads.h"
26f9448bf3SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
27f9448bf3SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
28f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
29f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h"
303ca95b02SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
31f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
32f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineMemOperand.h"
3317a519f9SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
34f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
35f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h"
36f22ef01cSRoman Divacky #include "llvm/CodeGen/PseudoSourceValue.h"
372cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
382cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
392cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
404ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
41139f7f9bSDimitry Andric #include "llvm/IR/Constants.h"
42f9448bf3SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
43f9448bf3SDimitry Andric #include "llvm/IR/DebugLoc.h"
44f9448bf3SDimitry Andric #include "llvm/IR/DerivedTypes.h"
45139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
46139f7f9bSDimitry Andric #include "llvm/IR/InlineAsm.h"
47f9448bf3SDimitry Andric #include "llvm/IR/InstrTypes.h"
48d88c1a5aSDimitry Andric #include "llvm/IR/Intrinsics.h"
49139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h"
50139f7f9bSDimitry Andric #include "llvm/IR/Metadata.h"
51139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
523dac3a9bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
53139f7f9bSDimitry Andric #include "llvm/IR/Type.h"
54139f7f9bSDimitry Andric #include "llvm/IR/Value.h"
55*b5893f02SDimitry Andric #include "llvm/IR/Operator.h"
5617a519f9SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
57f9448bf3SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
58db17bf38SDimitry Andric #include "llvm/MC/MCSymbol.h"
59f9448bf3SDimitry Andric #include "llvm/Support/Casting.h"
607d523365SDimitry Andric #include "llvm/Support/CommandLine.h"
61f9448bf3SDimitry Andric #include "llvm/Support/Compiler.h"
62f22ef01cSRoman Divacky #include "llvm/Support/Debug.h"
63f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
64f9448bf3SDimitry Andric #include "llvm/Support/LowLevelTypeImpl.h"
65f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h"
66f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h"
67d88c1a5aSDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
68139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
69f9448bf3SDimitry Andric #include <algorithm>
70f9448bf3SDimitry Andric #include <cassert>
71f9448bf3SDimitry Andric #include <cstddef>
72f9448bf3SDimitry Andric #include <cstdint>
73f9448bf3SDimitry Andric #include <cstring>
74f9448bf3SDimitry Andric #include <iterator>
75f9448bf3SDimitry Andric #include <utility>
76f9448bf3SDimitry Andric 
77f22ef01cSRoman Divacky using namespace llvm;
78f22ef01cSRoman Divacky 
getMFIfAvailable(const MachineInstr & MI)794ba319b5SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineInstr &MI) {
804ba319b5SDimitry Andric   if (const MachineBasicBlock *MBB = MI.getParent())
814ba319b5SDimitry Andric     if (const MachineFunction *MF = MBB->getParent())
824ba319b5SDimitry Andric       return MF;
834ba319b5SDimitry Andric   return nullptr;
844ba319b5SDimitry Andric }
854ba319b5SDimitry Andric 
864ba319b5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
874ba319b5SDimitry Andric // it.
tryToGetTargetInfo(const MachineInstr & MI,const TargetRegisterInfo * & TRI,const MachineRegisterInfo * & MRI,const TargetIntrinsicInfo * & IntrinsicInfo,const TargetInstrInfo * & TII)884ba319b5SDimitry Andric static void tryToGetTargetInfo(const MachineInstr &MI,
894ba319b5SDimitry Andric                                const TargetRegisterInfo *&TRI,
904ba319b5SDimitry Andric                                const MachineRegisterInfo *&MRI,
914ba319b5SDimitry Andric                                const TargetIntrinsicInfo *&IntrinsicInfo,
924ba319b5SDimitry Andric                                const TargetInstrInfo *&TII) {
934ba319b5SDimitry Andric 
944ba319b5SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(MI)) {
954ba319b5SDimitry Andric     TRI = MF->getSubtarget().getRegisterInfo();
964ba319b5SDimitry Andric     MRI = &MF->getRegInfo();
974ba319b5SDimitry Andric     IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
984ba319b5SDimitry Andric     TII = MF->getSubtarget().getInstrInfo();
994ba319b5SDimitry Andric   }
1004ba319b5SDimitry Andric }
1014ba319b5SDimitry Andric 
addImplicitDefUseOperands(MachineFunction & MF)102139f7f9bSDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {
10317a519f9SDimitry Andric   if (MCID->ImplicitDefs)
1047d523365SDimitry Andric     for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs;
1057d523365SDimitry Andric            ++ImpDefs)
106139f7f9bSDimitry Andric       addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true));
10717a519f9SDimitry Andric   if (MCID->ImplicitUses)
1087d523365SDimitry Andric     for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses;
1097d523365SDimitry Andric            ++ImpUses)
110139f7f9bSDimitry Andric       addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true));
111f22ef01cSRoman Divacky }
112f22ef01cSRoman Divacky 
113f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the
114f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by
11517a519f9SDimitry Andric /// the MCInstrDesc.
MachineInstr(MachineFunction & MF,const MCInstrDesc & tid,DebugLoc dl,bool NoImp)116139f7f9bSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
117ff0cc061SDimitry Andric                            DebugLoc dl, bool NoImp)
118f9448bf3SDimitry Andric     : MCID(&tid), debugLoc(std::move(dl)) {
11939d628a0SDimitry Andric   assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
12039d628a0SDimitry Andric 
121139f7f9bSDimitry Andric   // Reserve space for the expected number of operands.
122139f7f9bSDimitry Andric   if (unsigned NumOps = MCID->getNumOperands() +
123139f7f9bSDimitry Andric     MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) {
124139f7f9bSDimitry Andric     CapOperands = OperandCapacity::get(NumOps);
125139f7f9bSDimitry Andric     Operands = MF.allocateOperandArray(CapOperands);
126f22ef01cSRoman Divacky   }
127f22ef01cSRoman Divacky 
128139f7f9bSDimitry Andric   if (!NoImp)
129139f7f9bSDimitry Andric     addImplicitDefUseOperands(MF);
130f22ef01cSRoman Divacky }
131f22ef01cSRoman Divacky 
132f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly
133f22ef01cSRoman Divacky ///
MachineInstr(MachineFunction & MF,const MachineInstr & MI)134f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
135*b5893f02SDimitry Andric     : MCID(&MI.getDesc()), Info(MI.Info), debugLoc(MI.getDebugLoc()) {
13639d628a0SDimitry Andric   assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
13739d628a0SDimitry Andric 
138139f7f9bSDimitry Andric   CapOperands = OperandCapacity::get(MI.getNumOperands());
139139f7f9bSDimitry Andric   Operands = MF.allocateOperandArray(CapOperands);
140f22ef01cSRoman Divacky 
141139f7f9bSDimitry Andric   // Copy operands.
142ff0cc061SDimitry Andric   for (const MachineOperand &MO : MI.operands())
143ff0cc061SDimitry Andric     addOperand(MF, MO);
144f22ef01cSRoman Divacky 
145139f7f9bSDimitry Andric   // Copy all the sensible flags.
146139f7f9bSDimitry Andric   setFlags(MI.Flags);
147f22ef01cSRoman Divacky }
148f22ef01cSRoman Divacky 
149f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction,
150f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise
151f22ef01cSRoman Divacky /// return null.
getRegInfo()152f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() {
153f22ef01cSRoman Divacky   if (MachineBasicBlock *MBB = getParent())
154f22ef01cSRoman Divacky     return &MBB->getParent()->getRegInfo();
15591bc56edSDimitry Andric   return nullptr;
156f22ef01cSRoman Divacky }
157f22ef01cSRoman Divacky 
158f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
159f22ef01cSRoman Divacky /// this instruction from their respective use lists.  This requires that the
160f22ef01cSRoman Divacky /// operands already be on their use lists.
RemoveRegOperandsFromUseLists(MachineRegisterInfo & MRI)1617ae0e2c9SDimitry Andric void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) {
162ff0cc061SDimitry Andric   for (MachineOperand &MO : operands())
163ff0cc061SDimitry Andric     if (MO.isReg())
164ff0cc061SDimitry Andric       MRI.removeRegOperandFromUseList(&MO);
165f22ef01cSRoman Divacky }
166f22ef01cSRoman Divacky 
167f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in
168f22ef01cSRoman Divacky /// this instruction from their respective use lists.  This requires that the
169f22ef01cSRoman Divacky /// operands not be on their use lists yet.
AddRegOperandsToUseLists(MachineRegisterInfo & MRI)1707ae0e2c9SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) {
171ff0cc061SDimitry Andric   for (MachineOperand &MO : operands())
172ff0cc061SDimitry Andric     if (MO.isReg())
173ff0cc061SDimitry Andric       MRI.addRegOperandToUseList(&MO);
174f22ef01cSRoman Divacky }
175f22ef01cSRoman Divacky 
addOperand(const MachineOperand & Op)176139f7f9bSDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) {
177139f7f9bSDimitry Andric   MachineBasicBlock *MBB = getParent();
178139f7f9bSDimitry Andric   assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs");
179139f7f9bSDimitry Andric   MachineFunction *MF = MBB->getParent();
180139f7f9bSDimitry Andric   assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs");
181139f7f9bSDimitry Andric   addOperand(*MF, Op);
182139f7f9bSDimitry Andric }
183139f7f9bSDimitry Andric 
184139f7f9bSDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping
185139f7f9bSDimitry Andric /// ranges. If MRI is non-null also update use-def chains.
moveOperands(MachineOperand * Dst,MachineOperand * Src,unsigned NumOps,MachineRegisterInfo * MRI)186139f7f9bSDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src,
187139f7f9bSDimitry Andric                          unsigned NumOps, MachineRegisterInfo *MRI) {
188139f7f9bSDimitry Andric   if (MRI)
189139f7f9bSDimitry Andric     return MRI->moveOperands(Dst, Src, NumOps);
190139f7f9bSDimitry Andric 
191ff0cc061SDimitry Andric   // MachineOperand is a trivially copyable type so we can just use memmove.
192ff0cc061SDimitry Andric   std::memmove(Dst, Src, NumOps * sizeof(MachineOperand));
193139f7f9bSDimitry Andric }
194139f7f9bSDimitry Andric 
195f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction.  If it is an
196f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list.  If it is
197f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list
198f22ef01cSRoman Divacky /// (before the first implicit operand).
addOperand(MachineFunction & MF,const MachineOperand & Op)199139f7f9bSDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
2006122f3e6SDimitry Andric   assert(MCID && "Cannot add operands before providing an instr descriptor");
201f22ef01cSRoman Divacky 
202139f7f9bSDimitry Andric   // Check if we're adding one of our existing operands.
203139f7f9bSDimitry Andric   if (&Op >= Operands && &Op < Operands + NumOperands) {
204139f7f9bSDimitry Andric     // This is unusual: MI->addOperand(MI->getOperand(i)).
205139f7f9bSDimitry Andric     // If adding Op requires reallocating or moving existing operands around,
206139f7f9bSDimitry Andric     // the Op reference could go stale. Support it by copying Op.
207139f7f9bSDimitry Andric     MachineOperand CopyOp(Op);
208139f7f9bSDimitry Andric     return addOperand(MF, CopyOp);
209139f7f9bSDimitry Andric   }
210f22ef01cSRoman Divacky 
2116122f3e6SDimitry Andric   // Find the insert location for the new operand.  Implicit registers go at
212139f7f9bSDimitry Andric   // the end, everything else goes before the implicit regs.
213139f7f9bSDimitry Andric   //
2146122f3e6SDimitry Andric   // FIXME: Allow mixed explicit and implicit operands on inline asm.
2156122f3e6SDimitry Andric   // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as
2166122f3e6SDimitry Andric   // implicit-defs, but they must not be moved around.  See the FIXME in
2176122f3e6SDimitry Andric   // InstrEmitter.cpp.
218139f7f9bSDimitry Andric   unsigned OpNo = getNumOperands();
219139f7f9bSDimitry Andric   bool isImpReg = Op.isReg() && Op.isImplicit();
2206122f3e6SDimitry Andric   if (!isImpReg && !isInlineAsm()) {
2216122f3e6SDimitry Andric     while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) {
2226122f3e6SDimitry Andric       --OpNo;
2233861d79fSDimitry Andric       assert(!Operands[OpNo].isTied() && "Cannot move tied operands");
224f22ef01cSRoman Divacky     }
225f22ef01cSRoman Divacky   }
226f22ef01cSRoman Divacky 
227f785676fSDimitry Andric #ifndef NDEBUG
228*b5893f02SDimitry Andric   bool isDebugOp = Op.getType() == MachineOperand::MO_Metadata ||
229*b5893f02SDimitry Andric                    Op.getType() == MachineOperand::MO_MCSymbol;
2306122f3e6SDimitry Andric   // OpNo now points as the desired insertion point.  Unless this is a variadic
2316122f3e6SDimitry Andric   // instruction, only implicit regs are allowed beyond MCID->getNumOperands().
2327ae0e2c9SDimitry Andric   // RegMask operands go between the explicit and implicit operands.
2337ae0e2c9SDimitry Andric   assert((isImpReg || Op.isRegMask() || MCID->isVariadic() ||
234*b5893f02SDimitry Andric           OpNo < MCID->getNumOperands() || isDebugOp) &&
2356122f3e6SDimitry Andric          "Trying to add an operand to a machine instr that is already done!");
236f785676fSDimitry Andric #endif
237f22ef01cSRoman Divacky 
238139f7f9bSDimitry Andric   MachineRegisterInfo *MRI = getRegInfo();
239f22ef01cSRoman Divacky 
240139f7f9bSDimitry Andric   // Determine if the Operands array needs to be reallocated.
241139f7f9bSDimitry Andric   // Save the old capacity and operand array.
242139f7f9bSDimitry Andric   OperandCapacity OldCap = CapOperands;
243139f7f9bSDimitry Andric   MachineOperand *OldOperands = Operands;
244139f7f9bSDimitry Andric   if (!OldOperands || OldCap.getSize() == getNumOperands()) {
245139f7f9bSDimitry Andric     CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1);
246139f7f9bSDimitry Andric     Operands = MF.allocateOperandArray(CapOperands);
247139f7f9bSDimitry Andric     // Move the operands before the insertion point.
248139f7f9bSDimitry Andric     if (OpNo)
249139f7f9bSDimitry Andric       moveOperands(Operands, OldOperands, OpNo, MRI);
250139f7f9bSDimitry Andric   }
251f22ef01cSRoman Divacky 
252139f7f9bSDimitry Andric   // Move the operands following the insertion point.
253139f7f9bSDimitry Andric   if (OpNo != NumOperands)
254139f7f9bSDimitry Andric     moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo,
255139f7f9bSDimitry Andric                  MRI);
256139f7f9bSDimitry Andric   ++NumOperands;
2576122f3e6SDimitry Andric 
258139f7f9bSDimitry Andric   // Deallocate the old operand array.
259139f7f9bSDimitry Andric   if (OldOperands != Operands && OldOperands)
260139f7f9bSDimitry Andric     MF.deallocateOperandArray(OldCap, OldOperands);
261139f7f9bSDimitry Andric 
262139f7f9bSDimitry Andric   // Copy Op into place. It still needs to be inserted into the MRI use lists.
263139f7f9bSDimitry Andric   MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op);
264139f7f9bSDimitry Andric   NewMO->ParentMI = this;
265139f7f9bSDimitry Andric 
266139f7f9bSDimitry Andric   // When adding a register operand, tell MRI about it.
267139f7f9bSDimitry Andric   if (NewMO->isReg()) {
2687ae0e2c9SDimitry Andric     // Ensure isOnRegUseList() returns false, regardless of Op's status.
26991bc56edSDimitry Andric     NewMO->Contents.Reg.Prev = nullptr;
2703861d79fSDimitry Andric     // Ignore existing ties. This is not a property that can be copied.
271139f7f9bSDimitry Andric     NewMO->TiedTo = 0;
272139f7f9bSDimitry Andric     // Add the new operand to MRI, but only for instructions in an MBB.
273139f7f9bSDimitry Andric     if (MRI)
274139f7f9bSDimitry Andric       MRI->addRegOperandToUseList(NewMO);
2753861d79fSDimitry Andric     // The MCID operand information isn't accurate until we start adding
2763861d79fSDimitry Andric     // explicit operands. The implicit operands are added first, then the
2773861d79fSDimitry Andric     // explicits are inserted before them.
2783861d79fSDimitry Andric     if (!isImpReg) {
2793861d79fSDimitry Andric       // Tie uses to defs as indicated in MCInstrDesc.
280139f7f9bSDimitry Andric       if (NewMO->isUse()) {
2813861d79fSDimitry Andric         int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO);
2823861d79fSDimitry Andric         if (DefIdx != -1)
2833861d79fSDimitry Andric           tieOperands(DefIdx, OpNo);
2843861d79fSDimitry Andric       }
2856122f3e6SDimitry Andric       // If the register operand is flagged as early, mark the operand as such.
28617a519f9SDimitry Andric       if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)
287139f7f9bSDimitry Andric         NewMO->setIsEarlyClobber(true);
288f22ef01cSRoman Divacky     }
289f22ef01cSRoman Divacky   }
290f22ef01cSRoman Divacky }
291f22ef01cSRoman Divacky 
292f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
293f22ef01cSRoman Divacky /// fewer operand than it started with.
294f22ef01cSRoman Divacky ///
RemoveOperand(unsigned OpNo)295f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) {
296139f7f9bSDimitry Andric   assert(OpNo < getNumOperands() && "Invalid operand number");
2973861d79fSDimitry Andric   untieRegOperand(OpNo);
298f22ef01cSRoman Divacky 
2993861d79fSDimitry Andric #ifndef NDEBUG
3003861d79fSDimitry Andric   // Moving tied operands would break the ties.
301139f7f9bSDimitry Andric   for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i)
3023861d79fSDimitry Andric     if (Operands[i].isReg())
3033861d79fSDimitry Andric       assert(!Operands[i].isTied() && "Cannot move tied operands");
3043861d79fSDimitry Andric #endif
3053861d79fSDimitry Andric 
306139f7f9bSDimitry Andric   MachineRegisterInfo *MRI = getRegInfo();
307139f7f9bSDimitry Andric   if (MRI && Operands[OpNo].isReg())
308139f7f9bSDimitry Andric     MRI->removeRegOperandFromUseList(Operands + OpNo);
309f22ef01cSRoman Divacky 
310139f7f9bSDimitry Andric   // Don't call the MachineOperand destructor. A lot of this code depends on
311139f7f9bSDimitry Andric   // MachineOperand having a trivial destructor anyway, and adding a call here
312139f7f9bSDimitry Andric   // wouldn't make it 'destructor-correct'.
313139f7f9bSDimitry Andric 
314139f7f9bSDimitry Andric   if (unsigned N = NumOperands - 1 - OpNo)
315139f7f9bSDimitry Andric     moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI);
316139f7f9bSDimitry Andric   --NumOperands;
317f22ef01cSRoman Divacky }
318f22ef01cSRoman Divacky 
dropMemRefs(MachineFunction & MF)319*b5893f02SDimitry Andric void MachineInstr::dropMemRefs(MachineFunction &MF) {
320*b5893f02SDimitry Andric   if (memoperands_empty())
321*b5893f02SDimitry Andric     return;
322*b5893f02SDimitry Andric 
323*b5893f02SDimitry Andric   // See if we can just drop all of our extra info.
324*b5893f02SDimitry Andric   if (!getPreInstrSymbol() && !getPostInstrSymbol()) {
325*b5893f02SDimitry Andric     Info.clear();
326*b5893f02SDimitry Andric     return;
327*b5893f02SDimitry Andric   }
328*b5893f02SDimitry Andric   if (!getPostInstrSymbol()) {
329*b5893f02SDimitry Andric     Info.set<EIIK_PreInstrSymbol>(getPreInstrSymbol());
330*b5893f02SDimitry Andric     return;
331*b5893f02SDimitry Andric   }
332*b5893f02SDimitry Andric   if (!getPreInstrSymbol()) {
333*b5893f02SDimitry Andric     Info.set<EIIK_PostInstrSymbol>(getPostInstrSymbol());
334*b5893f02SDimitry Andric     return;
335*b5893f02SDimitry Andric   }
336*b5893f02SDimitry Andric 
337*b5893f02SDimitry Andric   // Otherwise allocate a fresh extra info with just these symbols.
338*b5893f02SDimitry Andric   Info.set<EIIK_OutOfLine>(
339*b5893f02SDimitry Andric       MF.createMIExtraInfo({}, getPreInstrSymbol(), getPostInstrSymbol()));
340*b5893f02SDimitry Andric }
341*b5893f02SDimitry Andric 
setMemRefs(MachineFunction & MF,ArrayRef<MachineMemOperand * > MMOs)342*b5893f02SDimitry Andric void MachineInstr::setMemRefs(MachineFunction &MF,
343*b5893f02SDimitry Andric                               ArrayRef<MachineMemOperand *> MMOs) {
344*b5893f02SDimitry Andric   if (MMOs.empty()) {
345*b5893f02SDimitry Andric     dropMemRefs(MF);
346*b5893f02SDimitry Andric     return;
347*b5893f02SDimitry Andric   }
348*b5893f02SDimitry Andric 
349*b5893f02SDimitry Andric   // Try to store a single MMO inline.
350*b5893f02SDimitry Andric   if (MMOs.size() == 1 && !getPreInstrSymbol() && !getPostInstrSymbol()) {
351*b5893f02SDimitry Andric     Info.set<EIIK_MMO>(MMOs[0]);
352*b5893f02SDimitry Andric     return;
353*b5893f02SDimitry Andric   }
354*b5893f02SDimitry Andric 
355*b5893f02SDimitry Andric   // Otherwise create an extra info struct with all of our info.
356*b5893f02SDimitry Andric   Info.set<EIIK_OutOfLine>(
357*b5893f02SDimitry Andric       MF.createMIExtraInfo(MMOs, getPreInstrSymbol(), getPostInstrSymbol()));
358*b5893f02SDimitry Andric }
359*b5893f02SDimitry Andric 
addMemOperand(MachineFunction & MF,MachineMemOperand * MO)360f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF,
361f22ef01cSRoman Divacky                                  MachineMemOperand *MO) {
362*b5893f02SDimitry Andric   SmallVector<MachineMemOperand *, 2> MMOs;
363*b5893f02SDimitry Andric   MMOs.append(memoperands_begin(), memoperands_end());
364*b5893f02SDimitry Andric   MMOs.push_back(MO);
365*b5893f02SDimitry Andric   setMemRefs(MF, MMOs);
366*b5893f02SDimitry Andric }
367f22ef01cSRoman Divacky 
cloneMemRefs(MachineFunction & MF,const MachineInstr & MI)368*b5893f02SDimitry Andric void MachineInstr::cloneMemRefs(MachineFunction &MF, const MachineInstr &MI) {
369*b5893f02SDimitry Andric   if (this == &MI)
370*b5893f02SDimitry Andric     // Nothing to do for a self-clone!
371*b5893f02SDimitry Andric     return;
372f22ef01cSRoman Divacky 
373*b5893f02SDimitry Andric   assert(&MF == MI.getMF() &&
374*b5893f02SDimitry Andric          "Invalid machine functions when cloning memory refrences!");
375*b5893f02SDimitry Andric   // See if we can just steal the extra info already allocated for the
376*b5893f02SDimitry Andric   // instruction. We can do this whenever the pre- and post-instruction symbols
377*b5893f02SDimitry Andric   // are the same (including null).
378*b5893f02SDimitry Andric   if (getPreInstrSymbol() == MI.getPreInstrSymbol() &&
379*b5893f02SDimitry Andric       getPostInstrSymbol() == MI.getPostInstrSymbol()) {
380*b5893f02SDimitry Andric     Info = MI.Info;
381*b5893f02SDimitry Andric     return;
382*b5893f02SDimitry Andric   }
383*b5893f02SDimitry Andric 
384*b5893f02SDimitry Andric   // Otherwise, fall back on a copy-based clone.
385*b5893f02SDimitry Andric   setMemRefs(MF, MI.memoperands());
386dff0c46cSDimitry Andric }
387dff0c46cSDimitry Andric 
388444ed5c5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are
389444ed5c5SDimitry Andric /// identical.
hasIdenticalMMOs(ArrayRef<MachineMemOperand * > LHS,ArrayRef<MachineMemOperand * > RHS)390*b5893f02SDimitry Andric static bool hasIdenticalMMOs(ArrayRef<MachineMemOperand *> LHS,
391*b5893f02SDimitry Andric                              ArrayRef<MachineMemOperand *> RHS) {
392*b5893f02SDimitry Andric   if (LHS.size() != RHS.size())
393444ed5c5SDimitry Andric     return false;
394*b5893f02SDimitry Andric 
395*b5893f02SDimitry Andric   auto LHSPointees = make_pointee_range(LHS);
396*b5893f02SDimitry Andric   auto RHSPointees = make_pointee_range(RHS);
397*b5893f02SDimitry Andric   return std::equal(LHSPointees.begin(), LHSPointees.end(),
398*b5893f02SDimitry Andric                     RHSPointees.begin());
399444ed5c5SDimitry Andric }
400444ed5c5SDimitry Andric 
cloneMergedMemRefs(MachineFunction & MF,ArrayRef<const MachineInstr * > MIs)401*b5893f02SDimitry Andric void MachineInstr::cloneMergedMemRefs(MachineFunction &MF,
402*b5893f02SDimitry Andric                                       ArrayRef<const MachineInstr *> MIs) {
403*b5893f02SDimitry Andric   // Try handling easy numbers of MIs with simpler mechanisms.
404*b5893f02SDimitry Andric   if (MIs.empty()) {
405*b5893f02SDimitry Andric     dropMemRefs(MF);
406*b5893f02SDimitry Andric     return;
407*b5893f02SDimitry Andric   }
408*b5893f02SDimitry Andric   if (MIs.size() == 1) {
409*b5893f02SDimitry Andric     cloneMemRefs(MF, *MIs[0]);
410*b5893f02SDimitry Andric     return;
411*b5893f02SDimitry Andric   }
412*b5893f02SDimitry Andric   // Because an empty memoperands list provides *no* information and must be
413*b5893f02SDimitry Andric   // handled conservatively (assuming the instruction can do anything), the only
414*b5893f02SDimitry Andric   // way to merge with it is to drop all other memoperands.
415*b5893f02SDimitry Andric   if (MIs[0]->memoperands_empty()) {
416*b5893f02SDimitry Andric     dropMemRefs(MF);
417*b5893f02SDimitry Andric     return;
418*b5893f02SDimitry Andric   }
419444ed5c5SDimitry Andric 
420*b5893f02SDimitry Andric   // Handle the general case.
421*b5893f02SDimitry Andric   SmallVector<MachineMemOperand *, 2> MergedMMOs;
422*b5893f02SDimitry Andric   // Start with the first instruction.
423*b5893f02SDimitry Andric   assert(&MF == MIs[0]->getMF() &&
424*b5893f02SDimitry Andric          "Invalid machine functions when cloning memory references!");
425*b5893f02SDimitry Andric   MergedMMOs.append(MIs[0]->memoperands_begin(), MIs[0]->memoperands_end());
426*b5893f02SDimitry Andric   // Now walk all the other instructions and accumulate any different MMOs.
427*b5893f02SDimitry Andric   for (const MachineInstr &MI : make_pointee_range(MIs.slice(1))) {
428*b5893f02SDimitry Andric     assert(&MF == MI.getMF() &&
429*b5893f02SDimitry Andric            "Invalid machine functions when cloning memory references!");
430444ed5c5SDimitry Andric 
431*b5893f02SDimitry Andric     // Skip MIs with identical operands to the first. This is a somewhat
432*b5893f02SDimitry Andric     // arbitrary hack but will catch common cases without being quadratic.
433*b5893f02SDimitry Andric     // TODO: We could fully implement merge semantics here if needed.
434*b5893f02SDimitry Andric     if (hasIdenticalMMOs(MIs[0]->memoperands(), MI.memoperands()))
435*b5893f02SDimitry Andric       continue;
436444ed5c5SDimitry Andric 
437*b5893f02SDimitry Andric     // Because an empty memoperands list provides *no* information and must be
438*b5893f02SDimitry Andric     // handled conservatively (assuming the instruction can do anything), the
439*b5893f02SDimitry Andric     // only way to merge with it is to drop all other memoperands.
440*b5893f02SDimitry Andric     if (MI.memoperands_empty()) {
441*b5893f02SDimitry Andric       dropMemRefs(MF);
442*b5893f02SDimitry Andric       return;
443*b5893f02SDimitry Andric     }
444444ed5c5SDimitry Andric 
445*b5893f02SDimitry Andric     // Otherwise accumulate these into our temporary buffer of the merged state.
446*b5893f02SDimitry Andric     MergedMMOs.append(MI.memoperands_begin(), MI.memoperands_end());
447*b5893f02SDimitry Andric   }
4484d0b32cdSDimitry Andric 
449*b5893f02SDimitry Andric   setMemRefs(MF, MergedMMOs);
450*b5893f02SDimitry Andric }
4514d0b32cdSDimitry Andric 
setPreInstrSymbol(MachineFunction & MF,MCSymbol * Symbol)452*b5893f02SDimitry Andric void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
453*b5893f02SDimitry Andric   MCSymbol *OldSymbol = getPreInstrSymbol();
454*b5893f02SDimitry Andric   if (OldSymbol == Symbol)
455*b5893f02SDimitry Andric     return;
456*b5893f02SDimitry Andric   if (OldSymbol && !Symbol) {
457*b5893f02SDimitry Andric     // We're removing a symbol rather than adding one. Try to clean up any
458*b5893f02SDimitry Andric     // extra info carried around.
459*b5893f02SDimitry Andric     if (Info.is<EIIK_PreInstrSymbol>()) {
460*b5893f02SDimitry Andric       Info.clear();
461*b5893f02SDimitry Andric       return;
462*b5893f02SDimitry Andric     }
463*b5893f02SDimitry Andric 
464*b5893f02SDimitry Andric     if (memoperands_empty()) {
465*b5893f02SDimitry Andric       assert(getPostInstrSymbol() &&
466*b5893f02SDimitry Andric              "Should never have only a single symbol allocated out-of-line!");
467*b5893f02SDimitry Andric       Info.set<EIIK_PostInstrSymbol>(getPostInstrSymbol());
468*b5893f02SDimitry Andric       return;
469*b5893f02SDimitry Andric     }
470*b5893f02SDimitry Andric 
471*b5893f02SDimitry Andric     // Otherwise fallback on the generic update.
472*b5893f02SDimitry Andric   } else if (!Info || Info.is<EIIK_PreInstrSymbol>()) {
473*b5893f02SDimitry Andric     // If we don't have any other extra info, we can store this inline.
474*b5893f02SDimitry Andric     Info.set<EIIK_PreInstrSymbol>(Symbol);
475*b5893f02SDimitry Andric     return;
476*b5893f02SDimitry Andric   }
477*b5893f02SDimitry Andric 
478*b5893f02SDimitry Andric   // Otherwise, allocate a full new set of extra info.
479*b5893f02SDimitry Andric   // FIXME: Maybe we should make the symbols in the extra info mutable?
480*b5893f02SDimitry Andric   Info.set<EIIK_OutOfLine>(
481*b5893f02SDimitry Andric       MF.createMIExtraInfo(memoperands(), Symbol, getPostInstrSymbol()));
482*b5893f02SDimitry Andric }
483*b5893f02SDimitry Andric 
setPostInstrSymbol(MachineFunction & MF,MCSymbol * Symbol)484*b5893f02SDimitry Andric void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
485*b5893f02SDimitry Andric   MCSymbol *OldSymbol = getPostInstrSymbol();
486*b5893f02SDimitry Andric   if (OldSymbol == Symbol)
487*b5893f02SDimitry Andric     return;
488*b5893f02SDimitry Andric   if (OldSymbol && !Symbol) {
489*b5893f02SDimitry Andric     // We're removing a symbol rather than adding one. Try to clean up any
490*b5893f02SDimitry Andric     // extra info carried around.
491*b5893f02SDimitry Andric     if (Info.is<EIIK_PostInstrSymbol>()) {
492*b5893f02SDimitry Andric       Info.clear();
493*b5893f02SDimitry Andric       return;
494*b5893f02SDimitry Andric     }
495*b5893f02SDimitry Andric 
496*b5893f02SDimitry Andric     if (memoperands_empty()) {
497*b5893f02SDimitry Andric       assert(getPreInstrSymbol() &&
498*b5893f02SDimitry Andric              "Should never have only a single symbol allocated out-of-line!");
499*b5893f02SDimitry Andric       Info.set<EIIK_PreInstrSymbol>(getPreInstrSymbol());
500*b5893f02SDimitry Andric       return;
501*b5893f02SDimitry Andric     }
502*b5893f02SDimitry Andric 
503*b5893f02SDimitry Andric     // Otherwise fallback on the generic update.
504*b5893f02SDimitry Andric   } else if (!Info || Info.is<EIIK_PostInstrSymbol>()) {
505*b5893f02SDimitry Andric     // If we don't have any other extra info, we can store this inline.
506*b5893f02SDimitry Andric     Info.set<EIIK_PostInstrSymbol>(Symbol);
507*b5893f02SDimitry Andric     return;
508*b5893f02SDimitry Andric   }
509*b5893f02SDimitry Andric 
510*b5893f02SDimitry Andric   // Otherwise, allocate a full new set of extra info.
511*b5893f02SDimitry Andric   // FIXME: Maybe we should make the symbols in the extra info mutable?
512*b5893f02SDimitry Andric   Info.set<EIIK_OutOfLine>(
513*b5893f02SDimitry Andric       MF.createMIExtraInfo(memoperands(), getPreInstrSymbol(), Symbol));
5144d0b32cdSDimitry Andric }
5154d0b32cdSDimitry Andric 
mergeFlagsWith(const MachineInstr & Other) const5164ba319b5SDimitry Andric uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
5174ba319b5SDimitry Andric   // For now, the just return the union of the flags. If the flags get more
5184ba319b5SDimitry Andric   // complicated over time, we might need more logic here.
5194ba319b5SDimitry Andric   return getFlags() | Other.getFlags();
5204ba319b5SDimitry Andric }
5214ba319b5SDimitry Andric 
copyIRFlags(const Instruction & I)522*b5893f02SDimitry Andric void MachineInstr::copyIRFlags(const Instruction &I) {
523*b5893f02SDimitry Andric   // Copy the wrapping flags.
524*b5893f02SDimitry Andric   if (const OverflowingBinaryOperator *OB =
525*b5893f02SDimitry Andric           dyn_cast<OverflowingBinaryOperator>(&I)) {
526*b5893f02SDimitry Andric     if (OB->hasNoSignedWrap())
527*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::NoSWrap);
528*b5893f02SDimitry Andric     if (OB->hasNoUnsignedWrap())
529*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::NoUWrap);
530*b5893f02SDimitry Andric   }
531*b5893f02SDimitry Andric 
532*b5893f02SDimitry Andric   // Copy the exact flag.
533*b5893f02SDimitry Andric   if (const PossiblyExactOperator *PE = dyn_cast<PossiblyExactOperator>(&I))
534*b5893f02SDimitry Andric     if (PE->isExact())
535*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::IsExact);
536*b5893f02SDimitry Andric 
537*b5893f02SDimitry Andric   // Copy the fast-math flags.
538*b5893f02SDimitry Andric   if (const FPMathOperator *FP = dyn_cast<FPMathOperator>(&I)) {
539*b5893f02SDimitry Andric     const FastMathFlags Flags = FP->getFastMathFlags();
540*b5893f02SDimitry Andric     if (Flags.noNaNs())
541*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::FmNoNans);
542*b5893f02SDimitry Andric     if (Flags.noInfs())
543*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::FmNoInfs);
544*b5893f02SDimitry Andric     if (Flags.noSignedZeros())
545*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::FmNsz);
546*b5893f02SDimitry Andric     if (Flags.allowReciprocal())
547*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::FmArcp);
548*b5893f02SDimitry Andric     if (Flags.allowContract())
549*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::FmContract);
550*b5893f02SDimitry Andric     if (Flags.approxFunc())
551*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::FmAfn);
552*b5893f02SDimitry Andric     if (Flags.allowReassoc())
553*b5893f02SDimitry Andric       setFlag(MachineInstr::MIFlag::FmReassoc);
554*b5893f02SDimitry Andric   }
555*b5893f02SDimitry Andric }
556*b5893f02SDimitry Andric 
hasPropertyInBundle(uint64_t Mask,QueryType Type) const557*b5893f02SDimitry Andric bool MachineInstr::hasPropertyInBundle(uint64_t Mask, QueryType Type) const {
558139f7f9bSDimitry Andric   assert(!isBundledWithPred() && "Must be called on bundle header");
5597d523365SDimitry Andric   for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) {
560dff0c46cSDimitry Andric     if (MII->getDesc().getFlags() & Mask) {
561dff0c46cSDimitry Andric       if (Type == AnyInBundle)
562dff0c46cSDimitry Andric         return true;
563dff0c46cSDimitry Andric     } else {
564139f7f9bSDimitry Andric       if (Type == AllInBundle && !MII->isBundle())
565dff0c46cSDimitry Andric         return false;
566dff0c46cSDimitry Andric     }
567139f7f9bSDimitry Andric     // This was the last instruction in the bundle.
568139f7f9bSDimitry Andric     if (!MII->isBundledWithSucc())
569dff0c46cSDimitry Andric       return Type == AllInBundle;
570f22ef01cSRoman Divacky   }
571139f7f9bSDimitry Andric }
572f22ef01cSRoman Divacky 
isIdenticalTo(const MachineInstr & Other,MICheckType Check) const5733ca95b02SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other,
574f22ef01cSRoman Divacky                                  MICheckType Check) const {
575f22ef01cSRoman Divacky   // If opcodes or number of operands are not the same then the two
576f22ef01cSRoman Divacky   // instructions are obviously not identical.
5773ca95b02SDimitry Andric   if (Other.getOpcode() != getOpcode() ||
5783ca95b02SDimitry Andric       Other.getNumOperands() != getNumOperands())
579f22ef01cSRoman Divacky     return false;
580f22ef01cSRoman Divacky 
581dff0c46cSDimitry Andric   if (isBundle()) {
582d88c1a5aSDimitry Andric     // We have passed the test above that both instructions have the same
583d88c1a5aSDimitry Andric     // opcode, so we know that both instructions are bundles here. Let's compare
584d88c1a5aSDimitry Andric     // MIs inside the bundle.
585d88c1a5aSDimitry Andric     assert(Other.isBundle() && "Expected that both instructions are bundles.");
5867d523365SDimitry Andric     MachineBasicBlock::const_instr_iterator I1 = getIterator();
5873ca95b02SDimitry Andric     MachineBasicBlock::const_instr_iterator I2 = Other.getIterator();
588d88c1a5aSDimitry Andric     // Loop until we analysed the last intruction inside at least one of the
589d88c1a5aSDimitry Andric     // bundles.
590d88c1a5aSDimitry Andric     while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) {
591d88c1a5aSDimitry Andric       ++I1;
592dff0c46cSDimitry Andric       ++I2;
593d88c1a5aSDimitry Andric       if (!I1->isIdenticalTo(*I2, Check))
594dff0c46cSDimitry Andric         return false;
595dff0c46cSDimitry Andric     }
596d88c1a5aSDimitry Andric     // If we've reached the end of just one of the two bundles, but not both,
597d88c1a5aSDimitry Andric     // the instructions are not identical.
598d88c1a5aSDimitry Andric     if (I1->isBundledWithSucc() || I2->isBundledWithSucc())
599d88c1a5aSDimitry Andric       return false;
600dff0c46cSDimitry Andric   }
601dff0c46cSDimitry Andric 
602f22ef01cSRoman Divacky   // Check operands to make sure they match.
603f22ef01cSRoman Divacky   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
604f22ef01cSRoman Divacky     const MachineOperand &MO = getOperand(i);
6053ca95b02SDimitry Andric     const MachineOperand &OMO = Other.getOperand(i);
606bd5abe19SDimitry Andric     if (!MO.isReg()) {
607bd5abe19SDimitry Andric       if (!MO.isIdenticalTo(OMO))
608bd5abe19SDimitry Andric         return false;
609bd5abe19SDimitry Andric       continue;
610bd5abe19SDimitry Andric     }
611bd5abe19SDimitry Andric 
612f22ef01cSRoman Divacky     // Clients may or may not want to ignore defs when testing for equality.
613f22ef01cSRoman Divacky     // For example, machine CSE pass only cares about finding common
614f22ef01cSRoman Divacky     // subexpressions, so it's safe to ignore virtual register defs.
615bd5abe19SDimitry Andric     if (MO.isDef()) {
616f22ef01cSRoman Divacky       if (Check == IgnoreDefs)
617f22ef01cSRoman Divacky         continue;
618bd5abe19SDimitry Andric       else if (Check == IgnoreVRegDefs) {
6192cab237bSDimitry Andric         if (!TargetRegisterInfo::isVirtualRegister(MO.getReg()) ||
6202cab237bSDimitry Andric             !TargetRegisterInfo::isVirtualRegister(OMO.getReg()))
6212cab237bSDimitry Andric           if (!MO.isIdenticalTo(OMO))
622f22ef01cSRoman Divacky             return false;
623bd5abe19SDimitry Andric       } else {
624bd5abe19SDimitry Andric         if (!MO.isIdenticalTo(OMO))
625f22ef01cSRoman Divacky           return false;
626bd5abe19SDimitry Andric         if (Check == CheckKillDead && MO.isDead() != OMO.isDead())
627bd5abe19SDimitry Andric           return false;
628bd5abe19SDimitry Andric       }
629bd5abe19SDimitry Andric     } else {
630bd5abe19SDimitry Andric       if (!MO.isIdenticalTo(OMO))
631bd5abe19SDimitry Andric         return false;
632bd5abe19SDimitry Andric       if (Check == CheckKillDead && MO.isKill() != OMO.isKill())
633bd5abe19SDimitry Andric         return false;
634bd5abe19SDimitry Andric     }
635f22ef01cSRoman Divacky   }
6364ba319b5SDimitry Andric   // If DebugLoc does not match then two debug instructions are not identical.
6374ba319b5SDimitry Andric   if (isDebugInstr())
6383ca95b02SDimitry Andric     if (getDebugLoc() && Other.getDebugLoc() &&
6393ca95b02SDimitry Andric         getDebugLoc() != Other.getDebugLoc())
64017a519f9SDimitry Andric       return false;
641f22ef01cSRoman Divacky   return true;
642f22ef01cSRoman Divacky }
643f22ef01cSRoman Divacky 
getMF() const6442cab237bSDimitry Andric const MachineFunction *MachineInstr::getMF() const {
6452cab237bSDimitry Andric   return getParent()->getParent();
6462cab237bSDimitry Andric }
6472cab237bSDimitry Andric 
removeFromParent()648f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() {
649f22ef01cSRoman Divacky   assert(getParent() && "Not embedded in a basic block!");
650139f7f9bSDimitry Andric   return getParent()->remove(this);
651f22ef01cSRoman Divacky }
652f22ef01cSRoman Divacky 
removeFromBundle()653139f7f9bSDimitry Andric MachineInstr *MachineInstr::removeFromBundle() {
654139f7f9bSDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
655139f7f9bSDimitry Andric   return getParent()->remove_instr(this);
656139f7f9bSDimitry Andric }
657f22ef01cSRoman Divacky 
eraseFromParent()658f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() {
659f22ef01cSRoman Divacky   assert(getParent() && "Not embedded in a basic block!");
660139f7f9bSDimitry Andric   getParent()->erase(this);
661f22ef01cSRoman Divacky }
662f22ef01cSRoman Divacky 
eraseFromParentAndMarkDBGValuesForRemoval()66339d628a0SDimitry Andric void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() {
66439d628a0SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
66539d628a0SDimitry Andric   MachineBasicBlock *MBB = getParent();
66639d628a0SDimitry Andric   MachineFunction *MF = MBB->getParent();
66739d628a0SDimitry Andric   assert(MF && "Not embedded in a function!");
66839d628a0SDimitry Andric 
66939d628a0SDimitry Andric   MachineInstr *MI = (MachineInstr *)this;
67039d628a0SDimitry Andric   MachineRegisterInfo &MRI = MF->getRegInfo();
67139d628a0SDimitry Andric 
672ff0cc061SDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
67339d628a0SDimitry Andric     if (!MO.isReg() || !MO.isDef())
67439d628a0SDimitry Andric       continue;
67539d628a0SDimitry Andric     unsigned Reg = MO.getReg();
67639d628a0SDimitry Andric     if (!TargetRegisterInfo::isVirtualRegister(Reg))
67739d628a0SDimitry Andric       continue;
67839d628a0SDimitry Andric     MRI.markUsesInDebugValueAsUndef(Reg);
67939d628a0SDimitry Andric   }
68039d628a0SDimitry Andric   MI->eraseFromParent();
68139d628a0SDimitry Andric }
68239d628a0SDimitry Andric 
eraseFromBundle()683139f7f9bSDimitry Andric void MachineInstr::eraseFromBundle() {
684139f7f9bSDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
685139f7f9bSDimitry Andric   getParent()->erase_instr(this);
686139f7f9bSDimitry Andric }
687f22ef01cSRoman Divacky 
getNumExplicitOperands() const688f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const {
68917a519f9SDimitry Andric   unsigned NumOperands = MCID->getNumOperands();
69017a519f9SDimitry Andric   if (!MCID->isVariadic())
691f22ef01cSRoman Divacky     return NumOperands;
692f22ef01cSRoman Divacky 
6934ba319b5SDimitry Andric   for (unsigned I = NumOperands, E = getNumOperands(); I != E; ++I) {
6944ba319b5SDimitry Andric     const MachineOperand &MO = getOperand(I);
6954ba319b5SDimitry Andric     // The operands must always be in the following order:
6964ba319b5SDimitry Andric     // - explicit reg defs,
6974ba319b5SDimitry Andric     // - other explicit operands (reg uses, immediates, etc.),
6984ba319b5SDimitry Andric     // - implicit reg defs
6994ba319b5SDimitry Andric     // - implicit reg uses
7004ba319b5SDimitry Andric     if (MO.isReg() && MO.isImplicit())
7014ba319b5SDimitry Andric       break;
7024ba319b5SDimitry Andric     ++NumOperands;
703f22ef01cSRoman Divacky   }
704f22ef01cSRoman Divacky   return NumOperands;
705f22ef01cSRoman Divacky }
706f22ef01cSRoman Divacky 
getNumExplicitDefs() const7074ba319b5SDimitry Andric unsigned MachineInstr::getNumExplicitDefs() const {
7084ba319b5SDimitry Andric   unsigned NumDefs = MCID->getNumDefs();
7094ba319b5SDimitry Andric   if (!MCID->isVariadic())
7104ba319b5SDimitry Andric     return NumDefs;
7114ba319b5SDimitry Andric 
7124ba319b5SDimitry Andric   for (unsigned I = NumDefs, E = getNumOperands(); I != E; ++I) {
7134ba319b5SDimitry Andric     const MachineOperand &MO = getOperand(I);
7144ba319b5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
7154ba319b5SDimitry Andric       break;
7164ba319b5SDimitry Andric     ++NumDefs;
7174ba319b5SDimitry Andric   }
7184ba319b5SDimitry Andric   return NumDefs;
7194ba319b5SDimitry Andric }
7204ba319b5SDimitry Andric 
bundleWithPred()721139f7f9bSDimitry Andric void MachineInstr::bundleWithPred() {
722139f7f9bSDimitry Andric   assert(!isBundledWithPred() && "MI is already bundled with its predecessor");
723139f7f9bSDimitry Andric   setFlag(BundledPred);
7247d523365SDimitry Andric   MachineBasicBlock::instr_iterator Pred = getIterator();
725139f7f9bSDimitry Andric   --Pred;
726139f7f9bSDimitry Andric   assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags");
727139f7f9bSDimitry Andric   Pred->setFlag(BundledSucc);
728139f7f9bSDimitry Andric }
729139f7f9bSDimitry Andric 
bundleWithSucc()730139f7f9bSDimitry Andric void MachineInstr::bundleWithSucc() {
731139f7f9bSDimitry Andric   assert(!isBundledWithSucc() && "MI is already bundled with its successor");
732139f7f9bSDimitry Andric   setFlag(BundledSucc);
7337d523365SDimitry Andric   MachineBasicBlock::instr_iterator Succ = getIterator();
734139f7f9bSDimitry Andric   ++Succ;
735139f7f9bSDimitry Andric   assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags");
736139f7f9bSDimitry Andric   Succ->setFlag(BundledPred);
737139f7f9bSDimitry Andric }
738139f7f9bSDimitry Andric 
unbundleFromPred()739139f7f9bSDimitry Andric void MachineInstr::unbundleFromPred() {
740139f7f9bSDimitry Andric   assert(isBundledWithPred() && "MI isn't bundled with its predecessor");
741139f7f9bSDimitry Andric   clearFlag(BundledPred);
7427d523365SDimitry Andric   MachineBasicBlock::instr_iterator Pred = getIterator();
743139f7f9bSDimitry Andric   --Pred;
744139f7f9bSDimitry Andric   assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags");
745139f7f9bSDimitry Andric   Pred->clearFlag(BundledSucc);
746139f7f9bSDimitry Andric }
747139f7f9bSDimitry Andric 
unbundleFromSucc()748139f7f9bSDimitry Andric void MachineInstr::unbundleFromSucc() {
749139f7f9bSDimitry Andric   assert(isBundledWithSucc() && "MI isn't bundled with its successor");
750139f7f9bSDimitry Andric   clearFlag(BundledSucc);
7517d523365SDimitry Andric   MachineBasicBlock::instr_iterator Succ = getIterator();
752139f7f9bSDimitry Andric   ++Succ;
753139f7f9bSDimitry Andric   assert(Succ->isBundledWithPred() && "Inconsistent bundle flags");
754139f7f9bSDimitry Andric   Succ->clearFlag(BundledPred);
755dff0c46cSDimitry Andric }
756dff0c46cSDimitry Andric 
isStackAligningInlineAsm() const7572754fe60SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const {
7582754fe60SDimitry Andric   if (isInlineAsm()) {
7592754fe60SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
7602754fe60SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
7612754fe60SDimitry Andric       return true;
7622754fe60SDimitry Andric   }
7632754fe60SDimitry Andric   return false;
7642754fe60SDimitry Andric }
765f22ef01cSRoman Divacky 
getInlineAsmDialect() const7663861d79fSDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const {
7673861d79fSDimitry Andric   assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!");
7683861d79fSDimitry Andric   unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
7693861d79fSDimitry Andric   return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0);
7703861d79fSDimitry Andric }
7713861d79fSDimitry Andric 
findInlineAsmFlagIdx(unsigned OpIdx,unsigned * GroupNo) const7726122f3e6SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx,
7736122f3e6SDimitry Andric                                        unsigned *GroupNo) const {
7746122f3e6SDimitry Andric   assert(isInlineAsm() && "Expected an inline asm instruction");
7756122f3e6SDimitry Andric   assert(OpIdx < getNumOperands() && "OpIdx out of range");
7766122f3e6SDimitry Andric 
7776122f3e6SDimitry Andric   // Ignore queries about the initial operands.
7786122f3e6SDimitry Andric   if (OpIdx < InlineAsm::MIOp_FirstOperand)
7796122f3e6SDimitry Andric     return -1;
7806122f3e6SDimitry Andric 
7816122f3e6SDimitry Andric   unsigned Group = 0;
7826122f3e6SDimitry Andric   unsigned NumOps;
7836122f3e6SDimitry Andric   for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
7846122f3e6SDimitry Andric        i += NumOps) {
7856122f3e6SDimitry Andric     const MachineOperand &FlagMO = getOperand(i);
7866122f3e6SDimitry Andric     // If we reach the implicit register operands, stop looking.
7876122f3e6SDimitry Andric     if (!FlagMO.isImm())
7886122f3e6SDimitry Andric       return -1;
7896122f3e6SDimitry Andric     NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm());
7906122f3e6SDimitry Andric     if (i + NumOps > OpIdx) {
7916122f3e6SDimitry Andric       if (GroupNo)
7926122f3e6SDimitry Andric         *GroupNo = Group;
7936122f3e6SDimitry Andric       return i;
7946122f3e6SDimitry Andric     }
7956122f3e6SDimitry Andric     ++Group;
7966122f3e6SDimitry Andric   }
7976122f3e6SDimitry Andric   return -1;
7986122f3e6SDimitry Andric }
7996122f3e6SDimitry Andric 
getDebugLabel() const8004ba319b5SDimitry Andric const DILabel *MachineInstr::getDebugLabel() const {
8014ba319b5SDimitry Andric   assert(isDebugLabel() && "not a DBG_LABEL");
8024ba319b5SDimitry Andric   return cast<DILabel>(getOperand(0).getMetadata());
8034ba319b5SDimitry Andric }
8044ba319b5SDimitry Andric 
getDebugVariable() const8053ca95b02SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const {
8063ca95b02SDimitry Andric   assert(isDebugValue() && "not a DBG_VALUE");
8073ca95b02SDimitry Andric   return cast<DILocalVariable>(getOperand(2).getMetadata());
8083ca95b02SDimitry Andric }
8093ca95b02SDimitry Andric 
getDebugExpression() const8103ca95b02SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const {
8113ca95b02SDimitry Andric   assert(isDebugValue() && "not a DBG_VALUE");
8123ca95b02SDimitry Andric   return cast<DIExpression>(getOperand(3).getMetadata());
8133ca95b02SDimitry Andric }
8143ca95b02SDimitry Andric 
8156122f3e6SDimitry Andric const TargetRegisterClass*
getRegClassConstraint(unsigned OpIdx,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const8166122f3e6SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx,
8176122f3e6SDimitry Andric                                     const TargetInstrInfo *TII,
8186122f3e6SDimitry Andric                                     const TargetRegisterInfo *TRI) const {
8197ae0e2c9SDimitry Andric   assert(getParent() && "Can't have an MBB reference here!");
8202cab237bSDimitry Andric   assert(getMF() && "Can't have an MF reference here!");
8212cab237bSDimitry Andric   const MachineFunction &MF = *getMF();
8227ae0e2c9SDimitry Andric 
8236122f3e6SDimitry Andric   // Most opcodes have fixed constraints in their MCInstrDesc.
8246122f3e6SDimitry Andric   if (!isInlineAsm())
8257ae0e2c9SDimitry Andric     return TII->getRegClass(getDesc(), OpIdx, TRI, MF);
8266122f3e6SDimitry Andric 
8276122f3e6SDimitry Andric   if (!getOperand(OpIdx).isReg())
82891bc56edSDimitry Andric     return nullptr;
8296122f3e6SDimitry Andric 
8306122f3e6SDimitry Andric   // For tied uses on inline asm, get the constraint from the def.
8316122f3e6SDimitry Andric   unsigned DefIdx;
8326122f3e6SDimitry Andric   if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx))
8336122f3e6SDimitry Andric     OpIdx = DefIdx;
8346122f3e6SDimitry Andric 
8356122f3e6SDimitry Andric   // Inline asm stores register class constraints in the flag word.
8366122f3e6SDimitry Andric   int FlagIdx = findInlineAsmFlagIdx(OpIdx);
8376122f3e6SDimitry Andric   if (FlagIdx < 0)
83891bc56edSDimitry Andric     return nullptr;
8396122f3e6SDimitry Andric 
8406122f3e6SDimitry Andric   unsigned Flag = getOperand(FlagIdx).getImm();
8416122f3e6SDimitry Andric   unsigned RCID;
8423ca95b02SDimitry Andric   if ((InlineAsm::getKind(Flag) == InlineAsm::Kind_RegUse ||
8433ca95b02SDimitry Andric        InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDef ||
8443ca95b02SDimitry Andric        InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDefEarlyClobber) &&
8453ca95b02SDimitry Andric       InlineAsm::hasRegClassConstraint(Flag, RCID))
8466122f3e6SDimitry Andric     return TRI->getRegClass(RCID);
8476122f3e6SDimitry Andric 
8486122f3e6SDimitry Andric   // Assume that all registers in a memory operand are pointers.
8496122f3e6SDimitry Andric   if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem)
8507ae0e2c9SDimitry Andric     return TRI->getPointerRegClass(MF);
8516122f3e6SDimitry Andric 
85291bc56edSDimitry Andric   return nullptr;
85391bc56edSDimitry Andric }
85491bc56edSDimitry Andric 
getRegClassConstraintEffectForVReg(unsigned Reg,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI,bool ExploreBundle) const85591bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg(
85691bc56edSDimitry Andric     unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII,
85791bc56edSDimitry Andric     const TargetRegisterInfo *TRI, bool ExploreBundle) const {
85891bc56edSDimitry Andric   // Check every operands inside the bundle if we have
85991bc56edSDimitry Andric   // been asked to.
86091bc56edSDimitry Andric   if (ExploreBundle)
8613ca95b02SDimitry Andric     for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC;
86291bc56edSDimitry Andric          ++OpndIt)
86391bc56edSDimitry Andric       CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl(
86491bc56edSDimitry Andric           OpndIt.getOperandNo(), Reg, CurRC, TII, TRI);
86591bc56edSDimitry Andric   else
86691bc56edSDimitry Andric     // Otherwise, just check the current operands.
86797bc6c73SDimitry Andric     for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i)
86897bc6c73SDimitry Andric       CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI);
86991bc56edSDimitry Andric   return CurRC;
87091bc56edSDimitry Andric }
87191bc56edSDimitry Andric 
getRegClassConstraintEffectForVRegImpl(unsigned OpIdx,unsigned Reg,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const87291bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl(
87391bc56edSDimitry Andric     unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC,
87491bc56edSDimitry Andric     const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
87591bc56edSDimitry Andric   assert(CurRC && "Invalid initial register class");
87691bc56edSDimitry Andric   // Check if Reg is constrained by some of its use/def from MI.
87791bc56edSDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
87891bc56edSDimitry Andric   if (!MO.isReg() || MO.getReg() != Reg)
87991bc56edSDimitry Andric     return CurRC;
88091bc56edSDimitry Andric   // If yes, accumulate the constraints through the operand.
88191bc56edSDimitry Andric   return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI);
88291bc56edSDimitry Andric }
88391bc56edSDimitry Andric 
getRegClassConstraintEffect(unsigned OpIdx,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const88491bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
88591bc56edSDimitry Andric     unsigned OpIdx, const TargetRegisterClass *CurRC,
88691bc56edSDimitry Andric     const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
88791bc56edSDimitry Andric   const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI);
88891bc56edSDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
88991bc56edSDimitry Andric   assert(MO.isReg() &&
89091bc56edSDimitry Andric          "Cannot get register constraints for non-register operand");
89191bc56edSDimitry Andric   assert(CurRC && "Invalid initial register class");
89291bc56edSDimitry Andric   if (unsigned SubIdx = MO.getSubReg()) {
89391bc56edSDimitry Andric     if (OpRC)
89491bc56edSDimitry Andric       CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx);
89591bc56edSDimitry Andric     else
89691bc56edSDimitry Andric       CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx);
89791bc56edSDimitry Andric   } else if (OpRC)
89891bc56edSDimitry Andric     CurRC = TRI->getCommonSubClass(CurRC, OpRC);
89991bc56edSDimitry Andric   return CurRC;
9006122f3e6SDimitry Andric }
9016122f3e6SDimitry Andric 
902139f7f9bSDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the
903139f7f9bSDimitry Andric /// header instruction.
getBundleSize() const904dff0c46cSDimitry Andric unsigned MachineInstr::getBundleSize() const {
9057d523365SDimitry Andric   MachineBasicBlock::const_instr_iterator I = getIterator();
906dff0c46cSDimitry Andric   unsigned Size = 0;
9073ca95b02SDimitry Andric   while (I->isBundledWithSucc()) {
9083ca95b02SDimitry Andric     ++Size;
9093ca95b02SDimitry Andric     ++I;
9103ca95b02SDimitry Andric   }
911dff0c46cSDimitry Andric   return Size;
912dff0c46cSDimitry Andric }
913dff0c46cSDimitry Andric 
9143ca95b02SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly
9153ca95b02SDimitry Andric /// the given register (not considering sub/super-registers).
hasRegisterImplicitUseOperand(unsigned Reg) const9163ca95b02SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(unsigned Reg) const {
9173ca95b02SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
9183ca95b02SDimitry Andric     const MachineOperand &MO = getOperand(i);
9193ca95b02SDimitry Andric     if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg)
9203ca95b02SDimitry Andric       return true;
9213ca95b02SDimitry Andric   }
9223ca95b02SDimitry Andric   return false;
9233ca95b02SDimitry Andric }
9243ca95b02SDimitry Andric 
925f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
926f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens
927f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true.
findRegisterUseOperandIdx(unsigned Reg,bool isKill,const TargetRegisterInfo * TRI) const928d88c1a5aSDimitry Andric int MachineInstr::findRegisterUseOperandIdx(
929d88c1a5aSDimitry Andric     unsigned Reg, bool isKill, const TargetRegisterInfo *TRI) const {
930f22ef01cSRoman Divacky   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
931f22ef01cSRoman Divacky     const MachineOperand &MO = getOperand(i);
932f22ef01cSRoman Divacky     if (!MO.isReg() || !MO.isUse())
933f22ef01cSRoman Divacky       continue;
934f22ef01cSRoman Divacky     unsigned MOReg = MO.getReg();
935f22ef01cSRoman Divacky     if (!MOReg)
936f22ef01cSRoman Divacky       continue;
937*b5893f02SDimitry Andric     if (MOReg == Reg || (TRI && Reg && MOReg && TRI->regsOverlap(MOReg, Reg)))
938f22ef01cSRoman Divacky       if (!isKill || MO.isKill())
939f22ef01cSRoman Divacky         return i;
940f22ef01cSRoman Divacky   }
941f22ef01cSRoman Divacky   return -1;
942f22ef01cSRoman Divacky }
943f22ef01cSRoman Divacky 
944f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
945f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers
946f22ef01cSRoman Divacky /// partial defines.
947f22ef01cSRoman Divacky std::pair<bool,bool>
readsWritesVirtualRegister(unsigned Reg,SmallVectorImpl<unsigned> * Ops) const948f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg,
949f22ef01cSRoman Divacky                                          SmallVectorImpl<unsigned> *Ops) const {
950f22ef01cSRoman Divacky   bool PartDef = false; // Partial redefine.
951f22ef01cSRoman Divacky   bool FullDef = false; // Full define.
952f22ef01cSRoman Divacky   bool Use = false;
953f22ef01cSRoman Divacky 
954f22ef01cSRoman Divacky   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
955f22ef01cSRoman Divacky     const MachineOperand &MO = getOperand(i);
956f22ef01cSRoman Divacky     if (!MO.isReg() || MO.getReg() != Reg)
957f22ef01cSRoman Divacky       continue;
958f22ef01cSRoman Divacky     if (Ops)
959f22ef01cSRoman Divacky       Ops->push_back(i);
960f22ef01cSRoman Divacky     if (MO.isUse())
961f22ef01cSRoman Divacky       Use |= !MO.isUndef();
9626122f3e6SDimitry Andric     else if (MO.getSubReg() && !MO.isUndef())
9632cab237bSDimitry Andric       // A partial def undef doesn't count as reading the register.
964f22ef01cSRoman Divacky       PartDef = true;
965f22ef01cSRoman Divacky     else
966f22ef01cSRoman Divacky       FullDef = true;
967f22ef01cSRoman Divacky   }
968f22ef01cSRoman Divacky   // A partial redefine uses Reg unless there is also a full define.
969f22ef01cSRoman Divacky   return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef);
970f22ef01cSRoman Divacky }
971f22ef01cSRoman Divacky 
972f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of
973f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs
974f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it
975f22ef01cSRoman Divacky /// also checks if there is a def of a super-register.
976f22ef01cSRoman Divacky int
findRegisterDefOperandIdx(unsigned Reg,bool isDead,bool Overlap,const TargetRegisterInfo * TRI) const977f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap,
978f22ef01cSRoman Divacky                                         const TargetRegisterInfo *TRI) const {
979f22ef01cSRoman Divacky   bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg);
980f22ef01cSRoman Divacky   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
981f22ef01cSRoman Divacky     const MachineOperand &MO = getOperand(i);
982dff0c46cSDimitry Andric     // Accept regmask operands when Overlap is set.
983dff0c46cSDimitry Andric     // Ignore them when looking for a specific def operand (Overlap == false).
984dff0c46cSDimitry Andric     if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg))
985dff0c46cSDimitry Andric       return i;
986f22ef01cSRoman Divacky     if (!MO.isReg() || !MO.isDef())
987f22ef01cSRoman Divacky       continue;
988f22ef01cSRoman Divacky     unsigned MOReg = MO.getReg();
989f22ef01cSRoman Divacky     bool Found = (MOReg == Reg);
990f22ef01cSRoman Divacky     if (!Found && TRI && isPhys &&
991f22ef01cSRoman Divacky         TargetRegisterInfo::isPhysicalRegister(MOReg)) {
992f22ef01cSRoman Divacky       if (Overlap)
993f22ef01cSRoman Divacky         Found = TRI->regsOverlap(MOReg, Reg);
994f22ef01cSRoman Divacky       else
995f22ef01cSRoman Divacky         Found = TRI->isSubRegister(MOReg, Reg);
996f22ef01cSRoman Divacky     }
997f22ef01cSRoman Divacky     if (Found && (!isDead || MO.isDead()))
998f22ef01cSRoman Divacky       return i;
999f22ef01cSRoman Divacky   }
1000f22ef01cSRoman Divacky   return -1;
1001f22ef01cSRoman Divacky }
1002f22ef01cSRoman Divacky 
1003f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the
1004f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if
1005f22ef01cSRoman Divacky /// none is found.
findFirstPredOperandIdx() const1006f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const {
10076122f3e6SDimitry Andric   // Don't call MCID.findFirstPredOperandIdx() because this variant
10086122f3e6SDimitry Andric   // is sometimes called on an instruction that's not yet complete, and
10096122f3e6SDimitry Andric   // so the number of operands is less than the MCID indicates. In
10106122f3e6SDimitry Andric   // particular, the PTX target does this.
101117a519f9SDimitry Andric   const MCInstrDesc &MCID = getDesc();
101217a519f9SDimitry Andric   if (MCID.isPredicable()) {
1013f22ef01cSRoman Divacky     for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
101417a519f9SDimitry Andric       if (MCID.OpInfo[i].isPredicate())
1015f22ef01cSRoman Divacky         return i;
1016f22ef01cSRoman Divacky   }
1017f22ef01cSRoman Divacky 
1018f22ef01cSRoman Divacky   return -1;
1019f22ef01cSRoman Divacky }
1020f22ef01cSRoman Divacky 
10213861d79fSDimitry Andric // MachineOperand::TiedTo is 4 bits wide.
10223861d79fSDimitry Andric const unsigned TiedMax = 15;
10236122f3e6SDimitry Andric 
10243861d79fSDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other.
10253861d79fSDimitry Andric ///
10263861d79fSDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo
10273861d79fSDimitry Andric /// field. TiedTo can have these values:
10283861d79fSDimitry Andric ///
10293861d79fSDimitry Andric /// 0:              Operand is not tied to anything.
10303861d79fSDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1).
10313861d79fSDimitry Andric /// TiedMax:        Tied to an operand >= TiedMax-1.
10323861d79fSDimitry Andric ///
10333861d79fSDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal
10343861d79fSDimitry Andric /// instruction. INLINEASM instructions allow more tied defs.
10353861d79fSDimitry Andric ///
tieOperands(unsigned DefIdx,unsigned UseIdx)10363861d79fSDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) {
10373861d79fSDimitry Andric   MachineOperand &DefMO = getOperand(DefIdx);
10383861d79fSDimitry Andric   MachineOperand &UseMO = getOperand(UseIdx);
10393861d79fSDimitry Andric   assert(DefMO.isDef() && "DefIdx must be a def operand");
10403861d79fSDimitry Andric   assert(UseMO.isUse() && "UseIdx must be a use operand");
10413861d79fSDimitry Andric   assert(!DefMO.isTied() && "Def is already tied to another use");
10423861d79fSDimitry Andric   assert(!UseMO.isTied() && "Use is already tied to another def");
10436122f3e6SDimitry Andric 
10443861d79fSDimitry Andric   if (DefIdx < TiedMax)
10453861d79fSDimitry Andric     UseMO.TiedTo = DefIdx + 1;
10463861d79fSDimitry Andric   else {
10473861d79fSDimitry Andric     // Inline asm can use the group descriptors to find tied operands, but on
10483861d79fSDimitry Andric     // normal instruction, the tied def must be within the first TiedMax
10493861d79fSDimitry Andric     // operands.
10503861d79fSDimitry Andric     assert(isInlineAsm() && "DefIdx out of range");
10513861d79fSDimitry Andric     UseMO.TiedTo = TiedMax;
10523861d79fSDimitry Andric   }
10533861d79fSDimitry Andric 
10543861d79fSDimitry Andric   // UseIdx can be out of range, we'll search for it in findTiedOperandIdx().
10553861d79fSDimitry Andric   DefMO.TiedTo = std::min(UseIdx + 1, TiedMax);
10563861d79fSDimitry Andric }
10573861d79fSDimitry Andric 
10583861d79fSDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to.
10593861d79fSDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand
10603861d79fSDimitry Andric /// which must exist.
findTiedOperandIdx(unsigned OpIdx) const10613861d79fSDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {
10623861d79fSDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
10633861d79fSDimitry Andric   assert(MO.isTied() && "Operand isn't tied");
10643861d79fSDimitry Andric 
10653861d79fSDimitry Andric   // Normally TiedTo is in range.
10663861d79fSDimitry Andric   if (MO.TiedTo < TiedMax)
10673861d79fSDimitry Andric     return MO.TiedTo - 1;
10683861d79fSDimitry Andric 
10693861d79fSDimitry Andric   // Uses on normal instructions can be out of range.
10703861d79fSDimitry Andric   if (!isInlineAsm()) {
10713861d79fSDimitry Andric     // Normal tied defs must be in the 0..TiedMax-1 range.
10723861d79fSDimitry Andric     if (MO.isUse())
10733861d79fSDimitry Andric       return TiedMax - 1;
10743861d79fSDimitry Andric     // MO is a def. Search for the tied use.
10753861d79fSDimitry Andric     for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) {
10763861d79fSDimitry Andric       const MachineOperand &UseMO = getOperand(i);
10773861d79fSDimitry Andric       if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1)
10783861d79fSDimitry Andric         return i;
10793861d79fSDimitry Andric     }
10803861d79fSDimitry Andric     llvm_unreachable("Can't find tied use");
10813861d79fSDimitry Andric   }
10823861d79fSDimitry Andric 
10833861d79fSDimitry Andric   // Now deal with inline asm by parsing the operand group descriptor flags.
10843861d79fSDimitry Andric   // Find the beginning of each operand group.
10853861d79fSDimitry Andric   SmallVector<unsigned, 8> GroupIdx;
10863861d79fSDimitry Andric   unsigned OpIdxGroup = ~0u;
10873861d79fSDimitry Andric   unsigned NumOps;
10883861d79fSDimitry Andric   for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
10893861d79fSDimitry Andric        i += NumOps) {
10903861d79fSDimitry Andric     const MachineOperand &FlagMO = getOperand(i);
10913861d79fSDimitry Andric     assert(FlagMO.isImm() && "Invalid tied operand on inline asm");
10923861d79fSDimitry Andric     unsigned CurGroup = GroupIdx.size();
10933861d79fSDimitry Andric     GroupIdx.push_back(i);
10943861d79fSDimitry Andric     NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm());
10953861d79fSDimitry Andric     // OpIdx belongs to this operand group.
10963861d79fSDimitry Andric     if (OpIdx > i && OpIdx < i + NumOps)
10973861d79fSDimitry Andric       OpIdxGroup = CurGroup;
10983861d79fSDimitry Andric     unsigned TiedGroup;
10993861d79fSDimitry Andric     if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup))
1100f22ef01cSRoman Divacky       continue;
11013861d79fSDimitry Andric     // Operands in this group are tied to operands in TiedGroup which must be
11023861d79fSDimitry Andric     // earlier. Find the number of operands between the two groups.
11033861d79fSDimitry Andric     unsigned Delta = i - GroupIdx[TiedGroup];
1104f22ef01cSRoman Divacky 
11053861d79fSDimitry Andric     // OpIdx is a use tied to TiedGroup.
11063861d79fSDimitry Andric     if (OpIdxGroup == CurGroup)
11073861d79fSDimitry Andric       return OpIdx - Delta;
1108f22ef01cSRoman Divacky 
11093861d79fSDimitry Andric     // OpIdx is a def tied to this use group.
11103861d79fSDimitry Andric     if (OpIdxGroup == TiedGroup)
11113861d79fSDimitry Andric       return OpIdx + Delta;
1112f22ef01cSRoman Divacky   }
11133861d79fSDimitry Andric   llvm_unreachable("Invalid tied operand on inline asm");
1114f22ef01cSRoman Divacky }
1115f22ef01cSRoman Divacky 
1116f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands.
1117f22ef01cSRoman Divacky ///
clearKillInfo()1118f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() {
1119ff0cc061SDimitry Andric   for (MachineOperand &MO : operands()) {
1120f22ef01cSRoman Divacky     if (MO.isReg() && MO.isUse())
1121f22ef01cSRoman Divacky       MO.setIsKill(false);
1122f22ef01cSRoman Divacky   }
1123f22ef01cSRoman Divacky }
1124f22ef01cSRoman Divacky 
substituteRegister(unsigned FromReg,unsigned ToReg,unsigned SubIdx,const TargetRegisterInfo & RegInfo)11254ba319b5SDimitry Andric void MachineInstr::substituteRegister(unsigned FromReg, unsigned ToReg,
1126ffd1746dSEd Schouten                                       unsigned SubIdx,
1127ffd1746dSEd Schouten                                       const TargetRegisterInfo &RegInfo) {
1128ffd1746dSEd Schouten   if (TargetRegisterInfo::isPhysicalRegister(ToReg)) {
1129ffd1746dSEd Schouten     if (SubIdx)
1130ffd1746dSEd Schouten       ToReg = RegInfo.getSubReg(ToReg, SubIdx);
1131ff0cc061SDimitry Andric     for (MachineOperand &MO : operands()) {
1132ffd1746dSEd Schouten       if (!MO.isReg() || MO.getReg() != FromReg)
1133ffd1746dSEd Schouten         continue;
1134ffd1746dSEd Schouten       MO.substPhysReg(ToReg, RegInfo);
1135ffd1746dSEd Schouten     }
1136ffd1746dSEd Schouten   } else {
1137ff0cc061SDimitry Andric     for (MachineOperand &MO : operands()) {
1138ffd1746dSEd Schouten       if (!MO.isReg() || MO.getReg() != FromReg)
1139ffd1746dSEd Schouten         continue;
1140ffd1746dSEd Schouten       MO.substVirtReg(ToReg, SubIdx, RegInfo);
1141ffd1746dSEd Schouten     }
1142ffd1746dSEd Schouten   }
1143ffd1746dSEd Schouten }
1144ffd1746dSEd Schouten 
1145f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If
1146f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between
1147f22ef01cSRoman Divacky /// the instruction's location and its intended destination.
isSafeToMove(AliasAnalysis * AA,bool & SawStore) const1148ff0cc061SDimitry Andric bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const {
1149f22ef01cSRoman Divacky   // Ignore stuff that we obviously can't move.
11503861d79fSDimitry Andric   //
11513861d79fSDimitry Andric   // Treat volatile loads as stores. This is not strictly necessary for
11523861d79fSDimitry Andric   // volatiles, but it is required for atomic loads. It is not allowed to move
11533861d79fSDimitry Andric   // a load across an atomic load with Ordering > Monotonic.
11542cab237bSDimitry Andric   if (mayStore() || isCall() || isPHI() ||
11553861d79fSDimitry Andric       (mayLoad() && hasOrderedMemoryRef())) {
1156f22ef01cSRoman Divacky     SawStore = true;
1157f22ef01cSRoman Divacky     return false;
1158f22ef01cSRoman Divacky   }
11592754fe60SDimitry Andric 
11604ba319b5SDimitry Andric   if (isPosition() || isDebugInstr() || isTerminator() ||
116191bc56edSDimitry Andric       hasUnmodeledSideEffects())
1162f22ef01cSRoman Divacky     return false;
1163f22ef01cSRoman Divacky 
1164f22ef01cSRoman Divacky   // See if this instruction does a load.  If so, we have to guarantee that the
1165f22ef01cSRoman Divacky   // loaded value doesn't change between the load and the its intended
1166f22ef01cSRoman Divacky   // destination. The check for isInvariantLoad gives the targe the chance to
1167f22ef01cSRoman Divacky   // classify the load as always returning a constant, e.g. a constant pool
1168f22ef01cSRoman Divacky   // load.
1169d88c1a5aSDimitry Andric   if (mayLoad() && !isDereferenceableInvariantLoad(AA))
1170f22ef01cSRoman Divacky     // Otherwise, this is a real load.  If there is a store between the load and
11713861d79fSDimitry Andric     // end of block, we can't move it.
11723861d79fSDimitry Andric     return !SawStore;
1173f22ef01cSRoman Divacky 
1174f22ef01cSRoman Divacky   return true;
1175f22ef01cSRoman Divacky }
1176f22ef01cSRoman Divacky 
mayAlias(AliasAnalysis * AA,MachineInstr & Other,bool UseTBAA)11777a7e6055SDimitry Andric bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other,
11787a7e6055SDimitry Andric                             bool UseTBAA) {
11792cab237bSDimitry Andric   const MachineFunction *MF = getMF();
11807a7e6055SDimitry Andric   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
11812cab237bSDimitry Andric   const MachineFrameInfo &MFI = MF->getFrameInfo();
11827a7e6055SDimitry Andric 
11837a7e6055SDimitry Andric   // If neither instruction stores to memory, they can't alias in any
11847a7e6055SDimitry Andric   // meaningful way, even if they read from the same address.
11857a7e6055SDimitry Andric   if (!mayStore() && !Other.mayStore())
11867a7e6055SDimitry Andric     return false;
11877a7e6055SDimitry Andric 
11887a7e6055SDimitry Andric   // Let the target decide if memory accesses cannot possibly overlap.
11897a7e6055SDimitry Andric   if (TII->areMemAccessesTriviallyDisjoint(*this, Other, AA))
11907a7e6055SDimitry Andric     return false;
11917a7e6055SDimitry Andric 
11927a7e6055SDimitry Andric   // FIXME: Need to handle multiple memory operands to support all targets.
11937a7e6055SDimitry Andric   if (!hasOneMemOperand() || !Other.hasOneMemOperand())
11947a7e6055SDimitry Andric     return true;
11957a7e6055SDimitry Andric 
11967a7e6055SDimitry Andric   MachineMemOperand *MMOa = *memoperands_begin();
11977a7e6055SDimitry Andric   MachineMemOperand *MMOb = *Other.memoperands_begin();
11987a7e6055SDimitry Andric 
11997a7e6055SDimitry Andric   // The following interface to AA is fashioned after DAGCombiner::isAlias
12007a7e6055SDimitry Andric   // and operates with MachineMemOperand offset with some important
12017a7e6055SDimitry Andric   // assumptions:
12027a7e6055SDimitry Andric   //   - LLVM fundamentally assumes flat address spaces.
12037a7e6055SDimitry Andric   //   - MachineOperand offset can *only* result from legalization and
12047a7e6055SDimitry Andric   //     cannot affect queries other than the trivial case of overlap
12057a7e6055SDimitry Andric   //     checking.
12067a7e6055SDimitry Andric   //   - These offsets never wrap and never step outside
12077a7e6055SDimitry Andric   //     of allocated objects.
12087a7e6055SDimitry Andric   //   - There should never be any negative offsets here.
12097a7e6055SDimitry Andric   //
12107a7e6055SDimitry Andric   // FIXME: Modify API to hide this math from "user"
12112cab237bSDimitry Andric   // Even before we go to AA we can reason locally about some
12127a7e6055SDimitry Andric   // memory objects. It can save compile time, and possibly catch some
12137a7e6055SDimitry Andric   // corner cases not currently covered.
12147a7e6055SDimitry Andric 
12152cab237bSDimitry Andric   int64_t OffsetA = MMOa->getOffset();
12162cab237bSDimitry Andric   int64_t OffsetB = MMOb->getOffset();
12172cab237bSDimitry Andric   int64_t MinOffset = std::min(OffsetA, OffsetB);
1218*b5893f02SDimitry Andric 
1219*b5893f02SDimitry Andric   uint64_t WidthA = MMOa->getSize();
1220*b5893f02SDimitry Andric   uint64_t WidthB = MMOb->getSize();
1221*b5893f02SDimitry Andric   bool KnownWidthA = WidthA != MemoryLocation::UnknownSize;
1222*b5893f02SDimitry Andric   bool KnownWidthB = WidthB != MemoryLocation::UnknownSize;
1223*b5893f02SDimitry Andric 
12242cab237bSDimitry Andric   const Value *ValA = MMOa->getValue();
12252cab237bSDimitry Andric   const Value *ValB = MMOb->getValue();
12262cab237bSDimitry Andric   bool SameVal = (ValA && ValB && (ValA == ValB));
12272cab237bSDimitry Andric   if (!SameVal) {
12282cab237bSDimitry Andric     const PseudoSourceValue *PSVa = MMOa->getPseudoValue();
12292cab237bSDimitry Andric     const PseudoSourceValue *PSVb = MMOb->getPseudoValue();
12302cab237bSDimitry Andric     if (PSVa && ValB && !PSVa->mayAlias(&MFI))
12312cab237bSDimitry Andric       return false;
12322cab237bSDimitry Andric     if (PSVb && ValA && !PSVb->mayAlias(&MFI))
12332cab237bSDimitry Andric       return false;
12342cab237bSDimitry Andric     if (PSVa && PSVb && (PSVa == PSVb))
12352cab237bSDimitry Andric       SameVal = true;
12362cab237bSDimitry Andric   }
12377a7e6055SDimitry Andric 
12382cab237bSDimitry Andric   if (SameVal) {
1239*b5893f02SDimitry Andric     if (!KnownWidthA || !KnownWidthB)
1240*b5893f02SDimitry Andric       return true;
12412cab237bSDimitry Andric     int64_t MaxOffset = std::max(OffsetA, OffsetB);
12422cab237bSDimitry Andric     int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB;
12432cab237bSDimitry Andric     return (MinOffset + LowWidth > MaxOffset);
12442cab237bSDimitry Andric   }
12452cab237bSDimitry Andric 
12462cab237bSDimitry Andric   if (!AA)
12472cab237bSDimitry Andric     return true;
12482cab237bSDimitry Andric 
12492cab237bSDimitry Andric   if (!ValA || !ValB)
12502cab237bSDimitry Andric     return true;
12512cab237bSDimitry Andric 
12522cab237bSDimitry Andric   assert((OffsetA >= 0) && "Negative MachineMemOperand offset");
12532cab237bSDimitry Andric   assert((OffsetB >= 0) && "Negative MachineMemOperand offset");
12542cab237bSDimitry Andric 
1255*b5893f02SDimitry Andric   int64_t OverlapA = KnownWidthA ? WidthA + OffsetA - MinOffset
1256*b5893f02SDimitry Andric                                  : MemoryLocation::UnknownSize;
1257*b5893f02SDimitry Andric   int64_t OverlapB = KnownWidthB ? WidthB + OffsetB - MinOffset
1258*b5893f02SDimitry Andric                                  : MemoryLocation::UnknownSize;
12592cab237bSDimitry Andric 
12602cab237bSDimitry Andric   AliasResult AAResult = AA->alias(
1261*b5893f02SDimitry Andric       MemoryLocation(ValA, OverlapA,
12627a7e6055SDimitry Andric                      UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
1263*b5893f02SDimitry Andric       MemoryLocation(ValB, OverlapB,
12647a7e6055SDimitry Andric                      UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
12657a7e6055SDimitry Andric 
12667a7e6055SDimitry Andric   return (AAResult != NoAlias);
12677a7e6055SDimitry Andric }
12687a7e6055SDimitry Andric 
12693861d79fSDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered
12703861d79fSDimitry Andric /// or volatile memory reference, or if the information describing the memory
12713861d79fSDimitry Andric /// reference is not available. Return false if it is known to have no ordered
12723861d79fSDimitry Andric /// memory references.
hasOrderedMemoryRef() const12733861d79fSDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const {
1274f22ef01cSRoman Divacky   // An instruction known never to access memory won't have a volatile access.
1275dff0c46cSDimitry Andric   if (!mayStore() &&
1276dff0c46cSDimitry Andric       !mayLoad() &&
1277dff0c46cSDimitry Andric       !isCall() &&
12782754fe60SDimitry Andric       !hasUnmodeledSideEffects())
1279f22ef01cSRoman Divacky     return false;
1280f22ef01cSRoman Divacky 
1281f22ef01cSRoman Divacky   // Otherwise, if the instruction has no memory reference information,
1282f22ef01cSRoman Divacky   // conservatively assume it wasn't preserved.
1283f22ef01cSRoman Divacky   if (memoperands_empty())
1284f22ef01cSRoman Divacky     return true;
1285f22ef01cSRoman Divacky 
12863ca95b02SDimitry Andric   // Check if any of our memory operands are ordered.
1287f9448bf3SDimitry Andric   return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) {
12883ca95b02SDimitry Andric     return !MMO->isUnordered();
12893ca95b02SDimitry Andric   });
1290f22ef01cSRoman Divacky }
1291f22ef01cSRoman Divacky 
1292d88c1a5aSDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never
1293d88c1a5aSDimitry Andric /// trap and is loading from a location whose value is invariant across a run of
1294d88c1a5aSDimitry Andric /// this function.
isDereferenceableInvariantLoad(AliasAnalysis * AA) const1295d88c1a5aSDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad(AliasAnalysis *AA) const {
1296f22ef01cSRoman Divacky   // If the instruction doesn't load at all, it isn't an invariant load.
1297dff0c46cSDimitry Andric   if (!mayLoad())
1298f22ef01cSRoman Divacky     return false;
1299f22ef01cSRoman Divacky 
1300f22ef01cSRoman Divacky   // If the instruction has lost its memoperands, conservatively assume that
1301f22ef01cSRoman Divacky   // it may not be an invariant load.
1302f22ef01cSRoman Divacky   if (memoperands_empty())
1303f22ef01cSRoman Divacky     return false;
1304f22ef01cSRoman Divacky 
1305d88c1a5aSDimitry Andric   const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo();
1306f22ef01cSRoman Divacky 
13073ca95b02SDimitry Andric   for (MachineMemOperand *MMO : memoperands()) {
13083ca95b02SDimitry Andric     if (MMO->isVolatile()) return false;
13093ca95b02SDimitry Andric     if (MMO->isStore()) return false;
1310d88c1a5aSDimitry Andric     if (MMO->isInvariant() && MMO->isDereferenceable())
1311d88c1a5aSDimitry Andric       continue;
131291bc56edSDimitry Andric 
1313f22ef01cSRoman Divacky     // A load from a constant PseudoSourceValue is invariant.
13143ca95b02SDimitry Andric     if (const PseudoSourceValue *PSV = MMO->getPseudoValue())
1315d88c1a5aSDimitry Andric       if (PSV->isConstant(&MFI))
1316f22ef01cSRoman Divacky         continue;
131791bc56edSDimitry Andric 
13183ca95b02SDimitry Andric     if (const Value *V = MMO->getValue()) {
1319f22ef01cSRoman Divacky       // If we have an AliasAnalysis, ask it whether the memory is constant.
13208f0fd8f6SDimitry Andric       if (AA &&
13218f0fd8f6SDimitry Andric           AA->pointsToConstantMemory(
13223ca95b02SDimitry Andric               MemoryLocation(V, MMO->getSize(), MMO->getAAInfo())))
1323f22ef01cSRoman Divacky         continue;
1324f22ef01cSRoman Divacky     }
1325f22ef01cSRoman Divacky 
1326f22ef01cSRoman Divacky     // Otherwise assume conservatively.
1327f22ef01cSRoman Divacky     return false;
1328f22ef01cSRoman Divacky   }
1329f22ef01cSRoman Divacky 
1330f22ef01cSRoman Divacky   // Everything checks out.
1331f22ef01cSRoman Divacky   return true;
1332f22ef01cSRoman Divacky }
1333f22ef01cSRoman Divacky 
1334f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always
1335f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise
1336f22ef01cSRoman Divacky /// return 0.
isConstantValuePHI() const1337f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const {
1338f22ef01cSRoman Divacky   if (!isPHI())
1339f22ef01cSRoman Divacky     return 0;
1340f22ef01cSRoman Divacky   assert(getNumOperands() >= 3 &&
1341f22ef01cSRoman Divacky          "It's illegal to have a PHI without source operands");
1342f22ef01cSRoman Divacky 
1343f22ef01cSRoman Divacky   unsigned Reg = getOperand(1).getReg();
1344f22ef01cSRoman Divacky   for (unsigned i = 3, e = getNumOperands(); i < e; i += 2)
1345f22ef01cSRoman Divacky     if (getOperand(i).getReg() != Reg)
1346f22ef01cSRoman Divacky       return 0;
1347f22ef01cSRoman Divacky   return Reg;
1348f22ef01cSRoman Divacky }
1349f22ef01cSRoman Divacky 
hasUnmodeledSideEffects() const13502754fe60SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const {
1351dff0c46cSDimitry Andric   if (hasProperty(MCID::UnmodeledSideEffects))
13522754fe60SDimitry Andric     return true;
13532754fe60SDimitry Andric   if (isInlineAsm()) {
13542754fe60SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
13552754fe60SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
13562754fe60SDimitry Andric       return true;
13572754fe60SDimitry Andric   }
13582754fe60SDimitry Andric 
13592754fe60SDimitry Andric   return false;
13602754fe60SDimitry Andric }
13612754fe60SDimitry Andric 
isLoadFoldBarrier() const13627d523365SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const {
13637d523365SDimitry Andric   return mayStore() || isCall() || hasUnmodeledSideEffects();
13647d523365SDimitry Andric }
13657d523365SDimitry Andric 
1366f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead.
1367f22ef01cSRoman Divacky ///
allDefsAreDead() const1368f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const {
1369ff0cc061SDimitry Andric   for (const MachineOperand &MO : operands()) {
1370f22ef01cSRoman Divacky     if (!MO.isReg() || MO.isUse())
1371f22ef01cSRoman Divacky       continue;
1372f22ef01cSRoman Divacky     if (!MO.isDead())
1373f22ef01cSRoman Divacky       return false;
1374f22ef01cSRoman Divacky   }
1375f22ef01cSRoman Divacky   return true;
1376f22ef01cSRoman Divacky }
1377f22ef01cSRoman Divacky 
13782754fe60SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified
13792754fe60SDimitry Andric /// instruction to this instruction.
copyImplicitOps(MachineFunction & MF,const MachineInstr & MI)1380139f7f9bSDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF,
13813ca95b02SDimitry Andric                                    const MachineInstr &MI) {
13823ca95b02SDimitry Andric   for (unsigned i = MI.getDesc().getNumOperands(), e = MI.getNumOperands();
13832754fe60SDimitry Andric        i != e; ++i) {
13843ca95b02SDimitry Andric     const MachineOperand &MO = MI.getOperand(i);
138591bc56edSDimitry Andric     if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask())
1386139f7f9bSDimitry Andric       addOperand(MF, MO);
13872754fe60SDimitry Andric   }
13882754fe60SDimitry Andric }
13892754fe60SDimitry Andric 
hasComplexRegisterTies() const13902cab237bSDimitry Andric bool MachineInstr::hasComplexRegisterTies() const {
13912cab237bSDimitry Andric   const MCInstrDesc &MCID = getDesc();
13922cab237bSDimitry Andric   for (unsigned I = 0, E = getNumOperands(); I < E; ++I) {
13932cab237bSDimitry Andric     const auto &Operand = getOperand(I);
13942cab237bSDimitry Andric     if (!Operand.isReg() || Operand.isDef())
13952cab237bSDimitry Andric       // Ignore the defined registers as MCID marks only the uses as tied.
13962cab237bSDimitry Andric       continue;
13972cab237bSDimitry Andric     int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO);
13982cab237bSDimitry Andric     int TiedIdx = Operand.isTied() ? int(findTiedOperandIdx(I)) : -1;
13992cab237bSDimitry Andric     if (ExpectedTiedIdx != TiedIdx)
14002cab237bSDimitry Andric       return true;
14012cab237bSDimitry Andric   }
14022cab237bSDimitry Andric   return false;
14032cab237bSDimitry Andric }
14042cab237bSDimitry Andric 
getTypeToPrint(unsigned OpIdx,SmallBitVector & PrintedTypes,const MachineRegisterInfo & MRI) const14052cab237bSDimitry Andric LLT MachineInstr::getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes,
14062cab237bSDimitry Andric                                  const MachineRegisterInfo &MRI) const {
14072cab237bSDimitry Andric   const MachineOperand &Op = getOperand(OpIdx);
14082cab237bSDimitry Andric   if (!Op.isReg())
14092cab237bSDimitry Andric     return LLT{};
14102cab237bSDimitry Andric 
14112cab237bSDimitry Andric   if (isVariadic() || OpIdx >= getNumExplicitOperands())
14122cab237bSDimitry Andric     return MRI.getType(Op.getReg());
14132cab237bSDimitry Andric 
14142cab237bSDimitry Andric   auto &OpInfo = getDesc().OpInfo[OpIdx];
14152cab237bSDimitry Andric   if (!OpInfo.isGenericType())
14162cab237bSDimitry Andric     return MRI.getType(Op.getReg());
14172cab237bSDimitry Andric 
14182cab237bSDimitry Andric   if (PrintedTypes[OpInfo.getGenericTypeIndex()])
14192cab237bSDimitry Andric     return LLT{};
14202cab237bSDimitry Andric 
14214ba319b5SDimitry Andric   LLT TypeToPrint = MRI.getType(Op.getReg());
14224ba319b5SDimitry Andric   // Don't mark the type index printed if it wasn't actually printed: maybe
14234ba319b5SDimitry Andric   // another operand with the same type index has an actual type attached:
14244ba319b5SDimitry Andric   if (TypeToPrint.isValid())
14252cab237bSDimitry Andric     PrintedTypes.set(OpInfo.getGenericTypeIndex());
14264ba319b5SDimitry Andric   return TypeToPrint;
14272cab237bSDimitry Andric }
14282cab237bSDimitry Andric 
14293861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const14307a7e6055SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const {
1431d88c1a5aSDimitry Andric   dbgs() << "  ";
14327a7e6055SDimitry Andric   print(dbgs());
1433f22ef01cSRoman Divacky }
14347a7e6055SDimitry Andric #endif
1435f22ef01cSRoman Divacky 
print(raw_ostream & OS,bool IsStandalone,bool SkipOpers,bool SkipDebugLoc,bool AddNewLine,const TargetInstrInfo * TII) const14364ba319b5SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool IsStandalone, bool SkipOpers,
14374ba319b5SDimitry Andric                          bool SkipDebugLoc, bool AddNewLine,
1438d88c1a5aSDimitry Andric                          const TargetInstrInfo *TII) const {
14393dac3a9bSDimitry Andric   const Module *M = nullptr;
14404ba319b5SDimitry Andric   const Function *F = nullptr;
14414ba319b5SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(*this)) {
14424ba319b5SDimitry Andric     F = &MF->getFunction();
14434ba319b5SDimitry Andric     M = F->getParent();
14444ba319b5SDimitry Andric     if (!TII)
14454ba319b5SDimitry Andric       TII = MF->getSubtarget().getInstrInfo();
14464ba319b5SDimitry Andric   }
14473dac3a9bSDimitry Andric 
14483dac3a9bSDimitry Andric   ModuleSlotTracker MST(M);
14494ba319b5SDimitry Andric   if (F)
14504ba319b5SDimitry Andric     MST.incorporateFunction(*F);
14514ba319b5SDimitry Andric   print(OS, MST, IsStandalone, SkipOpers, SkipDebugLoc, TII);
14523dac3a9bSDimitry Andric }
14533dac3a9bSDimitry Andric 
print(raw_ostream & OS,ModuleSlotTracker & MST,bool IsStandalone,bool SkipOpers,bool SkipDebugLoc,bool AddNewLine,const TargetInstrInfo * TII) const14543dac3a9bSDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
14554ba319b5SDimitry Andric                          bool IsStandalone, bool SkipOpers, bool SkipDebugLoc,
14564ba319b5SDimitry Andric                          bool AddNewLine, const TargetInstrInfo *TII) const {
1457ff0cc061SDimitry Andric   // We can be a bit tidier if we know the MachineFunction.
145891bc56edSDimitry Andric   const MachineFunction *MF = nullptr;
1459ff0cc061SDimitry Andric   const TargetRegisterInfo *TRI = nullptr;
146091bc56edSDimitry Andric   const MachineRegisterInfo *MRI = nullptr;
1461d88c1a5aSDimitry Andric   const TargetIntrinsicInfo *IntrinsicInfo = nullptr;
14624ba319b5SDimitry Andric   tryToGetTargetInfo(*this, TRI, MRI, IntrinsicInfo, TII);
1463d88c1a5aSDimitry Andric 
14644ba319b5SDimitry Andric   if (isCFIInstruction())
14654ba319b5SDimitry Andric     assert(getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
1466e580952dSDimitry Andric 
14672cab237bSDimitry Andric   SmallBitVector PrintedTypes(8);
1468*b5893f02SDimitry Andric   bool ShouldPrintRegisterTies = IsStandalone || hasComplexRegisterTies();
14692cab237bSDimitry Andric   auto getTiedOperandIdx = [&](unsigned OpIdx) {
14702cab237bSDimitry Andric     if (!ShouldPrintRegisterTies)
14712cab237bSDimitry Andric       return 0U;
14722cab237bSDimitry Andric     const MachineOperand &MO = getOperand(OpIdx);
14732cab237bSDimitry Andric     if (MO.isReg() && MO.isTied() && !MO.isDef())
14742cab237bSDimitry Andric       return findTiedOperandIdx(OpIdx);
14752cab237bSDimitry Andric     return 0U;
14762cab237bSDimitry Andric   };
14774ba319b5SDimitry Andric   unsigned StartOp = 0;
14784ba319b5SDimitry Andric   unsigned e = getNumOperands();
14794ba319b5SDimitry Andric 
1480f22ef01cSRoman Divacky   // Print explicitly defined operands on the left of an assignment syntax.
14814ba319b5SDimitry Andric   while (StartOp < e) {
14824ba319b5SDimitry Andric     const MachineOperand &MO = getOperand(StartOp);
14834ba319b5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
14844ba319b5SDimitry Andric       break;
14854ba319b5SDimitry Andric 
14862cab237bSDimitry Andric     if (StartOp != 0)
14872cab237bSDimitry Andric       OS << ", ";
14884ba319b5SDimitry Andric 
14892cab237bSDimitry Andric     LLT TypeToPrint = MRI ? getTypeToPrint(StartOp, PrintedTypes, *MRI) : LLT{};
14902cab237bSDimitry Andric     unsigned TiedOperandIdx = getTiedOperandIdx(StartOp);
14914ba319b5SDimitry Andric     MO.print(OS, MST, TypeToPrint, /*PrintDef=*/false, IsStandalone,
14924ba319b5SDimitry Andric              ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
14934ba319b5SDimitry Andric     ++StartOp;
1494f22ef01cSRoman Divacky   }
1495f22ef01cSRoman Divacky 
1496f22ef01cSRoman Divacky   if (StartOp != 0)
1497f22ef01cSRoman Divacky     OS << " = ";
1498f22ef01cSRoman Divacky 
14994ba319b5SDimitry Andric   if (getFlag(MachineInstr::FrameSetup))
15004ba319b5SDimitry Andric     OS << "frame-setup ";
15014ba319b5SDimitry Andric   if (getFlag(MachineInstr::FrameDestroy))
15024ba319b5SDimitry Andric     OS << "frame-destroy ";
15034ba319b5SDimitry Andric   if (getFlag(MachineInstr::FmNoNans))
15044ba319b5SDimitry Andric     OS << "nnan ";
15054ba319b5SDimitry Andric   if (getFlag(MachineInstr::FmNoInfs))
15064ba319b5SDimitry Andric     OS << "ninf ";
15074ba319b5SDimitry Andric   if (getFlag(MachineInstr::FmNsz))
15084ba319b5SDimitry Andric     OS << "nsz ";
15094ba319b5SDimitry Andric   if (getFlag(MachineInstr::FmArcp))
15104ba319b5SDimitry Andric     OS << "arcp ";
15114ba319b5SDimitry Andric   if (getFlag(MachineInstr::FmContract))
15124ba319b5SDimitry Andric     OS << "contract ";
15134ba319b5SDimitry Andric   if (getFlag(MachineInstr::FmAfn))
15144ba319b5SDimitry Andric     OS << "afn ";
15154ba319b5SDimitry Andric   if (getFlag(MachineInstr::FmReassoc))
15164ba319b5SDimitry Andric     OS << "reassoc ";
1517*b5893f02SDimitry Andric   if (getFlag(MachineInstr::NoUWrap))
1518*b5893f02SDimitry Andric     OS << "nuw ";
1519*b5893f02SDimitry Andric   if (getFlag(MachineInstr::NoSWrap))
1520*b5893f02SDimitry Andric     OS << "nsw ";
1521*b5893f02SDimitry Andric   if (getFlag(MachineInstr::IsExact))
1522*b5893f02SDimitry Andric     OS << "exact ";
15234ba319b5SDimitry Andric 
1524f22ef01cSRoman Divacky   // Print the opcode name.
1525ff0cc061SDimitry Andric   if (TII)
1526ff0cc061SDimitry Andric     OS << TII->getName(getOpcode());
1527dff0c46cSDimitry Andric   else
1528dff0c46cSDimitry Andric     OS << "UNKNOWN";
1529f22ef01cSRoman Divacky 
1530139f7f9bSDimitry Andric   if (SkipOpers)
1531139f7f9bSDimitry Andric     return;
1532139f7f9bSDimitry Andric 
1533f22ef01cSRoman Divacky   // Print the rest of the operands.
1534f22ef01cSRoman Divacky   bool FirstOp = true;
153517a519f9SDimitry Andric   unsigned AsmDescOp = ~0u;
153617a519f9SDimitry Andric   unsigned AsmOpCount = 0;
15372754fe60SDimitry Andric 
15386122f3e6SDimitry Andric   if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {
15392754fe60SDimitry Andric     // Print asm string.
15402754fe60SDimitry Andric     OS << " ";
15412cab237bSDimitry Andric     const unsigned OpIdx = InlineAsm::MIOp_AsmString;
15422cab237bSDimitry Andric     LLT TypeToPrint = MRI ? getTypeToPrint(OpIdx, PrintedTypes, *MRI) : LLT{};
15432cab237bSDimitry Andric     unsigned TiedOperandIdx = getTiedOperandIdx(OpIdx);
15444ba319b5SDimitry Andric     getOperand(OpIdx).print(OS, MST, TypeToPrint, /*PrintDef=*/true, IsStandalone,
15452cab237bSDimitry Andric                             ShouldPrintRegisterTies, TiedOperandIdx, TRI,
15462cab237bSDimitry Andric                             IntrinsicInfo);
15472754fe60SDimitry Andric 
1548139f7f9bSDimitry Andric     // Print HasSideEffects, MayLoad, MayStore, IsAlignStack
15492754fe60SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
15502754fe60SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
15512754fe60SDimitry Andric       OS << " [sideeffect]";
1552139f7f9bSDimitry Andric     if (ExtraInfo & InlineAsm::Extra_MayLoad)
1553139f7f9bSDimitry Andric       OS << " [mayload]";
1554139f7f9bSDimitry Andric     if (ExtraInfo & InlineAsm::Extra_MayStore)
1555139f7f9bSDimitry Andric       OS << " [maystore]";
15563ca95b02SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsConvergent)
15573ca95b02SDimitry Andric       OS << " [isconvergent]";
15582754fe60SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
15592754fe60SDimitry Andric       OS << " [alignstack]";
15603861d79fSDimitry Andric     if (getInlineAsmDialect() == InlineAsm::AD_ATT)
15613861d79fSDimitry Andric       OS << " [attdialect]";
15623861d79fSDimitry Andric     if (getInlineAsmDialect() == InlineAsm::AD_Intel)
15633861d79fSDimitry Andric       OS << " [inteldialect]";
15642754fe60SDimitry Andric 
156517a519f9SDimitry Andric     StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand;
15662754fe60SDimitry Andric     FirstOp = false;
15672754fe60SDimitry Andric   }
15682754fe60SDimitry Andric 
1569f22ef01cSRoman Divacky   for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
1570f22ef01cSRoman Divacky     const MachineOperand &MO = getOperand(i);
1571f22ef01cSRoman Divacky 
1572f22ef01cSRoman Divacky     if (FirstOp) FirstOp = false; else OS << ",";
1573f22ef01cSRoman Divacky     OS << " ";
15744ba319b5SDimitry Andric 
1575f22ef01cSRoman Divacky     if (isDebugValue() && MO.isMetadata()) {
1576f22ef01cSRoman Divacky       // Pretty print DBG_VALUE instructions.
1577ff0cc061SDimitry Andric       auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata());
1578ff0cc061SDimitry Andric       if (DIV && !DIV->getName().empty())
1579ff0cc061SDimitry Andric         OS << "!\"" << DIV->getName() << '\"';
15802cab237bSDimitry Andric       else {
15812cab237bSDimitry Andric         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
15822cab237bSDimitry Andric         unsigned TiedOperandIdx = getTiedOperandIdx(i);
15834ba319b5SDimitry Andric         MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, IsStandalone,
15842cab237bSDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
15852cab237bSDimitry Andric       }
15864ba319b5SDimitry Andric     } else if (isDebugLabel() && MO.isMetadata()) {
15874ba319b5SDimitry Andric       // Pretty print DBG_LABEL instructions.
15884ba319b5SDimitry Andric       auto *DIL = dyn_cast<DILabel>(MO.getMetadata());
15894ba319b5SDimitry Andric       if (DIL && !DIL->getName().empty())
15904ba319b5SDimitry Andric         OS << "\"" << DIL->getName() << '\"';
15914ba319b5SDimitry Andric       else {
15924ba319b5SDimitry Andric         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
15934ba319b5SDimitry Andric         unsigned TiedOperandIdx = getTiedOperandIdx(i);
15944ba319b5SDimitry Andric         MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, IsStandalone,
15954ba319b5SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
15964ba319b5SDimitry Andric       }
159717a519f9SDimitry Andric     } else if (i == AsmDescOp && MO.isImm()) {
159817a519f9SDimitry Andric       // Pretty print the inline asm operand descriptor.
159917a519f9SDimitry Andric       OS << '$' << AsmOpCount++;
160017a519f9SDimitry Andric       unsigned Flag = MO.getImm();
160117a519f9SDimitry Andric       switch (InlineAsm::getKind(Flag)) {
16026122f3e6SDimitry Andric       case InlineAsm::Kind_RegUse:             OS << ":[reguse"; break;
16036122f3e6SDimitry Andric       case InlineAsm::Kind_RegDef:             OS << ":[regdef"; break;
16046122f3e6SDimitry Andric       case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break;
16056122f3e6SDimitry Andric       case InlineAsm::Kind_Clobber:            OS << ":[clobber"; break;
16066122f3e6SDimitry Andric       case InlineAsm::Kind_Imm:                OS << ":[imm"; break;
16076122f3e6SDimitry Andric       case InlineAsm::Kind_Mem:                OS << ":[mem"; break;
16086122f3e6SDimitry Andric       default: OS << ":[??" << InlineAsm::getKind(Flag); break;
16096122f3e6SDimitry Andric       }
16106122f3e6SDimitry Andric 
16116122f3e6SDimitry Andric       unsigned RCID = 0;
16123ca95b02SDimitry Andric       if (!InlineAsm::isImmKind(Flag) && !InlineAsm::isMemKind(Flag) &&
16133ca95b02SDimitry Andric           InlineAsm::hasRegClassConstraint(Flag, RCID)) {
1614ff0cc061SDimitry Andric         if (TRI) {
1615ff0cc061SDimitry Andric           OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID));
161639d628a0SDimitry Andric         } else
16176122f3e6SDimitry Andric           OS << ":RC" << RCID;
161817a519f9SDimitry Andric       }
161917a519f9SDimitry Andric 
16203ca95b02SDimitry Andric       if (InlineAsm::isMemKind(Flag)) {
16213ca95b02SDimitry Andric         unsigned MCID = InlineAsm::getMemoryConstraintID(Flag);
16223ca95b02SDimitry Andric         switch (MCID) {
16233ca95b02SDimitry Andric         case InlineAsm::Constraint_es: OS << ":es"; break;
16243ca95b02SDimitry Andric         case InlineAsm::Constraint_i:  OS << ":i"; break;
16253ca95b02SDimitry Andric         case InlineAsm::Constraint_m:  OS << ":m"; break;
16263ca95b02SDimitry Andric         case InlineAsm::Constraint_o:  OS << ":o"; break;
16273ca95b02SDimitry Andric         case InlineAsm::Constraint_v:  OS << ":v"; break;
16283ca95b02SDimitry Andric         case InlineAsm::Constraint_Q:  OS << ":Q"; break;
16293ca95b02SDimitry Andric         case InlineAsm::Constraint_R:  OS << ":R"; break;
16303ca95b02SDimitry Andric         case InlineAsm::Constraint_S:  OS << ":S"; break;
16313ca95b02SDimitry Andric         case InlineAsm::Constraint_T:  OS << ":T"; break;
16323ca95b02SDimitry Andric         case InlineAsm::Constraint_Um: OS << ":Um"; break;
16333ca95b02SDimitry Andric         case InlineAsm::Constraint_Un: OS << ":Un"; break;
16343ca95b02SDimitry Andric         case InlineAsm::Constraint_Uq: OS << ":Uq"; break;
16353ca95b02SDimitry Andric         case InlineAsm::Constraint_Us: OS << ":Us"; break;
16363ca95b02SDimitry Andric         case InlineAsm::Constraint_Ut: OS << ":Ut"; break;
16373ca95b02SDimitry Andric         case InlineAsm::Constraint_Uv: OS << ":Uv"; break;
16383ca95b02SDimitry Andric         case InlineAsm::Constraint_Uy: OS << ":Uy"; break;
16393ca95b02SDimitry Andric         case InlineAsm::Constraint_X:  OS << ":X"; break;
16403ca95b02SDimitry Andric         case InlineAsm::Constraint_Z:  OS << ":Z"; break;
16413ca95b02SDimitry Andric         case InlineAsm::Constraint_ZC: OS << ":ZC"; break;
16423ca95b02SDimitry Andric         case InlineAsm::Constraint_Zy: OS << ":Zy"; break;
16433ca95b02SDimitry Andric         default: OS << ":?"; break;
16443ca95b02SDimitry Andric         }
16453ca95b02SDimitry Andric       }
16463ca95b02SDimitry Andric 
164717a519f9SDimitry Andric       unsigned TiedTo = 0;
164817a519f9SDimitry Andric       if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo))
16496122f3e6SDimitry Andric         OS << " tiedto:$" << TiedTo;
16506122f3e6SDimitry Andric 
16516122f3e6SDimitry Andric       OS << ']';
165217a519f9SDimitry Andric 
165317a519f9SDimitry Andric       // Compute the index of the next operand descriptor.
165417a519f9SDimitry Andric       AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag);
16552cab237bSDimitry Andric     } else {
16562cab237bSDimitry Andric       LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
16572cab237bSDimitry Andric       unsigned TiedOperandIdx = getTiedOperandIdx(i);
16582cab237bSDimitry Andric       if (MO.isImm() && isOperandSubregIdx(i))
16594ba319b5SDimitry Andric         MachineOperand::printSubRegIdx(OS, MO.getImm(), TRI);
16602cab237bSDimitry Andric       else
16614ba319b5SDimitry Andric         MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, IsStandalone,
16622cab237bSDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
16632cab237bSDimitry Andric     }
1664f22ef01cSRoman Divacky   }
1665f22ef01cSRoman Divacky 
1666*b5893f02SDimitry Andric   // Print any optional symbols attached to this instruction as-if they were
1667*b5893f02SDimitry Andric   // operands.
1668*b5893f02SDimitry Andric   if (MCSymbol *PreInstrSymbol = getPreInstrSymbol()) {
1669*b5893f02SDimitry Andric     if (!FirstOp) {
1670*b5893f02SDimitry Andric       FirstOp = false;
1671*b5893f02SDimitry Andric       OS << ',';
1672*b5893f02SDimitry Andric     }
1673*b5893f02SDimitry Andric     OS << " pre-instr-symbol ";
1674*b5893f02SDimitry Andric     MachineOperand::printSymbol(OS, *PreInstrSymbol);
1675*b5893f02SDimitry Andric   }
1676*b5893f02SDimitry Andric   if (MCSymbol *PostInstrSymbol = getPostInstrSymbol()) {
1677*b5893f02SDimitry Andric     if (!FirstOp) {
1678*b5893f02SDimitry Andric       FirstOp = false;
1679*b5893f02SDimitry Andric       OS << ',';
1680*b5893f02SDimitry Andric     }
1681*b5893f02SDimitry Andric     OS << " post-instr-symbol ";
1682*b5893f02SDimitry Andric     MachineOperand::printSymbol(OS, *PostInstrSymbol);
1683*b5893f02SDimitry Andric   }
1684*b5893f02SDimitry Andric 
16854ba319b5SDimitry Andric   if (!SkipDebugLoc) {
16864ba319b5SDimitry Andric     if (const DebugLoc &DL = getDebugLoc()) {
16874ba319b5SDimitry Andric       if (!FirstOp)
16884ba319b5SDimitry Andric         OS << ',';
16894ba319b5SDimitry Andric       OS << " debug-location ";
16904ba319b5SDimitry Andric       DL->printAsOperand(OS, MST);
16914d0b32cdSDimitry Andric     }
16923b0f4066SDimitry Andric   }
16933b0f4066SDimitry Andric 
1694f22ef01cSRoman Divacky   if (!memoperands_empty()) {
16954ba319b5SDimitry Andric     SmallVector<StringRef, 0> SSNs;
16964ba319b5SDimitry Andric     const LLVMContext *Context = nullptr;
16974ba319b5SDimitry Andric     std::unique_ptr<LLVMContext> CtxPtr;
16984ba319b5SDimitry Andric     const MachineFrameInfo *MFI = nullptr;
16994ba319b5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
17004ba319b5SDimitry Andric       MFI = &MF->getFrameInfo();
17014ba319b5SDimitry Andric       Context = &MF->getFunction().getContext();
17024ba319b5SDimitry Andric     } else {
17034ba319b5SDimitry Andric       CtxPtr = llvm::make_unique<LLVMContext>();
17044ba319b5SDimitry Andric       Context = CtxPtr.get();
17054d0b32cdSDimitry Andric     }
1706f22ef01cSRoman Divacky 
17074ba319b5SDimitry Andric     OS << " :: ";
17084ba319b5SDimitry Andric     bool NeedComma = false;
17094ba319b5SDimitry Andric     for (const MachineMemOperand *Op : memoperands()) {
17104ba319b5SDimitry Andric       if (NeedComma)
17114ba319b5SDimitry Andric         OS << ", ";
17124ba319b5SDimitry Andric       Op->print(OS, MST, SSNs, *Context, MFI, TII);
17134ba319b5SDimitry Andric       NeedComma = true;
1714f22ef01cSRoman Divacky     }
1715f22ef01cSRoman Divacky   }
1716f22ef01cSRoman Divacky 
17174ba319b5SDimitry Andric   if (SkipDebugLoc)
17184ba319b5SDimitry Andric     return;
17194ba319b5SDimitry Andric 
17204ba319b5SDimitry Andric   bool HaveSemi = false;
1721e580952dSDimitry Andric 
17223b0f4066SDimitry Andric   // Print debug location information.
17234ba319b5SDimitry Andric   if (const DebugLoc &DL = getDebugLoc()) {
17244ba319b5SDimitry Andric     if (!HaveSemi) {
17254ba319b5SDimitry Andric       OS << ';';
17264ba319b5SDimitry Andric       HaveSemi = true;
17274ba319b5SDimitry Andric     }
17284ba319b5SDimitry Andric     OS << ' ';
17294ba319b5SDimitry Andric     DL.print(OS);
17304ba319b5SDimitry Andric   }
17314ba319b5SDimitry Andric 
17324ba319b5SDimitry Andric   // Print extra comments for DEBUG_VALUE.
1733ff0cc061SDimitry Andric   if (isDebugValue() && getOperand(e - 2).isMetadata()) {
17344ba319b5SDimitry Andric     if (!HaveSemi) {
17354d0b32cdSDimitry Andric       OS << ";";
17364ba319b5SDimitry Andric       HaveSemi = true;
17374ba319b5SDimitry Andric     }
1738ff0cc061SDimitry Andric     auto *DV = cast<DILocalVariable>(getOperand(e - 2).getMetadata());
1739ff0cc061SDimitry Andric     OS << " line no:" <<  DV->getLine();
1740ff0cc061SDimitry Andric     if (auto *InlinedAt = debugLoc->getInlinedAt()) {
1741ff0cc061SDimitry Andric       DebugLoc InlinedAtDL(InlinedAt);
1742ff0cc061SDimitry Andric       if (InlinedAtDL && MF) {
17436122f3e6SDimitry Andric         OS << " inlined @[ ";
1744ff0cc061SDimitry Andric         InlinedAtDL.print(OS);
17456122f3e6SDimitry Andric         OS << " ]";
17466122f3e6SDimitry Andric       }
17476122f3e6SDimitry Andric     }
174839d628a0SDimitry Andric     if (isIndirectDebugValue())
174939d628a0SDimitry Andric       OS << " indirect";
1750f22ef01cSRoman Divacky   }
17514ba319b5SDimitry Andric   // TODO: DBG_LABEL
1752f22ef01cSRoman Divacky 
17534ba319b5SDimitry Andric   if (AddNewLine)
17543b0f4066SDimitry Andric     OS << '\n';
1755f22ef01cSRoman Divacky }
1756f22ef01cSRoman Divacky 
addRegisterKilled(unsigned IncomingReg,const TargetRegisterInfo * RegInfo,bool AddIfNotFound)1757f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg,
1758f22ef01cSRoman Divacky                                      const TargetRegisterInfo *RegInfo,
1759f22ef01cSRoman Divacky                                      bool AddIfNotFound) {
1760f22ef01cSRoman Divacky   bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg);
17617ae0e2c9SDimitry Andric   bool hasAliases = isPhysReg &&
17627ae0e2c9SDimitry Andric     MCRegAliasIterator(IncomingReg, RegInfo, false).isValid();
1763f22ef01cSRoman Divacky   bool Found = false;
1764f22ef01cSRoman Divacky   SmallVector<unsigned,4> DeadOps;
1765f22ef01cSRoman Divacky   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
1766f22ef01cSRoman Divacky     MachineOperand &MO = getOperand(i);
1767f22ef01cSRoman Divacky     if (!MO.isReg() || !MO.isUse() || MO.isUndef())
1768f22ef01cSRoman Divacky       continue;
17693ca95b02SDimitry Andric 
17703ca95b02SDimitry Andric     // DEBUG_VALUE nodes do not contribute to code generation and should
17713ca95b02SDimitry Andric     // always be ignored. Failure to do so may result in trying to modify
17723ca95b02SDimitry Andric     // KILL flags on DEBUG_VALUE nodes.
17733ca95b02SDimitry Andric     if (MO.isDebug())
17743ca95b02SDimitry Andric       continue;
17753ca95b02SDimitry Andric 
1776f22ef01cSRoman Divacky     unsigned Reg = MO.getReg();
1777f22ef01cSRoman Divacky     if (!Reg)
1778f22ef01cSRoman Divacky       continue;
1779f22ef01cSRoman Divacky 
1780f22ef01cSRoman Divacky     if (Reg == IncomingReg) {
1781f22ef01cSRoman Divacky       if (!Found) {
1782f22ef01cSRoman Divacky         if (MO.isKill())
1783f22ef01cSRoman Divacky           // The register is already marked kill.
1784f22ef01cSRoman Divacky           return true;
1785f22ef01cSRoman Divacky         if (isPhysReg && isRegTiedToDefOperand(i))
1786f22ef01cSRoman Divacky           // Two-address uses of physregs must not be marked kill.
1787f22ef01cSRoman Divacky           return true;
1788f22ef01cSRoman Divacky         MO.setIsKill();
1789f22ef01cSRoman Divacky         Found = true;
1790f22ef01cSRoman Divacky       }
1791f22ef01cSRoman Divacky     } else if (hasAliases && MO.isKill() &&
1792f22ef01cSRoman Divacky                TargetRegisterInfo::isPhysicalRegister(Reg)) {
1793f22ef01cSRoman Divacky       // A super-register kill already exists.
1794f22ef01cSRoman Divacky       if (RegInfo->isSuperRegister(IncomingReg, Reg))
1795f22ef01cSRoman Divacky         return true;
1796f22ef01cSRoman Divacky       if (RegInfo->isSubRegister(IncomingReg, Reg))
1797f22ef01cSRoman Divacky         DeadOps.push_back(i);
1798f22ef01cSRoman Divacky     }
1799f22ef01cSRoman Divacky   }
1800f22ef01cSRoman Divacky 
1801f22ef01cSRoman Divacky   // Trim unneeded kill operands.
1802f22ef01cSRoman Divacky   while (!DeadOps.empty()) {
1803f22ef01cSRoman Divacky     unsigned OpIdx = DeadOps.back();
1804*b5893f02SDimitry Andric     if (getOperand(OpIdx).isImplicit() &&
1805*b5893f02SDimitry Andric         (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
1806f22ef01cSRoman Divacky       RemoveOperand(OpIdx);
1807f22ef01cSRoman Divacky     else
1808f22ef01cSRoman Divacky       getOperand(OpIdx).setIsKill(false);
1809f22ef01cSRoman Divacky     DeadOps.pop_back();
1810f22ef01cSRoman Divacky   }
1811f22ef01cSRoman Divacky 
1812f22ef01cSRoman Divacky   // If not found, this means an alias of one of the operands is killed. Add a
1813f22ef01cSRoman Divacky   // new implicit operand if required.
1814f22ef01cSRoman Divacky   if (!Found && AddIfNotFound) {
1815f22ef01cSRoman Divacky     addOperand(MachineOperand::CreateReg(IncomingReg,
1816f22ef01cSRoman Divacky                                          false /*IsDef*/,
1817f22ef01cSRoman Divacky                                          true  /*IsImp*/,
1818f22ef01cSRoman Divacky                                          true  /*IsKill*/));
1819f22ef01cSRoman Divacky     return true;
1820f22ef01cSRoman Divacky   }
1821f22ef01cSRoman Divacky   return Found;
1822f22ef01cSRoman Divacky }
1823f22ef01cSRoman Divacky 
clearRegisterKills(unsigned Reg,const TargetRegisterInfo * RegInfo)1824dff0c46cSDimitry Andric void MachineInstr::clearRegisterKills(unsigned Reg,
1825dff0c46cSDimitry Andric                                       const TargetRegisterInfo *RegInfo) {
1826dff0c46cSDimitry Andric   if (!TargetRegisterInfo::isPhysicalRegister(Reg))
182791bc56edSDimitry Andric     RegInfo = nullptr;
1828ff0cc061SDimitry Andric   for (MachineOperand &MO : operands()) {
1829dff0c46cSDimitry Andric     if (!MO.isReg() || !MO.isUse() || !MO.isKill())
1830dff0c46cSDimitry Andric       continue;
1831dff0c46cSDimitry Andric     unsigned OpReg = MO.getReg();
18323ca95b02SDimitry Andric     if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg)
1833dff0c46cSDimitry Andric       MO.setIsKill(false);
1834dff0c46cSDimitry Andric   }
1835dff0c46cSDimitry Andric }
1836dff0c46cSDimitry Andric 
addRegisterDead(unsigned Reg,const TargetRegisterInfo * RegInfo,bool AddIfNotFound)1837f785676fSDimitry Andric bool MachineInstr::addRegisterDead(unsigned Reg,
1838f22ef01cSRoman Divacky                                    const TargetRegisterInfo *RegInfo,
1839f22ef01cSRoman Divacky                                    bool AddIfNotFound) {
1840f785676fSDimitry Andric   bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg);
18417ae0e2c9SDimitry Andric   bool hasAliases = isPhysReg &&
1842f785676fSDimitry Andric     MCRegAliasIterator(Reg, RegInfo, false).isValid();
1843f22ef01cSRoman Divacky   bool Found = false;
1844f22ef01cSRoman Divacky   SmallVector<unsigned,4> DeadOps;
1845f22ef01cSRoman Divacky   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
1846f22ef01cSRoman Divacky     MachineOperand &MO = getOperand(i);
1847f22ef01cSRoman Divacky     if (!MO.isReg() || !MO.isDef())
1848f22ef01cSRoman Divacky       continue;
1849f785676fSDimitry Andric     unsigned MOReg = MO.getReg();
1850f785676fSDimitry Andric     if (!MOReg)
1851f22ef01cSRoman Divacky       continue;
1852f22ef01cSRoman Divacky 
1853f785676fSDimitry Andric     if (MOReg == Reg) {
1854f22ef01cSRoman Divacky       MO.setIsDead();
1855f22ef01cSRoman Divacky       Found = true;
1856f22ef01cSRoman Divacky     } else if (hasAliases && MO.isDead() &&
1857f785676fSDimitry Andric                TargetRegisterInfo::isPhysicalRegister(MOReg)) {
1858f22ef01cSRoman Divacky       // There exists a super-register that's marked dead.
1859f785676fSDimitry Andric       if (RegInfo->isSuperRegister(Reg, MOReg))
1860f22ef01cSRoman Divacky         return true;
1861f785676fSDimitry Andric       if (RegInfo->isSubRegister(Reg, MOReg))
1862f22ef01cSRoman Divacky         DeadOps.push_back(i);
1863f22ef01cSRoman Divacky     }
1864f22ef01cSRoman Divacky   }
1865f22ef01cSRoman Divacky 
1866f22ef01cSRoman Divacky   // Trim unneeded dead operands.
1867f22ef01cSRoman Divacky   while (!DeadOps.empty()) {
1868f22ef01cSRoman Divacky     unsigned OpIdx = DeadOps.back();
1869*b5893f02SDimitry Andric     if (getOperand(OpIdx).isImplicit() &&
1870*b5893f02SDimitry Andric         (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
1871f22ef01cSRoman Divacky       RemoveOperand(OpIdx);
1872f22ef01cSRoman Divacky     else
1873f22ef01cSRoman Divacky       getOperand(OpIdx).setIsDead(false);
1874f22ef01cSRoman Divacky     DeadOps.pop_back();
1875f22ef01cSRoman Divacky   }
1876f22ef01cSRoman Divacky 
1877f22ef01cSRoman Divacky   // If not found, this means an alias of one of the operands is dead. Add a
1878f22ef01cSRoman Divacky   // new implicit operand if required.
1879f22ef01cSRoman Divacky   if (Found || !AddIfNotFound)
1880f22ef01cSRoman Divacky     return Found;
1881f22ef01cSRoman Divacky 
1882f785676fSDimitry Andric   addOperand(MachineOperand::CreateReg(Reg,
1883f22ef01cSRoman Divacky                                        true  /*IsDef*/,
1884f22ef01cSRoman Divacky                                        true  /*IsImp*/,
1885f22ef01cSRoman Divacky                                        false /*IsKill*/,
1886f22ef01cSRoman Divacky                                        true  /*IsDead*/));
1887f22ef01cSRoman Divacky   return true;
1888f22ef01cSRoman Divacky }
1889f22ef01cSRoman Divacky 
clearRegisterDeads(unsigned Reg)1890ff0cc061SDimitry Andric void MachineInstr::clearRegisterDeads(unsigned Reg) {
1891ff0cc061SDimitry Andric   for (MachineOperand &MO : operands()) {
1892ff0cc061SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg)
1893ff0cc061SDimitry Andric       continue;
1894ff0cc061SDimitry Andric     MO.setIsDead(false);
1895ff0cc061SDimitry Andric   }
1896ff0cc061SDimitry Andric }
1897ff0cc061SDimitry Andric 
setRegisterDefReadUndef(unsigned Reg,bool IsUndef)18987d523365SDimitry Andric void MachineInstr::setRegisterDefReadUndef(unsigned Reg, bool IsUndef) {
1899ff0cc061SDimitry Andric   for (MachineOperand &MO : operands()) {
1900ff0cc061SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0)
1901ff0cc061SDimitry Andric       continue;
19027d523365SDimitry Andric     MO.setIsUndef(IsUndef);
1903ff0cc061SDimitry Andric   }
1904ff0cc061SDimitry Andric }
1905ff0cc061SDimitry Andric 
addRegisterDefined(unsigned Reg,const TargetRegisterInfo * RegInfo)1906f785676fSDimitry Andric void MachineInstr::addRegisterDefined(unsigned Reg,
1907f22ef01cSRoman Divacky                                       const TargetRegisterInfo *RegInfo) {
1908f785676fSDimitry Andric   if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
1909f785676fSDimitry Andric     MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo);
1910f22ef01cSRoman Divacky     if (MO)
1911f22ef01cSRoman Divacky       return;
1912f22ef01cSRoman Divacky   } else {
1913ff0cc061SDimitry Andric     for (const MachineOperand &MO : operands()) {
1914f785676fSDimitry Andric       if (MO.isReg() && MO.getReg() == Reg && MO.isDef() &&
1915f22ef01cSRoman Divacky           MO.getSubReg() == 0)
1916f22ef01cSRoman Divacky         return;
1917f22ef01cSRoman Divacky     }
1918f22ef01cSRoman Divacky   }
1919f785676fSDimitry Andric   addOperand(MachineOperand::CreateReg(Reg,
1920f22ef01cSRoman Divacky                                        true  /*IsDef*/,
1921f22ef01cSRoman Divacky                                        true  /*IsImp*/));
1922f22ef01cSRoman Divacky }
1923f22ef01cSRoman Divacky 
setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs,const TargetRegisterInfo & TRI)1924dff0c46cSDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs,
1925ffd1746dSEd Schouten                                          const TargetRegisterInfo &TRI) {
1926dff0c46cSDimitry Andric   bool HasRegMask = false;
1927ff0cc061SDimitry Andric   for (MachineOperand &MO : operands()) {
1928dff0c46cSDimitry Andric     if (MO.isRegMask()) {
1929dff0c46cSDimitry Andric       HasRegMask = true;
1930dff0c46cSDimitry Andric       continue;
1931dff0c46cSDimitry Andric     }
1932ffd1746dSEd Schouten     if (!MO.isReg() || !MO.isDef()) continue;
1933ffd1746dSEd Schouten     unsigned Reg = MO.getReg();
1934dff0c46cSDimitry Andric     if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
1935ffd1746dSEd Schouten     // If there are no uses, including partial uses, the def is dead.
1936f9448bf3SDimitry Andric     if (llvm::none_of(UsedRegs,
1937ff0cc061SDimitry Andric                       [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); }))
1938ff0cc061SDimitry Andric       MO.setIsDead();
1939ffd1746dSEd Schouten   }
1940dff0c46cSDimitry Andric 
1941dff0c46cSDimitry Andric   // This is a call with a register mask operand.
1942dff0c46cSDimitry Andric   // Mask clobbers are always dead, so add defs for the non-dead defines.
1943dff0c46cSDimitry Andric   if (HasRegMask)
1944dff0c46cSDimitry Andric     for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end();
1945dff0c46cSDimitry Andric          I != E; ++I)
1946dff0c46cSDimitry Andric       addRegisterDefined(*I, &TRI);
1947ffd1746dSEd Schouten }
1948ffd1746dSEd Schouten 
1949f22ef01cSRoman Divacky unsigned
getHashValue(const MachineInstr * const & MI)1950f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {
1951dff0c46cSDimitry Andric   // Build up a buffer of hash code components.
1952dff0c46cSDimitry Andric   SmallVector<size_t, 8> HashComponents;
1953dff0c46cSDimitry Andric   HashComponents.reserve(MI->getNumOperands() + 1);
1954dff0c46cSDimitry Andric   HashComponents.push_back(MI->getOpcode());
1955ff0cc061SDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
19567ae0e2c9SDimitry Andric     if (MO.isReg() && MO.isDef() &&
19577ae0e2c9SDimitry Andric         TargetRegisterInfo::isVirtualRegister(MO.getReg()))
1958f22ef01cSRoman Divacky       continue;  // Skip virtual register defs.
19597ae0e2c9SDimitry Andric 
19607ae0e2c9SDimitry Andric     HashComponents.push_back(hash_value(MO));
1961f22ef01cSRoman Divacky   }
1962dff0c46cSDimitry Andric   return hash_combine_range(HashComponents.begin(), HashComponents.end());
1963f22ef01cSRoman Divacky }
196417a519f9SDimitry Andric 
emitError(StringRef Msg) const196517a519f9SDimitry Andric void MachineInstr::emitError(StringRef Msg) const {
196617a519f9SDimitry Andric   // Find the source location cookie.
196717a519f9SDimitry Andric   unsigned LocCookie = 0;
196891bc56edSDimitry Andric   const MDNode *LocMD = nullptr;
196917a519f9SDimitry Andric   for (unsigned i = getNumOperands(); i != 0; --i) {
197017a519f9SDimitry Andric     if (getOperand(i-1).isMetadata() &&
197117a519f9SDimitry Andric         (LocMD = getOperand(i-1).getMetadata()) &&
197217a519f9SDimitry Andric         LocMD->getNumOperands() != 0) {
197339d628a0SDimitry Andric       if (const ConstantInt *CI =
197439d628a0SDimitry Andric               mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) {
197517a519f9SDimitry Andric         LocCookie = CI->getZExtValue();
197617a519f9SDimitry Andric         break;
197717a519f9SDimitry Andric       }
197817a519f9SDimitry Andric     }
197917a519f9SDimitry Andric   }
198017a519f9SDimitry Andric 
198117a519f9SDimitry Andric   if (const MachineBasicBlock *MBB = getParent())
198217a519f9SDimitry Andric     if (const MachineFunction *MF = MBB->getParent())
198317a519f9SDimitry Andric       return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg);
198417a519f9SDimitry Andric   report_fatal_error(Msg);
198517a519f9SDimitry Andric }
19863ca95b02SDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,unsigned Reg,const MDNode * Variable,const MDNode * Expr)19873ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
19883ca95b02SDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
19892cab237bSDimitry Andric                                   unsigned Reg, const MDNode *Variable,
19902cab237bSDimitry Andric                                   const MDNode *Expr) {
19913ca95b02SDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
19923ca95b02SDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
19933ca95b02SDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
19943ca95b02SDimitry Andric          "Expected inlined-at fields to agree");
19954ba319b5SDimitry Andric   auto MIB = BuildMI(MF, DL, MCID).addReg(Reg, RegState::Debug);
19963ca95b02SDimitry Andric   if (IsIndirect)
19974ba319b5SDimitry Andric     MIB.addImm(0U);
19982cab237bSDimitry Andric   else
19994ba319b5SDimitry Andric     MIB.addReg(0U, RegState::Debug);
20004ba319b5SDimitry Andric   return MIB.addMetadata(Variable).addMetadata(Expr);
20014ba319b5SDimitry Andric }
20024ba319b5SDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,MachineOperand & MO,const MDNode * Variable,const MDNode * Expr)20034ba319b5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
20044ba319b5SDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
20054ba319b5SDimitry Andric                                   MachineOperand &MO, const MDNode *Variable,
20064ba319b5SDimitry Andric                                   const MDNode *Expr) {
20074ba319b5SDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
20084ba319b5SDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
20094ba319b5SDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
20104ba319b5SDimitry Andric          "Expected inlined-at fields to agree");
20114ba319b5SDimitry Andric   if (MO.isReg())
20124ba319b5SDimitry Andric     return BuildMI(MF, DL, MCID, IsIndirect, MO.getReg(), Variable, Expr);
20134ba319b5SDimitry Andric 
20144ba319b5SDimitry Andric   auto MIB = BuildMI(MF, DL, MCID).add(MO);
20154ba319b5SDimitry Andric   if (IsIndirect)
20164ba319b5SDimitry Andric     MIB.addImm(0U);
20174ba319b5SDimitry Andric   else
20184ba319b5SDimitry Andric     MIB.addReg(0U, RegState::Debug);
20194ba319b5SDimitry Andric   return MIB.addMetadata(Variable).addMetadata(Expr);
20203ca95b02SDimitry Andric  }
20213ca95b02SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,unsigned Reg,const MDNode * Variable,const MDNode * Expr)20223ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
20233ca95b02SDimitry Andric                                   MachineBasicBlock::iterator I,
20243ca95b02SDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
20253ca95b02SDimitry Andric                                   bool IsIndirect, unsigned Reg,
20262cab237bSDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
20273ca95b02SDimitry Andric   MachineFunction &MF = *BB.getParent();
20282cab237bSDimitry Andric   MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Variable, Expr);
20293ca95b02SDimitry Andric   BB.insert(I, MI);
20303ca95b02SDimitry Andric   return MachineInstrBuilder(MF, MI);
20313ca95b02SDimitry Andric }
20326bc11b14SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,MachineOperand & MO,const MDNode * Variable,const MDNode * Expr)20334ba319b5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
20344ba319b5SDimitry Andric                                   MachineBasicBlock::iterator I,
20354ba319b5SDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
20364ba319b5SDimitry Andric                                   bool IsIndirect, MachineOperand &MO,
20374ba319b5SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
20384ba319b5SDimitry Andric   MachineFunction &MF = *BB.getParent();
20394ba319b5SDimitry Andric   MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, MO, Variable, Expr);
20404ba319b5SDimitry Andric   BB.insert(I, MI);
20414ba319b5SDimitry Andric   return MachineInstrBuilder(MF, *MI);
20424ba319b5SDimitry Andric }
20434ba319b5SDimitry Andric 
20442cab237bSDimitry Andric /// Compute the new DIExpression to use with a DBG_VALUE for a spill slot.
20452cab237bSDimitry Andric /// This prepends DW_OP_deref when spilling an indirect DBG_VALUE.
computeExprForSpill(const MachineInstr & MI)20462cab237bSDimitry Andric static const DIExpression *computeExprForSpill(const MachineInstr &MI) {
20472cab237bSDimitry Andric   assert(MI.getOperand(0).isReg() && "can't spill non-register");
20482cab237bSDimitry Andric   assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
20492cab237bSDimitry Andric          "Expected inlined-at fields to agree");
20502cab237bSDimitry Andric 
20512cab237bSDimitry Andric   const DIExpression *Expr = MI.getDebugExpression();
20522cab237bSDimitry Andric   if (MI.isIndirectDebugValue()) {
20532cab237bSDimitry Andric     assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset");
20542cab237bSDimitry Andric     Expr = DIExpression::prepend(Expr, DIExpression::WithDeref);
20552cab237bSDimitry Andric   }
20562cab237bSDimitry Andric   return Expr;
20572cab237bSDimitry Andric }
20582cab237bSDimitry Andric 
buildDbgValueForSpill(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const MachineInstr & Orig,int FrameIndex)20596bc11b14SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,
20606bc11b14SDimitry Andric                                           MachineBasicBlock::iterator I,
20616bc11b14SDimitry Andric                                           const MachineInstr &Orig,
20626bc11b14SDimitry Andric                                           int FrameIndex) {
20632cab237bSDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig);
20642cab237bSDimitry Andric   return BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc())
20656bc11b14SDimitry Andric       .addFrameIndex(FrameIndex)
20662cab237bSDimitry Andric       .addImm(0U)
20672cab237bSDimitry Andric       .addMetadata(Orig.getDebugVariable())
20686bc11b14SDimitry Andric       .addMetadata(Expr);
20696bc11b14SDimitry Andric }
20702cab237bSDimitry Andric 
updateDbgValueForSpill(MachineInstr & Orig,int FrameIndex)20712cab237bSDimitry Andric void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) {
20722cab237bSDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig);
20732cab237bSDimitry Andric   Orig.getOperand(0).ChangeToFrameIndex(FrameIndex);
20742cab237bSDimitry Andric   Orig.getOperand(1).ChangeToImmediate(0U);
20752cab237bSDimitry Andric   Orig.getOperand(3).setMetadata(Expr);
20762cab237bSDimitry Andric }
2077*b5893f02SDimitry Andric 
collectDebugValues(SmallVectorImpl<MachineInstr * > & DbgValues)2078*b5893f02SDimitry Andric void MachineInstr::collectDebugValues(
2079*b5893f02SDimitry Andric                                 SmallVectorImpl<MachineInstr *> &DbgValues) {
2080*b5893f02SDimitry Andric   MachineInstr &MI = *this;
2081*b5893f02SDimitry Andric   if (!MI.getOperand(0).isReg())
2082*b5893f02SDimitry Andric     return;
2083*b5893f02SDimitry Andric 
2084*b5893f02SDimitry Andric   MachineBasicBlock::iterator DI = MI; ++DI;
2085*b5893f02SDimitry Andric   for (MachineBasicBlock::iterator DE = MI.getParent()->end();
2086*b5893f02SDimitry Andric        DI != DE; ++DI) {
2087*b5893f02SDimitry Andric     if (!DI->isDebugValue())
2088*b5893f02SDimitry Andric       return;
2089*b5893f02SDimitry Andric     if (DI->getOperand(0).isReg() &&
2090*b5893f02SDimitry Andric         DI->getOperand(0).getReg() == MI.getOperand(0).getReg())
2091*b5893f02SDimitry Andric       DbgValues.push_back(&*DI);
2092*b5893f02SDimitry Andric   }
2093*b5893f02SDimitry Andric }
2094*b5893f02SDimitry Andric 
changeDebugValuesDefReg(unsigned Reg)2095*b5893f02SDimitry Andric void MachineInstr::changeDebugValuesDefReg(unsigned Reg) {
2096*b5893f02SDimitry Andric   // Collect matching debug values.
2097*b5893f02SDimitry Andric   SmallVector<MachineInstr *, 2> DbgValues;
2098*b5893f02SDimitry Andric   collectDebugValues(DbgValues);
2099*b5893f02SDimitry Andric 
2100*b5893f02SDimitry Andric   // Propagate Reg to debug value instructions.
2101*b5893f02SDimitry Andric   for (auto *DBI : DbgValues)
2102*b5893f02SDimitry Andric     DBI->getOperand(0).setReg(Reg);
2103*b5893f02SDimitry Andric }
2104