23 cl::desc(
"Only split jump tables with size less or "
24 "equal than JumpTableSizeThreshold."),
31 "jump-table-to-switch-function-size-threshold",
cl::Hidden,
32 cl::desc(
"Only split jump tables containing functions whose sizes are less "
33 "or equal than this threshold."),
36#define DEBUG_TYPE "jump-table-to-switch"
58 DL.getIndexSizeInBits(
GEP->getPointerAddressSpace());
61 if (!
GEP->collectOffset(
DL,
BitWidth, VariableOffsets, ConstantOffset))
63 if (VariableOffsets.
size() != 1)
66 if (!ConstantOffset.
isZero())
68 APInt StrideBytes = VariableOffsets.
front().second;
70 if (JumpTableSizeBytes % StrideBytes.
getZExtValue() != 0)
76 JumpTableTy JumpTable;
77 JumpTable.Index = VariableOffsets.
front().first;
78 JumpTable.Funcs.reserve(
N);
79 for (
uint64_t Index = 0; Index <
N; ++Index) {
84 auto *Func = dyn_cast_or_null<Function>(
C);
85 if (!Func || Func->isDeclaration() ||
88 JumpTable.Funcs.push_back(Func);
107 F.getContext(),
"default.switch.case.unreachable", &
F,
Tail);
113 DTUpdates.
push_back({DominatorTree::Insert, BB, BBUnreachable});
122 DTUpdates.
push_back({DominatorTree::Insert, BB,
B});
126 Call->setCalledFunction(Func);
127 Call->insertInto(
B,
B->end());
129 cast<ConstantInt>(ConstantInt::get(JT.Index->getType(), Index)),
B);
132 PHI->addIncoming(Call,
B);
137 <<
"expanded indirect call into switch";
151 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
152 bool Changed =
false;
158 auto *Call = dyn_cast<CallInst>(&
I);
159 if (!Call || Call->getCalledFunction() || Call->isMustTailCall())
161 auto *L = dyn_cast<LoadInst>(Call->getCalledOperand());
163 if (!L || !L->isSimple())
165 auto *
GEP = dyn_cast<GetElementPtrInst>(L->getPointerOperand());
168 auto *PtrTy = dyn_cast<PointerType>(L->getType());
169 assert(PtrTy &&
"call operand must be a pointer");
177 CurrentBB = SplittedOutTail ? SplittedOutTail :
nullptr;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static cl::opt< unsigned > FunctionSizeThreshold("jump-table-to-switch-function-size-threshold", cl::Hidden, cl::desc("Only split jump tables containing functions whose sizes are less " "or equal than this threshold."), cl::init(50))
static cl::opt< unsigned > JumpTableSizeThreshold("jump-table-to-switch-size-threshold", cl::Hidden, cl::desc("Only split jump tables with size less or " "equal than JumpTableSizeThreshold."), cl::init(10))
static BasicBlock * expandToSwitch(CallBase *CB, const JumpTableTy &JT, DomTreeUpdater &DTU, OptimizationRemarkEmitter &ORE)
static std::optional< JumpTableTy > parseJumpTable(GetElementPtrInst *GEP, PointerType *PtrTy)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
UnreachableInst * CreateUnreachable()
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
SwitchInst * CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases=10, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a switch instruction with the specified value, default dest, and with a hint for the number of...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
std::pair< KeyT, ValueT > & front()
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserve()
Mark an analysis as preserved.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Type * getVoidTy(LLVMContext &C)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
constexpr unsigned BitWidth
BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
A MapVector that performs no allocations if smaller than a certain size.