diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-02-24 23:21:36 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-02-24 23:21:36 +0000 |
commit | 107d366df762c18294dc00f5de916f62672353ff (patch) | |
tree | 64d25754d5a121b212223565a908b8fbd21a26ad | |
parent | 4e671437ed9ff171e83fb34a971388c29cbe2704 (diff) |
Tweak the register allocator priority queue some more.
New live ranges are assigned in long -> short order, but live ranges that have
been evicted at least once are deferred and assigned in short -> long order.
Also disable splitting and spilling for live ranges seen for the first time.
The intention is to create a realistic interference pattern from the heavy live
ranges before starting splitting and spilling around it.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126451 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/RegAllocGreedy.cpp | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 0388619540..03d1372c2f 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -194,22 +194,26 @@ void RAGreedy::releaseMemory() { void RAGreedy::enqueue(LiveInterval *LI) { // Prioritize live ranges by size, assigning larger ranges first. // The queue holds (size, reg) pairs. - unsigned Size = LI->getSize(); - unsigned Reg = LI->reg; + const unsigned Size = LI->getSize(); + const unsigned Reg = LI->reg; assert(TargetRegisterInfo::isVirtualRegister(Reg) && "Can only enqueue virtual registers"); + const unsigned Hint = VRM->getRegAllocPref(Reg); + unsigned Prio; - // Boost ranges that have a physical register hint. - unsigned Hint = VRM->getRegAllocPref(Reg); - if (TargetRegisterInfo::isPhysicalRegister(Hint)) - Size |= (1u << 30); - - // Boost ranges that we see for the first time. Generation.grow(Reg); if (++Generation[Reg] == 1) - Size |= (1u << 31); + // 1st generation ranges are handled first, long -> short. + Prio = (1u << 31) + Size; + else + // Repeat offenders are handled second, short -> long + Prio = (1u << 30) - Size; - Queue.push(std::make_pair(Size, Reg)); + // Boost ranges that have a physical register hint. + if (TargetRegisterInfo::isPhysicalRegister(Hint)) + Prio |= (1u << 30); + + Queue.push(std::make_pair(Prio, Reg)); } LiveInterval *RAGreedy::dequeue() { @@ -1311,6 +1315,14 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, assert(NewVRegs.empty() && "Cannot append to existing NewVRegs"); + // The first time we see a live range, don't try to split or spill. + // Wait until the second time, when all smaller ranges have been allocated. + // This gives a better picture of the interference to split around. + if (Generation[VirtReg.reg] == 1) { + NewVRegs.push_back(&VirtReg); + return 0; + } + // Try splitting VirtReg or interferences. unsigned PhysReg = trySplit(VirtReg, Order, NewVRegs); if (PhysReg || !NewVRegs.empty()) |