diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/MergeICmps.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/MergeICmps.cpp | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/MergeICmps.cpp b/llvm/lib/Transforms/Scalar/MergeICmps.cpp index a56cffcdfa0..a8e109db3a2 100644 --- a/llvm/lib/Transforms/Scalar/MergeICmps.cpp +++ b/llvm/lib/Transforms/Scalar/MergeICmps.cpp @@ -28,6 +28,8 @@ #include <vector> #include "llvm/ADT/APSInt.h" #include "llvm/Analysis/Loads.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/IntrinsicInst.h" @@ -41,8 +43,6 @@ namespace { #define DEBUG_TYPE "mergeicmps" -#define MERGEICMPS_DOT_ON - // A BCE atom. struct BCEAtom { BCEAtom() : GEP(nullptr), LoadI(nullptr), Offset() {} @@ -430,10 +430,16 @@ void BCECmpChain::mergeComparisons(ArrayRef<BCECmpBlock> Comparisons, IRBuilder<> Builder(BB); const auto &DL = Phi.getModule()->getDataLayout(); - Value *const MemCmpCall = - emitMemCmp(FirstComparison.Lhs().GEP, FirstComparison.Rhs().GEP, - ConstantInt::get(DL.getIntPtrType(Context), TotalSize), - Builder, DL, TLI); + GetElementPtrInst *LhsArg = FirstComparison.Lhs().GEP; + GetElementPtrInst *RhsArg = FirstComparison.Rhs().GEP; + // If the values are named, use the smaller name as first argument to + // memcmp() so that results are reproducible. + if (LhsArg->hasName() && RhsArg->hasName() && + LhsArg->getName() > RhsArg->getName()) + std::swap(LhsArg, RhsArg); + Value *const MemCmpCall = emitMemCmp( + LhsArg, RhsArg, ConstantInt::get(DL.getIntPtrType(Context), TotalSize), + Builder, DL, TLI); Value *const MemCmpIsZero = Builder.CreateICmpEQ( MemCmpCall, ConstantInt::get(Type::getInt32Ty(Context), 0)); @@ -589,22 +595,30 @@ class MergeICmps : public FunctionPass { bool runOnFunction(Function &F) override { if (skipFunction(F)) return false; const auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); - auto PA = runImpl(F, &TLI); + const auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); + auto PA = runImpl(F, &TLI, &TTI); return !PA.areAllPreserved(); } private: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<TargetLibraryInfoWrapperPass>(); + AU.addRequired<TargetTransformInfoWrapperPass>(); } - PreservedAnalyses runImpl(Function &F, const TargetLibraryInfo *TLI); + PreservedAnalyses runImpl(Function &F, const TargetLibraryInfo *TLI, + const TargetTransformInfo *TTI); }; -PreservedAnalyses MergeICmps::runImpl(Function &F, - const TargetLibraryInfo *TLI) { +PreservedAnalyses MergeICmps::runImpl(Function &F, const TargetLibraryInfo *TLI, + const TargetTransformInfo *TTI) { DEBUG(dbgs() << "MergeICmpsPass: " << F.getName() << "\n"); + // We only try merging comparisons if the target wants to expand memcmp later. + // The rationale is to avoid turning small chains into memcmp calls. + unsigned MaxLoadSize; + if (!TTI->enableMemCmpExpansion(MaxLoadSize)) return PreservedAnalyses::all(); + bool MadeChange = false; for (auto BBIt = ++F.begin(); BBIt != F.end(); ++BBIt) { @@ -623,6 +637,7 @@ char MergeICmps::ID = 0; INITIALIZE_PASS_BEGIN(MergeICmps, "mergeicmps", "Merge contiguous icmps into a memcmp", false, false) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_END(MergeICmps, "mergeicmps", "Merge contiguous icmps into a memcmp", false, false) |