-static const TargetRegisterClass *getInstrOperandRegClass(
- const MRegisterInfo *MRI,
- const TargetInstrInfo *TII,
- const TargetInstrDesc &II,
- unsigned Op) {
- if (Op >= II.getNumOperands()) {
- assert(II.isVariadic() && "Invalid operand # of instruction");
- return NULL;
- }
- if (II.OpInfo[Op].isLookupPtrRegClass())
- return TII->getPointerRegClass();
- return MRI->getRegClass(II.OpInfo[Op].RegClass);
-}
-
-void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
- unsigned InstanceNo, unsigned SrcReg,
- DenseMap<SDOperand, unsigned> &VRBaseMap) {
- unsigned VRBase = 0;
- if (MRegisterInfo::isVirtualRegister(SrcReg)) {
- // Just use the input register directly!
- if (InstanceNo > 0)
- VRBaseMap.erase(SDOperand(Node, ResNo));
- bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,ResNo),SrcReg));
- assert(isNew && "Node emitted out of order - early");
- return;
- }
-
- // If the node is only used by a CopyToReg and the dest reg is a vreg, use
- // the CopyToReg'd destination register instead of creating a new vreg.
- bool MatchReg = true;
- for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
- UI != E; ++UI) {
- SDNode *Use = *UI;
- bool Match = true;
- if (Use->getOpcode() == ISD::CopyToReg &&
- Use->getOperand(2).Val == Node &&
- Use->getOperand(2).ResNo == ResNo) {
- unsigned DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
- if (MRegisterInfo::isVirtualRegister(DestReg)) {
- VRBase = DestReg;
- Match = false;
- } else if (DestReg != SrcReg)
- Match = false;
- } else {
- for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {
- SDOperand Op = Use->getOperand(i);
- if (Op.Val != Node || Op.ResNo != ResNo)
- continue;
- MVT::ValueType VT = Node->getValueType(Op.ResNo);
- if (VT != MVT::Other && VT != MVT::Flag)
- Match = false;
- }
- }
- MatchReg &= Match;
- if (VRBase)
- break;
- }
-
- const TargetRegisterClass *TRC = 0;
- // Figure out the register class to create for the destreg.
- if (VRBase)
- TRC = RegInfo.getRegClass(VRBase);
- else
- TRC = MRI->getPhysicalRegisterRegClass(Node->getValueType(ResNo), SrcReg);
-
- // If all uses are reading from the src physical register and copying the
- // register is either impossible or very expensive, then don't create a copy.
- if (MatchReg && TRC->getCopyCost() < 0) {
- VRBase = SrcReg;
- } else {
- // Create the reg, emit the copy.
- VRBase = RegInfo.createVirtualRegister(TRC);
- TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC, TRC);
- }
-
- if (InstanceNo > 0)
- VRBaseMap.erase(SDOperand(Node, ResNo));
- bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,ResNo), VRBase));
- assert(isNew && "Node emitted out of order - early");
-}
-
-void ScheduleDAG::CreateVirtualRegisters(SDNode *Node,
- MachineInstr *MI,
- const TargetInstrDesc &II,
- DenseMap<SDOperand, unsigned> &VRBaseMap) {
- for (unsigned i = 0; i < II.getNumDefs(); ++i) {
- // If the specific node value is only used by a CopyToReg and the dest reg
- // is a vreg, use the CopyToReg'd destination register instead of creating
- // a new vreg.
- unsigned VRBase = 0;
- for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
- UI != E; ++UI) {
- SDNode *Use = *UI;
- if (Use->getOpcode() == ISD::CopyToReg &&
- Use->getOperand(2).Val == Node &&
- Use->getOperand(2).ResNo == i) {
- unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
- if (MRegisterInfo::isVirtualRegister(Reg)) {
- VRBase = Reg;
- MI->addOperand(MachineOperand::CreateReg(Reg, true));
- break;
- }
- }
- }
-
- // Create the result registers for this node and add the result regs to
- // the machine instruction.
- if (VRBase == 0) {
- const TargetRegisterClass *RC = getInstrOperandRegClass(MRI, TII, II, i);
- assert(RC && "Isn't a register operand!");
- VRBase = RegInfo.createVirtualRegister(RC);
- MI->addOperand(MachineOperand::CreateReg(VRBase, true));
- }
-
- bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,i), VRBase));
- assert(isNew && "Node emitted out of order - early");
- }
-}
-
-/// getVR - Return the virtual register corresponding to the specified result
-/// of the specified node.
-static unsigned getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap) {
- DenseMap<SDOperand, unsigned>::iterator I = VRBaseMap.find(Op);
- assert(I != VRBaseMap.end() && "Node emitted out of order - late");
- return I->second;
-}
-
-
-/// AddOperand - Add the specified operand to the specified machine instr. II
-/// specifies the instruction information for the node, and IIOpNum is the
-/// operand number (in the II) that we are adding. IIOpNum and II are used for
-/// assertions only.
-void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
- unsigned IIOpNum,
- const TargetInstrDesc *II,
- DenseMap<SDOperand, unsigned> &VRBaseMap) {
- if (Op.isTargetOpcode()) {
- // Note that this case is redundant with the final else block, but we
- // include it because it is the most common and it makes the logic
- // simpler here.
- assert(Op.getValueType() != MVT::Other &&
- Op.getValueType() != MVT::Flag &&
- "Chain and flag operands should occur at end of operand list!");
-
- // Get/emit the operand.
- unsigned VReg = getVR(Op, VRBaseMap);
- const TargetInstrDesc &TID = MI->getDesc();
- bool isOptDef = (IIOpNum < TID.getNumOperands())
- ? (TID.OpInfo[IIOpNum].isOptionalDef()) : false;
- MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef));
-
- // Verify that it is right.
- assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
- if (II) {
- const TargetRegisterClass *RC =
- getInstrOperandRegClass(MRI, TII, *II, IIOpNum);
- assert(RC && "Don't have operand info for this instruction!");
- const TargetRegisterClass *VRC = RegInfo.getRegClass(VReg);
- if (VRC != RC) {
- cerr << "Register class of operand and regclass of use don't agree!\n";
-#ifndef NDEBUG
- cerr << "Operand = " << IIOpNum << "\n";
- cerr << "Op->Val = "; Op.Val->dump(&DAG); cerr << "\n";
- cerr << "MI = "; MI->print(cerr);
- cerr << "VReg = " << VReg << "\n";
- cerr << "VReg RegClass size = " << VRC->getSize()
- << ", align = " << VRC->getAlignment() << "\n";
- cerr << "Expected RegClass size = " << RC->getSize()
- << ", align = " << RC->getAlignment() << "\n";
-#endif
- cerr << "Fatal error, aborting.\n";
- abort();
- }
- }
- } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateImm(C->getValue()));
- } else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateReg(R->getReg(), false));
- } else if (GlobalAddressSDNode *TGA = dyn_cast<GlobalAddressSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(),TGA->getOffset()));
- } else if (BasicBlockSDNode *BB = dyn_cast<BasicBlockSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateMBB(BB->getBasicBlock()));
- } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateFI(FI->getIndex()));
- } else if (JumpTableSDNode *JT = dyn_cast<JumpTableSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateJTI(JT->getIndex()));
- } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) {
- int Offset = CP->getOffset();
- unsigned Align = CP->getAlignment();
- const Type *Type = CP->getType();
- // MachineConstantPool wants an explicit alignment.
- if (Align == 0) {
- Align = TM.getTargetData()->getPreferredTypeAlignmentShift(Type);
- if (Align == 0) {
- // Alignment of vector types. FIXME!
- Align = TM.getTargetData()->getABITypeSize(Type);
- Align = Log2_64(Align);
- }
- }
-
- unsigned Idx;
- if (CP->isMachineConstantPoolEntry())
- Idx = ConstPool->getConstantPoolIndex(CP->getMachineCPVal(), Align);
- else
- Idx = ConstPool->getConstantPoolIndex(CP->getConstVal(), Align);
- MI->addOperand(MachineOperand::CreateCPI(Idx, Offset));
- } else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateES(ES->getSymbol()));
- } else {
- assert(Op.getValueType() != MVT::Other &&
- Op.getValueType() != MVT::Flag &&
- "Chain and flag operands should occur at end of operand list!");
- unsigned VReg = getVR(Op, VRBaseMap);
- MI->addOperand(MachineOperand::CreateReg(VReg, false));
-
- // Verify that it is right.
- assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
- if (II) {
- const TargetRegisterClass *RC =
- getInstrOperandRegClass(MRI, TII, *II, IIOpNum);
- assert(RC && "Don't have operand info for this instruction!");
- assert(RegInfo.getRegClass(VReg) == RC &&
- "Register class of operand and regclass of use don't agree!");
- }
- }
-
-}
-
-// Returns the Register Class of a subregister
-static const TargetRegisterClass *getSubRegisterRegClass(
- const TargetRegisterClass *TRC,
- unsigned SubIdx) {
- // Pick the register class of the subregister
- MRegisterInfo::regclass_iterator I = TRC->subregclasses_begin() + SubIdx-1;
- assert(I < TRC->subregclasses_end() &&
- "Invalid subregister index for register class");
- return *I;
-}
-
-static const TargetRegisterClass *getSuperregRegisterClass(
- const TargetRegisterClass *TRC,
- unsigned SubIdx,
- MVT::ValueType VT) {
- // Pick the register class of the superegister for this type
- for (MRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(),
- E = TRC->superregclasses_end(); I != E; ++I)
- if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC)
- return *I;
- assert(false && "Couldn't find the register class");
- return 0;
-}
-
-/// EmitSubregNode - Generate machine code for subreg nodes.
-///
-void ScheduleDAG::EmitSubregNode(SDNode *Node,
- DenseMap<SDOperand, unsigned> &VRBaseMap) {
- unsigned VRBase = 0;
- unsigned Opc = Node->getTargetOpcode();
- if (Opc == TargetInstrInfo::EXTRACT_SUBREG) {
- // If the node is only used by a CopyToReg and the dest reg is a vreg, use
- // the CopyToReg'd destination register instead of creating a new vreg.
- for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
- UI != E; ++UI) {
- SDNode *Use = *UI;
- if (Use->getOpcode() == ISD::CopyToReg &&
- Use->getOperand(2).Val == Node) {
- unsigned DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
- if (MRegisterInfo::isVirtualRegister(DestReg)) {
- VRBase = DestReg;
- break;
- }
- }
- }
-
- unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getValue();
-
- // TODO: If the node is a use of a CopyFromReg from a physical register
- // fold the extract into the copy now
-
- // Create the extract_subreg machine instruction.
- MachineInstr *MI =
- new MachineInstr(BB, TII->get(TargetInstrInfo::EXTRACT_SUBREG));
-
- // Figure out the register class to create for the destreg.
- unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
- const TargetRegisterClass *TRC = RegInfo.getRegClass(VReg);
- const TargetRegisterClass *SRC = getSubRegisterRegClass(TRC, SubIdx);
-
- if (VRBase) {
- // Grab the destination register
- const TargetRegisterClass *DRC = 0;
- DRC = RegInfo.getRegClass(VRBase);
- assert(SRC == DRC &&
- "Source subregister and destination must have the same class");
- } else {
- // Create the reg
- VRBase = RegInfo.createVirtualRegister(SRC);
- }
-
- // Add def, source, and subreg index
- MI->addOperand(MachineOperand::CreateReg(VRBase, true));
- AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
- MI->addOperand(MachineOperand::CreateImm(SubIdx));
-
- } else if (Opc == TargetInstrInfo::INSERT_SUBREG) {
- assert((Node->getNumOperands() == 2 || Node->getNumOperands() == 3) &&
- "Malformed insert_subreg node");
- bool isUndefInput = (Node->getNumOperands() == 2);
- unsigned SubReg = 0;
- unsigned SubIdx = 0;
-
- if (isUndefInput) {
- SubReg = getVR(Node->getOperand(0), VRBaseMap);
- SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getValue();
- } else {
- SubReg = getVR(Node->getOperand(1), VRBaseMap);
- SubIdx = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
- }
-
- // TODO: Add tracking info to MachineRegisterInfo of which vregs are subregs
- // to allow coalescing in the allocator
-
- // If the node is only used by a CopyToReg and the dest reg is a vreg, use
- // the CopyToReg'd destination register instead of creating a new vreg.
- // If the CopyToReg'd destination register is physical, then fold the
- // insert into the copy
- for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
- UI != E; ++UI) {
- SDNode *Use = *UI;
- if (Use->getOpcode() == ISD::CopyToReg &&
- Use->getOperand(2).Val == Node) {
- unsigned DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
- if (MRegisterInfo::isVirtualRegister(DestReg)) {
- VRBase = DestReg;
- break;
- }
- }
- }
-
- // Create the insert_subreg machine instruction.
- MachineInstr *MI =
- new MachineInstr(BB, TII->get(TargetInstrInfo::INSERT_SUBREG));
-
- // Figure out the register class to create for the destreg.
- const TargetRegisterClass *TRC = 0;
- if (VRBase) {
- TRC = RegInfo.getRegClass(VRBase);
- } else {
- TRC = getSuperregRegisterClass(RegInfo.getRegClass(SubReg), SubIdx,
- Node->getValueType(0));
- assert(TRC && "Couldn't determine register class for insert_subreg");
- VRBase = RegInfo.createVirtualRegister(TRC); // Create the reg
- }
-
- MI->addOperand(MachineOperand::CreateReg(VRBase, true));
- AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
- if (!isUndefInput)
- AddOperand(MI, Node->getOperand(1), 0, 0, VRBaseMap);
- MI->addOperand(MachineOperand::CreateImm(SubIdx));
- } else
- assert(0 && "Node is not a subreg insert or extract");
-
- bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,0), VRBase));
- assert(isNew && "Node emitted out of order - early");
-}
-
-/// EmitNode - Generate machine code for an node and needed dependencies.
-///
-void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo,
- DenseMap<SDOperand, unsigned> &VRBaseMap) {
- // If machine instruction
- if (Node->isTargetOpcode()) {
- unsigned Opc = Node->getTargetOpcode();
-
- // Handle subreg insert/extract specially
- if (Opc == TargetInstrInfo::EXTRACT_SUBREG ||
- Opc == TargetInstrInfo::INSERT_SUBREG) {
- EmitSubregNode(Node, VRBaseMap);
- return;
- }
-
- const TargetInstrDesc &II = TII->get(Opc);
-
- unsigned NumResults = CountResults(Node);
- unsigned NodeOperands = CountOperands(Node);
- unsigned NumMIOperands = NodeOperands + NumResults;
- bool HasPhysRegOuts = (NumResults > II.getNumDefs()) &&
- II.getImplicitDefs() != 0;
-#ifndef NDEBUG
- assert((II.getNumOperands() == NumMIOperands ||
- HasPhysRegOuts || II.isVariadic()) &&
- "#operands for dag node doesn't match .td file!");
-#endif
-
- // Create the new machine instruction.
- MachineInstr *MI = new MachineInstr(II);
-
- // Add result register values for things that are defined by this
- // instruction.
- if (NumResults)
- CreateVirtualRegisters(Node, MI, II, VRBaseMap);
-
- // Emit all of the actual operands of this instruction, adding them to the
- // instruction as appropriate.
- for (unsigned i = 0; i != NodeOperands; ++i)
- AddOperand(MI, Node->getOperand(i), i+II.getNumDefs(), &II, VRBaseMap);
-
- // Commute node if it has been determined to be profitable.
- if (CommuteSet.count(Node)) {
- MachineInstr *NewMI = TII->commuteInstruction(MI);
- if (NewMI == 0)
- DOUT << "Sched: COMMUTING FAILED!\n";
- else {
- DOUT << "Sched: COMMUTED TO: " << *NewMI;
- if (MI != NewMI) {
- delete MI;
- MI = NewMI;
- }
- }
- }
-
- // Now that we have emitted all operands, emit this instruction itself.
- if (Opc == TargetInstrInfo::LABEL &&
- !BB->empty() && &MF->front() == BB) {
- // If we are inserting a LABEL and this happens to be the first label in
- // the entry block, it is the "function start" label. Make sure there are
- // no other instructions before it.
- bool SeenLabel = false;
- MachineBasicBlock::iterator MBBI = BB->begin();
- while (MBBI != BB->end()) {
- if (MBBI->getOpcode() == TargetInstrInfo::LABEL) {
- SeenLabel = true;
- break;
- }
- ++MBBI;
- }
- if (!SeenLabel)
- BB->insert(BB->begin(), MI);
- else
- BB->push_back(MI);
- } else if (II.usesCustomDAGSchedInsertionHook())
- // Insert this instruction into the basic block using a target
- // specific inserter which may returns a new basic block.
- BB = DAG.getTargetLoweringInfo().EmitInstrWithCustomInserter(MI, BB);
- else
- BB->push_back(MI);
-
- // Additional results must be an physical register def.
- if (HasPhysRegOuts) {
- for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {
- unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()];
- if (Node->hasAnyUseOfValue(i))
- EmitCopyFromReg(Node, i, InstanceNo, Reg, VRBaseMap);
- }
- }
- } else {
- switch (Node->getOpcode()) {
- default:
-#ifndef NDEBUG
- Node->dump(&DAG);
-#endif
- assert(0 && "This target-independent node should have been selected!");
- case ISD::EntryToken: // fall thru
- case ISD::TokenFactor:
- case ISD::LABEL:
- break;
- case ISD::CopyToReg: {
- unsigned InReg;
- if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node->getOperand(2)))
- InReg = R->getReg();
- else
- InReg = getVR(Node->getOperand(2), VRBaseMap);
- unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
- if (InReg != DestReg) {// Coalesced away the copy?
- const TargetRegisterClass *TRC = 0;
- // Get the target register class
- if (MRegisterInfo::isVirtualRegister(InReg))
- TRC = RegInfo.getRegClass(InReg);
- else
- TRC =
- MRI->getPhysicalRegisterRegClass(Node->getOperand(2).getValueType(),
- InReg);
- TII->copyRegToReg(*BB, BB->end(), DestReg, InReg, TRC, TRC);
- }
- break;
- }
- case ISD::CopyFromReg: {
- unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
- EmitCopyFromReg(Node, 0, InstanceNo, SrcReg, VRBaseMap);
- break;
- }
- case ISD::INLINEASM: {
- unsigned NumOps = Node->getNumOperands();
- if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag)
- --NumOps; // Ignore the flag operand.
-
- // Create the inline asm machine instruction.
- MachineInstr *MI =
- new MachineInstr(BB, TII->get(TargetInstrInfo::INLINEASM));
-
- // Add the asm string as an external symbol operand.
- const char *AsmStr =
- cast<ExternalSymbolSDNode>(Node->getOperand(1))->getSymbol();
- MI->addOperand(MachineOperand::CreateES(AsmStr));
-
- // Add all of the operand registers to the instruction.
- for (unsigned i = 2; i != NumOps;) {
- unsigned Flags = cast<ConstantSDNode>(Node->getOperand(i))->getValue();
- unsigned NumVals = Flags >> 3;
-
- MI->addOperand(MachineOperand::CreateImm(Flags));
- ++i; // Skip the ID value.
-
- switch (Flags & 7) {
- default: assert(0 && "Bad flags!");
- case 1: // Use of register.
- for (; NumVals; --NumVals, ++i) {
- unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
- MI->addOperand(MachineOperand::CreateReg(Reg, false));
- }
- break;
- case 2: // Def of register.
- for (; NumVals; --NumVals, ++i) {
- unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
- MI->addOperand(MachineOperand::CreateReg(Reg, true));
- }
- break;
- case 3: { // Immediate.
- for (; NumVals; --NumVals, ++i) {
- if (ConstantSDNode *CS =
- dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
- MI->addOperand(MachineOperand::CreateImm(CS->getValue()));
- } else if (GlobalAddressSDNode *GA =
- dyn_cast<GlobalAddressSDNode>(Node->getOperand(i))) {
- MI->addOperand(MachineOperand::CreateGA(GA->getGlobal(),
- GA->getOffset()));
- } else {
- BasicBlockSDNode *BB =cast<BasicBlockSDNode>(Node->getOperand(i));
- MI->addOperand(MachineOperand::CreateMBB(BB->getBasicBlock()));
- }
- }
- break;
- }
- case 4: // Addressing mode.
- // The addressing mode has been selected, just add all of the
- // operands to the machine instruction.
- for (; NumVals; --NumVals, ++i)
- AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap);
- break;
- }
- }
- break;
- }
- }
- }
-}
-
-void ScheduleDAG::EmitNoop() {
- TII->insertNoop(*BB, BB->end());
-}
-
-void ScheduleDAG::EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap) {
- for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
- I != E; ++I) {
- if (I->isCtrl) continue; // ignore chain preds
- if (!I->Dep->Node) {
- // Copy to physical register.
- DenseMap<SUnit*, unsigned>::iterator VRI = VRBaseMap.find(I->Dep);
- assert(VRI != VRBaseMap.end() && "Node emitted out of order - late");
- // Find the destination physical register.
- unsigned Reg = 0;
- for (SUnit::const_succ_iterator II = SU->Succs.begin(),
- EE = SU->Succs.end(); II != EE; ++II) {
- if (I->Reg) {
- Reg = I->Reg;
- break;
- }
- }
- assert(I->Reg && "Unknown physical register!");
- TII->copyRegToReg(*BB, BB->end(), Reg, VRI->second,
- SU->CopyDstRC, SU->CopySrcRC);
- } else {
- // Copy from physical register.
- assert(I->Reg && "Unknown physical register!");
- unsigned VRBase = RegInfo.createVirtualRegister(SU->CopyDstRC);
- bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase));
- assert(isNew && "Node emitted out of order - early");
- TII->copyRegToReg(*BB, BB->end(), VRBase, I->Reg,
- SU->CopyDstRC, SU->CopySrcRC);
- }
- break;
- }
-}
-
-/// EmitSchedule - Emit the machine code in scheduled order.
-void ScheduleDAG::EmitSchedule() {
- // If this is the first basic block in the function, and if it has live ins
- // that need to be copied into vregs, emit the copies into the top of the
- // block before emitting the code for the block.
- if (&MF->front() == BB) {
- for (MachineRegisterInfo::livein_iterator LI = RegInfo.livein_begin(),
- E = RegInfo.livein_end(); LI != E; ++LI)
- if (LI->second) {
- const TargetRegisterClass *RC = RegInfo.getRegClass(LI->second);
- TII->copyRegToReg(*MF->begin(), MF->begin()->end(), LI->second,
- LI->first, RC, RC);
- }
- }
-
-
- // Finally, emit the code for all of the scheduled instructions.
- DenseMap<SDOperand, unsigned> VRBaseMap;
- DenseMap<SUnit*, unsigned> CopyVRBaseMap;
- for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
- if (SUnit *SU = Sequence[i]) {
- for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; ++j)
- EmitNode(SU->FlaggedNodes[j], SU->InstanceNo, VRBaseMap);
- if (SU->Node)
- EmitNode(SU->Node, SU->InstanceNo, VRBaseMap);
- else
- EmitCrossRCCopy(SU, CopyVRBaseMap);
- } else {
- // Null SUnit* is a noop.
- EmitNoop();
- }
- }
-}