diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-09-26 21:36:17 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-09-26 21:36:17 +0000 |
commit | 42d60274eaa70f8cdbed76d04d25d7a8fc1237cb (patch) | |
tree | ffdc3ccf379243e9ac3249039ff5c14eabb83448 /lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | |
parent | 117acf9e36a0789d56b52525e031f575f80fe169 (diff) |
- Move getPhysicalRegisterRegClass() from ScheduleDAG to MRegisterInfo.
- Added ability to emit cross class register copies to the BBRU scheduler.
- More aggressive backtracking.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42375 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/ScheduleDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 70 |
1 files changed, 46 insertions, 24 deletions
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index a6e32b2bfa..6197b6fa0e 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -28,24 +28,6 @@ using namespace llvm; -/// getPhysicalRegisterRegClass - Returns the Register Class of a physical -/// register. -static const TargetRegisterClass *getPhysicalRegisterRegClass( - const MRegisterInfo *MRI, - MVT::ValueType VT, - unsigned reg) { - assert(MRegisterInfo::isPhysicalRegister(reg) && - "reg must be a physical register"); - // 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)->hasType(VT) && (*I)->contains(reg)) - return *I; - assert(false && "Couldn't find the register class"); - return 0; -} - - /// CheckForPhysRegDependency - Check if the dependency between def and use of /// a specified operand is a physical register dependency. If so, returns the /// register and the cost of copying the register. @@ -67,7 +49,7 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *Use, unsigned Op, II.ImplicitDefs[ResNo - II.numDefs] == Reg) { PhysReg = Reg; const TargetRegisterClass *RC = - getPhysicalRegisterRegClass(MRI, Def->getValueType(ResNo), Reg); + MRI->getPhysicalRegisterRegClass(Def->getValueType(ResNo), Reg); Cost = RC->getCopyCost(); } } @@ -356,7 +338,7 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, if (VRBase) TRC = RegMap->getRegClass(VRBase); else - TRC = getPhysicalRegisterRegClass(MRI, Node->getValueType(ResNo), SrcReg); + 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. @@ -766,8 +748,8 @@ void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo, if (MRegisterInfo::isVirtualRegister(InReg)) TRC = RegMap->getRegClass(InReg); else - TRC = getPhysicalRegisterRegClass(MRI, - Node->getOperand(2).getValueType(), + TRC = + MRI->getPhysicalRegisterRegClass(Node->getOperand(2).getValueType(), InReg); MRI->copyRegToReg(*BB, BB->end(), DestReg, InReg, TRC, TRC); } @@ -845,6 +827,39 @@ 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!"); + MRI->copyRegToReg(*BB, BB->end(), Reg, VRI->second, + SU->CopyDstRC, SU->CopySrcRC); + } else { + // Copy from physical register. + assert(I->Reg && "Unknown physical register!"); + unsigned VRBase = RegMap->createVirtualRegister(SU->CopyDstRC); + bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)); + assert(isNew && "Node emitted out of order - early"); + MRI->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 @@ -864,11 +879,15 @@ void ScheduleDAG::EmitSchedule() { // 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); - EmitNode(SU->Node, SU->InstanceNo, VRBaseMap); + if (SU->Node) + EmitNode(SU->Node, SU->InstanceNo, VRBaseMap); + else + EmitCrossRCCopy(SU, CopyVRBaseMap); } else { // Null SUnit* is a noop. EmitNoop(); @@ -903,7 +922,10 @@ MachineBasicBlock *ScheduleDAG::Run() { /// a group of nodes flagged together. void SUnit::dump(const SelectionDAG *G) const { cerr << "SU(" << NodeNum << "): "; - Node->dump(G); + if (Node) + Node->dump(G); + else + cerr << "CROSS RC COPY "; cerr << "\n"; if (FlaggedNodes.size() != 0) { for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) { |