[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:
Krzysztof Parzyszek 2015-11-24 14:55:26 +00:00
parent 42fec0866c
commit 8e716832ef
9 changed files with 3187 additions and 1356 deletions

View File

@ -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

View File

@ -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;
};
}

View File

@ -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);

View File

@ -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;

View File

@ -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.

View 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

View File

@ -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 =

View File

@ -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 *** //