Go to the documentation of this file.
47 #define DEBUG_TYPE "indirectbr-expand"
73 "Expand indirectbr instructions",
false,
false)
79 return new IndirectBrExpandPass();
83 auto &
DL =
F.getParent()->getDataLayout();
84 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
89 auto &STI = *
TM.getSubtargetImpl(
F);
90 if (!STI.enableIndirectBrExpand())
92 TLI = STI.getTargetLowering();
94 std::optional<DomTreeUpdater> DTU;
95 if (
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
105 if (
auto *IBr = dyn_cast<IndirectBrInst>(
BB.getTerminator())) {
108 if (IBr->getNumSuccessors() == 0) {
114 IndirectBrs.push_back(IBr);
116 IndirectBrSuccs.
insert(SuccBB);
119 if (IndirectBrs.empty())
131 if (!IndirectBrSuccs.
count(&
BB))
134 auto IsBlockAddressUse = [&](
const Use &U) {
135 return isa<BlockAddress>(U.getUser());
138 if (BlockAddressUseIt ==
BB.use_end())
142 IsBlockAddressUse) ==
BB.use_end() &&
143 "There should only ever be a single blockaddress use because it is "
144 "a constant and should be uniqued.");
146 auto *BA = cast<BlockAddress>(BlockAddressUseIt->getUser());
150 if (!BA->isConstantUsed())
155 int BBIndex = BBs.size() + 1;
158 auto *ITy = cast<IntegerType>(
DL.getIntPtrType(BA->getType()));
174 for (
auto *IBr : IndirectBrs) {
183 assert(Updates.size() == IndirectBrSuccs.
size() &&
184 "Got unexpected update count.");
185 DTU->applyUpdates(Updates);
195 for (
auto *IBr : IndirectBrs) {
197 cast<IntegerType>(
DL.getIntPtrType(IBr->getAddress()->getType()));
198 if (!CommonITy || ITy->getBitWidth() > CommonITy->
getBitWidth())
204 IBr->getAddress(), CommonITy,
205 Twine(IBr->getAddress()->getName()) +
".switch_cast", IBr);
210 if (IndirectBrs.size() == 1) {
215 SwitchValue = GetSwitchValue(IBr);
220 assert(Updates.size() == IndirectBrSuccs.
size() &&
221 "Got unexpected update count.");
230 "switch_value_phi", SwitchBB);
231 SwitchValue = SwitchPN;
236 Updates.
reserve(IndirectBrs.size() + 2 * IndirectBrSuccs.
size());
237 for (
auto *IBr : IndirectBrs) {
238 SwitchPN->addIncoming(GetSwitchValue(IBr), IBr->
getParent());
254 for (
int i : llvm::seq<int>(1, BBs.size()))
261 Updates.
reserve(Updates.size() + BBs.size());
263 if (UniqueSuccessors.
insert(
BB).second)
266 DTU->applyUpdates(Updates);
This is an optimization pass for GlobalISel generic memory operations.
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, Instruction *InsertBefore=nullptr)
static constexpr UpdateKind Insert
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
LLVM Basic Block Representation.
This is the shared class of boolean and integer constants.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
void initializeIndirectBrExpandPassPass(PassRegistry &)
Represent the analysis usage information of a pass.
Class to represent integer types.
Legacy analysis pass which computes a DominatorTree.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
inst_range instructions(Function *F)
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Primary interface to the complete machine description for the target machine.
INITIALIZE_PASS_BEGIN(IndirectBrExpandPass, DEBUG_TYPE, "Expand indirectbr instructions", false, false) INITIALIZE_PASS_END(IndirectBrExpandPass
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
iterator_range< succ_op_iterator > successors()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
static bool runOnFunction(Function &F, bool PostInlining)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
Indirect Branch Instruction.
const BasicBlock * getParent() const
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
const char LLVMTargetMachineRef TM
FunctionPass class - This class is used to implement most global optimizations.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
This function has undefined behavior.
static CastInst * CreatePointerCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd)
Create a BitCast AddrSpaceCast, or a PtrToInt cast instruction.
void reserve(size_type N)
LLVM Value Representation.
static constexpr UpdateKind Delete
A Use represents the edge between a Value definition and its users.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.