[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