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