Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -493,6 +493,9 @@ /// containing this constant value for the target. bool shouldBuildLookupTablesForConstant(Constant *C) const; + bool shouldThreadJumpIntoLoopHeader(Instruction *Branch, + BasicBlock *Header) const; + unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const; unsigned getOperandsScalarizationOverhead(ArrayRef Args, @@ -912,6 +915,8 @@ virtual unsigned getJumpBufSize() = 0; virtual bool shouldBuildLookupTables() = 0; virtual bool shouldBuildLookupTablesForConstant(Constant *C) = 0; + virtual bool shouldThreadJumpIntoLoopHeader(Instruction *Branch, + BasicBlock *Header) = 0; virtual unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) = 0; virtual unsigned getOperandsScalarizationOverhead(ArrayRef Args, @@ -1147,6 +1152,10 @@ bool shouldBuildLookupTablesForConstant(Constant *C) override { return Impl.shouldBuildLookupTablesForConstant(C); } + bool shouldThreadJumpIntoLoopHeader(Instruction *Branch, + BasicBlock *Header) override { + return Impl.shouldThreadJumpIntoLoopHeader(Branch, Header); + } unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) override { return Impl.getScalarizationOverhead(Ty, Insert, Extract); Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -278,7 +278,9 @@ bool shouldBuildLookupTables() { return true; } bool shouldBuildLookupTablesForConstant(Constant *C) { return true; } - + bool shouldThreadJumpIntoLoopHeader(Instruction *Branch, BasicBlock *Header) { + return true; + } unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) { return 0; } Index: include/llvm/Transforms/Scalar/JumpThreading.h =================================================================== --- include/llvm/Transforms/Scalar/JumpThreading.h +++ include/llvm/Transforms/Scalar/JumpThreading.h @@ -23,6 +23,7 @@ #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/LazyValueInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/ValueHandle.h" @@ -60,6 +61,7 @@ /// class JumpThreadingPass : public PassInfoMixin { TargetLibraryInfo *TLI; + TargetTransformInfo *TTI; LazyValueInfo *LVI; AliasAnalysis *AA; std::unique_ptr BFI; @@ -91,8 +93,8 @@ JumpThreadingPass(int T = -1); // Glue for old PM. - bool runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo *LVI_, - AliasAnalysis *AA_, bool HasProfileData_, + bool runImpl(Function &F, TargetLibraryInfo *TLI_, TargetTransformInfo *TTI_, + LazyValueInfo *LVI_, AliasAnalysis *AA_, bool HasProfileData_, std::unique_ptr BFI_, std::unique_ptr BPI_); Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -221,6 +221,11 @@ return TTIImpl->shouldBuildLookupTablesForConstant(C); } +bool TargetTransformInfo::shouldThreadJumpIntoLoopHeader(Instruction *Branch, + BasicBlock *Header) const { + return TTIImpl->shouldThreadJumpIntoLoopHeader(Branch, Header); +} + unsigned TargetTransformInfo:: getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const { return TTIImpl->getScalarizationOverhead(Ty, Insert, Extract); Index: lib/Target/Hexagon/HexagonTargetTransformInfo.h =================================================================== --- lib/Target/Hexagon/HexagonTargetTransformInfo.h +++ lib/Target/Hexagon/HexagonTargetTransformInfo.h @@ -74,6 +74,11 @@ // Hexagon specific decision to generate a lookup table. bool shouldBuildLookupTables() const; + + bool shouldThreadJumpIntoLoopHeader(Instruction *Branch, + BasicBlock *Header) const { + return false; + } }; } // end namespace llvm Index: lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- lib/Transforms/Scalar/JumpThreading.cpp +++ lib/Transforms/Scalar/JumpThreading.cpp @@ -24,6 +24,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/DataLayout.h" @@ -104,6 +105,7 @@ AU.addRequired(); AU.addPreserved(); AU.addRequired(); + AU.addRequired(); } void releaseMemory() override { Impl.releaseMemory(); } @@ -115,6 +117,7 @@ "Jump Threading", false, false) INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(JumpThreading, "jump-threading", "Jump Threading", false, false) @@ -132,6 +135,7 @@ if (skipFunction(F)) return false; auto TLI = &getAnalysis().getTLI(); + auto TTI = &getAnalysis().getTTI(F); auto LVI = &getAnalysis().getLVI(); auto AA = &getAnalysis().getAAResults(); std::unique_ptr BFI; @@ -143,8 +147,8 @@ BFI.reset(new BlockFrequencyInfo(F, *BPI, LI)); } - bool Changed = Impl.runImpl(F, TLI, LVI, AA, HasProfileData, std::move(BFI), - std::move(BPI)); + bool Changed = Impl.runImpl(F, TLI, TTI, LVI, AA, HasProfileData, + std::move(BFI), std::move(BPI)); if (PrintLVIAfterJumpThreading) { dbgs() << "LVI for function '" << F.getName() << "':\n"; LVI->printLVI(F, getAnalysis().getDomTree(), @@ -157,6 +161,7 @@ FunctionAnalysisManager &AM) { auto &TLI = AM.getResult(F); + auto &TTI = AM.getResult(F); auto &LVI = AM.getResult(F); auto &AA = AM.getResult(F); @@ -169,8 +174,8 @@ BFI.reset(new BlockFrequencyInfo(F, *BPI, LI)); } - bool Changed = runImpl(F, &TLI, &LVI, &AA, HasProfileData, std::move(BFI), - std::move(BPI)); + bool Changed = runImpl(F, &TLI, &TTI, &LVI, &AA, HasProfileData, + std::move(BFI), std::move(BPI)); if (!Changed) return PreservedAnalyses::all(); @@ -180,6 +185,7 @@ } bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, + TargetTransformInfo *TTI_, LazyValueInfo *LVI_, AliasAnalysis *AA_, bool HasProfileData_, std::unique_ptr BFI_, @@ -187,6 +193,7 @@ DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n"); TLI = TLI_; + TTI = TTI_; LVI = LVI_; AA = AA_; BFI.reset(); @@ -1684,6 +1691,11 @@ return false; } + if (LoopHeaders.count(SuccBB)) { + if (!TTI->shouldThreadJumpIntoLoopHeader(BB->getTerminator(), SuccBB)) + return false; + } + unsigned JumpThreadCost = getJumpThreadDuplicationCost(BB, BB->getTerminator(), BBDupThreshold); if (JumpThreadCost > BBDupThreshold) { Index: test/CodeGen/Hexagon/jump-threading-headers.ll =================================================================== --- /dev/null +++ test/CodeGen/Hexagon/jump-threading-headers.ll @@ -0,0 +1,32 @@ +; RUN: opt -march=hexagon -jump-threading -correlated-propagation -loop-simplify -S < %s | FileCheck %s + +; Make sure that we don't thread jumps into the loop header on Hexagon. +; CHECK-NOT: header.outer + +target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048" +target triple = "hexagon" + +define void @fred(i32 %a0) #0 { +b1: + br label %header + +header: ; preds = %b8, %b1 + %v3 = phi <16 x i32>* [ undef, %b1 ], [ %v9, %b8 ] + %v4 = phi i32 [ %a0, %b1 ], [ undef, %b8 ] + %v5 = icmp sgt i32 %v4, 128 + br i1 %v5, label %b6, label %b8 + +b6: ; preds = %header + %v7 = getelementptr inbounds <16 x i32>, <16 x i32>* %v3, i32 1 + br label %b8 + +b8: ; preds = %b6, %header + %v9 = phi <16 x i32>* [ %v7, %b6 ], [ %v3, %header ] + %v10 = icmp sgt i32 %v4, 64 + br i1 %v10, label %header, label %b11 + +b11: ; preds = %b8 + ret void +} + +attributes #0 = { nounwind } Index: test/Other/new-pm-lto-defaults.ll =================================================================== --- test/Other/new-pm-lto-defaults.ll +++ test/Other/new-pm-lto-defaults.ll @@ -64,13 +64,13 @@ ; CHECK-O2-NEXT: Running pass: InstCombinePass ; CHECK-EP-Peephole-NEXT: Running pass: NoOpFunctionPass ; CHECK-O2-NEXT: Running pass: JumpThreadingPass +; CHECK-O2-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O2-NEXT: Running analysis: LazyValueAnalysis ; CHECK-O2-NEXT: Running pass: SROA on foo ; CHECK-O2-NEXT: Finished llvm::Function pass manager run. ; CHECK-O2-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}PostOrderFunctionAttrsPass> ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> ; CHECK-O2-NEXT: Running analysis: MemoryDependenceAnalysis -; CHECK-O2-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O2-NEXT: Running analysis: DemandedBitsAnalysis ; CHECK-O2-NEXT: Running pass: CrossDSOCFIPass ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}SimplifyCFGPass>