class TargetRegisterInfo;
class BranchProbability;
class TargetSubtargetInfo;
+class TargetSchedModel;
class DFAPacketizer;
template<class T> class SmallVectorImpl;
return true;
}
+ /// Represents a predicate at the MachineFunction level. The control flow a
+ /// MachineBranchPredicate represents is:
+ ///
+ /// Reg <def>= LHS `Predicate` RHS == ConditionDef
+ /// if Reg then goto TrueDest else goto FalseDest
+ ///
+ struct MachineBranchPredicate {
+ enum ComparePredicate {
+ PRED_EQ, // True if two values are equal
+ PRED_NE, // True if two values are not equal
+ PRED_INVALID // Sentinel value
+ };
+
+ ComparePredicate Predicate;
+ MachineOperand LHS;
+ MachineOperand RHS;
+ MachineBasicBlock *TrueDest;
+ MachineBasicBlock *FalseDest;
+ MachineInstr *ConditionDef;
+
+ /// SingleUseCondition is true if ConditionDef is dead except for the
+ /// branch(es) at the end of the basic block.
+ ///
+ bool SingleUseCondition;
+
+ explicit MachineBranchPredicate()
+ : Predicate(PRED_INVALID), LHS(MachineOperand::CreateImm(0)),
+ RHS(MachineOperand::CreateImm(0)), TrueDest(nullptr),
+ FalseDest(nullptr), ConditionDef(nullptr), SingleUseCondition(false) {
+ }
+ };
+
+ /// Analyze the branching code at the end of MBB and parse it into the
+ /// MachineBranchPredicate structure if possible. Returns false on success
+ /// and true on failure.
+ ///
+ /// If AllowModify is true, then this routine is allowed to modify the basic
+ /// block (e.g. delete instructions after the unconditional branch).
+ ///
+ virtual bool AnalyzeBranchPredicate(MachineBasicBlock &MBB,
+ MachineBranchPredicate &MBP,
+ bool AllowModify = false) const {
+ return true;
+ }
+
/// Remove the branching code at the end of the specific MBB.
/// This is only invoked in cases where AnalyzeBranch returns success. It
/// returns the number of instructions that were removed.
/// merging needs to be disabled.
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
- const SmallVectorImpl<MachineOperand> &Cond,
+ ArrayRef<MachineOperand> Cond,
DebugLoc DL) const {
llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch!");
}
/// @param TrueCycles Latency from TrueReg to select output.
/// @param FalseCycles Latency from FalseReg to select output.
virtual bool canInsertSelect(const MachineBasicBlock &MBB,
- const SmallVectorImpl<MachineOperand> &Cond,
+ ArrayRef<MachineOperand> Cond,
unsigned TrueReg, unsigned FalseReg,
int &CondCycles,
int &TrueCycles, int &FalseCycles) const {
/// @param FalseReg Virtual register to copy when Cons is false.
virtual void insertSelect(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
- unsigned DstReg,
- const SmallVectorImpl<MachineOperand> &Cond,
+ unsigned DstReg, ArrayRef<MachineOperand> Cond,
unsigned TrueReg, unsigned FalseReg) const {
llvm_unreachable("Target didn't implement TargetInstrInfo::insertSelect!");
}
/// order since the pattern evaluator stops checking as soon as it finds a
/// faster sequence.
/// \param Root - Instruction that could be combined with one of its operands
- /// \param Pattern - Vector of possible combination pattern
- virtual bool hasPattern(
+ /// \param Pattern - Vector of possible combination patterns
+ virtual bool getMachineCombinerPatterns(
MachineInstr &Root,
SmallVectorImpl<MachineCombinerPattern::MC_PATTERN> &Pattern) const {
return false;
}
- /// When hasPattern() finds a pattern this function generates the instructions
- /// that could replace the original code sequence. The client has to decide
- /// whether the actual replacement is beneficial or not.
+ /// When getMachineCombinerPatterns() finds patterns, this function generates
+ /// the instructions that could replace the original code sequence. The client
+ /// has to decide whether the actual replacement is beneficial or not.
/// \param Root - Instruction that could be combined with one of its operands
- /// \param P - Combination pattern for Root
+ /// \param Pattern - Combination pattern for Root
/// \param InsInstrs - Vector of new instructions that implement P
/// \param DelInstrs - Old instructions, including Root, that could be
/// replaced by InsInstr
/// \param InstrIdxForVirtReg - map of virtual register to instruction in
/// InsInstr that defines it
virtual void genAlternativeCodeSequence(
- MachineInstr &Root, MachineCombinerPattern::MC_PATTERN P,
+ MachineInstr &Root, MachineCombinerPattern::MC_PATTERN Pattern,
SmallVectorImpl<MachineInstr *> &InsInstrs,
SmallVectorImpl<MachineInstr *> &DelInstrs,
DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
}
public:
- /// Returns true for the specified load / store if folding is possible.
- virtual bool canFoldMemoryOperand(const MachineInstr *MI,
- ArrayRef<unsigned> Ops) const;
-
/// unfoldMemoryOperand - Separate a single instruction which folded a load or
/// a store or a load and a store into two or more instruction. If this is
/// possible, returns true as well as the new instructions by reference.
return false;
}
- /// Get the base register and byte offset of a load/store instr.
- virtual bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
- unsigned &BaseReg, unsigned &Offset,
- const TargetRegisterInfo *TRI) const {
+ /// Get the base register and byte offset of an instruction that reads/writes
+ /// memory.
+ virtual bool getMemOpBaseRegImmOfs(MachineInstr *MemOp, unsigned &BaseReg,
+ unsigned &Offset,
+ const TargetRegisterInfo *TRI) const {
return false;
}
/// It returns true if the operation was successful.
virtual
bool PredicateInstruction(MachineInstr *MI,
- const SmallVectorImpl<MachineOperand> &Pred) const;
+ ArrayRef<MachineOperand> Pred) const;
/// Returns true if the first specified predicate
/// subsumes the second, e.g. GE subsumes GT.
virtual
- bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
- const SmallVectorImpl<MachineOperand> &Pred2) const {
+ bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
+ ArrayRef<MachineOperand> Pred2) const {
return false;
}
/// determine whether it makes sense to hoist an instruction out even in a
/// high register pressure situation.
virtual
- bool hasHighOperandLatency(const InstrItineraryData *ItinData,
+ bool hasHighOperandLatency(const TargetSchedModel &SchedModel,
const MachineRegisterInfo *MRI,
const MachineInstr *DefMI, unsigned DefIdx,
const MachineInstr *UseMI, unsigned UseIdx) const {
/// Compute operand latency of a def of 'Reg'. Return true
/// if the target considered it 'low'.
virtual
- bool hasLowDefLatency(const InstrItineraryData *ItinData,
+ bool hasLowDefLatency(const TargetSchedModel &SchedModel,
const MachineInstr *DefMI, unsigned DefIdx) const;
/// Perform target-specific instruction verification.
return 5;
}
+ /// Return an array that contains the ids of the target indices (used for the
+ /// TargetIndex machine operand) and their names.
+ ///
+ /// MIR Serialization is able to serialize only the target indices that are
+ /// defined by this method.
+ virtual ArrayRef<std::pair<int, const char *>>
+ getSerializableTargetIndices() const {
+ return None;
+ }
+
+ /// Decompose the machine operand's target flags into two values - the direct
+ /// target flag value and any of bit flags that are applied.
+ virtual std::pair<unsigned, unsigned>
+ decomposeMachineOperandsTargetFlags(unsigned /*TF*/) const {
+ return std::make_pair(0u, 0u);
+ }
+
+ /// Return an array that contains the direct target flag values and their
+ /// names.
+ ///
+ /// MIR Serialization is able to serialize only the target flags that are
+ /// defined by this method.
+ virtual ArrayRef<std::pair<unsigned, const char *>>
+ getSerializableDirectMachineOperandTargetFlags() const {
+ return None;
+ }
+
+ /// Return an array that contains the bitmask target flag values and their
+ /// names.
+ ///
+ /// MIR Serialization is able to serialize only the target flags that are
+ /// defined by this method.
+ virtual ArrayRef<std::pair<unsigned, const char *>>
+ getSerializableBitmaskMachineOperandTargetFlags() const {
+ return None;
+ }
+
private:
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
};
+/// \brief Provide DenseMapInfo for TargetInstrInfo::RegSubRegPair.
+template<>
+struct DenseMapInfo<TargetInstrInfo::RegSubRegPair> {
+ typedef DenseMapInfo<unsigned> RegInfo;
+
+ static inline TargetInstrInfo::RegSubRegPair getEmptyKey() {
+ return TargetInstrInfo::RegSubRegPair(RegInfo::getEmptyKey(),
+ RegInfo::getEmptyKey());
+ }
+ static inline TargetInstrInfo::RegSubRegPair getTombstoneKey() {
+ return TargetInstrInfo::RegSubRegPair(RegInfo::getTombstoneKey(),
+ RegInfo::getTombstoneKey());
+ }
+ /// \brief Reuse getHashValue implementation from
+ /// std::pair<unsigned, unsigned>.
+ static unsigned getHashValue(const TargetInstrInfo::RegSubRegPair &Val) {
+ std::pair<unsigned, unsigned> PairVal =
+ std::make_pair(Val.Reg, Val.SubReg);
+ return DenseMapInfo<std::pair<unsigned, unsigned>>::getHashValue(PairVal);
+ }
+ static bool isEqual(const TargetInstrInfo::RegSubRegPair &LHS,
+ const TargetInstrInfo::RegSubRegPair &RHS) {
+ return RegInfo::isEqual(LHS.Reg, RHS.Reg) &&
+ RegInfo::isEqual(LHS.SubReg, RHS.SubReg);
+ }
+};
+
} // End llvm namespace
#endif