[llvm-commits] [llvm] r133051 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/Target/TargetRegisterInfo.cpp utils/TableGen/RegisterInfoEmitter.cpp
Owen Anderson
resistor at mac.com
Wed Jun 15 00:05:41 PDT 2011
I forgot to thank Jakob for pointing this out to me. Kudos to him!
--Owen
On Jun 14, 2011, at 11:53 PM, Owen Anderson wrote:
> Author: resistor
> Date: Wed Jun 15 01:53:50 2011
> New Revision: 133051
>
> URL: http://llvm.org/viewvc/llvm-project?rev=133051&view=rev
> Log:
> Replace the statically generated hashtables for checking register relationships with just scanning the (typically tiny) static lists.
>
> At the time I wrote this code (circa 2007), TargetRegisterInfo was using a std::set to perform these queries. Switching to the static hashtables was an obvious improvement, but in reality there's no reason to do anything other than scan.
> With this change, total LLC time on a whole-program 403.gcc is reduced by approximately 1.5%, almost all of which comes from a 15% reduction in LiveVariables time. It also reduces the binary size of LLC by 86KB, thanks to eliminating a bunch of very large static tables.
>
> Modified:
> llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
> llvm/trunk/lib/Target/TargetRegisterInfo.cpp
> llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
>
> Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=133051&r1=133050&r2=133051&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original)
> +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Wed Jun 15 01:53:50 2011
> @@ -285,11 +285,6 @@
> /// descriptor.
> ///
> class TargetRegisterInfo {
> -protected:
> - const unsigned* SubregHash;
> - const unsigned SubregHashSize;
> - const unsigned* AliasesHash;
> - const unsigned AliasesHashSize;
> public:
> typedef const TargetRegisterClass * const * regclass_iterator;
> private:
> @@ -307,11 +302,7 @@
> regclass_iterator RegClassEnd,
> const char *const *subregindexnames,
> int CallFrameSetupOpcode = -1,
> - int CallFrameDestroyOpcode = -1,
> - const unsigned* subregs = 0,
> - const unsigned subregsize = 0,
> - const unsigned* aliases = 0,
> - const unsigned aliasessize = 0);
> + int CallFrameDestroyOpcode = -1);
> virtual ~TargetRegisterInfo();
> public:
>
> @@ -468,50 +459,28 @@
> /// regsOverlap - Returns true if the two registers are equal or alias each
> /// other. The registers may be virtual register.
> bool regsOverlap(unsigned regA, unsigned regB) const {
> - if (regA == regB)
> - return true;
> -
> - if (regA > regB)
> - std::swap(regA, regB);
> -
> + if (regA == regB) return true;
> if (isVirtualRegister(regA) || isVirtualRegister(regB))
> return false;
> -
> - // regA and regB are distinct physical registers. Do they alias?
> - size_t index = (regA * 11 + regB * 97) & (AliasesHashSize-1);
> - unsigned ProbeAmt = 1;
> - while (AliasesHash[index*2] != 0 && AliasesHash[index*2+1] != 0) {
> - if (AliasesHash[index*2] == regA && AliasesHash[index*2+1] == regB)
> - return true;
> -
> - index = (index + ProbeAmt) & (AliasesHashSize-1);
> - ProbeAmt += 1;
> + for (const unsigned *regList = getOverlaps(regA)+1; *regList; ++regList) {
> + if (*regList == regB) return true;
> }
> -
> return false;
> }
>
> /// isSubRegister - Returns true if regB is a sub-register of regA.
> ///
> bool isSubRegister(unsigned regA, unsigned regB) const {
> - // SubregHash is a simple quadratically probed hash table.
> - size_t index = (regA * 11 + regB * 97) & (SubregHashSize-1);
> - unsigned ProbeAmt = 1;
> - while (SubregHash[index*2] != 0 && SubregHash[index*2+1] != 0) {
> - if (SubregHash[index*2] == regA && SubregHash[index*2+1] == regB)
> - return true;
> -
> - index = (index + ProbeAmt) & (SubregHashSize-1);
> - ProbeAmt += 1;
> - }
> -
> - return false;
> + return isSuperRegister(regB, regA);
> }
>
> /// isSuperRegister - Returns true if regB is a super-register of regA.
> ///
> bool isSuperRegister(unsigned regA, unsigned regB) const {
> - return isSubRegister(regB, regA);
> + for (const unsigned *regList = getSuperRegisters(regA); *regList;++regList){
> + if (*regList == regB) return true;
> + }
> + return false;
> }
>
> /// getCalleeSavedRegs - Return a null-terminated list of all of the
>
> Modified: llvm/trunk/lib/Target/TargetRegisterInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetRegisterInfo.cpp?rev=133051&r1=133050&r2=133051&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/TargetRegisterInfo.cpp (original)
> +++ llvm/trunk/lib/Target/TargetRegisterInfo.cpp Wed Jun 15 01:53:50 2011
> @@ -23,12 +23,8 @@
> TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR,
> regclass_iterator RCB, regclass_iterator RCE,
> const char *const *subregindexnames,
> - int CFSO, int CFDO,
> - const unsigned* subregs, const unsigned subregsize,
> - const unsigned* aliases, const unsigned aliasessize)
> - : SubregHash(subregs), SubregHashSize(subregsize),
> - AliasesHash(aliases), AliasesHashSize(aliasessize),
> - Desc(D), SubRegIndexNames(subregindexnames), NumRegs(NR),
> + int CFSO, int CFDO)
> + : Desc(D), SubRegIndexNames(subregindexnames), NumRegs(NR),
> RegClassBegin(RCB), RegClassEnd(RCE) {
> assert(isPhysicalRegister(NumRegs) &&
> "Target has too many physical registers!");
>
> Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=133051&r1=133050&r2=133051&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Wed Jun 15 01:53:50 2011
> @@ -129,64 +129,6 @@
> typedef std::pair<unsigned, unsigned> UUPair;
> typedef std::vector<UUPair> UUVector;
>
> -// Generate and print a quadratically probed hash table of unsigned pairs.
> -// The pair (0,0) is used as a sentinel, so it cannot be a data point.
> -static void generateHashTable(raw_ostream &OS, const char *Name,
> - const UUVector &Data) {
> - const UUPair Sentinel(0, 0);
> - unsigned HSize = Data.size();
> - UUVector HT;
> -
> - // Grow the hash table until all entries can be found in less than 8 probes.
> - unsigned MaxProbes;
> - do {
> - // Hashtable size must be a power of two.
> - HSize = NextPowerOf2(HSize);
> - HT.assign(HSize, Sentinel);
> -
> - // Insert all entries.
> - for (unsigned i = 0, e = Data.size(); i != e; ++i) {
> - UUPair D = Data[i];
> - unsigned Idx = (D.first * 11 + D.second * 97) & (HSize - 1);
> - unsigned ProbeAmt = 1;
> - while (HT[Idx] != Sentinel) {
> - Idx = (Idx + ProbeAmt) & (HSize - 1);
> - ProbeAmt += 1;
> - }
> - HT[Idx] = D;
> - }
> -
> - // Now measure the max number of probes for any worst case miss.
> - MaxProbes = 0;
> - unsigned TotalProbes = 0;
> - for (unsigned i = 0, e = HSize; i != e; ++i) {
> - unsigned Idx = i;
> - unsigned ProbeAmt = 1;
> - while (HT[Idx] != Sentinel) {
> - Idx = (Idx + ProbeAmt) & (HSize - 1);
> - ProbeAmt += 1;
> - }
> - TotalProbes += ProbeAmt;
> - MaxProbes = std::max(MaxProbes, ProbeAmt);
> - }
> - OS << "\n // Max number of probes: " << MaxProbes
> - << format(", avg %.1f", float(TotalProbes)/HSize);
> - } while (MaxProbes >= 6);
> -
> - // Print the hash table.
> - OS << "\n // Used entries: " << Data.size()
> - << "\n const unsigned " << Name << "Size = " << HSize << ';'
> - << "\n const unsigned " << Name << "[] = {\n";
> -
> - for (unsigned i = 0, e = HSize; i != e; ++i) {
> - UUPair D = HT[i];
> - OS << format(" %3u,%3u,", D.first, D.second);
> - if (i % 8 == 7 && i + 1 != e)
> - OS << '\n';
> - }
> - OS << "\n };\n";
> -}
> -
> //
> // RegisterInfoEmitter::run - Main register file description emitter.
> //
> @@ -445,33 +387,6 @@
> DwarfRegNumsMapTy DwarfRegNums;
> const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
>
> - // Print the SubregHashTable, a simple quadratically probed
> - // hash table for determining if a register is a subregister
> - // of another register.
> - UUVector HTData;
> - for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
> - unsigned RegNo = Regs[i].EnumValue;
> - const CodeGenRegister::SuperRegList &SR = Regs[i].getSuperRegs();
> - for (CodeGenRegister::SuperRegList::const_iterator I = SR.begin(),
> - E = SR.end(); I != E; ++I)
> - HTData.push_back(UUPair((*I)->EnumValue, RegNo));
> - }
> - generateHashTable(OS, "SubregHashTable", HTData);
> -
> - // Print the AliasHashTable, a simple quadratically probed
> - // hash table for determining if a register aliases another register.
> - // Since the overlaps() relation is symmetric, only store a < b pairs.
> - HTData.clear();
> - for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
> - unsigned RegNo = Regs[i].EnumValue;
> - const CodeGenRegister::Set &O = Overlaps[&Regs[i]];
> - for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end();
> - I != E; ++I)
> - if (RegNo < (*I)->EnumValue)
> - HTData.push_back(UUPair(RegNo, (*I)->EnumValue));
> - }
> - generateHashTable(OS, "AliasesHashTable", HTData);
> -
> // Emit an overlap list for all registers.
> for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
> const CodeGenRegister *Reg = &Regs[i];
> @@ -640,9 +555,7 @@
> << " : TargetRegisterInfo(RegisterDescriptors, " << Regs.size()+1
> << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
> << " SubRegIndexTable,\n"
> - << " CallFrameSetupOpcode, CallFrameDestroyOpcode,\n"
> - << " SubregHashTable, SubregHashTableSize,\n"
> - << " AliasesHashTable, AliasesHashTableSize) {\n"
> + << " CallFrameSetupOpcode, CallFrameDestroyOpcode) {\n"
> << "}\n\n";
>
> // Collect all information about dwarf register numbers
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list