From 46dcb57e18884099ca6ad2aebb81fd7e1513c1f6 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 19 Jul 2010 18:47:01 +0000 Subject: [PATCH] Teach computeRegisterProperties() to compute "representative" register class for legal value types. A "representative" register class is the largest legal super-reg register class for a value type. e.g. On i386, GR32 is the rep register class for i8 / i16 / i32; on x86_64 it would be GR64. 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 | 32 +++++++++++++ lib/CodeGen/SelectionDAG/TargetLowering.cpp | 52 +++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 2b6e4fa8526..67ecb722198 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -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, diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index fb3f7c07d0c..5c09db28607 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -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 {