[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:23:58 PDT 2012


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.

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);
 };
 





More information about the llvm-commits mailing list