diff options
author | Chris Lattner <sabre@nondot.org> | 2005-10-30 18:54:27 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-10-30 18:54:27 +0000 |
commit | a4176525cc4018e781b48fd35d4000040841287f (patch) | |
tree | 4d3d877a16079a9c203eeb869f1ace8440b18e0e /lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | |
parent | c1d6f67e8ed2fc0616dc9a09e47dcf122ebdbbe5 (diff) |
Reduce the number of copies emitted as machine instructions by
generating results in vregs that will need them. In the case of something
like this: CopyToReg((add X, Y), reg1024), we no longer emit code like
this:
reg1025 = add X, Y
reg1024 = reg 1025
Instead, we emit:
reg1024 = add X, Y
Whoa! :)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24111 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/ScheduleDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 1c3fa587f7..c0c720ccc8 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -1006,7 +1006,28 @@ void SimpleSched::EmitNode(NodeInfo *NI) { // Add result register values for things that are defined by this // instruction. - if (NumResults) VRBase = CreateVirtualRegisters(MI, NumResults, II); + + // 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 (NumResults == 1) { + 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 Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg(); + if (MRegisterInfo::isVirtualRegister(Reg)) { + VRBase = Reg; + MI->addRegOperand(Reg, MachineOperand::Def); + break; + } + } + } + } + + // Otherwise, create new virtual registers. + if (NumResults && VRBase == 0) + VRBase = CreateVirtualRegisters(MI, NumResults, II); // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. @@ -1084,10 +1105,11 @@ void SimpleSched::EmitNode(NodeInfo *NI) { case ISD::TokenFactor: break; case ISD::CopyToReg: { - unsigned Val = getVR(Node->getOperand(2)); - MRI.copyRegToReg(*BB, BB->end(), - cast<RegisterSDNode>(Node->getOperand(1))->getReg(), Val, - RegMap->getRegClass(Val)); + unsigned InReg = getVR(Node->getOperand(2)); + unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg(); + if (InReg != DestReg) // Coallesced away the copy? + MRI.copyRegToReg(*BB, BB->end(), DestReg, InReg, + RegMap->getRegClass(InReg)); break; } case ISD::CopyFromReg: { @@ -1097,21 +1119,40 @@ void SimpleSched::EmitNode(NodeInfo *NI) { break; } + // 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; + } + } + } + // Figure out the register class to create for the destreg. const TargetRegisterClass *TRC = 0; + if (VRBase) { + TRC = RegMap->getRegClass(VRBase); + } else { - // Pick the register class of the right type that contains this physreg. - for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), - E = MRI.regclass_end(); I != E; ++I) - if ((*I)->getType() == Node->getValueType(0) && - (*I)->contains(SrcReg)) { - TRC = *I; - break; - } - assert(TRC && "Couldn't find register class for reg copy!"); + // Pick the register class of the right type that contains this physreg. + for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), + E = MRI.regclass_end(); I != E; ++I) + if ((*I)->getType() == Node->getValueType(0) && + (*I)->contains(SrcReg)) { + TRC = *I; + break; + } + assert(TRC && "Couldn't find register class for reg copy!"); - // Create the reg, emit the copy. - VRBase = RegMap->createVirtualRegister(TRC); + // Create the reg, emit the copy. + VRBase = RegMap->createVirtualRegister(TRC); + } MRI.copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC); break; } |