llvm.org GIT mirror llvm / f96b006
Add new RegionInfo pass. The RegionInfo pass detects single entry single exit regions in a function, where a region is defined as any subgraph that is connected to the remaining graph at only two spots. Furthermore an hierarchical region tree is built. Use it by calling "opt -regions analyze" or "opt -view-regions". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109089 91177308-0d34-0410-b5e6-96231b3b80d8 Tobias Grosser 9 years ago
32 changed file(s) with 2707 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
119119
-print-used-typesFind Used Types
120120
-profile-estimatorEstimate profiling information
121121
-profile-loaderLoad profile information from llvmprof.out
122
-regionsDetect single entry single exit regions in a function
122123
-profile-verifierVerify profiling information
123124
-scalar-evolutionScalar Evolution Analysis
124125
-scev-aaScalarEvolution-based Alias Analysis
770771
771772

Pass that checks profiling information for plausibility.

772773
774
775 -regions: Detect single entry single exit regions in a function
776
777
778

779 The RegionInfo pass detects single entry single exit regions in a
780 function, where a region is defined as any subgraph that is connected to the
781 remaining graph at only two spots. Furthermore, an hierarchical region tree is
782 built.
783

784
773785
774786
775787
153153 // print debug info intrinsics in human readable form
154154 FunctionPass *createDbgInfoPrinterPass();
155155
156 //===--------------------------------------------------------------------===//
157 //
158 // createRegionInfoPass - This pass finds all single entry single exit regions
159 // in a function and builds the region hierarchy.
160 //
161 FunctionPass *createRegionInfoPass();
162
156163 // Print module-level debug info metadata in human-readable form.
157164 ModulePass *createModuleDebugInfoPrinterPass();
158165 }
0 //===- RegionInfo.h - SESE region analysis ----------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Calculate a program structure tree built out of single entry single exit
10 // regions.
11 // The basic ideas are taken from "The Program Structure Tree - Richard Johnson,
12 // David Pearson, Keshav Pingali - 1994", however enriched with ideas from "The
13 // Refined Process Structure Tree - Jussi Vanhatalo, Hagen Voelyer, Jana
14 // Koehler - 2009".
15 // The algorithm to calculate these data structures however is completely
16 // different, as it takes advantage of existing information already available
17 // in (Post)dominace tree and dominance frontier passes. This leads to a simpler
18 // and in practice hopefully better performing algorithm. The runtime of the
19 // algorithms described in the papers above are both linear in graph size,
20 // O(V+E), whereas this algorithm is not, as the dominance frontier information
21 // itself is not, but in practice runtime seems to be in the order of magnitude
22 // of dominance tree calculation.
23 //
24 //===----------------------------------------------------------------------===//
25
26 #ifndef LLVM_ANALYSIS_REGION_INFO_H
27 #define LLVM_ANALYSIS_REGION_INFO_H
28
29 #include "llvm/ADT/PointerIntPair.h"
30 #include "llvm/Analysis/Dominators.h"
31 #include "llvm/Analysis/PostDominators.h"
32 #include "llvm/Support/Allocator.h"
33
34 namespace llvm {
35
36 class Region;
37 class RegionInfo;
38 class raw_ostream;
39
40 /// @brief Marker class to iterate over the elements of a Region in flat mode.
41 ///
42 /// The class is used to either iterate in Flat mode or by not using it to not
43 /// iterate in Flat mode. During a Flat mode iteration all Regions are entered
44 /// and the iteration returns every BasicBlock. If the Flat mode is not
45 /// selected for SubRegions just one RegionNode containing the subregion is
46 /// returned.
47 template
48 class FlatIt {};
49
50 /// @brief A RegionNode represents a subregion or a BasicBlock that is part of a
51 /// Region.
52 class RegionNode {
53 // DO NOT IMPLEMENT
54 RegionNode(const RegionNode &);
55 // DO NOT IMPLEMENT
56 const RegionNode &operator=(const RegionNode &);
57
58 /// This is the entry basic block that starts this region node. If this is a
59 /// BasicBlock RegionNode, then entry is just the basic block, that this
60 /// RegionNode represents. Otherwise it is the entry of this (Sub)RegionNode.
61 ///
62 /// In the BBtoRegionNode map of the parent of this node, BB will always map
63 /// to this node no matter which kind of node this one is.
64 ///
65 /// The node can hold either a Region or a BasicBlock.
66 /// Use one bit to save, if this RegionNode is a subregion or BasicBlock
67 /// RegionNode.
68 PointerIntPair entry;
69
70 protected:
71 /// @brief The parent Region of this RegionNode.
72 /// @see getParent()
73 Region* parent;
74
75 public:
76 /// @brief Create a RegionNode.
77 ///
78 /// @param Parent The parent of this RegionNode.
79 /// @param Entry The entry BasicBlock of the RegionNode. If this
80 /// RegionNode represents a BasicBlock, this is the
81 /// BasicBlock itself. If it represents a subregion, this
82 /// is the entry BasicBlock of the subregion.
83 /// @param isSubRegion If this RegionNode represents a SubRegion.
84 inline RegionNode(Region* Parent, BasicBlock* Entry, bool isSubRegion = 0)
85 : entry(Entry, isSubRegion), parent(Parent) {}
86
87 /// @brief Get the parent Region of this RegionNode.
88 ///
89 /// The parent Region is the Region this RegionNode belongs to. If for
90 /// example a BasicBlock is element of two Regions, there exist two
91 /// RegionNodes for this BasicBlock. Each with the getParent() function
92 /// pointing to the Region this RegionNode belongs to.
93 ///
94 /// @return Get the parent Region of this RegionNode.
95 inline Region* getParent() const { return parent; }
96
97 /// @brief Get the entry BasicBlock of this RegionNode.
98 ///
99 /// If this RegionNode represents a BasicBlock this is just the BasicBlock
100 /// itself, otherwise we return the entry BasicBlock of the Subregion
101 ///
102 /// @return The entry BasicBlock of this RegionNode.
103 inline BasicBlock* getEntry() const { return entry.getPointer(); }
104
105 /// @brief Get the content of this RegionNode.
106 ///
107 /// This can be either a BasicBlock or a subregion. Before calling getNodeAs()
108 /// check the type of the content with the isSubRegion() function call.
109 ///
110 /// @return The content of this RegionNode.
111 template
112 inline T* getNodeAs() const;
113
114 /// @brief Is this RegionNode a subregion?
115 ///
116 /// @return True if it contains a subregion. False if it contains a
117 /// BasicBlock.
118 inline bool isSubRegion() const {
119 return entry.getInt();
120 }
121 };
122
123 /// Print a RegionNode.
124 inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node);
125
126 template<>
127 inline BasicBlock* RegionNode::getNodeAs() const {
128 assert(!isSubRegion() && "This is not a BasicBlock RegionNode!");
129 return getEntry();
130 }
131
132 template<>
133 inline Region* RegionNode::getNodeAs() const {
134 assert(isSubRegion() && "This is not a subregion RegionNode!");
135 return reinterpret_cast(const_cast(this));
136 }
137
138 //===----------------------------------------------------------------------===//
139 /// @brief A single entry single exit Region.
140 ///
141 /// A Region is a connected subgraph of a control flow graph that has exactly
142 /// two connections to the remaining graph. It can be used to analyze or
143 /// optimize parts of the control flow graph.
144 ///
145 /// A simple Region is connected to the remaing graph by just two
146 /// edges. One edge entering the Region and another one leaving the Region.
147 ///
148 /// An extended Region (or just Region) is a subgraph that can be
149 /// transform into a simple Region. The transformation is done by adding
150 /// BasicBlocks that merge several entry or exit edges so that after the merge
151 /// just one entry and one exit edge exists.
152 ///
153 /// The \e Entry of a Region is the first BasicBlock that is passed after
154 /// entering the Region. It is an element of the Region. The entry BasicBlock
155 /// dominates all BasicBlocks in the Region.
156 ///
157 /// The \e Exit of a Region is the first BasicBlock that is passed after
158 /// leaving the Region. It is not an element of the Region. The exit BasicBlock,
159 /// postdominates all BasicBlocks in the Region.
160 ///
161 /// A canonical Region cannot be constructed by combining smaller
162 /// Regions.
163 ///
164 /// Region A is the \e parent of Region B, if B is completely contained in A.
165 ///
166 /// Two canonical Regions either do not intersect at all or one is
167 /// the parent of the other.
168 ///
169 /// The Program Structure Tree is a graph (V, E) where V is the set of
170 /// Regions in the control flow graph and E is the \e parent relation of these
171 /// Regions.
172 ///
173 /// Example:
174 ///
175 /// \verbatim
176 /// A simple control flow graph, that contains two regions.
177 ///
178 /// 1
179 /// / |
180 /// 2 |
181 /// / \ 3
182 /// 4 5 |
183 /// | | |
184 /// 6 7 8
185 /// \ | /
186 /// \ |/ Region A: 1 -> 9 {1,2,3,4,5,6,7,8}
187 /// 9 Region B: 2 -> 9 {2,4,5,6,7}
188 /// \endverbatim
189 ///
190 /// You can obtain more examples by either calling
191 ///
192 /// "opt -regions -analyze anyprogram.ll"
193 /// or
194 /// "opt -view-regions-only anyprogram.ll"
195 ///
196 /// on any LLVM file you are interested in.
197 ///
198 /// The first call returns a textual representation of the program structure
199 /// tree, the second one creates a graphical representation using graphviz.
200 class Region : public RegionNode {
201 friend class RegionInfo;
202 // DO NOT IMPLEMENT
203 Region(const Region &);
204 // DO NOT IMPLEMENT
205 const Region &operator=(const Region &);
206
207 // Information necessary to manage this Region.
208 RegionInfo* RI;
209 DominatorTree *DT;
210
211 // The exit BasicBlock of this region.
212 // (The entry BasicBlock is part of RegionNode)
213 BasicBlock *exit;
214
215 typedef std::vector RegionSet;
216
217 // The subregions of this region.
218 RegionSet children;
219
220 typedef std::map BBNodeMapT;
221
222 // Save the BasicBlock RegionNodes that are element of this Region.
223 mutable BBNodeMapT BBNodeMap;
224
225 /// verifyBBInRegion - Check if a BB is in this Region. This check also works
226 /// if the region is incorrectly built. (EXPENSIVE!)
227 void verifyBBInRegion(BasicBlock* BB) const;
228
229 /// verifyWalk - Walk over all the BBs of the region starting from BB and
230 /// verify that all reachable basic blocks are elements of the region.
231 /// (EXPENSIVE!)
232 void verifyWalk(BasicBlock* BB, std::set* visitedBB) const;
233
234 /// verifyRegionNest - Verify if the region and its children are valid
235 /// regions (EXPENSIVE!)
236 void verifyRegionNest() const;
237
238 public:
239 /// @brief Create a new region.
240 ///
241 /// @param Entry The entry basic block of the region.
242 /// @param Exit The exit basic block of the region.
243 /// @param RI The region info object that is managing this region.
244 /// @param DT The dominator tree of the current function.
245 /// @param Parent The surrounding region or NULL if this is a top level
246 /// region.
247 Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RI,
248 DominatorTree *DT, Region *Parent = 0);
249
250 /// Delete the Region and all its subregions.
251 ~Region();
252
253 /// @brief Get the entry BasicBlock of the Region.
254 /// @return The entry BasicBlock of the region.
255 BasicBlock *getEntry() const { return RegionNode::getEntry(); }
256
257 /// @brief Get the exit BasicBlock of the Region.
258 /// @return The exit BasicBlock of the Region, NULL if this is the TopLevel
259 /// Region.
260 BasicBlock *getExit() const { return exit; }
261
262 /// @brief Get the parent of the Region.
263 /// @return The parent of the Region or NULL if this is a top level
264 /// Region.
265 Region *getParent() const { return RegionNode::getParent(); }
266
267 /// @brief Get the RegionNode representing the current Region.
268 /// @return The RegionNode representing the current Region.
269 RegionNode* getNode() const {
270 return const_cast(reinterpret_cast(this));
271 }
272
273 /// @brief Get the nesting level of this Region.
274 ///
275 /// An toplevel Region has depth 0.
276 ///
277 /// @return The depth of the region.
278 unsigned getDepth() const;
279
280 /// @brief Is this a simple region?
281 ///
282 /// A region is simple if it has exactly one exit and one entry edge.
283 ///
284 /// @return True if the Region is simple.
285 bool isSimple() const;
286
287 /// @brief Returns the name of the Region.
288 /// @return The Name of the Region.
289 std::string getNameStr() const {
290 std::string exitName;
291
292 if (getExit())
293 exitName = getExit()->getNameStr();
294 else
295 exitName = "";
296
297 return getEntry()->getNameStr() + " => " + exitName;
298 }
299
300 /// @brief Return the RegionInfo object, that belongs to this Region.
301 RegionInfo *getRegionInfo() const {
302 return RI;
303 }
304
305 /// @brief Print the region.
306 ///
307 /// @param OS The output stream the Region is printed to.
308 /// @param printTree Print also the tree of subregions.
309 /// @param level The indentation level used for printing.
310 void print(raw_ostream& OS, bool printTree = true, unsigned level = 0) const;
311
312 /// @brief Print the region to stderr.
313 void dump() const;
314
315 /// @brief Check if the region contains a BasicBlock.
316 ///
317 /// @param BB The BasicBlock that might be contained in this Region.
318 /// @return True if the block is contained in the region otherwise false.
319 bool contains(const BasicBlock *BB) const;
320
321 /// @brief Check if the region contains another region.
322 ///
323 /// @param SubRegion The region that might be contained in this Region.
324 /// @return True if SubRegion is contained in the region otherwise false.
325 bool contains(const Region *SubRegion) const {
326 // Toplevel Region.
327 if (!getExit())
328 return true;
329
330 return contains(SubRegion->getEntry())
331 && (contains(SubRegion->getExit()) || SubRegion->getExit() == getExit());
332 }
333
334 /// @brief Check if the region contains an Instruction.
335 ///
336 /// @param Inst The Instruction that might be contained in this region.
337 /// @return True if the Instruction is contained in the region otherwise false.
338 bool contains(const Instruction *Inst) const {
339 return contains(Inst->getParent());
340 }
341
342 /// @brief Get the subregion that starts at a BasicBlock
343 ///
344 /// @param BB The BasicBlock the subregion should start.
345 /// @return The Subregion if available, otherwise NULL.
346 Region* getSubRegionNode(BasicBlock *BB) const;
347
348 /// @brief Get the RegionNode for a BasicBlock
349 ///
350 /// @param BB The BasicBlock at which the RegionNode should start.
351 /// @return If available, the RegionNode that represents the subregion
352 /// starting at BB. If no subregion starts at BB, the RegionNode
353 /// representing BB.
354 RegionNode* getNode(BasicBlock *BB) const;
355
356 /// @brief Get the BasicBlock RegionNode for a BasicBlock
357 ///
358 /// @param BB The BasicBlock for which the RegionNode is requested.
359 /// @return The RegionNode representing the BB.
360 RegionNode* getBBNode(BasicBlock *BB) const;
361
362 /// @brief Add a new subregion to this Region.
363 ///
364 /// @param SubRegion The new subregion that will be added.
365 void addSubRegion(Region *SubRegion);
366
367 /// @brief Remove a subregion from this Region.
368 ///
369 /// The subregion is not deleted, as it will probably be inserted into another
370 /// region.
371 /// @param SubRegion The SubRegion that will be removed.
372 Region *removeSubRegion(Region *SubRegion);
373
374 /// @brief Move all direct child nodes of this Region to another Region.
375 ///
376 /// @param To The Region the child nodes will be transfered to.
377 void transferChildrenTo(Region *To);
378
379 /// @brief Verify if the region is a correct region.
380 ///
381 /// Check if this is a correctly build Region. This is an expensive check, as
382 /// the complete CFG of the Region will be walked.
383 void verifyRegion() const;
384
385 /// @brief Clear the cache for BB RegionNodes.
386 ///
387 /// After calling this function the BasicBlock RegionNodes will be stored at
388 /// different memory locations. RegionNodes obtained before this function is
389 /// called are therefore not comparable to RegionNodes abtained afterwords.
390 void clearNodeCache();
391
392 /// @name Subregion Iterators
393 ///
394 /// These iterators iterator over all subregions of this Region.
395 //@{
396 typedef RegionSet::iterator iterator;
397 typedef RegionSet::const_iterator const_iterator;
398
399 iterator begin() { return children.begin(); }
400 iterator end() { return children.end(); }
401
402 const_iterator begin() const { return children.begin(); }
403 const_iterator end() const { return children.end(); }
404 //@}
405
406 /// @name BasicBlock Iterators
407 ///
408 /// These iterators iterate over all BasicBlock RegionNodes that are
409 /// contained in this Region. The iterator also iterates over BasicBlocks
410 /// that are elements of a subregion of this Region. It is therefore called a
411 /// flat iterator.
412 //@{
413 typedef df_iterator, false,
414 GraphTraits > > block_iterator;
415
416 typedef df_iterator,
417 false, GraphTraits > >
418 const_block_iterator;
419
420 block_iterator block_begin();
421 block_iterator block_end();
422
423 const_block_iterator block_begin() const;
424 const_block_iterator block_end() const;
425 //@}
426
427 /// @name Element Iterators
428 ///
429 /// These iterators iterate over all BasicBlock and subregion RegionNodes that
430 /// are direct children of this Region. It does not iterate over any
431 /// RegionNodes that are also element of a subregion of this Region.
432 //@{
433 typedef df_iterator, false,
434 GraphTraits > element_iterator;
435
436 typedef df_iterator,
437 false, GraphTraits >
438 const_element_iterator;
439
440 element_iterator element_begin();
441 element_iterator element_end();
442
443 const_element_iterator element_begin() const;
444 const_element_iterator element_end() const;
445 //@}
446 };
447
448 //===----------------------------------------------------------------------===//
449 /// @brief Analysis that detects all canonical Regions.
450 ///
451 /// The RegionInfo pass detects all canonical regions in a function. The Regions
452 /// are connected using the parent relation. This builds a Program Structure
453 /// Tree.
454 class RegionInfo : public FunctionPass {
455 typedef DenseMap BBtoBBMap;
456 typedef DenseMap BBtoRegionMap;
457 typedef SmallPtrSet RegionSet;
458
459 // DO NOT IMPLEMENT
460 RegionInfo(const RegionInfo &);
461 // DO NOT IMPLEMENT
462 const RegionInfo &operator=(const RegionInfo &);
463
464 DominatorTree *DT;
465 PostDominatorTree *PDT;
466 DominanceFrontier *DF;
467
468 /// The top level region.
469 Region *TopLevelRegion;
470
471 /// Map every BB to the smallest region, that contains BB.
472 BBtoRegionMap BBtoRegion;
473
474 // isCommonDomFrontier - Returns true if BB is in the dominance frontier of
475 // entry, because it was inherited from exit. In the other case there is an
476 // edge going from entry to BB without passing exit.
477 bool isCommonDomFrontier(BasicBlock* BB, BasicBlock* entry,
478 BasicBlock* exit) const;
479
480 // isRegion - Check if entry and exit surround a valid region, based on
481 // dominance tree and dominance frontier.
482 bool isRegion(BasicBlock* entry, BasicBlock* exit) const;
483
484 // insertShortCut - Saves a shortcut pointing from entry to exit.
485 // This function may extend this shortcut if possible.
486 void insertShortCut(BasicBlock* entry, BasicBlock* exit,
487 BBtoBBMap* ShortCut) const;
488
489 // getNextPostDom - Returns the next BB that postdominates N, while skipping
490 // all post dominators that cannot finish a canonical region.
491 DomTreeNode *getNextPostDom(DomTreeNode* N, BBtoBBMap *ShortCut) const;
492
493 // isTrivialRegion - A region is trivial, if it contains only one BB.
494 bool isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const;
495
496 // createRegion - Creates a single entry single exit region.
497 Region *createRegion(BasicBlock *entry, BasicBlock *exit);
498
499 // findRegionsWithEntry - Detect all regions starting with bb 'entry'.
500 void findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut);
501
502 // scanForRegions - Detects regions in F.
503 void scanForRegions(Function &F, BBtoBBMap *ShortCut);
504
505 // getTopMostParent - Get the top most parent with the same entry block.
506 Region *getTopMostParent(Region *region);
507
508 // buildRegionsTree - build the region hierarchy after all region detected.
509 void buildRegionsTree(DomTreeNode *N, Region *region);
510
511 // Calculate - detecte all regions in function and build the region tree.
512 void Calculate(Function& F);
513
514 void releaseMemory();
515
516 // updateStatistics - Update statistic about created regions.
517 void updateStatistics(Region *R);
518
519 // isSimple - Check if a region is a simple region with exactly one entry
520 // edge and exactly one exit edge.
521 bool isSimple(Region* R) const;
522
523 public:
524 static char ID;
525 explicit RegionInfo();
526
527 ~RegionInfo();
528
529 /// @name FunctionPass interface
530 //@{
531 virtual bool runOnFunction(Function &F);
532 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
533 virtual void print(raw_ostream &OS, const Module *) const;
534 virtual void verifyAnalysis() const;
535 //@}
536
537 /// @brief Get the smallest region that contains a BasicBlock.
538 ///
539 /// @param BB The basic block.
540 /// @return The smallest region, that contains BB or NULL, if there is no
541 /// region containing BB.
542 Region *getRegionFor(BasicBlock *BB) const;
543
544 /// @brief A shortcut for getRegionFor().
545 ///
546 /// @param BB The basic block.
547 /// @return The smallest region, that contains BB or NULL, if there is no
548 /// region containing BB.
549 Region *operator[](BasicBlock *BB) const;
550
551 /// @brief Find the smallest region that contains two regions.
552 ///
553 /// @param A The first region.
554 /// @param B The second region.
555 /// @return The smallest region containing A and B.
556 Region *getCommonRegion(Region* A, Region *B) const;
557
558 /// @brief Find the smallest region that contains two basic blocks.
559 ///
560 /// @param A The first basic block.
561 /// @param B The second basic block.
562 /// @return The smallest region that contains A and B.
563 Region* getCommonRegion(BasicBlock* A, BasicBlock *B) const {
564 return getCommonRegion(getRegionFor(A), getRegionFor(B));
565 }
566
567 /// @brief Find the smallest region that contains a set of regions.
568 ///
569 /// @param Regions A vector of regions.
570 /// @return The smallest region that contains all regions in Regions.
571 Region* getCommonRegion(SmallVectorImpl &Regions) const;
572
573 /// @brief Find the smallest region that contains a set of basic blocks.
574 ///
575 /// @param BBs A vector of basic blocks.
576 /// @return The smallest region that contains all basic blocks in BBS.
577 Region* getCommonRegion(SmallVectorImpl &BBs) const;
578
579 Region *getTopLevelRegion() const {
580 return TopLevelRegion;
581 }
582
583 /// @brief Clear the Node Cache for all Regions.
584 ///
585 /// @see Region::clearNodeCache()
586 void clearNodeCache() {
587 if (TopLevelRegion)
588 TopLevelRegion->clearNodeCache();
589 }
590 };
591
592 inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node) {
593 if (Node.isSubRegion())
594 return OS << Node.getNodeAs()->getNameStr();
595 else
596 return OS << Node.getNodeAs()->getNameStr();
597 }
598 } // End llvm namespace
599 #endif
600
0 //===- RegionIterator.h - Iterators to iteratate over Regions ---*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // This file defines the iterators to iterate over the elements of a Region.
9 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_ANALYSIS_REGION_ITERATOR_H
11 #define LLVM_ANALYSIS_REGION_ITERATOR_H
12
13 #include "llvm/ADT/GraphTraits.h"
14 #include "llvm/ADT/SmallPtrSet.h"
15 #include "llvm/ADT/PointerIntPair.h"
16 #include "llvm/Analysis/RegionInfo.h"
17 #include "llvm/Support/CFG.h"
18 #include "llvm/Support/raw_ostream.h"
19
20 namespace llvm {
21 //===----------------------------------------------------------------------===//
22 /// @brief Hierachical RegionNode successor iterator.
23 ///
24 /// This iterator iterates over all successors of a RegionNode.
25 ///
26 /// For a BasicBlock RegionNode it skips all BasicBlocks that are not part of
27 /// the parent Region. Furthermore for BasicBlocks that start a subregion, a
28 /// RegionNode representing the subregion is returned.
29 ///
30 /// For a subregion RegionNode there is just one successor. The RegionNode
31 /// representing the exit of the subregion.
32 template
33 class RNSuccIterator : public std::iterator
34 NodeType, ptrdiff_t>
35 {
36 typedef std::iterator super;
37 // The iterator works in two modes, bb mode or region mode.
38 enum ItMode{
39 // In BB mode it returns all successors of this BasicBlock as its
40 // successors.
41 ItBB,
42 // In region mode there is only one successor, thats the regionnode mapping
43 // to the exit block of the regionnode
44 ItRgBegin, // At the beginning of the regionnode successor.
45 ItRgEnd // At the end of the regionnode successor.
46 };
47
48 // Use two bit to represent the mode iterator.
49 PointerIntPair Node;
50
51 // The block successor iterator.
52 succ_iterator BItor;
53
54 // advanceRegionSucc - A region node has only one successor. It reaches end
55 // once we advance it.
56 void advanceRegionSucc() {
57 assert(Node.getInt() == ItRgBegin && "Cannot advance region successor!");
58 Node.setInt(ItRgEnd);
59 }
60
61 NodeType* getNode() const{ return Node.getPointer(); }
62
63 // isRegionMode - Is the current iterator in region mode?
64 bool isRegionMode() const { return Node.getInt() != ItBB; }
65
66 // Get the immediate successor. This function may return a Basic Block
67 // RegionNode or a subregion RegionNode.
68 RegionNode* getISucc(BasicBlock* BB) const {
69 RegionNode *succ;
70 succ = getNode()->getParent()->getNode(BB);
71 assert(succ && "BB not in Region or entered subregion!");
72 return succ;
73 }
74
75 // getRegionSucc - Return the successor basic block of a SubRegion RegionNode.
76 inline BasicBlock* getRegionSucc() const {
77 assert(Node.getInt() == ItRgBegin && "Cannot get the region successor!");
78 return getNode()->template getNodeAs()->getExit();
79 }
80
81 // isExit - Is this the exit BB of the Region?
82 inline bool isExit(BasicBlock* BB) const {
83 return getNode()->getParent()->getExit() == BB;
84 }
85 public:
86 typedef RNSuccIterator Self;
87
88 typedef typename super::pointer pointer;
89
90 /// @brief Create begin iterator of a RegionNode.
91 inline RNSuccIterator(NodeType* node)
92 : Node(node, node->isSubRegion() ? ItRgBegin : ItBB),
93 BItor(succ_begin(node->getEntry())) {
94
95
96 // Skip the exit block
97 if (!isRegionMode())
98 while (succ_end(node->getEntry()) != BItor && isExit(*BItor))
99 ++BItor;
100
101 if (isRegionMode() && isExit(getRegionSucc()))
102 advanceRegionSucc();
103 }
104
105 /// @brief Create an end iterator.
106 inline RNSuccIterator(NodeType* node, bool)
107 : Node(node, node->isSubRegion() ? ItRgEnd : ItBB),
108 BItor(succ_end(node->getEntry())) {}
109
110 inline bool operator==(const Self& x) const {
111 assert(isRegionMode() == x.isRegionMode() && "Broken iterator!");
112 if (isRegionMode())
113 return Node.getInt() == x.Node.getInt();
114 else
115 return BItor == x.BItor;
116 }
117
118 inline bool operator!=(const Self& x) const { return !operator==(x); }
119
120 inline pointer operator*() const {
121 BasicBlock* BB = isRegionMode() ? getRegionSucc() : *BItor;
122 assert(!isExit(BB) && "Iterator out of range!");
123 return getISucc(BB);
124 }
125
126 inline Self& operator++() {
127 if(isRegionMode()) {
128 // The Region only has 1 successor.
129 advanceRegionSucc();
130 } else {
131 // Skip the exit.
132 do
133 ++BItor;
134 while (BItor != succ_end(getNode()->getEntry())
135 && isExit(*BItor));
136 }
137 return *this;
138 }
139
140 inline Self operator++(int) {
141 Self tmp = *this;
142 ++*this;
143 return tmp;
144 }
145
146 inline const Self &operator=(const Self &I) {
147 if (this != &I) {
148 assert(getNode()->getParent() == I.getNode()->getParent()
149 && "Cannot assign iterators of two different regions!");
150 Node = I.Node;
151 BItor = I.BItor;
152 }
153 return *this;
154 }
155 };
156
157
158 //===----------------------------------------------------------------------===//
159 /// @brief Flat RegionNode iterator.
160 ///
161 /// The Flat Region iterator will iterate over all BasicBlock RegionNodes that
162 /// are contained in the Region and its subregions. This is close to a virtual
163 /// control flow graph of the Region.
164 template
165 class RNSuccIterator >
166 : public std::iterator
167 {
168 typedef std::iterator super;
169 NodeType* Node;
170 succ_iterator Itor;
171
172 public:
173 typedef RNSuccIterator > Self;
174 typedef typename super::pointer pointer;
175
176 /// @brief Create the iterator from a RegionNode.
177 ///
178 /// Note that the incoming node must be a bb node, otherwise it will trigger
179 /// an assertion when we try to get a BasicBlock.
180 inline RNSuccIterator(NodeType* node) : Node(node),
181 Itor(succ_begin(node->getEntry())) {
182 assert(!Node->isSubRegion()
183 && "Subregion node not allowed in flat iterating mode!");
184 assert(Node->getParent() && "A BB node must have a parent!");
185
186 // Skip the exit block of the iterating region.
187 while (succ_end(Node->getEntry()) != Itor
188 && Node->getParent()->getExit() == *Itor)
189 ++Itor;
190 }
191 /// @brief Create an end iterator
192 inline RNSuccIterator(NodeType* node, bool) : Node(node),
193 Itor(succ_end(node->getEntry())) {
194 assert(!Node->isSubRegion()
195 && "Subregion node not allowed in flat iterating mode!");
196 }
197
198 inline bool operator==(const Self& x) const {
199 assert(Node->getParent() == x.Node->getParent()
200 && "Cannot compare iterators of different regions!");
201
202 return Itor == x.Itor && Node == x.Node;
203 }
204
205 inline bool operator!=(const Self& x) const { return !operator==(x); }
206
207 inline pointer operator*() const {
208 BasicBlock* BB = *Itor;
209
210 // Get the iterating region.
211 Region* Parent = Node->getParent();
212
213 // The only case that the successor reaches out of the region is it reaches
214 // the exit of the region.
215 assert(Parent->getExit() != BB && "iterator out of range!");
216
217 return Parent->getBBNode(BB);
218 }
219
220 inline Self& operator++() {
221 // Skip the exit block of the iterating region.
222 do
223 ++Itor;
224 while (Itor != succ_end(Node->getEntry())
225 && Node->getParent()->getExit() == *Itor);
226
227 return *this;
228 }
229
230 inline Self operator++(int) {
231 Self tmp = *this;
232 ++*this;
233 return tmp;
234 }
235
236 inline const Self &operator=(const Self &I) {
237 if (this != &I) {
238 assert(Node->getParent() == I.Node->getParent()
239 && "Cannot assign iterators to two different regions!");
240 Node = I.Node;
241 Itor = I.Itor;
242 }
243 return *this;
244 }
245 };
246
247 template
248 inline RNSuccIterator succ_begin(NodeType* Node) {
249 return RNSuccIterator(Node);
250 }
251
252 template
253 inline RNSuccIterator succ_end(NodeType* Node) {
254 return RNSuccIterator(Node, true);
255 }
256
257 //===--------------------------------------------------------------------===//
258 // RegionNode GraphTraits specialization so the bbs in the region can be
259 // iterate by generic graph iterators.
260 //
261 // NodeT can either be region node or const region node, otherwise child_begin
262 // and child_end fail.
263
264 #define RegionNodeGraphTraits(NodeT) \
265 template<> struct GraphTraits { \
266 typedef NodeT NodeType; \
267 typedef RNSuccIterator ChildIteratorType; \
268 static NodeType *getEntryNode(NodeType* N) { return N; } \
269 static inline ChildIteratorType child_begin(NodeType *N) { \
270 return RNSuccIterator(N); \
271 } \
272 static inline ChildIteratorType child_end(NodeType *N) { \
273 return RNSuccIterator(N, true); \
274 } \
275 }; \
276 template<> struct GraphTraits > { \
277 typedef NodeT NodeType; \
278 typedef RNSuccIterator > ChildIteratorType; \
279 static NodeType *getEntryNode(NodeType* N) { return N; } \
280 static inline ChildIteratorType child_begin(NodeType *N) { \
281 return RNSuccIterator >(N); \
282 } \
283 static inline ChildIteratorType child_end(NodeType *N) { \
284 return RNSuccIterator >(N, true); \
285 } \
286 }
287
288 #define RegionGraphTraits(RegionT, NodeT) \
289 template<> struct GraphTraits \
290 : public GraphTraits { \
291 typedef df_iterator nodes_iterator; \
292 static NodeType *getEntryNode(RegionT* R) { \
293 return R->getNode(R->getEntry()); \
294 } \
295 static nodes_iterator nodes_begin(RegionT* R) { \
296 return nodes_iterator::begin(getEntryNode(R)); \
297 } \
298 static nodes_iterator nodes_end(RegionT* R) { \
299 return nodes_iterator::end(getEntryNode(R)); \
300 } \
301 }; \
302 template<> struct GraphTraits > \
303 : public GraphTraits > { \
304 typedef df_iterator, false, \
305 GraphTraits > > nodes_iterator; \
306 static NodeType *getEntryNode(RegionT* R) { \
307 return R->getBBNode(R->getEntry()); \
308 } \
309 static nodes_iterator nodes_begin(RegionT* R) { \
310 return nodes_iterator::begin(getEntryNode(R)); \
311 } \
312 static nodes_iterator nodes_end(RegionT* R) { \
313 return nodes_iterator::end(getEntryNode(R)); \
314 } \
315 }
316
317 RegionNodeGraphTraits(RegionNode);
318 RegionNodeGraphTraits(const RegionNode);
319
320 RegionGraphTraits(Region, RegionNode);
321 RegionGraphTraits(const Region, const RegionNode);
322
323 template <> struct GraphTraits
324 : public GraphTraits > {
325 typedef df_iterator, false,
326 GraphTraits > > nodes_iterator;
327
328 static NodeType *getEntryNode(RegionInfo *RI) {
329 return GraphTraits >::getEntryNode(RI->getTopLevelRegion());
330 }
331 static nodes_iterator nodes_begin(RegionInfo* RI) {
332 return nodes_iterator::begin(getEntryNode(RI));
333 }
334 static nodes_iterator nodes_end(RegionInfo *RI) {
335 return nodes_iterator::end(getEntryNode(RI));
336 }
337 };
338
339 } // End namespace llvm
340
341 #endif
0 //===-- RegionPrinter.h - Region printer external interface -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines external functions that can be called to explicitly
10 // instantiate the region printer.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ANALYSIS_REGIONPRINTER_H
15 #define LLVM_ANALYSIS_REGIONPRINTER_H
16
17 namespace llvm {
18 class FunctionPass;
19 FunctionPass *createRegionViewerPass();
20 FunctionPass *createRegionOnlyViewerPass();
21 FunctionPass *createRegionPrinterPass();
22 FunctionPass *createRegionOnlyPrinterPass();
23 } // End llvm namespace
24
25 #endif
2121 #include "llvm/Analysis/Passes.h"
2222 #include "llvm/Analysis/PointerTracking.h"
2323 #include "llvm/Analysis/PostDominators.h"
24 #include "llvm/Analysis/RegionPrinter.h"
2425 #include "llvm/Analysis/ScalarEvolution.h"
2526 #include "llvm/Analysis/Lint.h"
2627 #include "llvm/Assembly/PrintModulePass.h"
105106 (void) llvm::createPostDomOnlyViewerPass();
106107 (void) llvm::createPostDomViewerPass();
107108 (void) llvm::createReassociatePass();
109 (void) llvm::createRegionInfoPass();
110 (void) llvm::createRegionOnlyPrinterPass();
111 (void) llvm::createRegionOnlyViewerPass();
112 (void) llvm::createRegionPrinterPass();
113 (void) llvm::createRegionViewerPass();
108114 (void) llvm::createSCCPPass();
109115 (void) llvm::createScalarReplAggregatesPass();
110116 (void) llvm::createSimplifyLibCallsPass();
270270 O << "[" << Attrs << "]";
271271 O << ";\n";
272272 }
273
274 /// getOStream - Get the raw output stream into the graph file. Useful to
275 /// write fancy things using addCustomGraphFeatures().
276 raw_ostream &getOStream() {
277 return O;
278 }
273279 };
274280
275281 template
3737 ProfileInfoLoader.cpp
3838 ProfileInfoLoaderPass.cpp
3939 ProfileVerifierPass.cpp
40 RegionInfo.cpp
41 RegionPrinter.cpp
4042 ScalarEvolution.cpp
4143 ScalarEvolutionAliasAnalysis.cpp
4244 ScalarEvolutionExpander.cpp
0 //===- RegionInfo.cpp - SESE region detection analysis --------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // Detects single entry single exit regions in the control flow graph.
9 //===----------------------------------------------------------------------===//
10
11 #include "llvm/Analysis/RegionInfo.h"
12 #include "llvm/Analysis/RegionIterator.h"
13
14 #include "llvm/ADT/PostOrderIterator.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/Support/CommandLine.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Support/raw_ostream.h"
19
20 #define DEBUG_TYPE "region"
21 #include "llvm/Support/Debug.h"
22
23 #include
24 #include
25
26 using namespace llvm;
27
28 // Always verify if expensive checking is enabled.
29 #ifdef XDEBUG
30 bool VerifyRegionInfo = true;
31 #else
32 bool VerifyRegionInfo = false;
33 #endif
34
35 static cl::opt
36 VerifyRegionInfoX("verify-region-info", cl::location(VerifyRegionInfo),
37 cl::desc("Verify region info (time consuming)"));
38
39 STATISTIC(numRegions, "The # of regions");
40 STATISTIC(numSimpleRegions, "The # of simple regions");
41
42 //===----------------------------------------------------------------------===//
43 /// PrintStyle - Print region in difference ways.
44 enum PrintStyle { PrintNone, PrintBB, PrintRN };
45
46 cl::opt printStyle("print-region-style", cl::Hidden,
47 cl::desc("style of printing regions"),
48 cl::values(
49 clEnumValN(PrintNone, "none", "print no details"),
50 clEnumValN(PrintBB, "bb", "print regions in detail with block_iterator"),
51 clEnumValN(PrintRN, "rn", "print regions in detail with element_iterator"),
52 clEnumValEnd));
53 //===----------------------------------------------------------------------===//
54 /// Region Implementation
55 Region::Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RInfo,
56 DominatorTree *dt, Region *Parent)
57 : RegionNode(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {}
58
59 Region::~Region() {
60 // Only clean the cache for this Region. Caches of child Regions will be
61 // cleaned when the child Regions are deleted.
62 BBNodeMap.clear();
63
64 for (iterator I = begin(), E = end(); I != E; ++I)
65 delete *I;
66 }
67
68 bool Region::contains(const BasicBlock *B) const {
69 BasicBlock *BB = const_cast(B);
70
71 assert(DT->getNode(BB) && "BB not part of the dominance tree");
72
73 BasicBlock *entry = getEntry(), *exit = getExit();
74
75 // Toplevel region.
76 if (!exit)
77 return true;
78
79 return (DT->dominates(entry, BB)
80 && !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
81 }
82
83 bool Region::isSimple() const {
84 bool isSimple = true;
85 bool found = false;
86
87 BasicBlock *entry = getEntry(), *exit = getExit();
88
89 // TopLevelRegion
90 if (!exit)
91 return false;
92
93 for (pred_iterator PI = pred_begin(entry), PE = pred_end(entry); PI != PE;
94 ++PI)
95 if (!contains(*PI)) {
96 if (found) {
97 isSimple = false;
98 break;
99 }
100 found = true;
101 }
102
103 found = false;
104
105 for (pred_iterator PI = pred_begin(exit), PE = pred_end(exit); PI != PE;
106 ++PI)
107 if (contains(*PI)) {
108 if (found) {
109 isSimple = false;
110 break;
111 }
112 found = true;
113 }
114
115 return isSimple;
116 }
117
118 void Region::verifyBBInRegion(BasicBlock *BB) const {
119 if (!contains(BB))
120 llvm_unreachable("Broken region found!");
121
122 BasicBlock *entry = getEntry(), *exit = getExit();
123
124 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
125 if (!contains(*SI) && exit != *SI)
126 llvm_unreachable("Broken region found!");
127
128 if (entry != BB)
129 for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB); SI != SE; ++SI)
130 if (!contains(*SI))
131 llvm_unreachable("Broken region found!");
132 }
133
134 void Region::verifyWalk(BasicBlock *BB, std::set *visited) const {
135 BasicBlock *exit = getExit();
136
137 visited->insert(BB);
138
139 verifyBBInRegion(BB);
140
141 for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
142 if (*SI != exit && visited->find(*SI) == visited->end())
143 verifyWalk(*SI, visited);
144 }
145
146 void Region::verifyRegion() const {
147 // Only do verification when user wants to, otherwise this expensive
148 // check will be invoked by PassManager.
149 if (!VerifyRegionInfo) return;
150
151 std::set visited;
152 verifyWalk(getEntry(), &visited);
153 }
154
155 void Region::verifyRegionNest() const {
156 for (Region::const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
157 (*RI)->verifyRegionNest();
158
159 verifyRegion();
160 }
161
162 Region::block_iterator Region::block_begin() {
163 return GraphTraits >::nodes_begin(this);
164 }
165
166 Region::block_iterator Region::block_end() {
167 return GraphTraits >::nodes_end(this);
168 }
169
170 Region::const_block_iterator Region::block_begin() const {
171 return GraphTraits >::nodes_begin(this);
172 }
173
174 Region::const_block_iterator Region::block_end() const {
175 return GraphTraits >::nodes_end(this);
176 }
177
178 Region::element_iterator Region::element_begin() {
179 return GraphTraits::nodes_begin(this);
180 }
181
182 Region::element_iterator Region::element_end() {
183 return GraphTraits::nodes_end(this);
184 }
185
186 Region::const_element_iterator Region::element_begin() const {
187 return GraphTraits::nodes_begin(this);
188 }
189
190 Region::const_element_iterator Region::element_end() const {
191 return GraphTraits::nodes_end(this);
192 }
193
194 Region* Region::getSubRegionNode(BasicBlock *BB) const {
195 Region *R = RI->getRegionFor(BB);
196
197 if (!R || R == this)
198 return 0;
199
200 // If we pass the BB out of this region, that means our code is broken.
201 assert(contains(R) && "BB not in current region!");
202
203 while (contains(R->getParent()) && R->getParent() != this)
204 R = R->getParent();
205
206 if (R->getEntry() != BB)
207 return 0;
208
209 return R;
210 }
211
212 RegionNode* Region::getBBNode(BasicBlock *BB) const {
213 assert(contains(BB) && "Can get BB node out of this region!");
214
215 BBNodeMapT::const_iterator at = BBNodeMap.find(BB);
216
217 if (at != BBNodeMap.end())
218 return at->second;
219
220 RegionNode *NewNode = new RegionNode(const_cast(this), BB);
221 BBNodeMap.insert(std::make_pair(BB, NewNode));
222 return NewNode;
223 }
224
225 RegionNode* Region::getNode(BasicBlock *BB) const {
226 assert(contains(BB) && "Can get BB node out of this region!");
227 if (Region* Child = getSubRegionNode(BB))
228 return Child->getNode();
229
230 return getBBNode(BB);
231 }
232
233 void Region::transferChildrenTo(Region *To) {
234 for (iterator I = begin(), E = end(); I != E; ++I) {
235 (*I)->parent = To;
236 To->children.push_back(*I);
237 }
238 children.clear();
239 }
240
241 void Region::addSubRegion(Region *SubRegion) {
242 assert(SubRegion->parent == 0 && "SubRegion already has a parent!");
243 SubRegion->parent = this;
244 // Set up the region node.
245 assert(std::find(children.begin(), children.end(), SubRegion) == children.end()
246 && "Node already exist!");
247 children.push_back(SubRegion);
248 }
249
250
251 Region *Region::removeSubRegion(Region *Child) {
252 assert(Child->parent == this && "Child is not a child of this region!");
253 Child->parent = 0;
254 RegionSet::iterator I = std::find(children.begin(), children.end(), Child);
255 assert(I != children.end() && "Region does not exit. Unable to remove.");
256 children.erase(children.begin()+(I-begin()));
257 return Child;
258 }
259
260 unsigned Region::getDepth() const {
261 unsigned Depth = 0;
262
263 for (Region *R = parent; R != 0; R = R->parent)
264 ++Depth;
265
266 return Depth;
267 }
268
269 void Region::print(raw_ostream &OS, bool print_tree, unsigned level) const {
270 if (print_tree)
271 OS.indent(level*2) << "[" << level << "] " << getNameStr();
272 else
273 OS.indent(level*2) << getNameStr();
274
275 OS << "\n";
276
277
278 if (printStyle != PrintNone) {
279 OS.indent(level*2) << "{\n";
280 OS.indent(level*2 + 2);
281
282 if (printStyle == PrintBB) {
283 for (const_block_iterator I = block_begin(), E = block_end(); I!=E; ++I)
284 OS << **I << ", "; // TODO: remove the last ","
285 } else if (printStyle == PrintRN) {
286 for (const_element_iterator I = element_begin(), E = element_end(); I!=E; ++I)
287 OS << **I << ", "; // TODO: remove the last ",
288 }
289
290 OS << "\n";
291 }
292
293 if (print_tree)
294 for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
295 (*RI)->print(OS, print_tree, level+1);
296
297 if (printStyle != PrintNone)
298 OS.indent(level*2) << "} \n";
299 }
300
301 void Region::dump() const {
302 print(dbgs(), true, getDepth());
303 }
304
305 void Region::clearNodeCache() {
306 BBNodeMap.clear();
307 for (Region::iterator RI = begin(), RE = end(); RI != RE; ++RI)
308 (*RI)->clearNodeCache();
309 }
310
311 //===----------------------------------------------------------------------===//
312 // RegionInfo implementation
313 //
314
315 bool RegionInfo::isCommonDomFrontier(BasicBlock *BB, BasicBlock *entry,
316 BasicBlock *exit) const {
317 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI)
318 if (DT->dominates(entry, *PI) && !DT->dominates(exit, *PI))
319 return false;
320
321 return true;
322 }
323
324 bool RegionInfo::isRegion(BasicBlock *entry, BasicBlock *exit) const {
325 assert(entry && exit && "entry and exit must not be null!");
326 typedef DominanceFrontier::DomSetType DST;
327
328 DST *entrySuccs = &(*DF->find(entry)).second;
329
330 // Exit is the header of a loop that contains the entry. In this case,
331 // the dominance frontier must only contain the exit.
332 if (!DT->dominates(entry, exit)) {
333 for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
334 SI != SE; ++SI)
335 if (*SI != exit && *SI != entry)
336 return false;
337
338 return true;
339 }
340
341 DST *exitSuccs = &(*DF->find(exit)).second;
342
343 // Do not allow edges leaving the region.
344 for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
345 SI != SE; ++SI) {
346 if (*SI == exit || *SI == entry)
347 continue;
348 if (exitSuccs->find(*SI) == exitSuccs->end())
349 return false;
350 if (!isCommonDomFrontier(*SI, entry, exit))
351 return false;
352 }
353
354 // Do not allow edges pointing into the region.
355 for (DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end();
356 SI != SE; ++SI)
357 if (DT->dominates(entry, *SI) && *SI != entry && *SI != exit)
358 return false;
359
360
361 return true;
362 }
363
364 void RegionInfo::insertShortCut(BasicBlock *entry, BasicBlock *exit,
365 BBtoBBMap *ShortCut) const {
366 assert(entry && exit && "entry and exit must not be null!");
367
368 BBtoBBMap::iterator e = ShortCut->find(exit);
369
370 if (e == ShortCut->end())
371 // No further region at exit available.
372 (*ShortCut)[entry] = exit;
373 else {
374 // We found a region e that starts at exit. Therefore (entry, e->second)
375 // is also a region, that is larger than (entry, exit). Insert the
376 // larger one.
377 BasicBlock *BB = e->second;
378 (*ShortCut)[entry] = BB;
379 }
380 }
381
382 DomTreeNode* RegionInfo::getNextPostDom(DomTreeNode* N,
383 BBtoBBMap *ShortCut) const {
384 BBtoBBMap::iterator e = ShortCut->find(N->getBlock());
385
386 if (e == ShortCut->end())
387 return N->getIDom();
388
389 return PDT->getNode(e->second)->getIDom();
390 }
391
392 bool RegionInfo::isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const {
393 assert(entry && exit && "entry and exit must not be null!");
394
395 unsigned num_successors = succ_end(entry) - succ_begin(entry);
396
397 if (num_successors <= 1 && exit == *(succ_begin(entry)))
398 return true;
399
400 return false;
401 }
402
403 void RegionInfo::updateStatistics(Region *R) {
404 ++numRegions;
405
406 // TODO: Slow. Should only be enabled if -stats is used.
407 if (R->isSimple()) ++numSimpleRegions;
408 }
409
410 Region *RegionInfo::createRegion(BasicBlock *entry, BasicBlock *exit) {
411 assert(entry && exit && "entry and exit must not be null!");
412
413 if (isTrivialRegion(entry, exit))
414 return 0;
415
416 Region *region = new Region(entry, exit, this, DT);
417 BBtoRegion.insert(std::make_pair(entry, region));
418
419 #ifdef XDEBUG
420 region->verifyRegion();
421 #else
422 DEBUG(region->verifyRegion());
423 #endif
424
425 updateStatistics(region);
426 return region;
427 }
428
429 void RegionInfo::findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut) {
430 assert(entry);
431
432 DomTreeNode *N = PDT->getNode(entry);
433
434 if (!N)
435 return;
436
437 Region *lastRegion= 0;
438 BasicBlock *lastExit = entry;
439
440 // As only a BasicBlock that postdominates entry can finish a region, walk the
441 // post dominance tree upwards.
442 while ((N = getNextPostDom(N, ShortCut))) {
443 BasicBlock *exit = N->getBlock();
444
445 if (!exit)
446 break;
447
448 if (isRegion(entry, exit)) {
449 Region *newRegion = createRegion(entry, exit);
450
451 if (lastRegion)
452 newRegion->addSubRegion(lastRegion);
453
454 lastRegion = newRegion;
455 lastExit = exit;
456 }
457
458 // This can never be a region, so stop the search.
459 if (!DT->dominates(entry, exit))
460 break;
461 }
462
463 // Tried to create regions from entry to lastExit. Next time take a
464 // shortcut from entry to lastExit.
465 if (lastExit != entry)
466 insertShortCut(entry, lastExit, ShortCut);
467 }
468
469 void RegionInfo::scanForRegions(Function &F, BBtoBBMap *ShortCut) {
470 BasicBlock *entry = &(F.getEntryBlock());
471 DomTreeNode *N = DT->getNode(entry);
472
473 // Iterate over the dominance tree in post order to start with the small
474 // regions from the bottom of the dominance tree. If the small regions are
475 // detected first, detection of bigger regions is faster, as we can jump
476 // over the small regions.
477 for (po_iterator FI = po_begin(N), FE = po_end(N); FI != FE;
478 ++FI) {
479 findRegionsWithEntry((*FI)->getBlock(), ShortCut);
480 }
481 }
482
483 Region *RegionInfo::getTopMostParent(Region *region) {
484 while (region->parent)
485 region = region->getParent();
486
487 return region;
488 }
489
490 void RegionInfo::buildRegionsTree(DomTreeNode *N, Region *region) {
491 BasicBlock *BB = N->getBlock();
492
493 // Passed region exit
494 while (BB == region->getExit())
495 region = region->getParent();
496
497 BBtoRegionMap::iterator it = BBtoRegion.find(BB);
498
499 // This basic block is a start block of a region. It is already in the
500 // BBtoRegion relation. Only the child basic blocks have to be updated.
501 if (it != BBtoRegion.end()) {
502 Region *newRegion = it->second;;
503 region->addSubRegion(getTopMostParent(newRegion));
504 region = newRegion;
505 } else {
506 BBtoRegion[BB] = region;
507 }
508
509 for (DomTreeNode::iterator CI = N->begin(), CE = N->end(); CI != CE; ++CI)
510 buildRegionsTree(*CI, region);
511 }
512
513 void RegionInfo::releaseMemory() {
514 BBtoRegion.clear();
515 if (TopLevelRegion)
516 delete TopLevelRegion;
517 TopLevelRegion = 0;
518 }
519
520 RegionInfo::RegionInfo() : FunctionPass(&ID) {
521 TopLevelRegion = 0;
522 }
523
524 RegionInfo::~RegionInfo() {
525 releaseMemory();
526 }
527
528 void RegionInfo::Calculate(Function &F) {
529 // ShortCut a function where for every BB the exit of the largest region
530 // starting with BB is stored. These regions can be threated as single BBS.
531 // This improves performance on linear CFGs.
532 BBtoBBMap ShortCut;
533
534 scanForRegions(F, &ShortCut);
535 BasicBlock *BB = &F.getEntryBlock();
536 buildRegionsTree(DT->getNode(BB), TopLevelRegion);
537 }
538
539 bool RegionInfo::runOnFunction(Function &F) {
540 releaseMemory();
541
542 DT = &getAnalysis();
543 PDT = &getAnalysis();
544 DF = &getAnalysis();
545
546 TopLevelRegion = new Region(&F.getEntryBlock(), 0, this, DT, 0);
547 updateStatistics(TopLevelRegion);
548
549 Calculate(F);
550
551 return false;
552 }
553
554 void RegionInfo::getAnalysisUsage(AnalysisUsage &AU) const {
555 AU.setPreservesAll();
556 AU.addRequiredTransitive();
557 AU.addRequired();
558 AU.addRequired();
559 }
560
561 void RegionInfo::print(raw_ostream &OS, const Module *) const {
562 OS << "Region tree:\n";
563 TopLevelRegion->print(OS, true, 0);
564 OS << "End region tree\n";
565 }
566
567 void RegionInfo::verifyAnalysis() const {
568 // Only do verification when user wants to, otherwise this expensive check
569 // will be invoked by PMDataManager::verifyPreservedAnalysis when
570 // a regionpass (marked PreservedAll) finish.
571 if (!VerifyRegionInfo) return;
572
573 TopLevelRegion->verifyRegionNest();
574 }
575
576 // Region pass manager support.
577 Region *RegionInfo::getRegionFor(BasicBlock *BB) const {
578 BBtoRegionMap::const_iterator I=
579 BBtoRegion.find(BB);
580 return I != BBtoRegion.end() ? I->second : 0;
581 }
582
583 Region *RegionInfo::operator[](BasicBlock *BB) const {
584 return getRegionFor(BB);
585 }
586
587 Region*
588 RegionInfo::getCommonRegion(Region *A, Region *B) const {
589 assert (A && B && "One of the Regions is NULL");
590
591 if (A->contains(B)) return A;
592
593 while (!B->contains(A))
594 B = B->getParent();
595
596 return B;
597 }
598
599 Region*
600 RegionInfo::getCommonRegion(SmallVectorImpl &Regions) const {
601 Region* ret = Regions.back();
602 Regions.pop_back();
603
604 for (SmallVectorImpl::const_iterator I = Regions.begin(),
605 E = Regions.end(); I != E; ++I)
606 ret = getCommonRegion(ret, *I);
607
608 return ret;
609 }
610
611 Region*
612 RegionInfo::getCommonRegion(SmallVectorImpl &BBs) const {
613 Region* ret = getRegionFor(BBs.back());
614 BBs.pop_back();
615
616 for (SmallVectorImpl::const_iterator I = BBs.begin(),
617 E = BBs.end(); I != E; ++I)
618 ret = getCommonRegion(ret, getRegionFor(*I));
619
620 return ret;
621 }
622
623 char RegionInfo::ID = 0;
624 INITIALIZE_PASS(RegionInfo, "regions",
625 "Detect single entry single exit regions", true, true);
626
627 // Create methods available outside of this file, to use them
628 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
629 // the link time optimization.
630
631 namespace llvm {
632 FunctionPass *createRegionInfoPass() {
633 return new RegionInfo();
634 }
635 }
636
0 //===- RegionPrinter.cpp - Print regions tree pass ------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // Print out the region tree of a function using dotty/graphviz.
9 //===----------------------------------------------------------------------===//
10
11 #include "llvm/Analysis/RegionInfo.h"
12 #include "llvm/Analysis/RegionIterator.h"
13 #include "llvm/Analysis/RegionPrinter.h"
14 #include "llvm/Analysis/Passes.h"
15 #include "llvm/Analysis/DOTGraphTraitsPass.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/ADT/PostOrderIterator.h"
18 #include "llvm/ADT/DepthFirstIterator.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/CommandLine.h"
21 #include "llvm/Support/raw_ostream.h"
22
23 using namespace llvm;
24
25 //===----------------------------------------------------------------------===//
26 /// onlySimpleRegion - Show only the simple regions in the RegionViewer.
27 static cl::opt
28 onlySimpleRegions("only-simple-regions",
29 cl::desc("Show only simple regions in the graphviz viewer"),
30 cl::Hidden,
31 cl::init(false));
32
33 namespace llvm {
34 template<>
35 struct DOTGraphTraits : public DefaultDOTGraphTraits {
36
37 DOTGraphTraits (bool isSimple=false)
38 : DefaultDOTGraphTraits(isSimple) {}
39
40 std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
41
42 if (!Node->isSubRegion()) {
43 BasicBlock *BB = Node->getNodeAs();
44
45 if (isSimple())
46 return DOTGraphTraits
47 ::getSimpleNodeLabel(BB, BB->getParent());
48 else
49 return DOTGraphTraits
50 ::getCompleteNodeLabel(BB, BB->getParent());
51 }
52
53 return "Not implemented";
54 }
55 };
56
57 template<>
58 struct DOTGraphTraits : public DOTGraphTraits {
59
60 DOTGraphTraits (bool isSimple=false)
61 : DOTGraphTraits(isSimple) {}
62
63 static std::string getGraphName(RegionInfo *DT) {
64 return "Region Graph";
65 }
66
67 std::string getNodeLabel(RegionNode *Node, RegionInfo *G) {
68 return DOTGraphTraits::getNodeLabel(Node,
69 G->getTopLevelRegion());
70 }
71
72 // Print the cluster of the subregions. This groups the single basic blocks
73 // and adds a different background color for each group.
74 static void printRegionCluster(const Region *R, GraphWriter &GW,
75 unsigned depth = 0) {
76 raw_ostream &O = GW.getOStream();
77 O.indent(2 * depth) << "subgraph cluster_" << static_cast(R)
78 << " {\n";
79 O.indent(2 * (depth + 1)) << "label = \"\";\n";
80
81 if (!onlySimpleRegions || R->isSimple()) {
82 O.indent(2 * (depth + 1)) << "style = filled;\n";
83 O.indent(2 * (depth + 1)) << "color = "
84 << ((R->getDepth() * 2 % 12) + 1) << "\n";
85
86 } else {
87 O.indent(2 * (depth + 1)) << "style = solid;\n";
88 O.indent(2 * (depth + 1)) << "color = "
89 << ((R->getDepth() * 2 % 12) + 2) << "\n";
90 }
91
92 for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
93 printRegionCluster(*RI, GW, depth + 1);
94
95 RegionInfo *RI = R->getRegionInfo();
96
97 for (Region::const_block_iterator BI = R->block_begin(),
98 BE = R->block_end(); BI != BE; ++BI) {
99 BasicBlock *BB = (*BI)->getNodeAs();
100 if (RI->getRegionFor(BB) == R)
101 O.indent(2 * (depth + 1)) << "Node"
102 << static_cast(RI->getTopLevelRegion()->getBBNode(BB))
103 << ";\n";
104 }
105
106 O.indent(2 * depth) << "}\n";
107 }
108
109 static void addCustomGraphFeatures(const RegionInfo* RI,
110 GraphWriter &GW) {
111 raw_ostream &O = GW.getOStream();
112 O << "\tcolorscheme = \"paired12\"\n";
113 printRegionCluster(RI->getTopLevelRegion(), GW, 4);
114 }
115 };
116 } //end namespace llvm
117
118 namespace {
119
120 struct RegionViewer
121 : public DOTGraphTraitsViewer {
122 static char ID;
123 RegionViewer() : DOTGraphTraitsViewer("reg", &ID){}
124 };
125
126 char RegionViewer::ID = 0;
127 INITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function",
128 true, true);
129
130 struct RegionOnlyViewer
131 : public DOTGraphTraitsViewer {
132 static char ID;
133 RegionOnlyViewer() : DOTGraphTraitsViewer("regonly", &ID){}
134 };
135
136 char RegionOnlyViewer::ID = 0;
137 INITIALIZE_PASS(RegionOnlyViewer, "view-regions-only",
138 "View regions of function (with no function bodies)",
139 true, true);
140
141 struct RegionPrinter
142 : public DOTGraphTraitsPrinter {
143 static char ID;
144 RegionPrinter() :
145 DOTGraphTraitsPrinter("reg", &ID) {}
146 };
147 } //end anonymous namespace
148
149 char RegionPrinter::ID = 0;
150 INITIALIZE_PASS(RegionPrinter, "dot-regions",
151 "Print regions of function to 'dot' file", true, true);
152
153 struct RegionOnlyPrinter
154 : public DOTGraphTraitsPrinter {
155 static char ID;
156 RegionOnlyPrinter() :
157 DOTGraphTraitsPrinter("reg", &ID) {}
158 };
159
160 char RegionOnlyPrinter::ID = 0;
161 INITIALIZE_PASS(RegionOnlyPrinter, "dot-regions-only",
162 "Print regions of function to 'dot' file "
163 "(with no function bodies)",
164 true, true);
165
166 FunctionPass* llvm::createRegionViewerPass() {
167 return new RegionViewer();
168 }
169
170 FunctionPass* llvm::createRegionOnlyViewerPass() {
171 return new RegionOnlyViewer();
172 }
173
174 FunctionPass* llvm::createRegionPrinterPass() {
175 return new RegionPrinter();
176 }
177
178 FunctionPass* llvm::createRegionOnlyPrinterPass() {
179 return new RegionOnlyPrinter();
180 }
181
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats -analyze < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @BZ2_blockSort() nounwind {
6 start:
7 br label %while
8
9 while:
10 br label %while.body134.i.i
11
12 while.body134.i.i:
13 br i1 1, label %end, label %w
14
15 w:
16 br label %if.end140.i.i
17
18 if.end140.i.i:
19 br i1 1, label %while.end186.i.i, label %if.end183.i.i
20
21 if.end183.i.i:
22 br label %while.body134.i.i
23
24 while.end186.i.i:
25 br label %while
26
27 end:
28 ret void
29 }
30 ; CHECK-NOT: =>
31 ; CHECK: [0] start =>
32 ; CHECK: [1] while => end
33
34 ; STAT: 2 region - The # of regions
35 ; STAT: 1 region - The # of simple regions
36
37 ; BBIT: start, while, while.body134.i.i, end, w, if.end140.i.i, while.end186.i.i, if.end183.i.i,
38 ; BBIT: while, while.body134.i.i, w, if.end140.i.i, while.end186.i.i, if.end183.i.i,
39
40 ; RNIT: start, while => end, end,
41 ; RNIT: while, while.body134.i.i, w, if.end140.i.i, while.end186.i.i, if.end183.i.i,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @normal_condition() nounwind {
6 5:
7 br label %"0"
8
9 0:
10 br label %"1"
11 1:
12 br i1 1, label %"2", label %"3"
13 2:
14 ret void
15 3:
16 br i1 1, label %"1", label %"4"
17 4:
18 br label %"0"
19 }
20
21 ; CHECK-NOT: =>
22 ; CHECK: [0] 5 =>
23 ; CHECK: [1] 0 => 2
24
25 ; STAT: 2 region - The # of regions
26 ; STAT: 1 region - The # of simple regions
27
28 ; BBIT: 5, 0, 1, 2, 3, 4,
29 ; BBIT: 0, 1, 3, 4,
30
31 ; RNIT: 5, 0 => 2, 2,
32 ; RNIT: 0, 1, 3, 4,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define internal fastcc zeroext i8 @handle_compress() nounwind {
6 end165:
7 br i1 1, label %false239, label %true181
8
9 true181:
10 br i1 1, label %then187, label %else232
11
12 then187:
13 br label %end265
14
15 else232:
16 br i1 1, label %false239, label %then245
17
18 false239:
19 br i1 1, label %then245, label %else259
20
21 then245:
22 br i1 1, label %then251, label %end253
23
24 then251:
25 br label %end253
26
27 end253:
28 br label %end265
29
30 else259:
31 br label %end265
32
33 end265:
34 br i1 1, label %then291, label %end298
35
36 then291:
37 br label %end298
38
39 end298:
40 ret i8 1
41 }
42
43 ; CHECK-NOT: =>
44 ; CHECK: [0] end165 =>
45 ; CHECK-NEXT: [1] end165 => end265
46 ; CHECK-NEXT: [2] then245 => end253
47 ; CHECK-NEXT: [1] end265 => end298
48
49 ; STAT: 4 region - The # of regions
50
51 ; BBIT: end165, false239, then245, then251, end253, end265, then291, end298, else259, true181, then187, else232,
52 ; BBIT: end165, false239, then245, then251, end253, else259, true181, then187, else232,
53 ; BBIT: then245, then251,
54 ; BBIT: end265, then291,
55
56 ; RNIT: end165 => end265, end265 => end298, end298,
57 ; RNIT: end165, false239, then245 => end253, end253, else259, true181, then187, else232,
58 ; RNIT: then245, then251,
59 ; RNIT: end265, then291,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define internal fastcc void @compress() nounwind {
6 end33:
7 br i1 1, label %end124, label %lor.lhs.false95
8
9 lor.lhs.false95:
10 br i1 1, label %then107, label %end172
11
12 then107:
13 br i1 1, label %end124, label %then113
14
15 then113:
16 br label %end124
17
18 end124:
19 br label %exit
20
21 end172:
22 br label %exit
23
24
25 exit:
26 unreachable
27
28
29 }
30 ; CHECK-NOT: =>
31 ; CHECK: [0] end33 =>
32 ; CHECK-NEXT: [1] end33 => exit
33 ; CHECK-NEXT: [2] then107 => end124
34
35 ; STAT: 3 region - The # of regions
36
37 ; BBIT: end33, end124, exit, lor.lhs.false95, then107, then113, end172,
38 ; BBIT: end33, end124, lor.lhs.false95, then107, then113, end172,
39 ; BBIT: then107, then113,
40
41 ; RNIT: end33 => exit, exit,
42 ; RNIT: end33, end124, lor.lhs.false95, then107 => end124, end172,
43 ; RNIT: then107, then113,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @normal_condition() nounwind {
6 0:
7 br label %"1"
8 1:
9 br i1 1, label %"2", label %"3"
10 2:
11 br label %"3"
12 3:
13 ret void
14 }
15 ; CHECK-NOT: =>
16 ; CHECK: [0] 0 =>
17 ; CHECK: [1] 1 => 3
18
19 ; STAT: 2 region - The # of regions
20
21 ; BBIT: 0, 1, 2, 3,
22 ; BBIT: 1, 2,
23
24 ; RNIT: 0, 1 => 3, 3,
25 ; RNIT: 1, 2,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @normal_condition() nounwind {
6 0:
7 br i1 1, label %"1", label %"4"
8
9 1:
10 br i1 1, label %"2", label %"3"
11 2:
12 br label %"4"
13 3:
14 br label %"4"
15 4:
16 ret void
17 }
18 ; CHECK-NOT: =>
19 ; CHECK: [0] 0 =>
20 ; CHECK-NEXT: [1] 0 => 4
21 ; CHECK-NEXT: [2] 1 => 4
22 ; STAT: 3 region - The # of regions
23
24 ; BBIT: 0, 1, 2, 4, 3,
25 ; BBIT: 0, 1, 2, 3,
26 ; BBIT: 1, 2, 3,
27
28 ; RNIT: 0 => 4, 4,
29 ; RNIT: 0, 1 => 4,
30 ; RNIT: 1, 2, 3,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @normal_condition() nounwind {
6 0:
7 br label %"1"
8 1:
9 br i1 1, label %"2", label %"3"
10 2:
11 br label %"4"
12 3:
13 br label %"4"
14 4:
15 ret void
16 }
17
18 ; CHECK-NOT: =>
19 ; CHECK: [0] 0 =>
20 ; CHECK-NEXT: [1] 1 => 4
21 ; STAT: 2 region - The # of regions
22
23 ; BBIT: 0, 1, 2, 4, 3,
24 ; BBIT: 1, 2, 3,
25
26 ; RNIT: 0, 1 => 4, 4,
27 ; RNIT: 1, 2, 3,
0 load_lib llvm.exp
1
2 RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define internal fastcc zeroext i8 @handle_compress() nounwind {
6 entry:
7 br label %outer
8
9 outer:
10 br label %body
11
12 body:
13 br i1 1, label %body.i, label %if.end
14
15 body.i:
16 br i1 1, label %end, label %if.end
17
18 if.end:
19 br label %if.then64
20
21 if.then64:
22 br label %outer
23
24 end:
25 ret i8 1
26 }
27 ; CHECK-NOT: =>
28 ; CHECK: [0] entry =>
29 ; CHECK-NEXT: [1] outer => end
30 ; STAT: 2 region - The # of regions
31 ; STAT: 1 region - The # of simple regions
32
33 ; BBIT: entry, outer, body, body.i, end, if.end, if.then64,
34 ; BBIT: outer, body, body.i, if.end, if.then64,
35
36 ; RNIT: entry, outer => end, end,
37 ; RNIT: outer, body, body.i, if.end, if.then64,
0 ; RUN: opt -regions -analyze < %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2
3 define void @normal_condition() nounwind {
4 0:
5 br label %"1"
6 1:
7 br i1 1, label %"2", label %"3"
8 2:
9 br label %"2"
10 3:
11 br label %"4"
12 4:
13 ret void
14 }
15 ; CHECK-NOT: =>
16 ; CHECK: [0] 0 =>
17 ; CHECK: [1] 1 => 4
18 ; STAT: 2 region - The # of regions
19 ; STAT: 1 region - The # of simple regions
0 ; RUN: opt -regions -analyze < %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @normal_condition() nounwind {
6 0:
7 br label %"1"
8 1:
9 br i1 1, label %"2", label %"3"
10 2:
11 br label %"5"
12 5:
13 br i1 1, label %"11", label %"12"
14 11:
15 br label %"6"
16 12:
17 br label %"6"
18 6:
19 br label %"2"
20 3:
21 br label %"4"
22 4:
23 ret void
24 }
25 ; CHECK-NOT: =>
26 ; CHECK: [0] 0 =>
27 ; CHECK: [1] 1 => 3
28 ; STAT: 2 region - The # of regions
29 ; STAT: 1 region - The # of simple regions
30
31 ; BBIT: 0, 1, 2, 5, 11, 6, 12, 3, 4,
32 ; BBIT: 1, 2, 5, 11, 6, 12,
33
34 ; RNIT: 0, 1 => 3, 3, 4,
35 ; RNIT: 1, 2, 5, 11, 6, 12,
0 ; RUN: opt -regions -analyze < %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2
3 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
4 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
5
6 define void @normal_condition() nounwind {
7 0:
8 br label %"7"
9 7:
10 br i1 1, label %"1", label %"8"
11 1:
12 br i1 1, label %"2", label %"3"
13 2:
14 br label %"5"
15 5:
16 br i1 1, label %"11", label %"12"
17 11:
18 br label %"6"
19 12:
20 br label %"6"
21 6:
22 br label %"2"
23 8:
24 br label %"9"
25 9:
26 br i1 1, label %"13", label %"14"
27 13:
28 br label %"10"
29 14:
30 br label %"10"
31 10:
32 br label %"8"
33 3:
34 br label %"4"
35 4:
36 ret void
37 }
38 ; CHECK-NOT: =>
39 ; CHECK: [0] 0 =>
40 ; CHECK-NEXT: [1] 1 => 3
41 ; CHECK-NEXT: [1] 7 => 1
42 ; STAT: 3 region - The # of regions
43 ; STAT: 2 region - The # of simple regions
44
45 ; BBIT: 0, 7, 1, 2, 5, 11, 6, 12, 3, 4, 8, 9, 13, 10, 14,
46 ; BBIT: 7, 8, 9, 13, 10, 14,
47 ; BBIT: 1, 2, 5, 11, 6, 12,
48
49 ; RNIT: 0, 7 => 1, 1 => 3, 3, 4,
50 ; RNIT: 7, 8, 9, 13, 10, 14,
51 ; RNIT: 1, 2, 5, 11, 6, 12,
0 ; RUN: opt -regions -analyze < %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @normal_condition() nounwind {
6 0:
7 br label %"7"
8 7:
9 br i1 1, label %"1", label %"8"
10 1:
11 br i1 1, label %"2", label %"3"
12 2:
13 br label %"5"
14 5:
15 br i1 1, label %"11", label %"12"
16 11:
17 br label %"6"
18 12:
19 br label %"6"
20 6:
21 br i1 1, label %"2", label %"10"
22 8:
23 br label %"9"
24 9:
25 br i1 1, label %"13", label %"14"
26 13:
27 br label %"10"
28 14:
29 br label %"10"
30 10:
31 br label %"8"
32 3:
33 br label %"4"
34 4:
35 ret void
36 }
37 ; CHECK-NOT: =>
38 ; CHECK: [0] 0 =>
39 ; CHECK-NEXT: [1] 7 => 3
40 ; STAT: 2 region - The # of regions
41 ; STAT: 1 region - The # of simple regions
42
43 ; BBIT: 0, 7, 1, 2, 5, 11, 6, 10, 8, 9, 13, 14, 12, 3, 4,
44 ; BBIT: 7, 1, 2, 5, 11, 6, 10, 8, 9, 13, 14, 12,
45
46 ; RNIT: 0, 7 => 3, 3, 4,
47 ; RNIT: 7, 1, 2, 5, 11, 6, 10, 8, 9, 13, 14, 12,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2
3 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
4 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
5
6 define void @normal_condition() nounwind {
7 0:
8 br label %"1"
9 1:
10 br i1 1, label %"6", label %"2"
11 2:
12 br i1 1, label %"3", label %"4"
13 3:
14 br label %"5"
15 4:
16 br label %"5"
17 5:
18 br label %"8"
19 8:
20 br i1 1, label %"7", label %"9"
21 9:
22 br label %"2"
23 7:
24 br label %"6"
25 6:
26 ret void
27 }
28
29 ; CHECK-NOT: =>
30 ; CHECK: [0] 0 =>
31 ; CHECK-NEXT: [1] 1 => 6
32 ; CHECK-NEXT: [2] 2 => 7
33 ; CHECK-NEXT: [3] 2 => 5
34 ; STAT: 4 region - The # of regions
35 ; STAT: 1 region - The # of simple regions
36
37 ; BBIT: 0, 1, 6, 2, 3, 5, 8, 7, 9, 4,
38 ; BBIT: 1, 2, 3, 5, 8, 7, 9, 4,
39 ; BBIT: 2, 3, 5, 8, 9, 4,
40 ; BBIT: 2, 3, 4,
41
42 ; RNIT: 0, 1 => 6, 6,
43 ; RNIT: 1, 2 => 7, 7,
44 ; RNIT: 2 => 5, 5, 8, 9,
45 ; RNIT: 2, 3, 4,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define internal fastcc zeroext i8 @loops_1() nounwind {
6 entry:
7 br i1 1, label %outer , label %a
8
9 a:
10 br label %body
11
12 outer:
13 br label %body
14
15 body:
16 br i1 1, label %land, label %if
17
18 land:
19 br i1 1, label %exit, label %end
20
21 exit:
22 br i1 1, label %if, label %end
23
24 if:
25 br label %outer
26
27 end:
28 ret i8 1
29 }
30 ; CHECK-NOT: =>
31 ; CHECK: [0] entry =>
32 ; CHECK-NEXT: [1] entry => end
33 ; STAT: 2 region - The # of regions
34
35 ; BBIT: entry, outer, body, land, exit, if, end, a,
36 ; BBIT: entry, outer, body, land, exit, if, a,
37
38 ; RNIT: entry => end, end,
39 ; RNIT: entry, outer, body, land, exit, if, a,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @meread_() nounwind {
6 entry:
7 br label %bb23
8
9 bb23:
10 br label %bb.i
11
12 bb.i: ; preds = %bb.i, %bb54
13 br label %pflini_.exit
14
15 pflini_.exit: ; preds = %bb.i
16 br label %bb58thread-split
17
18 bb58thread-split: ; preds = %bb64, %bb61, %pflini_.exit
19 br label %bb58
20
21 bb58: ; preds = %bb60, %bb58thread-split
22 br i1 1, label %bb59, label %bb23
23
24 bb59: ; preds = %bb58
25 switch i32 1, label %bb60 [
26 i32 1, label %l98
27 ]
28
29 bb60: ; preds = %bb59
30 br i1 1, label %bb61, label %bb58
31
32 bb61: ; preds = %bb60
33 br label %bb58thread-split
34
35 l98: ; preds = %bb69, %bb59
36 ret void
37 }
38 ; CHECK-NOT: =>
39 ; CHECK: [0] entry =>
40 ; CHECK: [1] bb23 => l98
41 ; STAT: 2 region - The # of regions
42 ; STAT: 1 region - The # of simple regions
43
44 ; BBIT: entry, bb23, bb.i, pflini_.exit, bb58thread-split, bb58, bb59, bb60, bb61, l98,
45 ; BBIT: bb23, bb.i, pflini_.exit, bb58thread-split, bb58, bb59, bb60, bb61,
46
47 ; RNIT: entry, bb23 => l98, l98,
48 ; RNIT: bb23, bb.i, pflini_.exit, bb58thread-split, bb58, bb59, bb60, bb61,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2
3 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
4 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
5
6 define void @a_linear_impl_fig_1() nounwind {
7 0:
8
9 br i1 1, label %"1", label %"15"
10 1:
11 switch i32 0, label %"2" [ i32 0, label %"3"
12 i32 1, label %"7"]
13 2:
14 br label %"4"
15 3:
16 br label %"5"
17 4:
18 br label %"6"
19 5:
20 br label %"6"
21 6:
22 br label %"7"
23 7:
24 br label %"15"
25 15:
26 br label %"8"
27 8:
28 br label %"16"
29 16:
30 br label %"9"
31 9:
32 br i1 1, label %"10", label %"11"
33 11:
34 br i1 1, label %"13", label %"12"
35 13:
36 br label %"14"
37 12:
38 br label %"14"
39 14:
40 br label %"8"
41 10:
42 br label %"17"
43 17:
44 br label %"18"
45 18:
46 ret void
47 }
48
49 ; CHECK-NOT: =>
50 ; CHECK: [0] 0 =>
51 ; CHECK-NEXT: [1] 0 => 15
52 ; CHECK-NEXT: [2] 1 => 7
53 ; CHECK-NEXT: [1] 8 => 10
54 ; CHECK-NEXT: [2] 11 => 14
55 ; STAT: 5 region - The # of regions
56 ; STAT: 1 region - The # of simple regions
57
58 ; BBIT: 0, 1, 2, 4, 6, 7, 15, 8, 16, 9, 10, 17, 18, 11, 13, 14, 12, 3, 5,
59 ; BBIT: 0, 1, 2, 4, 6, 7, 3, 5,
60 ; BBIT: 1, 2, 4, 6, 3, 5,
61 ; BBIT: 8, 16, 9, 11, 13, 14, 12,
62 ; BBIT: 11, 13, 12,
63
64 ; RNIT: 0 => 15, 15, 8 => 10, 10, 17, 18,
65 ; RNIT: 0, 1 => 7, 7,
66 ; RNIT: 1, 2, 4, 6, 3, 5,
67 ; RNIT: 8, 16, 9, 11 => 14, 14,
68 ; RNIT: 11, 13, 12,
0 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
1 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
2
3 define void @normal_condition_0() nounwind {
4 bb38: ; preds = %bb34, %bb34, %bb37
5 switch i32 undef, label %bb42 [
6 i32 67, label %bb42
7 i32 90, label %bb41
8 ]
9 bb41: ; preds = %bb38
10 br label %bb42
11 bb42: ; preds = %bb38, %bb38, %bb41
12 ret void
13 }
14
15 ; BBIT: bb38, bb42, bb41,
16 ; BBIT: bb38, bb41,
17
18 ; RNIT: bb38 => bb42, bb42,
19 ; RNIT: bb38, bb41,
20
21 define void @normal_condition_1() nounwind {
22 bb38: ; preds = %bb34, %bb34, %bb37
23 switch i32 undef, label %bb41 [
24 i32 67, label %bb42
25 i32 90, label %bb42
26 ]
27 bb41: ; preds = %bb38
28 br label %bb42
29 bb42: ; preds = %bb38, %bb38, %bb41
30 ret void
31 }
32
33 ; BBIT: bb38, bb41, bb42,
34 ; BBIT: bb38, bb41,
35
36 ; RNIT: bb38 => bb42, bb42,
37 ; RNIT: bb38, bb41,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2
3 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
4 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
5
6 define internal fastcc zeroext i8 @handle_compress() nounwind {
7 entry:
8 br label %outer
9
10 outer:
11 br label %body
12
13 body:
14 br i1 1, label %exit172, label %end
15
16 exit172:
17 br i1 1, label %end, label %outer
18
19 end:
20 ret i8 1
21 }
22 ; CHECK-NOT: =>
23 ; CHECK: [0] entry =>
24 ; CHECK-NEXT: [1] outer => end
25
26 ; STAT: 2 region - The # of regions
27
28 ; BBIT: entry, outer, body, exit172, end,
29 ; BBIT: outer, body, exit172,
30
31 ; RNIT: entry, outer => end, end,
32 ; RNIT: outer, body, exit172,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @MAIN__() nounwind {
6 entry:
7 br label %__label_002001.outer
8
9 __label_002001.outer: ; preds = %bb236, %bb92
10 br label %__label_002001
11
12 __label_002001: ; preds = %bb229, %__label_002001.outer
13 br i1 1, label %bb93, label %__label_000020
14
15 bb93: ; preds = %__label_002001
16 br i1 1, label %__label_000020, label %bb197
17
18 bb197: ; preds = %bb193
19 br i1 1, label %bb229, label %bb224
20
21 bb224: ; preds = %bb223, %bb227
22 br i1 1, label %bb229, label %bb224
23
24 bb229: ; preds = %bb227, %bb223
25 br i1 1, label %__label_002001, label %__label_002001.outer
26
27 __label_000020: ; preds = %__label_002001, %bb194
28 ret void
29 }
30
31 ; CHECK-NOT: =>
32 ; CHECK: [0] entry =>
33 ; CHECK-NEXT: [1] __label_002001.outer => __label_000020
34 ; CHECK-NEXT; [2] bb197 => bb229
35 ; CHECK-NEXT; [3] bb224 => bb229
36
37 ; STAT: 4 region - The # of regions
38 ; STAT: 1 region - The # of simple regions
39
40 ; BBIT: entry, __label_002001.outer, __label_002001, bb93, __label_000020, bb197, bb229, bb224,
41 ; BBIT: __label_002001.outer, __label_002001, bb93, bb197, bb229, bb224,
42 ; BBIT: bb197, bb224,
43 ; BBIT: bb224,
44
45 ; RNIT: entry, __label_002001.outer => __label_000020, __label_000020,
46 ; RNIT: __label_002001.outer, __label_002001, bb93, bb197 => bb229, bb229,
47 ; RNIT: bb197, bb224 => bb229,
48 ; RNIT: bb224,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define void @a_linear_impl_fig_1() nounwind {
6 0:
7 br label %"1"
8 1:
9 br label %"2"
10 2:
11 br label %"3"
12 3:
13 br i1 1, label %"13", label %"4"
14 4:
15 br i1 1, label %"5", label %"1"
16 5:
17 br i1 1, label %"8", label %"6"
18 6:
19 br i1 1, label %"7", label %"4"
20 7:
21 ret void
22 8:
23 br i1 1, label %"9", label %"1"
24 9:
25 br label %"10"
26 10:
27 br i1 1, label %"12", label %"11"
28 11:
29 br i1 1, label %"9", label %"8"
30 13:
31 br i1 1, label %"2", label %"1"
32 12:
33 switch i32 0, label %"1" [ i32 0, label %"9"
34 i32 1, label %"8"]
35 }
36
37 ; CHECK-NOT: =>
38 ; CHECK: [0] 0 =>
39 ; CHECK-NEXT: [1] 1 => 7
40 ; CHECK-NEXT: [2] 1 => 4
41 ; CHECK-NEXT: [2] 8 => 1
42
43 ; STAT: 4 region - The # of regions
44 ; STAT: 1 region - The # of simple regions
45
46 ; BBIT: 0, 1, 2, 3, 13, 4, 5, 8, 9, 10, 12, 11, 6, 7,
47 ; BBIT: 1, 2, 3, 13, 4, 5, 8, 9, 10, 12, 11, 6,
48 ; BBIT: 1, 2, 3, 13,
49 ; BBIT: 8, 9, 10, 12, 11,
50
51 ; RNIT: 0, 1 => 7, 7,
52 ; RNIT: 1 => 4, 4, 5, 8 => 1, 6,
53 ; RNIT: 1, 2, 3, 13,
54 ; RNIT: 8, 9, 10, 12, 11,
0 ; RUN: opt -regions -analyze < %s | FileCheck %s
1 ; RUN: opt -regions -stats < %s |& FileCheck -check-prefix=STAT %s
2 ; RUN: opt -regions -print-region-style=bb -analyze < %s |& FileCheck -check-prefix=BBIT %s
3 ; RUN: opt -regions -print-region-style=rn -analyze < %s |& FileCheck -check-prefix=RNIT %s
4
5 define internal fastcc zeroext i8 @handle_compress() nounwind {
6 entry:
7 br label %outer
8
9 outer:
10 br label %body
11
12 body:
13 br i1 1, label %else, label %true77
14
15 true77:
16 br i1 1, label %then83, label %else
17
18 then83:
19 br label %outer
20
21 else:
22 br label %else106
23
24 else106:
25 br i1 1, label %end, label %outer
26
27 end:
28 ret i8 1
29 }
30
31 ; CHECK-NOT: =>
32 ; CHECK: [0] entry =>
33 ; CHECK-NEXT: [1] outer => end
34 ; CHECK-NEXT: [2] outer => else
35
36 ; STAT: 3 region - The # of regions
37 ; STAT: 1 region - The # of simple regions
38
39 ; BBIT: entry, outer, body, else, else106, end, true77, then83,
40 ; BBIT: outer, body, else, else106, true77, then83,
41 ; BBIT: outer, body, true77, then83,
42
43 ; RNIT: entry, outer => end, end,
44 ; RNIT: outer => else, else, else106,
45 ; RNIT: outer, body, true77, then83,