From dac67649f271cc085f61d450c649a3ca271c8828 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Wed, 20 Aug 2014 21:51:26 +0000 Subject: [PATCH] Add isExtractSubreg property. This patch adds a new property: isExtractSubreg and the related target hooks: TargetIntrInfo::getExtractSubregInputs and TargetInstrInfo::getExtractSubregLikeInputs to specify that a target specific instruction is a (kind of) EXTRACT_SUBREG. The approach is similar to r215394. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216130 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineInstr.h | 15 +++++++++++++ include/llvm/MC/MCInstrDesc.h | 18 ++++++++++++++- include/llvm/Target/Target.td | 3 +++ include/llvm/Target/TargetInstrInfo.h | 32 +++++++++++++++++++++++++++ lib/CodeGen/TargetInstrInfo.cpp | 23 +++++++++++++++++++ utils/TableGen/CodeGenInstruction.cpp | 1 + utils/TableGen/CodeGenInstruction.h | 1 + utils/TableGen/InstrInfoEmitter.cpp | 1 + 8 files changed, 93 insertions(+), 1 deletion(-) diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index b71b8bbf1b3..896e2630a4f 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -524,6 +524,21 @@ public: return hasProperty(MCID::RegSequence, Type); } + /// \brief Return true if this instruction behaves + /// the same way as the generic EXTRACT_SUBREG instructions. + /// E.g., on ARM, + /// rX, rY VMOVRRD dZ + /// is equivalent to two EXTRACT_SUBREG: + /// rX = EXTRACT_SUBREG dZ, ssub_0 + /// rY = EXTRACT_SUBREG dZ, ssub_1 + /// + /// Note that for the optimizers to be able to take advantage of + /// this property, TargetInstrInfo::getExtractSubregLikeInputs has to be + /// override accordingly. + bool isExtractSubregLike(QueryType Type = IgnoreBundle) const { + return hasProperty(MCID::ExtractSubreg, Type); + } + //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 72bf3ef0574..03b74256850 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -126,7 +126,8 @@ namespace MCID { CheapAsAMove, ExtraSrcRegAllocReq, ExtraDefRegAllocReq, - RegSequence + RegSequence, + ExtractSubreg }; } @@ -370,6 +371,21 @@ public: /// override accordingly. bool isRegSequenceLike() const { return Flags & (1 << MCID::RegSequence); } + /// \brief Return true if this instruction behaves + /// the same way as the generic EXTRACT_SUBREG instructions. + /// E.g., on ARM, + /// rX, rY VMOVRRD dZ + /// is equivalent to two EXTRACT_SUBREG: + /// rX = EXTRACT_SUBREG dZ, ssub_0 + /// rY = EXTRACT_SUBREG dZ, ssub_1 + /// + /// Note that for the optimizers to be able to take advantage of + /// this property, TargetInstrInfo::getExtractSubregLikeInputs has to be + /// override accordingly. + bool isExtractSubregLike() const { + return Flags & (1 << MCID::ExtractSubreg); + } + //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 5527e268e77..e7658329a14 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -384,6 +384,9 @@ class Instruction { bit isPseudo = 0; // Is this instruction a pseudo-instruction? // If so, won't have encoding information for // the [MC]CodeEmitter stuff. + bit isExtractSubreg = 0; // Is this instruction a kind of extract subreg? + // If so, make sure to override + // TargetInstrInfo::getExtractSubregInputs. // Side effect flags - When set, the flags have these meanings: // diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 2442c275bc7..505cb2b052e 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -303,6 +303,24 @@ public: getRegSequenceInputs(const MachineInstr &MI, unsigned DefIdx, SmallVectorImpl &InputRegs) const; + /// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI + /// and \p DefIdx. + /// \p [out] InputReg of the equivalent EXTRACT_SUBREG. + /// E.g., EXTRACT_SUBREG vreg1:sub1, sub0, sub1 would produce: + /// - vreg1:sub1, sub0 + /// + /// \returns true if it is possible to build such an input sequence + /// with the pair \p MI, \p DefIdx. False otherwise. + /// + /// \pre MI.isExtractSubreg() or MI.isExtractSubregLike(). + /// + /// \note The generic implementation does not provide any support for + /// MI.isExtractSubregLike(). In other words, one has to override + /// getExtractSubregLikeInputs for target specific instructions. + bool + getExtractSubregInputs(const MachineInstr &MI, unsigned DefIdx, + RegSubRegPairAndIdx &InputReg) const; + /// produceSameValue - Return true if two machine instructions would produce /// identical values. By default, this is only true when the two instructions /// are deemed identical except for defs. If this function is called when the @@ -685,6 +703,20 @@ protected: return false; } + /// \brief Target-dependent implementation of getExtractSubregInputs. + /// + /// \returns true if it is possible to build the equivalent + /// EXTRACT_SUBREG inputs with the pair \p MI, \p DefIdx. False otherwise. + /// + /// \pre MI.isExtractSubregLike(). + /// + /// \see TargetInstrInfo::getExtractSubregInputs. + virtual bool getExtractSubregLikeInputs( + const MachineInstr &MI, unsigned DefIdx, + RegSubRegPairAndIdx &InputReg) const { + return false; + } + public: /// canFoldMemoryOperand - Returns true for the specified load / store if /// folding is possible. diff --git a/lib/CodeGen/TargetInstrInfo.cpp b/lib/CodeGen/TargetInstrInfo.cpp index 44fbc4bb631..a177b3d71e0 100644 --- a/lib/CodeGen/TargetInstrInfo.cpp +++ b/lib/CodeGen/TargetInstrInfo.cpp @@ -877,3 +877,26 @@ bool TargetInstrInfo::getRegSequenceInputs( } return true; } + +bool TargetInstrInfo::getExtractSubregInputs( + const MachineInstr &MI, unsigned DefIdx, + RegSubRegPairAndIdx &InputReg) const { + assert((MI.isExtractSubreg() || + MI.isExtractSubregLike()) && "Instruction do not have the proper type"); + + if (!MI.isExtractSubreg()) + return getExtractSubregLikeInputs(MI, DefIdx, InputReg); + + // We are looking at: + // Def = EXTRACT_SUBREG v0.sub1, sub0. + assert(DefIdx == 0 && "EXTRACT_SUBREG only has one def"); + const MachineOperand &MOReg = MI.getOperand(1); + const MachineOperand &MOSubIdx = MI.getOperand(2); + assert(MOSubIdx.isImm() && + "The subindex of the extract_subreg is not an immediate"); + + InputReg.Reg = MOReg.getReg(); + InputReg.SubReg = MOReg.getSubReg(); + InputReg.SubIdx = (unsigned)MOSubIdx.getImm(); + return true; +} diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 179858d7632..20edef5a71c 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -315,6 +315,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) hasCtrlDep = R->getValueAsBit("hasCtrlDep"); isNotDuplicable = R->getValueAsBit("isNotDuplicable"); isRegSequence = R->getValueAsBit("isRegSequence"); + isExtractSubreg = R->getValueAsBit("isExtractSubreg"); bool Unset; mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset); diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index e0a9044dbfa..649fbc29ce7 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -254,6 +254,7 @@ namespace llvm { bool isCodeGenOnly : 1; bool isPseudo : 1; bool isRegSequence : 1; + bool isExtractSubreg : 1; std::string DeprecatedReason; bool HasComplexDeprecationPredicate; diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index edd2f1f0e3c..86578a84d96 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -506,6 +506,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<getValueAsBitsInit("TSFlags"); -- 2.34.1