| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 1 | //===---- ScheduleDAGEmit.cpp - Emit routines for the ScheduleDAG class ---===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
 | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This implements the Emit routines for the ScheduleDAG class, which creates | 
 | 11 | // MachineInstrs according to the computed schedule. | 
 | 12 | // | 
 | 13 | //===----------------------------------------------------------------------===// | 
 | 14 |  | 
 | 15 | #define DEBUG_TYPE "pre-RA-sched" | 
| Dan Gohman | 84fbac5 | 2009-02-06 17:22:58 +0000 | [diff] [blame] | 16 | #include "ScheduleDAGSDNodes.h" | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 17 | #include "llvm/CodeGen/MachineConstantPool.h" | 
 | 18 | #include "llvm/CodeGen/MachineFunction.h" | 
 | 19 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
 | 20 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
 | 21 | #include "llvm/Target/TargetData.h" | 
 | 22 | #include "llvm/Target/TargetMachine.h" | 
 | 23 | #include "llvm/Target/TargetInstrInfo.h" | 
 | 24 | #include "llvm/Target/TargetLowering.h" | 
 | 25 | #include "llvm/ADT/Statistic.h" | 
 | 26 | #include "llvm/Support/CommandLine.h" | 
 | 27 | #include "llvm/Support/Debug.h" | 
 | 28 | #include "llvm/Support/MathExtras.h" | 
 | 29 | using namespace llvm; | 
 | 30 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 31 | /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an | 
 | 32 | /// implicit physical register output. | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 33 | void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo, | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 34 |                                          bool IsClone, bool IsCloned, | 
 | 35 |                                          unsigned SrcReg, | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 36 |                                          DenseMap<SDValue, unsigned> &VRBaseMap) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 37 |   unsigned VRBase = 0; | 
 | 38 |   if (TargetRegisterInfo::isVirtualRegister(SrcReg)) { | 
 | 39 |     // Just use the input register directly! | 
 | 40 |     SDValue Op(Node, ResNo); | 
 | 41 |     if (IsClone) | 
 | 42 |       VRBaseMap.erase(Op); | 
 | 43 |     bool isNew = VRBaseMap.insert(std::make_pair(Op, SrcReg)).second; | 
 | 44 |     isNew = isNew; // Silence compiler warning. | 
 | 45 |     assert(isNew && "Node emitted out of order - early"); | 
 | 46 |     return; | 
 | 47 |   } | 
 | 48 |  | 
 | 49 |   // If the node is only used by a CopyToReg and the dest reg is a vreg, use | 
 | 50 |   // the CopyToReg'd destination register instead of creating a new vreg. | 
 | 51 |   bool MatchReg = true; | 
| Evan Cheng | 1cd3327 | 2008-09-16 23:12:11 +0000 | [diff] [blame] | 52 |   const TargetRegisterClass *UseRC = NULL; | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 53 |   if (!IsClone && !IsCloned) | 
 | 54 |     for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); | 
 | 55 |          UI != E; ++UI) { | 
 | 56 |       SDNode *User = *UI; | 
 | 57 |       bool Match = true; | 
 | 58 |       if (User->getOpcode() == ISD::CopyToReg &&  | 
 | 59 |           User->getOperand(2).getNode() == Node && | 
 | 60 |           User->getOperand(2).getResNo() == ResNo) { | 
 | 61 |         unsigned DestReg = cast<RegisterSDNode>(User->getOperand(1))->getReg(); | 
 | 62 |         if (TargetRegisterInfo::isVirtualRegister(DestReg)) { | 
 | 63 |           VRBase = DestReg; | 
 | 64 |           Match = false; | 
 | 65 |         } else if (DestReg != SrcReg) | 
 | 66 |           Match = false; | 
 | 67 |       } else { | 
 | 68 |         for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) { | 
 | 69 |           SDValue Op = User->getOperand(i); | 
 | 70 |           if (Op.getNode() != Node || Op.getResNo() != ResNo) | 
 | 71 |             continue; | 
 | 72 |           MVT VT = Node->getValueType(Op.getResNo()); | 
 | 73 |           if (VT == MVT::Other || VT == MVT::Flag) | 
 | 74 |             continue; | 
 | 75 |           Match = false; | 
 | 76 |           if (User->isMachineOpcode()) { | 
 | 77 |             const TargetInstrDesc &II = TII->get(User->getMachineOpcode()); | 
 | 78 |             const TargetRegisterClass *RC = | 
| Evan Cheng | 770bcc7 | 2009-02-06 17:43:24 +0000 | [diff] [blame] | 79 |               getInstrOperandRegClass(TRI, II, i+II.getNumDefs()); | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 80 |             if (!UseRC) | 
 | 81 |               UseRC = RC; | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 82 |             else if (RC) { | 
 | 83 |               if (UseRC->hasSuperClass(RC)) | 
 | 84 |                 UseRC = RC; | 
 | 85 |               else | 
 | 86 |                 assert((UseRC == RC || RC->hasSuperClass(UseRC)) && | 
 | 87 |                        "Multiple uses expecting different register classes!"); | 
 | 88 |             } | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 89 |           } | 
| Evan Cheng | 1cd3327 | 2008-09-16 23:12:11 +0000 | [diff] [blame] | 90 |         } | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 91 |       } | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 92 |       MatchReg &= Match; | 
 | 93 |       if (VRBase) | 
 | 94 |         break; | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 95 |     } | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 96 |  | 
| Evan Cheng | 1cd3327 | 2008-09-16 23:12:11 +0000 | [diff] [blame] | 97 |   MVT VT = Node->getValueType(ResNo); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 98 |   const TargetRegisterClass *SrcRC = 0, *DstRC = 0; | 
| Evan Cheng | 1cd3327 | 2008-09-16 23:12:11 +0000 | [diff] [blame] | 99 |   SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 100 |    | 
 | 101 |   // Figure out the register class to create for the destreg. | 
 | 102 |   if (VRBase) { | 
 | 103 |     DstRC = MRI.getRegClass(VRBase); | 
| Evan Cheng | 1cd3327 | 2008-09-16 23:12:11 +0000 | [diff] [blame] | 104 |   } else if (UseRC) { | 
 | 105 |     assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!"); | 
 | 106 |     DstRC = UseRC; | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 107 |   } else { | 
| Evan Cheng | 1cd3327 | 2008-09-16 23:12:11 +0000 | [diff] [blame] | 108 |     DstRC = TLI->getRegClassFor(VT); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 109 |   } | 
 | 110 |      | 
 | 111 |   // If all uses are reading from the src physical register and copying the | 
 | 112 |   // register is either impossible or very expensive, then don't create a copy. | 
 | 113 |   if (MatchReg && SrcRC->getCopyCost() < 0) { | 
 | 114 |     VRBase = SrcReg; | 
 | 115 |   } else { | 
 | 116 |     // Create the reg, emit the copy. | 
 | 117 |     VRBase = MRI.createVirtualRegister(DstRC); | 
| Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 118 |     bool Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg, | 
 | 119 |                                      DstRC, SrcRC); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 120 |  | 
 | 121 |     assert(Emitted && "Unable to issue a copy instruction!\n"); | 
| Daniel Dunbar | 8c562e2 | 2009-05-18 16:43:04 +0000 | [diff] [blame] | 122 |     (void) Emitted; | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 123 |   } | 
 | 124 |  | 
 | 125 |   SDValue Op(Node, ResNo); | 
 | 126 |   if (IsClone) | 
 | 127 |     VRBaseMap.erase(Op); | 
 | 128 |   bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; | 
 | 129 |   isNew = isNew; // Silence compiler warning. | 
 | 130 |   assert(isNew && "Node emitted out of order - early"); | 
 | 131 | } | 
 | 132 |  | 
 | 133 | /// getDstOfCopyToRegUse - If the only use of the specified result number of | 
 | 134 | /// node is a CopyToReg, return its destination register. Return 0 otherwise. | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 135 | unsigned ScheduleDAGSDNodes::getDstOfOnlyCopyToRegUse(SDNode *Node, | 
 | 136 |                                                       unsigned ResNo) const { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 137 |   if (!Node->hasOneUse()) | 
 | 138 |     return 0; | 
 | 139 |  | 
 | 140 |   SDNode *User = *Node->use_begin(); | 
 | 141 |   if (User->getOpcode() == ISD::CopyToReg &&  | 
 | 142 |       User->getOperand(2).getNode() == Node && | 
 | 143 |       User->getOperand(2).getResNo() == ResNo) { | 
 | 144 |     unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg(); | 
 | 145 |     if (TargetRegisterInfo::isVirtualRegister(Reg)) | 
 | 146 |       return Reg; | 
 | 147 |   } | 
 | 148 |   return 0; | 
 | 149 | } | 
 | 150 |  | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 151 | void ScheduleDAGSDNodes::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 152 |                                        const TargetInstrDesc &II, | 
 | 153 |                                        bool IsClone, bool IsCloned, | 
| Evan Cheng | 5c3c5a4 | 2009-01-09 22:44:02 +0000 | [diff] [blame] | 154 |                                        DenseMap<SDValue, unsigned> &VRBaseMap) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 155 |   assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF && | 
 | 156 |          "IMPLICIT_DEF should have been handled as a special case elsewhere!"); | 
 | 157 |  | 
 | 158 |   for (unsigned i = 0; i < II.getNumDefs(); ++i) { | 
 | 159 |     // If the specific node value is only used by a CopyToReg and the dest reg | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 160 |     // is a vreg in the same register class, use the CopyToReg'd destination | 
 | 161 |     // register instead of creating a new vreg. | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 162 |     unsigned VRBase = 0; | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 163 |     const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, II, i); | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 164 |  | 
 | 165 |     if (!IsClone && !IsCloned) | 
 | 166 |       for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); | 
 | 167 |            UI != E; ++UI) { | 
 | 168 |         SDNode *User = *UI; | 
 | 169 |         if (User->getOpcode() == ISD::CopyToReg &&  | 
 | 170 |             User->getOperand(2).getNode() == Node && | 
 | 171 |             User->getOperand(2).getResNo() == i) { | 
 | 172 |           unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg(); | 
 | 173 |           if (TargetRegisterInfo::isVirtualRegister(Reg)) { | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 174 |             const TargetRegisterClass *RegRC = MRI.getRegClass(Reg); | 
 | 175 |             if (RegRC == RC) { | 
 | 176 |               VRBase = Reg; | 
 | 177 |               MI->addOperand(MachineOperand::CreateReg(Reg, true)); | 
 | 178 |               break; | 
 | 179 |             } | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 180 |           } | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 181 |         } | 
 | 182 |       } | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 183 |  | 
 | 184 |     // Create the result registers for this node and add the result regs to | 
 | 185 |     // the machine instruction. | 
 | 186 |     if (VRBase == 0) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 187 |       assert(RC && "Isn't a register operand!"); | 
 | 188 |       VRBase = MRI.createVirtualRegister(RC); | 
 | 189 |       MI->addOperand(MachineOperand::CreateReg(VRBase, true)); | 
 | 190 |     } | 
 | 191 |  | 
 | 192 |     SDValue Op(Node, i); | 
| Evan Cheng | 5c3c5a4 | 2009-01-09 22:44:02 +0000 | [diff] [blame] | 193 |     if (IsClone) | 
 | 194 |       VRBaseMap.erase(Op); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 195 |     bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; | 
 | 196 |     isNew = isNew; // Silence compiler warning. | 
 | 197 |     assert(isNew && "Node emitted out of order - early"); | 
 | 198 |   } | 
 | 199 | } | 
 | 200 |  | 
 | 201 | /// getVR - Return the virtual register corresponding to the specified result | 
 | 202 | /// of the specified node. | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 203 | unsigned ScheduleDAGSDNodes::getVR(SDValue Op, | 
 | 204 |                                    DenseMap<SDValue, unsigned> &VRBaseMap) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 205 |   if (Op.isMachineOpcode() && | 
 | 206 |       Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) { | 
 | 207 |     // Add an IMPLICIT_DEF instruction before every use. | 
 | 208 |     unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo()); | 
 | 209 |     // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc | 
 | 210 |     // does not include operand register class info. | 
 | 211 |     if (!VReg) { | 
 | 212 |       const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType()); | 
 | 213 |       VReg = MRI.createVirtualRegister(RC); | 
 | 214 |     } | 
| Bill Wendling | f2ad58d | 2009-02-03 01:02:39 +0000 | [diff] [blame] | 215 |     BuildMI(BB, Op.getDebugLoc(), TII->get(TargetInstrInfo::IMPLICIT_DEF),VReg); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 216 |     return VReg; | 
 | 217 |   } | 
 | 218 |  | 
 | 219 |   DenseMap<SDValue, unsigned>::iterator I = VRBaseMap.find(Op); | 
 | 220 |   assert(I != VRBaseMap.end() && "Node emitted out of order - late"); | 
 | 221 |   return I->second; | 
 | 222 | } | 
 | 223 |  | 
 | 224 |  | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 225 | /// AddRegisterOperand - Add the specified register as an operand to the | 
 | 226 | /// specified machine instr. Insert register copies if the register is | 
 | 227 | /// not in the required register class. | 
 | 228 | void | 
 | 229 | ScheduleDAGSDNodes::AddRegisterOperand(MachineInstr *MI, SDValue Op, | 
 | 230 |                                        unsigned IIOpNum, | 
 | 231 |                                        const TargetInstrDesc *II, | 
 | 232 |                                        DenseMap<SDValue, unsigned> &VRBaseMap) { | 
 | 233 |   assert(Op.getValueType() != MVT::Other && | 
 | 234 |          Op.getValueType() != MVT::Flag && | 
 | 235 |          "Chain and flag operands should occur at end of operand list!"); | 
 | 236 |   // Get/emit the operand. | 
 | 237 |   unsigned VReg = getVR(Op, VRBaseMap); | 
 | 238 |   assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); | 
 | 239 |  | 
 | 240 |   const TargetInstrDesc &TID = MI->getDesc(); | 
 | 241 |   bool isOptDef = IIOpNum < TID.getNumOperands() && | 
 | 242 |     TID.OpInfo[IIOpNum].isOptionalDef(); | 
 | 243 |  | 
 | 244 |   // If the instruction requires a register in a different class, create | 
 | 245 |   // a new virtual register and copy the value into it. | 
 | 246 |   if (II) { | 
 | 247 |     const TargetRegisterClass *SrcRC = | 
 | 248 |       MRI.getRegClass(VReg); | 
 | 249 |     const TargetRegisterClass *DstRC = | 
 | 250 |       getInstrOperandRegClass(TRI, *II, IIOpNum); | 
 | 251 |     assert((DstRC || (TID.isVariadic() && IIOpNum >= TID.getNumOperands())) && | 
 | 252 |            "Don't have operand info for this instruction!"); | 
 | 253 |     if (DstRC && SrcRC != DstRC && !SrcRC->hasSuperClass(DstRC)) { | 
 | 254 |       unsigned NewVReg = MRI.createVirtualRegister(DstRC); | 
 | 255 |       bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg, | 
 | 256 |                                        DstRC, SrcRC); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 257 |       assert(Emitted && "Unable to issue a copy instruction!\n"); | 
| Daniel Dunbar | 8c562e2 | 2009-05-18 16:43:04 +0000 | [diff] [blame] | 258 |       (void) Emitted; | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 259 |       VReg = NewVReg; | 
 | 260 |     } | 
 | 261 |   } | 
 | 262 |  | 
 | 263 |   MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef)); | 
 | 264 | } | 
 | 265 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 266 | /// AddOperand - Add the specified operand to the specified machine instr.  II | 
 | 267 | /// specifies the instruction information for the node, and IIOpNum is the | 
 | 268 | /// operand number (in the II) that we are adding. IIOpNum and II are used for  | 
 | 269 | /// assertions only. | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 270 | void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op, | 
 | 271 |                                     unsigned IIOpNum, | 
 | 272 |                                     const TargetInstrDesc *II, | 
 | 273 |                                     DenseMap<SDValue, unsigned> &VRBaseMap) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 274 |   if (Op.isMachineOpcode()) { | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 275 |     AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 276 |   } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) { | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 277 |     MI->addOperand(MachineOperand::CreateImm(C->getZExtValue())); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 278 |   } else if (ConstantFPSDNode *F = dyn_cast<ConstantFPSDNode>(Op)) { | 
| Dan Gohman | 4fbd796 | 2008-09-12 18:08:03 +0000 | [diff] [blame] | 279 |     const ConstantFP *CFP = F->getConstantFPValue(); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 280 |     MI->addOperand(MachineOperand::CreateFPImm(CFP)); | 
 | 281 |   } else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) { | 
| Dale Johannesen | 86b49f8 | 2008-09-24 01:07:17 +0000 | [diff] [blame] | 282 |     MI->addOperand(MachineOperand::CreateReg(R->getReg(), false)); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 283 |   } else if (GlobalAddressSDNode *TGA = dyn_cast<GlobalAddressSDNode>(Op)) { | 
 | 284 |     MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(),TGA->getOffset())); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 285 |   } else if (BasicBlockSDNode *BBNode = dyn_cast<BasicBlockSDNode>(Op)) { | 
 | 286 |     MI->addOperand(MachineOperand::CreateMBB(BBNode->getBasicBlock())); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 287 |   } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) { | 
 | 288 |     MI->addOperand(MachineOperand::CreateFI(FI->getIndex())); | 
 | 289 |   } else if (JumpTableSDNode *JT = dyn_cast<JumpTableSDNode>(Op)) { | 
 | 290 |     MI->addOperand(MachineOperand::CreateJTI(JT->getIndex())); | 
 | 291 |   } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) { | 
 | 292 |     int Offset = CP->getOffset(); | 
 | 293 |     unsigned Align = CP->getAlignment(); | 
 | 294 |     const Type *Type = CP->getType(); | 
 | 295 |     // MachineConstantPool wants an explicit alignment. | 
 | 296 |     if (Align == 0) { | 
| Evan Cheng | 1606e8e | 2009-03-13 07:51:59 +0000 | [diff] [blame] | 297 |       Align = TM.getTargetData()->getPrefTypeAlignment(Type); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 298 |       if (Align == 0) { | 
 | 299 |         // Alignment of vector types.  FIXME! | 
| Duncan Sands | 777d230 | 2009-05-09 07:06:46 +0000 | [diff] [blame] | 300 |         Align = TM.getTargetData()->getTypeAllocSize(Type); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 301 |       } | 
 | 302 |     } | 
 | 303 |      | 
 | 304 |     unsigned Idx; | 
 | 305 |     if (CP->isMachineConstantPoolEntry()) | 
 | 306 |       Idx = ConstPool->getConstantPoolIndex(CP->getMachineCPVal(), Align); | 
 | 307 |     else | 
 | 308 |       Idx = ConstPool->getConstantPoolIndex(CP->getConstVal(), Align); | 
 | 309 |     MI->addOperand(MachineOperand::CreateCPI(Idx, Offset)); | 
| Bill Wendling | 056292f | 2008-09-16 21:48:12 +0000 | [diff] [blame] | 310 |   } else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 311 |     MI->addOperand(MachineOperand::CreateES(ES->getSymbol())); | 
 | 312 |   } else { | 
 | 313 |     assert(Op.getValueType() != MVT::Other && | 
 | 314 |            Op.getValueType() != MVT::Flag && | 
 | 315 |            "Chain and flag operands should occur at end of operand list!"); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 316 |     AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap); | 
 | 317 |   } | 
 | 318 | } | 
 | 319 |  | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 320 | /// getSuperRegisterRegClass - Returns the register class of a superreg A whose | 
 | 321 | /// "SubIdx"'th sub-register class is the specified register class and whose | 
 | 322 | /// type matches the specified type. | 
 | 323 | static const TargetRegisterClass* | 
 | 324 | getSuperRegisterRegClass(const TargetRegisterClass *TRC, | 
 | 325 |                          unsigned SubIdx, MVT VT) { | 
 | 326 |   // Pick the register class of the superegister for this type | 
 | 327 |   for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(), | 
 | 328 |          E = TRC->superregclasses_end(); I != E; ++I) | 
| Jakob Stoklund Olesen | fa4677b | 2009-04-28 16:34:09 +0000 | [diff] [blame] | 329 |     if ((*I)->hasType(VT) && (*I)->getSubRegisterRegClass(SubIdx) == TRC) | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 330 |       return *I; | 
 | 331 |   assert(false && "Couldn't find the register class"); | 
 | 332 |   return 0; | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 333 | } | 
 | 334 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 335 | /// EmitSubregNode - Generate machine code for subreg nodes. | 
 | 336 | /// | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 337 | void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node,  | 
 | 338 |                                         DenseMap<SDValue, unsigned> &VRBaseMap) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 339 |   unsigned VRBase = 0; | 
 | 340 |   unsigned Opc = Node->getMachineOpcode(); | 
 | 341 |    | 
 | 342 |   // If the node is only used by a CopyToReg and the dest reg is a vreg, use | 
 | 343 |   // the CopyToReg'd destination register instead of creating a new vreg. | 
 | 344 |   for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); | 
 | 345 |        UI != E; ++UI) { | 
 | 346 |     SDNode *User = *UI; | 
 | 347 |     if (User->getOpcode() == ISD::CopyToReg &&  | 
 | 348 |         User->getOperand(2).getNode() == Node) { | 
 | 349 |       unsigned DestReg = cast<RegisterSDNode>(User->getOperand(1))->getReg(); | 
 | 350 |       if (TargetRegisterInfo::isVirtualRegister(DestReg)) { | 
 | 351 |         VRBase = DestReg; | 
 | 352 |         break; | 
 | 353 |       } | 
 | 354 |     } | 
 | 355 |   } | 
 | 356 |    | 
 | 357 |   if (Opc == TargetInstrInfo::EXTRACT_SUBREG) { | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 358 |     unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 359 |  | 
 | 360 |     // Create the extract_subreg machine instruction. | 
| Bill Wendling | f2ad58d | 2009-02-03 01:02:39 +0000 | [diff] [blame] | 361 |     MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), | 
 | 362 |                                TII->get(TargetInstrInfo::EXTRACT_SUBREG)); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 363 |  | 
 | 364 |     // Figure out the register class to create for the destreg. | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 365 |     unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); | 
 | 366 |     const TargetRegisterClass *TRC = MRI.getRegClass(VReg); | 
| Jakob Stoklund Olesen | fa4677b | 2009-04-28 16:34:09 +0000 | [diff] [blame] | 367 |     const TargetRegisterClass *SRC = TRC->getSubRegisterRegClass(SubIdx); | 
 | 368 |     assert(SRC && "Invalid subregister index in EXTRACT_SUBREG"); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 369 |  | 
| Dan Gohman | 5ec3b42 | 2009-04-14 22:17:14 +0000 | [diff] [blame] | 370 |     // Figure out the register class to create for the destreg. | 
 | 371 |     // Note that if we're going to directly use an existing register, | 
 | 372 |     // it must be precisely the required class, and not a subclass | 
 | 373 |     // thereof. | 
 | 374 |     if (VRBase == 0 || SRC != MRI.getRegClass(VRBase)) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 375 |       // Create the reg | 
 | 376 |       assert(SRC && "Couldn't find source register class"); | 
 | 377 |       VRBase = MRI.createVirtualRegister(SRC); | 
 | 378 |     } | 
| Dan Gohman | 5ec3b42 | 2009-04-14 22:17:14 +0000 | [diff] [blame] | 379 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 380 |     // Add def, source, and subreg index | 
 | 381 |     MI->addOperand(MachineOperand::CreateReg(VRBase, true)); | 
 | 382 |     AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap); | 
 | 383 |     MI->addOperand(MachineOperand::CreateImm(SubIdx)); | 
| Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 384 |     BB->insert(InsertPos, MI); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 385 |   } else if (Opc == TargetInstrInfo::INSERT_SUBREG || | 
 | 386 |              Opc == TargetInstrInfo::SUBREG_TO_REG) { | 
 | 387 |     SDValue N0 = Node->getOperand(0); | 
 | 388 |     SDValue N1 = Node->getOperand(1); | 
 | 389 |     SDValue N2 = Node->getOperand(2); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 390 |     unsigned SubReg = getVR(N1, VRBaseMap); | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 391 |     unsigned SubIdx = cast<ConstantSDNode>(N2)->getZExtValue(); | 
| Dan Gohman | 5ec3b42 | 2009-04-14 22:17:14 +0000 | [diff] [blame] | 392 |     const TargetRegisterClass *TRC = MRI.getRegClass(SubReg); | 
 | 393 |     const TargetRegisterClass *SRC = | 
 | 394 |       getSuperRegisterRegClass(TRC, SubIdx, | 
 | 395 |                                Node->getValueType(0)); | 
 | 396 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 397 |     // Figure out the register class to create for the destreg. | 
| Dan Gohman | 5ec3b42 | 2009-04-14 22:17:14 +0000 | [diff] [blame] | 398 |     // Note that if we're going to directly use an existing register, | 
 | 399 |     // it must be precisely the required class, and not a subclass | 
 | 400 |     // thereof. | 
 | 401 |     if (VRBase == 0 || SRC != MRI.getRegClass(VRBase)) { | 
 | 402 |       // Create the reg | 
 | 403 |       assert(SRC && "Couldn't find source register class"); | 
 | 404 |       VRBase = MRI.createVirtualRegister(SRC); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 405 |     } | 
| Dan Gohman | 5ec3b42 | 2009-04-14 22:17:14 +0000 | [diff] [blame] | 406 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 407 |     // Create the insert_subreg or subreg_to_reg machine instruction. | 
| Bill Wendling | f2ad58d | 2009-02-03 01:02:39 +0000 | [diff] [blame] | 408 |     MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), TII->get(Opc)); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 409 |     MI->addOperand(MachineOperand::CreateReg(VRBase, true)); | 
 | 410 |      | 
 | 411 |     // If creating a subreg_to_reg, then the first input operand | 
 | 412 |     // is an implicit value immediate, otherwise it's a register | 
 | 413 |     if (Opc == TargetInstrInfo::SUBREG_TO_REG) { | 
 | 414 |       const ConstantSDNode *SD = cast<ConstantSDNode>(N0); | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 415 |       MI->addOperand(MachineOperand::CreateImm(SD->getZExtValue())); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 416 |     } else | 
 | 417 |       AddOperand(MI, N0, 0, 0, VRBaseMap); | 
 | 418 |     // Add the subregster being inserted | 
 | 419 |     AddOperand(MI, N1, 0, 0, VRBaseMap); | 
 | 420 |     MI->addOperand(MachineOperand::CreateImm(SubIdx)); | 
| Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 421 |     BB->insert(InsertPos, MI); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 422 |   } else | 
 | 423 |     assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg"); | 
 | 424 |       | 
 | 425 |   SDValue Op(Node, 0); | 
 | 426 |   bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; | 
 | 427 |   isNew = isNew; // Silence compiler warning. | 
 | 428 |   assert(isNew && "Node emitted out of order - early"); | 
 | 429 | } | 
 | 430 |  | 
| Dan Gohman | 88c7af0 | 2009-04-13 21:06:25 +0000 | [diff] [blame] | 431 | /// EmitCopyToRegClassNode - Generate machine code for COPY_TO_REGCLASS nodes. | 
 | 432 | /// COPY_TO_REGCLASS is just a normal copy, except that the destination | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 433 | /// register is constrained to be in a particular register class. | 
 | 434 | /// | 
 | 435 | void | 
| Dan Gohman | 88c7af0 | 2009-04-13 21:06:25 +0000 | [diff] [blame] | 436 | ScheduleDAGSDNodes::EmitCopyToRegClassNode(SDNode *Node, | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 437 |                                        DenseMap<SDValue, unsigned> &VRBaseMap) { | 
 | 438 |   unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); | 
 | 439 |   const TargetRegisterClass *SrcRC = MRI.getRegClass(VReg); | 
 | 440 |  | 
 | 441 |   unsigned DstRCIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); | 
 | 442 |   const TargetRegisterClass *DstRC = TRI->getRegClass(DstRCIdx); | 
 | 443 |  | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 444 |   // Create the new VReg in the destination class and emit a copy. | 
 | 445 |   unsigned NewVReg = MRI.createVirtualRegister(DstRC); | 
 | 446 |   bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg, | 
 | 447 |                                    DstRC, SrcRC); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 448 |   assert(Emitted && | 
| Dan Gohman | 88c7af0 | 2009-04-13 21:06:25 +0000 | [diff] [blame] | 449 |          "Unable to issue a copy instruction for a COPY_TO_REGCLASS node!\n"); | 
| Daniel Dunbar | 8c562e2 | 2009-05-18 16:43:04 +0000 | [diff] [blame] | 450 |   (void) Emitted; | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 451 |  | 
 | 452 |   SDValue Op(Node, 0); | 
 | 453 |   bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).second; | 
 | 454 |   isNew = isNew; // Silence compiler warning. | 
 | 455 |   assert(isNew && "Node emitted out of order - early"); | 
 | 456 | } | 
 | 457 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 458 | /// EmitNode - Generate machine code for an node and needed dependencies. | 
 | 459 | /// | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 460 | void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 461 |                                   DenseMap<SDValue, unsigned> &VRBaseMap) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 462 |   // If machine instruction | 
 | 463 |   if (Node->isMachineOpcode()) { | 
 | 464 |     unsigned Opc = Node->getMachineOpcode(); | 
 | 465 |      | 
 | 466 |     // Handle subreg insert/extract specially | 
 | 467 |     if (Opc == TargetInstrInfo::EXTRACT_SUBREG ||  | 
 | 468 |         Opc == TargetInstrInfo::INSERT_SUBREG || | 
 | 469 |         Opc == TargetInstrInfo::SUBREG_TO_REG) { | 
 | 470 |       EmitSubregNode(Node, VRBaseMap); | 
 | 471 |       return; | 
 | 472 |     } | 
 | 473 |  | 
| Dan Gohman | 88c7af0 | 2009-04-13 21:06:25 +0000 | [diff] [blame] | 474 |     // Handle COPY_TO_REGCLASS specially. | 
 | 475 |     if (Opc == TargetInstrInfo::COPY_TO_REGCLASS) { | 
 | 476 |       EmitCopyToRegClassNode(Node, VRBaseMap); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 477 |       return; | 
 | 478 |     } | 
 | 479 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 480 |     if (Opc == TargetInstrInfo::IMPLICIT_DEF) | 
 | 481 |       // We want a unique VR for each IMPLICIT_DEF use. | 
 | 482 |       return; | 
 | 483 |      | 
 | 484 |     const TargetInstrDesc &II = TII->get(Opc); | 
 | 485 |     unsigned NumResults = CountResults(Node); | 
 | 486 |     unsigned NodeOperands = CountOperands(Node); | 
 | 487 |     unsigned MemOperandsEnd = ComputeMemOperandsEnd(Node); | 
 | 488 |     bool HasPhysRegOuts = (NumResults > II.getNumDefs()) && | 
 | 489 |                           II.getImplicitDefs() != 0; | 
 | 490 | #ifndef NDEBUG | 
 | 491 |     unsigned NumMIOperands = NodeOperands + NumResults; | 
 | 492 |     assert((II.getNumOperands() == NumMIOperands || | 
 | 493 |             HasPhysRegOuts || II.isVariadic()) && | 
 | 494 |            "#operands for dag node doesn't match .td file!");  | 
 | 495 | #endif | 
 | 496 |  | 
 | 497 |     // Create the new machine instruction. | 
| Bill Wendling | f2ad58d | 2009-02-03 01:02:39 +0000 | [diff] [blame] | 498 |     MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), II); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 499 |      | 
 | 500 |     // Add result register values for things that are defined by this | 
 | 501 |     // instruction. | 
 | 502 |     if (NumResults) | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 503 |       CreateVirtualRegisters(Node, MI, II, IsClone, IsCloned, VRBaseMap); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 504 |      | 
 | 505 |     // Emit all of the actual operands of this instruction, adding them to the | 
 | 506 |     // instruction as appropriate. | 
 | 507 |     for (unsigned i = 0; i != NodeOperands; ++i) | 
 | 508 |       AddOperand(MI, Node->getOperand(i), i+II.getNumDefs(), &II, VRBaseMap); | 
 | 509 |  | 
 | 510 |     // Emit all of the memory operands of this instruction | 
 | 511 |     for (unsigned i = NodeOperands; i != MemOperandsEnd; ++i) | 
 | 512 |       AddMemOperand(MI, cast<MemOperandSDNode>(Node->getOperand(i))->MO); | 
 | 513 |  | 
| Dan Gohman | f711939 | 2009-01-16 22:10:20 +0000 | [diff] [blame] | 514 |     if (II.usesCustomDAGSchedInsertionHook()) { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 515 |       // Insert this instruction into the basic block using a target | 
 | 516 |       // specific inserter which may returns a new basic block. | 
 | 517 |       BB = TLI->EmitInstrWithCustomInserter(MI, BB); | 
| Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 518 |       InsertPos = BB->end(); | 
| Bill Wendling | f2ad58d | 2009-02-03 01:02:39 +0000 | [diff] [blame] | 519 |     } else { | 
| Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 520 |       BB->insert(InsertPos, MI); | 
| Bill Wendling | f2ad58d | 2009-02-03 01:02:39 +0000 | [diff] [blame] | 521 |     } | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 522 |  | 
 | 523 |     // Additional results must be an physical register def. | 
 | 524 |     if (HasPhysRegOuts) { | 
 | 525 |       for (unsigned i = II.getNumDefs(); i < NumResults; ++i) { | 
 | 526 |         unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()]; | 
 | 527 |         if (Node->hasAnyUseOfValue(i)) | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 528 |           EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 529 |       } | 
 | 530 |     } | 
 | 531 |     return; | 
 | 532 |   } | 
 | 533 |  | 
 | 534 |   switch (Node->getOpcode()) { | 
 | 535 |   default: | 
 | 536 | #ifndef NDEBUG | 
| Dan Gohman | a23b3b8 | 2008-11-13 21:21:28 +0000 | [diff] [blame] | 537 |     Node->dump(DAG); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 538 | #endif | 
 | 539 |     assert(0 && "This target-independent node should have been selected!"); | 
 | 540 |     break; | 
 | 541 |   case ISD::EntryToken: | 
 | 542 |     assert(0 && "EntryToken should have been excluded from the schedule!"); | 
 | 543 |     break; | 
 | 544 |   case ISD::TokenFactor: // fall thru | 
 | 545 |     break; | 
 | 546 |   case ISD::CopyToReg: { | 
 | 547 |     unsigned SrcReg; | 
 | 548 |     SDValue SrcVal = Node->getOperand(2); | 
 | 549 |     if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(SrcVal)) | 
 | 550 |       SrcReg = R->getReg(); | 
 | 551 |     else | 
 | 552 |       SrcReg = getVR(SrcVal, VRBaseMap); | 
 | 553 |        | 
 | 554 |     unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg(); | 
 | 555 |     if (SrcReg == DestReg) // Coalesced away the copy? Ignore. | 
 | 556 |       break; | 
 | 557 |        | 
 | 558 |     const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0; | 
 | 559 |     // Get the register classes of the src/dst. | 
 | 560 |     if (TargetRegisterInfo::isVirtualRegister(SrcReg)) | 
 | 561 |       SrcTRC = MRI.getRegClass(SrcReg); | 
 | 562 |     else | 
 | 563 |       SrcTRC = TRI->getPhysicalRegisterRegClass(SrcReg,SrcVal.getValueType()); | 
 | 564 |  | 
 | 565 |     if (TargetRegisterInfo::isVirtualRegister(DestReg)) | 
 | 566 |       DstTRC = MRI.getRegClass(DestReg); | 
 | 567 |     else | 
 | 568 |       DstTRC = TRI->getPhysicalRegisterRegClass(DestReg, | 
 | 569 |                                             Node->getOperand(1).getValueType()); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 570 |  | 
| Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 571 |     bool Emitted = TII->copyRegToReg(*BB, InsertPos, DestReg, SrcReg, | 
 | 572 |                                      DstTRC, SrcTRC); | 
| Dan Gohman | f8c7394 | 2009-04-13 15:38:05 +0000 | [diff] [blame] | 573 |     assert(Emitted && "Unable to issue a copy instruction!\n"); | 
| Daniel Dunbar | 8c562e2 | 2009-05-18 16:43:04 +0000 | [diff] [blame] | 574 |     (void) Emitted; | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 575 |     break; | 
 | 576 |   } | 
 | 577 |   case ISD::CopyFromReg: { | 
 | 578 |     unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg(); | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 579 |     EmitCopyFromReg(Node, 0, IsClone, IsCloned, SrcReg, VRBaseMap); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 580 |     break; | 
 | 581 |   } | 
 | 582 |   case ISD::INLINEASM: { | 
 | 583 |     unsigned NumOps = Node->getNumOperands(); | 
 | 584 |     if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag) | 
 | 585 |       --NumOps;  // Ignore the flag operand. | 
 | 586 |        | 
 | 587 |     // Create the inline asm machine instruction. | 
| Bill Wendling | f2ad58d | 2009-02-03 01:02:39 +0000 | [diff] [blame] | 588 |     MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), | 
 | 589 |                                TII->get(TargetInstrInfo::INLINEASM)); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 590 |  | 
 | 591 |     // Add the asm string as an external symbol operand. | 
| Bill Wendling | 056292f | 2008-09-16 21:48:12 +0000 | [diff] [blame] | 592 |     const char *AsmStr = | 
 | 593 |       cast<ExternalSymbolSDNode>(Node->getOperand(1))->getSymbol(); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 594 |     MI->addOperand(MachineOperand::CreateES(AsmStr)); | 
 | 595 |        | 
 | 596 |     // Add all of the operand registers to the instruction. | 
 | 597 |     for (unsigned i = 2; i != NumOps;) { | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 598 |       unsigned Flags = | 
 | 599 |         cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue(); | 
| Evan Cheng | 697cbbf | 2009-03-20 18:03:34 +0000 | [diff] [blame] | 600 |       unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 601 |          | 
 | 602 |       MI->addOperand(MachineOperand::CreateImm(Flags)); | 
 | 603 |       ++i;  // Skip the ID value. | 
 | 604 |          | 
 | 605 |       switch (Flags & 7) { | 
 | 606 |       default: assert(0 && "Bad flags!"); | 
 | 607 |       case 2:   // Def of register. | 
 | 608 |         for (; NumVals; --NumVals, ++i) { | 
 | 609 |           unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg(); | 
 | 610 |           MI->addOperand(MachineOperand::CreateReg(Reg, true)); | 
 | 611 |         } | 
 | 612 |         break; | 
| Dale Johannesen | 913d3df | 2008-09-12 17:49:03 +0000 | [diff] [blame] | 613 |       case 6:   // Def of earlyclobber register. | 
 | 614 |         for (; NumVals; --NumVals, ++i) { | 
 | 615 |           unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg(); | 
 | 616 |           MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false,  | 
 | 617 |                                                    false, 0, true)); | 
 | 618 |         } | 
 | 619 |         break; | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 620 |       case 1:  // Use of register. | 
 | 621 |       case 3:  // Immediate. | 
 | 622 |       case 4:  // Addressing mode. | 
 | 623 |         // The addressing mode has been selected, just add all of the | 
 | 624 |         // operands to the machine instruction. | 
 | 625 |         for (; NumVals; --NumVals, ++i) | 
| Dale Johannesen | 86b49f8 | 2008-09-24 01:07:17 +0000 | [diff] [blame] | 626 |           AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 627 |         break; | 
 | 628 |       } | 
 | 629 |     } | 
| Dan Gohman | 47ac0f0 | 2009-02-11 04:27:20 +0000 | [diff] [blame] | 630 |     BB->insert(InsertPos, MI); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 631 |     break; | 
 | 632 |   } | 
 | 633 |   } | 
 | 634 | } | 
 | 635 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 636 | /// EmitSchedule - Emit the machine code in scheduled order. | 
| Dan Gohman | 343f0c0 | 2008-11-19 23:18:57 +0000 | [diff] [blame] | 637 | MachineBasicBlock *ScheduleDAGSDNodes::EmitSchedule() { | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 638 |   DenseMap<SDValue, unsigned> VRBaseMap; | 
 | 639 |   DenseMap<SUnit*, unsigned> CopyVRBaseMap; | 
 | 640 |   for (unsigned i = 0, e = Sequence.size(); i != e; i++) { | 
 | 641 |     SUnit *SU = Sequence[i]; | 
 | 642 |     if (!SU) { | 
 | 643 |       // Null SUnit* is a noop. | 
 | 644 |       EmitNoop(); | 
 | 645 |       continue; | 
 | 646 |     } | 
| Dan Gohman | f449bf3 | 2008-11-14 00:06:09 +0000 | [diff] [blame] | 647 |  | 
| Dan Gohman | f449bf3 | 2008-11-14 00:06:09 +0000 | [diff] [blame] | 648 |     // For pre-regalloc scheduling, create instructions corresponding to the | 
 | 649 |     // SDNode and any flagged SDNodes and append them to the block. | 
| Evan Cheng | c29a56d | 2009-01-12 03:19:55 +0000 | [diff] [blame] | 650 |     if (!SU->getNode()) { | 
 | 651 |       // Emit a copy. | 
 | 652 |       EmitPhysRegCopy(SU, CopyVRBaseMap); | 
 | 653 |       continue; | 
 | 654 |     } | 
 | 655 |  | 
| Dan Gohman | d23e0f8 | 2008-11-13 23:24:17 +0000 | [diff] [blame] | 656 |     SmallVector<SDNode *, 4> FlaggedNodes; | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 657 |     for (SDNode *N = SU->getNode()->getFlaggedNode(); N; | 
 | 658 |          N = N->getFlaggedNode()) | 
| Dan Gohman | d23e0f8 | 2008-11-13 23:24:17 +0000 | [diff] [blame] | 659 |       FlaggedNodes.push_back(N); | 
 | 660 |     while (!FlaggedNodes.empty()) { | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 661 |       EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, SU->isCloned,VRBaseMap); | 
| Dan Gohman | d23e0f8 | 2008-11-13 23:24:17 +0000 | [diff] [blame] | 662 |       FlaggedNodes.pop_back(); | 
 | 663 |     } | 
| Evan Cheng | e57187c | 2009-01-16 20:57:18 +0000 | [diff] [blame] | 664 |     EmitNode(SU->getNode(), SU->OrigNode != SU, SU->isCloned, VRBaseMap); | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 665 |   } | 
 | 666 |  | 
| Dan Gohman | 94b8d7e | 2008-09-03 16:01:59 +0000 | [diff] [blame] | 667 |   return BB; | 
 | 668 | } |