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.

<rdar://problem/12702965>


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216130 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Quentin Colombet 2014-08-20 21:51:26 +00:00
parent fa210acc3b
commit dac67649f2
8 changed files with 93 additions and 1 deletions

View File

@ -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
//===--------------------------------------------------------------------===//

View File

@ -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
//===--------------------------------------------------------------------===//

View File

@ -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:
//

View File

@ -303,6 +303,24 @@ public:
getRegSequenceInputs(const MachineInstr &MI, unsigned DefIdx,
SmallVectorImpl<RegSubRegPairAndIdx> &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.

View File

@ -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;
}

View File

@ -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);

View File

@ -254,6 +254,7 @@ namespace llvm {
bool isCodeGenOnly : 1;
bool isPseudo : 1;
bool isRegSequence : 1;
bool isExtractSubreg : 1;
std::string DeprecatedReason;
bool HasComplexDeprecationPredicate;

View File

@ -506,6 +506,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)";
if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)";
if (Inst.isRegSequence) OS << "|(1<<MCID::RegSequence)";
if (Inst.isExtractSubreg) OS << "|(1<<MCID::ExtractSubreg)";
// Emit all of the target-specific flags...
BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");