return hasProperty(MCID::ExtractSubreg, Type);
}
+ /// \brief Return true if this instruction behaves
+ /// the same way as the generic INSERT_SUBREG instructions.
+ /// E.g., on ARM,
+ /// dX = VSETLNi32 dY, rZ, Imm
+ /// is equivalent to a INSERT_SUBREG:
+ /// dX = INSERT_SUBREG dY, rZ, translateImmToSubIdx(Imm)
+ ///
+ /// Note that for the optimizers to be able to take advantage of
+ /// this property, TargetInstrInfo::getInsertSubregLikeInputs has to be
+ /// override accordingly.
+ bool isInsertSubregLike(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::InsertSubreg, Type);
+ }
+
//===--------------------------------------------------------------------===//
// Side Effect Analysis
//===--------------------------------------------------------------------===//
ExtraSrcRegAllocReq,
ExtraDefRegAllocReq,
RegSequence,
- ExtractSubreg
+ ExtractSubreg,
+ InsertSubreg
};
}
return Flags & (1 << MCID::ExtractSubreg);
}
+ /// \brief Return true if this instruction behaves
+ /// the same way as the generic INSERT_SUBREG instructions.
+ /// E.g., on ARM,
+ /// dX = VSETLNi32 dY, rZ, Imm
+ /// is equivalent to a INSERT_SUBREG:
+ /// dX = INSERT_SUBREG dY, rZ, translateImmToSubIdx(Imm)
+ ///
+ /// Note that for the optimizers to be able to take advantage of
+ /// this property, TargetInstrInfo::getInsertSubregLikeInputs has to be
+ /// override accordingly.
+ bool isInsertSubregLike() const {
+ return Flags & (1 << MCID::InsertSubreg);
+ }
+
//===--------------------------------------------------------------------===//
// Side Effect Analysis
//===--------------------------------------------------------------------===//
bit isExtractSubreg = 0; // Is this instruction a kind of extract subreg?
// If so, make sure to override
// TargetInstrInfo::getExtractSubregLikeInputs.
+ bit isInsertSubreg = 0; // Is this instruction a kind of insert subreg?
+ // If so, make sure to override
+ // TargetInstrInfo::getInsertSubregLikeInputs.
// Side effect flags - When set, the flags have these meanings:
//
getExtractSubregInputs(const MachineInstr &MI, unsigned DefIdx,
RegSubRegPairAndIdx &InputReg) const;
+ /// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI
+ /// and \p DefIdx.
+ /// \p [out] BaseReg and \p [out] InsertedReg contain
+ /// the equivalent inputs of INSERT_SUBREG.
+ /// E.g., INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce:
+ /// - BaseReg: vreg0:sub0
+ /// - InsertedReg: vreg1:sub1, sub3
+ ///
+ /// \returns true if it is possible to build such an input sequence
+ /// with the pair \p MI, \p DefIdx. False otherwise.
+ ///
+ /// \pre MI.isInsertSubreg() or MI.isInsertSubregLike().
+ ///
+ /// \note The generic implementation does not provide any support for
+ /// MI.isInsertSubregLike(). In other words, one has to override
+ /// getInsertSubregLikeInputs for target specific instructions.
+ bool
+ getInsertSubregInputs(const MachineInstr &MI, unsigned DefIdx,
+ RegSubRegPair &BaseReg,
+ RegSubRegPairAndIdx &InsertedReg) 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
return false;
}
+ /// \brief Target-dependent implementation of getInsertSubregInputs.
+ ///
+ /// \returns true if it is possible to build the equivalent
+ /// INSERT_SUBREG inputs with the pair \p MI, \p DefIdx. False otherwise.
+ ///
+ /// \pre MI.isInsertSubregLike().
+ ///
+ /// \see TargetInstrInfo::getInsertSubregInputs.
+ virtual bool
+ getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
+ RegSubRegPair &BaseReg,
+ RegSubRegPairAndIdx &InsertedReg) const {
+ return false;
+ }
+
public:
/// canFoldMemoryOperand - Returns true for the specified load / store if
/// folding is possible.
InputReg.SubIdx = (unsigned)MOSubIdx.getImm();
return true;
}
+
+bool TargetInstrInfo::getInsertSubregInputs(
+ const MachineInstr &MI, unsigned DefIdx,
+ RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const {
+ assert((MI.isInsertSubreg() ||
+ MI.isInsertSubregLike()) && "Instruction do not have the proper type");
+
+ if (!MI.isInsertSubreg())
+ return getInsertSubregLikeInputs(MI, DefIdx, BaseReg, InsertedReg);
+
+ // We are looking at:
+ // Def = INSERT_SEQUENCE v0, v1, sub0.
+ assert(DefIdx == 0 && "INSERT_SUBREG only has one def");
+ const MachineOperand &MOBaseReg = MI.getOperand(1);
+ const MachineOperand &MOInsertedReg = MI.getOperand(2);
+ const MachineOperand &MOSubIdx = MI.getOperand(3);
+ assert(MOSubIdx.isImm() &&
+ "One of the subindex of the reg_sequence is not an immediate");
+ BaseReg.Reg = MOBaseReg.getReg();
+ BaseReg.SubReg = MOBaseReg.getSubReg();
+
+ InsertedReg.Reg = MOInsertedReg.getReg();
+ InsertedReg.SubReg = MOInsertedReg.getSubReg();
+ InsertedReg.SubIdx = (unsigned)MOSubIdx.getImm();
+ return true;
+}
isNotDuplicable = R->getValueAsBit("isNotDuplicable");
isRegSequence = R->getValueAsBit("isRegSequence");
isExtractSubreg = R->getValueAsBit("isExtractSubreg");
+ isInsertSubreg = R->getValueAsBit("isInsertSubreg");
bool Unset;
mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset);
bool isPseudo : 1;
bool isRegSequence : 1;
bool isExtractSubreg : 1;
+ bool isInsertSubreg : 1;
std::string DeprecatedReason;
bool HasComplexDeprecationPredicate;
if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)";
if (Inst.isRegSequence) OS << "|(1<<MCID::RegSequence)";
if (Inst.isExtractSubreg) OS << "|(1<<MCID::ExtractSubreg)";
+ if (Inst.isInsertSubreg) OS << "|(1<<MCID::InsertSubreg)";
// Emit all of the target-specific flags...
BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");