48#define DEBUG_TYPE "indirectbr-expand"
75 if (!STI->enableIndirectBrExpand())
78 auto *TLI = STI->getTargetLowering();
82 bool Changed =
runImpl(
F, TLI, DT ? &DTU :
nullptr);
90char IndirectBrExpandLegacyPass::ID = 0;
93 "Expand indirectbr instructions",
false,
false)
99 return new IndirectBrExpandLegacyPass();
103 auto &
DL =
F.getDataLayout();
112 if (
auto *IBr = dyn_cast<IndirectBrInst>(BB.getTerminator())) {
115 if (IBr->getNumSuccessors() == 0) {
125 if (IndirectBrs.
empty())
137 if (!IndirectBrSuccs.
count(&BB))
140 auto IsBlockAddressUse = [&](
const Use &U) {
141 return isa<BlockAddress>(U.getUser());
143 auto BlockAddressUseIt =
llvm::find_if(BB.uses(), IsBlockAddressUse);
144 if (BlockAddressUseIt == BB.use_end())
147 assert(std::none_of(std::next(BlockAddressUseIt), BB.use_end(),
148 IsBlockAddressUse) &&
149 "There should only ever be a single blockaddress use because it is "
150 "a constant and should be uniqued.");
152 auto *BA = cast<BlockAddress>(BlockAddressUseIt->getUser());
156 if (!BA->isConstantUsed())
161 int BBIndex = BBs.
size() + 1;
164 auto *ITy = cast<IntegerType>(
DL.getIntPtrType(BA->getType()));
165 ConstantInt *BBIndexC = ConstantInt::get(ITy, BBIndex);
180 for (
auto *IBr : IndirectBrs) {
190 "Got unexpected update count.");
201 for (
auto *IBr : IndirectBrs) {
203 cast<IntegerType>(
DL.getIntPtrType(IBr->getAddress()->getType()));
210 Twine(IBr->getAddress()->getName()) +
217 if (IndirectBrs.
size() == 1) {
222 SwitchValue = GetSwitchValue(IBr);
228 "Got unexpected update count.");
237 "switch_value_phi", SwitchBB);
238 SwitchValue = SwitchPN;
244 for (
auto *IBr : IndirectBrs) {
245 SwitchPN->addIncoming(GetSwitchValue(IBr), IBr->getParent());
252 IBr->eraseFromParent();
261 for (
int i : llvm::seq<int>(1, BBs.
size()))
262 SI->addCase(ConstantInt::get(CommonITy, i + 1), BBs[i]);
270 if (UniqueSuccessors.
insert(BB).second)
279bool IndirectBrExpandLegacyPass::runOnFunction(
Function &
F) {
280 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
285 auto &STI = *
TM.getSubtargetImpl(
F);
286 if (!STI.enableIndirectBrExpand())
288 auto *TLI = STI.getTargetLowering();
290 std::optional<DomTreeUpdater> DTU;
291 if (
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
292 DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);
294 return runImpl(
F, TLI, DTU ? &*DTU :
nullptr);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runImpl(Function &F, const TargetLowering &TLI)
static bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU)
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Provides some synthesis utilities to produce sequences of values.
This file defines the SmallVector class.
Target-Independent Code Generator Pass Configuration Options pass.
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.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
static LLVM_ABI CastInst * CreatePointerCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a BitCast, AddrSpaceCast or a PtrToInt cast instruction.
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is the shared class of boolean and integer constants.
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
Legacy analysis pass which computes a DominatorTree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Indirect Branch Instruction.
iterator_range< succ_op_iterator > successors()
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Class to represent integer types.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
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.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static SwitchInst * Create(Value *Value, BasicBlock *Default, unsigned NumCases, InsertPosition InsertBefore=nullptr)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const ParentTy * getParent() const
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void initializeIndirectBrExpandLegacyPassPass(PassRegistry &)
LLVM_ABI FunctionPass * createIndirectBrExpandPass()
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.