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