LLVM: include/llvm/Analysis/RegionIterator.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11#ifndef LLVM_ANALYSIS_REGIONITERATOR_H

12#define LLVM_ANALYSIS_REGIONITERATOR_H

13

18#include

19#include

20#include <type_traits>

21

22namespace llvm {

23

25class RegionInfo;

26

27

28

29

30

31

32

33

34

35

36

37

38template <class NodeRef, class BlockT, class RegionT> class RNSuccIterator {

39public:

45

46private:

48 using SuccIterTy = typename BlockTraits::ChildIteratorType;

49

50

51 enum ItMode {

52

53

54 ItBB,

55

56

57 ItRgBegin,

58 ItRgEnd

59 };

60

61 static_assert(std::is_pointer::value,

62 "FIXME: Currently RNSuccIterator only supports NodeRef as "

63 "pointers due to the use of pointer-specific data structures "

64 "(e.g. PointerIntPair and SmallPtrSet) internally. Generalize "

65 "it to support non-pointer types");

66

67

69

70

71 SuccIterTy BItor;

72

73

74

75 void advanceRegionSucc() {

76 assert(Node.getInt() == ItRgBegin && "Cannot advance region successor!");

77 Node.setInt(ItRgEnd);

78 }

79

80 NodeRef getNode() const { return Node.getPointer(); }

81

82

83 bool isRegionMode() const { return Node.getInt() != ItBB; }

84

85

86

87 NodeRef getISucc(BlockT *BB) const {

89 succ = getNode()->getParent()->getNode(BB);

90 assert(succ && "BB not in Region or entered subregion!");

91 return succ;

92 }

93

94

95 inline BlockT* getRegionSucc() const {

96 assert(Node.getInt() == ItRgBegin && "Cannot get the region successor!");

97 return getNode()->template getNodeAs()->getExit();

98 }

99

100

101 inline bool isExit(BlockT* BB) const {

102 return getNode()->getParent()->getExit() == BB;

103 }

104

105public:

107

108

110 : Node(node, node->isSubRegion() ? ItRgBegin : ItBB),

111 BItor(BlockTraits::child_begin(node->getEntry())) {

112

113 if (!isRegionMode())

114 while (BlockTraits::child_end(node->getEntry()) != BItor && isExit(*BItor))

115 ++BItor;

116

117 if (isRegionMode() && isExit(getRegionSucc()))

118 advanceRegionSucc();

119 }

120

121

123 : Node(node, node->isSubRegion() ? ItRgEnd : ItBB),

124 BItor(BlockTraits::child_end(node->getEntry())) {}

125

127 assert(isRegionMode() == x.isRegionMode() && "Broken iterator!");

128 if (isRegionMode())

129 return Node.getInt() == x.Node.getInt();

130 else

131 return BItor == x.BItor;

132 }

133

135

137 BlockT *BB = isRegionMode() ? getRegionSucc() : *BItor;

138 assert(!isExit(BB) && "Iterator out of range!");

139 return getISucc(BB);

140 }

141

143 if(isRegionMode()) {

144

145 advanceRegionSucc();

146 } else {

147

148 do

149 ++BItor;

150 while (BItor != BlockTraits::child_end(getNode()->getEntry())

151 && isExit(*BItor));

152 }

153 return *this;

154 }

155

157 Self tmp = *this;

158 ++*this;

159 return tmp;

160 }

161};

162

163

164

165

166

167

168

169template <class NodeRef, class BlockT, class RegionT>

172 using SuccIterTy = typename BlockTraits::ChildIteratorType;

173

174 NodeRef Node;

175 SuccIterTy Itor;

176

177public:

183

185

186

187

188

189

191 : Node(node), Itor(BlockTraits::child_begin(node->getEntry())) {

193 "Subregion node not allowed in flat iterating mode!");

194 assert(Node->getParent() && "A BB node must have a parent!");

195

196

197 while (BlockTraits::child_end(Node->getEntry()) != Itor &&

198 Node->getParent()->getExit() == *Itor)

199 ++Itor;

200 }

201

202

204 : Node(node), Itor(BlockTraits::child_end(node->getEntry())) {

206 "Subregion node not allowed in flat iterating mode!");

207 }

208

210 assert(Node->getParent() == x.Node->getParent()

211 && "Cannot compare iterators of different regions!");

212

213 return Itor == x.Itor && Node == x.Node;

214 }

215

216 inline bool operator!=(const Self& x) const { return !operator==(x); }

217

219 BlockT *BB = *Itor;

220

221

222 RegionT *Parent = Node->getParent();

223

224

225

226 assert(Parent->getExit() != BB && "iterator out of range!");

227

228 return Parent->getBBNode(BB);

229 }

230

232

233 do

234 ++Itor;

236 && Node->getParent()->getExit() == *Itor);

237

238 return *this;

239 }

240

242 Self tmp = *this;

243 ++*this;

244 return tmp;

245 }

246};

247

248template <class NodeRef, class BlockT, class RegionT>

251}

252

253template <class NodeRef, class BlockT, class RegionT>

256}

257

258

259

260

261

262

263

264

265#define RegionNodeGraphTraits(NodeT, BlockT, RegionT) \

266 template <> struct GraphTraits<NodeT *> { \

267 using NodeRef = NodeT *; \

268 using ChildIteratorType = RNSuccIterator<NodeRef, BlockT, RegionT>; \

269 static NodeRef getEntryNode(NodeRef N) { return N; } \

270 static inline ChildIteratorType child_begin(NodeRef N) { \

271 return RNSuccIterator<NodeRef, BlockT, RegionT>(N); \

272 } \

273 static inline ChildIteratorType child_end(NodeRef N) { \

274 return RNSuccIterator<NodeRef, BlockT, RegionT>(N, true); \

275 } \

276 }; \

277 template <> struct GraphTraits<FlatIt<NodeT *>> { \

278 using NodeRef = NodeT *; \

279 using ChildIteratorType = \

280 RNSuccIterator<FlatIt, BlockT, RegionT>; \

281 static NodeRef getEntryNode(NodeRef N) { return N; } \

282 static inline ChildIteratorType child_begin(NodeRef N) { \

283 return RNSuccIterator<FlatIt, BlockT, RegionT>(N); \

284 } \

285 static inline ChildIteratorType child_end(NodeRef N) { \

286 return RNSuccIterator<FlatIt, BlockT, RegionT>(N, true); \

287 } \

288 }

289

290#define RegionGraphTraits(RegionT, NodeT) \

291 template <> struct GraphTraits<RegionT *> : public GraphTraits<NodeT *> { \

292 using nodes_iterator = df_iterator; \

293 static NodeRef getEntryNode(RegionT *R) { \

294 return R->getNode(R->getEntry()); \

295 } \

296 static nodes_iterator nodes_begin(RegionT *R) { \

297 return nodes_iterator::begin(getEntryNode(R)); \

298 } \

299 static nodes_iterator nodes_end(RegionT *R) { \

300 return nodes_iterator::end(getEntryNode(R)); \

301 } \

302 }; \

303 template <> \

304 struct GraphTraits<FlatIt<RegionT *>> \

305 : public GraphTraits<FlatIt<NodeT *>> { \

306 using nodes_iterator = \

307 df_iterator<NodeRef, df_iterator_default_set, false, \

308 GraphTraits<FlatIt>>; \

309 static NodeRef getEntryNode(RegionT *R) { \

310 return R->getBBNode(R->getEntry()); \

311 } \

312 static nodes_iterator nodes_begin(RegionT *R) { \

313 return nodes_iterator::begin(getEntryNode(R)); \

314 } \

315 static nodes_iterator nodes_end(RegionT *R) { \

316 return nodes_iterator::end(getEntryNode(R)); \

317 } \

318 }

319

322

325

331

334 }

335

337 return nodes_iterator::begin(getEntryNode(RI));

338 }

339

341 return nodes_iterator::end(getEntryNode(RI));

342 }

343};

344

350

353 }

354

357 }

358

361 }

362};

363

364}

365

366#endif

This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.

This file defines the little GraphTraits template class that should be specialized by classes that...

This file defines the PointerIntPair class.

#define RegionNodeGraphTraits(NodeT, BlockT, RegionT)

#define RegionGraphTraits(RegionT, NodeT)

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

LLVM Basic Block Representation.

Marker class to iterate over the elements of a Region in flat mode.

PointerIntPair - This class implements a pair of a pointer and small integer.

Flat RegionNode iterator.

std::forward_iterator_tag iterator_category

bool operator==(const Self &x) const

RNSuccIterator(NodeRef node, bool)

Create an end iterator.

value_type operator*() const

RNSuccIterator(NodeRef node)

Create the iterator from a RegionNode.

bool operator!=(const Self &x) const

std::ptrdiff_t difference_type

Hierarchical RegionNode successor iterator.

value_type operator*() const

RNSuccIterator(NodeRef node, bool)

Create an end iterator.

std::forward_iterator_tag iterator_category

std::ptrdiff_t difference_type

bool operator!=(const Self &x) const

bool operator==(const Self &x) const

RNSuccIterator(NodeRef node)

Create begin iterator of a RegionNode.

RegionT * getTopLevelRegion() const

RegionInfo & getRegionInfo()

@ BasicBlock

Various leaf nodes.

std::pair< NodeId, LaneBitmask > NodeRef

This is an optimization pass for GlobalISel generic memory operations.

RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)

RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)

static nodes_iterator nodes_begin(RegionInfoPass *RI)

static nodes_iterator nodes_end(RegionInfoPass *RI)

static NodeRef getEntryNode(RegionInfoPass *RI)

static nodes_iterator nodes_begin(RegionInfo *RI)

static nodes_iterator nodes_end(RegionInfo *RI)

static NodeRef getEntryNode(RegionInfo *RI)

typename GraphType::UnknownGraphTypeError NodeRef