class LiveVariables;
class MCAsmInfo;
class MachineMemOperand;
+class MachineRegisterInfo;
class MDNode;
class MCInst;
class SDNode;
AliasAnalysis *AA) const;
public:
- /// isMoveInstr - Return true if the instruction is a register to register
- /// move and return the source and dest operands and their sub-register
- /// indices by reference.
- virtual bool isMoveInstr(const MachineInstr& MI,
- unsigned& SrcReg, unsigned& DstReg,
- unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
- return false;
- }
-
/// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
/// extension instruction. That is, it's like a copy where it's legal for the
/// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
return false;
}
- /// isIdentityCopy - Return true if the instruction is a copy (or
- /// extract_subreg, insert_subreg, subreg_to_reg) where the source and
- /// destination registers are the same.
- bool isIdentityCopy(const MachineInstr &MI) const {
- unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
- if (isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
- SrcReg == DstReg)
- return true;
-
- if ((MI.getOpcode() == TargetOpcode::INSERT_SUBREG ||
- MI.getOpcode() == TargetOpcode::SUBREG_TO_REG) &&
- MI.getOperand(0).getReg() == MI.getOperand(2).getReg())
- return true;
- return false;
- }
-
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
/// the destination along with the FrameIndex of the loaded stack slot. If
return true;
}
- /// isProfitableToIfCvt - Return true if it's profitable to first "NumInstrs"
- /// of the specified basic block.
+ /// isProfitableToIfCvt - Return true if it's profitable to predicate
+ /// instructions with accumulated instruction latency of "NumCycles"
+ /// of the specified basic block, where the probability of the instructions
+ /// being executed is given by Probability, and Confidence is a measure
+ /// of our confidence that it will be properly predicted.
virtual
- bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const {
+ bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
+ unsigned ExtraPredCycles,
+ float Probability, float Confidence) const {
return false;
}
/// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one
/// checks for the case where two basic blocks from true and false path
/// of a if-then-else (diamond) are predicated on mutally exclusive
- /// predicates.
+ /// predicates, where the probability of the true path being taken is given
+ /// by Probability, and Confidence is a measure of our confidence that it
+ /// will be properly predicted.
virtual bool
- isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTInstrs,
- MachineBasicBlock &FMBB, unsigned NumFInstrs) const {
+ isProfitableToIfCvt(MachineBasicBlock &TMBB,
+ unsigned NumTCycles, unsigned ExtraTCycles,
+ MachineBasicBlock &FMBB,
+ unsigned NumFCycles, unsigned ExtraFCycles,
+ float Probability, float Confidence) const {
return false;
}
/// isProfitableToDupForIfCvt - Return true if it's profitable for
- /// if-converter to duplicate a specific number of instructions in the
- /// specified MBB to enable if-conversion.
+ /// if-converter to duplicate instructions of specified accumulated
+ /// instruction latencies in the specified MBB to enable if-conversion.
+ /// The probability of the instructions being executed is given by
+ /// Probability, and Confidence is a measure of our confidence that it
+ /// will be properly predicted.
virtual bool
- isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs) const {
+ isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
+ float Probability, float Confidence) const {
return false;
}
unsigned SrcReg, bool isKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
- assert(0 && "Target didn't implement TargetInstrInfo::storeRegToStackSlot!");
+ assert(0 && "Target didn't implement TargetInstrInfo::storeRegToStackSlot!");
}
/// loadRegFromStackSlot - Load the specified register of the given register
unsigned DestReg, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
- assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
+ assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
}
/// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
/// storeRegToStackSlot(). Returns false otherwise.
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
+ const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const {
return false;
}
/// take care of adding a MachineMemOperand to the newly created instruction.
virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
MachineInstr* MI,
- const SmallVectorImpl<unsigned> &Ops,
+ const SmallVectorImpl<unsigned> &Ops,
MachineInstr* LoadMI) const {
return 0;
}
/// only differences between the two addresses are the offset. It also returns
/// the offsets by reference.
virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
- int64_t &Offset1, int64_t &Offset2) const {
+ int64_t &Offset1, int64_t &Offset2) const {
return false;
}
const MachineBasicBlock *MBB,
const MachineFunction &MF) const = 0;
- /// GetInstSize - Returns the size of the specified Instruction.
- ///
- virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const {
- assert(0 && "Target didn't implement TargetInstrInfo::GetInstSize!");
- return 0;
- }
-
- /// GetFunctionSizeInBytes - Returns the size of the specified
- /// MachineFunction.
- ///
- virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const = 0;
-
/// Measure the specified inline asm to determine an approximation of its
/// length.
virtual unsigned getInlineAsmLength(const char *Str,
/// to use for this target when scheduling the machine instructions after
/// register allocation.
virtual ScheduleHazardRecognizer*
- CreateTargetPostRAHazardRecognizer(const InstrItineraryData&) const = 0;
+ CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const = 0;
+
+ /// AnalyzeCompare - For a comparison instruction, return the source register
+ /// in SrcReg and the value it compares against in CmpValue. Return true if
+ /// the comparison instruction can be analyzed.
+ virtual bool AnalyzeCompare(const MachineInstr *MI,
+ unsigned &SrcReg, int &Mask, int &Value) const {
+ return false;
+ }
+
+ /// OptimizeCompareInstr - See if the comparison instruction can be converted
+ /// into something more efficient. E.g., on ARM most instructions can set the
+ /// flags register, obviating the need for a separate CMP.
+ virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr,
+ unsigned SrcReg, int Mask, int Value,
+ const MachineRegisterInfo *MRI) const {
+ return false;
+ }
+
+ /// FoldImmediate - 'Reg' is known to be defined by a move immediate
+ /// instruction, try to fold the immediate into the use instruction.
+ virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
+ unsigned Reg, MachineRegisterInfo *MRI) const {
+ return false;
+ }
+
+ /// getNumMicroOps - Return the number of u-operations the given machine
+ /// instruction will be decoded to on the target cpu.
+ virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
+ const MachineInstr *MI) const;
+
+ /// getOperandLatency - Compute and return the use operand latency of a given
+ /// pair of def and use.
+ /// In most cases, the static scheduling itinerary was enough to determine the
+ /// operand latency. But it may not be possible for instructions with variable
+ /// number of defs / uses.
+ virtual int getOperandLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *DefMI, unsigned DefIdx,
+ const MachineInstr *UseMI, unsigned UseIdx) const;
+
+ virtual int getOperandLatency(const InstrItineraryData *ItinData,
+ SDNode *DefNode, unsigned DefIdx,
+ SDNode *UseNode, unsigned UseIdx) const;
+
+ /// getInstrLatency - Compute the instruction latency of a given instruction.
+ /// If the instruction has higher cost when predicated, it's returned via
+ /// PredCost.
+ virtual int getInstrLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *MI,
+ unsigned *PredCost = 0) const;
+
+ virtual int getInstrLatency(const InstrItineraryData *ItinData,
+ SDNode *Node) const;
+
+ /// hasHighOperandLatency - Compute operand latency between a def of 'Reg'
+ /// and an use in the current loop, return true if the target considered
+ /// it 'high'. This is used by optimization passes such as machine LICM to
+ /// determine whether it makes sense to hoist an instruction out even in
+ /// high register pressure situation.
+ virtual
+ bool hasHighOperandLatency(const InstrItineraryData *ItinData,
+ const MachineRegisterInfo *MRI,
+ const MachineInstr *DefMI, unsigned DefIdx,
+ const MachineInstr *UseMI, unsigned UseIdx) const {
+ return false;
+ }
+
+ /// hasLowDefLatency - Compute operand latency of a def of 'Reg', return true
+ /// if the target considered it 'low'.
+ virtual
+ bool hasLowDefLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *DefMI, unsigned DefIdx) const;
};
/// TargetInstrInfoImpl - This is the default implementation of
virtual bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const;
- virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
virtual ScheduleHazardRecognizer *
- CreateTargetPostRAHazardRecognizer(const InstrItineraryData&) const;
+ CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const;
};
} // End llvm namespace