Index: include/llvm/Target/TargetInstrInfo.h =================================================================== --- include/llvm/Target/TargetInstrInfo.h +++ include/llvm/Target/TargetInstrInfo.h @@ -586,6 +586,16 @@ ArrayRef(), DL, BytesAdded); } + /// For a machine block that contains the loop thest, return the source + /// registers of the loop test 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. + virtual bool analyzeLoopTestBlock(MachineBasicBlock &MB, unsigned &CmpReg1, + unsigned &CmpReg2, int &CmpMask, + int &CmpImm) const { + return false; + } + /// Analyze the loop code, return true if it cannot be understoo. Upon /// success, this function returns false and returns information about the /// induction variable and compare instruction used at the end. Index: lib/Target/Hexagon/HexagonInstrInfo.h =================================================================== --- lib/Target/Hexagon/HexagonInstrInfo.h +++ lib/Target/Hexagon/HexagonInstrInfo.h @@ -248,6 +248,11 @@ CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, const ScheduleDAG *DAG) const override; + /// Returns true when MB contains a compare with an immediate value + bool analyzeLoopTestBlock(MachineBasicBlock &MB, unsigned &CmpReg1, + unsigned &CmpReg2, int &CmpMask, + int &CmpImm) 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 Index: lib/Target/Hexagon/HexagonInstrInfo.cpp =================================================================== --- lib/Target/Hexagon/HexagonInstrInfo.cpp +++ lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1513,6 +1513,37 @@ return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG); } +/// return the source registers in +/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it +/// compares against in CmpValue. Return true if the comparison instruction +/// can be analyzed. +bool HexagonInstrInfo::analyzeLoopTestBlock(MachineBasicBlock &MB, + unsigned &CmpReg1, + unsigned &CmpReg2, + int &CmpMask, int &CmpImm) const { + SmallVector Cond; + MachineBasicBlock *TB = nullptr, *FB = nullptr; + bool NotAnalyzed = analyzeBranch(MB, TB, FB, Cond, false); + if (NotAnalyzed) + return false; + + unsigned PredR, PredPos, PredRegFlags; + if (!getPredReg(Cond, PredR, PredPos, PredRegFlags)) + return false; + + MachineRegisterInfo &MRI = MB.getParent()->getRegInfo(); + MachineInstr *PredI = MRI.getVRegDef(PredR); + if (!PredI->isCompare()) + return false; + + // Fail if the compare was not analyzed, or it's not comparing a register + // with an immediate value. Not checking the mask here, since we handle + // the individual compare opcodes (including A4_cmpb*) later on. + if (!analyzeCompare(*PredI, CmpReg1, CmpReg2, CmpMask, CmpImm)) + return false; + + return true; +} /// \brief For a comparison instruction, return the source registers in /// \p SrcReg and \p SrcReg2 if having two register operands, and the value it