When emitting implicit use/def lists, only emit each unique list once. Though
authorChris Lattner <sabre@nondot.org>
Thu, 18 Aug 2005 21:36:47 +0000 (21:36 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 18 Aug 2005 21:36:47 +0000 (21:36 +0000)
LLVM is able to merge identical static const globals, GCC isn't, and this caused
some bloat in the generated data.  This has a marginal effect on PPC, shrinking
the implicit sets from 10->4, but shrinks X86 from 179 to 23, a much bigger
reduction.

This should speed up the register allocator as well by reducing the dcache
footprint for this static data.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22879 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/InstrInfoEmitter.cpp
utils/TableGen/InstrInfoEmitter.h

index 2b2a81c1f34e836c3bfa86d767633121d468860b..7dc13bc9ce262b4c7fb4ea2ed6d5528fc87e1fdf 100644 (file)
@@ -46,14 +46,21 @@ void InstrInfoEmitter::runEnums(std::ostream &OS) {
   OS << "} // End llvm namespace \n";
 }
 
-void InstrInfoEmitter::printDefList(ListInit *LI, const std::string &Name,
-                                    std::ostream &OS) const {
-  OS << "static const unsigned " << Name << "[] = { ";
-  for (unsigned j = 0, e = LI->getSize(); j != e; ++j)
-    if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(j)))
-      OS << getQualifiedName(DI->getDef()) << ", ";
+static std::vector<Record*> GetDefList(ListInit *LI, const std::string &Name) {
+  std::vector<Record*> Result;
+  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
+    if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i)))
+      Result.push_back(DI->getDef());
     else
       throw "Illegal value in '" + Name + "' list!";
+  return Result;
+}
+
+void InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses,
+                                    unsigned Num, std::ostream &OS) const {
+  OS << "static const unsigned ImplicitList" << Num << "[] = { ";
+  for (unsigned i = 0, e = Uses.size(); i != e; ++i)
+    OS << getQualifiedName(Uses[i]) << ", ";
   OS << "0 };\n";
 }
 
@@ -69,34 +76,50 @@ void InstrInfoEmitter::run(std::ostream &OS) {
   Record *PHI = InstrInfo->getValueAsDef("PHIInst");
 
   // Emit empty implicit uses and defs lists
-  OS << "static const unsigned EmptyImpUses[] = { 0 };\n"
-     << "static const unsigned EmptyImpDefs[] = { 0 };\n";
-
-  // Emit all of the instruction's implicit uses and defs...
+  OS << "static const unsigned EmptyImpList[] = { 0 };\n";
+
+  // Keep track of all of the def lists we have emitted already.
+  std::map<std::vector<Record*>, unsigned> EmittedLists;
+  std::map<ListInit*, unsigned> ListNumbers;
+  unsigned ListNumber = 0;
+  // Emit all of the instruction's implicit uses and defs.
   for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
          E = Target.inst_end(); II != E; ++II) {
     Record *Inst = II->second.TheDef;
     ListInit *LI = Inst->getValueAsListInit("Uses");
-    if (LI->getSize()) printDefList(LI, Inst->getName()+"ImpUses", OS);
+    if (LI->getSize()) {
+      std::vector<Record*> Uses = GetDefList(LI, Inst->getName());
+      unsigned &IL = EmittedLists[Uses];
+      if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
+      ListNumbers[LI] = IL;
+    }
     LI = Inst->getValueAsListInit("Defs");
-    if (LI->getSize()) printDefList(LI, Inst->getName()+"ImpDefs", OS);
+    if (LI->getSize()) {
+      std::vector<Record*> Uses = GetDefList(LI, Inst->getName());
+      unsigned &IL = EmittedLists[Uses];
+      if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
+      ListNumbers[LI] = IL;
+    }
   }
 
   OS << "\nstatic const TargetInstrDescriptor " << TargetName
      << "Insts[] = {\n";
-  emitRecord(Target.getPHIInstruction(), 0, InstrInfo, OS);
+  emitRecord(Target.getPHIInstruction(), 0, InstrInfo, ListNumbers, OS);
 
   unsigned i = 0;
   for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
          E = Target.inst_end(); II != E; ++II)
     if (II->second.TheDef != PHI)
-      emitRecord(II->second, ++i, InstrInfo, OS);
+      emitRecord(II->second, ++i, InstrInfo, ListNumbers, OS);
   OS << "};\n";
   OS << "} // End llvm namespace \n";
 }
 
 void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
-                                  Record *InstrInfo, std::ostream &OS) {
+                                  Record *InstrInfo,
+                                  std::map<ListInit*, unsigned> &ListNumbers,
+                                  std::ostream &OS) {
   OS << "  { \"";
   if (Inst.Name.empty())
     OS << Inst.TheDef->getName();
@@ -134,15 +157,15 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
   // Emit the implicit uses and defs lists...
   LI = Inst.TheDef->getValueAsListInit("Uses");
   if (!LI->getSize())
-    OS << "EmptyImpUses, ";
+    OS << "EmptyImpList, ";
   else
-    OS << Inst.TheDef->getName() << "ImpUses, ";
+    OS << "ImplicitList" << ListNumbers[LI] << ", ";
 
   LI = Inst.TheDef->getValueAsListInit("Defs");
   if (!LI->getSize())
-    OS << "EmptyImpDefs ";
+    OS << "EmptyImpList ";
   else
-    OS << Inst.TheDef->getName() << "ImpDefs ";
+    OS << "ImplicitList" << ListNumbers[LI] << " ";
 
   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
 }
index 005fd3810b4ca2886ac8d282dd4edc5cf865f63e..8b516f1978b1bafad31370480f18b4ec85a33e53 100644 (file)
@@ -16,6 +16,8 @@
 #define INSTRINFO_EMITTER_H
 
 #include "TableGenBackend.h"
+#include <vector>
+#include <map>
 
 namespace llvm {
 
@@ -35,10 +37,12 @@ public:
   // runEnums - Print out enum values for all of the instructions.
   void runEnums(std::ostream &OS);
 private:
-  void printDefList(ListInit *LI, const std::string &Name,
+  void printDefList(const std::vector<Record*> &Uses, unsigned Num,
                     std::ostream &OS) const;
   void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
-                  Record *InstrInfo, std::ostream &OS);
+                  Record *InstrInfo, 
+                  std::map<ListInit*, unsigned> &ListNumbers,
+                  std::ostream &OS);
   void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift,
                         std::ostream &OS);
 };