Teach computeRegisterProperties() to compute "representative" register class for...
authorEvan Cheng <evan.cheng@apple.com>
Mon, 19 Jul 2010 18:47:01 +0000 (18:47 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 19 Jul 2010 18:47:01 +0000 (18:47 +0000)
This property will be used by the register pressure tracking instruction scheduler.

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

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/TargetLowering.cpp

index 2b6e4fa8526d54ae21bf3e28931f9a3ff9240885..67ecb722198a6b6ee661a0b15b4cdb94decf1518 100644 (file)
@@ -168,6 +168,18 @@ public:
     return RC;
   }
 
+  /// getRepRegClassFor - Return the 'representative' register class for the
+  /// specified value type. The 'representative' register class is the largest
+  /// legal super-reg register class for the register class of the value type.
+  /// For example, on i386 the rep register class for i8, i16, and i32 are GR32;
+  /// while the rep register class is GR64 on x86_64.
+  virtual const TargetRegisterClass *getRepRegClassFor(EVT VT) const {
+    assert(VT.isSimple() && "getRegClassFor called on illegal type!");
+    const TargetRegisterClass *RC = RepRegClassForVT[VT.getSimpleVT().SimpleTy];
+    assert(RC && "This value type is not natively supported!");
+    return RC;
+  }
+
   /// isTypeLegal - Return true if the target has native support for the
   /// specified value type.  This means that it has a register that directly
   /// holds it without promotions or expansions.
@@ -1562,6 +1574,12 @@ private:
   unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
   EVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
 
+  /// RepRegClassForVT - This indicates the "representative" register class to
+  /// use for each ValueType the target supports natively. This information is
+  /// used by the scheduler to track register pressure. e.g. On x86, i8, i16,
+  /// and i32's representative class would be GR32.
+  const TargetRegisterClass *RepRegClassForVT[MVT::LAST_VALUETYPE];
+
   /// Synthesizable indicates whether it is OK for the compiler to create new
   /// operations using this type.  All Legal types are Synthesizable except
   /// MMX types on X86.  Non-Legal types are not Synthesizable.
@@ -1672,6 +1690,20 @@ protected:
   /// This field specifies whether the target can benefit from code placement
   /// optimization.
   bool benefitFromCodePlacementOpt;
+
+private:
+  /// isLegalRC - Return true if the value types that can be represented by the
+  /// specified register class are all legal.
+  bool isLegalRC(const TargetRegisterClass *RC) const;
+
+  /// hasLegalSuperRegRegClasses - Return true if the specified register class
+  /// has one or more super-reg register classes that are legal.
+  bool hasLegalSuperRegRegClasses(const TargetRegisterClass *RC);
+
+  /// findRepresentativeClass - Return the largest legal super-reg register class
+  /// of the specified register class.
+  const TargetRegisterClass *
+  findRepresentativeClass(const TargetRegisterClass *RC);
 };
 
 /// GetReturnInfo - Given an LLVM IR type and return type attributes,
index fb3f7c07d0c4c435a447de2aa75dad41681cf2a1..5c09db28607341259474715e8833346c735e035d 100644 (file)
@@ -651,6 +651,50 @@ static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
   return NumVectorRegs;
 }
 
+/// isLegalRC - Return true if the value types that can be represented by the
+/// specified register class are all legal.
+bool TargetLowering::isLegalRC(const TargetRegisterClass *RC) const {
+  for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end();
+       I != E; ++I) {
+    if (isTypeLegal(*I))
+      return true;
+  }
+  return false;
+}
+
+/// hasLegalSuperRegRegClasses - Return true if the specified register class
+/// has one or more super-reg register classes that are legal.
+bool TargetLowering::hasLegalSuperRegRegClasses(const TargetRegisterClass *RC) {
+  if (*RC->superregclasses_begin() == 0)
+    return false;
+  for (TargetRegisterInfo::regclass_iterator I = RC->superregclasses_begin(),
+         E = RC->superregclasses_end(); I != E; ++I) {
+    const TargetRegisterClass *RRC = *I;
+    if (isLegalRC(RRC))
+      return true;
+  }
+  return false;
+}
+
+/// findRepresentativeClass - Return the largest legal super-reg register class
+/// of the specified register class.
+const TargetRegisterClass *
+TargetLowering::findRepresentativeClass(const TargetRegisterClass *RC) {
+  if (!RC) return 0;
+
+  const TargetRegisterClass *BestRC = RC;
+  for (TargetRegisterInfo::regclass_iterator I = RC->superregclasses_begin(),
+         E = RC->superregclasses_end(); I != E; ++I) {
+    const TargetRegisterClass *RRC = *I;
+    if (RRC->isASubClass() || !isLegalRC(RRC))
+      continue;
+    if (!hasLegalSuperRegRegClasses(RRC))
+      return RRC;
+    BestRC = RRC;
+  }
+  return BestRC;
+}
+
 /// computeRegisterProperties - Once all of the register classes are added,
 /// this allows us to compute derived properties we expose.
 void TargetLowering::computeRegisterProperties() {
@@ -770,6 +814,14 @@ void TargetLowering::computeRegisterProperties() {
       }
     }
   }
+
+  // Determine the 'representative' register class for each value type.
+  // An representative register class is the largest (meaning one which is
+  // not a sub-register class / subreg register class) legal register class for
+  // a group of value types. For example, on i386, i8, i16, and i32
+  // representative would be GR32; while on x86_64 it's GR64.
+  for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i)
+    RepRegClassForVT[i] = findRepresentativeClass(RegClassForVT[i]);
 }
 
 const char *TargetLowering::getTargetNodeName(unsigned Opcode) const {