JumpThreading.h revision 360784
1//===- JumpThreading.h - thread control through conditional BBs -*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 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/ArrayRef.h" 18#include "llvm/ADT/DenseSet.h" 19#include "llvm/ADT/SmallPtrSet.h" 20#include "llvm/ADT/SmallSet.h" 21#include "llvm/ADT/SmallVector.h" 22#include "llvm/Analysis/AliasAnalysis.h" 23#include "llvm/Analysis/BlockFrequencyInfo.h" 24#include "llvm/Analysis/BranchProbabilityInfo.h" 25#include "llvm/Analysis/DomTreeUpdater.h" 26#include "llvm/IR/ValueHandle.h" 27#include <memory> 28#include <utility> 29 30namespace llvm { 31 32class BasicBlock; 33class BinaryOperator; 34class BranchInst; 35class CmpInst; 36class Constant; 37class DomTreeUpdater; 38class Function; 39class Instruction; 40class IntrinsicInst; 41class LazyValueInfo; 42class LoadInst; 43class PHINode; 44class TargetLibraryInfo; 45class Value; 46 47/// A private "module" namespace for types and utilities used by 48/// JumpThreading. 49/// These are implementation details and should not be used by clients. 50namespace jumpthreading { 51 52// These are at global scope so static functions can use them too. 53using PredValueInfo = SmallVectorImpl<std::pair<Constant *, BasicBlock *>>; 54using PredValueInfoTy = SmallVector<std::pair<Constant *, BasicBlock *>, 8>; 55 56// This is used to keep track of what kind of constant we're currently hoping 57// to find. 58enum ConstantPreference { WantInteger, WantBlockAddress }; 59 60} // end namespace jumpthreading 61 62/// This pass performs 'jump threading', which looks at blocks that have 63/// multiple predecessors and multiple successors. If one or more of the 64/// predecessors of the block can be proven to always jump to one of the 65/// successors, we forward the edge from the predecessor to the successor by 66/// duplicating the contents of this block. 67/// 68/// An example of when this can occur is code like this: 69/// 70/// if () { ... 71/// X = 4; 72/// } 73/// if (X < 3) { 74/// 75/// In this case, the unconditional branch at the end of the first if can be 76/// revectored to the false side of the second if. 77class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> { 78 TargetLibraryInfo *TLI; 79 LazyValueInfo *LVI; 80 AliasAnalysis *AA; 81 DomTreeUpdater *DTU; 82 std::unique_ptr<BlockFrequencyInfo> BFI; 83 std::unique_ptr<BranchProbabilityInfo> BPI; 84 bool HasProfileData = false; 85 bool HasGuards = false; 86#ifdef NDEBUG 87 SmallPtrSet<const BasicBlock *, 16> LoopHeaders; 88#else 89 SmallSet<AssertingVH<const BasicBlock>, 16> LoopHeaders; 90#endif 91 92 unsigned BBDupThreshold; 93 94public: 95 JumpThreadingPass(int T = -1); 96 97 // Glue for old PM. 98 bool runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo *LVI_, 99 AliasAnalysis *AA_, DomTreeUpdater *DTU_, bool HasProfileData_, 100 std::unique_ptr<BlockFrequencyInfo> BFI_, 101 std::unique_ptr<BranchProbabilityInfo> BPI_); 102 103 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 104 105 void releaseMemory() { 106 BFI.reset(); 107 BPI.reset(); 108 } 109 110 void FindLoopHeaders(Function &F); 111 bool ProcessBlock(BasicBlock *BB); 112 bool MaybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB); 113 void UpdateSSA(BasicBlock *BB, BasicBlock *NewBB, 114 DenseMap<Instruction *, Value *> &ValueMapping); 115 DenseMap<Instruction *, Value *> CloneInstructions(BasicBlock::iterator BI, 116 BasicBlock::iterator BE, 117 BasicBlock *NewBB, 118 BasicBlock *PredBB); 119 bool TryThreadEdge(BasicBlock *BB, 120 const SmallVectorImpl<BasicBlock *> &PredBBs, 121 BasicBlock *SuccBB); 122 void ThreadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs, 123 BasicBlock *SuccBB); 124 bool DuplicateCondBranchOnPHIIntoPred( 125 BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs); 126 127 bool ComputeValueKnownInPredecessorsImpl( 128 Value *V, BasicBlock *BB, jumpthreading::PredValueInfo &Result, 129 jumpthreading::ConstantPreference Preference, 130 DenseSet<std::pair<Value *, BasicBlock *>> &RecursionSet, 131 Instruction *CxtI = nullptr); 132 bool 133 ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB, 134 jumpthreading::PredValueInfo &Result, 135 jumpthreading::ConstantPreference Preference, 136 Instruction *CxtI = nullptr) { 137 DenseSet<std::pair<Value *, BasicBlock *>> RecursionSet; 138 return ComputeValueKnownInPredecessorsImpl(V, BB, Result, Preference, 139 RecursionSet, CxtI); 140 } 141 142 bool ProcessThreadableEdges(Value *Cond, BasicBlock *BB, 143 jumpthreading::ConstantPreference Preference, 144 Instruction *CxtI = nullptr); 145 146 bool ProcessBranchOnPHI(PHINode *PN); 147 bool ProcessBranchOnXOR(BinaryOperator *BO); 148 bool ProcessImpliedCondition(BasicBlock *BB); 149 150 bool SimplifyPartiallyRedundantLoad(LoadInst *LI); 151 void UnfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB, SelectInst *SI, 152 PHINode *SIUse, unsigned Idx); 153 154 bool TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB); 155 bool TryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB); 156 bool TryToUnfoldSelectInCurrBB(BasicBlock *BB); 157 158 bool ProcessGuards(BasicBlock *BB); 159 bool ThreadGuard(BasicBlock *BB, IntrinsicInst *Guard, BranchInst *BI); 160 161private: 162 BasicBlock *SplitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds, 163 const char *Suffix); 164 void UpdateBlockFreqAndEdgeWeight(BasicBlock *PredBB, BasicBlock *BB, 165 BasicBlock *NewBB, BasicBlock *SuccBB); 166 /// Check if the block has profile metadata for its outgoing edges. 167 bool doesBlockHaveProfileData(BasicBlock *BB); 168}; 169 170} // end namespace llvm 171 172#endif // LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H 173