MLIR: include/mlir/IR/UseDefLists.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13 #ifndef MLIR_IR_USEDEFLISTS_H

14 #define MLIR_IR_USEDEFLISTS_H

15

17 #include "llvm/ADT/PointerIntPair.h"

18 #include "llvm/ADT/iterator_range.h"

19

20 namespace mlir {

21

22 class Operation;

23 template

24 class ValueUseIterator;

25 template <typename UseIteratorT, typename OperandType>

26 class ValueUserIterator;

27

28

29

30

31

32 namespace detail {

33

34

36 public:

37

39

40

41

42

44

45

46

48 assert(this == *self);

51 }

52

53

58 }

59

60 protected:

63 *this = std::move(other);

64 }

67 other.removeFromCurrent();

68 other.back = nullptr;

70 back = nullptr;

71 return *this;

72 }

73

76

78

79

83 back = nullptr;

84 }

85

86

89 return;

93 }

94

95

96 template

98 back = &useList->firstUse;

99 nextUse = useList->firstUse;

102 useList->firstUse = this;

103 }

104

105

107

108

110

111 private:

112

114 };

115 }

116

117

118

119

120

121

122

123

124

125

126 template <typename DerivedT, typename IRValueT>

128 public:

132 insertIntoCurrent();

133 }

134

135

136

138 *this = std::move(other);

139 }

142 value = other.value;

143 other.value = nullptr;

144 if (value)

145 insertIntoCurrent();

146 return *this;

147 }

148

149

150

151

153 return this == &other;

154 }

156 return !(*this == other);

157 }

158

159

160 IRValueT get() const { return value; }

161

162

163 void set(IRValueT newValue) {

164

165

167 value = newValue;

168 insertIntoCurrent();

169 }

170

171

172 bool is(IRValueT other) const { return value == other; }

173

174

177 value = nullptr;

178 }

179

180 private:

181

182

183 IRValueT value = {};

184

185

186 void insertIntoCurrent() { insertInto(DerivedT::getUseList(value)); }

187 };

188

189

190

191

192

193

194 template

196 public:

198 assert(use_empty() && "Cannot destroy a value that still has uses!");

199 }

200

201

205 }

206

207

208

209

210 template

212 assert((!newValue || this != OperandType::getUseList(newValue)) &&

213 "cannot RAUW a value with itself");

216 }

217

218

219

220

221

223 assert((size_t)std::distance(getUses().begin(), getUses().end()) ==

224 indices.size() &&

225 "indices vector expected to have a number of elements equal to the "

226 "number of uses");

229 for (size_t idx = 0; idx < indices.size();

231 shuffled[indices[idx]] = ptr;

232

233 initFirstUse(shuffled.front());

234 auto *current = firstUse;

235 for (auto &next : llvm::drop_begin(shuffled)) {

236 current->linkTo(next);

237 current = next;

238 }

239 current->linkTo(nullptr);

240 }

241

242

243

244

245

248

251

252

254

255

258 }

259

260

261 bool use_empty() const { return firstUse == nullptr; }

262

263

264

265

266

269

272

273

275

276 protected:

278

279

280

281 OperandType *getFirstUse() const { return (OperandType *)firstUse; }

282

283 private:

284

286 firstUse = use;

288 }

289

290 detail::IROperandBase *firstUse = nullptr;

291

292

293 friend detail::IROperandBase;

294 };

295

296

297

298

299

300

301

302 template

304 : public llvm::iterator_facade_base<ValueUseIterator,

305 std::forward_iterator_tag,

306 OperandType> {

307 public:

309

310

312

313

316

317 using llvm::iterator_facade_base<ValueUseIterator,

318 std::forward_iterator_tag,

319 OperandType>::operator++;

321 assert(current && "incrementing past end()!");

323 return *this;

324 }

325

328 }

329

330 protected:

332 };

333

334

335

336

337

338

339

340 template <typename UseIteratorT, typename OperandType>

342 : public llvm::mapped_iterator_base<

343 ValueUserIterator<UseIteratorT, OperandType>, UseIteratorT,

344 Operation *> {

345 public:

346 using llvm::mapped_iterator_base<ValueUserIterator<UseIteratorT, OperandType>,

347 UseIteratorT,

348 Operation *>::mapped_iterator_base;

349

350

352

353

355 };

356

357 }

358

359 #endif

This class represents a single IR object that contains a use list.

bool hasOneUse() const

Returns true if this value has exactly one use.

use_range getUses() const

Returns a range of all uses, which is useful for iterating over all uses.

user_range getUsers() const

Returns a range of all users.

ValueUseIterator< OperandType > use_iterator

OperandType * getFirstUse() const

Return the first operand that is using this value, for use by custom use/def iterators.

void dropAllUses()

Drop all uses of this object from their respective owners.

user_iterator user_end() const

void shuffleUseList(ArrayRef< unsigned > indices)

Shuffle the use-list chain according to the provided indices vector, which need to represent a valid ...

use_iterator use_begin() const

ValueUserIterator< use_iterator, OperandType > user_iterator

IRObjectWithUseList()=default

bool use_empty() const

Returns true if this value has no uses.

user_iterator user_begin() const

void replaceAllUsesWith(ValueT &&newValue)

Replace all uses of 'this' value with the new value, updating anything in the IR that uses 'this' to ...

use_iterator use_end() const

A reference to a value, suitable for use as an operand of an operation.

IRValueT get() const

Return the current value being used by this operand.

void set(IRValueT newValue)

Set the current value being used by this operand.

IROperand & operator=(IROperand &&other)

bool operator==(const IROperand< DerivedT, IRValueT > &other) const

Two operands are equal if they have the same owner and the same operand number.

bool is(IRValueT other) const

Returns true if this operand contains the given value.

IROperand(IROperand &&other)

We support a move constructor so IROperand's can be in vectors, but this shouldn't be used by general...

IROperand(Operation *owner)

IROperand(Operation *owner, IRValueT value)

void drop()

Remove this use of the operand.

bool operator!=(const IROperand< DerivedT, IRValueT > &other) const

Operation is the basic unit of execution within MLIR.

An iterator class that allows for iterating over the uses of an IR operand type.

ValueUseIterator(detail::IROperandBase *use=nullptr)

bool operator==(const ValueUseIterator &rhs) const

detail::IROperandBase * current

Operation * getUser() const

Returns the operation that owns this use.

ValueUseIterator & operator++()

OperandType * getOperand() const

Returns the current operands.

OperandType & operator*() const

An iterator over the users of an IRObject.

Operation * operator->()

Provide access to the underlying operation.

Operation * mapElement(OperandType &value) const

Map the element to the iterator result type.

This class is the base for IROperand, and provides all of the non-templated facilities for operand us...

IROperandBase & operator=(const IROperandBase &use)=delete

IROperandBase * nextUse

The next operand in the use-chain.

IROperandBase ** back

This points to the previous link in the use-chain.

IROperandBase(const IROperandBase &use)=delete

Operands are not copyable or assignable.

void removeFromCurrent()

Remove this operand from the current use list.

IROperandBase(Operation *owner)

Operation * getOwner() const

Return the owner of this operand.

void linkTo(IROperandBase *next)

Link the current node to next.

void drop()

Remove this use of the operand.

IROperandBase(IROperandBase &&other)

void insertInto(UseListT *useList)

Insert this operand into the given use list.

IROperandBase & operator=(IROperandBase &&other)

void initChainWithUse(IROperandBase **self)

Initialize the use-def chain by setting the back address to self and nextUse to nullptr.

IROperandBase * getNextOperandUsingThisValue()

Return the next operand on the use-list of the value we are referring to.

Include the generated interface declarations.