From 9df8567548e15c6cd91e8a5851784574c4f09528 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 23 Jul 2011 00:47:49 +0000 Subject: [PATCH] Turn the DenseSet in MCRegisterClass into a tblgenerated bit field. This should be faster and smaller. Goodbye static ctors and dtors! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135836 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCRegisterInfo.h | 30 +++++++++--------- include/llvm/Target/TargetRegisterInfo.h | 2 +- utils/TableGen/RegisterInfoEmitter.cpp | 40 +++++++++++++++++++++++- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 7ed84f214d0..eeb4f3e8f30 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -17,7 +17,6 @@ #define LLVM_MC_MCREGISTERINFO_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" #include namespace llvm { @@ -34,20 +33,18 @@ private: const int CopyCost; const bool Allocatable; const iterator RegsBegin, RegsEnd; - DenseSet RegSet; + const unsigned char *RegSet; + const unsigned RegSetSize; public: MCRegisterClass(unsigned id, const char *name, unsigned RS, unsigned Al, int CC, bool Allocable, - iterator RB, iterator RE) + iterator RB, iterator RE, const unsigned char *Bits, + unsigned NumBytes) : ID(id), Name(name), RegSize(RS), Alignment(Al), CopyCost(CC), - Allocatable(Allocable), RegsBegin(RB), RegsEnd(RE) {} - - /// initMCRegisterClass - Initialize initMCRegisterClass. *DO NOT USE*. - // FIXME: This could go away if RegSet would use a constant bit field. - void initMCRegisterClass() { - RegSet.resize(getNumRegs()); - for (iterator I = RegsBegin, E = RegsEnd; I != E; ++I) - RegSet.insert(*I); + Allocatable(Allocable), RegsBegin(RB), RegsEnd(RE), RegSet(Bits), + RegSetSize(NumBytes) { + for (iterator i = RegsBegin; i != RegsEnd; ++i) + assert (contains(*i) && "Bit field corrupted."); } /// getID() - Return the register class ID number. @@ -77,7 +74,11 @@ public: /// contains - Return true if the specified register is included in this /// register class. This does not include virtual registers. bool contains(unsigned Reg) const { - return RegSet.count(Reg); + unsigned InByte = Reg % 8; + unsigned Byte = Reg / 8; + if (Byte > RegSetSize) + return false; + return (RegSet[Byte] & (1 << InByte)) != 0; } /// contains - Return true if both registers are in this class. @@ -151,15 +152,12 @@ public: /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, - MCRegisterClass *C, unsigned NC) { + const MCRegisterClass *C, unsigned NC) { Desc = D; NumRegs = NR; RAReg = RA; Classes = C; NumClasses = NC; - // FIXME: This should go away. - for (unsigned i = 0; i != NC; ++i) - C[i].initMCRegisterClass(); } /// mapLLVMRegToDwarfReg - Used to initialize LLVM register to Dwarf diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 19e656de0d5..7dc9ec40de0 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -46,7 +46,7 @@ private: const sc_iterator SubRegClasses; const sc_iterator SuperRegClasses; public: - TargetRegisterClass(MCRegisterClass *MC, const EVT *vts, + TargetRegisterClass(const MCRegisterClass *MC, const EVT *vts, const TargetRegisterClass * const *subcs, const TargetRegisterClass * const *supcs, const TargetRegisterClass * const *subregcs, diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 05411e59ada..8ec45d41f27 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -17,6 +17,7 @@ #include "CodeGenTarget.h" #include "CodeGenRegisters.h" #include "Record.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Format.h" @@ -202,6 +203,30 @@ RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS, } } +// Helper to emit a set of bits into a constant byte array. +class BitVectorEmitter { + BitVector Values; + unsigned Len; +public: + BitVectorEmitter(unsigned L) : Len(L%8 ? ((L/8)+1)*8 : L) { + Values.resize(Len); + } + + void add(unsigned v) { Values[v] = true; } + + void print(raw_ostream &OS) { + for (unsigned i = 0, e = Len / 8; i != e; ++i) { + unsigned char out = 0; + for (unsigned ii = 0, ie = 8; ii != ie; ++ii) + if (Values[i * 8 + ii]) + out |= 1 << ii; + OS << "0x"; + OS.write_hex(out); + OS << ", "; + } + } +}; + // // runMCDesc - Print out MC register descriptions. // @@ -320,6 +345,18 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << getQualifiedName(Reg) << ", "; } OS << "\n };\n\n"; + + OS << " // " << Name << " Bit set.\n" + << " static const unsigned char " << Name + << "Bits[] = {\n "; + BitVectorEmitter BVE(Target.getRegBank().getRegisters().size()+1); + for (unsigned i = 0, e = Order.size(); i != e; ++i) { + Record *Reg = Order[i]; + BVE.add(Target.getRegBank().getReg(Reg)->EnumValue); + } + BVE.print(OS); + OS << "\n };\n\n"; + } OS << "}\n\n"; @@ -337,7 +374,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << RC.CopyCost << ", " << RC.Allocatable << ", " << RC.getName() << ", " << RC.getName() << " + " - << RC.getOrder().size() + << RC.getOrder().size() << ", " + << RC.getName() << "Bits, sizeof(" << RC.getName() << "Bits)" << "),\n"; }