[llvm-commits] [llvm] r73671 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/RegAllocLinearScan.cpp lib/CodeGen/SimpleRegisterCoalescing.cpp lib/Target/ARM/ARMLoadStoreOptimizer.cpp lib/Target/ARM/ARMRegisterInfo.cpp lib/Target/ARM/ARMRegisterInfo.h
Evan Cheng
evan.cheng at apple.com
Wed Jun 17 19:04:01 PDT 2009
Author: evancheng
Date: Wed Jun 17 21:04:01 2009
New Revision: 73671
URL: http://llvm.org/viewvc/llvm-project?rev=73671&view=rev
Log:
- 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.
Modified:
llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp
llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h
Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=73671&r1=73670&r2=73671&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Wed Jun 17 21:04:01 2009
@@ -523,7 +523,7 @@
/// register class in the form of a pair of TargetRegisterClass iterators.
virtual std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
getAllocationOrder(const TargetRegisterClass *RC,
- std::pair<unsigned,unsigned> Hint,
+ unsigned HintType, unsigned HintReg,
const MachineFunction &MF) const {
return std::make_pair(RC->allocation_order_begin(MF),
RC->allocation_order_end(MF));
@@ -531,13 +531,24 @@
/// ResolveRegAllocHint - Resolves the specified register allocation hint
/// to a physical register. Returns the physical register if it is successful.
- unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
- const MachineFunction &MF) const {
+ virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
+ const MachineFunction &MF) const {
if (Type == 0 && Reg && isPhysicalRegister(Reg))
return Reg;
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
/// responsible for rounding up the stack frame (probably at emitPrologue
/// time).
Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=73671&r1=73670&r2=73671&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Wed Jun 17 21:04:01 2009
@@ -1356,9 +1356,15 @@
unsigned FreeReg = 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;
- tie(I, E) = tri_->getAllocationOrder(RC,
- mri_->getRegAllocationHint(cur->reg), *mf_);
+ tie(I, E) = tri_->getAllocationOrder(RC, Hint.first, physReg, *mf_);
assert(I != E && "No allocatable register in this register class!");
// Scan for the first available register.
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=73671&r1=73670&r2=73671&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Wed Jun 17 21:04:01 2009
@@ -1766,6 +1766,9 @@
// being merged.
li_->removeInterval(SrcReg);
+ // Update regalloc hint.
+ tri_->UpdateRegAllocHint(SrcReg, DstReg, *mf_);
+
// Manually deleted the live interval copy.
if (SavedLI) {
SavedLI->clear();
Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=73671&r1=73670&r2=73671&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Wed Jun 17 21:04:01 2009
@@ -41,6 +41,12 @@
STATISTIC(NumFLDMGened, "Number of fldm instructions generated");
STATISTIC(NumFSTMGened, "Number of fstm instructions generated");
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
/// load / store instructions to form ldm / stm instructions.
@@ -651,9 +657,9 @@
if ((EvenRegNum & 1) == 0 && (EvenRegNum + 1) == OddRegNum)
return false;
- bool isDef = Opcode == ARM::LDRD;
- bool EvenKill = isDef ? false : MI->getOperand(0).isKill();
- bool OddKill = isDef ? false : MI->getOperand(1).isKill();
+ bool isLd = Opcode == ARM::LDRD;
+ bool EvenKill = isLd ? false : MI->getOperand(0).isKill();
+ bool OddKill = isLd ? false : MI->getOperand(1).isKill();
const MachineOperand &BaseOp = MI->getOperand(2);
unsigned BaseReg = BaseOp.getReg();
bool BaseKill = BaseOp.isKill();
@@ -668,34 +674,49 @@
// Ascending register numbers and no offset. It's safe to change it to a
// ldm or stm.
unsigned NewOpc = (Opcode == ARM::LDRD) ? ARM::LDM : ARM::STM;
- 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, getDefRegState(isDef))
- .addReg(OddReg, getDefRegState(isDef));
+ if (isLd) {
+ 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, 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 {
// Split into two instructions.
unsigned NewOpc = (Opcode == ARM::LDRD) ? ARM::LDR : ARM::STR;
DebugLoc dl = MBBI->getDebugLoc();
// 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.
- if (isDef &&
+ if (isLd &&
(BaseKill || OffKill) &&
(TRI->regsOverlap(EvenReg, BaseReg) ||
(OffReg && TRI->regsOverlap(EvenReg, OffReg)))) {
assert(!TRI->regsOverlap(OddReg, BaseReg) &&
(!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);
- 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);
} 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);
- 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);
}
+ if (isLd)
+ ++NumLDRD2LDR;
+ else
+ ++NumSTRD2STR;
}
MBBI = prior(MBBI);
@@ -1069,6 +1090,7 @@
MachineInstr *FirstOp = 0;
MachineInstr *LastOp = 0;
int LastOffset = 0;
+ unsigned LastOpcode = 0;
unsigned LastBytes = 0;
unsigned NumMove = 0;
for (int i = Ops.size() - 1; i >= 0; --i) {
@@ -1083,6 +1105,10 @@
LastOp = Op;
}
+ unsigned Opcode = Op->getOpcode();
+ if (LastOpcode && Opcode != LastOpcode)
+ break;
+
int Offset = getMemoryOpOffset(Op);
unsigned Bytes = getLSMultipleTransferSize(Op);
if (LastBytes) {
@@ -1091,6 +1117,7 @@
}
LastOffset = Offset;
LastBytes = Bytes;
+ LastOpcode = Opcode;
if (++NumMove == 4)
break;
}
@@ -1131,22 +1158,25 @@
Offset, PredReg, Pred)) {
Ops.pop_back();
Ops.pop_back();
- MBB->erase(Op0);
- MBB->erase(Op1);
// Form the pair instruction.
- if (isLd)
+ if (isLd) {
BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc))
.addReg(EvenReg, RegState::Define)
.addReg(OddReg, RegState::Define)
.addReg(BaseReg).addReg(0).addImm(Offset)
.addImm(Pred).addReg(PredReg);
- else
+ ++NumLDRDFormed;
+ } else {
BuildMI(*MBB, InsertPos, dl, TII->get(NewOpc))
.addReg(EvenReg)
.addReg(OddReg)
.addReg(BaseReg).addReg(0).addImm(Offset)
.addImm(Pred).addReg(PredReg);
+ ++NumSTRDFormed;
+ }
+ MBB->erase(Op0);
+ MBB->erase(Op1);
// Add register allocation hints to form register pairs.
MRI->setRegAllocationHint(EvenReg, ARMRI::RegPairEven, OddReg);
Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=73671&r1=73670&r2=73671&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Wed Jun 17 21:04:01 2009
@@ -308,7 +308,7 @@
/// register class in the form of a pair of TargetRegisterClass iterators.
std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
- std::pair<unsigned, unsigned> Hint,
+ unsigned HintType, unsigned HintReg,
const MachineFunction &MF) const {
// Alternative register allocation orders when favoring even / odd registers
// of register pairs.
@@ -384,7 +384,13 @@
};
- 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.isR9Reserved())
return std::make_pair(GPREven1,
@@ -407,7 +413,13 @@
return std::make_pair(GPREven6,
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.isR9Reserved())
return std::make_pair(GPROdd1,
@@ -453,6 +465,26 @@
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
ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
@@ -1680,68 +1712,68 @@
default: break;
// Return 0 if either register of the pair is a special register.
// So no R12, etc.
- case ARM::R0: case ARM::R1:
+ case ARM::R1:
return ARM::R0;
- case ARM::R2: case ARM::R3:
+ case ARM::R3:
// FIXME!
return STI.isThumb() ? 0 : ARM::R2;
- case ARM::R4: case ARM::R5:
+ case ARM::R5:
return ARM::R4;
- case ARM::R6: case ARM::R7:
+ case ARM::R7:
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;
- case ARM::R10: case ARM::R11:
+ case ARM::R11:
return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
- case ARM::S0: case ARM::S1:
+ case ARM::S1:
return ARM::S0;
- case ARM::S2: case ARM::S3:
+ case ARM::S3:
return ARM::S2;
- case ARM::S4: case ARM::S5:
+ case ARM::S5:
return ARM::S4;
- case ARM::S6: case ARM::S7:
+ case ARM::S7:
return ARM::S6;
- case ARM::S8: case ARM::S9:
+ case ARM::S9:
return ARM::S8;
- case ARM::S10: case ARM::S11:
+ case ARM::S11:
return ARM::S10;
- case ARM::S12: case ARM::S13:
+ case ARM::S13:
return ARM::S12;
- case ARM::S14: case ARM::S15:
+ case ARM::S15:
return ARM::S14;
- case ARM::S16: case ARM::S17:
+ case ARM::S17:
return ARM::S16;
- case ARM::S18: case ARM::S19:
+ case ARM::S19:
return ARM::S18;
- case ARM::S20: case ARM::S21:
+ case ARM::S21:
return ARM::S20;
- case ARM::S22: case ARM::S23:
+ case ARM::S23:
return ARM::S22;
- case ARM::S24: case ARM::S25:
+ case ARM::S25:
return ARM::S24;
- case ARM::S26: case ARM::S27:
+ case ARM::S27:
return ARM::S26;
- case ARM::S28: case ARM::S29:
+ case ARM::S29:
return ARM::S28;
- case ARM::S30: case ARM::S31:
+ case ARM::S31:
return ARM::S30;
- case ARM::D0: case ARM::D1:
+ case ARM::D1:
return ARM::D0;
- case ARM::D2: case ARM::D3:
+ case ARM::D3:
return ARM::D2;
- case ARM::D4: case ARM::D5:
+ case ARM::D5:
return ARM::D4;
- case ARM::D6: case ARM::D7:
+ case ARM::D7:
return ARM::D6;
- case ARM::D8: case ARM::D9:
+ case ARM::D9:
return ARM::D8;
- case ARM::D10: case ARM::D11:
+ case ARM::D11:
return ARM::D10;
- case ARM::D12: case ARM::D13:
+ case ARM::D13:
return ARM::D12;
- case ARM::D14: case ARM::D15:
+ case ARM::D15:
return ARM::D14;
}
@@ -1754,68 +1786,68 @@
default: break;
// Return 0 if either register of the pair is a special register.
// So no R12, etc.
- case ARM::R0: case ARM::R1:
+ case ARM::R0:
return ARM::R1;
- case ARM::R2: case ARM::R3:
+ case ARM::R2:
// FIXME!
return STI.isThumb() ? 0 : ARM::R3;
- case ARM::R4: case ARM::R5:
+ case ARM::R4:
return ARM::R5;
- case ARM::R6: case ARM::R7:
+ case ARM::R6:
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;
- case ARM::R10: case ARM::R11:
+ case ARM::R10:
return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
- case ARM::S0: case ARM::S1:
+ case ARM::S0:
return ARM::S1;
- case ARM::S2: case ARM::S3:
+ case ARM::S2:
return ARM::S3;
- case ARM::S4: case ARM::S5:
+ case ARM::S4:
return ARM::S5;
- case ARM::S6: case ARM::S7:
+ case ARM::S6:
return ARM::S7;
- case ARM::S8: case ARM::S9:
+ case ARM::S8:
return ARM::S9;
- case ARM::S10: case ARM::S11:
+ case ARM::S10:
return ARM::S11;
- case ARM::S12: case ARM::S13:
+ case ARM::S12:
return ARM::S13;
- case ARM::S14: case ARM::S15:
+ case ARM::S14:
return ARM::S15;
- case ARM::S16: case ARM::S17:
+ case ARM::S16:
return ARM::S17;
- case ARM::S18: case ARM::S19:
+ case ARM::S18:
return ARM::S19;
- case ARM::S20: case ARM::S21:
+ case ARM::S20:
return ARM::S21;
- case ARM::S22: case ARM::S23:
+ case ARM::S22:
return ARM::S23;
- case ARM::S24: case ARM::S25:
+ case ARM::S24:
return ARM::S25;
- case ARM::S26: case ARM::S27:
+ case ARM::S26:
return ARM::S27;
- case ARM::S28: case ARM::S29:
+ case ARM::S28:
return ARM::S29;
- case ARM::S30: case ARM::S31:
+ case ARM::S30:
return ARM::S31;
- case ARM::D0: case ARM::D1:
+ case ARM::D0:
return ARM::D1;
- case ARM::D2: case ARM::D3:
+ case ARM::D2:
return ARM::D3;
- case ARM::D4: case ARM::D5:
+ case ARM::D4:
return ARM::D5;
- case ARM::D6: case ARM::D7:
+ case ARM::D6:
return ARM::D7;
- case ARM::D8: case ARM::D9:
+ case ARM::D8:
return ARM::D9;
- case ARM::D10: case ARM::D11:
+ case ARM::D10:
return ARM::D11;
- case ARM::D12: case ARM::D13:
+ case ARM::D12:
return ARM::D13;
- case ARM::D14: case ARM::D15:
+ case ARM::D14:
return ARM::D15;
}
Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h?rev=73671&r1=73670&r2=73671&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h Wed Jun 17 21:04:01 2009
@@ -70,12 +70,15 @@
std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
getAllocationOrder(const TargetRegisterClass *RC,
- std::pair<unsigned,unsigned> Hint,
+ unsigned HintType, unsigned HintReg,
const MachineFunction &MF) const;
unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
const MachineFunction &MF) const;
+ void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
+ MachineFunction &MF) const;
+
bool requiresRegisterScavenging(const MachineFunction &MF) const;
bool hasFP(const MachineFunction &MF) const;
More information about the llvm-commits
mailing list