diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-06-15 08:28:29 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-06-15 08:28:29 +0000 |
commit | 358dec51804ee52e47ea3a47c9248086e458ad7c (patch) | |
tree | 55cae00b3830a7107f21212681aec06a9a79dc4f /lib/CodeGen | |
parent | d3b295c23fe945c992e7ffc29962248a0e573ea2 (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.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/MachineRegisterInfo.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocLinearScan.cpp | 25 | ||||
-rw-r--r-- | lib/CodeGen/SimpleRegisterCoalescing.cpp | 47 | ||||
-rw-r--r-- | lib/CodeGen/VirtRegMap.cpp | 39 |
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) { |