From 00621efb40edb7fe16bf2af6d4699c9d024a28e7 Mon Sep 17 00:00:00 2001 From: David Goodwin Date: Fri, 20 Nov 2009 23:33:54 +0000 Subject: [PATCH] Restructure code to allow renaming of multiple-register groups for anti-dep breaking. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89511 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetRegisterInfo.h | 2 +- lib/CodeGen/AggressiveAntiDepBreaker.cpp | 117 +++++++++++++++++++------------ 2 files changed, 74 insertions(+), 45 deletions(-) diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index cd6fd286fb0..e82a0c7f8ec 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -465,7 +465,7 @@ public: virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0; /// getSubRegIndex - For a given register pair, return the sub-register index - /// if they are second register is a sub-register of the second. Return zero + /// if the are second register is a sub-register of the first. Return zero /// otherwise. virtual unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const = 0; diff --git a/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/lib/CodeGen/AggressiveAntiDepBreaker.cpp index f9c2bf02a42..e8fb86cfcda 100644 --- a/lib/CodeGen/AggressiveAntiDepBreaker.cpp +++ b/lib/CodeGen/AggressiveAntiDepBreaker.cpp @@ -587,79 +587,108 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( return false; } +#ifndef NDEBUG + // If DebugDiv > 0 then only rename (renamecnt % DebugDiv) == DebugMod + if (DebugDiv > 0) { + static int renamecnt = 0; + if (renamecnt++ % DebugDiv != DebugMod) + return false; + + errs() << "*** Performing rename " << TRI->getName(SuperReg) << + " for debug ***\n"; + } +#endif + // Check each possible rename register for SuperReg in round-robin // order. If that register is available, and the corresponding // registers are available for the other group subregisters, then we // can use those registers to rename. - BitVector SuperBV = RenameRegisterMap[SuperReg]; const TargetRegisterClass *SuperRC = TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other); const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF); const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF); if (RB == RE) { - DEBUG(errs() << "\tEmpty Regclass!!\n"); + DEBUG(errs() << "\tEmpty Super Regclass!!\n"); return false; } -#ifndef NDEBUG - // If DebugDiv > 0 then only rename (renamecnt % DebugDiv) == DebugMod - if (DebugDiv > 0) { - static int renamecnt = 0; - if (renamecnt++ % DebugDiv != DebugMod) - return false; - - errs() << "*** Performing rename " << TRI->getName(SuperReg) << - " for debug ***\n"; - } -#endif + DEBUG(errs() << "\tFind Registers:"); if (RenameOrder.count(SuperRC) == 0) RenameOrder.insert(RenameOrderType::value_type(SuperRC, RE)); - DEBUG(errs() << "\tFind Register:"); - const TargetRegisterClass::iterator OrigR = RenameOrder[SuperRC]; const TargetRegisterClass::iterator EndR = ((OrigR == RE) ? RB : OrigR); TargetRegisterClass::iterator R = OrigR; do { if (R == RB) R = RE; --R; - const unsigned Reg = *R; + const unsigned NewSuperReg = *R; // Don't replace a register with itself. - if (Reg == SuperReg) continue; - - DEBUG(errs() << " " << TRI->getName(Reg)); + if (NewSuperReg == SuperReg) continue; - // If Reg is dead and Reg's most recent def is not before - // SuperRegs's kill, it's safe to replace SuperReg with Reg. We - // must also check all aliases of Reg. because we can't define a - // register when any sub or super is already live. - if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { - DEBUG(errs() << "(live)"); - continue; - } else { - bool found = false; - for (const unsigned *Alias = TRI->getAliasSet(Reg); - *Alias; ++Alias) { - unsigned AliasReg = *Alias; - if (State->IsLive(AliasReg) || (KillIndices[SuperReg] > DefIndices[AliasReg])) { - DEBUG(errs() << "(alias " << TRI->getName(AliasReg) << " live)"); - found = true; - break; + DEBUG(errs() << " [" << TRI->getName(NewSuperReg) << ':'); + RenameMap.clear(); + + // For each referenced group register (which must be a SuperReg or + // a subregister of SuperReg), find the corresponding subregister + // of NewSuperReg and make sure it is free to be renamed. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + unsigned Reg = Regs[i]; + unsigned NewReg = 0; + if (Reg == SuperReg) { + NewReg = NewSuperReg; + } else { + unsigned NewSubRegIdx = TRI->getSubRegIndex(SuperReg, Reg); + if (NewSubRegIdx != 0) + NewReg = TRI->getSubReg(NewSuperReg, NewSubRegIdx); + } + + DEBUG(errs() << " " << TRI->getName(NewReg)); + + // Check if Reg can be renamed to NewReg. + BitVector BV = RenameRegisterMap[Reg]; + if (!BV.test(NewReg)) { + DEBUG(errs() << "(no rename)"); + goto next_super_reg; + } + + // If NewReg is dead and NewReg's most recent def is not before + // Regs's kill, it's safe to replace Reg with NewReg. We + // must also check all aliases of NewReg, because we can't define a + // register when any sub or super is already live. + if (State->IsLive(NewReg) || (KillIndices[Reg] > DefIndices[NewReg])) { + DEBUG(errs() << "(live)"); + goto next_super_reg; + } else { + bool found = false; + for (const unsigned *Alias = TRI->getAliasSet(NewReg); + *Alias; ++Alias) { + unsigned AliasReg = *Alias; + if (State->IsLive(AliasReg) || (KillIndices[Reg] > DefIndices[AliasReg])) { + DEBUG(errs() << "(alias " << TRI->getName(AliasReg) << " live)"); + found = true; + break; + } } + if (found) + goto next_super_reg; } - if (found) - continue; + + // Record that 'Reg' can be renamed to 'NewReg'. + RenameMap.insert(std::pair(Reg, NewReg)); } - if (Reg != 0) { - DEBUG(errs() << '\n'); - RenameOrder.erase(SuperRC); - RenameOrder.insert(RenameOrderType::value_type(SuperRC, R)); - RenameMap.insert(std::pair(SuperReg, Reg)); - return true; - } + // If we fall-out here, then every register in the group can be + // renamed, as recorded in RenameMap. + RenameOrder.erase(SuperRC); + RenameOrder.insert(RenameOrderType::value_type(SuperRC, R)); + DEBUG(errs() << "]\n"); + return true; + + next_super_reg: + DEBUG(errs() << ']'); } while (R != EndR); DEBUG(errs() << '\n'); -- 2.11.0