LLVM: lib/CodeGen/IndirectBrExpandPass.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

44#include

45

46using namespace llvm;

47

48#define DEBUG_TYPE "indirectbr-expand"

49

50namespace {

51

52class IndirectBrExpandLegacyPass : public FunctionPass {

53public:

54 static char ID;

55

58 }

59

62 }

63

65};

66

67}

68

71

75 if (!STI->enableIndirectBrExpand())

77

78 auto *TLI = STI->getTargetLowering();

80 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);

81

82 bool Changed = runImpl(F, TLI, DT ? &DTU : nullptr);

83 if (!Changed)

87 return PA;

88}

89

90char IndirectBrExpandLegacyPass::ID = 0;

91

93 "Expand indirectbr instructions", false, false)

97

99 return new IndirectBrExpandLegacyPass();

100}

101

103 auto &DL = F.getDataLayout();

104

106

107

109

110

112 if (auto *IBr = dyn_cast(BB.getTerminator())) {

113

114

115 if (IBr->getNumSuccessors() == 0) {

116 (void)new UnreachableInst(F.getContext(), IBr->getIterator());

118 continue;

119 }

120

122 for (BasicBlock *SuccBB : IBr->successors())

123 IndirectBrSuccs.insert(SuccBB);

124 }

125

126 if (IndirectBrs.empty())

127 return false;

128

129

130

131

132

134

136

137

138 if (!IndirectBrSuccs.count(&BB))

139 continue;

140

141 auto IsBlockAddressUse = [&](const Use &U) {

142 return isa(U.getUser());

143 };

144 auto BlockAddressUseIt = llvm::find_if(BB.uses(), IsBlockAddressUse);

145 if (BlockAddressUseIt == BB.use_end())

146 continue;

147

148 assert(std::find_if(std::next(BlockAddressUseIt), BB.use_end(),

149 IsBlockAddressUse) == BB.use_end() &&

150 "There should only ever be a single blockaddress use because it is "

151 "a constant and should be uniqued.");

152

153 auto *BA = cast(BlockAddressUseIt->getUser());

154

155

156

157 if (!BA->isConstantUsed())

158 continue;

159

160

161

162 int BBIndex = BBs.size() + 1;

164

165 auto *ITy = cast(DL.getIntPtrType(BA->getType()));

166 ConstantInt *BBIndexC = ConstantInt::get(ITy, BBIndex);

167

168

169

170

171

173 }

174

175 if (BBs.empty()) {

176

177

179 if (DTU)

181 for (auto *IBr : IndirectBrs) {

182 if (DTU) {

183 for (BasicBlock *SuccBB : IBr->successors())

185 }

186 (void)new UnreachableInst(F.getContext(), IBr->getIterator());

188 }

189 if (DTU) {

191 "Got unexpected update count.");

193 }

194 return true;

195 }

196

198 Value *SwitchValue;

199

200

202 for (auto *IBr : IndirectBrs) {

203 auto *ITy =

204 cast(DL.getIntPtrType(IBr->getAddress()->getType()));

206 CommonITy = ITy;

207 }

208

209 auto GetSwitchValue = [CommonITy](IndirectBrInst *IBr) {

211 Twine(IBr->getAddress()->getName()) +

212 ".switch_cast",

213 IBr->getIterator());

214 };

215

217

218 if (IndirectBrs.size() == 1) {

219

220

223 SwitchValue = GetSwitchValue(IBr);

224 if (DTU) {

229 "Got unexpected update count.");

230 }

232 } else {

233

234

235

238 "switch_value_phi", SwitchBB);

239 SwitchValue = SwitchPN;

240

241

242

243 if (DTU)

244 Updates.reserve(IndirectBrs.size() + 2 * IndirectBrSuccs.size());

245 for (auto *IBr : IndirectBrs) {

246 SwitchPN->addIncoming(GetSwitchValue(IBr), IBr->getParent());

248 if (DTU) {

250 for (BasicBlock *SuccBB : IBr->successors())

252 }

253 IBr->eraseFromParent();

254 }

255 }

256

257

258

260

261

262 for (int i : llvm::seq(1, BBs.size()))

263 SI->addCase(ConstantInt::get(CommonITy, i + 1), BBs[i]);

264

265 if (DTU) {

266

267

271 if (UniqueSuccessors.insert(BB).second)

273 }

275 }

276

277 return true;

278}

279

280bool IndirectBrExpandLegacyPass::runOnFunction(Function &F) {

281 auto *TPC = getAnalysisIfAvailable();

282 if (!TPC)

283 return false;

284

286 auto &STI = *TM.getSubtargetImpl(F);

287 if (!STI.enableIndirectBrExpand())

288 return false;

289 auto *TLI = STI.getTargetLowering();

290

291 std::optional DTU;

292 if (auto *DTWP = getAnalysisIfAvailable())

293 DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);

294

295 return runImpl(F, TLI, DTU ? &*DTU : nullptr);

296}

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)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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 CastInst * CreatePointerCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Create a BitCast, AddrSpaceCast or a PtrToInt cast instruction.

static 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()

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 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.

void 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.

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.

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.

void initializeIndirectBrExpandLegacyPassPass(PassRegistry &)