LLVM: lib/Transforms/Utils/ControlFlowUtils.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

21

22#define DEBUG_TYPE "control-flow-hub"

23

24using namespace llvm;

25

28

29

30

31

32

33

34

38 "Only support branch terminator.");

40 auto *Condition = Branch->isConditional() ? Branch->getCondition() : nullptr;

41

42 assert(Succ0 || Succ1);

43

44 if (Branch->isUnconditional()) {

45 assert(Succ0 == Branch->getSuccessor(0));

47 Branch->setSuccessor(0, FirstGuardBlock);

48 } else {

49 assert(!Succ1 || Succ1 == Branch->getSuccessor(1));

50 if (Succ0 && !Succ1) {

51 Branch->setSuccessor(0, FirstGuardBlock);

52 } else if (Succ1 && !Succ0) {

53 Branch->setSuccessor(1, FirstGuardBlock);

54 } else {

55 Branch->eraseFromParent();

57 }

58 }

59

60 return Condition;

61}

62

63

64

65

66

67

73 int I = 0;

74 for (int E = GuardBlocks.size() - 1; I != E; ++I) {

77 GuardBlocks[I]);

78 }

81 GuardBlocks[I]);

82}

83

84

85

93

95 FirstGuardBlock);

96

97 for (auto [BB, Succ0, Succ1] : Branches) {

99 Value *IncomingId = nullptr;

100 if (Succ0 && Succ1) {

101 auto Succ0Iter = find(Outgoing, Succ0);

102 auto Succ1Iter = find(Outgoing, Succ1);

104 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), Succ0Iter));

106 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), Succ1Iter));

107 IncomingId = SelectInst::Create(Condition, Id0, Id1, "target.bb.idx",

108 BB->getTerminator()->getIterator());

109 } else {

110

111 auto SuccIter = Succ0 ? find(Outgoing, Succ0) : find(Outgoing, Succ1);

112 IncomingId =

113 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), SuccIter));

114 }

115 Phi->addIncoming(IncomingId, BB);

116 }

117

118 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {

121 << "\n");

123 ConstantInt::get(Int32Ty, I),

124 Out->getName() + ".predicate", GuardBlocks[I]);

125 GuardPredicates[Out] = Cmp;

126 }

127}

128

129

130

139

140

141

142 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {

145 << "\n");

146

147 auto *Phi =

150 GuardPredicates[Out] = Phi;

151 }

152

153 for (auto [BB, Succ0, Succ1] : Branches) {

155

156

157

158

159

160

161

162

163 bool OneSuccessorDone = false;

164 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {

167 if (Out != Succ0 && Out != Succ1) {

168 Phi->addIncoming(BoolFalse, BB);

169 } else if (!Succ0 || !Succ1 || OneSuccessorDone) {

170

171

172 Phi->addIncoming(BoolTrue, BB);

173 } else {

174 assert(Succ0 && Succ1);

175 if (Out == Succ0) {

176 Phi->addIncoming(Condition, BB);

177 } else {

179 DeletionCandidates.push_back(Condition);

180 Phi->addIncoming(Inverted, BB);

181 }

182 OneSuccessorDone = true;

183 }

184 }

185 }

186}

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

206 std::optional MaxControlFlowBooleans) {

209

210 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I)

213

214

215

216

217

218

219 if (!MaxControlFlowBooleans || Outgoing.size() <= *MaxControlFlowBooleans)

221 DeletionCandidates);

222 else

224

226}

227

228

229

230

231

232

233

234

235

236

240 auto I = Out->begin();

243 auto *NewPhi =

245 Phi->getName() + ".moved", FirstGuardBlock->begin());

246 bool AllUndef = true;

247 for (auto [BB, Succ0, Succ1] : Incoming) {

249 if (Phi->getBasicBlockIndex(BB) != -1) {

250 V = Phi->removeIncomingValue(BB, false);

251 if (BB == Out) {

252 V = NewPhi;

253 }

255 }

256

257 NewPhi->addIncoming(V, BB);

258 }

259 assert(NewPhi->getNumIncomingValues() == Incoming.size());

260 Value *NewV = NewPhi;

261 if (AllUndef) {

262 NewPhi->eraseFromParent();

264 }

265 if (Phi->getNumOperands() == 0) {

266 Phi->replaceAllUsesWith(NewV);

267 I = Phi->eraseFromParent();

268 continue;

269 }

270 Phi->addIncoming(NewV, GuardBlock);

271 ++I;

272 }

273}

274

277 const StringRef Prefix, std::optional MaxControlFlowBooleans) {

278#ifndef NDEBUG

280#endif

282

283 for (auto [BB, Succ0, Succ1] : Branches) {

284#ifndef NDEBUG

287 "Duplicate entry for incoming block.");

288#endif

289 if (Succ0)

290 Outgoing.insert(Succ0);

291 if (Succ1)

292 Outgoing.insert(Succ1);

293 }

294

295 if (Outgoing.size() < 2)

296 return {Outgoing.front(), false};

297

299 if (DTU) {

300 for (auto [BB, Succ0, Succ1] : Branches) {

301 if (Succ0)

303 if (Succ1)

305 }

306 }

307

310 DeletionCandidates, Prefix, MaxControlFlowBooleans);

312

313

314 for (int I = 0, E = GuardBlocks.size(); I != E; ++I)

316

318

319 if (DTU) {

320 int NumGuards = GuardBlocks.size();

321

322 for (auto [BB, Succ0, Succ1] : Branches)

324

325 for (int I = 0; I != NumGuards - 1; ++I) {

329 }

330

331

333 Outgoing[NumGuards - 1]});

335 Outgoing[NumGuards]});

337 }

338

339 for (auto I : DeletionCandidates) {

340 if (I->use_empty())

342 Inst->eraseFromParent();

343 }

344

345 return {FirstGuardBlock, true};

346}

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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

static void calcPredicateUsingBooleans(ArrayRef< EdgeDescriptor > Branches, ArrayRef< BasicBlock * > Outgoing, SmallVectorImpl< BasicBlock * > &GuardBlocks, BBPredicates &GuardPredicates, SmallVectorImpl< WeakVH > &DeletionCandidates)

Definition ControlFlowUtils.cpp:131

static void setupBranchForGuard(ArrayRef< BasicBlock * > GuardBlocks, ArrayRef< BasicBlock * > Outgoing, BBPredicates &GuardPredicates)

Definition ControlFlowUtils.cpp:68

static void reconnectPhis(BasicBlock *Out, BasicBlock *GuardBlock, ArrayRef< EdgeDescriptor > Incoming, BasicBlock *FirstGuardBlock)

Definition ControlFlowUtils.cpp:237

static void calcPredicateUsingInteger(ArrayRef< EdgeDescriptor > Branches, ArrayRef< BasicBlock * > Outgoing, ArrayRef< BasicBlock * > GuardBlocks, BBPredicates &GuardPredicates)

Definition ControlFlowUtils.cpp:86

DenseMap< BasicBlock *, Instruction * > BBPredicates

Definition ControlFlowUtils.cpp:26

static Value * redirectToHub(BasicBlock *BB, BasicBlock *Succ0, BasicBlock *Succ1, BasicBlock *FirstGuardBlock)

Definition ControlFlowUtils.cpp:35

static void convertToGuardPredicates(ArrayRef< EdgeDescriptor > Branches, ArrayRef< BasicBlock * > Outgoing, SmallVectorImpl< BasicBlock * > &GuardBlocks, SmallVectorImpl< WeakVH > &DeletionCandidates, const StringRef Prefix, std::optional< unsigned > MaxControlFlowBooleans)

Definition ControlFlowUtils.cpp:202

ControlFlowHub::BranchDescriptor EdgeDescriptor

Definition ControlFlowUtils.cpp:27

This file implements a set that has insertion order iteration characteristics.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

const T & front() const

front - Get the first element.

size_t size() const

size - Get the array size.

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)

Creates a new BasicBlock.

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)

static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Construct a compare instruction, given the opcode, the predicate and the two operands.

static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)

static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)

static constexpr UpdateKind Delete

static constexpr UpdateKind Insert

void applyUpdates(ArrayRef< UpdateT > Updates)

Submit updates to all available trees.

This is an important class for using LLVM in a threaded context.

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 PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)

A vector that has set insertion semantics.

ArrayRef< value_type > getArrayRef() const

size_type size() const

Determine the number of elements in the SetVector.

const value_type & front() const

Return the first element of the SetVector.

const value_type & back() const

Return the last element of the SetVector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

The instances of the Type class are immutable: once they are created, they are never changed.

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)

LLVM Value Representation.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

This is an optimization pass for GlobalISel generic memory operations.

auto find(R &&Range, const T &Val)

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

FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty

auto dyn_cast_or_null(const Y &Val)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

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.

LLVM_ABI Value * invertCondition(Value *Condition)

Invert the given true/false value, possibly reusing an existing copy.

std::pair< BasicBlock *, bool > finalize(DomTreeUpdater *DTU, SmallVectorImpl< BasicBlock * > &GuardBlocks, const StringRef Prefix, std::optional< unsigned > MaxControlFlowBooleans=std::nullopt)

Return the unified loop exit block and a flag indicating if the CFG was changed at all.

Definition ControlFlowUtils.cpp:275

SmallVector< BranchDescriptor > Branches

Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...