From: Jakob Stoklund Olesen Date: Thu, 24 Feb 2011 23:21:36 +0000 (+0000) Subject: Tweak the register allocator priority queue some more. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=107d366df762c18294dc00f5de916f62672353ff;p=oota-llvm.git 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 --- diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 03886195404..03d1372c2f9 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())