1f22ef01cSRoman Divacky //===-- 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 14f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineInstr.h" 15f22ef01cSRoman Divacky #include "llvm/Constants.h" 16f22ef01cSRoman Divacky #include "llvm/Function.h" 17f22ef01cSRoman Divacky #include "llvm/InlineAsm.h" 18f22ef01cSRoman Divacky #include "llvm/Metadata.h" 19f22ef01cSRoman Divacky #include "llvm/Type.h" 20f22ef01cSRoman Divacky #include "llvm/Value.h" 21f22ef01cSRoman Divacky #include "llvm/Assembly/Writer.h" 22f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineConstantPool.h" 23f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h" 24f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineMemOperand.h" 25f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h" 26f22ef01cSRoman Divacky #include "llvm/CodeGen/PseudoSourceValue.h" 27f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h" 28f22ef01cSRoman Divacky #include "llvm/Target/TargetMachine.h" 29f22ef01cSRoman Divacky #include "llvm/Target/TargetInstrInfo.h" 30f22ef01cSRoman Divacky #include "llvm/Target/TargetInstrDesc.h" 31f22ef01cSRoman Divacky #include "llvm/Target/TargetRegisterInfo.h" 32f22ef01cSRoman Divacky #include "llvm/Analysis/AliasAnalysis.h" 33f22ef01cSRoman Divacky #include "llvm/Analysis/DebugInfo.h" 34f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 35f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 36f22ef01cSRoman Divacky #include "llvm/Support/LeakDetector.h" 37f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h" 38f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 39f22ef01cSRoman Divacky #include "llvm/ADT/FoldingSet.h" 40f22ef01cSRoman Divacky using namespace llvm; 41f22ef01cSRoman Divacky 42f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 43f22ef01cSRoman Divacky // MachineOperand Implementation 44f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 45f22ef01cSRoman Divacky 46f22ef01cSRoman Divacky /// AddRegOperandToRegInfo - Add this register operand to the specified 47f22ef01cSRoman Divacky /// MachineRegisterInfo. If it is null, then the next/prev fields should be 48f22ef01cSRoman Divacky /// explicitly nulled out. 49f22ef01cSRoman Divacky void MachineOperand::AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo) { 50f22ef01cSRoman Divacky assert(isReg() && "Can only add reg operand to use lists"); 51f22ef01cSRoman Divacky 52f22ef01cSRoman Divacky // If the reginfo pointer is null, just explicitly null out or next/prev 53f22ef01cSRoman Divacky // pointers, to ensure they are not garbage. 54f22ef01cSRoman Divacky if (RegInfo == 0) { 55f22ef01cSRoman Divacky Contents.Reg.Prev = 0; 56f22ef01cSRoman Divacky Contents.Reg.Next = 0; 57f22ef01cSRoman Divacky return; 58f22ef01cSRoman Divacky } 59f22ef01cSRoman Divacky 60f22ef01cSRoman Divacky // Otherwise, add this operand to the head of the registers use/def list. 61f22ef01cSRoman Divacky MachineOperand **Head = &RegInfo->getRegUseDefListHead(getReg()); 62f22ef01cSRoman Divacky 63f22ef01cSRoman Divacky // For SSA values, we prefer to keep the definition at the start of the list. 64f22ef01cSRoman Divacky // we do this by skipping over the definition if it is at the head of the 65f22ef01cSRoman Divacky // list. 66f22ef01cSRoman Divacky if (*Head && (*Head)->isDef()) 67f22ef01cSRoman Divacky Head = &(*Head)->Contents.Reg.Next; 68f22ef01cSRoman Divacky 69f22ef01cSRoman Divacky Contents.Reg.Next = *Head; 70f22ef01cSRoman Divacky if (Contents.Reg.Next) { 71f22ef01cSRoman Divacky assert(getReg() == Contents.Reg.Next->getReg() && 72f22ef01cSRoman Divacky "Different regs on the same list!"); 73f22ef01cSRoman Divacky Contents.Reg.Next->Contents.Reg.Prev = &Contents.Reg.Next; 74f22ef01cSRoman Divacky } 75f22ef01cSRoman Divacky 76f22ef01cSRoman Divacky Contents.Reg.Prev = Head; 77f22ef01cSRoman Divacky *Head = this; 78f22ef01cSRoman Divacky } 79f22ef01cSRoman Divacky 80f22ef01cSRoman Divacky /// RemoveRegOperandFromRegInfo - Remove this register operand from the 81f22ef01cSRoman Divacky /// MachineRegisterInfo it is linked with. 82f22ef01cSRoman Divacky void MachineOperand::RemoveRegOperandFromRegInfo() { 83f22ef01cSRoman Divacky assert(isOnRegUseList() && "Reg operand is not on a use list"); 84f22ef01cSRoman Divacky // Unlink this from the doubly linked list of operands. 85f22ef01cSRoman Divacky MachineOperand *NextOp = Contents.Reg.Next; 86f22ef01cSRoman Divacky *Contents.Reg.Prev = NextOp; 87f22ef01cSRoman Divacky if (NextOp) { 88f22ef01cSRoman Divacky assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!"); 89f22ef01cSRoman Divacky NextOp->Contents.Reg.Prev = Contents.Reg.Prev; 90f22ef01cSRoman Divacky } 91f22ef01cSRoman Divacky Contents.Reg.Prev = 0; 92f22ef01cSRoman Divacky Contents.Reg.Next = 0; 93f22ef01cSRoman Divacky } 94f22ef01cSRoman Divacky 95f22ef01cSRoman Divacky void MachineOperand::setReg(unsigned Reg) { 96f22ef01cSRoman Divacky if (getReg() == Reg) return; // No change. 97f22ef01cSRoman Divacky 98f22ef01cSRoman Divacky // Otherwise, we have to change the register. If this operand is embedded 99f22ef01cSRoman Divacky // into a machine function, we need to update the old and new register's 100f22ef01cSRoman Divacky // use/def lists. 101f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 102f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 103f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) { 104f22ef01cSRoman Divacky RemoveRegOperandFromRegInfo(); 105f22ef01cSRoman Divacky Contents.Reg.RegNo = Reg; 106f22ef01cSRoman Divacky AddRegOperandToRegInfo(&MF->getRegInfo()); 107f22ef01cSRoman Divacky return; 108f22ef01cSRoman Divacky } 109f22ef01cSRoman Divacky 110f22ef01cSRoman Divacky // Otherwise, just change the register, no problem. :) 111f22ef01cSRoman Divacky Contents.Reg.RegNo = Reg; 112f22ef01cSRoman Divacky } 113f22ef01cSRoman Divacky 114ffd1746dSEd Schouten void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 115ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 116ffd1746dSEd Schouten assert(TargetRegisterInfo::isVirtualRegister(Reg)); 117ffd1746dSEd Schouten if (SubIdx && getSubReg()) 118ffd1746dSEd Schouten SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 119ffd1746dSEd Schouten setReg(Reg); 120ffd1746dSEd Schouten if (SubIdx) 121ffd1746dSEd Schouten setSubReg(SubIdx); 122ffd1746dSEd Schouten } 123ffd1746dSEd Schouten 124ffd1746dSEd Schouten void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 125ffd1746dSEd Schouten assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 126ffd1746dSEd Schouten if (getSubReg()) { 127ffd1746dSEd Schouten Reg = TRI.getSubReg(Reg, getSubReg()); 128ffd1746dSEd Schouten assert(Reg && "Invalid SubReg for physical register"); 129ffd1746dSEd Schouten setSubReg(0); 130ffd1746dSEd Schouten } 131ffd1746dSEd Schouten setReg(Reg); 132ffd1746dSEd Schouten } 133ffd1746dSEd Schouten 134f22ef01cSRoman Divacky /// ChangeToImmediate - Replace this operand with a new immediate operand of 135f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an immediate already, 136f22ef01cSRoman Divacky /// the setImm method should be used. 137f22ef01cSRoman Divacky void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 138f22ef01cSRoman Divacky // If this operand is currently a register operand, and if this is in a 139f22ef01cSRoman Divacky // function, deregister the operand from the register's use/def list. 140f22ef01cSRoman Divacky if (isReg() && getParent() && getParent()->getParent() && 141f22ef01cSRoman Divacky getParent()->getParent()->getParent()) 142f22ef01cSRoman Divacky RemoveRegOperandFromRegInfo(); 143f22ef01cSRoman Divacky 144f22ef01cSRoman Divacky OpKind = MO_Immediate; 145f22ef01cSRoman Divacky Contents.ImmVal = ImmVal; 146f22ef01cSRoman Divacky } 147f22ef01cSRoman Divacky 148f22ef01cSRoman Divacky /// ChangeToRegister - Replace this operand with a new register operand of 149f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an register already, 150f22ef01cSRoman Divacky /// the setReg method should be used. 151f22ef01cSRoman Divacky void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 152f22ef01cSRoman Divacky bool isKill, bool isDead, bool isUndef, 153f22ef01cSRoman Divacky bool isDebug) { 154f22ef01cSRoman Divacky // If this operand is already a register operand, use setReg to update the 155f22ef01cSRoman Divacky // register's use/def lists. 156f22ef01cSRoman Divacky if (isReg()) { 157f22ef01cSRoman Divacky assert(!isEarlyClobber()); 158f22ef01cSRoman Divacky setReg(Reg); 159f22ef01cSRoman Divacky } else { 160f22ef01cSRoman Divacky // Otherwise, change this to a register and set the reg#. 161f22ef01cSRoman Divacky OpKind = MO_Register; 162f22ef01cSRoman Divacky Contents.Reg.RegNo = Reg; 163f22ef01cSRoman Divacky 164f22ef01cSRoman Divacky // If this operand is embedded in a function, add the operand to the 165f22ef01cSRoman Divacky // register's use/def list. 166f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 167f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 168f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) 169f22ef01cSRoman Divacky AddRegOperandToRegInfo(&MF->getRegInfo()); 170f22ef01cSRoman Divacky } 171f22ef01cSRoman Divacky 172f22ef01cSRoman Divacky IsDef = isDef; 173f22ef01cSRoman Divacky IsImp = isImp; 174f22ef01cSRoman Divacky IsKill = isKill; 175f22ef01cSRoman Divacky IsDead = isDead; 176f22ef01cSRoman Divacky IsUndef = isUndef; 177f22ef01cSRoman Divacky IsEarlyClobber = false; 178f22ef01cSRoman Divacky IsDebug = isDebug; 179f22ef01cSRoman Divacky SubReg = 0; 180f22ef01cSRoman Divacky } 181f22ef01cSRoman Divacky 182f22ef01cSRoman Divacky /// isIdenticalTo - Return true if this operand is identical to the specified 183f22ef01cSRoman Divacky /// operand. 184f22ef01cSRoman Divacky bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 185f22ef01cSRoman Divacky if (getType() != Other.getType() || 186f22ef01cSRoman Divacky getTargetFlags() != Other.getTargetFlags()) 187f22ef01cSRoman Divacky return false; 188f22ef01cSRoman Divacky 189f22ef01cSRoman Divacky switch (getType()) { 190f22ef01cSRoman Divacky default: llvm_unreachable("Unrecognized operand type"); 191f22ef01cSRoman Divacky case MachineOperand::MO_Register: 192f22ef01cSRoman Divacky return getReg() == Other.getReg() && isDef() == Other.isDef() && 193f22ef01cSRoman Divacky getSubReg() == Other.getSubReg(); 194f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 195f22ef01cSRoman Divacky return getImm() == Other.getImm(); 196f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 197f22ef01cSRoman Divacky return getFPImm() == Other.getFPImm(); 198f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 199f22ef01cSRoman Divacky return getMBB() == Other.getMBB(); 200f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 201f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 202f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 203f22ef01cSRoman Divacky return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 204f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 205f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 206f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 207f22ef01cSRoman Divacky return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 208f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 209f22ef01cSRoman Divacky return !strcmp(getSymbolName(), Other.getSymbolName()) && 210f22ef01cSRoman Divacky getOffset() == Other.getOffset(); 211f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 212f22ef01cSRoman Divacky return getBlockAddress() == Other.getBlockAddress(); 213f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 214f22ef01cSRoman Divacky return getMCSymbol() == Other.getMCSymbol(); 215f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 216f22ef01cSRoman Divacky return getMetadata() == Other.getMetadata(); 217f22ef01cSRoman Divacky } 218f22ef01cSRoman Divacky } 219f22ef01cSRoman Divacky 220f22ef01cSRoman Divacky /// print - Print the specified machine operand. 221f22ef01cSRoman Divacky /// 222f22ef01cSRoman Divacky void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { 223f22ef01cSRoman Divacky // If the instruction is embedded into a basic block, we can find the 224f22ef01cSRoman Divacky // target info for the instruction. 225f22ef01cSRoman Divacky if (!TM) 226f22ef01cSRoman Divacky if (const MachineInstr *MI = getParent()) 227f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = MI->getParent()) 228f22ef01cSRoman Divacky if (const MachineFunction *MF = MBB->getParent()) 229f22ef01cSRoman Divacky TM = &MF->getTarget(); 230f22ef01cSRoman Divacky 231f22ef01cSRoman Divacky switch (getType()) { 232f22ef01cSRoman Divacky case MachineOperand::MO_Register: 233f22ef01cSRoman Divacky if (getReg() == 0 || TargetRegisterInfo::isVirtualRegister(getReg())) { 234f22ef01cSRoman Divacky OS << "%reg" << getReg(); 235f22ef01cSRoman Divacky } else { 236f22ef01cSRoman Divacky if (TM) 237f22ef01cSRoman Divacky OS << "%" << TM->getRegisterInfo()->get(getReg()).Name; 238f22ef01cSRoman Divacky else 239f22ef01cSRoman Divacky OS << "%physreg" << getReg(); 240f22ef01cSRoman Divacky } 241f22ef01cSRoman Divacky 242f22ef01cSRoman Divacky if (getSubReg() != 0) { 243f22ef01cSRoman Divacky if (TM) 244f22ef01cSRoman Divacky OS << ':' << TM->getRegisterInfo()->getSubRegIndexName(getSubReg()); 245f22ef01cSRoman Divacky else 246f22ef01cSRoman Divacky OS << ':' << getSubReg(); 247f22ef01cSRoman Divacky } 248f22ef01cSRoman Divacky 249f22ef01cSRoman Divacky if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || 250f22ef01cSRoman Divacky isEarlyClobber()) { 251f22ef01cSRoman Divacky OS << '<'; 252f22ef01cSRoman Divacky bool NeedComma = false; 253f22ef01cSRoman Divacky if (isDef()) { 254f22ef01cSRoman Divacky if (NeedComma) OS << ','; 255f22ef01cSRoman Divacky if (isEarlyClobber()) 256f22ef01cSRoman Divacky OS << "earlyclobber,"; 257f22ef01cSRoman Divacky if (isImplicit()) 258f22ef01cSRoman Divacky OS << "imp-"; 259f22ef01cSRoman Divacky OS << "def"; 260f22ef01cSRoman Divacky NeedComma = true; 261f22ef01cSRoman Divacky } else if (isImplicit()) { 262f22ef01cSRoman Divacky OS << "imp-use"; 263f22ef01cSRoman Divacky NeedComma = true; 264f22ef01cSRoman Divacky } 265f22ef01cSRoman Divacky 266f22ef01cSRoman Divacky if (isKill() || isDead() || isUndef()) { 267f22ef01cSRoman Divacky if (NeedComma) OS << ','; 268f22ef01cSRoman Divacky if (isKill()) OS << "kill"; 269f22ef01cSRoman Divacky if (isDead()) OS << "dead"; 270f22ef01cSRoman Divacky if (isUndef()) { 271f22ef01cSRoman Divacky if (isKill() || isDead()) 272f22ef01cSRoman Divacky OS << ','; 273f22ef01cSRoman Divacky OS << "undef"; 274f22ef01cSRoman Divacky } 275f22ef01cSRoman Divacky } 276f22ef01cSRoman Divacky OS << '>'; 277f22ef01cSRoman Divacky } 278f22ef01cSRoman Divacky break; 279f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 280f22ef01cSRoman Divacky OS << getImm(); 281f22ef01cSRoman Divacky break; 282f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 283f22ef01cSRoman Divacky if (getFPImm()->getType()->isFloatTy()) 284f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToFloat(); 285f22ef01cSRoman Divacky else 286f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToDouble(); 287f22ef01cSRoman Divacky break; 288f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 289f22ef01cSRoman Divacky OS << "<BB#" << getMBB()->getNumber() << ">"; 290f22ef01cSRoman Divacky break; 291f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 292f22ef01cSRoman Divacky OS << "<fi#" << getIndex() << '>'; 293f22ef01cSRoman Divacky break; 294f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 295f22ef01cSRoman Divacky OS << "<cp#" << getIndex(); 296f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 297f22ef01cSRoman Divacky OS << '>'; 298f22ef01cSRoman Divacky break; 299f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 300f22ef01cSRoman Divacky OS << "<jt#" << getIndex() << '>'; 301f22ef01cSRoman Divacky break; 302f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 303f22ef01cSRoman Divacky OS << "<ga:"; 304f22ef01cSRoman Divacky WriteAsOperand(OS, getGlobal(), /*PrintType=*/false); 305f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 306f22ef01cSRoman Divacky OS << '>'; 307f22ef01cSRoman Divacky break; 308f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 309f22ef01cSRoman Divacky OS << "<es:" << getSymbolName(); 310f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 311f22ef01cSRoman Divacky OS << '>'; 312f22ef01cSRoman Divacky break; 313f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 314f22ef01cSRoman Divacky OS << '<'; 315f22ef01cSRoman Divacky WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false); 316f22ef01cSRoman Divacky OS << '>'; 317f22ef01cSRoman Divacky break; 318f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 319f22ef01cSRoman Divacky OS << '<'; 320f22ef01cSRoman Divacky WriteAsOperand(OS, getMetadata(), /*PrintType=*/false); 321f22ef01cSRoman Divacky OS << '>'; 322f22ef01cSRoman Divacky break; 323f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 324f22ef01cSRoman Divacky OS << "<MCSym=" << *getMCSymbol() << '>'; 325f22ef01cSRoman Divacky break; 326f22ef01cSRoman Divacky default: 327f22ef01cSRoman Divacky llvm_unreachable("Unrecognized operand type"); 328f22ef01cSRoman Divacky } 329f22ef01cSRoman Divacky 330f22ef01cSRoman Divacky if (unsigned TF = getTargetFlags()) 331f22ef01cSRoman Divacky OS << "[TF=" << TF << ']'; 332f22ef01cSRoman Divacky } 333f22ef01cSRoman Divacky 334f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 335f22ef01cSRoman Divacky // MachineMemOperand Implementation 336f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 337f22ef01cSRoman Divacky 338f22ef01cSRoman Divacky MachineMemOperand::MachineMemOperand(const Value *v, unsigned int f, 339f22ef01cSRoman Divacky int64_t o, uint64_t s, unsigned int a) 340f22ef01cSRoman Divacky : Offset(o), Size(s), V(v), 341f22ef01cSRoman Divacky Flags((f & ((1 << MOMaxBits) - 1)) | ((Log2_32(a) + 1) << MOMaxBits)) { 342f22ef01cSRoman Divacky assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 343f22ef01cSRoman Divacky assert((isLoad() || isStore()) && "Not a load/store!"); 344f22ef01cSRoman Divacky } 345f22ef01cSRoman Divacky 346f22ef01cSRoman Divacky /// Profile - Gather unique data for the object. 347f22ef01cSRoman Divacky /// 348f22ef01cSRoman Divacky void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 349f22ef01cSRoman Divacky ID.AddInteger(Offset); 350f22ef01cSRoman Divacky ID.AddInteger(Size); 351f22ef01cSRoman Divacky ID.AddPointer(V); 352f22ef01cSRoman Divacky ID.AddInteger(Flags); 353f22ef01cSRoman Divacky } 354f22ef01cSRoman Divacky 355f22ef01cSRoman Divacky void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 356f22ef01cSRoman Divacky // The Value and Offset may differ due to CSE. But the flags and size 357f22ef01cSRoman Divacky // should be the same. 358f22ef01cSRoman Divacky assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 359f22ef01cSRoman Divacky assert(MMO->getSize() == getSize() && "Size mismatch!"); 360f22ef01cSRoman Divacky 361f22ef01cSRoman Divacky if (MMO->getBaseAlignment() >= getBaseAlignment()) { 362f22ef01cSRoman Divacky // Update the alignment value. 363f22ef01cSRoman Divacky Flags = (Flags & ((1 << MOMaxBits) - 1)) | 364f22ef01cSRoman Divacky ((Log2_32(MMO->getBaseAlignment()) + 1) << MOMaxBits); 365f22ef01cSRoman Divacky // Also update the base and offset, because the new alignment may 366f22ef01cSRoman Divacky // not be applicable with the old ones. 367f22ef01cSRoman Divacky V = MMO->getValue(); 368f22ef01cSRoman Divacky Offset = MMO->getOffset(); 369f22ef01cSRoman Divacky } 370f22ef01cSRoman Divacky } 371f22ef01cSRoman Divacky 372f22ef01cSRoman Divacky /// getAlignment - Return the minimum known alignment in bytes of the 373f22ef01cSRoman Divacky /// actual memory reference. 374f22ef01cSRoman Divacky uint64_t MachineMemOperand::getAlignment() const { 375f22ef01cSRoman Divacky return MinAlign(getBaseAlignment(), getOffset()); 376f22ef01cSRoman Divacky } 377f22ef01cSRoman Divacky 378f22ef01cSRoman Divacky raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { 379f22ef01cSRoman Divacky assert((MMO.isLoad() || MMO.isStore()) && 380f22ef01cSRoman Divacky "SV has to be a load, store or both."); 381f22ef01cSRoman Divacky 382f22ef01cSRoman Divacky if (MMO.isVolatile()) 383f22ef01cSRoman Divacky OS << "Volatile "; 384f22ef01cSRoman Divacky 385f22ef01cSRoman Divacky if (MMO.isLoad()) 386f22ef01cSRoman Divacky OS << "LD"; 387f22ef01cSRoman Divacky if (MMO.isStore()) 388f22ef01cSRoman Divacky OS << "ST"; 389f22ef01cSRoman Divacky OS << MMO.getSize(); 390f22ef01cSRoman Divacky 391f22ef01cSRoman Divacky // Print the address information. 392f22ef01cSRoman Divacky OS << "["; 393f22ef01cSRoman Divacky if (!MMO.getValue()) 394f22ef01cSRoman Divacky OS << "<unknown>"; 395f22ef01cSRoman Divacky else 396f22ef01cSRoman Divacky WriteAsOperand(OS, MMO.getValue(), /*PrintType=*/false); 397f22ef01cSRoman Divacky 398f22ef01cSRoman Divacky // If the alignment of the memory reference itself differs from the alignment 399f22ef01cSRoman Divacky // of the base pointer, print the base alignment explicitly, next to the base 400f22ef01cSRoman Divacky // pointer. 401f22ef01cSRoman Divacky if (MMO.getBaseAlignment() != MMO.getAlignment()) 402f22ef01cSRoman Divacky OS << "(align=" << MMO.getBaseAlignment() << ")"; 403f22ef01cSRoman Divacky 404f22ef01cSRoman Divacky if (MMO.getOffset() != 0) 405f22ef01cSRoman Divacky OS << "+" << MMO.getOffset(); 406f22ef01cSRoman Divacky OS << "]"; 407f22ef01cSRoman Divacky 408f22ef01cSRoman Divacky // Print the alignment of the reference. 409f22ef01cSRoman Divacky if (MMO.getBaseAlignment() != MMO.getAlignment() || 410f22ef01cSRoman Divacky MMO.getBaseAlignment() != MMO.getSize()) 411f22ef01cSRoman Divacky OS << "(align=" << MMO.getAlignment() << ")"; 412f22ef01cSRoman Divacky 413f22ef01cSRoman Divacky return OS; 414f22ef01cSRoman Divacky } 415f22ef01cSRoman Divacky 416f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 417f22ef01cSRoman Divacky // MachineInstr Implementation 418f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 419f22ef01cSRoman Divacky 420f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a dummy MachineInstr with 421f22ef01cSRoman Divacky /// TID NULL and no operands. 422f22ef01cSRoman Divacky MachineInstr::MachineInstr() 423f22ef01cSRoman Divacky : TID(0), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), 424f22ef01cSRoman Divacky Parent(0) { 425f22ef01cSRoman Divacky // Make sure that we get added to a machine basicblock 426f22ef01cSRoman Divacky LeakDetector::addGarbageObject(this); 427f22ef01cSRoman Divacky } 428f22ef01cSRoman Divacky 429f22ef01cSRoman Divacky void MachineInstr::addImplicitDefUseOperands() { 430f22ef01cSRoman Divacky if (TID->ImplicitDefs) 431f22ef01cSRoman Divacky for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) 432f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(*ImpDefs, true, true)); 433f22ef01cSRoman Divacky if (TID->ImplicitUses) 434f22ef01cSRoman Divacky for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) 435f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(*ImpUses, false, true)); 436f22ef01cSRoman Divacky } 437f22ef01cSRoman Divacky 438f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 439f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by 440f22ef01cSRoman Divacky /// the TargetInstrDesc. 441f22ef01cSRoman Divacky MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp) 442f22ef01cSRoman Divacky : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), 443f22ef01cSRoman Divacky MemRefs(0), MemRefsEnd(0), Parent(0) { 444f22ef01cSRoman Divacky if (!NoImp) 445f22ef01cSRoman Divacky NumImplicitOps = TID->getNumImplicitDefs() + TID->getNumImplicitUses(); 446f22ef01cSRoman Divacky Operands.reserve(NumImplicitOps + TID->getNumOperands()); 447f22ef01cSRoman Divacky if (!NoImp) 448f22ef01cSRoman Divacky addImplicitDefUseOperands(); 449f22ef01cSRoman Divacky // Make sure that we get added to a machine basicblock 450f22ef01cSRoman Divacky LeakDetector::addGarbageObject(this); 451f22ef01cSRoman Divacky } 452f22ef01cSRoman Divacky 453f22ef01cSRoman Divacky /// MachineInstr ctor - As above, but with a DebugLoc. 454f22ef01cSRoman Divacky MachineInstr::MachineInstr(const TargetInstrDesc &tid, const DebugLoc dl, 455f22ef01cSRoman Divacky bool NoImp) 456f22ef01cSRoman Divacky : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), 457f22ef01cSRoman Divacky Parent(0), debugLoc(dl) { 458f22ef01cSRoman Divacky if (!NoImp) 459f22ef01cSRoman Divacky NumImplicitOps = TID->getNumImplicitDefs() + TID->getNumImplicitUses(); 460f22ef01cSRoman Divacky Operands.reserve(NumImplicitOps + TID->getNumOperands()); 461f22ef01cSRoman Divacky if (!NoImp) 462f22ef01cSRoman Divacky addImplicitDefUseOperands(); 463f22ef01cSRoman Divacky // Make sure that we get added to a machine basicblock 464f22ef01cSRoman Divacky LeakDetector::addGarbageObject(this); 465f22ef01cSRoman Divacky } 466f22ef01cSRoman Divacky 467f22ef01cSRoman Divacky /// MachineInstr ctor - Work exactly the same as the ctor two above, except 468f22ef01cSRoman Divacky /// that the MachineInstr is created and added to the end of the specified 469f22ef01cSRoman Divacky /// basic block. 470f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &tid) 471f22ef01cSRoman Divacky : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), 472f22ef01cSRoman Divacky MemRefs(0), MemRefsEnd(0), Parent(0) { 473f22ef01cSRoman Divacky assert(MBB && "Cannot use inserting ctor with null basic block!"); 474f22ef01cSRoman Divacky NumImplicitOps = TID->getNumImplicitDefs() + TID->getNumImplicitUses(); 475f22ef01cSRoman Divacky Operands.reserve(NumImplicitOps + TID->getNumOperands()); 476f22ef01cSRoman Divacky addImplicitDefUseOperands(); 477f22ef01cSRoman Divacky // Make sure that we get added to a machine basicblock 478f22ef01cSRoman Divacky LeakDetector::addGarbageObject(this); 479f22ef01cSRoman Divacky MBB->push_back(this); // Add instruction to end of basic block! 480f22ef01cSRoman Divacky } 481f22ef01cSRoman Divacky 482f22ef01cSRoman Divacky /// MachineInstr ctor - As above, but with a DebugLoc. 483f22ef01cSRoman Divacky /// 484f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, 485f22ef01cSRoman Divacky const TargetInstrDesc &tid) 486f22ef01cSRoman Divacky : TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), 487f22ef01cSRoman Divacky Parent(0), debugLoc(dl) { 488f22ef01cSRoman Divacky assert(MBB && "Cannot use inserting ctor with null basic block!"); 489f22ef01cSRoman Divacky NumImplicitOps = TID->getNumImplicitDefs() + TID->getNumImplicitUses(); 490f22ef01cSRoman Divacky Operands.reserve(NumImplicitOps + TID->getNumOperands()); 491f22ef01cSRoman Divacky addImplicitDefUseOperands(); 492f22ef01cSRoman Divacky // Make sure that we get added to a machine basicblock 493f22ef01cSRoman Divacky LeakDetector::addGarbageObject(this); 494f22ef01cSRoman Divacky MBB->push_back(this); // Add instruction to end of basic block! 495f22ef01cSRoman Divacky } 496f22ef01cSRoman Divacky 497f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly 498f22ef01cSRoman Divacky /// 499f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 500f22ef01cSRoman Divacky : TID(&MI.getDesc()), NumImplicitOps(0), AsmPrinterFlags(0), 501f22ef01cSRoman Divacky MemRefs(MI.MemRefs), MemRefsEnd(MI.MemRefsEnd), 502f22ef01cSRoman Divacky Parent(0), debugLoc(MI.getDebugLoc()) { 503f22ef01cSRoman Divacky Operands.reserve(MI.getNumOperands()); 504f22ef01cSRoman Divacky 505f22ef01cSRoman Divacky // Add operands 506f22ef01cSRoman Divacky for (unsigned i = 0; i != MI.getNumOperands(); ++i) 507f22ef01cSRoman Divacky addOperand(MI.getOperand(i)); 508f22ef01cSRoman Divacky NumImplicitOps = MI.NumImplicitOps; 509f22ef01cSRoman Divacky 510f22ef01cSRoman Divacky // Set parent to null. 511f22ef01cSRoman Divacky Parent = 0; 512f22ef01cSRoman Divacky 513f22ef01cSRoman Divacky LeakDetector::addGarbageObject(this); 514f22ef01cSRoman Divacky } 515f22ef01cSRoman Divacky 516f22ef01cSRoman Divacky MachineInstr::~MachineInstr() { 517f22ef01cSRoman Divacky LeakDetector::removeGarbageObject(this); 518f22ef01cSRoman Divacky #ifndef NDEBUG 519f22ef01cSRoman Divacky for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 520f22ef01cSRoman Divacky assert(Operands[i].ParentMI == this && "ParentMI mismatch!"); 521f22ef01cSRoman Divacky assert((!Operands[i].isReg() || !Operands[i].isOnRegUseList()) && 522f22ef01cSRoman Divacky "Reg operand def/use list corrupted"); 523f22ef01cSRoman Divacky } 524f22ef01cSRoman Divacky #endif 525f22ef01cSRoman Divacky } 526f22ef01cSRoman Divacky 527f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction, 528f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise 529f22ef01cSRoman Divacky /// return null. 530f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() { 531f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = getParent()) 532f22ef01cSRoman Divacky return &MBB->getParent()->getRegInfo(); 533f22ef01cSRoman Divacky return 0; 534f22ef01cSRoman Divacky } 535f22ef01cSRoman Divacky 536f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in 537f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 538f22ef01cSRoman Divacky /// operands already be on their use lists. 539f22ef01cSRoman Divacky void MachineInstr::RemoveRegOperandsFromUseLists() { 540f22ef01cSRoman Divacky for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 541f22ef01cSRoman Divacky if (Operands[i].isReg()) 542f22ef01cSRoman Divacky Operands[i].RemoveRegOperandFromRegInfo(); 543f22ef01cSRoman Divacky } 544f22ef01cSRoman Divacky } 545f22ef01cSRoman Divacky 546f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in 547f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 548f22ef01cSRoman Divacky /// operands not be on their use lists yet. 549f22ef01cSRoman Divacky void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo) { 550f22ef01cSRoman Divacky for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 551f22ef01cSRoman Divacky if (Operands[i].isReg()) 552f22ef01cSRoman Divacky Operands[i].AddRegOperandToRegInfo(&RegInfo); 553f22ef01cSRoman Divacky } 554f22ef01cSRoman Divacky } 555f22ef01cSRoman Divacky 556f22ef01cSRoman Divacky 557f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction. If it is an 558f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list. If it is 559f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list 560f22ef01cSRoman Divacky /// (before the first implicit operand). 561f22ef01cSRoman Divacky void MachineInstr::addOperand(const MachineOperand &Op) { 562f22ef01cSRoman Divacky bool isImpReg = Op.isReg() && Op.isImplicit(); 563f22ef01cSRoman Divacky assert((isImpReg || !OperandsComplete()) && 564f22ef01cSRoman Divacky "Trying to add an operand to a machine instr that is already done!"); 565f22ef01cSRoman Divacky 566f22ef01cSRoman Divacky MachineRegisterInfo *RegInfo = getRegInfo(); 567f22ef01cSRoman Divacky 568f22ef01cSRoman Divacky // If we are adding the operand to the end of the list, our job is simpler. 569f22ef01cSRoman Divacky // This is true most of the time, so this is a reasonable optimization. 570f22ef01cSRoman Divacky if (isImpReg || NumImplicitOps == 0) { 571f22ef01cSRoman Divacky // We can only do this optimization if we know that the operand list won't 572f22ef01cSRoman Divacky // reallocate. 573f22ef01cSRoman Divacky if (Operands.empty() || Operands.size()+1 <= Operands.capacity()) { 574f22ef01cSRoman Divacky Operands.push_back(Op); 575f22ef01cSRoman Divacky 576f22ef01cSRoman Divacky // Set the parent of the operand. 577f22ef01cSRoman Divacky Operands.back().ParentMI = this; 578f22ef01cSRoman Divacky 579f22ef01cSRoman Divacky // If the operand is a register, update the operand's use list. 580f22ef01cSRoman Divacky if (Op.isReg()) { 581f22ef01cSRoman Divacky Operands.back().AddRegOperandToRegInfo(RegInfo); 582f22ef01cSRoman Divacky // If the register operand is flagged as early, mark the operand as such 583f22ef01cSRoman Divacky unsigned OpNo = Operands.size() - 1; 584f22ef01cSRoman Divacky if (TID->getOperandConstraint(OpNo, TOI::EARLY_CLOBBER) != -1) 585f22ef01cSRoman Divacky Operands[OpNo].setIsEarlyClobber(true); 586f22ef01cSRoman Divacky } 587f22ef01cSRoman Divacky return; 588f22ef01cSRoman Divacky } 589f22ef01cSRoman Divacky } 590f22ef01cSRoman Divacky 591f22ef01cSRoman Divacky // Otherwise, we have to insert a real operand before any implicit ones. 592f22ef01cSRoman Divacky unsigned OpNo = Operands.size()-NumImplicitOps; 593f22ef01cSRoman Divacky 594f22ef01cSRoman Divacky // If this instruction isn't embedded into a function, then we don't need to 595f22ef01cSRoman Divacky // update any operand lists. 596f22ef01cSRoman Divacky if (RegInfo == 0) { 597f22ef01cSRoman Divacky // Simple insertion, no reginfo update needed for other register operands. 598f22ef01cSRoman Divacky Operands.insert(Operands.begin()+OpNo, Op); 599f22ef01cSRoman Divacky Operands[OpNo].ParentMI = this; 600f22ef01cSRoman Divacky 601f22ef01cSRoman Divacky // Do explicitly set the reginfo for this operand though, to ensure the 602f22ef01cSRoman Divacky // next/prev fields are properly nulled out. 603f22ef01cSRoman Divacky if (Operands[OpNo].isReg()) { 604f22ef01cSRoman Divacky Operands[OpNo].AddRegOperandToRegInfo(0); 605f22ef01cSRoman Divacky // If the register operand is flagged as early, mark the operand as such 606f22ef01cSRoman Divacky if (TID->getOperandConstraint(OpNo, TOI::EARLY_CLOBBER) != -1) 607f22ef01cSRoman Divacky Operands[OpNo].setIsEarlyClobber(true); 608f22ef01cSRoman Divacky } 609f22ef01cSRoman Divacky 610f22ef01cSRoman Divacky } else if (Operands.size()+1 <= Operands.capacity()) { 611f22ef01cSRoman Divacky // Otherwise, we have to remove register operands from their register use 612f22ef01cSRoman Divacky // list, add the operand, then add the register operands back to their use 613f22ef01cSRoman Divacky // list. This also must handle the case when the operand list reallocates 614f22ef01cSRoman Divacky // to somewhere else. 615f22ef01cSRoman Divacky 616f22ef01cSRoman Divacky // If insertion of this operand won't cause reallocation of the operand 617f22ef01cSRoman Divacky // list, just remove the implicit operands, add the operand, then re-add all 618f22ef01cSRoman Divacky // the rest of the operands. 619f22ef01cSRoman Divacky for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) { 620f22ef01cSRoman Divacky assert(Operands[i].isReg() && "Should only be an implicit reg!"); 621f22ef01cSRoman Divacky Operands[i].RemoveRegOperandFromRegInfo(); 622f22ef01cSRoman Divacky } 623f22ef01cSRoman Divacky 624f22ef01cSRoman Divacky // Add the operand. If it is a register, add it to the reg list. 625f22ef01cSRoman Divacky Operands.insert(Operands.begin()+OpNo, Op); 626f22ef01cSRoman Divacky Operands[OpNo].ParentMI = this; 627f22ef01cSRoman Divacky 628f22ef01cSRoman Divacky if (Operands[OpNo].isReg()) { 629f22ef01cSRoman Divacky Operands[OpNo].AddRegOperandToRegInfo(RegInfo); 630f22ef01cSRoman Divacky // If the register operand is flagged as early, mark the operand as such 631f22ef01cSRoman Divacky if (TID->getOperandConstraint(OpNo, TOI::EARLY_CLOBBER) != -1) 632f22ef01cSRoman Divacky Operands[OpNo].setIsEarlyClobber(true); 633f22ef01cSRoman Divacky } 634f22ef01cSRoman Divacky 635f22ef01cSRoman Divacky // Re-add all the implicit ops. 636f22ef01cSRoman Divacky for (unsigned i = OpNo+1, e = Operands.size(); i != e; ++i) { 637f22ef01cSRoman Divacky assert(Operands[i].isReg() && "Should only be an implicit reg!"); 638f22ef01cSRoman Divacky Operands[i].AddRegOperandToRegInfo(RegInfo); 639f22ef01cSRoman Divacky } 640f22ef01cSRoman Divacky } else { 641f22ef01cSRoman Divacky // Otherwise, we will be reallocating the operand list. Remove all reg 642f22ef01cSRoman Divacky // operands from their list, then readd them after the operand list is 643f22ef01cSRoman Divacky // reallocated. 644f22ef01cSRoman Divacky RemoveRegOperandsFromUseLists(); 645f22ef01cSRoman Divacky 646f22ef01cSRoman Divacky Operands.insert(Operands.begin()+OpNo, Op); 647f22ef01cSRoman Divacky Operands[OpNo].ParentMI = this; 648f22ef01cSRoman Divacky 649f22ef01cSRoman Divacky // Re-add all the operands. 650f22ef01cSRoman Divacky AddRegOperandsToUseLists(*RegInfo); 651f22ef01cSRoman Divacky 652f22ef01cSRoman Divacky // If the register operand is flagged as early, mark the operand as such 653f22ef01cSRoman Divacky if (Operands[OpNo].isReg() 654f22ef01cSRoman Divacky && TID->getOperandConstraint(OpNo, TOI::EARLY_CLOBBER) != -1) 655f22ef01cSRoman Divacky Operands[OpNo].setIsEarlyClobber(true); 656f22ef01cSRoman Divacky } 657f22ef01cSRoman Divacky } 658f22ef01cSRoman Divacky 659f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand from an instruction, leaving it with one 660f22ef01cSRoman Divacky /// fewer operand than it started with. 661f22ef01cSRoman Divacky /// 662f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) { 663f22ef01cSRoman Divacky assert(OpNo < Operands.size() && "Invalid operand number"); 664f22ef01cSRoman Divacky 665f22ef01cSRoman Divacky // Special case removing the last one. 666f22ef01cSRoman Divacky if (OpNo == Operands.size()-1) { 667f22ef01cSRoman Divacky // If needed, remove from the reg def/use list. 668f22ef01cSRoman Divacky if (Operands.back().isReg() && Operands.back().isOnRegUseList()) 669f22ef01cSRoman Divacky Operands.back().RemoveRegOperandFromRegInfo(); 670f22ef01cSRoman Divacky 671f22ef01cSRoman Divacky Operands.pop_back(); 672f22ef01cSRoman Divacky return; 673f22ef01cSRoman Divacky } 674f22ef01cSRoman Divacky 675f22ef01cSRoman Divacky // Otherwise, we are removing an interior operand. If we have reginfo to 676f22ef01cSRoman Divacky // update, remove all operands that will be shifted down from their reg lists, 677f22ef01cSRoman Divacky // move everything down, then re-add them. 678f22ef01cSRoman Divacky MachineRegisterInfo *RegInfo = getRegInfo(); 679f22ef01cSRoman Divacky if (RegInfo) { 680f22ef01cSRoman Divacky for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) { 681f22ef01cSRoman Divacky if (Operands[i].isReg()) 682f22ef01cSRoman Divacky Operands[i].RemoveRegOperandFromRegInfo(); 683f22ef01cSRoman Divacky } 684f22ef01cSRoman Divacky } 685f22ef01cSRoman Divacky 686f22ef01cSRoman Divacky Operands.erase(Operands.begin()+OpNo); 687f22ef01cSRoman Divacky 688f22ef01cSRoman Divacky if (RegInfo) { 689f22ef01cSRoman Divacky for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) { 690f22ef01cSRoman Divacky if (Operands[i].isReg()) 691f22ef01cSRoman Divacky Operands[i].AddRegOperandToRegInfo(RegInfo); 692f22ef01cSRoman Divacky } 693f22ef01cSRoman Divacky } 694f22ef01cSRoman Divacky } 695f22ef01cSRoman Divacky 696f22ef01cSRoman Divacky /// addMemOperand - Add a MachineMemOperand to the machine instruction. 697f22ef01cSRoman Divacky /// This function should be used only occasionally. The setMemRefs function 698f22ef01cSRoman Divacky /// is the primary method for setting up a MachineInstr's MemRefs list. 699f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF, 700f22ef01cSRoman Divacky MachineMemOperand *MO) { 701f22ef01cSRoman Divacky mmo_iterator OldMemRefs = MemRefs; 702f22ef01cSRoman Divacky mmo_iterator OldMemRefsEnd = MemRefsEnd; 703f22ef01cSRoman Divacky 704f22ef01cSRoman Divacky size_t NewNum = (MemRefsEnd - MemRefs) + 1; 705f22ef01cSRoman Divacky mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum); 706f22ef01cSRoman Divacky mmo_iterator NewMemRefsEnd = NewMemRefs + NewNum; 707f22ef01cSRoman Divacky 708f22ef01cSRoman Divacky std::copy(OldMemRefs, OldMemRefsEnd, NewMemRefs); 709f22ef01cSRoman Divacky NewMemRefs[NewNum - 1] = MO; 710f22ef01cSRoman Divacky 711f22ef01cSRoman Divacky MemRefs = NewMemRefs; 712f22ef01cSRoman Divacky MemRefsEnd = NewMemRefsEnd; 713f22ef01cSRoman Divacky } 714f22ef01cSRoman Divacky 715f22ef01cSRoman Divacky bool MachineInstr::isIdenticalTo(const MachineInstr *Other, 716f22ef01cSRoman Divacky MICheckType Check) const { 717f22ef01cSRoman Divacky // If opcodes or number of operands are not the same then the two 718f22ef01cSRoman Divacky // instructions are obviously not identical. 719f22ef01cSRoman Divacky if (Other->getOpcode() != getOpcode() || 720f22ef01cSRoman Divacky Other->getNumOperands() != getNumOperands()) 721f22ef01cSRoman Divacky return false; 722f22ef01cSRoman Divacky 723f22ef01cSRoman Divacky // Check operands to make sure they match. 724f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 725f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 726f22ef01cSRoman Divacky const MachineOperand &OMO = Other->getOperand(i); 727f22ef01cSRoman Divacky // Clients may or may not want to ignore defs when testing for equality. 728f22ef01cSRoman Divacky // For example, machine CSE pass only cares about finding common 729f22ef01cSRoman Divacky // subexpressions, so it's safe to ignore virtual register defs. 730f22ef01cSRoman Divacky if (Check != CheckDefs && MO.isReg() && MO.isDef()) { 731f22ef01cSRoman Divacky if (Check == IgnoreDefs) 732f22ef01cSRoman Divacky continue; 733f22ef01cSRoman Divacky // Check == IgnoreVRegDefs 734f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) || 735f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(OMO.getReg())) 736f22ef01cSRoman Divacky if (MO.getReg() != OMO.getReg()) 737f22ef01cSRoman Divacky return false; 738f22ef01cSRoman Divacky } else if (!MO.isIdenticalTo(OMO)) 739f22ef01cSRoman Divacky return false; 740f22ef01cSRoman Divacky } 741f22ef01cSRoman Divacky return true; 742f22ef01cSRoman Divacky } 743f22ef01cSRoman Divacky 744f22ef01cSRoman Divacky /// removeFromParent - This method unlinks 'this' from the containing basic 745f22ef01cSRoman Divacky /// block, and returns it, but does not delete it. 746f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() { 747f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 748f22ef01cSRoman Divacky getParent()->remove(this); 749f22ef01cSRoman Divacky return this; 750f22ef01cSRoman Divacky } 751f22ef01cSRoman Divacky 752f22ef01cSRoman Divacky 753f22ef01cSRoman Divacky /// eraseFromParent - This method unlinks 'this' from the containing basic 754f22ef01cSRoman Divacky /// block, and deletes it. 755f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() { 756f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 757f22ef01cSRoman Divacky getParent()->erase(this); 758f22ef01cSRoman Divacky } 759f22ef01cSRoman Divacky 760f22ef01cSRoman Divacky 761f22ef01cSRoman Divacky /// OperandComplete - Return true if it's illegal to add a new operand 762f22ef01cSRoman Divacky /// 763f22ef01cSRoman Divacky bool MachineInstr::OperandsComplete() const { 764f22ef01cSRoman Divacky unsigned short NumOperands = TID->getNumOperands(); 765f22ef01cSRoman Divacky if (!TID->isVariadic() && getNumOperands()-NumImplicitOps >= NumOperands) 766f22ef01cSRoman Divacky return true; // Broken: we have all the operands of this instruction! 767f22ef01cSRoman Divacky return false; 768f22ef01cSRoman Divacky } 769f22ef01cSRoman Divacky 770f22ef01cSRoman Divacky /// getNumExplicitOperands - Returns the number of non-implicit operands. 771f22ef01cSRoman Divacky /// 772f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const { 773f22ef01cSRoman Divacky unsigned NumOperands = TID->getNumOperands(); 774f22ef01cSRoman Divacky if (!TID->isVariadic()) 775f22ef01cSRoman Divacky return NumOperands; 776f22ef01cSRoman Divacky 777f22ef01cSRoman Divacky for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { 778f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 779f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isImplicit()) 780f22ef01cSRoman Divacky NumOperands++; 781f22ef01cSRoman Divacky } 782f22ef01cSRoman Divacky return NumOperands; 783f22ef01cSRoman Divacky } 784f22ef01cSRoman Divacky 785f22ef01cSRoman Divacky 786f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 787f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens 788f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true. 789f22ef01cSRoman Divacky int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill, 790f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 791f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 792f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 793f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 794f22ef01cSRoman Divacky continue; 795f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 796f22ef01cSRoman Divacky if (!MOReg) 797f22ef01cSRoman Divacky continue; 798f22ef01cSRoman Divacky if (MOReg == Reg || 799f22ef01cSRoman Divacky (TRI && 800f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg) && 801f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg) && 802f22ef01cSRoman Divacky TRI->isSubRegister(MOReg, Reg))) 803f22ef01cSRoman Divacky if (!isKill || MO.isKill()) 804f22ef01cSRoman Divacky return i; 805f22ef01cSRoman Divacky } 806f22ef01cSRoman Divacky return -1; 807f22ef01cSRoman Divacky } 808f22ef01cSRoman Divacky 809f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 810f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers 811f22ef01cSRoman Divacky /// partial defines. 812f22ef01cSRoman Divacky std::pair<bool,bool> 813f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg, 814f22ef01cSRoman Divacky SmallVectorImpl<unsigned> *Ops) const { 815f22ef01cSRoman Divacky bool PartDef = false; // Partial redefine. 816f22ef01cSRoman Divacky bool FullDef = false; // Full define. 817f22ef01cSRoman Divacky bool Use = false; 818f22ef01cSRoman Divacky 819f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 820f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 821f22ef01cSRoman Divacky if (!MO.isReg() || MO.getReg() != Reg) 822f22ef01cSRoman Divacky continue; 823f22ef01cSRoman Divacky if (Ops) 824f22ef01cSRoman Divacky Ops->push_back(i); 825f22ef01cSRoman Divacky if (MO.isUse()) 826f22ef01cSRoman Divacky Use |= !MO.isUndef(); 827f22ef01cSRoman Divacky else if (MO.getSubReg()) 828f22ef01cSRoman Divacky PartDef = true; 829f22ef01cSRoman Divacky else 830f22ef01cSRoman Divacky FullDef = true; 831f22ef01cSRoman Divacky } 832f22ef01cSRoman Divacky // A partial redefine uses Reg unless there is also a full define. 833f22ef01cSRoman Divacky return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 834f22ef01cSRoman Divacky } 835f22ef01cSRoman Divacky 836f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 837f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs 838f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 839f22ef01cSRoman Divacky /// also checks if there is a def of a super-register. 840f22ef01cSRoman Divacky int 841f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, 842f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 843f22ef01cSRoman Divacky bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg); 844f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 845f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 846f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 847f22ef01cSRoman Divacky continue; 848f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 849f22ef01cSRoman Divacky bool Found = (MOReg == Reg); 850f22ef01cSRoman Divacky if (!Found && TRI && isPhys && 851f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg)) { 852f22ef01cSRoman Divacky if (Overlap) 853f22ef01cSRoman Divacky Found = TRI->regsOverlap(MOReg, Reg); 854f22ef01cSRoman Divacky else 855f22ef01cSRoman Divacky Found = TRI->isSubRegister(MOReg, Reg); 856f22ef01cSRoman Divacky } 857f22ef01cSRoman Divacky if (Found && (!isDead || MO.isDead())) 858f22ef01cSRoman Divacky return i; 859f22ef01cSRoman Divacky } 860f22ef01cSRoman Divacky return -1; 861f22ef01cSRoman Divacky } 862f22ef01cSRoman Divacky 863f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the 864f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if 865f22ef01cSRoman Divacky /// none is found. 866f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const { 867f22ef01cSRoman Divacky const TargetInstrDesc &TID = getDesc(); 868f22ef01cSRoman Divacky if (TID.isPredicable()) { 869f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 870f22ef01cSRoman Divacky if (TID.OpInfo[i].isPredicate()) 871f22ef01cSRoman Divacky return i; 872f22ef01cSRoman Divacky } 873f22ef01cSRoman Divacky 874f22ef01cSRoman Divacky return -1; 875f22ef01cSRoman Divacky } 876f22ef01cSRoman Divacky 877f22ef01cSRoman Divacky /// isRegTiedToUseOperand - Given the index of a register def operand, 878f22ef01cSRoman Divacky /// check if the register def is tied to a source operand, due to either 879f22ef01cSRoman Divacky /// two-address elimination or inline assembly constraints. Returns the 880f22ef01cSRoman Divacky /// first tied use operand index by reference is UseOpIdx is not null. 881f22ef01cSRoman Divacky bool MachineInstr:: 882f22ef01cSRoman Divacky isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const { 883f22ef01cSRoman Divacky if (isInlineAsm()) { 884ffd1746dSEd Schouten assert(DefOpIdx >= 3); 885f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(DefOpIdx); 886f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0) 887f22ef01cSRoman Divacky return false; 888f22ef01cSRoman Divacky // Determine the actual operand index that corresponds to this index. 889f22ef01cSRoman Divacky unsigned DefNo = 0; 890f22ef01cSRoman Divacky unsigned DefPart = 0; 891ffd1746dSEd Schouten for (unsigned i = 2, e = getNumOperands(); i < e; ) { 892f22ef01cSRoman Divacky const MachineOperand &FMO = getOperand(i); 893f22ef01cSRoman Divacky // After the normal asm operands there may be additional imp-def regs. 894f22ef01cSRoman Divacky if (!FMO.isImm()) 895f22ef01cSRoman Divacky return false; 896f22ef01cSRoman Divacky // Skip over this def. 897f22ef01cSRoman Divacky unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm()); 898f22ef01cSRoman Divacky unsigned PrevDef = i + 1; 899f22ef01cSRoman Divacky i = PrevDef + NumOps; 900f22ef01cSRoman Divacky if (i > DefOpIdx) { 901f22ef01cSRoman Divacky DefPart = DefOpIdx - PrevDef; 902f22ef01cSRoman Divacky break; 903f22ef01cSRoman Divacky } 904f22ef01cSRoman Divacky ++DefNo; 905f22ef01cSRoman Divacky } 906ffd1746dSEd Schouten for (unsigned i = 2, e = getNumOperands(); i != e; ++i) { 907f22ef01cSRoman Divacky const MachineOperand &FMO = getOperand(i); 908f22ef01cSRoman Divacky if (!FMO.isImm()) 909f22ef01cSRoman Divacky continue; 910f22ef01cSRoman Divacky if (i+1 >= e || !getOperand(i+1).isReg() || !getOperand(i+1).isUse()) 911f22ef01cSRoman Divacky continue; 912f22ef01cSRoman Divacky unsigned Idx; 913f22ef01cSRoman Divacky if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) && 914f22ef01cSRoman Divacky Idx == DefNo) { 915f22ef01cSRoman Divacky if (UseOpIdx) 916f22ef01cSRoman Divacky *UseOpIdx = (unsigned)i + 1 + DefPart; 917f22ef01cSRoman Divacky return true; 918f22ef01cSRoman Divacky } 919f22ef01cSRoman Divacky } 920f22ef01cSRoman Divacky return false; 921f22ef01cSRoman Divacky } 922f22ef01cSRoman Divacky 923f22ef01cSRoman Divacky assert(getOperand(DefOpIdx).isDef() && "DefOpIdx is not a def!"); 924f22ef01cSRoman Divacky const TargetInstrDesc &TID = getDesc(); 925f22ef01cSRoman Divacky for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) { 926f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 927f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse() && 928f22ef01cSRoman Divacky TID.getOperandConstraint(i, TOI::TIED_TO) == (int)DefOpIdx) { 929f22ef01cSRoman Divacky if (UseOpIdx) 930f22ef01cSRoman Divacky *UseOpIdx = (unsigned)i; 931f22ef01cSRoman Divacky return true; 932f22ef01cSRoman Divacky } 933f22ef01cSRoman Divacky } 934f22ef01cSRoman Divacky return false; 935f22ef01cSRoman Divacky } 936f22ef01cSRoman Divacky 937f22ef01cSRoman Divacky /// isRegTiedToDefOperand - Return true if the operand of the specified index 938f22ef01cSRoman Divacky /// is a register use and it is tied to an def operand. It also returns the def 939f22ef01cSRoman Divacky /// operand index by reference. 940f22ef01cSRoman Divacky bool MachineInstr:: 941f22ef01cSRoman Divacky isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const { 942f22ef01cSRoman Divacky if (isInlineAsm()) { 943f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(UseOpIdx); 944f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.getReg() == 0) 945f22ef01cSRoman Divacky return false; 946f22ef01cSRoman Divacky 947f22ef01cSRoman Divacky // Find the flag operand corresponding to UseOpIdx 948f22ef01cSRoman Divacky unsigned FlagIdx, NumOps=0; 949ffd1746dSEd Schouten for (FlagIdx = 2; FlagIdx < UseOpIdx; FlagIdx += NumOps+1) { 950f22ef01cSRoman Divacky const MachineOperand &UFMO = getOperand(FlagIdx); 951f22ef01cSRoman Divacky // After the normal asm operands there may be additional imp-def regs. 952f22ef01cSRoman Divacky if (!UFMO.isImm()) 953f22ef01cSRoman Divacky return false; 954f22ef01cSRoman Divacky NumOps = InlineAsm::getNumOperandRegisters(UFMO.getImm()); 955f22ef01cSRoman Divacky assert(NumOps < getNumOperands() && "Invalid inline asm flag"); 956f22ef01cSRoman Divacky if (UseOpIdx < FlagIdx+NumOps+1) 957f22ef01cSRoman Divacky break; 958f22ef01cSRoman Divacky } 959f22ef01cSRoman Divacky if (FlagIdx >= UseOpIdx) 960f22ef01cSRoman Divacky return false; 961f22ef01cSRoman Divacky const MachineOperand &UFMO = getOperand(FlagIdx); 962f22ef01cSRoman Divacky unsigned DefNo; 963f22ef01cSRoman Divacky if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) { 964f22ef01cSRoman Divacky if (!DefOpIdx) 965f22ef01cSRoman Divacky return true; 966f22ef01cSRoman Divacky 967ffd1746dSEd Schouten unsigned DefIdx = 2; 968ffd1746dSEd Schouten // Remember to adjust the index. First operand is asm string, second is 969ffd1746dSEd Schouten // the AlignStack bit, then there is a flag for each. 970f22ef01cSRoman Divacky while (DefNo) { 971f22ef01cSRoman Divacky const MachineOperand &FMO = getOperand(DefIdx); 972f22ef01cSRoman Divacky assert(FMO.isImm()); 973f22ef01cSRoman Divacky // Skip over this def. 974f22ef01cSRoman Divacky DefIdx += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1; 975f22ef01cSRoman Divacky --DefNo; 976f22ef01cSRoman Divacky } 977f22ef01cSRoman Divacky *DefOpIdx = DefIdx + UseOpIdx - FlagIdx; 978f22ef01cSRoman Divacky return true; 979f22ef01cSRoman Divacky } 980f22ef01cSRoman Divacky return false; 981f22ef01cSRoman Divacky } 982f22ef01cSRoman Divacky 983f22ef01cSRoman Divacky const TargetInstrDesc &TID = getDesc(); 984f22ef01cSRoman Divacky if (UseOpIdx >= TID.getNumOperands()) 985f22ef01cSRoman Divacky return false; 986f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(UseOpIdx); 987f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 988f22ef01cSRoman Divacky return false; 989f22ef01cSRoman Divacky int DefIdx = TID.getOperandConstraint(UseOpIdx, TOI::TIED_TO); 990f22ef01cSRoman Divacky if (DefIdx == -1) 991f22ef01cSRoman Divacky return false; 992f22ef01cSRoman Divacky if (DefOpIdx) 993f22ef01cSRoman Divacky *DefOpIdx = (unsigned)DefIdx; 994f22ef01cSRoman Divacky return true; 995f22ef01cSRoman Divacky } 996f22ef01cSRoman Divacky 997f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands. 998f22ef01cSRoman Divacky /// 999f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() { 1000f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1001f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1002f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse()) 1003f22ef01cSRoman Divacky MO.setIsKill(false); 1004f22ef01cSRoman Divacky } 1005f22ef01cSRoman Divacky } 1006f22ef01cSRoman Divacky 1007f22ef01cSRoman Divacky /// copyKillDeadInfo - Copies kill / dead operand properties from MI. 1008f22ef01cSRoman Divacky /// 1009f22ef01cSRoman Divacky void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { 1010f22ef01cSRoman Divacky for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 1011f22ef01cSRoman Divacky const MachineOperand &MO = MI->getOperand(i); 1012f22ef01cSRoman Divacky if (!MO.isReg() || (!MO.isKill() && !MO.isDead())) 1013f22ef01cSRoman Divacky continue; 1014f22ef01cSRoman Divacky for (unsigned j = 0, ee = getNumOperands(); j != ee; ++j) { 1015f22ef01cSRoman Divacky MachineOperand &MOp = getOperand(j); 1016f22ef01cSRoman Divacky if (!MOp.isIdenticalTo(MO)) 1017f22ef01cSRoman Divacky continue; 1018f22ef01cSRoman Divacky if (MO.isKill()) 1019f22ef01cSRoman Divacky MOp.setIsKill(); 1020f22ef01cSRoman Divacky else 1021f22ef01cSRoman Divacky MOp.setIsDead(); 1022f22ef01cSRoman Divacky break; 1023f22ef01cSRoman Divacky } 1024f22ef01cSRoman Divacky } 1025f22ef01cSRoman Divacky } 1026f22ef01cSRoman Divacky 1027f22ef01cSRoman Divacky /// copyPredicates - Copies predicate operand(s) from MI. 1028f22ef01cSRoman Divacky void MachineInstr::copyPredicates(const MachineInstr *MI) { 1029f22ef01cSRoman Divacky const TargetInstrDesc &TID = MI->getDesc(); 1030f22ef01cSRoman Divacky if (!TID.isPredicable()) 1031f22ef01cSRoman Divacky return; 1032f22ef01cSRoman Divacky for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 1033f22ef01cSRoman Divacky if (TID.OpInfo[i].isPredicate()) { 1034f22ef01cSRoman Divacky // Predicated operands must be last operands. 1035f22ef01cSRoman Divacky addOperand(MI->getOperand(i)); 1036f22ef01cSRoman Divacky } 1037f22ef01cSRoman Divacky } 1038f22ef01cSRoman Divacky } 1039f22ef01cSRoman Divacky 1040ffd1746dSEd Schouten void MachineInstr::substituteRegister(unsigned FromReg, 1041ffd1746dSEd Schouten unsigned ToReg, 1042ffd1746dSEd Schouten unsigned SubIdx, 1043ffd1746dSEd Schouten const TargetRegisterInfo &RegInfo) { 1044ffd1746dSEd Schouten if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { 1045ffd1746dSEd Schouten if (SubIdx) 1046ffd1746dSEd Schouten ToReg = RegInfo.getSubReg(ToReg, SubIdx); 1047ffd1746dSEd Schouten for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1048ffd1746dSEd Schouten MachineOperand &MO = getOperand(i); 1049ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1050ffd1746dSEd Schouten continue; 1051ffd1746dSEd Schouten MO.substPhysReg(ToReg, RegInfo); 1052ffd1746dSEd Schouten } 1053ffd1746dSEd Schouten } else { 1054ffd1746dSEd Schouten for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1055ffd1746dSEd Schouten MachineOperand &MO = getOperand(i); 1056ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1057ffd1746dSEd Schouten continue; 1058ffd1746dSEd Schouten MO.substVirtReg(ToReg, SubIdx, RegInfo); 1059ffd1746dSEd Schouten } 1060ffd1746dSEd Schouten } 1061ffd1746dSEd Schouten } 1062ffd1746dSEd Schouten 1063f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If 1064f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between 1065f22ef01cSRoman Divacky /// the instruction's location and its intended destination. 1066f22ef01cSRoman Divacky bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII, 1067f22ef01cSRoman Divacky AliasAnalysis *AA, 1068f22ef01cSRoman Divacky bool &SawStore) const { 1069f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move. 1070f22ef01cSRoman Divacky if (TID->mayStore() || TID->isCall()) { 1071f22ef01cSRoman Divacky SawStore = true; 1072f22ef01cSRoman Divacky return false; 1073f22ef01cSRoman Divacky } 1074f22ef01cSRoman Divacky if (TID->isTerminator() || TID->hasUnmodeledSideEffects()) 1075f22ef01cSRoman Divacky return false; 1076f22ef01cSRoman Divacky 1077f22ef01cSRoman Divacky // See if this instruction does a load. If so, we have to guarantee that the 1078f22ef01cSRoman Divacky // loaded value doesn't change between the load and the its intended 1079f22ef01cSRoman Divacky // destination. The check for isInvariantLoad gives the targe the chance to 1080f22ef01cSRoman Divacky // classify the load as always returning a constant, e.g. a constant pool 1081f22ef01cSRoman Divacky // load. 1082f22ef01cSRoman Divacky if (TID->mayLoad() && !isInvariantLoad(AA)) 1083f22ef01cSRoman Divacky // Otherwise, this is a real load. If there is a store between the load and 1084f22ef01cSRoman Divacky // end of block, or if the load is volatile, we can't move it. 1085f22ef01cSRoman Divacky return !SawStore && !hasVolatileMemoryRef(); 1086f22ef01cSRoman Divacky 1087f22ef01cSRoman Divacky return true; 1088f22ef01cSRoman Divacky } 1089f22ef01cSRoman Divacky 1090f22ef01cSRoman Divacky /// isSafeToReMat - Return true if it's safe to rematerialize the specified 1091f22ef01cSRoman Divacky /// instruction which defined the specified register instead of copying it. 1092f22ef01cSRoman Divacky bool MachineInstr::isSafeToReMat(const TargetInstrInfo *TII, 1093f22ef01cSRoman Divacky AliasAnalysis *AA, 1094f22ef01cSRoman Divacky unsigned DstReg) const { 1095f22ef01cSRoman Divacky bool SawStore = false; 1096f22ef01cSRoman Divacky if (!TII->isTriviallyReMaterializable(this, AA) || 1097f22ef01cSRoman Divacky !isSafeToMove(TII, AA, SawStore)) 1098f22ef01cSRoman Divacky return false; 1099f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1100f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1101f22ef01cSRoman Divacky if (!MO.isReg()) 1102f22ef01cSRoman Divacky continue; 1103f22ef01cSRoman Divacky // FIXME: For now, do not remat any instruction with register operands. 1104f22ef01cSRoman Divacky // Later on, we can loosen the restriction is the register operands have 1105f22ef01cSRoman Divacky // not been modified between the def and use. Note, this is different from 1106f22ef01cSRoman Divacky // MachineSink because the code is no longer in two-address form (at least 1107f22ef01cSRoman Divacky // partially). 1108f22ef01cSRoman Divacky if (MO.isUse()) 1109f22ef01cSRoman Divacky return false; 1110f22ef01cSRoman Divacky else if (!MO.isDead() && MO.getReg() != DstReg) 1111f22ef01cSRoman Divacky return false; 1112f22ef01cSRoman Divacky } 1113f22ef01cSRoman Divacky return true; 1114f22ef01cSRoman Divacky } 1115f22ef01cSRoman Divacky 1116f22ef01cSRoman Divacky /// hasVolatileMemoryRef - Return true if this instruction may have a 1117f22ef01cSRoman Divacky /// volatile memory reference, or if the information describing the 1118f22ef01cSRoman Divacky /// memory reference is not available. Return false if it is known to 1119f22ef01cSRoman Divacky /// have no volatile memory references. 1120f22ef01cSRoman Divacky bool MachineInstr::hasVolatileMemoryRef() const { 1121f22ef01cSRoman Divacky // An instruction known never to access memory won't have a volatile access. 1122f22ef01cSRoman Divacky if (!TID->mayStore() && 1123f22ef01cSRoman Divacky !TID->mayLoad() && 1124f22ef01cSRoman Divacky !TID->isCall() && 1125f22ef01cSRoman Divacky !TID->hasUnmodeledSideEffects()) 1126f22ef01cSRoman Divacky return false; 1127f22ef01cSRoman Divacky 1128f22ef01cSRoman Divacky // Otherwise, if the instruction has no memory reference information, 1129f22ef01cSRoman Divacky // conservatively assume it wasn't preserved. 1130f22ef01cSRoman Divacky if (memoperands_empty()) 1131f22ef01cSRoman Divacky return true; 1132f22ef01cSRoman Divacky 1133f22ef01cSRoman Divacky // Check the memory reference information for volatile references. 1134f22ef01cSRoman Divacky for (mmo_iterator I = memoperands_begin(), E = memoperands_end(); I != E; ++I) 1135f22ef01cSRoman Divacky if ((*I)->isVolatile()) 1136f22ef01cSRoman Divacky return true; 1137f22ef01cSRoman Divacky 1138f22ef01cSRoman Divacky return false; 1139f22ef01cSRoman Divacky } 1140f22ef01cSRoman Divacky 1141f22ef01cSRoman Divacky /// isInvariantLoad - Return true if this instruction is loading from a 1142f22ef01cSRoman Divacky /// location whose value is invariant across the function. For example, 1143f22ef01cSRoman Divacky /// loading a value from the constant pool or from the argument area 1144f22ef01cSRoman Divacky /// of a function if it does not change. This should only return true of 1145f22ef01cSRoman Divacky /// *all* loads the instruction does are invariant (if it does multiple loads). 1146f22ef01cSRoman Divacky bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const { 1147f22ef01cSRoman Divacky // If the instruction doesn't load at all, it isn't an invariant load. 1148f22ef01cSRoman Divacky if (!TID->mayLoad()) 1149f22ef01cSRoman Divacky return false; 1150f22ef01cSRoman Divacky 1151f22ef01cSRoman Divacky // If the instruction has lost its memoperands, conservatively assume that 1152f22ef01cSRoman Divacky // it may not be an invariant load. 1153f22ef01cSRoman Divacky if (memoperands_empty()) 1154f22ef01cSRoman Divacky return false; 1155f22ef01cSRoman Divacky 1156f22ef01cSRoman Divacky const MachineFrameInfo *MFI = getParent()->getParent()->getFrameInfo(); 1157f22ef01cSRoman Divacky 1158f22ef01cSRoman Divacky for (mmo_iterator I = memoperands_begin(), 1159f22ef01cSRoman Divacky E = memoperands_end(); I != E; ++I) { 1160f22ef01cSRoman Divacky if ((*I)->isVolatile()) return false; 1161f22ef01cSRoman Divacky if ((*I)->isStore()) return false; 1162f22ef01cSRoman Divacky 1163f22ef01cSRoman Divacky if (const Value *V = (*I)->getValue()) { 1164f22ef01cSRoman Divacky // A load from a constant PseudoSourceValue is invariant. 1165f22ef01cSRoman Divacky if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V)) 1166f22ef01cSRoman Divacky if (PSV->isConstant(MFI)) 1167f22ef01cSRoman Divacky continue; 1168f22ef01cSRoman Divacky // If we have an AliasAnalysis, ask it whether the memory is constant. 1169f22ef01cSRoman Divacky if (AA && AA->pointsToConstantMemory(V)) 1170f22ef01cSRoman Divacky continue; 1171f22ef01cSRoman Divacky } 1172f22ef01cSRoman Divacky 1173f22ef01cSRoman Divacky // Otherwise assume conservatively. 1174f22ef01cSRoman Divacky return false; 1175f22ef01cSRoman Divacky } 1176f22ef01cSRoman Divacky 1177f22ef01cSRoman Divacky // Everything checks out. 1178f22ef01cSRoman Divacky return true; 1179f22ef01cSRoman Divacky } 1180f22ef01cSRoman Divacky 1181f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always 1182f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise 1183f22ef01cSRoman Divacky /// return 0. 1184f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const { 1185f22ef01cSRoman Divacky if (!isPHI()) 1186f22ef01cSRoman Divacky return 0; 1187f22ef01cSRoman Divacky assert(getNumOperands() >= 3 && 1188f22ef01cSRoman Divacky "It's illegal to have a PHI without source operands"); 1189f22ef01cSRoman Divacky 1190f22ef01cSRoman Divacky unsigned Reg = getOperand(1).getReg(); 1191f22ef01cSRoman Divacky for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 1192f22ef01cSRoman Divacky if (getOperand(i).getReg() != Reg) 1193f22ef01cSRoman Divacky return 0; 1194f22ef01cSRoman Divacky return Reg; 1195f22ef01cSRoman Divacky } 1196f22ef01cSRoman Divacky 1197f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead. 1198f22ef01cSRoman Divacky /// 1199f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const { 1200f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i < e; ++i) { 1201f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1202f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUse()) 1203f22ef01cSRoman Divacky continue; 1204f22ef01cSRoman Divacky if (!MO.isDead()) 1205f22ef01cSRoman Divacky return false; 1206f22ef01cSRoman Divacky } 1207f22ef01cSRoman Divacky return true; 1208f22ef01cSRoman Divacky } 1209f22ef01cSRoman Divacky 1210f22ef01cSRoman Divacky void MachineInstr::dump() const { 1211f22ef01cSRoman Divacky dbgs() << " " << *this; 1212f22ef01cSRoman Divacky } 1213f22ef01cSRoman Divacky 1214ffd1746dSEd Schouten static void printDebugLoc(DebugLoc DL, const MachineFunction *MF, 1215ffd1746dSEd Schouten raw_ostream &CommentOS) { 1216ffd1746dSEd Schouten const LLVMContext &Ctx = MF->getFunction()->getContext(); 1217ffd1746dSEd Schouten if (!DL.isUnknown()) { // Print source line info. 1218ffd1746dSEd Schouten DIScope Scope(DL.getScope(Ctx)); 1219ffd1746dSEd Schouten // Omit the directory, because it's likely to be long and uninteresting. 1220ffd1746dSEd Schouten if (Scope.Verify()) 1221ffd1746dSEd Schouten CommentOS << Scope.getFilename(); 1222ffd1746dSEd Schouten else 1223ffd1746dSEd Schouten CommentOS << "<unknown>"; 1224ffd1746dSEd Schouten CommentOS << ':' << DL.getLine(); 1225ffd1746dSEd Schouten if (DL.getCol() != 0) 1226ffd1746dSEd Schouten CommentOS << ':' << DL.getCol(); 1227ffd1746dSEd Schouten DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx)); 1228ffd1746dSEd Schouten if (!InlinedAtDL.isUnknown()) { 1229ffd1746dSEd Schouten CommentOS << " @[ "; 1230ffd1746dSEd Schouten printDebugLoc(InlinedAtDL, MF, CommentOS); 1231ffd1746dSEd Schouten CommentOS << " ]"; 1232ffd1746dSEd Schouten } 1233ffd1746dSEd Schouten } 1234ffd1746dSEd Schouten } 1235ffd1746dSEd Schouten 1236f22ef01cSRoman Divacky void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { 1237f22ef01cSRoman Divacky // We can be a bit tidier if we know the TargetMachine and/or MachineFunction. 1238f22ef01cSRoman Divacky const MachineFunction *MF = 0; 1239f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = getParent()) { 1240f22ef01cSRoman Divacky MF = MBB->getParent(); 1241f22ef01cSRoman Divacky if (!TM && MF) 1242f22ef01cSRoman Divacky TM = &MF->getTarget(); 1243f22ef01cSRoman Divacky } 1244f22ef01cSRoman Divacky 1245f22ef01cSRoman Divacky // Print explicitly defined operands on the left of an assignment syntax. 1246f22ef01cSRoman Divacky unsigned StartOp = 0, e = getNumOperands(); 1247f22ef01cSRoman Divacky for (; StartOp < e && getOperand(StartOp).isReg() && 1248f22ef01cSRoman Divacky getOperand(StartOp).isDef() && 1249f22ef01cSRoman Divacky !getOperand(StartOp).isImplicit(); 1250f22ef01cSRoman Divacky ++StartOp) { 1251f22ef01cSRoman Divacky if (StartOp != 0) OS << ", "; 1252f22ef01cSRoman Divacky getOperand(StartOp).print(OS, TM); 1253f22ef01cSRoman Divacky } 1254f22ef01cSRoman Divacky 1255f22ef01cSRoman Divacky if (StartOp != 0) 1256f22ef01cSRoman Divacky OS << " = "; 1257f22ef01cSRoman Divacky 1258f22ef01cSRoman Divacky // Print the opcode name. 1259f22ef01cSRoman Divacky OS << getDesc().getName(); 1260f22ef01cSRoman Divacky 1261f22ef01cSRoman Divacky // Print the rest of the operands. 1262f22ef01cSRoman Divacky bool OmittedAnyCallClobbers = false; 1263f22ef01cSRoman Divacky bool FirstOp = true; 1264f22ef01cSRoman Divacky for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 1265f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1266f22ef01cSRoman Divacky 1267f22ef01cSRoman Divacky // Omit call-clobbered registers which aren't used anywhere. This makes 1268f22ef01cSRoman Divacky // call instructions much less noisy on targets where calls clobber lots 1269f22ef01cSRoman Divacky // of registers. Don't rely on MO.isDead() because we may be called before 1270f22ef01cSRoman Divacky // LiveVariables is run, or we may be looking at a non-allocatable reg. 1271f22ef01cSRoman Divacky if (MF && getDesc().isCall() && 1272f22ef01cSRoman Divacky MO.isReg() && MO.isImplicit() && MO.isDef()) { 1273f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 1274f22ef01cSRoman Divacky if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) { 1275f22ef01cSRoman Divacky const MachineRegisterInfo &MRI = MF->getRegInfo(); 1276f22ef01cSRoman Divacky if (MRI.use_empty(Reg) && !MRI.isLiveOut(Reg)) { 1277f22ef01cSRoman Divacky bool HasAliasLive = false; 1278f22ef01cSRoman Divacky for (const unsigned *Alias = TM->getRegisterInfo()->getAliasSet(Reg); 1279f22ef01cSRoman Divacky unsigned AliasReg = *Alias; ++Alias) 1280f22ef01cSRoman Divacky if (!MRI.use_empty(AliasReg) || MRI.isLiveOut(AliasReg)) { 1281f22ef01cSRoman Divacky HasAliasLive = true; 1282f22ef01cSRoman Divacky break; 1283f22ef01cSRoman Divacky } 1284f22ef01cSRoman Divacky if (!HasAliasLive) { 1285f22ef01cSRoman Divacky OmittedAnyCallClobbers = true; 1286f22ef01cSRoman Divacky continue; 1287f22ef01cSRoman Divacky } 1288f22ef01cSRoman Divacky } 1289f22ef01cSRoman Divacky } 1290f22ef01cSRoman Divacky } 1291f22ef01cSRoman Divacky 1292f22ef01cSRoman Divacky if (FirstOp) FirstOp = false; else OS << ","; 1293f22ef01cSRoman Divacky OS << " "; 1294f22ef01cSRoman Divacky if (i < getDesc().NumOperands) { 1295f22ef01cSRoman Divacky const TargetOperandInfo &TOI = getDesc().OpInfo[i]; 1296f22ef01cSRoman Divacky if (TOI.isPredicate()) 1297f22ef01cSRoman Divacky OS << "pred:"; 1298f22ef01cSRoman Divacky if (TOI.isOptionalDef()) 1299f22ef01cSRoman Divacky OS << "opt:"; 1300f22ef01cSRoman Divacky } 1301f22ef01cSRoman Divacky if (isDebugValue() && MO.isMetadata()) { 1302f22ef01cSRoman Divacky // Pretty print DBG_VALUE instructions. 1303f22ef01cSRoman Divacky const MDNode *MD = MO.getMetadata(); 1304f22ef01cSRoman Divacky if (const MDString *MDS = dyn_cast<MDString>(MD->getOperand(2))) 1305f22ef01cSRoman Divacky OS << "!\"" << MDS->getString() << '\"'; 1306f22ef01cSRoman Divacky else 1307f22ef01cSRoman Divacky MO.print(OS, TM); 1308ffd1746dSEd Schouten } else if (TM && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { 1309ffd1746dSEd Schouten OS << TM->getRegisterInfo()->getSubRegIndexName(MO.getImm()); 1310f22ef01cSRoman Divacky } else 1311f22ef01cSRoman Divacky MO.print(OS, TM); 1312f22ef01cSRoman Divacky } 1313f22ef01cSRoman Divacky 1314f22ef01cSRoman Divacky // Briefly indicate whether any call clobbers were omitted. 1315f22ef01cSRoman Divacky if (OmittedAnyCallClobbers) { 1316f22ef01cSRoman Divacky if (!FirstOp) OS << ","; 1317f22ef01cSRoman Divacky OS << " ..."; 1318f22ef01cSRoman Divacky } 1319f22ef01cSRoman Divacky 1320f22ef01cSRoman Divacky bool HaveSemi = false; 1321f22ef01cSRoman Divacky if (!memoperands_empty()) { 1322f22ef01cSRoman Divacky if (!HaveSemi) OS << ";"; HaveSemi = true; 1323f22ef01cSRoman Divacky 1324f22ef01cSRoman Divacky OS << " mem:"; 1325f22ef01cSRoman Divacky for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); 1326f22ef01cSRoman Divacky i != e; ++i) { 1327f22ef01cSRoman Divacky OS << **i; 1328f22ef01cSRoman Divacky if (next(i) != e) 1329f22ef01cSRoman Divacky OS << " "; 1330f22ef01cSRoman Divacky } 1331f22ef01cSRoman Divacky } 1332f22ef01cSRoman Divacky 1333f22ef01cSRoman Divacky if (!debugLoc.isUnknown() && MF) { 1334f22ef01cSRoman Divacky if (!HaveSemi) OS << ";"; 1335f22ef01cSRoman Divacky OS << " dbg:"; 1336ffd1746dSEd Schouten printDebugLoc(debugLoc, MF, OS); 1337f22ef01cSRoman Divacky } 1338f22ef01cSRoman Divacky 1339f22ef01cSRoman Divacky OS << "\n"; 1340f22ef01cSRoman Divacky } 1341f22ef01cSRoman Divacky 1342f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg, 1343f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1344f22ef01cSRoman Divacky bool AddIfNotFound) { 1345f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 1346f22ef01cSRoman Divacky bool hasAliases = isPhysReg && RegInfo->getAliasSet(IncomingReg); 1347f22ef01cSRoman Divacky bool Found = false; 1348f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1349f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1350f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1351f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 1352f22ef01cSRoman Divacky continue; 1353f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 1354f22ef01cSRoman Divacky if (!Reg) 1355f22ef01cSRoman Divacky continue; 1356f22ef01cSRoman Divacky 1357f22ef01cSRoman Divacky if (Reg == IncomingReg) { 1358f22ef01cSRoman Divacky if (!Found) { 1359f22ef01cSRoman Divacky if (MO.isKill()) 1360f22ef01cSRoman Divacky // The register is already marked kill. 1361f22ef01cSRoman Divacky return true; 1362f22ef01cSRoman Divacky if (isPhysReg && isRegTiedToDefOperand(i)) 1363f22ef01cSRoman Divacky // Two-address uses of physregs must not be marked kill. 1364f22ef01cSRoman Divacky return true; 1365f22ef01cSRoman Divacky MO.setIsKill(); 1366f22ef01cSRoman Divacky Found = true; 1367f22ef01cSRoman Divacky } 1368f22ef01cSRoman Divacky } else if (hasAliases && MO.isKill() && 1369f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 1370f22ef01cSRoman Divacky // A super-register kill already exists. 1371f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 1372f22ef01cSRoman Divacky return true; 1373f22ef01cSRoman Divacky if (RegInfo->isSubRegister(IncomingReg, Reg)) 1374f22ef01cSRoman Divacky DeadOps.push_back(i); 1375f22ef01cSRoman Divacky } 1376f22ef01cSRoman Divacky } 1377f22ef01cSRoman Divacky 1378f22ef01cSRoman Divacky // Trim unneeded kill operands. 1379f22ef01cSRoman Divacky while (!DeadOps.empty()) { 1380f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 1381f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 1382f22ef01cSRoman Divacky RemoveOperand(OpIdx); 1383f22ef01cSRoman Divacky else 1384f22ef01cSRoman Divacky getOperand(OpIdx).setIsKill(false); 1385f22ef01cSRoman Divacky DeadOps.pop_back(); 1386f22ef01cSRoman Divacky } 1387f22ef01cSRoman Divacky 1388f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is killed. Add a 1389f22ef01cSRoman Divacky // new implicit operand if required. 1390f22ef01cSRoman Divacky if (!Found && AddIfNotFound) { 1391f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 1392f22ef01cSRoman Divacky false /*IsDef*/, 1393f22ef01cSRoman Divacky true /*IsImp*/, 1394f22ef01cSRoman Divacky true /*IsKill*/)); 1395f22ef01cSRoman Divacky return true; 1396f22ef01cSRoman Divacky } 1397f22ef01cSRoman Divacky return Found; 1398f22ef01cSRoman Divacky } 1399f22ef01cSRoman Divacky 1400f22ef01cSRoman Divacky bool MachineInstr::addRegisterDead(unsigned IncomingReg, 1401f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1402f22ef01cSRoman Divacky bool AddIfNotFound) { 1403f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 1404f22ef01cSRoman Divacky bool hasAliases = isPhysReg && RegInfo->getAliasSet(IncomingReg); 1405f22ef01cSRoman Divacky bool Found = false; 1406f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1407f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1408f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1409f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1410f22ef01cSRoman Divacky continue; 1411f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 1412f22ef01cSRoman Divacky if (!Reg) 1413f22ef01cSRoman Divacky continue; 1414f22ef01cSRoman Divacky 1415f22ef01cSRoman Divacky if (Reg == IncomingReg) { 1416f22ef01cSRoman Divacky if (!Found) { 1417f22ef01cSRoman Divacky if (MO.isDead()) 1418f22ef01cSRoman Divacky // The register is already marked dead. 1419f22ef01cSRoman Divacky return true; 1420f22ef01cSRoman Divacky MO.setIsDead(); 1421f22ef01cSRoman Divacky Found = true; 1422f22ef01cSRoman Divacky } 1423f22ef01cSRoman Divacky } else if (hasAliases && MO.isDead() && 1424f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 1425f22ef01cSRoman Divacky // There exists a super-register that's marked dead. 1426f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 1427f22ef01cSRoman Divacky return true; 1428f22ef01cSRoman Divacky if (RegInfo->getSubRegisters(IncomingReg) && 1429f22ef01cSRoman Divacky RegInfo->getSuperRegisters(Reg) && 1430f22ef01cSRoman Divacky RegInfo->isSubRegister(IncomingReg, Reg)) 1431f22ef01cSRoman Divacky DeadOps.push_back(i); 1432f22ef01cSRoman Divacky } 1433f22ef01cSRoman Divacky } 1434f22ef01cSRoman Divacky 1435f22ef01cSRoman Divacky // Trim unneeded dead operands. 1436f22ef01cSRoman Divacky while (!DeadOps.empty()) { 1437f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 1438f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 1439f22ef01cSRoman Divacky RemoveOperand(OpIdx); 1440f22ef01cSRoman Divacky else 1441f22ef01cSRoman Divacky getOperand(OpIdx).setIsDead(false); 1442f22ef01cSRoman Divacky DeadOps.pop_back(); 1443f22ef01cSRoman Divacky } 1444f22ef01cSRoman Divacky 1445f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is dead. Add a 1446f22ef01cSRoman Divacky // new implicit operand if required. 1447f22ef01cSRoman Divacky if (Found || !AddIfNotFound) 1448f22ef01cSRoman Divacky return Found; 1449f22ef01cSRoman Divacky 1450f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 1451f22ef01cSRoman Divacky true /*IsDef*/, 1452f22ef01cSRoman Divacky true /*IsImp*/, 1453f22ef01cSRoman Divacky false /*IsKill*/, 1454f22ef01cSRoman Divacky true /*IsDead*/)); 1455f22ef01cSRoman Divacky return true; 1456f22ef01cSRoman Divacky } 1457f22ef01cSRoman Divacky 1458f22ef01cSRoman Divacky void MachineInstr::addRegisterDefined(unsigned IncomingReg, 1459f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo) { 1460f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(IncomingReg)) { 1461f22ef01cSRoman Divacky MachineOperand *MO = findRegisterDefOperand(IncomingReg, false, RegInfo); 1462f22ef01cSRoman Divacky if (MO) 1463f22ef01cSRoman Divacky return; 1464f22ef01cSRoman Divacky } else { 1465f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1466f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1467f22ef01cSRoman Divacky if (MO.isReg() && MO.getReg() == IncomingReg && MO.isDef() && 1468f22ef01cSRoman Divacky MO.getSubReg() == 0) 1469f22ef01cSRoman Divacky return; 1470f22ef01cSRoman Divacky } 1471f22ef01cSRoman Divacky } 1472f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 1473f22ef01cSRoman Divacky true /*IsDef*/, 1474f22ef01cSRoman Divacky true /*IsImp*/)); 1475f22ef01cSRoman Divacky } 1476f22ef01cSRoman Divacky 1477ffd1746dSEd Schouten void MachineInstr::setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRegs, 1478ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 1479ffd1746dSEd Schouten for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1480ffd1746dSEd Schouten MachineOperand &MO = getOperand(i); 1481ffd1746dSEd Schouten if (!MO.isReg() || !MO.isDef()) continue; 1482ffd1746dSEd Schouten unsigned Reg = MO.getReg(); 1483ffd1746dSEd Schouten if (Reg == 0) continue; 1484ffd1746dSEd Schouten bool Dead = true; 1485ffd1746dSEd Schouten for (SmallVectorImpl<unsigned>::const_iterator I = UsedRegs.begin(), 1486ffd1746dSEd Schouten E = UsedRegs.end(); I != E; ++I) 1487ffd1746dSEd Schouten if (TRI.regsOverlap(*I, Reg)) { 1488ffd1746dSEd Schouten Dead = false; 1489ffd1746dSEd Schouten break; 1490ffd1746dSEd Schouten } 1491ffd1746dSEd Schouten // If there are no uses, including partial uses, the def is dead. 1492ffd1746dSEd Schouten if (Dead) MO.setIsDead(); 1493ffd1746dSEd Schouten } 1494ffd1746dSEd Schouten } 1495ffd1746dSEd Schouten 1496f22ef01cSRoman Divacky unsigned 1497f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 1498f22ef01cSRoman Divacky unsigned Hash = MI->getOpcode() * 37; 1499f22ef01cSRoman Divacky for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 1500f22ef01cSRoman Divacky const MachineOperand &MO = MI->getOperand(i); 1501f22ef01cSRoman Divacky uint64_t Key = (uint64_t)MO.getType() << 32; 1502f22ef01cSRoman Divacky switch (MO.getType()) { 1503f22ef01cSRoman Divacky default: break; 1504f22ef01cSRoman Divacky case MachineOperand::MO_Register: 1505f22ef01cSRoman Divacky if (MO.isDef() && MO.getReg() && 1506f22ef01cSRoman Divacky TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1507f22ef01cSRoman Divacky continue; // Skip virtual register defs. 1508f22ef01cSRoman Divacky Key |= MO.getReg(); 1509f22ef01cSRoman Divacky break; 1510f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 1511f22ef01cSRoman Divacky Key |= MO.getImm(); 1512f22ef01cSRoman Divacky break; 1513f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 1514f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 1515f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 1516f22ef01cSRoman Divacky Key |= MO.getIndex(); 1517f22ef01cSRoman Divacky break; 1518f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 1519f22ef01cSRoman Divacky Key |= DenseMapInfo<void*>::getHashValue(MO.getMBB()); 1520f22ef01cSRoman Divacky break; 1521f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 1522f22ef01cSRoman Divacky Key |= DenseMapInfo<void*>::getHashValue(MO.getGlobal()); 1523f22ef01cSRoman Divacky break; 1524f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 1525f22ef01cSRoman Divacky Key |= DenseMapInfo<void*>::getHashValue(MO.getBlockAddress()); 1526f22ef01cSRoman Divacky break; 1527f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 1528f22ef01cSRoman Divacky Key |= DenseMapInfo<void*>::getHashValue(MO.getMCSymbol()); 1529f22ef01cSRoman Divacky break; 1530f22ef01cSRoman Divacky } 1531f22ef01cSRoman Divacky Key += ~(Key << 32); 1532f22ef01cSRoman Divacky Key ^= (Key >> 22); 1533f22ef01cSRoman Divacky Key += ~(Key << 13); 1534f22ef01cSRoman Divacky Key ^= (Key >> 8); 1535f22ef01cSRoman Divacky Key += (Key << 3); 1536f22ef01cSRoman Divacky Key ^= (Key >> 15); 1537f22ef01cSRoman Divacky Key += ~(Key << 27); 1538f22ef01cSRoman Divacky Key ^= (Key >> 31); 1539f22ef01cSRoman Divacky Hash = (unsigned)Key + Hash * 37; 1540f22ef01cSRoman Divacky } 1541f22ef01cSRoman Divacky return Hash; 1542f22ef01cSRoman Divacky } 1543