[llvm-commits] [llvm] r153837 - in /llvm/trunk: include/llvm/MC/MCRegisterInfo.h utils/TableGen/RegisterInfoEmitter.cpp utils/TableGen/RegisterInfoEmitter.h
Benjamin Kramer
benny.kra at googlemail.com
Sun Apr 1 07:30:03 PDT 2012
On 01.04.2012, at 16:23, Benjamin Kramer wrote:
> Author: d0k
> Date: Sun Apr 1 09:23:58 2012
> New Revision: 153837
>
> URL: http://llvm.org/viewvc/llvm-project?rev=153837&view=rev
> Log:
> Emit the LLVM<->DWARF register mapping as a sorted table and use binary search to do the lookup.
>
> This also avoids emitting the information twice, which led to code bloat. On i386-linux-Release+Asserts
> with all targets built this change shaves a whopping 1.3 MB off clang. The number is probably exaggerated
> by recent inliner changes but the methods were already enormous with the old inline cost computation.
>
> The DWARF reg -> LLVM reg mapping doesn't seem to have holes in it, so it could be a simple lookup table.
> I didn't implement that optimization yet to avoid potentially changing functionality.
Further investigation showed that there are holes on ARM, so we can't get rid of the binary search.
- Ben
>
> There is still some duplication both in tablegen and the generated code that should be cleaned up eventually.
>
> Modified:
> llvm/trunk/include/llvm/MC/MCRegisterInfo.h
> llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
> llvm/trunk/utils/TableGen/RegisterInfoEmitter.h
>
> Modified: llvm/trunk/include/llvm/MC/MCRegisterInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCRegisterInfo.h?rev=153837&r1=153836&r2=153837&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCRegisterInfo.h (original)
> +++ llvm/trunk/include/llvm/MC/MCRegisterInfo.h Sun Apr 1 09:23:58 2012
> @@ -127,6 +127,16 @@
> class MCRegisterInfo {
> public:
> typedef const MCRegisterClass *regclass_iterator;
> +
> + /// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be
> + /// performed with a binary search.
> + struct DwarfLLVMRegPair {
> + unsigned FromReg;
> + unsigned ToReg;
> +
> + bool operator==(unsigned Reg) const { return FromReg == Reg; }
> + bool operator<(unsigned Reg) const { return FromReg < Reg; }
> + };
> private:
> const MCRegisterDesc *Desc; // Pointer to the descriptor array
> unsigned NumRegs; // Number of entries in the array
> @@ -137,10 +147,15 @@
> const uint16_t *SubRegIndices; // Pointer to the subreg lookup
> // array.
> unsigned NumSubRegIndices; // Number of subreg indices.
> - DenseMap<unsigned, int> L2DwarfRegs; // LLVM to Dwarf regs mapping
> - DenseMap<unsigned, int> EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH
> - DenseMap<unsigned, unsigned> Dwarf2LRegs; // Dwarf to LLVM regs mapping
> - DenseMap<unsigned, unsigned> EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH
> +
> + unsigned L2DwarfRegsSize;
> + unsigned EHL2DwarfRegsSize;
> + unsigned Dwarf2LRegsSize;
> + unsigned EHDwarf2LRegsSize;
> + const DwarfLLVMRegPair *L2DwarfRegs; // LLVM to Dwarf regs mapping
> + const DwarfLLVMRegPair *EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH
> + const DwarfLLVMRegPair *Dwarf2LRegs; // Dwarf to LLVM regs mapping
> + const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH
> DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping
>
> public:
> @@ -161,24 +176,32 @@
> NumSubRegIndices = NumIndices;
> }
>
> - /// mapLLVMRegToDwarfReg - Used to initialize LLVM register to Dwarf
> + /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf
> /// register number mapping. Called by TableGen auto-generated routines.
> /// *DO NOT USE*.
> - void mapLLVMRegToDwarfReg(unsigned LLVMReg, int DwarfReg, bool isEH) {
> - if (isEH)
> - EHL2DwarfRegs[LLVMReg] = DwarfReg;
> - else
> - L2DwarfRegs[LLVMReg] = DwarfReg;
> + void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size,
> + bool isEH) {
> + if (isEH) {
> + EHL2DwarfRegs = Map;
> + EHL2DwarfRegsSize = Size;
> + } else {
> + L2DwarfRegs = Map;
> + L2DwarfRegsSize = Size;
> + }
> }
>
> - /// mapDwarfRegToLLVMReg - Used to initialize Dwarf register to LLVM
> + /// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM
> /// register number mapping. Called by TableGen auto-generated routines.
> /// *DO NOT USE*.
> - void mapDwarfRegToLLVMReg(unsigned DwarfReg, unsigned LLVMReg, bool isEH) {
> - if (isEH)
> - EHDwarf2LRegs[DwarfReg] = LLVMReg;
> - else
> - Dwarf2LRegs[DwarfReg] = LLVMReg;
> + void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size,
> + bool isEH) {
> + if (isEH) {
> + EHDwarf2LRegs = Map;
> + EHDwarf2LRegsSize = Size;
> + } else {
> + Dwarf2LRegs = Map;
> + Dwarf2LRegsSize = Size;
> + }
> }
>
> /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register
> @@ -289,21 +312,24 @@
> /// parameter allows targets to use different numberings for EH info and
> /// debugging info.
> int getDwarfRegNum(unsigned RegNum, bool isEH) const {
> - const DenseMap<unsigned, int> &M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
> - const DenseMap<unsigned, int>::const_iterator I = M.find(RegNum);
> - if (I == M.end()) return -1;
> - return I->second;
> + const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
> + unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
> +
> + const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, RegNum);
> + if (I == M+Size || I->FromReg != RegNum)
> + return -1;
> + return I->ToReg;
> }
>
> /// getLLVMRegNum - Map a dwarf register back to a target register.
> ///
> int getLLVMRegNum(unsigned RegNum, bool isEH) const {
> - const DenseMap<unsigned, unsigned> &M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
> - const DenseMap<unsigned, unsigned>::const_iterator I = M.find(RegNum);
> - if (I == M.end()) {
> - llvm_unreachable("Invalid RegNum");
> - }
> - return I->second;
> + const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
> + unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;
> +
> + const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, RegNum);
> + assert(I != M+Size && I->FromReg == RegNum && "Invalid RegNum");
> + return I->ToReg;
> }
>
> /// getSEHRegNum - Map a target register to an equivalent SEH register
>
> Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=153837&r1=153836&r2=153837&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Sun Apr 1 09:23:58 2012
> @@ -118,11 +118,11 @@
> OS << "#endif // GET_REGINFO_ENUM\n\n";
> }
>
> -void
> -RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS,
> - const std::vector<CodeGenRegister*> &Regs,
> - bool isCtor) {
>
> +void
> +RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS,
> + const std::vector<CodeGenRegister*> &Regs,
> + bool isCtor) {
> // Collect all information about dwarf register numbers
> typedef std::map<Record*, std::vector<int64_t>, LessRecord> DwarfRegNumsMapTy;
> DwarfRegNumsMapTy DwarfRegNums;
> @@ -148,6 +148,121 @@
> for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
> I->second.push_back(-1);
>
> + std::string Namespace = Regs[0]->TheDef->getValueAsString("Namespace");
> +
> + OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n";
> +
> + // Emit reverse information about the dwarf register numbers.
> + for (unsigned j = 0; j < 2; ++j) {
> + for (unsigned i = 0, e = maxLength; i != e; ++i) {
> + OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
> + OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
> + OS << i << "Dwarf2L[]";
> +
> + if (!isCtor) {
> + OS << " = {\n";
> +
> + // Store the mapping sorted by the LLVM reg num so lookup can be done
> + // with a binary search.
> + std::map<uint64_t, Record*> Dwarf2LMap;
> + for (DwarfRegNumsMapTy::iterator
> + I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
> + int DwarfRegNo = I->second[i];
> + if (DwarfRegNo < 0)
> + continue;
> + Dwarf2LMap[DwarfRegNo] = I->first;
> + }
> +
> + for (std::map<uint64_t, Record*>::iterator
> + I = Dwarf2LMap.begin(), E = Dwarf2LMap.end(); I != E; ++I)
> + OS << " { " << I->first << "U, " << getQualifiedName(I->second)
> + << " },\n";
> +
> + OS << "};\n";
> + } else {
> + OS << ";\n";
> + }
> +
> + // We have to store the size in a const global, it's used in multiple
> + // places.
> + OS << "extern const unsigned " << Namespace
> + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "Dwarf2LSize";
> + if (!isCtor)
> + OS << " = sizeof(" << Namespace
> + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
> + << "Dwarf2L)/sizeof(MCRegisterInfo::DwarfLLVMRegPair);\n\n";
> + else
> + OS << ";\n\n";
> + }
> + }
> +
> + for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
> + Record *Reg = Regs[i]->TheDef;
> + const RecordVal *V = Reg->getValue("DwarfAlias");
> + if (!V || !V->getValue())
> + continue;
> +
> + DefInit *DI = dynamic_cast<DefInit*>(V->getValue());
> + Record *Alias = DI->getDef();
> + DwarfRegNums[Reg] = DwarfRegNums[Alias];
> + }
> +
> + // Emit information about the dwarf register numbers.
> + for (unsigned j = 0; j < 2; ++j) {
> + for (unsigned i = 0, e = maxLength; i != e; ++i) {
> + OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
> + OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
> + OS << i << "L2Dwarf[]";
> + if (!isCtor) {
> + OS << " = {\n";
> + // Store the mapping sorted by the Dwarf reg num so lookup can be done
> + // with a binary search.
> + for (DwarfRegNumsMapTy::iterator
> + I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
> + int RegNo = I->second[i];
> + if (RegNo == -1) // -1 is the default value, don't emit a mapping.
> + continue;
> +
> + OS << " { " << getQualifiedName(I->first) << ", " << RegNo
> + << "U },\n";
> + }
> + OS << "};\n";
> + } else {
> + OS << ";\n";
> + }
> +
> + // We have to store the size in a const global, it's used in multiple
> + // places.
> + OS << "extern const unsigned " << Namespace
> + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2DwarfSize";
> + if (!isCtor)
> + OS << " = sizeof(" << Namespace
> + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
> + << "L2Dwarf)/sizeof(MCRegisterInfo::DwarfLLVMRegPair);\n\n";
> + else
> + OS << ";\n\n";
> + }
> + }
> +}
> +
> +void
> +RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS,
> + const std::vector<CodeGenRegister*> &Regs,
> + bool isCtor) {
> + // Emit the initializer so the tables from EmitRegMappingTables get wired up
> + // to the MCRegisterInfo object.
> + unsigned maxLength = 0;
> + for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
> + Record *Reg = Regs[i]->TheDef;
> + maxLength = std::max((size_t)maxLength,
> + Reg->getValueAsListOfInts("DwarfNumbers").size());
> + }
> +
> + if (!maxLength)
> + return;
> +
> + std::string Namespace = Regs[0]->TheDef->getValueAsString("Namespace");
> +
> // Emit reverse information about the dwarf register numbers.
> for (unsigned j = 0; j < 2; ++j) {
> OS << " switch (";
> @@ -161,38 +276,24 @@
>
> for (unsigned i = 0, e = maxLength; i != e; ++i) {
> OS << " case " << i << ":\n";
> - for (DwarfRegNumsMapTy::iterator
> - I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
> - int DwarfRegNo = I->second[i];
> - if (DwarfRegNo < 0)
> - continue;
> - OS << " ";
> - if (!isCtor)
> - OS << "RI->";
> - OS << "mapDwarfRegToLLVMReg(" << DwarfRegNo << ", "
> - << getQualifiedName(I->first) << ", ";
> - if (j == 0)
> + OS << " ";
> + if (!isCtor)
> + OS << "RI->";
> + std::string Tmp;
> + raw_string_ostream(Tmp) << Namespace
> + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
> + << "Dwarf2L";
> + OS << "mapDwarfRegsToLLVMRegs(" << Tmp << ", " << Tmp << "Size, ";
> + if (j == 0)
> OS << "false";
> else
> OS << "true";
> - OS << " );\n";
> - }
> + OS << ");\n";
> OS << " break;\n";
> }
> OS << " }\n";
> }
>
> - for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
> - Record *Reg = Regs[i]->TheDef;
> - const RecordVal *V = Reg->getValue("DwarfAlias");
> - if (!V || !V->getValue())
> - continue;
> -
> - DefInit *DI = dynamic_cast<DefInit*>(V->getValue());
> - Record *Alias = DI->getDef();
> - DwarfRegNums[Reg] = DwarfRegNums[Alias];
> - }
> -
> // Emit information about the dwarf register numbers.
> for (unsigned j = 0; j < 2; ++j) {
> OS << " switch (";
> @@ -206,24 +307,19 @@
>
> for (unsigned i = 0, e = maxLength; i != e; ++i) {
> OS << " case " << i << ":\n";
> - // Sort by name to get a stable order.
> - for (DwarfRegNumsMapTy::iterator
> - I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
> - int RegNo = I->second[i];
> - if (RegNo == -1) // -1 is the default value, don't emit a mapping.
> - continue;
> -
> - OS << " ";
> - if (!isCtor)
> - OS << "RI->";
> - OS << "mapLLVMRegToDwarfReg(" << getQualifiedName(I->first) << ", "
> - << RegNo << ", ";
> - if (j == 0)
> + OS << " ";
> + if (!isCtor)
> + OS << "RI->";
> + std::string Tmp;
> + raw_string_ostream(Tmp) << Namespace
> + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
> + << "L2Dwarf";
> + OS << "mapLLVMRegsToDwarfRegs(" << Tmp << ", " << Tmp << "Size, ";
> + if (j == 0)
> OS << "false";
> else
> OS << "true";
> - OS << " );\n";
> - }
> + OS << ");\n";
> OS << " break;\n";
> }
> OS << " }\n";
> @@ -448,6 +544,8 @@
> << "SubRegTable;\n}\n\n";
> }
>
> + EmitRegMappingTables(OS, Regs, false);
> +
> // MCRegisterInfo initialization routine.
> OS << "static inline void Init" << TargetName
> << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
> @@ -872,6 +970,8 @@
> OS << "extern const uint16_t *get" << TargetName
> << "SubRegTable();\n";
>
> + EmitRegMappingTables(OS, Regs, true);
> +
> OS << ClassName << "::\n" << ClassName
> << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
> << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
>
> Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.h?rev=153837&r1=153836&r2=153837&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.h (original)
> +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.h Sun Apr 1 09:23:58 2012
> @@ -50,6 +50,9 @@
> private:
> void EmitRegMapping(raw_ostream &o,
> const std::vector<CodeGenRegister*> &Regs, bool isCtor);
> + void EmitRegMappingTables(raw_ostream &o,
> + const std::vector<CodeGenRegister*> &Regs,
> + bool isCtor);
> void EmitRegClasses(raw_ostream &OS, CodeGenTarget &Target);
> };
>
>
>
> _______________________________________________
> 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