- Update register allocation hint after coalescing. This is done by the target since the hint is target dependent. This is important for ARM register pair hints.

- Register allocator should resolve the second part of the hint (register number) before passing it to the target since it knows virtual register to physical register mapping.
- More fixes to get ARM load / store double word working.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73671 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2009-06-18 02:04:01 +00:00
parent 063989455d
commit f9f1da17f8
6 changed files with 172 additions and 87 deletions

View File

@ -523,7 +523,7 @@ public:
/// register class in the form of a pair of TargetRegisterClass iterators. /// register class in the form of a pair of TargetRegisterClass iterators.
virtual std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator> virtual std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
getAllocationOrder(const TargetRegisterClass *RC, getAllocationOrder(const TargetRegisterClass *RC,
std::pair<unsigned,unsigned> Hint, unsigned HintType, unsigned HintReg,
const MachineFunction &MF) const { const MachineFunction &MF) const {
return std::make_pair(RC->allocation_order_begin(MF), return std::make_pair(RC->allocation_order_begin(MF),
RC->allocation_order_end(MF)); RC->allocation_order_end(MF));
@ -531,13 +531,24 @@ public:
/// ResolveRegAllocHint - Resolves the specified register allocation hint /// ResolveRegAllocHint - Resolves the specified register allocation hint
/// to a physical register. Returns the physical register if it is successful. /// to a physical register. Returns the physical register if it is successful.
unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg, virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
const MachineFunction &MF) const { const MachineFunction &MF) const {
if (Type == 0 && Reg && isPhysicalRegister(Reg)) if (Type == 0 && Reg && isPhysicalRegister(Reg))
return Reg; return Reg;
return 0; return 0;
} }
/// UpdateRegAllocHint - A callback to allow target a chance to update
/// register allocation hints when a register is "changed" (e.g. coalesced)
/// to another register. e.g. On ARM, some virtual registers should target
/// register pairs, if one of pair is coalesced to another register, the
/// allocation hint of the other half of the pair should be changed to point
/// to the new register.
virtual void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
MachineFunction &MF) const {
// Do nothing.
}
/// targetHandlesStackFrameRounding - Returns true if the target is /// targetHandlesStackFrameRounding - Returns true if the target is
/// responsible for rounding up the stack frame (probably at emitPrologue /// responsible for rounding up the stack frame (probably at emitPrologue
/// time). /// time).

View File

@ -1356,9 +1356,15 @@ unsigned RALinScan::getFreePhysReg(LiveInterval* cur,
unsigned FreeReg = 0; unsigned FreeReg = 0;
unsigned FreeRegInactiveCount = 0; unsigned FreeRegInactiveCount = 0;
std::pair<unsigned, unsigned> Hint = mri_->getRegAllocationHint(cur->reg);
// Resolve second part of the hint (if possible) given the current allocation.
unsigned physReg = Hint.second;
if (physReg &&
TargetRegisterInfo::isVirtualRegister(physReg) && vrm_->hasPhys(physReg))
physReg = vrm_->getPhys(physReg);
TargetRegisterClass::iterator I, E; TargetRegisterClass::iterator I, E;
tie(I, E) = tri_->getAllocationOrder(RC, tie(I, E) = tri_->getAllocationOrder(RC, Hint.first, physReg, *mf_);
mri_->getRegAllocationHint(cur->reg), *mf_);
assert(I != E && "No allocatable register in this register class!"); assert(I != E && "No allocatable register in this register class!");
// Scan for the first available register. // Scan for the first available register.

View File

@ -1766,6 +1766,9 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// being merged. // being merged.
li_->removeInterval(SrcReg); li_->removeInterval(SrcReg);
// Update regalloc hint.
tri_->UpdateRegAllocHint(SrcReg, DstReg, *mf_);
// Manually deleted the live interval copy. // Manually deleted the live interval copy.
if (SavedLI) { if (SavedLI) {
SavedLI->clear(); SavedLI->clear();

View File

@ -41,6 +41,12 @@ STATISTIC(NumSTMGened , "Number of stm instructions generated");
STATISTIC(NumFLDMGened, "Number of fldm instructions generated"); STATISTIC(NumFLDMGened, "Number of fldm instructions generated");
STATISTIC(NumFSTMGened, "Number of fstm instructions generated"); STATISTIC(NumFSTMGened, "Number of fstm instructions generated");
STATISTIC(NumLdStMoved, "Number of load / store instructions moved"); STATISTIC(NumLdStMoved, "Number of load / store instructions moved");
STATISTIC(NumLDRDFormed,"Number of ldrd created before allocation");
STATISTIC(NumSTRDFormed,"Number of strd created before allocation");
STATISTIC(NumLDRD2LDM, "Number of ldrd instructions turned back into ldm");
STATISTIC(NumSTRD2STM, "Number of strd instructions turned back into stm");
STATISTIC(NumLDRD2LDR, "Number of ldrd instructions turned back into ldr's");
STATISTIC(NumSTRD2STR, "Number of strd instructions turned back into str's");
/// ARMAllocLoadStoreOpt - Post- register allocation pass the combine /// ARMAllocLoadStoreOpt - Post- register allocation pass the combine
/// load / store instructions to form ldm / stm instructions. /// load / store instructions to form ldm / stm instructions.
@ -651,9 +657,9 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
if ((EvenRegNum & 1) == 0 && (EvenRegNum + 1) == OddRegNum) if ((EvenRegNum & 1) == 0 && (EvenRegNum + 1) == OddRegNum)
return false; return false;
bool isDef = Opcode == ARM::LDRD; bool isLd = Opcode == ARM::LDRD;
bool EvenKill = isDef ? false : MI->getOperand(0).isKill(); bool EvenKill = isLd ? false : MI->getOperand(0).isKill();
bool OddKill = isDef ? false : MI->getOperand(1).isKill(); bool OddKill = isLd ? false : MI->getOperand(1).isKill();
const MachineOperand &BaseOp = MI->getOperand(2); const MachineOperand &BaseOp = MI->getOperand(2);
unsigned BaseReg = BaseOp.getReg(); unsigned BaseReg = BaseOp.getReg();
bool BaseKill = BaseOp.isKill(); bool BaseKill = BaseOp.isKill();
@ -668,34 +674,49 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
// Ascending register numbers and no offset. It's safe to change it to a // Ascending register numbers and no offset. It's safe to change it to a
// ldm or stm. // ldm or stm.
unsigned NewOpc = (Opcode == ARM::LDRD) ? ARM::LDM : ARM::STM; unsigned NewOpc = (Opcode == ARM::LDRD) ? ARM::LDM : ARM::STM;
BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc)) if (isLd) {
.addReg(BaseReg, getKillRegState(BaseKill)) BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc))
.addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)) .addReg(BaseReg, getKillRegState(BaseKill))
.addImm(Pred).addReg(PredReg) .addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia))
.addReg(EvenReg, getDefRegState(isDef)) .addImm(Pred).addReg(PredReg)
.addReg(OddReg, getDefRegState(isDef)); .addReg(EvenReg, getDefRegState(isLd))
.addReg(OddReg, getDefRegState(isLd));
++NumLDRD2LDM;
} else {
BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc))
.addReg(BaseReg, getKillRegState(BaseKill))
.addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia))
.addImm(Pred).addReg(PredReg)
.addReg(EvenReg, getKillRegState(EvenKill))
.addReg(OddReg, getKillRegState(OddKill));
++NumSTRD2STM;
}
} else { } else {
// Split into two instructions. // Split into two instructions.
unsigned NewOpc = (Opcode == ARM::LDRD) ? ARM::LDR : ARM::STR; unsigned NewOpc = (Opcode == ARM::LDRD) ? ARM::LDR : ARM::STR;
DebugLoc dl = MBBI->getDebugLoc(); DebugLoc dl = MBBI->getDebugLoc();
// If this is a load and base register is killed, it may have been // If this is a load and base register is killed, it may have been
// re-defed by the load, make sure the first load does not clobber it. // re-defed by the load, make sure the first load does not clobber it.
if (isDef && if (isLd &&
(BaseKill || OffKill) && (BaseKill || OffKill) &&
(TRI->regsOverlap(EvenReg, BaseReg) || (TRI->regsOverlap(EvenReg, BaseReg) ||
(OffReg && TRI->regsOverlap(EvenReg, OffReg)))) { (OffReg && TRI->regsOverlap(EvenReg, OffReg)))) {
assert(!TRI->regsOverlap(OddReg, BaseReg) && assert(!TRI->regsOverlap(OddReg, BaseReg) &&
(!OffReg || !TRI->regsOverlap(OddReg, OffReg))); (!OffReg || !TRI->regsOverlap(OddReg, OffReg)));
InsertLDR_STR(MBB, MBBI, OffImm+4, isDef, dl, NewOpc, OddReg, OddKill, InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc, OddReg, OddKill,
BaseReg, false, OffReg, false, Pred, PredReg, TII); BaseReg, false, OffReg, false, Pred, PredReg, TII);
InsertLDR_STR(MBB, MBBI, OffImm, isDef, dl, NewOpc, EvenReg, EvenKill, InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, EvenReg, EvenKill,
BaseReg, BaseKill, OffReg, OffKill, Pred, PredReg, TII); BaseReg, BaseKill, OffReg, OffKill, Pred, PredReg, TII);
} else { } else {
InsertLDR_STR(MBB, MBBI, OffImm, isDef, dl, NewOpc, EvenReg, EvenKill, InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, EvenReg, EvenKill,
BaseReg, false, OffReg, false, Pred, PredReg, TII); BaseReg, false, OffReg, false, Pred, PredReg, TII);
InsertLDR_STR(MBB, MBBI, OffImm+4, isDef, dl, NewOpc, OddReg, OddKill, InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc, OddReg, OddKill,
BaseReg, BaseKill, OffReg, OffKill, Pred, PredReg, TII); BaseReg, BaseKill, OffReg, OffKill, Pred, PredReg, TII);
} }
if (isLd)
++NumLDRD2LDR;
else
++NumSTRD2STR;
} }
MBBI = prior(MBBI); MBBI = prior(MBBI);
@ -1069,6 +1090,7 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,
MachineInstr *FirstOp = 0; MachineInstr *FirstOp = 0;
MachineInstr *LastOp = 0; MachineInstr *LastOp = 0;
int LastOffset = 0; int LastOffset = 0;
unsigned LastOpcode = 0;
unsigned LastBytes = 0; unsigned LastBytes = 0;
unsigned NumMove = 0; unsigned NumMove = 0;
for (int i = Ops.size() - 1; i >= 0; --i) { for (int i = Ops.size() - 1; i >= 0; --i) {
@ -1083,6 +1105,10 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,
LastOp = Op; LastOp = Op;
} }
unsigned Opcode = Op->getOpcode();
if (LastOpcode && Opcode != LastOpcode)
break;
int Offset = getMemoryOpOffset(Op); int Offset = getMemoryOpOffset(Op);
unsigned Bytes = getLSMultipleTransferSize(Op); unsigned Bytes = getLSMultipleTransferSize(Op);
if (LastBytes) { if (LastBytes) {
@ -1091,6 +1117,7 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,
} }
LastOffset = Offset; LastOffset = Offset;
LastBytes = Bytes; LastBytes = Bytes;
LastOpcode = Opcode;
if (++NumMove == 4) if (++NumMove == 4)
break; break;
} }
@ -1131,22 +1158,25 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB,
Offset, PredReg, Pred)) { Offset, PredReg, Pred)) {
Ops.pop_back(); Ops.pop_back();
Ops.pop_back(); Ops.pop_back();
MBB->erase(Op0);
MBB->erase(Op1);
// Form the pair instruction. // Form the pair instruction.
if (isLd) if (isLd) {
BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc)) BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc))
.addReg(EvenReg, RegState::Define) .addReg(EvenReg, RegState::Define)
.addReg(OddReg, RegState::Define) .addReg(OddReg, RegState::Define)
.addReg(BaseReg).addReg(0).addImm(Offset) .addReg(BaseReg).addReg(0).addImm(Offset)
.addImm(Pred).addReg(PredReg); .addImm(Pred).addReg(PredReg);
else ++NumLDRDFormed;
} else {
BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc)) BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc))
.addReg(EvenReg) .addReg(EvenReg)
.addReg(OddReg) .addReg(OddReg)
.addReg(BaseReg).addReg(0).addImm(Offset) .addReg(BaseReg).addReg(0).addImm(Offset)
.addImm(Pred).addReg(PredReg); .addImm(Pred).addReg(PredReg);
++NumSTRDFormed;
}
MBB->erase(Op0);
MBB->erase(Op1);
// Add register allocation hints to form register pairs. // Add register allocation hints to form register pairs.
MRI->setRegAllocationHint(EvenReg, ARMRI::RegPairEven, OddReg); MRI->setRegAllocationHint(EvenReg, ARMRI::RegPairEven, OddReg);

View File

@ -308,7 +308,7 @@ const TargetRegisterClass *ARMRegisterInfo::getPointerRegClass() const {
/// register class in the form of a pair of TargetRegisterClass iterators. /// register class in the form of a pair of TargetRegisterClass iterators.
std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator> std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC, ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
std::pair<unsigned, unsigned> Hint, unsigned HintType, unsigned HintReg,
const MachineFunction &MF) const { const MachineFunction &MF) const {
// Alternative register allocation orders when favoring even / odd registers // Alternative register allocation orders when favoring even / odd registers
// of register pairs. // of register pairs.
@ -384,7 +384,13 @@ ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
}; };
if (Hint.first == ARMRI::RegPairEven) { if (HintType == ARMRI::RegPairEven) {
if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
// It's no longer possible to fulfill this hint. Return the default
// allocation order.
return std::make_pair(RC->allocation_order_begin(MF),
RC->allocation_order_end(MF));
if (!STI.isTargetDarwin() && !hasFP(MF)) { if (!STI.isTargetDarwin() && !hasFP(MF)) {
if (!STI.isR9Reserved()) if (!STI.isR9Reserved())
return std::make_pair(GPREven1, return std::make_pair(GPREven1,
@ -407,7 +413,13 @@ ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
return std::make_pair(GPREven6, return std::make_pair(GPREven6,
GPREven6 + (sizeof(GPREven6)/sizeof(unsigned))); GPREven6 + (sizeof(GPREven6)/sizeof(unsigned)));
} }
} else if (Hint.first == ARMRI::RegPairOdd) { } else if (HintType == ARMRI::RegPairOdd) {
if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0)
// It's no longer possible to fulfill this hint. Return the default
// allocation order.
return std::make_pair(RC->allocation_order_begin(MF),
RC->allocation_order_end(MF));
if (!STI.isTargetDarwin() && !hasFP(MF)) { if (!STI.isTargetDarwin() && !hasFP(MF)) {
if (!STI.isR9Reserved()) if (!STI.isR9Reserved())
return std::make_pair(GPROdd1, return std::make_pair(GPROdd1,
@ -453,6 +465,26 @@ ARMRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
return 0; return 0;
} }
void
ARMRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
MachineFunction &MF) const {
MachineRegisterInfo *MRI = &MF.getRegInfo();
std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
Hint.first == (unsigned)ARMRI::RegPairEven) &&
Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) {
// If 'Reg' is one of the even / odd register pair and it's now changed
// (e.g. coalesced) into a different register. The other register of the
// pair allocation hint must be updated to reflect the relationship
// change.
unsigned OtherReg = Hint.second;
Hint = MRI->getRegAllocationHint(OtherReg);
if (Hint.second == Reg)
// Make sure the pair has not already divorced.
MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
}
}
bool bool
ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
@ -1680,68 +1712,68 @@ unsigned ARMRegisterInfo::getRegisterPairEven(unsigned Reg,
default: break; default: break;
// Return 0 if either register of the pair is a special register. // Return 0 if either register of the pair is a special register.
// So no R12, etc. // So no R12, etc.
case ARM::R0: case ARM::R1: case ARM::R1:
return ARM::R0; return ARM::R0;
case ARM::R2: case ARM::R3: case ARM::R3:
// FIXME! // FIXME!
return STI.isThumb() ? 0 : ARM::R2; return STI.isThumb() ? 0 : ARM::R2;
case ARM::R4: case ARM::R5: case ARM::R5:
return ARM::R4; return ARM::R4;
case ARM::R6: case ARM::R7: case ARM::R7:
return isReservedReg(MF, ARM::R7) ? 0 : ARM::R6; return isReservedReg(MF, ARM::R7) ? 0 : ARM::R6;
case ARM::R8: case ARM::R9: case ARM::R9:
return isReservedReg(MF, ARM::R9) ? 0 :ARM::R8; return isReservedReg(MF, ARM::R9) ? 0 :ARM::R8;
case ARM::R10: case ARM::R11: case ARM::R11:
return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10; return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
case ARM::S0: case ARM::S1: case ARM::S1:
return ARM::S0; return ARM::S0;
case ARM::S2: case ARM::S3: case ARM::S3:
return ARM::S2; return ARM::S2;
case ARM::S4: case ARM::S5: case ARM::S5:
return ARM::S4; return ARM::S4;
case ARM::S6: case ARM::S7: case ARM::S7:
return ARM::S6; return ARM::S6;
case ARM::S8: case ARM::S9: case ARM::S9:
return ARM::S8; return ARM::S8;
case ARM::S10: case ARM::S11: case ARM::S11:
return ARM::S10; return ARM::S10;
case ARM::S12: case ARM::S13: case ARM::S13:
return ARM::S12; return ARM::S12;
case ARM::S14: case ARM::S15: case ARM::S15:
return ARM::S14; return ARM::S14;
case ARM::S16: case ARM::S17: case ARM::S17:
return ARM::S16; return ARM::S16;
case ARM::S18: case ARM::S19: case ARM::S19:
return ARM::S18; return ARM::S18;
case ARM::S20: case ARM::S21: case ARM::S21:
return ARM::S20; return ARM::S20;
case ARM::S22: case ARM::S23: case ARM::S23:
return ARM::S22; return ARM::S22;
case ARM::S24: case ARM::S25: case ARM::S25:
return ARM::S24; return ARM::S24;
case ARM::S26: case ARM::S27: case ARM::S27:
return ARM::S26; return ARM::S26;
case ARM::S28: case ARM::S29: case ARM::S29:
return ARM::S28; return ARM::S28;
case ARM::S30: case ARM::S31: case ARM::S31:
return ARM::S30; return ARM::S30;
case ARM::D0: case ARM::D1: case ARM::D1:
return ARM::D0; return ARM::D0;
case ARM::D2: case ARM::D3: case ARM::D3:
return ARM::D2; return ARM::D2;
case ARM::D4: case ARM::D5: case ARM::D5:
return ARM::D4; return ARM::D4;
case ARM::D6: case ARM::D7: case ARM::D7:
return ARM::D6; return ARM::D6;
case ARM::D8: case ARM::D9: case ARM::D9:
return ARM::D8; return ARM::D8;
case ARM::D10: case ARM::D11: case ARM::D11:
return ARM::D10; return ARM::D10;
case ARM::D12: case ARM::D13: case ARM::D13:
return ARM::D12; return ARM::D12;
case ARM::D14: case ARM::D15: case ARM::D15:
return ARM::D14; return ARM::D14;
} }
@ -1754,68 +1786,68 @@ unsigned ARMRegisterInfo::getRegisterPairOdd(unsigned Reg,
default: break; default: break;
// Return 0 if either register of the pair is a special register. // Return 0 if either register of the pair is a special register.
// So no R12, etc. // So no R12, etc.
case ARM::R0: case ARM::R1: case ARM::R0:
return ARM::R1; return ARM::R1;
case ARM::R2: case ARM::R3: case ARM::R2:
// FIXME! // FIXME!
return STI.isThumb() ? 0 : ARM::R3; return STI.isThumb() ? 0 : ARM::R3;
case ARM::R4: case ARM::R5: case ARM::R4:
return ARM::R5; return ARM::R5;
case ARM::R6: case ARM::R7: case ARM::R6:
return isReservedReg(MF, ARM::R7) ? 0 : ARM::R7; return isReservedReg(MF, ARM::R7) ? 0 : ARM::R7;
case ARM::R8: case ARM::R9: case ARM::R8:
return isReservedReg(MF, ARM::R9) ? 0 :ARM::R9; return isReservedReg(MF, ARM::R9) ? 0 :ARM::R9;
case ARM::R10: case ARM::R11: case ARM::R10:
return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11; return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
case ARM::S0: case ARM::S1: case ARM::S0:
return ARM::S1; return ARM::S1;
case ARM::S2: case ARM::S3: case ARM::S2:
return ARM::S3; return ARM::S3;
case ARM::S4: case ARM::S5: case ARM::S4:
return ARM::S5; return ARM::S5;
case ARM::S6: case ARM::S7: case ARM::S6:
return ARM::S7; return ARM::S7;
case ARM::S8: case ARM::S9: case ARM::S8:
return ARM::S9; return ARM::S9;
case ARM::S10: case ARM::S11: case ARM::S10:
return ARM::S11; return ARM::S11;
case ARM::S12: case ARM::S13: case ARM::S12:
return ARM::S13; return ARM::S13;
case ARM::S14: case ARM::S15: case ARM::S14:
return ARM::S15; return ARM::S15;
case ARM::S16: case ARM::S17: case ARM::S16:
return ARM::S17; return ARM::S17;
case ARM::S18: case ARM::S19: case ARM::S18:
return ARM::S19; return ARM::S19;
case ARM::S20: case ARM::S21: case ARM::S20:
return ARM::S21; return ARM::S21;
case ARM::S22: case ARM::S23: case ARM::S22:
return ARM::S23; return ARM::S23;
case ARM::S24: case ARM::S25: case ARM::S24:
return ARM::S25; return ARM::S25;
case ARM::S26: case ARM::S27: case ARM::S26:
return ARM::S27; return ARM::S27;
case ARM::S28: case ARM::S29: case ARM::S28:
return ARM::S29; return ARM::S29;
case ARM::S30: case ARM::S31: case ARM::S30:
return ARM::S31; return ARM::S31;
case ARM::D0: case ARM::D1: case ARM::D0:
return ARM::D1; return ARM::D1;
case ARM::D2: case ARM::D3: case ARM::D2:
return ARM::D3; return ARM::D3;
case ARM::D4: case ARM::D5: case ARM::D4:
return ARM::D5; return ARM::D5;
case ARM::D6: case ARM::D7: case ARM::D6:
return ARM::D7; return ARM::D7;
case ARM::D8: case ARM::D9: case ARM::D8:
return ARM::D9; return ARM::D9;
case ARM::D10: case ARM::D11: case ARM::D10:
return ARM::D11; return ARM::D11;
case ARM::D12: case ARM::D13: case ARM::D12:
return ARM::D13; return ARM::D13;
case ARM::D14: case ARM::D15: case ARM::D14:
return ARM::D15; return ARM::D15;
} }

View File

@ -70,12 +70,15 @@ public:
std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator> std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
getAllocationOrder(const TargetRegisterClass *RC, getAllocationOrder(const TargetRegisterClass *RC,
std::pair<unsigned,unsigned> Hint, unsigned HintType, unsigned HintReg,
const MachineFunction &MF) const; const MachineFunction &MF) const;
unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg, unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
const MachineFunction &MF) const; const MachineFunction &MF) const;
void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
MachineFunction &MF) const;
bool requiresRegisterScavenging(const MachineFunction &MF) const; bool requiresRegisterScavenging(const MachineFunction &MF) const;
bool hasFP(const MachineFunction &MF) const; bool hasFP(const MachineFunction &MF) const;