aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-06-15 08:28:29 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-06-15 08:28:29 +0000
commit358dec51804ee52e47ea3a47c9248086e458ad7c (patch)
tree55cae00b3830a7107f21212681aec06a9a79dc4f /lib/CodeGen
parentd3b295c23fe945c992e7ffc29962248a0e573ea2 (diff)
Part 1.
- Change register allocation hint to a pair of unsigned integers. The hint type is zero (which means prefer the register specified as second part of the pair) or entirely target dependent. - Allow targets to specify alternative register allocation orders based on allocation hint. Part 2. - Use the register allocation hint system to implement more aggressive load / store multiple formation. - Aggressively form LDRD / STRD. These are formed *before* register allocation. It has to be done this way to shorten live interval of base and offset registers. e.g. v1025 = LDR v1024, 0 v1026 = LDR v1024, 0 => v1025,v1026 = LDRD v1024, 0 If this transformation isn't done before allocation, v1024 will overlap v1025 which means it more difficult to allocate a register pair. - Even with the register allocation hint, it may not be possible to get the desired allocation. In that case, the post-allocation load / store multiple pass must fix the ldrd / strd instructions. They can either become ldm / stm instructions or back to a pair of ldr / str instructions. This is work in progress, not yet enabled. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73381 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/LiveInterval.cpp12
-rw-r--r--lib/CodeGen/MachineRegisterInfo.cpp2
-rw-r--r--lib/CodeGen/RegAllocLinearScan.cpp25
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp47
-rw-r--r--lib/CodeGen/VirtRegMap.cpp39
5 files changed, 39 insertions, 86 deletions
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
index 97926dd6fd..4d3ce3a9d4 100644
--- a/lib/CodeGen/LiveInterval.cpp
+++ b/lib/CodeGen/LiveInterval.cpp
@@ -507,12 +507,11 @@ void LiveInterval::join(LiveInterval &Other, const int *LHSValNoAssignments,
// Update regalloc hint if currently there isn't one.
if (TargetRegisterInfo::isVirtualRegister(reg) &&
TargetRegisterInfo::isVirtualRegister(Other.reg)) {
- std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> Hint =
- MRI->getRegAllocationHint(reg);
- if (Hint.first == MachineRegisterInfo::RA_None) {
- std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> OtherHint =
+ std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(reg);
+ if (Hint.first == 0 && Hint.second == 0) {
+ std::pair<unsigned, unsigned> OtherHint =
MRI->getRegAllocationHint(Other.reg);
- if (OtherHint.first != MachineRegisterInfo::RA_None)
+ if (OtherHint.first || OtherHint.second)
MRI->setRegAllocationHint(reg, OtherHint.first, OtherHint.second);
}
}
@@ -772,8 +771,7 @@ void LiveInterval::Copy(const LiveInterval &RHS,
BumpPtrAllocator &VNInfoAllocator) {
ranges.clear();
valnos.clear();
- std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> Hint =
- MRI->getRegAllocationHint(RHS.reg);
+ std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(RHS.reg);
MRI->setRegAllocationHint(reg, Hint.first, Hint.second);
weight = RHS.weight;
diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp
index 9649c4c44c..544d83a33f 100644
--- a/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/lib/CodeGen/MachineRegisterInfo.cpp
@@ -65,7 +65,7 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass){
// Add a reg, but keep track of whether the vector reallocated or not.
void *ArrayBase = VRegInfo.empty() ? 0 : &VRegInfo[0];
VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0));
- RegAllocHints.push_back(std::make_pair(RA_None, 0));
+ RegAllocHints.push_back(std::make_pair(0, 0));
if (!((&VRegInfo[0] == ArrayBase || VRegInfo.size() == 1)))
// The vector reallocated, handle this now.
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp
index 3c445e7942..ec956c2c17 100644
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -281,7 +281,8 @@ namespace {
/// getFreePhysReg - return a free physical register for this virtual
/// register interval if we have one, otherwise return 0.
unsigned getFreePhysReg(LiveInterval* cur);
- unsigned getFreePhysReg(const TargetRegisterClass *RC,
+ unsigned getFreePhysReg(LiveInterval* cur,
+ const TargetRegisterClass *RC,
unsigned MaxInactiveCount,
SmallVector<unsigned, 256> &inactiveCounts,
bool SkipDGRegs);
@@ -936,8 +937,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
if (DstSubReg)
Reg = tri_->getMatchingSuperReg(Reg, DstSubReg, RC);
if (Reg && allocatableRegs_[Reg] && RC->contains(Reg))
- mri_->setRegAllocationHint(cur->reg,
- MachineRegisterInfo::RA_Preference, Reg);
+ mri_->setRegAllocationHint(cur->reg, 0, Reg);
}
}
}
@@ -1046,8 +1046,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
if (LiveInterval *NextReloadLI = hasNextReloadInterval(cur)) {
// "Downgrade" physReg to try to keep physReg from being allocated until
// the next reload from the same SS is allocated.
- mri_->setRegAllocationHint(NextReloadLI->reg,
- MachineRegisterInfo::RA_Preference, physReg);
+ mri_->setRegAllocationHint(NextReloadLI->reg, 0, physReg);
DowngradeRegister(cur, physReg);
}
return;
@@ -1293,7 +1292,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
// It interval has a preference, it must be defined by a copy. Clear the
// preference now since the source interval allocation may have been
// undone as well.
- mri_->setRegAllocationHint(i->reg, MachineRegisterInfo::RA_None, 0);
+ mri_->setRegAllocationHint(i->reg, 0, 0);
else {
UpgradeRegister(ii->second);
}
@@ -1349,15 +1348,17 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
}
}
-unsigned RALinScan::getFreePhysReg(const TargetRegisterClass *RC,
+unsigned RALinScan::getFreePhysReg(LiveInterval* cur,
+ const TargetRegisterClass *RC,
unsigned MaxInactiveCount,
SmallVector<unsigned, 256> &inactiveCounts,
bool SkipDGRegs) {
unsigned FreeReg = 0;
unsigned FreeRegInactiveCount = 0;
- TargetRegisterClass::iterator I = RC->allocation_order_begin(*mf_);
- TargetRegisterClass::iterator E = RC->allocation_order_end(*mf_);
+ TargetRegisterClass::iterator I, E;
+ tie(I, E) = tri_->getAllocationOrder(RC,
+ mri_->getRegAllocationHint(cur->reg), *mf_);
assert(I != E && "No allocatable register in this register class!");
// Scan for the first available register.
@@ -1380,7 +1381,7 @@ unsigned RALinScan::getFreePhysReg(const TargetRegisterClass *RC,
// return this register.
if (FreeReg == 0 || FreeRegInactiveCount == MaxInactiveCount)
return FreeReg;
-
+
// Continue scanning the registers, looking for the one with the highest
// inactive count. Alkis found that this reduced register pressure very
// slightly on X86 (in rev 1.94 of this file), though this should probably be
@@ -1440,12 +1441,12 @@ unsigned RALinScan::getFreePhysReg(LiveInterval *cur) {
}
if (!DowngradedRegs.empty()) {
- unsigned FreeReg = getFreePhysReg(RC, MaxInactiveCount, inactiveCounts,
+ unsigned FreeReg = getFreePhysReg(cur, RC, MaxInactiveCount, inactiveCounts,
true);
if (FreeReg)
return FreeReg;
}
- return getFreePhysReg(RC, MaxInactiveCount, inactiveCounts, false);
+ return getFreePhysReg(cur, RC, MaxInactiveCount, inactiveCounts, false);
}
FunctionPass* llvm::createLinearScanRegisterAllocator() {
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index 95e5acaab4..7d9170a2fe 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -1272,26 +1272,8 @@ static unsigned getRegAllocPreference(unsigned Reg, MachineFunction &MF,
const TargetRegisterInfo *TRI) {
if (TargetRegisterInfo::isPhysicalRegister(Reg))
return 0;
-
- std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> Hint =
- MRI->getRegAllocationHint(Reg);
- switch (Hint.first) {
- default: assert(0);
- case MachineRegisterInfo::RA_None:
- return 0;
- case MachineRegisterInfo::RA_Preference:
- return Hint.second;
- case MachineRegisterInfo::RA_PairEven:
- if (TargetRegisterInfo::isPhysicalRegister(Hint.second))
- return TRI->getRegisterPairOdd(MF, Hint.second);
- return Hint.second;
- case MachineRegisterInfo::RA_PairOdd:
- if (TargetRegisterInfo::isPhysicalRegister(Hint.second))
- return TRI->getRegisterPairEven(MF, Hint.second);
- return Hint.second;
- }
- // Shouldn't reach here.
- return 0;
+ std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
+ return TRI->ResolveRegAllocHint(Hint.first, Hint.second, MF);
}
/// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
@@ -1595,8 +1577,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
if (PhysJoinTweak) {
if (SrcIsPhys) {
if (!isWinToJoinVRWithSrcPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
- mri_->setRegAllocationHint(DstInt.reg,
- MachineRegisterInfo::RA_Preference, SrcReg);
+ mri_->setRegAllocationHint(DstInt.reg, 0, SrcReg);
++numAborts;
DOUT << "\tMay tie down a physical register, abort!\n";
Again = true; // May be possible to coalesce later.
@@ -1604,8 +1585,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
}
} else {
if (!isWinToJoinVRWithDstPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
- mri_->setRegAllocationHint(SrcInt.reg,
- MachineRegisterInfo::RA_Preference, DstReg);
+ mri_->setRegAllocationHint(SrcInt.reg, 0, DstReg);
++numAborts;
DOUT << "\tMay tie down a physical register, abort!\n";
Again = true; // May be possible to coalesce later.
@@ -1629,8 +1609,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
if (Length > Threshold &&
(((float)std::distance(mri_->use_begin(JoinVReg),
mri_->use_end()) / Length) < Ratio)) {
- mri_->setRegAllocationHint(JoinVInt.reg,
- MachineRegisterInfo::RA_Preference, JoinPReg);
+ mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
++numAborts;
DOUT << "\tMay tie down a physical register, abort!\n";
Again = true; // May be possible to coalesce later.
@@ -1815,8 +1794,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
TargetRegisterInfo::isVirtualRegister(ResDstInt->reg)) {
const TargetRegisterClass *RC = mri_->getRegClass(ResDstInt->reg);
if (!RC->contains(Preference))
- mri_->setRegAllocationHint(ResDstInt->reg,
- MachineRegisterInfo::RA_None, 0);
+ mri_->setRegAllocationHint(ResDstInt->reg, 0, 0);
}
DOUT << "\n\t\tJoined. Result = "; ResDstInt->print(DOUT, tri_);
@@ -2067,12 +2045,9 @@ bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS){
// Update regalloc hint if both are virtual registers.
if (TargetRegisterInfo::isVirtualRegister(LHS.reg) &&
TargetRegisterInfo::isVirtualRegister(RHS.reg)) {
- std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> RHSPref =
- mri_->getRegAllocationHint(RHS.reg);
- std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> LHSPref =
- mri_->getRegAllocationHint(LHS.reg);
- if (RHSPref.first != MachineRegisterInfo::RA_None &&
- LHSPref.first == MachineRegisterInfo::RA_None)
+ std::pair<unsigned, unsigned> RHSPref = mri_->getRegAllocationHint(RHS.reg);
+ std::pair<unsigned, unsigned> LHSPref = mri_->getRegAllocationHint(LHS.reg);
+ if (RHSPref != LHSPref)
mri_->setRegAllocationHint(LHS.reg, RHSPref.first, RHSPref.second);
}
@@ -2846,8 +2821,8 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
}
// Slightly prefer live interval that has been assigned a preferred reg.
- if (mri_->getRegAllocationHint(LI.reg).first !=
- MachineRegisterInfo::RA_None)
+ std::pair<unsigned, unsigned> Hint = mri_->getRegAllocationHint(LI.reg);
+ if (Hint.first || Hint.second)
LI.weight *= 1.01F;
// Divide the weight of the interval by its size. This encourages
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index 87d75dd006..4d3417fdff 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -100,36 +100,15 @@ void VirtRegMap::grow() {
}
unsigned VirtRegMap::getRegAllocPref(unsigned virtReg) {
- std::pair<MachineRegisterInfo::RegAllocHintType, unsigned> Hint =
- MRI->getRegAllocationHint(virtReg);
- switch (Hint.first) {
- default: assert(0);
- case MachineRegisterInfo::RA_None:
- return 0;
- case MachineRegisterInfo::RA_Preference:
- if (TargetRegisterInfo::isPhysicalRegister(Hint.second))
- return Hint.second;
- if (hasPhys(Hint.second))
- return getPhys(Hint.second);
- case MachineRegisterInfo::RA_PairEven: {
- unsigned physReg = Hint.second;
- if (TargetRegisterInfo::isPhysicalRegister(physReg))
- return TRI->getRegisterPairEven(*MF, physReg);
- else if (hasPhys(physReg))
- return TRI->getRegisterPairEven(*MF, getPhys(physReg));
- return 0;
- }
- case MachineRegisterInfo::RA_PairOdd: {
- unsigned physReg = Hint.second;
- if (TargetRegisterInfo::isPhysicalRegister(physReg))
- return TRI->getRegisterPairOdd(*MF, physReg);
- else if (hasPhys(physReg))
- return TRI->getRegisterPairOdd(*MF, getPhys(physReg));
- return 0;
- }
- }
- // Shouldn't reach here.
- return 0;
+ std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(virtReg);
+ unsigned physReg = Hint.second;
+ if (physReg &&
+ TargetRegisterInfo::isVirtualRegister(physReg) && hasPhys(physReg))
+ physReg = getPhys(physReg);
+ if (Hint.first == 0)
+ return (physReg && TargetRegisterInfo::isPhysicalRegister(physReg))
+ ? physReg : 0;
+ return TRI->ResolveRegAllocHint(Hint.first, physReg, *MF);
}
int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {