mirror of
https://github.com/RPCS3/llvm.git
synced 2025-03-05 09:09:23 +00:00
[Hexagon] Bring HexagonInstrInfo up to date
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253986 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
42fec0866c
commit
8e716832ef
@ -71,6 +71,7 @@ class NewValueRel: PredNewRel;
|
||||
// NewValueRel - Filter class used to relate load/store instructions having
|
||||
// different addressing modes with each other.
|
||||
class AddrModeRel: NewValueRel;
|
||||
class IntrinsicsRel;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Generate mapping table to relate non-predicate instructions with their
|
||||
@ -186,6 +187,37 @@ def getRegForm : InstrMapping {
|
||||
let ValueCols = [["reg"]];
|
||||
}
|
||||
|
||||
def getRegShlForm : InstrMapping {
|
||||
let FilterClass = "ImmRegShl";
|
||||
let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
|
||||
let ColFields = ["InputType"];
|
||||
let KeyCol = ["imm"];
|
||||
let ValueCols = [["reg"]];
|
||||
}
|
||||
|
||||
def notTakenBranchPrediction : InstrMapping {
|
||||
let FilterClass = "PredRel";
|
||||
let RowFields = ["BaseOpcode", "PNewValue", "PredSense", "isBranch", "isPredicated"];
|
||||
let ColFields = ["isBrTaken"];
|
||||
let KeyCol = ["true"];
|
||||
let ValueCols = [["false"]];
|
||||
}
|
||||
|
||||
def takenBranchPrediction : InstrMapping {
|
||||
let FilterClass = "PredRel";
|
||||
let RowFields = ["BaseOpcode", "PNewValue", "PredSense", "isBranch", "isPredicated"];
|
||||
let ColFields = ["isBrTaken"];
|
||||
let KeyCol = ["false"];
|
||||
let ValueCols = [["true"]];
|
||||
}
|
||||
|
||||
def getRealHWInstr : InstrMapping {
|
||||
let FilterClass = "IntrinsicsRel";
|
||||
let RowFields = ["BaseOpcode"];
|
||||
let ColFields = ["InstrType"];
|
||||
let KeyCol = ["Pseudo"];
|
||||
let ValueCols = [["Pseudo"], ["Real"]];
|
||||
}
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Register File, Calling Conv, Instruction Descriptions
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -210,6 +242,10 @@ def : Proc<"hexagonv4", HexagonModelV4,
|
||||
[ArchV4]>;
|
||||
def : Proc<"hexagonv5", HexagonModelV4,
|
||||
[ArchV4, ArchV5]>;
|
||||
def : Proc<"hexagonv55", HexagonModelV55,
|
||||
[ArchV4, ArchV5, ArchV55]>;
|
||||
def : Proc<"hexagonv60", HexagonModelV60,
|
||||
[ArchV4, ArchV5, ArchV55, ArchV60, ExtensionHVX]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Declare the target which we are implementing
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,3 @@
|
||||
|
||||
//===- HexagonInstrInfo.h - Hexagon Instruction Information -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
@ -28,23 +27,18 @@ namespace llvm {
|
||||
|
||||
struct EVT;
|
||||
class HexagonSubtarget;
|
||||
|
||||
class HexagonInstrInfo : public HexagonGenInstrInfo {
|
||||
virtual void anchor();
|
||||
const HexagonRegisterInfo RI;
|
||||
const HexagonSubtarget &Subtarget;
|
||||
|
||||
public:
|
||||
typedef unsigned Opcode_t;
|
||||
|
||||
explicit HexagonInstrInfo(HexagonSubtarget &ST);
|
||||
|
||||
/// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
|
||||
/// such, whenever a client has an instance of instruction info, it should
|
||||
/// always be able to get register info as well (through this method).
|
||||
/// TargetInstrInfo overrides.
|
||||
///
|
||||
const HexagonRegisterInfo &getRegisterInfo() const { return RI; }
|
||||
|
||||
/// isLoadFromStackSlot - If the specified machine instruction is a direct
|
||||
/// 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
|
||||
/// not, return 0. This predicate must return 0 if the instruction has
|
||||
@ -52,7 +46,7 @@ public:
|
||||
unsigned isLoadFromStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const override;
|
||||
|
||||
/// isStoreToStackSlot - If the specified machine instruction is a direct
|
||||
/// If the specified machine instruction is a direct
|
||||
/// store to a stack slot, return the virtual or physical register number of
|
||||
/// the source reg along with the FrameIndex of the loaded stack slot. If
|
||||
/// not, return 0. This predicate must return 0 if the instruction has
|
||||
@ -60,50 +54,118 @@ public:
|
||||
unsigned isStoreToStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const override;
|
||||
|
||||
|
||||
/// Analyze the branching code at the end of MBB, returning
|
||||
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
|
||||
/// implemented for a target). Upon success, this returns false and returns
|
||||
/// with the following information in various cases:
|
||||
///
|
||||
/// 1. If this block ends with no branches (it just falls through to its succ)
|
||||
/// just return false, leaving TBB/FBB null.
|
||||
/// 2. If this block ends with only an unconditional branch, it sets TBB to be
|
||||
/// the destination block.
|
||||
/// 3. If this block ends with a conditional branch and it falls through to a
|
||||
/// successor block, it sets TBB to be the branch destination block and a
|
||||
/// list of operands that evaluate the condition. These operands can be
|
||||
/// passed to other TargetInstrInfo methods to create new branches.
|
||||
/// 4. If this block ends with a conditional branch followed by an
|
||||
/// unconditional branch, it returns the 'true' destination in TBB, the
|
||||
/// 'false' destination in FBB, and a list of operands that evaluate the
|
||||
/// condition. These operands can be passed to other TargetInstrInfo
|
||||
/// methods to create new branches.
|
||||
///
|
||||
/// Note that RemoveBranch and InsertBranch must be implemented to support
|
||||
/// cases where this method returns success.
|
||||
///
|
||||
/// If AllowModify is true, then this routine is allowed to modify the basic
|
||||
/// block (e.g. delete instructions after the unconditional branch).
|
||||
///
|
||||
bool AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
bool AllowModify) const override;
|
||||
|
||||
/// 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.
|
||||
unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
|
||||
|
||||
/// Insert branch code into the end of the specified MachineBasicBlock.
|
||||
/// The operands to this method are the same as those
|
||||
/// returned by AnalyzeBranch. This is only invoked in cases where
|
||||
/// AnalyzeBranch returns success. It returns the number of instructions
|
||||
/// inserted.
|
||||
///
|
||||
/// It is also invoked by tail merging to add unconditional branches in
|
||||
/// cases where AnalyzeBranch doesn't apply because there was no original
|
||||
/// branch to analyze. At least this much must be implemented, else tail
|
||||
/// merging needs to be disabled.
|
||||
unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
|
||||
DebugLoc DL) const override;
|
||||
|
||||
bool analyzeCompare(const MachineInstr *MI,
|
||||
unsigned &SrcReg, unsigned &SrcReg2,
|
||||
int &Mask, int &Value) const override;
|
||||
/// 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.
|
||||
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
|
||||
unsigned ExtraPredCycles,
|
||||
BranchProbability Probability) const override;
|
||||
|
||||
/// 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, 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.
|
||||
bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
|
||||
unsigned NumTCycles, unsigned ExtraTCycles,
|
||||
MachineBasicBlock &FMBB,
|
||||
unsigned NumFCycles, unsigned ExtraFCycles,
|
||||
BranchProbability Probability) const override;
|
||||
|
||||
/// Return true if it's profitable for 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.
|
||||
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
|
||||
BranchProbability Probability) const override;
|
||||
|
||||
/// Emit instructions to copy a pair of physical registers.
|
||||
///
|
||||
/// This function should support copies within any legal register class as
|
||||
/// well as any cross-class copies created during instruction selection.
|
||||
///
|
||||
/// The source and destination registers may overlap, which may require a
|
||||
/// careful implementation when multiple copy instructions are required for
|
||||
/// large registers. See for example the ARM target.
|
||||
void copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I, DebugLoc DL,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const override;
|
||||
|
||||
/// Store the specified register of the given register class to the specified
|
||||
/// stack frame index. The store instruction is to be added to the given
|
||||
/// machine basic block before the specified machine instruction. If isKill
|
||||
/// is true, the register operand is the last use and must be marked kill.
|
||||
void storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI,
|
||||
unsigned SrcReg, bool isKill, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const override;
|
||||
|
||||
void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill,
|
||||
SmallVectorImpl<MachineOperand> &Addr,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||
|
||||
/// Load the specified register of the given register class from the specified
|
||||
/// stack frame index. The load instruction is to be added to the given
|
||||
/// machine basic block before the specified machine instruction.
|
||||
void loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI,
|
||||
unsigned DestReg, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const override;
|
||||
|
||||
void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
|
||||
SmallVectorImpl<MachineOperand> &Addr,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||
|
||||
/// expandPostRAPseudo - This function is called for all pseudo instructions
|
||||
/// This function is called for all pseudo instructions
|
||||
/// that remain after register allocation. Many pseudo instructions are
|
||||
/// created to help register allocation. This is the place to convert them
|
||||
/// into real instructions. The target can edit MI in place, or it can insert
|
||||
@ -111,122 +173,223 @@ public:
|
||||
/// anything was changed.
|
||||
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
|
||||
|
||||
MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
|
||||
ArrayRef<unsigned> Ops,
|
||||
MachineBasicBlock::iterator InsertPt,
|
||||
int FrameIndex) const override;
|
||||
/// Reverses the branch condition of the specified condition list,
|
||||
/// returning false on success and true if it cannot be reversed.
|
||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond)
|
||||
const override;
|
||||
|
||||
MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
|
||||
ArrayRef<unsigned> Ops,
|
||||
MachineBasicBlock::iterator InsertPt,
|
||||
MachineInstr *LoadMI) const override {
|
||||
return nullptr;
|
||||
}
|
||||
/// Insert a noop into the instruction stream at the specified point.
|
||||
void insertNoop(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const override;
|
||||
|
||||
unsigned createVR(MachineFunction* MF, MVT VT) const;
|
||||
/// Returns true if the instruction is already predicated.
|
||||
bool isPredicated(const MachineInstr *MI) const override;
|
||||
|
||||
bool isBranch(const MachineInstr *MI) const;
|
||||
bool isPredicable(MachineInstr *MI) const override;
|
||||
/// Convert the instruction into a predicated instruction.
|
||||
/// It returns true if the operation was successful.
|
||||
bool PredicateInstruction(MachineInstr *MI,
|
||||
ArrayRef<MachineOperand> Cond) const override;
|
||||
|
||||
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
|
||||
unsigned ExtraPredCycles,
|
||||
BranchProbability Probability) const override;
|
||||
|
||||
bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
|
||||
unsigned NumTCycles, unsigned ExtraTCycles,
|
||||
MachineBasicBlock &FMBB,
|
||||
unsigned NumFCycles, unsigned ExtraFCycles,
|
||||
BranchProbability Probability) const override;
|
||||
|
||||
bool isPredicated(const MachineInstr *MI) const override;
|
||||
bool isPredicated(unsigned Opcode) const;
|
||||
bool isPredicatedTrue(const MachineInstr *MI) const;
|
||||
bool isPredicatedTrue(unsigned Opcode) const;
|
||||
bool isPredicatedNew(const MachineInstr *MI) const;
|
||||
bool isPredicatedNew(unsigned Opcode) const;
|
||||
bool DefinesPredicate(MachineInstr *MI,
|
||||
std::vector<MachineOperand> &Pred) const override;
|
||||
/// Returns true if the first specified predicate
|
||||
/// subsumes the second, e.g. GE subsumes GT.
|
||||
bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
|
||||
ArrayRef<MachineOperand> Pred2) const override;
|
||||
|
||||
bool
|
||||
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
|
||||
/// If the specified instruction defines any predicate
|
||||
/// or condition code register(s) used for predication, returns true as well
|
||||
/// as the definition predicate(s) by reference.
|
||||
bool DefinesPredicate(MachineInstr *MI,
|
||||
std::vector<MachineOperand> &Pred) const override;
|
||||
|
||||
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
|
||||
BranchProbability Probability) const override;
|
||||
|
||||
DFAPacketizer *
|
||||
CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override;
|
||||
/// Return true if the specified instruction can be predicated.
|
||||
/// By default, this returns true for every instruction with a
|
||||
/// PredicateOperand.
|
||||
bool isPredicable(MachineInstr *MI) const override;
|
||||
|
||||
/// Test if the given instruction should be considered a scheduling boundary.
|
||||
/// This primarily includes labels and terminators.
|
||||
bool isSchedulingBoundary(const MachineInstr *MI,
|
||||
const MachineBasicBlock *MBB,
|
||||
const MachineFunction &MF) const override;
|
||||
bool isValidOffset(unsigned Opcode, int Offset, bool Extend = true) const;
|
||||
bool isValidAutoIncImm(const EVT VT, const int Offset) const;
|
||||
bool isMemOp(const MachineInstr *MI) const;
|
||||
bool isSpillPredRegOp(const MachineInstr *MI) const;
|
||||
bool isU6_3Immediate(const int value) const;
|
||||
bool isU6_2Immediate(const int value) const;
|
||||
bool isU6_1Immediate(const int value) const;
|
||||
bool isU6_0Immediate(const int value) const;
|
||||
bool isS4_3Immediate(const int value) const;
|
||||
bool isS4_2Immediate(const int value) const;
|
||||
bool isS4_1Immediate(const int value) const;
|
||||
bool isS4_0Immediate(const int value) const;
|
||||
bool isS12_Immediate(const int value) const;
|
||||
bool isU6_Immediate(const int value) const;
|
||||
bool isS8_Immediate(const int value) const;
|
||||
bool isS6_Immediate(const int value) const;
|
||||
|
||||
bool isSaveCalleeSavedRegsCall(const MachineInstr* MI) const;
|
||||
bool isConditionalTransfer(const MachineInstr* MI) const;
|
||||
/// Measure the specified inline asm to determine an approximation of its
|
||||
/// length.
|
||||
unsigned getInlineAsmLength(const char *Str,
|
||||
const MCAsmInfo &MAI) const override;
|
||||
|
||||
/// Allocate and return a hazard recognizer to use for this target when
|
||||
/// scheduling the machine instructions after register allocation.
|
||||
ScheduleHazardRecognizer*
|
||||
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
|
||||
const ScheduleDAG *DAG) const override;
|
||||
|
||||
/// For a comparison instruction, return the source registers
|
||||
/// in SrcReg and SrcReg2 if having two register operands, and the value it
|
||||
/// compares against in CmpValue. Return true if the comparison instruction
|
||||
/// can be analyzed.
|
||||
bool analyzeCompare(const MachineInstr *MI,
|
||||
unsigned &SrcReg, unsigned &SrcReg2,
|
||||
int &Mask, int &Value) const override;
|
||||
|
||||
/// Compute the instruction latency of a given instruction.
|
||||
/// If the instruction has higher cost when predicated, it's returned via
|
||||
/// PredCost.
|
||||
unsigned getInstrLatency(const InstrItineraryData *ItinData,
|
||||
const MachineInstr *MI,
|
||||
unsigned *PredCost = 0) const override;
|
||||
|
||||
/// Create machine specific model for scheduling.
|
||||
DFAPacketizer *
|
||||
CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override;
|
||||
|
||||
// Sometimes, it is possible for the target
|
||||
// to tell, even without aliasing information, that two MIs access different
|
||||
// memory addresses. This function returns true if two MIs access different
|
||||
// memory addresses and false otherwise.
|
||||
bool areMemAccessesTriviallyDisjoint(MachineInstr *MIa, MachineInstr *MIb,
|
||||
AliasAnalysis *AA = nullptr)
|
||||
const override;
|
||||
|
||||
|
||||
/// HexagonInstrInfo specifics.
|
||||
///
|
||||
|
||||
const HexagonRegisterInfo &getRegisterInfo() const { return RI; }
|
||||
|
||||
unsigned createVR(MachineFunction* MF, MVT VT) const;
|
||||
|
||||
bool isAbsoluteSet(const MachineInstr* MI) const;
|
||||
bool isAccumulator(const MachineInstr *MI) const;
|
||||
bool isComplex(const MachineInstr *MI) const;
|
||||
bool isCompoundBranchInstr(const MachineInstr *MI) const;
|
||||
bool isCondInst(const MachineInstr *MI) const;
|
||||
bool isConditionalALU32 (const MachineInstr* MI) const;
|
||||
bool isConditionalLoad (const MachineInstr* MI) const;
|
||||
bool isConditionalLoad(const MachineInstr* MI) const;
|
||||
bool isConditionalStore(const MachineInstr* MI) const;
|
||||
bool isNewValueInst(const MachineInstr* MI) const;
|
||||
bool isNewValue(const MachineInstr* MI) const;
|
||||
bool isNewValue(Opcode_t Opcode) const;
|
||||
bool isDotNewInst(const MachineInstr* MI) const;
|
||||
int GetDotOldOp(const int opc) const;
|
||||
int GetDotNewOp(const MachineInstr* MI) const;
|
||||
int GetDotNewPredOp(MachineInstr *MI,
|
||||
const MachineBranchProbabilityInfo
|
||||
*MBPI) const;
|
||||
bool mayBeNewStore(const MachineInstr* MI) const;
|
||||
bool isConditionalTransfer(const MachineInstr* MI) const;
|
||||
bool isConstExtended(const MachineInstr *MI) const;
|
||||
bool isDeallocRet(const MachineInstr *MI) const;
|
||||
unsigned getInvertedPredicatedOpcode(const int Opc) const;
|
||||
bool isDependent(const MachineInstr *ProdMI,
|
||||
const MachineInstr *ConsMI) const;
|
||||
bool isDotCurInst(const MachineInstr* MI) const;
|
||||
bool isDotNewInst(const MachineInstr* MI) const;
|
||||
bool isDuplexPair(const MachineInstr *MIa, const MachineInstr *MIb) const;
|
||||
bool isEarlySourceInstr(MachineInstr *MI) const;
|
||||
bool isEndLoopN(unsigned Opcode) const;
|
||||
bool isExpr(unsigned OpType) const;
|
||||
bool isExtendable(const MachineInstr* MI) const;
|
||||
bool isExtended(const MachineInstr* MI) const;
|
||||
bool isPostIncrement(const MachineInstr* MI) const;
|
||||
bool isFloat(MachineInstr *MI) const;
|
||||
bool isIndirectCall(const MachineInstr *MI) const;
|
||||
bool isIndirectL4Return(const MachineInstr *MI) const;
|
||||
bool isJumpR(const MachineInstr *MI) const;
|
||||
bool isJumpWithinBranchRange(const MachineInstr *MI, unsigned offset) const;
|
||||
bool isLateInstrFeedsEarlyInstr(MachineInstr *LRMI, MachineInstr *ESMI) const;
|
||||
bool isLateResultInstr(MachineInstr *MI) const;
|
||||
bool isLateSourceInstr(const MachineInstr *MI) const;
|
||||
bool isLoopN(unsigned Opcode) const;
|
||||
bool isMemOp(const MachineInstr *MI) const;
|
||||
bool isNewValue(const MachineInstr* MI) const;
|
||||
bool isNewValue(unsigned Opcode) const;
|
||||
bool isNewValueInst(const MachineInstr* MI) const;
|
||||
bool isNewValueJump(const MachineInstr* MI) const;
|
||||
bool isNewValueJump(unsigned Opcode) const;
|
||||
bool isNewValueStore(const MachineInstr* MI) const;
|
||||
bool isNewValueStore(unsigned Opcode) const;
|
||||
bool isNewValueJump(const MachineInstr* MI) const;
|
||||
bool isNewValueJump(Opcode_t Opcode) const;
|
||||
bool isNewValueJumpCandidate(const MachineInstr *MI) const;
|
||||
bool isOperandExtended(const MachineInstr *MI, unsigned OperandNum) const;
|
||||
bool isPostIncrement(const MachineInstr* MI) const;
|
||||
bool isPredicatedNew(const MachineInstr *MI) const;
|
||||
bool isPredicatedNew(unsigned Opcode) const;
|
||||
bool isPredicatedTrue(const MachineInstr *MI) const;
|
||||
bool isPredicatedTrue(unsigned Opcode) const;
|
||||
bool isPredicated(unsigned Opcode) const;
|
||||
bool isPredicateLate(unsigned Opcode) const;
|
||||
bool isPredictedTaken(unsigned Opcode) const;
|
||||
bool isSaveCalleeSavedRegsCall(const MachineInstr *MI) const;
|
||||
bool isSolo(const MachineInstr* MI) const;
|
||||
bool isSpillPredRegOp(const MachineInstr *MI) const;
|
||||
bool isTC1(const MachineInstr *MI) const;
|
||||
bool isTC2(const MachineInstr *MI) const;
|
||||
bool isTC2Early(const MachineInstr *MI) const;
|
||||
bool isTC4x(const MachineInstr *MI) const;
|
||||
bool isV60VectorInstruction(const MachineInstr *MI) const;
|
||||
bool isValidAutoIncImm(const EVT VT, const int Offset) const;
|
||||
bool isValidOffset(unsigned Opcode, int Offset, bool Extend = true) const;
|
||||
bool isVecAcc(const MachineInstr *MI) const;
|
||||
bool isVecALU(const MachineInstr *MI) const;
|
||||
bool isVecUsableNextPacket(const MachineInstr *ProdMI,
|
||||
const MachineInstr *ConsMI) const;
|
||||
|
||||
|
||||
bool hasEHLabel(const MachineBasicBlock *B) const;
|
||||
bool hasNonExtEquivalent(const MachineInstr *MI) const;
|
||||
bool hasPseudoInstrPair(MachineInstr *MI) const;
|
||||
bool hasUncondBranch(const MachineBasicBlock *B) const;
|
||||
bool mayBeCurLoad(const MachineInstr* MI) const;
|
||||
bool mayBeNewStore(const MachineInstr* MI) const;
|
||||
bool producesStall(const MachineInstr *ProdMI,
|
||||
const MachineInstr *ConsMI) const;
|
||||
bool producesStall(const MachineInstr *MI,
|
||||
MachineBasicBlock::const_instr_iterator MII) const;
|
||||
bool predCanBeUsedAsDotNew(MachineInstr *MI, unsigned PredReg) const;
|
||||
bool PredOpcodeHasJMP_c(unsigned Opcode) const;
|
||||
bool predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const;
|
||||
|
||||
|
||||
unsigned getAddrMode(const MachineInstr* MI) const;
|
||||
unsigned getBaseAndOffset(const MachineInstr *MI, int &Offset,
|
||||
unsigned &AccessSize) const;
|
||||
bool getBaseAndOffsetPosition(const MachineInstr *MI, unsigned &BasePos,
|
||||
unsigned &OffsetPos) const;
|
||||
SmallVector<MachineInstr*,2> getBranchingInstrs(MachineBasicBlock& MBB) const;
|
||||
unsigned getCExtOpNum(const MachineInstr *MI) const;
|
||||
HexagonII::CompoundGroup
|
||||
getCompoundCandidateGroup(const MachineInstr *MI) const;
|
||||
unsigned getCompoundOpcode(const MachineInstr *GA,
|
||||
const MachineInstr *GB) const;
|
||||
int getCondOpcode(int Opc, bool sense) const;
|
||||
int getDotCurOp(const MachineInstr* MI) const;
|
||||
int getDotNewOp(const MachineInstr* MI) const;
|
||||
int getDotNewPredJumpOp(MachineInstr *MI,
|
||||
const MachineBranchProbabilityInfo *MBPI) const;
|
||||
int getDotNewPredOp(MachineInstr *MI,
|
||||
const MachineBranchProbabilityInfo *MBPI) const;
|
||||
int getDotOldOp(const int opc) const;
|
||||
HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr *MI)
|
||||
const;
|
||||
short getEquivalentHWInstr(MachineInstr *MI) const;
|
||||
MachineInstr *getFirstNonDbgInst(MachineBasicBlock *BB) const;
|
||||
unsigned getInstrTimingClassLatency(const InstrItineraryData *ItinData,
|
||||
const MachineInstr *MI) const;
|
||||
bool getInvertedPredSense(SmallVectorImpl<MachineOperand> &Cond) const;
|
||||
unsigned getInvertedPredicatedOpcode(const int Opc) const;
|
||||
int getMaxValue(const MachineInstr *MI) const;
|
||||
unsigned getMemAccessSize(const MachineInstr* MI) const;
|
||||
int getMinValue(const MachineInstr *MI) const;
|
||||
short getNonExtOpcode(const MachineInstr *MI) const;
|
||||
bool getPredReg(ArrayRef<MachineOperand> Cond, unsigned &PredReg,
|
||||
unsigned &PredRegPos, unsigned &PredRegFlags) const;
|
||||
short getPseudoInstrPair(MachineInstr *MI) const;
|
||||
short getRegForm(const MachineInstr *MI) const;
|
||||
unsigned getSize(const MachineInstr *MI) const;
|
||||
uint64_t getType(const MachineInstr* MI) const;
|
||||
unsigned getUnits(const MachineInstr* MI) const;
|
||||
unsigned getValidSubTargets(const unsigned Opcode) const;
|
||||
|
||||
|
||||
/// getInstrTimingClassLatency - Compute the instruction latency of a given
|
||||
/// instruction using Timing Class information, if available.
|
||||
unsigned nonDbgBBSize(const MachineBasicBlock *BB) const;
|
||||
unsigned nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const;
|
||||
|
||||
|
||||
void immediateExtend(MachineInstr *MI) const;
|
||||
bool isConstExtended(const MachineInstr *MI) const;
|
||||
unsigned getSize(const MachineInstr *MI) const;
|
||||
int getDotNewPredJumpOp(MachineInstr *MI,
|
||||
const MachineBranchProbabilityInfo *MBPI) const;
|
||||
unsigned getAddrMode(const MachineInstr* MI) const;
|
||||
bool isOperandExtended(const MachineInstr *MI,
|
||||
unsigned short OperandNum) const;
|
||||
unsigned short getCExtOpNum(const MachineInstr *MI) const;
|
||||
int getMinValue(const MachineInstr *MI) const;
|
||||
int getMaxValue(const MachineInstr *MI) const;
|
||||
bool NonExtEquivalentExists (const MachineInstr *MI) const;
|
||||
short getNonExtOpcode(const MachineInstr *MI) const;
|
||||
bool PredOpcodeHasJMP_c(Opcode_t Opcode) const;
|
||||
bool predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const;
|
||||
bool isEndLoopN(Opcode_t Opcode) const;
|
||||
bool getPredReg(ArrayRef<MachineOperand> Cond, unsigned &PredReg,
|
||||
unsigned &PredRegPos, unsigned &PredRegFlags) const;
|
||||
int getCondOpcode(int Opc, bool sense) const;
|
||||
|
||||
bool invertAndChangeJumpTarget(MachineInstr* MI,
|
||||
MachineBasicBlock* NewTarget) const;
|
||||
void genAllInsnTimingClasses(MachineFunction &MF) const;
|
||||
bool reversePredSense(MachineInstr* MI) const;
|
||||
unsigned reversePrediction(unsigned Opcode) const;
|
||||
bool validateBranchCond(const ArrayRef<MachineOperand> &Cond) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ namespace {
|
||||
/// \brief A handle to the branch probability pass.
|
||||
const MachineBranchProbabilityInfo *MBPI;
|
||||
|
||||
bool isNewValueJumpCandidate(const MachineInstr *MI) const;
|
||||
};
|
||||
|
||||
} // end of anonymous namespace
|
||||
@ -280,9 +281,9 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Given a compare operator, return a matching New Value Jump
|
||||
// compare operator. Make sure that MI here is included in
|
||||
// HexagonInstrInfo.cpp::isNewValueJumpCandidate
|
||||
|
||||
// Given a compare operator, return a matching New Value Jump compare operator.
|
||||
// Make sure that MI here is included in isNewValueJumpCandidate.
|
||||
static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
|
||||
bool secondRegNewified,
|
||||
MachineBasicBlock *jmpTarget,
|
||||
@ -348,6 +349,26 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool HexagonNewValueJump::isNewValueJumpCandidate(const MachineInstr *MI)
|
||||
const {
|
||||
switch (MI->getOpcode()) {
|
||||
case Hexagon::C2_cmpeq:
|
||||
case Hexagon::C2_cmpeqi:
|
||||
case Hexagon::C2_cmpgt:
|
||||
case Hexagon::C2_cmpgti:
|
||||
case Hexagon::C2_cmpgtu:
|
||||
case Hexagon::C2_cmpgtui:
|
||||
case Hexagon::C4_cmpneq:
|
||||
case Hexagon::C4_cmplte:
|
||||
case Hexagon::C4_cmplteu:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
||||
DEBUG(dbgs() << "********** Hexagon New Value Jump **********\n"
|
||||
@ -468,7 +489,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
||||
MI->getOperand(0).getReg() == predReg) {
|
||||
|
||||
// Not all compares can be new value compare. Arch Spec: 7.6.1.1
|
||||
if (QII->isNewValueJumpCandidate(MI)) {
|
||||
if (isNewValueJumpCandidate(MI)) {
|
||||
|
||||
assert((MI->getDesc().isCompare()) &&
|
||||
"Only compare instruction can be collapsed into New Value Jump");
|
||||
@ -591,8 +612,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
||||
DebugLoc dl = MI->getDebugLoc();
|
||||
MachineInstr *NewMI;
|
||||
|
||||
assert((QII->isNewValueJumpCandidate(cmpInstr)) &&
|
||||
"This compare is not a New Value Jump candidate.");
|
||||
assert((isNewValueJumpCandidate(cmpInstr)) &&
|
||||
"This compare is not a New Value Jump candidate.");
|
||||
unsigned opc = getNewValueJumpOpcode(cmpInstr, cmpOp2,
|
||||
isSecondOpNewified,
|
||||
jmpTarget, MBPI);
|
||||
|
@ -35,7 +35,7 @@ def SLOT_ENDLOOP: FuncUnit;
|
||||
|
||||
// Itinerary classes.
|
||||
def PSEUDO : InstrItinClass;
|
||||
def PSEUDOM : InstrItinClass;
|
||||
def PSEUDOM : InstrItinClass;
|
||||
// ALU64/M/S Instruction classes of V2 are collectively knownn as XTYPE in V4.
|
||||
def DUPLEX : InstrItinClass;
|
||||
def PREFIX : InstrItinClass;
|
||||
|
@ -24,10 +24,6 @@ using namespace llvm;
|
||||
#define GET_SUBTARGETINFO_TARGET_DESC
|
||||
#include "HexagonGenSubtargetInfo.inc"
|
||||
|
||||
static cl::opt<bool>
|
||||
EnableV3("enable-hexagon-v3", cl::Hidden,
|
||||
cl::desc("Enable Hexagon V3 instructions."));
|
||||
|
||||
static cl::opt<bool>
|
||||
EnableMemOps(
|
||||
"enable-hexagon-memops",
|
||||
@ -48,6 +44,9 @@ EnableIEEERndNear(
|
||||
cl::Hidden, cl::ZeroOrMore, cl::init(false),
|
||||
cl::desc("Generate non-chopped conversion from fp to int."));
|
||||
|
||||
static cl::opt<bool> EnableBSBSched("enable-bsb-sched",
|
||||
cl::Hidden, cl::ZeroOrMore, cl::init(true));
|
||||
|
||||
static cl::opt<bool> DisableHexagonMISched("disable-hexagon-misched",
|
||||
cl::Hidden, cl::ZeroOrMore, cl::init(false),
|
||||
cl::desc("Disable Hexagon MI Scheduling"));
|
||||
@ -91,6 +90,8 @@ HexagonSubtarget::HexagonSubtarget(const Triple &TT, StringRef CPU,
|
||||
ModeIEEERndNear = true;
|
||||
else
|
||||
ModeIEEERndNear = false;
|
||||
|
||||
UseBSBScheduling = hasV60TOps() && EnableBSBSched;
|
||||
}
|
||||
|
||||
// Pin the vtable to this file.
|
||||
|
@ -43,6 +43,10 @@ public:
|
||||
};
|
||||
|
||||
HexagonArchEnum HexagonArchVersion;
|
||||
/// True if the target should use Back-Skip-Back scheduling. This is the
|
||||
/// default for V60.
|
||||
bool UseBSBScheduling;
|
||||
|
||||
private:
|
||||
std::string CPUString;
|
||||
HexagonInstrInfo InstrInfo;
|
||||
@ -89,6 +93,8 @@ public:
|
||||
bool modeIEEERndNear() const { return ModeIEEERndNear; }
|
||||
bool useHVXDblOps() const { return UseHVXDblOps; }
|
||||
bool useHVXSglOps() const { return UseHVXOps && !UseHVXDblOps; }
|
||||
|
||||
bool useBSBScheduling() const { return UseBSBScheduling; }
|
||||
bool enableMachineScheduler() const override;
|
||||
// Always use the TargetLowering default scheduler.
|
||||
// FIXME: This will use the vliw scheduler which is probably just hurting
|
||||
|
@ -432,9 +432,9 @@ bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI,
|
||||
|
||||
int NewOpcode;
|
||||
if (RC == &Hexagon::PredRegsRegClass)
|
||||
NewOpcode = QII->GetDotNewPredOp(MI, MBPI);
|
||||
NewOpcode = QII->getDotNewPredOp(MI, MBPI);
|
||||
else
|
||||
NewOpcode = QII->GetDotNewOp(MI);
|
||||
NewOpcode = QII->getDotNewOp(MI);
|
||||
MI->setDesc(QII->get(NewOpcode));
|
||||
|
||||
return true;
|
||||
@ -442,7 +442,7 @@ bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI,
|
||||
|
||||
bool HexagonPacketizerList::DemoteToDotOld(MachineInstr* MI) {
|
||||
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
|
||||
int NewOpcode = QII->GetDotOldOp(MI->getOpcode());
|
||||
int NewOpcode = QII->getDotOldOp(MI->getOpcode());
|
||||
MI->setDesc(QII->get(NewOpcode));
|
||||
return true;
|
||||
}
|
||||
@ -757,7 +757,7 @@ bool HexagonPacketizerList::CanPromoteToDotNew(
|
||||
else {
|
||||
// Create a dot new machine instruction to see if resources can be
|
||||
// allocated. If not, bail out now.
|
||||
int NewOpcode = QII->GetDotNewOp(MI);
|
||||
int NewOpcode = QII->getDotNewOp(MI);
|
||||
const MCInstrDesc &desc = QII->get(NewOpcode);
|
||||
DebugLoc dl;
|
||||
MachineInstr *NewMI =
|
||||
|
@ -191,7 +191,15 @@ namespace HexagonII {
|
||||
|
||||
// Which operand consumes or produces a new value.
|
||||
NewValueOpPos2 = 51,
|
||||
NewValueOpMask2 = 0x7
|
||||
NewValueOpMask2 = 0x7,
|
||||
|
||||
// Accumulator instructions.
|
||||
AccumulatorPos = 54,
|
||||
AccumulatorMask = 0x1,
|
||||
|
||||
// Complex XU, prevent xu competition by prefering slot3
|
||||
PrefersSlot3Pos = 55,
|
||||
PrefersSlot3Mask = 0x1,
|
||||
};
|
||||
|
||||
// *** The code above must match HexagonInstrFormat*.td *** //
|
||||
|
Loading…
x
Reference in New Issue
Block a user