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

60 void getAnalysisUsage(AnalysisUsage &AU) const override {

62 }

63

65};

66

67}

68

71

74 auto *STI = TM->getSubtargetImpl(F);

75 if (!STI->enableIndirectBrExpand())

77

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

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

81

87 return PA;

88}

89

90char IndirectBrExpandLegacyPass::ID = 0;

91

93 "Expand indirectbr instructions", false, false)

96 "Expand indirectbr instructions", false, false)

97

99 return new IndirectBrExpandLegacyPass();

100}

101

103 auto &DL = F.getDataLayout();

104

106

107

109

110

113

114

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

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

118 continue;

119 }

120

122 IndirectBrSuccs.insert_range(IBr->successors());

123 }

124

125 if (IndirectBrs.empty())

126 return false;

127

128

129

130

131

133

135

136

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

138 continue;

139

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

142 };

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

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

145 continue;

146

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.");

151

153

154

155

156 if (!BA->isConstantUsed())

157 continue;

158

159

160

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

163

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

166

167

168

169

170

172 }

173

174 if (BBs.empty()) {

175

176

178 if (DTU)

180 for (auto *IBr : IndirectBrs) {

181 if (DTU) {

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

184 }

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

187 }

188 if (DTU) {

190 "Got unexpected update count.");

192 }

193 return true;

194 }

195

197 Value *SwitchValue;

198

199

201 for (auto *IBr : IndirectBrs) {

202 auto *ITy =

205 CommonITy = ITy;

206 }

207

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

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

211 ".switch_cast",

212 IBr->getIterator());

213 };

214

216

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

218

219

222 SwitchValue = GetSwitchValue(IBr);

223 if (DTU) {

228 "Got unexpected update count.");

229 }

231 } else {

232

233

234

237 "switch_value_phi", SwitchBB);

238 SwitchValue = SwitchPN;

239

240

241

242 if (DTU)

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

244 for (auto *IBr : IndirectBrs) {

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

247 if (DTU) {

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

251 }

252 IBr->eraseFromParent();

253 }

254 }

255

256

257

259

260

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

263

264 if (DTU) {

265

266

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

272 }

274 }

275

276 return true;

277}

278

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

280 auto *TPC = getAnalysisIfAvailable();

281 if (!TPC)

282 return false;

283

286 if (!STI.enableIndirectBrExpand())

287 return false;

288 auto *TLI = STI.getTargetLowering();

289

290 std::optional DTU;

291 if (auto *DTWP = getAnalysisIfAvailable())

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

293

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

295}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static bool runOnFunction(Function &F, bool PostInlining)

static bool runImpl(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)

static bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU)

Definition IndirectBrExpandPass.cpp:102

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.

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.

void applyUpdates(ArrayRef< UpdateT > Updates)

Submit updates to all available trees.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)

Definition IndirectBrExpandPass.cpp:72

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

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

Definition IndirectBrExpandPass.cpp:98

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

auto seq(T Begin, T End)

Iterate over an integral type from Begin up to - but not including - End.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.