Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 9897e75

Browse files
committed
Bring back "[PM] Port JumpThreading to the new PM" with a fix
This reverts commit r272603 and adds a fix. Big thanks to Davide for pointing me at r216244 which gives some insight into how to fix this VS2013 issue. VS2013 can't synthesize a move constructor. So the fix here is to add one explicitly to the JumpThreadingPass class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272607 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d4b40fa commit 9897e75

File tree

5 files changed

+225
-113
lines changed

5 files changed

+225
-113
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//===- JumpThreading.h - thread control through conditional BBs -*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
/// \file
10+
/// See the comments on JumpThreadingPass.
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
15+
#define LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
16+
17+
#include "llvm/ADT/DenseSet.h"
18+
#include "llvm/ADT/SmallPtrSet.h"
19+
#include "llvm/ADT/SmallSet.h"
20+
#include "llvm/Analysis/BlockFrequencyInfo.h"
21+
#include "llvm/Analysis/BranchProbabilityInfo.h"
22+
#include "llvm/Analysis/LazyValueInfo.h"
23+
#include "llvm/Analysis/TargetLibraryInfo.h"
24+
#include "llvm/IR/Instructions.h"
25+
#include "llvm/IR/ValueHandle.h"
26+
27+
namespace llvm {
28+
29+
/// A private "module" namespace for types and utilities used by
30+
/// JumpThreading.
31+
/// These are implementation details and should not be used by clients.
32+
namespace jumpthreading {
33+
// These are at global scope so static functions can use them too.
34+
typedef SmallVectorImpl<std::pair<Constant *, BasicBlock *>> PredValueInfo;
35+
typedef SmallVector<std::pair<Constant *, BasicBlock *>, 8> PredValueInfoTy;
36+
37+
// This is used to keep track of what kind of constant we're currently hoping
38+
// to find.
39+
enum ConstantPreference { WantInteger, WantBlockAddress };
40+
}
41+
42+
/// This pass performs 'jump threading', which looks at blocks that have
43+
/// multiple predecessors and multiple successors. If one or more of the
44+
/// predecessors of the block can be proven to always jump to one of the
45+
/// successors, we forward the edge from the predecessor to the successor by
46+
/// duplicating the contents of this block.
47+
///
48+
/// An example of when this can occur is code like this:
49+
///
50+
/// if () { ...
51+
/// X = 4;
52+
/// }
53+
/// if (X < 3) {
54+
///
55+
/// In this case, the unconditional branch at the end of the first if can be
56+
/// revectored to the false side of the second if.
57+
///
58+
class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
59+
TargetLibraryInfo *TLI;
60+
LazyValueInfo *LVI;
61+
std::unique_ptr<BlockFrequencyInfo> BFI;
62+
std::unique_ptr<BranchProbabilityInfo> BPI;
63+
bool HasProfileData;
64+
#ifdef NDEBUG
65+
SmallPtrSet<const BasicBlock *, 16> LoopHeaders;
66+
#else
67+
SmallSet<AssertingVH<const BasicBlock>, 16> LoopHeaders;
68+
#endif
69+
DenseSet<std::pair<Value *, BasicBlock *>> RecursionSet;
70+
71+
unsigned BBDupThreshold;
72+
73+
// RAII helper for updating the recursion stack.
74+
struct RecursionSetRemover {
75+
DenseSet<std::pair<Value *, BasicBlock *>> &TheSet;
76+
std::pair<Value *, BasicBlock *> ThePair;
77+
78+
RecursionSetRemover(DenseSet<std::pair<Value *, BasicBlock *>> &S,
79+
std::pair<Value *, BasicBlock *> P)
80+
: TheSet(S), ThePair(P) {}
81+
82+
~RecursionSetRemover() { TheSet.erase(ThePair); }
83+
};
84+
85+
public:
86+
JumpThreadingPass(int T = -1);
87+
// Hack for MSVC 2013 which seems like it can't synthesize this.
88+
JumpThreadingPass(JumpThreadingPass &&Other)
89+
: TLI(Other.TLI), LVI(Other.LVI), BFI(std::move(Other.BFI)),
90+
BPI(std::move(Other.BPI)), HasProfileData(Other.HasProfileData),
91+
LoopHeaders(std::move(Other.LoopHeaders)),
92+
RecursionSet(std::move(Other.RecursionSet)),
93+
BBDupThreshold(Other.BBDupThreshold) {}
94+
95+
// Glue for old PM.
96+
bool runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo *LVI_,
97+
bool HasProfileData_, std::unique_ptr<BlockFrequencyInfo> BFI_,
98+
std::unique_ptr<BranchProbabilityInfo> BPI_);
99+
100+
PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM);
101+
102+
void releaseMemory() {
103+
BFI.reset();
104+
BPI.reset();
105+
}
106+
107+
void FindLoopHeaders(Function &F);
108+
bool ProcessBlock(BasicBlock *BB);
109+
bool ThreadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs,
110+
BasicBlock *SuccBB);
111+
bool DuplicateCondBranchOnPHIIntoPred(
112+
BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs);
113+
114+
bool
115+
ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,
116+
jumpthreading::PredValueInfo &Result,
117+
jumpthreading::ConstantPreference Preference,
118+
Instruction *CxtI = nullptr);
119+
bool ProcessThreadableEdges(Value *Cond, BasicBlock *BB,
120+
jumpthreading::ConstantPreference Preference,
121+
Instruction *CxtI = nullptr);
122+
123+
bool ProcessBranchOnPHI(PHINode *PN);
124+
bool ProcessBranchOnXOR(BinaryOperator *BO);
125+
bool ProcessImpliedCondition(BasicBlock *BB);
126+
127+
bool SimplifyPartiallyRedundantLoad(LoadInst *LI);
128+
bool TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
129+
bool TryToUnfoldSelectInCurrBB(BasicBlock *BB);
130+
131+
private:
132+
BasicBlock *SplitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
133+
const char *Suffix);
134+
void UpdateBlockFreqAndEdgeWeight(BasicBlock *PredBB, BasicBlock *BB,
135+
BasicBlock *NewBB, BasicBlock *SuccBB);
136+
};
137+
138+
} // end namespace llvm
139+
140+
#endif

lib/Passes/PassBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include "llvm/Transforms/Scalar/GVN.h"
7676
#include "llvm/Transforms/Scalar/GuardWidening.h"
7777
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
78+
#include "llvm/Transforms/Scalar/JumpThreading.h"
7879
#include "llvm/Transforms/Scalar/LoopRotation.h"
7980
#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
8081
#include "llvm/Transforms/Scalar/LowerAtomic.h"

lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass())
130130
FUNCTION_PASS("guard-widening", GuardWideningPass())
131131
FUNCTION_PASS("gvn", GVN())
132132
FUNCTION_PASS("mldst-motion", MergedLoadStoreMotionPass())
133+
FUNCTION_PASS("jump-threading", JumpThreadingPass())
133134
FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass())
134135
FUNCTION_PASS("lcssa", LCSSAPass())
135136
FUNCTION_PASS("print", PrintFunctionPass(dbgs()))

0 commit comments

Comments
 (0)