Use an enumeration to eliminate data relocations.
authorJim Laskey <jlaskey@mac.com>
Fri, 21 Jul 2006 20:57:35 +0000 (20:57 +0000)
committerJim Laskey <jlaskey@mac.com>
Fri, 21 Jul 2006 20:57:35 +0000 (20:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29249 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/MRegisterInfo.h
include/llvm/Target/TargetInstrInfo.h
lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
utils/TableGen/InstrInfoEmitter.cpp
utils/TableGen/RegisterInfoEmitter.cpp

index 1ca560eab14f7977929b0a51b5a61194c28ab42b..7b28d5eeb63c7205e2048b056e12105a03563c33 100644 (file)
@@ -49,6 +49,7 @@ public:
   typedef const MVT::ValueType* vt_iterator;
   typedef const TargetRegisterClass* const * sc_iterator;
 private:
+  unsigned ID;
   bool  isSubClass;
   const vt_iterator VTs;
   const sc_iterator SubClasses;
@@ -56,14 +57,18 @@ private:
   const unsigned RegSize, Alignment;    // Size & Alignment of register in bytes
   const iterator RegsBegin, RegsEnd;
 public:
-  TargetRegisterClass(const MVT::ValueType *vts,
+  TargetRegisterClass(unsigned id,
+                      const MVT::ValueType *vts,
                       const TargetRegisterClass * const *subcs,
                       const TargetRegisterClass * const *supcs,
                       unsigned RS, unsigned Al, iterator RB, iterator RE)
-    : VTs(vts), SubClasses(subcs), SuperClasses(supcs),
+    : ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs),
     RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
   virtual ~TargetRegisterClass() {}     // Allow subclasses
-
+  
+  // getID() - Return the register class ID number.
+  unsigned getID() const { return ID; }
+  
   // begin/end - Return all of the registers in this class.
   iterator       begin() const { return RegsBegin; }
   iterator         end() const { return RegsEnd; }
@@ -300,6 +305,13 @@ public:
   unsigned getNumRegClasses() const {
     return regclass_end()-regclass_begin();
   }
+  
+  /// getRegClass - Returns the register class associated with the enumeration
+  /// value.  See class TargetOperandInfo.
+  const TargetRegisterClass *getRegClass(unsigned i) const {
+    assert(i <= getNumRegClasses() && "Register Class ID out of range");
+    return i ? RegClassBegin[i - 1] : NULL;
+  }
 
   //===--------------------------------------------------------------------===//
   // Interfaces used by the register allocator and stack frame
index ae271d2f6cdecaa977896aae458fce9ca24ae685..905384eaa77e3df2a604f2952f8296da30443ce7 100644 (file)
@@ -90,10 +90,10 @@ const unsigned M_LOOK_UP_PTR_REG_CLASS = 1 << 0;
 ///
 class TargetOperandInfo {
 public:
-  /// RegClass - This specifies the register class of the operand if the
-  /// operand is a register.  If not, this contains null.
-  const TargetRegisterClass *RegClass;
-  unsigned Flags;
+  /// RegClass - This specifies the register class enumeration of the operand 
+  /// if the operand is a register.  If not, this contains 0.
+  unsigned short RegClass;
+  unsigned short Flags;
   /// Currently no other information.
 };
 
@@ -146,17 +146,6 @@ public:
     return get(Opcode).Name;
   }
 
-  const TargetRegisterClass
-  *getInstrOperandRegClass(const TargetInstrDescriptor *II, unsigned Op) const {
-    if (Op >= II->numOperands) {
-      assert((II->Flags & M_VARIABLE_OPS)&& "Invalid operand # of instruction");
-      return NULL;
-    }
-    const TargetOperandInfo &toi = II->OpInfo[Op];
-    return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS)
-           ? getPointerRegClass() : toi.RegClass;
-  }
-
   int getNumOperands(MachineOpCode Opcode) const {
     return get(Opcode).numOperands;
   }
index 186b041b586d98768b386404a80668b0e1e34cb0..97eccb2b95923960d14da374d0374f156c53a846 100644 (file)
@@ -226,7 +226,22 @@ static unsigned CountOperands(SDNode *Node) {
   return N;
 }
 
-static unsigned CreateVirtualRegisters(MachineInstr *MI,
+static const TargetRegisterClass *getInstrOperandRegClass(
+        const MRegisterInfo *MRI, 
+        const TargetInstrInfo *TII,
+        const TargetInstrDescriptor *II,
+        unsigned Op) {
+  if (Op >= II->numOperands) {
+    assert((II->Flags & M_VARIABLE_OPS)&& "Invalid operand # of instruction");
+    return NULL;
+  }
+  const TargetOperandInfo &toi = II->OpInfo[Op];
+  return (toi.Flags & M_LOOK_UP_PTR_REG_CLASS)
+         ? TII->getPointerRegClass() : MRI->getRegClass(toi.RegClass);
+}
+
+static unsigned CreateVirtualRegisters(const MRegisterInfo *MRI,
+                                       MachineInstr *MI,
                                        unsigned NumResults,
                                        SSARegMap *RegMap,
                                        const TargetInstrInfo *TII,
@@ -234,10 +249,10 @@ static unsigned CreateVirtualRegisters(MachineInstr *MI,
   // Create the result registers for this node and add the result regs to
   // the machine instruction.
   unsigned ResultReg =
-    RegMap->createVirtualRegister(TII->getInstrOperandRegClass(&II, 0));
+    RegMap->createVirtualRegister(getInstrOperandRegClass(MRI, TII, &II, 0));
   MI->addRegOperand(ResultReg, MachineOperand::Def);
   for (unsigned i = 1; i != NumResults; ++i) {
-    const TargetRegisterClass *RC = TII->getInstrOperandRegClass(&II, i);
+    const TargetRegisterClass *RC = getInstrOperandRegClass(MRI, TII, &II, i);
     assert(RC && "Isn't a register operand!");
     MI->addRegOperand(RegMap->createVirtualRegister(RC), MachineOperand::Def);
   }
@@ -276,7 +291,8 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
     // Verify that it is right.
     assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
     if (II) {
-      const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum);
+      const TargetRegisterClass *RC =
+                          getInstrOperandRegClass(MRI, TII, II, IIOpNum);
       assert(RC && "Don't have operand info for this instruction!");
       assert(RegMap->getRegClass(VReg) == RC &&
              "Register class of operand and regclass of use don't agree!");
@@ -333,7 +349,8 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
     // Verify that it is right.
     assert(MRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?");
     if (II) {
-      const TargetRegisterClass *RC = TII->getInstrOperandRegClass(II, IIOpNum);
+      const TargetRegisterClass *RC =
+                            getInstrOperandRegClass(MRI, TII, II, IIOpNum);
       assert(RC && "Don't have operand info for this instruction!");
       assert(RegMap->getRegClass(VReg) == RC &&
              "Register class of operand and regclass of use don't agree!");
@@ -389,7 +406,7 @@ void ScheduleDAG::EmitNode(SDNode *Node,
     
     // Otherwise, create new virtual registers.
     if (NumResults && VRBase == 0)
-      VRBase = CreateVirtualRegisters(MI, NumResults, RegMap, TII, II);
+      VRBase = CreateVirtualRegisters(MRI, MI, NumResults, RegMap, TII, II);
     
     // Emit all of the actual operands of this instruction, adding them to the
     // instruction as appropriate.
index b6c2d352b358c928becb6f7789882fe068d57843..3718e64d9ce7c5013f15a50738c14dd1b8f28860 100644 (file)
@@ -152,7 +152,7 @@ static const TargetRegisterClass *getRegClass(SUnit *SU,
   if (SU->Node->isTargetOpcode()) {
     unsigned Opc = SU->Node->getTargetOpcode();
     const TargetInstrDescriptor &II = TII->get(Opc);
-    return II.OpInfo->RegClass;
+    return MRI->getRegClass(II.OpInfo->RegClass);
   } else {
     assert(SU->Node->getOpcode() == ISD::CopyFromReg);
     unsigned SrcReg = cast<RegisterSDNode>(SU->Node->getOperand(1))->getReg();
index f91babcf860bccc03baea8e0a5af9ee6acacc109..de93792556f9a2be40c3d0a777ac1e233971cd4d 100644 (file)
@@ -137,7 +137,7 @@ void InstrInfoEmitter::run(std::ostream &OS) {
         Record *RC = OperandInfo[i];
         // FIXME: We only care about register operands for now.
         if (RC && RC->isSubClassOf("RegisterClass"))
-          OS << "{ &" << getQualifiedName(RC) << "RegClass, 0 }, ";
+          OS << "{ " << getQualifiedName(RC) << "RegClassID, 0 }, ";
         else if (RC && RC->getName() == "ptr_rc")
           // Ptr value whose register class is resolved via callback.
           OS << "{ 0, 1 }, ";
index e572544075da3dd9a3b2aa5ae6ae8b84aa212f31..11107f212b99db68ddb8e1424cf45923df911eea 100644 (file)
@@ -68,6 +68,15 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) {
   if (!RegisterClasses.empty()) {
     OS << "namespace " << RegisterClasses[0].Namespace
        << " { // Register classes\n";
+       
+    OS << "  enum {\n";
+    for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
+      if (i) OS << ",\n";
+      OS << "    " << RegisterClasses[i].getName() << "RegClassID";
+      if (!i) OS << " = 1";
+    }
+    OS << "\n  };\n\n";
+
     for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
       const std::string &Name = RegisterClasses[i].getName();
 
@@ -165,7 +174,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
     for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i)
       OS << "  " << RegisterClasses[i].getName()  << "Class\t"
          << RegisterClasses[i].getName() << "RegClass;\n";
-
+         
     std::map<unsigned, std::set<unsigned> > SuperClassMap;
     OS << "\n";
     // Emit the sub-classes array for each RegisterClass
@@ -244,6 +253,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
       OS << RC.MethodBodies << "\n";
       OS << RC.getName() << "Class::" << RC.getName() 
          << "Class()  : TargetRegisterClass("
+         << RC.getName() + "RegClassID" << ", "
          << RC.getName() + "VTs" << ", "
          << RC.getName() + "Subclasses" << ", "
          << RC.getName() + "Superclasses" << ", "