MLIR: lib/IR/Block.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10

13 #include "llvm/ADT/BitVector.h"

14 #include "llvm/ADT/SmallPtrSet.h"

15

16 using namespace mlir;

17

18

19

20

21

23 assert(verifyOpOrder() && "Expected valid operation ordering.");

26 arg.destroy();

27 }

28

30

31

32

35 }

36

37

39

40

41

43 assert(getParent() && "already inserted into a block!");

44 assert(block->getParent() && "cannot insert before a block without a parent");

46 }

47

49 assert(getParent() && "already inserted into a block!");

50 assert(block->getParent() && "cannot insert before a block without a parent");

51 block->getParent()->getBlocks().insertAfter(block->getIterator(), this);

52 }

53

54

55

57 assert(block->getParent() && "cannot insert before a block without a parent");

59 }

60

61

62

65 }

66

67

69 assert(getParent() && "Block has no parent");

71 }

72

73

74

75

77

78

79 auto *currOp = &op;

80 while (currOp->getBlock() != this) {

82 if (!currOp)

83 return nullptr;

84 }

85 return currOp;

86 }

87

88

89

90

94 }

95

98 arg.dropAllUses();

99 for (auto &op : *this)

100 op.dropAllDefinedValueUses();

102 }

103

104

105

107

108

110

112 parentValidOpOrderPair.setInt(false);

113 }

114

115

116

118

120 return false;

121

122 if (operations.empty() || llvm::hasSingleElement(operations))

123 return false;

124

126 for (auto &i : *this) {

127

128

129 if (prev && prev->orderIndex != Operation::kInvalidOrderIdx &&

130 prev->orderIndex >= i.orderIndex)

131 return true;

132 prev = &i;

133 }

134 return false;

135 }

136

137

139 parentValidOpOrderPair.setInt(true);

140

141 unsigned orderIndex = 0;

142 for (auto &op : *this)

143 op.orderIndex = (orderIndex += Operation::kOrderStride);

144 }

145

146

147

148

149

150

153 }

154

156 BlockArgument arg = BlockArgument::create(type, this, arguments.size(), loc);

157 arguments.push_back(arg);

158 return arg;

159 }

160

161

164 assert(types.size() == locs.size() &&

165 "incorrect number of block argument locations");

166 size_t initialSize = arguments.size();

167 arguments.reserve(initialSize + types.size());

168

169 for (auto typeAndLoc : llvm::zip(types, locs))

170 addArgument(std::get<0>(typeAndLoc), std::get<1>(typeAndLoc));

171 return {arguments.data() + initialSize, arguments.data() + arguments.size()};

172 }

173

175 assert(index <= arguments.size() && "invalid insertion index");

176

177 auto arg = BlockArgument::create(type, this, index, loc);

178 arguments.insert(arguments.begin() + index, arg);

179

180

181 ++index;

182 for (BlockArgument arg : llvm::drop_begin(arguments, index))

183 arg.setArgNumber(index++);

184 return arg;

185 }

186

187

188

191 "cannot insert arguments to blocks with predecessors");

192 return insertArgument(it->getArgNumber(), type, loc);

193 }

194

196 assert(index < arguments.size());

197 arguments[index].destroy();

198 arguments.erase(arguments.begin() + index);

199 for (BlockArgument arg : llvm::drop_begin(arguments, index))

200 arg.setArgNumber(index++);

201 }

202

204 assert(start + num <= arguments.size());

205 for (unsigned i = 0; i < num; ++i)

206 arguments[start + i].destroy();

207 arguments.erase(arguments.begin() + start, arguments.begin() + start + num);

208 for (BlockArgument arg : llvm::drop_begin(arguments, start))

209 arg.setArgNumber(start++);

210 }

211

215 }

216

218 auto firstDead = llvm::find_if(arguments, shouldEraseFn);

219 if (firstDead == arguments.end())

220 return;

221

222

223

224 unsigned index = firstDead->getArgNumber();

225 firstDead->destroy();

226

227

228 for (auto it = std::next(firstDead), e = arguments.end(); it != e; ++it) {

229

230 if (shouldEraseFn(*it)) {

231 it->destroy();

232 } else {

233 it->setArgNumber(index++);

234 *firstDead++ = *it;

235 }

236 }

237 arguments.erase(firstDead, arguments.end());

238 }

239

240

241

242

243

244

245

248 return &back();

249 }

250

251

254 }

255

256

259 }

260

264 }

265

266

267

268

269

270

271

275 return nullptr;

276 auto *firstPred = *it;

277 ++it;

278 return it == pred_end() ? firstPred : nullptr;

279 }

280

281

282

285 if (it == e)

286 return nullptr;

287

288

289 auto *firstPred = *it;

290 for (++it; it != e; ++it)

291 if (*it != firstPred)

292 return nullptr;

293 return firstPred;

294 }

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

311

312

313 auto *newBB = new Block();

315

316

317

318 newBB->getOperations().splice(newBB->end(), getOperations(), splitBefore,

320 return newBB;

321 }

322

323

324

325

326

329 }

330

331

333 return I->getOperandNumber();

334 }

335

336

337

338

339

341

343 if (block->empty() || llvm::hasSingleElement(*block->getParent()))

344 return;

348 }

349

353 }

354

357 if (except.contains(other)) {

358

359

360 return false;

361 }

363 while (!worklist.empty()) {

364 Block *next = worklist.pop_back_val();

365 if (next == other)

366 return true;

367

368 if (!except.insert(next).second)

369 continue;

371 }

372 return false;

373 }

374

375

376

377

378

380 if ((count = blocks.size()))

381 base = blocks.data();

382 }

383

386

387

388 BlockRange::OwnerT BlockRange::offset_base(OwnerT object, ptrdiff_t index) {

389 if (auto *operand = llvm::dyn_cast_if_present<BlockOperand *>(object))

390 return {operand + index};

391 return {llvm::dyn_cast_if_present<Block *const *>(object) + index};

392 }

393

394

395 Block *BlockRange::dereference_iterator(OwnerT object, ptrdiff_t index) {

396 if (const auto *operand = llvm::dyn_cast_if_present<BlockOperand *>(object))

397 return operand[index].get();

398 return llvm::dyn_cast_if_present<Block *const *>(object)[index];

399 }

static Value getBase(Value v)

Looks through known "view-like" ops to find the base memref.

This class represents an argument of a Block.

unsigned getArgNumber() const

Returns the number of this argument.

A block operand represents an operand that holds a reference to a Block, e.g.

This class provides an abstraction over the different types of ranges over Blocks.

BlockRange(ArrayRef< Block * > blocks=std::nullopt)

Block represents an ordered list of Operations.

void recomputeOpOrder()

Recomputes the ordering of child operations within the block.

OpListType::iterator iterator

Operation * findAncestorOpInBlock(Operation &op)

Returns 'op' if 'op' lies in this block, or otherwise finds the ancestor operation of 'op' that lies ...

ValueTypeRange< BlockArgListType > getArgumentTypes()

Return a range containing the types of the arguments for this block.

unsigned getNumSuccessors()

void erase()

Unlink this Block from its parent region and delete it.

BlockArgument insertArgument(args_iterator it, Type type, Location loc)

Insert one value to the position in the argument list indicated by the given iterator.

iterator_range< args_iterator > addArguments(TypeRange types, ArrayRef< Location > locs)

Add one argument to the argument list for each type specified in the list.

Block * splitBlock(iterator splitBefore)

Split the block into two blocks before the specified operation or iterator.

Region * getParent() const

Provide a 'getParent' method for ilist_node_with_parent methods.

bool isOpOrderValid()

Returns true if the ordering of the child operations is valid, false otherwise.

pred_iterator pred_begin()

void dropAllDefinedValueUses()

This drops all uses of values defined in this block or in the blocks of nested regions wherever the u...

bool verifyOpOrder()

Verifies the current ordering of child operations matches the validOpOrder flag.

void invalidateOpOrder()

Invalidates the current ordering of operations.

Block * getSinglePredecessor()

If this block has exactly one predecessor, return it.

void insertAfter(Block *block)

Insert this block (which must not already be in a region) right after the specified block.

Operation * getTerminator()

Get the terminator operation of this block.

succ_iterator succ_begin()

iterator_range< pred_iterator > getPredecessors()

BlockArgument addArgument(Type type, Location loc)

Add one value to the argument list.

void eraseArguments(unsigned start, unsigned num)

Erases 'num' arguments from the index 'start'.

OpListType & getOperations()

bool mightHaveTerminator()

Check whether this block might have a terminator.

BlockArgListType getArguments()

bool isReachable(Block *other, SmallPtrSet< Block *, 16 > &&except={})

Return "true" if there is a path from this block to the given block (according to the successors rela...

Block * getUniquePredecessor()

If this block has a unique predecessor, i.e., all incoming edges originate from one block,...

void eraseArgument(unsigned index)

Erase the argument at 'index' and remove it from the argument list.

Block * getSuccessor(unsigned i)

bool isEntryBlock()

Return if this block is the entry block in the parent region.

void dropAllReferences()

This drops all operand uses from operations within this block, which is an essential step in breaking...

void insertBefore(Block *block)

Insert this block (which must not already be in a region) right before the specified block.

void moveBefore(Block *block)

Unlink this block from its current region and insert it right before the specific block.

Operation * getParentOp()

Returns the closest surrounding operation that contains this block.

BlockArgListType::iterator args_iterator

void dropAllUses()

Drop all uses of this object from their respective owners.

This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...

This class provides the API for ops that are known to be terminators.

Operation is the basic unit of execution within MLIR.

Block * getSuccessor(unsigned index)

unsigned getNumSuccessors()

void dropAllReferences()

This drops all operand uses from this operation, which is an essential step in breaking cyclic depend...

bool mightHaveTrait()

Returns true if the operation might have the provided trait.

Operation * getParentOp()

Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...

Block * getBlock()

Returns the operation block that contains this operation.

MutableArrayRef< BlockOperand > getBlockOperands()

unsigned getSuccessorIndex() const

Get the successor number in the predecessor terminator.

This class contains a list of basic blocks and a link to the parent operation it is attached to.

Operation * getParentOp()

Return the parent operation this region is attached to.

BlockListType & getBlocks()

BlockListType::iterator iterator

This class implements the successor iterators for Block.

This class provides an abstraction over the various different ranges of value types.

Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...

This class implements iteration on the types of a given range of values.

Operation * getOwner() const

Return the owner of this operand.

Include the generated interface declarations.