Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -53,6 +53,17 @@ Value *PtrVal; }; +/// \brief This class provides a function that implements target-specific +/// loop idiom recognition. Targets that want to handle specific loop idioms +/// should implement this class and return a pointer to it from their +/// respective TTI implementations. +/// See \c TargetTransformInfo::getTargetLoopIdiomRecognize below. +class TargetLoopIdiomRecognize { +public: + virtual bool run(Pass *P, Loop *L) = 0; + virtual ~TargetLoopIdiomRecognize() {} +}; + /// \brief This pass provides access to the codegen interfaces that are needed /// for IR-level transformations. class TargetTransformInfo { @@ -378,6 +389,12 @@ Type *Ty) const; int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty) const; + + /// \brief Get a class implementing target-specific loop idiom recognition, + /// or nullptr if the target does not require handling of specific loop + /// idioms. + TargetLoopIdiomRecognize *getTargetLoopIdiomRecognize() const; + /// @} /// \name Vector Target Information @@ -586,6 +603,7 @@ Type *Ty) = 0; virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty) = 0; + virtual TargetLoopIdiomRecognize *getTargetLoopIdiomRecognize() = 0; virtual unsigned getNumberOfRegisters(bool Vector) = 0; virtual unsigned getRegisterBitWidth(bool Vector) = 0; virtual unsigned getMaxInterleaveFactor(unsigned VF) = 0; @@ -737,6 +755,9 @@ Type *Ty) override { return Impl.getIntImmCost(IID, Idx, Imm, Ty); } + TargetLoopIdiomRecognize *getTargetLoopIdiomRecognize() override { + return Impl.getTargetLoopIdiomRecognize(); + } unsigned getNumberOfRegisters(bool Vector) override { return Impl.getNumberOfRegisters(Vector); } Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -250,6 +250,8 @@ return TTI::TCC_Free; } + TargetLoopIdiomRecognize *getTargetLoopIdiomRecognize() { return nullptr; } + unsigned getNumberOfRegisters(bool Vector) { return 8; } unsigned getRegisterBitWidth(bool Vector) { return 32; } Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -201,6 +201,11 @@ return Cost; } +TargetLoopIdiomRecognize *TargetTransformInfo::getTargetLoopIdiomRecognize() + const { + return TTIImpl->getTargetLoopIdiomRecognize(); +} + unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const { return TTIImpl->getNumberOfRegisters(Vector); } Index: lib/Target/Hexagon/CMakeLists.txt =================================================================== --- lib/Target/Hexagon/CMakeLists.txt +++ lib/Target/Hexagon/CMakeLists.txt @@ -30,6 +30,7 @@ HexagonInstrInfo.cpp HexagonISelDAGToDAG.cpp HexagonISelLowering.cpp + HexagonLoopIdiomRecognize.cpp HexagonMachineFunctionInfo.cpp HexagonMachineScheduler.cpp HexagonMCInstLower.cpp Index: lib/Target/Hexagon/HexagonLoopIdiomRecognize.h =================================================================== --- /dev/null +++ lib/Target/Hexagon/HexagonLoopIdiomRecognize.h @@ -0,0 +1,12 @@ +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Pass.h" + +using namespace llvm; + +namespace llvm { + class HexagonLoopIdiomRecognize : public TargetLoopIdiomRecognize { + public: + bool run(Pass *P, Loop *L) override; + }; +} Index: lib/Target/Hexagon/HexagonLoopIdiomRecognize.cpp =================================================================== --- /dev/null +++ lib/Target/Hexagon/HexagonLoopIdiomRecognize.cpp @@ -0,0 +1,38 @@ +#define DEBUG_TYPE "hexidiom" + +#include "HexagonLoopIdiomRecognize.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/Dominators.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/PatternMatch.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Utils/Local.h" + +using namespace llvm; + +bool llvm::HexagonLoopIdiomRecognize::run(Pass *P, Loop *L) { + BasicBlock *Header = L->getHeader(); + if (!Header) + return false; + + auto *DL = &Header->getParent()->getParent()->getDataLayout(); + auto *DTW = P->getAnalysisIfAvailable(); + auto *TLIW = P->getAnalysisIfAvailable(); + auto *SE = P->getAnalysisIfAvailable(); + + (void)DL; + if (!DTW || !TLIW || !SE) + return false; + + dbgs() << "Hello, all is in order\n"; + return false; +} + Index: lib/Target/Hexagon/HexagonTargetMachine.cpp =================================================================== --- lib/Target/Hexagon/HexagonTargetMachine.cpp +++ lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -138,9 +138,11 @@ return I.get(); } +static HexagonLoopIdiomRecognize HLIR; + TargetIRAnalysis HexagonTargetMachine::getTargetIRAnalysis() { return TargetIRAnalysis([this](Function &F) { - return TargetTransformInfo(HexagonTTIImpl(this, F)); + return TargetTransformInfo(HexagonTTIImpl(this, F, &HLIR)); }); } Index: lib/Target/Hexagon/HexagonTargetTransformInfo.h =================================================================== --- lib/Target/Hexagon/HexagonTargetTransformInfo.h +++ lib/Target/Hexagon/HexagonTargetTransformInfo.h @@ -18,6 +18,7 @@ #include "Hexagon.h" #include "HexagonTargetMachine.h" +#include "HexagonLoopIdiomRecognize.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/CodeGen/BasicTTIImpl.h" #include "llvm/Target/TargetLowering.h" @@ -31,21 +32,24 @@ const HexagonSubtarget *ST; const HexagonTargetLowering *TLI; + HexagonLoopIdiomRecognize *HLIR; const HexagonSubtarget *getST() const { return ST; } const HexagonTargetLowering *getTLI() const { return TLI; } public: - explicit HexagonTTIImpl(const HexagonTargetMachine *TM, Function &F) + explicit HexagonTTIImpl(const HexagonTargetMachine *TM, Function &F, + HexagonLoopIdiomRecognize *LIR) : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), - TLI(ST->getTargetLowering()) {} + TLI(ST->getTargetLowering()), HLIR(LIR) {} // Provide value semantics. MSVC requires that we spell all of these out. HexagonTTIImpl(const HexagonTTIImpl &Arg) - : BaseT(static_cast(Arg)), ST(Arg.ST), TLI(Arg.TLI) {} + : BaseT(static_cast(Arg)), ST(Arg.ST), TLI(Arg.TLI), + HLIR(Arg.HLIR) {} HexagonTTIImpl(HexagonTTIImpl &&Arg) : BaseT(std::move(static_cast(Arg))), ST(std::move(Arg.ST)), - TLI(std::move(Arg.TLI)) {} + TLI(std::move(Arg.TLI)), HLIR(std::move(Arg.HLIR)) {} /// \name Scalar TTI Implementations /// @{ @@ -55,6 +59,10 @@ // The Hexagon target can unroll loops with run-time trip counts. void getUnrollingPreferences(Loop *L, TTI::UnrollingPreferences &UP); + HexagonLoopIdiomRecognize *getTargetLoopIdiomRecognize() const { + return HLIR; + } + /// @} /// \name Vector TTI Implementations Index: lib/Transforms/Scalar/LoopIdiomRecognize.cpp =================================================================== --- lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -674,9 +674,14 @@ return false; SE = &getAnalysis(); - if (SE->hasLoopInvariantBackedgeTakenCount(L)) - return runOnCountableLoop(); - return runOnNoncountableLoop(); + bool HasInvCount = SE->hasLoopInvariantBackedgeTakenCount(L); + bool Changed = HasInvCount ? runOnCountableLoop() + : runOnNoncountableLoop(); + + if (auto *TLIR = getTargetTransformInfo()->getTargetLoopIdiomRecognize()) + Changed |= TLIR->run(this, L); + + return Changed; } /// runOnLoopBlock - Process the specified block, which lives in a counted loop