Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -1010,6 +1010,10 @@ bool shouldExpandReduction(const IntrinsicInst *II) const; /// @} + /// \returns True if loop idiom recognition is allowed to generate + /// memset, mempcy, or memmove for the given optimization level. + bool shouldAllowLIR(bool OptForSize) const; + private: /// Estimate the latency of specified instruction. /// Returns 1 as the default value. @@ -1214,6 +1218,7 @@ virtual bool useReductionIntrinsic(unsigned Opcode, Type *Ty, ReductionFlags) const = 0; virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0; + virtual bool shouldAllowLIR(bool OptForSize) const = 0; virtual int getInstructionLatency(const Instruction *I) = 0; }; @@ -1621,9 +1626,15 @@ ReductionFlags Flags) const override { return Impl.useReductionIntrinsic(Opcode, Ty, Flags); } + bool shouldExpandReduction(const IntrinsicInst *II) const override { return Impl.shouldExpandReduction(II); } + + bool shouldAllowLIR(bool OptForSize) const override { + return Impl.shouldAllowLIR(OptForSize); + } + int getInstructionLatency(const Instruction *I) override { return Impl.getInstructionLatency(I); } Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -584,6 +584,10 @@ return true; } + bool shouldAllowLIR(bool OptForSize) const { + return true; + } + protected: // Obtain the minimum required size to hold the value (without the sign) // In case of a vector it returns the min required size for one element. Index: include/llvm/CodeGen/BasicTTIImpl.h =================================================================== --- include/llvm/CodeGen/BasicTTIImpl.h +++ include/llvm/CodeGen/BasicTTIImpl.h @@ -1609,6 +1609,8 @@ unsigned getVectorSplitCost() { return 1; } + bool shouldAllowLIR(bool) const { return true; } + /// @} }; Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -691,6 +691,10 @@ return TTIImpl->shouldExpandReduction(II); } +bool TargetTransformInfo::shouldAllowLIR(bool OptForSize) const { + return TTIImpl->shouldAllowLIR(OptForSize); +} + int TargetTransformInfo::getInstructionLatency(const Instruction *I) const { return TTIImpl->getInstructionLatency(I); } Index: lib/Target/RISCV/RISCVTargetMachine.h =================================================================== --- lib/Target/RISCV/RISCVTargetMachine.h +++ lib/Target/RISCV/RISCVTargetMachine.h @@ -36,6 +36,8 @@ TargetPassConfig *createPassConfig(PassManagerBase &PM) override; + TargetTransformInfo getTargetTransformInfo(const Function &F) override; + TargetLoweringObjectFile *getObjFileLowering() const override { return TLOF.get(); } Index: lib/Target/RISCV/RISCVTargetMachine.cpp =================================================================== --- lib/Target/RISCV/RISCVTargetMachine.cpp +++ lib/Target/RISCV/RISCVTargetMachine.cpp @@ -12,6 +12,7 @@ #include "RISCV.h" #include "RISCVTargetMachine.h" +#include "RISCVTargetTransformInfo.h" #include "RISCVTargetObjectFile.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/Passes.h" @@ -78,6 +79,11 @@ }; } +TargetTransformInfo +RISCVTargetMachine::getTargetTransformInfo(const Function &F) { + return TargetTransformInfo(RISCVTTIImpl(this, F)); +} + TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) { return new RISCVPassConfig(*this, PM); } Index: lib/Target/RISCV/RISCVTargetTransformInfo.h =================================================================== --- /dev/null +++ lib/Target/RISCV/RISCVTargetTransformInfo.h @@ -0,0 +1,46 @@ +//===- RISCVTargetTransformInfo.h - RISCV specific TTI ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H +#define LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H + +#include "RISCV.h" +#include "RISCVSubtarget.h" +#include "RISCVTargetMachine.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/BasicTTIImpl.h" +#include "llvm/IR/Function.h" +#include "llvm/MC/SubtargetFeature.h" + +namespace llvm { + +class RISCVTTIImpl : public BasicTTIImplBase { + using BaseT = BasicTTIImplBase; + using TTI = TargetTransformInfo; + + friend BaseT; + + const RISCVSubtarget *ST; + const RISCVTargetLowering *TLI; + + const RISCVSubtarget *getST() const { return ST; } + const RISCVTargetLowering *getTLI() const { return TLI; } + +public: + explicit RISCVTTIImpl(const RISCVTargetMachine *TM, const Function &F) + : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), + TLI(ST->getTargetLowering()) {} + + bool shouldAllowLIR(bool OptForSize) const { + // When building for code size do not implement loop idiom recognition. + return !OptForSize; + } +}; +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H Index: lib/Transforms/Scalar/LoopIdiomRecognize.cpp =================================================================== --- lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -120,6 +120,7 @@ const TargetTransformInfo *TTI; const DataLayout *DL; bool ApplyCodeSizeHeuristics; + bool OptForSize; public: explicit LoopIdiomRecognize(AliasAnalysis *AA, DominatorTree *DT, @@ -283,8 +284,8 @@ return false; // Determine if code size heuristics need to be applied. - ApplyCodeSizeHeuristics = - L->getHeader()->getParent()->optForSize() && UseLIRCodeSizeHeurs; + OptForSize = L->getHeader()->getParent()->optForSize(); + ApplyCodeSizeHeuristics = OptForSize && UseLIRCodeSizeHeurs; HasMemset = TLI->has(LibFunc_memset); HasMemsetPattern = TLI->has(LibFunc_memset_pattern16); @@ -904,6 +905,9 @@ return false; } + if (!TTI->shouldAllowLIR(OptForSize)) + return false; + if (avoidLIRForMultiBlockLoop(/*IsMemset=*/true, IsLoopMemset)) return false; @@ -1036,6 +1040,9 @@ return false; } + if (!TTI->shouldAllowLIR(OptForSize)) + return false; + if (avoidLIRForMultiBlockLoop()) return false;