From: Chris Lattner Date: Wed, 29 Jul 2009 21:10:12 +0000 (+0000) Subject: 1. Introduce a new TargetOperandInfo::getRegClass() helper method X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=cb778a8634454c70d88955b3732f330a6cbe5b07 1. Introduce a new TargetOperandInfo::getRegClass() helper method and convert code to using it, instead of having lots of things poke the isLookupPtrRegClass() method directly. 2. Make PointerLikeRegClass contain a 'kind' int, and store it in the existing regclass field of TargetOperandInfo when the isLookupPtrRegClass() predicate is set. Make getRegClass pass this into TargetRegisterInfo::getPointerRegClass(), allowing targets to have multiple ptr_rc things. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77504 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index a62036a5203..1532dba466f 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -263,8 +263,8 @@ def variable_ops; /// derived from this. TableGen treats the register class as having a symbolic /// type that it doesn't know, and resolves the actual regclass to use by using /// the TargetRegisterInfo::getPointerRegClass() hook at codegen time. -class PointerLikeRegClass { - +class PointerLikeRegClass { + int RegClassKind = Kind; } @@ -272,7 +272,7 @@ class PointerLikeRegClass { /// register class is resolved dynamically via a callback to TargetInstrInfo. /// FIXME: We should probably change this to a class which contain a list of /// flags. But currently we have but one flag. -def ptr_rc : PointerLikeRegClass; +def ptr_rc : PointerLikeRegClass<0>; /// unknown definition - Mark this operand as being of unknown type, causing /// it to be resolved by inference in the context it is used. diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h index 622a216c33c..431e6e8b063 100644 --- a/include/llvm/Target/TargetInstrDesc.h +++ b/include/llvm/Target/TargetInstrDesc.h @@ -18,7 +18,8 @@ namespace llvm { class TargetRegisterClass; - +class TargetRegisterInfo; + //===----------------------------------------------------------------------===// // Machine Operand Flags and Description //===----------------------------------------------------------------------===// @@ -45,14 +46,28 @@ namespace TOI { class TargetOperandInfo { public: /// RegClass - This specifies the register class enumeration of the operand - /// if the operand is a register. If not, this contains 0. + /// if the operand is a register. If isLookupPtrRegClass is set, then this is + /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to + /// get a dynamic register class. + /// + /// NOTE: This member should be considered to be private, all access should go + /// through "getRegClass(TRI)" below. unsigned short RegClass; + + /// Flags - These are flags from the TOI::OperandFlags enum. unsigned short Flags; + /// Lower 16 bits are used to specify which constraints are set. The higher 16 /// bits are used to specify the value of constraints (4 bits each). - unsigned int Constraints; + unsigned Constraints; /// Currently no other information. + /// getRegClass - Get the register class for the operand, handling resolution + /// of "symbolic" pointer register classes etc. If this is not a register + /// operand, this returns null. + const TargetRegisterClass *getRegClass(const TargetRegisterInfo *TRI) const; + + /// isLookupPtrRegClass - Set if this operand is a pointer value and it /// requires a callback to look up its register class. bool isLookupPtrRegClass() const { return Flags&(1 <getRegClass(TOI.RegClass); + if (const TargetRegisterClass *DRC = TOI.getRegClass(TRI)) { if (!DRC->contains(sr)) { report("Illegal physical register for instruction", MO, MONum); *OS << TRI->getName(sr) << " is not a " @@ -426,8 +425,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) } RC = *(RC->subregclasses_begin()+SubIdx); } - if (TOI.RegClass) { - const TargetRegisterClass *DRC = TRI->getRegClass(TOI.RegClass); + if (const TargetRegisterClass *DRC = TOI.getRegClass(TRI)) { if (RC != DRC && !RC->hasSuperClass(DRC)) { report("Illegal virtual register for instruction", MO, MONum); *OS << "Expected a " << DRC->getName() << " register, but got a " diff --git a/lib/Target/TargetInstrInfo.cpp b/lib/Target/TargetInstrInfo.cpp index ceaea0c2027..afbadbfc63e 100644 --- a/lib/Target/TargetInstrInfo.cpp +++ b/lib/Target/TargetInstrInfo.cpp @@ -37,14 +37,23 @@ bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { return !isPredicated(MI); } +/// getRegClass - Get the register class for the operand, handling resolution +/// of "symbolic" pointer register classes etc. If this is not a register +/// operand, this returns null. +const TargetRegisterClass * +TargetOperandInfo::getRegClass(const TargetRegisterInfo *TRI) const { + if (isLookupPtrRegClass()) + return TRI->getPointerRegClass(RegClass); + return TRI->getRegClass(RegClass); +} + /// getInstrOperandRegClass - Return register class of the operand of an /// instruction of the specified TargetInstrDesc. const TargetRegisterClass* llvm::getInstrOperandRegClass(const TargetRegisterInfo *TRI, - const TargetInstrDesc &II, unsigned Op) { + const TargetInstrDesc &II, unsigned Op) { + // FIXME: Should be an assert! if (Op >= II.getNumOperands()) return NULL; - if (II.OpInfo[Op].isLookupPtrRegClass()) - return TRI->getPointerRegClass(); - return TRI->getRegClass(II.OpInfo[Op].RegClass); + return II.OpInfo[Op].getRegClass(TRI); } diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index e3da39a4d07..4b293050864 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -2381,8 +2381,7 @@ bool X86InstrInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, const TargetInstrDesc &TID = get(Opc); const TargetOperandInfo &TOI = TID.OpInfo[Index]; - const TargetRegisterClass *RC = TOI.isLookupPtrRegClass() - ? RI.getPointerRegClass() : RI.getRegClass(TOI.RegClass); + const TargetRegisterClass *RC = TOI.getRegClass(&RI); SmallVector AddrOps; SmallVector BeforeOps; SmallVector AfterOps; @@ -2460,9 +2459,7 @@ bool X86InstrInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, // Emit the store instruction. if (UnfoldStore) { - const TargetOperandInfo &DstTOI = TID.OpInfo[0]; - const TargetRegisterClass *DstRC = DstTOI.isLookupPtrRegClass() - ? RI.getPointerRegClass() : RI.getRegClass(DstTOI.RegClass); + const TargetRegisterClass *DstRC = TID.OpInfo[0].getRegClass(&RI); storeRegToAddr(MF, Reg, true, AddrOps, DstRC, NewMIs); } @@ -2484,9 +2481,7 @@ X86InstrInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, bool FoldedLoad = I->second.second & (1 << 4); bool FoldedStore = I->second.second & (1 << 5); const TargetInstrDesc &TID = get(Opc); - const TargetOperandInfo &TOI = TID.OpInfo[Index]; - const TargetRegisterClass *RC = TOI.isLookupPtrRegClass() - ? RI.getPointerRegClass() : RI.getRegClass(TOI.RegClass); + const TargetRegisterClass *RC = TID.OpInfo[Index].getRegClass(&RI); unsigned NumDefs = TID.NumDefs; std::vector AddrOps; std::vector BeforeOps; @@ -2521,9 +2516,7 @@ X86InstrInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, std::vector VTs; const TargetRegisterClass *DstRC = 0; if (TID.getNumDefs() > 0) { - const TargetOperandInfo &DstTOI = TID.OpInfo[0]; - DstRC = DstTOI.isLookupPtrRegClass() - ? RI.getPointerRegClass() : RI.getRegClass(DstTOI.RegClass); + DstRC = TID.OpInfo[0].getRegClass(&RI); VTs.push_back(*DstRC->vt_begin()); } for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index c0e441cc48b..ef52c07692a 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -94,8 +94,11 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { if (OpR->isSubClassOf("RegisterClass")) Res += getQualifiedName(OpR) + "RegClassID, "; + else if (OpR->isSubClassOf("PointerLikeRegClass")) + Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; else Res += "0, "; + // Fill in applicable flags. Res += "0";