diff options
Diffstat (limited to 'lib/CodeGen/SelectionDAG/ScheduleDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 273 |
1 files changed, 139 insertions, 134 deletions
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index de2c1bc90a..b5889fc677 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -224,26 +224,26 @@ void ScheduleDAG::ComputeLatency(SUnit *SU) { if (InstrItins.isEmpty()) { // No latency information. SU->Latency = 1; - } else { - SU->Latency = 0; - if (SU->Node->isTargetOpcode()) { - unsigned SchedClass = - TII->get(SU->Node->getTargetOpcode()).getSchedClass(); + return; + } + + SU->Latency = 0; + if (SU->Node->isTargetOpcode()) { + unsigned SchedClass = TII->get(SU->Node->getTargetOpcode()).getSchedClass(); + const InstrStage *S = InstrItins.begin(SchedClass); + const InstrStage *E = InstrItins.end(SchedClass); + for (; S != E; ++S) + SU->Latency += S->Cycles; + } + for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) { + SDNode *FNode = SU->FlaggedNodes[i]; + if (FNode->isTargetOpcode()) { + unsigned SchedClass = TII->get(FNode->getTargetOpcode()).getSchedClass(); const InstrStage *S = InstrItins.begin(SchedClass); const InstrStage *E = InstrItins.end(SchedClass); for (; S != E; ++S) SU->Latency += S->Cycles; } - for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) { - SDNode *FNode = SU->FlaggedNodes[i]; - if (FNode->isTargetOpcode()) { - unsigned SchedClass =TII->get(FNode->getTargetOpcode()).getSchedClass(); - const InstrStage *S = InstrItins.begin(SchedClass); - const InstrStage *E = InstrItins.end(SchedClass); - for (; S != E; ++S) - SU->Latency += S->Cycles; - } - } } } @@ -390,11 +390,12 @@ unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) { return N; } -static const TargetRegisterClass *getInstrOperandRegClass( - const TargetRegisterInfo *TRI, - const TargetInstrInfo *TII, - const TargetInstrDesc &II, - unsigned Op) { +/// getInstrOperandRegClass - Return register class of the operand of an +/// instruction of the specified TargetInstrDesc. +static const TargetRegisterClass* +getInstrOperandRegClass(const TargetRegisterInfo *TRI, + const TargetInstrInfo *TII, const TargetInstrDesc &II, + unsigned Op) { if (Op >= II.getNumOperands()) { assert(II.isVariadic() && "Invalid operand # of instruction"); return NULL; @@ -404,6 +405,8 @@ static const TargetRegisterClass *getInstrOperandRegClass( return TRI->getRegClass(II.OpInfo[Op].RegClass); } +/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an +/// implicit physical register output. void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, unsigned SrcReg, DenseMap<SDOperand, unsigned> &VRBaseMap) { @@ -660,18 +663,17 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, assert(getInstrOperandRegClass(TRI, TII, *II, IIOpNum) && "Don't have operand info for this instruction!"); } - } - + } } void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO) { MI->addMemOperand(MO); } -// Returns the Register Class of a subregister -static const TargetRegisterClass *getSubRegisterRegClass( - const TargetRegisterClass *TRC, - unsigned SubIdx) { +/// getSubRegisterRegClass - Returns the register class of specified register +/// class' "SubIdx"'th sub-register class. +static const TargetRegisterClass* +getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx) { // Pick the register class of the subregister TargetRegisterInfo::regclass_iterator I = TRC->subregclasses_begin() + SubIdx-1; @@ -680,10 +682,12 @@ static const TargetRegisterClass *getSubRegisterRegClass( return *I; } -static const TargetRegisterClass *getSuperregRegisterClass( - const TargetRegisterClass *TRC, - unsigned SubIdx, - MVT VT) { +/// getSuperRegisterRegClass - Returns the register class of a superreg A whose +/// "SubIdx"'th sub-register class is the specified register class and whose +/// type matches the specified type. +static const TargetRegisterClass* +getSuperRegisterRegClass(const TargetRegisterClass *TRC, + unsigned SubIdx, MVT VT) { // Pick the register class of the superegister for this type for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(), E = TRC->superregclasses_end(); I != E; ++I) @@ -758,7 +762,7 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node, if (VRBase) { TRC = MRI.getRegClass(VRBase); } else { - TRC = getSuperregRegisterClass(MRI.getRegClass(SubReg), SubIdx, + TRC = getSuperRegisterRegClass(MRI.getRegClass(SubReg), SubIdx, Node->getValueType(0)); assert(TRC && "Couldn't determine register class for insert_subreg"); VRBase = MRI.createVirtualRegister(TRC); // Create the reg @@ -867,124 +871,125 @@ void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone, EmitCopyFromReg(Node, i, IsClone, Reg, VRBaseMap); } } - } else { - switch (Node->getOpcode()) { - default: + return; + } + + switch (Node->getOpcode()) { + default: #ifndef NDEBUG - Node->dump(&DAG); + Node->dump(&DAG); #endif - assert(0 && "This target-independent node should have been selected!"); - break; - case ISD::EntryToken: - assert(0 && "EntryToken should have been excluded from the schedule!"); - break; - case ISD::TokenFactor: // fall thru - case ISD::DECLARE: - case ISD::SRCVALUE: - break; - case ISD::DBG_LABEL: - BB->push_back(BuildMI(TII->get(TargetInstrInfo::DBG_LABEL)) - .addImm(cast<LabelSDNode>(Node)->getLabelID())); - break; - case ISD::EH_LABEL: - BB->push_back(BuildMI(TII->get(TargetInstrInfo::EH_LABEL)) - .addImm(cast<LabelSDNode>(Node)->getLabelID())); - break; - case ISD::CopyToReg: { - unsigned SrcReg; - SDOperand SrcVal = Node->getOperand(2); - if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(SrcVal)) - SrcReg = R->getReg(); - else - SrcReg = getVR(SrcVal, VRBaseMap); + assert(0 && "This target-independent node should have been selected!"); + break; + case ISD::EntryToken: + assert(0 && "EntryToken should have been excluded from the schedule!"); + break; + case ISD::TokenFactor: // fall thru + case ISD::DECLARE: + case ISD::SRCVALUE: + break; + case ISD::DBG_LABEL: + BB->push_back(BuildMI(TII->get(TargetInstrInfo::DBG_LABEL)) + .addImm(cast<LabelSDNode>(Node)->getLabelID())); + break; + case ISD::EH_LABEL: + BB->push_back(BuildMI(TII->get(TargetInstrInfo::EH_LABEL)) + .addImm(cast<LabelSDNode>(Node)->getLabelID())); + break; + case ISD::CopyToReg: { + unsigned SrcReg; + SDOperand SrcVal = Node->getOperand(2); + if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(SrcVal)) + SrcReg = R->getReg(); + else + SrcReg = getVR(SrcVal, VRBaseMap); - unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg(); - if (SrcReg == DestReg) // Coalesced away the copy? Ignore. - break; + unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg(); + if (SrcReg == DestReg) // Coalesced away the copy? Ignore. + break; - const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0; - // Get the register classes of the src/dst. - if (TargetRegisterInfo::isVirtualRegister(SrcReg)) - SrcTRC = MRI.getRegClass(SrcReg); - else - SrcTRC = TRI->getPhysicalRegisterRegClass(SrcReg,SrcVal.getValueType()); + const TargetRegisterClass *SrcTRC = 0, *DstTRC = 0; + // Get the register classes of the src/dst. + if (TargetRegisterInfo::isVirtualRegister(SrcReg)) + SrcTRC = MRI.getRegClass(SrcReg); + else + SrcTRC = TRI->getPhysicalRegisterRegClass(SrcReg,SrcVal.getValueType()); - if (TargetRegisterInfo::isVirtualRegister(DestReg)) - DstTRC = MRI.getRegClass(DestReg); - else - DstTRC = TRI->getPhysicalRegisterRegClass(DestReg, + if (TargetRegisterInfo::isVirtualRegister(DestReg)) + DstTRC = MRI.getRegClass(DestReg); + else + DstTRC = TRI->getPhysicalRegisterRegClass(DestReg, Node->getOperand(1).getValueType()); - TII->copyRegToReg(*BB, BB->end(), DestReg, SrcReg, DstTRC, SrcTRC); - break; - } - case ISD::CopyFromReg: { - unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg(); - EmitCopyFromReg(Node, 0, IsClone, SrcReg, VRBaseMap); - break; - } - case ISD::INLINEASM: { - unsigned NumOps = Node->getNumOperands(); - if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag) - --NumOps; // Ignore the flag operand. + TII->copyRegToReg(*BB, BB->end(), DestReg, SrcReg, DstTRC, SrcTRC); + break; + } + case ISD::CopyFromReg: { + unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg(); + EmitCopyFromReg(Node, 0, IsClone, 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 = BuildMI(TII->get(TargetInstrInfo::INLINEASM)); + // Create the inline asm machine instruction. + MachineInstr *MI = BuildMI(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 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; + // 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. + 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; + 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)); } - 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; + 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; } - BB->push_back(MI); - break; - } } + BB->push_back(MI); + break; + } } } |