mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
Add isRegSequence property.
This patch adds a new property: isRegSequence and the related target hooks: TargetIntrInfo::getRegSequenceInputs and TargetInstrInfo::getRegSequenceLikeInputs to specify that a target specific instruction is a (kind of) REG_SEQUENCE. <rdar://problem/12702965> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215394 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7f4f923aa5
commit
1b425402eb
@ -510,6 +510,20 @@ public:
|
||||
return hasProperty(MCID::FoldableAsLoad, Type);
|
||||
}
|
||||
|
||||
/// \brief Return true if this instruction behaves
|
||||
/// the same way as the generic REG_SEQUENCE instructions.
|
||||
/// E.g., on ARM,
|
||||
/// dX VMOVDRR rY, rZ
|
||||
/// is equivalent to
|
||||
/// dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1.
|
||||
///
|
||||
/// Note that for the optimizers to be able to take advantage of
|
||||
/// this property, TargetInstrInfo::getRegSequenceLikeInputs has to be
|
||||
/// override accordingly.
|
||||
bool isRegSequenceLike(QueryType Type = IgnoreBundle) const {
|
||||
return hasProperty(MCID::RegSequence, Type);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Side Effect Analysis
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -125,7 +125,8 @@ namespace MCID {
|
||||
Rematerializable,
|
||||
CheapAsAMove,
|
||||
ExtraSrcRegAllocReq,
|
||||
ExtraDefRegAllocReq
|
||||
ExtraDefRegAllocReq,
|
||||
RegSequence
|
||||
};
|
||||
}
|
||||
|
||||
@ -357,6 +358,18 @@ public:
|
||||
return Flags & (1 << MCID::FoldableAsLoad);
|
||||
}
|
||||
|
||||
/// \brief Return true if this instruction behaves
|
||||
/// the same way as the generic REG_SEQUENCE instructions.
|
||||
/// E.g., on ARM,
|
||||
/// dX VMOVDRR rY, rZ
|
||||
/// is equivalent to
|
||||
/// dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1.
|
||||
///
|
||||
/// Note that for the optimizers to be able to take advantage of
|
||||
/// this property, TargetInstrInfo::getRegSequenceLikeInputs has to be
|
||||
/// override accordingly.
|
||||
bool isRegSequenceLike() const { return Flags & (1 << MCID::RegSequence); }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Side Effect Analysis
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -378,6 +378,9 @@ class Instruction {
|
||||
bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
|
||||
bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement?
|
||||
bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement?
|
||||
bit isRegSequence = 0; // Is this instruction a kind of reg sequence?
|
||||
// If so, make sure to override
|
||||
// TargetInstrInfo::getRegSequenceLikeInputs.
|
||||
bit isPseudo = 0; // Is this instruction a pseudo-instruction?
|
||||
// If so, won't have encoding information for
|
||||
// the [MC]CodeEmitter stuff.
|
||||
|
@ -264,6 +264,45 @@ public:
|
||||
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
|
||||
unsigned &SrcOpIdx2) const;
|
||||
|
||||
/// A pair composed of a register and a sub-register index.
|
||||
/// Used to give some type checking when modeling Reg:SubReg.
|
||||
struct RegSubRegPair {
|
||||
unsigned Reg;
|
||||
unsigned SubReg;
|
||||
RegSubRegPair(unsigned Reg = 0, unsigned SubReg = 0)
|
||||
: Reg(Reg), SubReg(SubReg) {}
|
||||
};
|
||||
/// A pair composed of a pair of a register and a sub-register index,
|
||||
/// and another sub-register index.
|
||||
/// Used to give some type checking when modeling Reg:SubReg1, SubReg2.
|
||||
struct RegSubRegPairAndIdx : RegSubRegPair {
|
||||
unsigned SubIdx;
|
||||
RegSubRegPairAndIdx(unsigned Reg = 0, unsigned SubReg = 0,
|
||||
unsigned SubIdx = 0)
|
||||
: RegSubRegPair(Reg, SubReg), SubIdx(SubIdx) {}
|
||||
};
|
||||
|
||||
/// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI
|
||||
/// and \p DefIdx.
|
||||
/// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of
|
||||
/// the list is modeled as <Reg:SubReg, SubIdx>.
|
||||
/// E.g., REG_SEQUENCE vreg1:sub1, sub0, vreg2, sub1 would produce
|
||||
/// two elements:
|
||||
/// - vreg1:sub1, sub0
|
||||
/// - vreg2<:0>, sub1
|
||||
///
|
||||
/// \returns true if it is possible to build such an input sequence
|
||||
/// with the pair \p MI, \p DefIdx. False otherwise.
|
||||
///
|
||||
/// \pre MI.isRegSequence() or MI.isRegSequenceLike().
|
||||
///
|
||||
/// \note The generic implementation does not provide any support for
|
||||
/// MI.isRegSequenceLike(). In other words, one has to override
|
||||
/// getRegSequenceLikeInputs for target specific instructions.
|
||||
bool
|
||||
getRegSequenceInputs(const MachineInstr &MI, unsigned DefIdx,
|
||||
SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) 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
|
||||
@ -632,6 +671,20 @@ protected:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// \brief Target-dependent implementation of getRegSequenceInputs.
|
||||
///
|
||||
/// \returns true if it is possible to build the equivalent
|
||||
/// REG_SEQUENCE inputs with the pair \p MI, \p DefIdx. False otherwise.
|
||||
///
|
||||
/// \pre MI.isRegSequenceLike().
|
||||
///
|
||||
/// \see TargetInstrInfo::getRegSequenceInputs.
|
||||
virtual bool getRegSequenceLikeInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx,
|
||||
SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
/// canFoldMemoryOperand - Returns true for the specified load / store if
|
||||
/// folding is possible.
|
||||
|
@ -852,3 +852,28 @@ computeOperandLatency(const InstrItineraryData *ItinData,
|
||||
defaultDefLatency(ItinData->SchedModel, DefMI));
|
||||
return InstrLatency;
|
||||
}
|
||||
|
||||
bool TargetInstrInfo::getRegSequenceInputs(
|
||||
const MachineInstr &MI, unsigned DefIdx,
|
||||
SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const {
|
||||
assert(MI.isRegSequence() ||
|
||||
MI.isRegSequenceLike() && "Instruction do not have the proper type");
|
||||
|
||||
if (!MI.isRegSequence())
|
||||
return getRegSequenceLikeInputs(MI, DefIdx, InputRegs);
|
||||
|
||||
// We are looking at:
|
||||
// Def = REG_SEQUENCE v0, sub0, v1, sub1, ...
|
||||
assert(DefIdx == 0 && "REG_SEQUENCE only has one def");
|
||||
for (unsigned OpIdx = 1, EndOpIdx = MI.getNumOperands(); OpIdx != EndOpIdx;
|
||||
OpIdx += 2) {
|
||||
const MachineOperand &MOReg = MI.getOperand(OpIdx);
|
||||
const MachineOperand &MOSubIdx = MI.getOperand(OpIdx + 1);
|
||||
assert(MOSubIdx.isImm() &&
|
||||
"One of the subindex of the reg_sequence is not an immediate");
|
||||
// Record Reg:SubReg, SubIdx.
|
||||
InputRegs.push_back(RegSubRegPairAndIdx(MOReg.getReg(), MOReg.getSubReg(),
|
||||
(unsigned)MOSubIdx.getImm()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -314,6 +314,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R)
|
||||
hasPostISelHook = R->getValueAsBit("hasPostISelHook");
|
||||
hasCtrlDep = R->getValueAsBit("hasCtrlDep");
|
||||
isNotDuplicable = R->getValueAsBit("isNotDuplicable");
|
||||
isRegSequence = R->getValueAsBit("isRegSequence");
|
||||
|
||||
bool Unset;
|
||||
mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset);
|
||||
|
@ -253,6 +253,7 @@ namespace llvm {
|
||||
bool hasExtraDefRegAllocReq : 1;
|
||||
bool isCodeGenOnly : 1;
|
||||
bool isPseudo : 1;
|
||||
bool isRegSequence : 1;
|
||||
|
||||
std::string DeprecatedReason;
|
||||
bool HasComplexDeprecationPredicate;
|
||||
|
@ -505,6 +505,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
if (Inst.isAsCheapAsAMove) OS << "|(1<<MCID::CheapAsAMove)";
|
||||
if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)";
|
||||
if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)";
|
||||
if (Inst.isRegSequence) OS << "|(1<<MCID::RegSequence)";
|
||||
|
||||
// Emit all of the target-specific flags...
|
||||
BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
|
||||
|
Loading…
Reference in New Issue
Block a user