LLVM  13.0.0git
Macros | Enumerations | Functions | Variables
LoopUnswitch.cpp File Reference
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CodeMetrics.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/LegacyDivergenceAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/MustExecute.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
#include <cassert>
#include <map>
#include <set>
#include <tuple>
#include <utility>
#include <vector>

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "loop-unswitch"
 

Enumerations

enum  OperatorChain { OC_OpChainNone, OC_OpChainOr, OC_OpChainAnd, OC_OpChainMixed }
 Operator chain lattice. More...
 

Functions

 STATISTIC (NumBranches, "Number of branches unswitched")
 
 STATISTIC (NumSwitches, "Number of switches unswitched")
 
 STATISTIC (NumGuards, "Number of guards unswitched")
 
 STATISTIC (NumSelects, "Number of selects unswitched")
 
 STATISTIC (NumTrivial, "Number of unswitches that are trivial")
 
 STATISTIC (NumSimplify, "Number of simplifications of unswitched code")
 
 STATISTIC (TotalInsts, "Total number of instructions analyzed")
 
 INITIALIZE_PASS_BEGIN (LoopUnswitch, "loop-unswitch", "Unswitch loops", false, false) INITIALIZE_PASS_END(LoopUnswitch
 
static ValuefindLIVLoopCondition (Value *Cond, Loop *L, bool &Changed, OperatorChain &ParentChain, DenseMap< Value *, Value * > &Cache, MemorySSAUpdater *MSSAU)
 Cond is a condition that occurs in L. More...
 
static std::pair< Value *, OperatorChainfindLIVLoopCondition (Value *Cond, Loop *L, bool &Changed, MemorySSAUpdater *MSSAU)
 Cond is a condition that occurs in L. More...
 
static bool equalityPropUnSafe (Value &LoopCond)
 FIXME: Remove this workaround when freeze related patches are done. More...
 
static bool isTrivialLoopExitBlockHelper (Loop *L, BasicBlock *BB, BasicBlock *&ExitBB, std::set< BasicBlock * > &Visited)
 Check to see if all paths from BB exit the loop with no side effects (including infinite loops). More...
 
static BasicBlockisTrivialLoopExitBlock (Loop *L, BasicBlock *BB)
 Return true if the specified block unconditionally leads to an exit from the specified loop, and has no side-effects in the process. More...
 
static void removeFromWorklist (Instruction *I, std::vector< Instruction * > &Worklist)
 Remove all instances of I from the worklist vector specified. More...
 
static void replaceUsesOfWith (Instruction *I, Value *V, std::vector< Instruction * > &Worklist, Loop *L, LPPassManager *LPM, MemorySSAUpdater *MSSAU)
 When we find that I really equals V, remove I from the program, replacing all uses with V and update the worklist. More...
 

Variables

static cl::opt< unsigned > Threshold ("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
 
static cl::opt< unsigned > MSSAThreshold ("loop-unswitch-memoryssa-threshold", cl::desc("Max number of memory uses to explore during " "partial unswitching analysis"), cl::init(100), cl::Hidden)
 
loop unswitch
 
loop Unswitch loops
 
loop Unswitch false
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "loop-unswitch"

Definition at line 87 of file LoopUnswitch.cpp.

Enumeration Type Documentation

◆ OperatorChain

Operator chain lattice.

Enumerator
OC_OpChainNone 

There is no operator.

OC_OpChainOr 

There are only ORs.

OC_OpChainAnd 

There are only ANDs.

OC_OpChainMixed 

There are ANDs and ORs.

Definition at line 417 of file LoopUnswitch.cpp.

Function Documentation

◆ equalityPropUnSafe()

static bool equalityPropUnSafe ( Value LoopCond)
static

FIXME: Remove this workaround when freeze related patches are done.

LoopUnswitch and Equality propagation in GVN have discrepancy about whether branch on undef/poison has undefine behavior. Here it is to rule out some common cases that we found such discrepancy already causing problems. Detail could be found in PR31652. Note if the func returns true, it is unsafe. But if it is false, it doesn't mean it is necessarily safe.

Definition at line 608 of file LoopUnswitch.cpp.

References llvm::User::getOperand(), llvm::ICmpInst::isEquality(), and SI.

◆ findLIVLoopCondition() [1/2]

static std::pair<Value *, OperatorChain> findLIVLoopCondition ( Value Cond,
Loop L,
bool &  Changed,
MemorySSAUpdater MSSAU 
)
static

Cond is a condition that occurs in L.

If it is invariant in the loop, or has an invariant piece, return the invariant along with the operator chain type. Otherwise, return null.

Definition at line 519 of file LoopUnswitch.cpp.

References assert(), Cond, findLIVLoopCondition(), OC_OpChainMixed, and OC_OpChainNone.

◆ findLIVLoopCondition() [2/2]

static Value* findLIVLoopCondition ( Value Cond,
Loop L,
bool &  Changed,
OperatorChain ParentChain,
DenseMap< Value *, Value * > &  Cache,
MemorySSAUpdater MSSAU 
)
static

Cond is a condition that occurs in L.

If it is invariant in the loop, or has an invariant piece, return the invariant. Otherwise, return null. NOTE: findLIVLoopCondition will not return a partial LIV by walking up a mixed operator chain, as we can not reliably find a value which will simplify the operator chain. If the chain is AND-only or OR-only, we can use 0 or ~0 to simplify the chain.

NOTE: In case a partial LIV and a mixed operator chain, we may be able to simplify the condition itself to a loop variant condition, but at the cost of creating an entirely new loop.

Definition at line 435 of file LoopUnswitch.cpp.

References Cond, llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end(), llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find(), llvm::Loop::makeLoopInvariant(), OC_OpChainAnd, OC_OpChainMixed, OC_OpChainNone, and OC_OpChainOr.

Referenced by findLIVLoopCondition().

◆ INITIALIZE_PASS_BEGIN()

INITIALIZE_PASS_BEGIN ( LoopUnswitch  ,
"loop-unswitch ,
"Unswitch loops ,
false  ,
false   
)

◆ isTrivialLoopExitBlock()

static BasicBlock* isTrivialLoopExitBlock ( Loop L,
BasicBlock BB 
)
static

Return true if the specified block unconditionally leads to an exit from the specified loop, and has no side-effects in the process.

If so, return the block that is exited to, otherwise return null.

Definition at line 948 of file LoopUnswitch.cpp.

References BB, llvm::LoopBase< BlockT, LoopT >::getHeader(), and isTrivialLoopExitBlockHelper().

◆ isTrivialLoopExitBlockHelper()

static bool isTrivialLoopExitBlockHelper ( Loop L,
BasicBlock BB,
BasicBlock *&  ExitBB,
std::set< BasicBlock * > &  Visited 
)
static

Check to see if all paths from BB exit the loop with no side effects (including infinite loops).

If true, we return true and set ExitBB to the block we exit through.

Definition at line 913 of file LoopUnswitch.cpp.

References BB, llvm::LoopBase< BlockT, LoopT >::contains(), I, and llvm::successors().

Referenced by isTrivialLoopExitBlock().

◆ removeFromWorklist()

static void removeFromWorklist ( Instruction I,
std::vector< Instruction * > &  Worklist 
)
static

Remove all instances of I from the worklist vector specified.

Definition at line 1519 of file LoopUnswitch.cpp.

References llvm::erase_value(), and I.

Referenced by replaceUsesOfWith().

◆ replaceUsesOfWith()

static void replaceUsesOfWith ( Instruction I,
Value V,
std::vector< Instruction * > &  Worklist,
Loop L,
LPPassManager LPM,
MemorySSAUpdater MSSAU 
)
static

When we find that I really equals V, remove I from the program, replacing all uses with V and update the worklist.

Definition at line 1526 of file LoopUnswitch.cpp.

References llvm::dbgs(), llvm::numbers::e, i, I, LLVM_DEBUG, removeFromWorklist(), and llvm::MemorySSAUpdater::removeMemoryAccess().

Referenced by llvm::InnerLoopVectorizer::fixReduction().

◆ STATISTIC() [1/7]

STATISTIC ( NumBranches  ,
"Number of branches unswitched"   
)

◆ STATISTIC() [2/7]

STATISTIC ( NumGuards  ,
"Number of guards unswitched"   
)

◆ STATISTIC() [3/7]

STATISTIC ( NumSelects  ,
"Number of selects unswitched"   
)

◆ STATISTIC() [4/7]

STATISTIC ( NumSimplify  ,
"Number of simplifications of unswitched code  
)

◆ STATISTIC() [5/7]

STATISTIC ( NumSwitches  ,
"Number of switches unswitched"   
)

◆ STATISTIC() [6/7]

STATISTIC ( NumTrivial  ,
"Number of unswitches that are trivial"   
)

◆ STATISTIC() [7/7]

STATISTIC ( TotalInsts  ,
"Total number of instructions analyzed"   
)

Variable Documentation

◆ false

loop Unswitch false

Definition at line 410 of file LoopUnswitch.cpp.

◆ loops

loop Unswitch loops

Definition at line 409 of file LoopUnswitch.cpp.

◆ MSSAThreshold

cl::opt<unsigned> MSSAThreshold("loop-unswitch-memoryssa-threshold", cl::desc("Max number of memory uses to explore during " "partial unswitching analysis"), cl::init(100), cl::Hidden)
static

◆ Threshold

cl::opt<unsigned> Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
static

◆ unswitch

loop unswitch

Definition at line 409 of file LoopUnswitch.cpp.