RegionInfo: Add getMaxRegionExit()
[oota-llvm.git] / lib / Analysis / RegionInfo.cpp
1 //===- RegionInfo.cpp - SESE region detection analysis --------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Detects single entry single exit regions in the control flow graph.
10 //===----------------------------------------------------------------------===//
11
12 #include "llvm/Analysis/RegionInfo.h"
13 #include "llvm/Analysis/RegionIterator.h"
14
15 #include "llvm/ADT/PostOrderIterator.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include "llvm/Analysis/LoopInfo.h"
21
22 #define DEBUG_TYPE "region"
23 #include "llvm/Support/Debug.h"
24
25 #include <set>
26 #include <algorithm>
27
28 using namespace llvm;
29
30 // Always verify if expensive checking is enabled.
31 #ifdef XDEBUG
32 bool VerifyRegionInfo = true;
33 #else
34 bool VerifyRegionInfo = false;
35 #endif
36
37 static cl::opt<bool,true>
38 VerifyRegionInfoX("verify-region-info", cl::location(VerifyRegionInfo),
39                 cl::desc("Verify region info (time consuming)"));
40
41 STATISTIC(numRegions,       "The # of regions");
42 STATISTIC(numSimpleRegions, "The # of simple regions");
43
44 //===----------------------------------------------------------------------===//
45 /// PrintStyle - Print region in difference ways.
46 enum PrintStyle { PrintNone, PrintBB, PrintRN  };
47
48 cl::opt<enum PrintStyle> printStyle("print-region-style", cl::Hidden,
49   cl::desc("style of printing regions"),
50   cl::values(
51     clEnumValN(PrintNone, "none",  "print no details"),
52     clEnumValN(PrintBB, "bb",  "print regions in detail with block_iterator"),
53     clEnumValN(PrintRN, "rn",  "print regions in detail with element_iterator"),
54     clEnumValEnd));
55 //===----------------------------------------------------------------------===//
56 /// Region Implementation
57 Region::Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RInfo,
58                DominatorTree *dt, Region *Parent)
59                : RegionNode(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {}
60
61 Region::~Region() {
62   // Only clean the cache for this Region. Caches of child Regions will be
63   // cleaned when the child Regions are deleted.
64   BBNodeMap.clear();
65
66   for (iterator I = begin(), E = end(); I != E; ++I)
67     delete *I;
68 }
69
70 bool Region::contains(const BasicBlock *B) const {
71   BasicBlock *BB = const_cast<BasicBlock*>(B);
72
73   assert(DT->getNode(BB) && "BB not part of the dominance tree");
74
75   BasicBlock *entry = getEntry(), *exit = getExit();
76
77   // Toplevel region.
78   if (!exit)
79     return true;
80
81   return (DT->dominates(entry, BB)
82     && !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
83 }
84
85 bool Region::contains(const Loop *L) const {
86   // BBs that are not part of any loop are element of the Loop
87   // described by the NULL pointer. This loop is not part of any region,
88   // except if the region describes the whole function.
89   if (L == 0)
90     return getExit() == 0;
91
92   if (!contains(L->getHeader()))
93     return false;
94
95   SmallVector<BasicBlock *, 8> ExitingBlocks;
96   L->getExitingBlocks(ExitingBlocks);
97
98   for (SmallVectorImpl<BasicBlock*>::iterator BI = ExitingBlocks.begin(),
99        BE = ExitingBlocks.end(); BI != BE; ++BI)
100     if (!contains(*BI))
101       return false;
102
103   return true;
104 }
105
106 Loop *Region::outermostLoopInRegion(Loop *L) const {
107   if (!contains(L))
108     return 0;
109
110   while (L && contains(L->getParentLoop())) {
111     L = L->getParentLoop();
112   }
113
114   return L;
115 }
116
117 Loop *Region::outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const {
118   assert(LI && BB && "LI and BB cannot be null!");
119   Loop *L = LI->getLoopFor(BB);
120   return outermostLoopInRegion(L);
121 }
122
123 bool Region::isSimple() const {
124   bool isSimple = true;
125   bool found = false;
126
127   BasicBlock *entry = getEntry(), *exit = getExit();
128
129   // TopLevelRegion
130   if (!exit)
131     return false;
132
133   for (pred_iterator PI = pred_begin(entry), PE = pred_end(entry); PI != PE;
134        ++PI)
135     if (!contains(*PI)) {
136       if (found) {
137         isSimple = false;
138         break;
139       }
140       found = true;
141     }
142
143   found = false;
144
145   for (pred_iterator PI = pred_begin(exit), PE = pred_end(exit); PI != PE;
146        ++PI)
147     if (contains(*PI)) {
148       if (found) {
149         isSimple = false;
150         break;
151       }
152       found = true;
153     }
154
155   return isSimple;
156 }
157
158 std::string Region::getNameStr() const {
159   std::string exitName;
160   std::string entryName;
161
162   if (getEntry()->getName().empty()) {
163     raw_string_ostream OS(entryName);
164
165     WriteAsOperand(OS, getEntry(), false);
166     entryName = OS.str();
167   } else
168     entryName = getEntry()->getNameStr();
169
170   if (getExit()) {
171     if (getExit()->getName().empty()) {
172       raw_string_ostream OS(exitName);
173
174       WriteAsOperand(OS, getExit(), false);
175       exitName = OS.str();
176     } else
177       exitName = getExit()->getNameStr();
178   } else
179     exitName = "<Function Return>";
180
181   return entryName + " => " + exitName;
182 }
183
184 void Region::verifyBBInRegion(BasicBlock *BB) const {
185   if (!contains(BB))
186     llvm_unreachable("Broken region found!");
187
188   BasicBlock *entry = getEntry(), *exit = getExit();
189
190   for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
191     if (!contains(*SI) && exit != *SI)
192       llvm_unreachable("Broken region found!");
193
194   if (entry != BB)
195     for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB); SI != SE; ++SI)
196       if (!contains(*SI))
197         llvm_unreachable("Broken region found!");
198 }
199
200 void Region::verifyWalk(BasicBlock *BB, std::set<BasicBlock*> *visited) const {
201   BasicBlock *exit = getExit();
202
203   visited->insert(BB);
204
205   verifyBBInRegion(BB);
206
207   for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
208     if (*SI != exit && visited->find(*SI) == visited->end())
209         verifyWalk(*SI, visited);
210 }
211
212 void Region::verifyRegion() const {
213   // Only do verification when user wants to, otherwise this expensive
214   // check will be invoked by PassManager.
215   if (!VerifyRegionInfo) return;
216
217   std::set<BasicBlock*> visited;
218   verifyWalk(getEntry(), &visited);
219 }
220
221 void Region::verifyRegionNest() const {
222   for (Region::const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
223     (*RI)->verifyRegionNest();
224
225   verifyRegion();
226 }
227
228 Region::block_iterator Region::block_begin() {
229   return GraphTraits<FlatIt<Region*> >::nodes_begin(this);
230 }
231
232 Region::block_iterator Region::block_end() {
233   return GraphTraits<FlatIt<Region*> >::nodes_end(this);
234 }
235
236 Region::const_block_iterator Region::block_begin() const {
237   return GraphTraits<FlatIt<const Region*> >::nodes_begin(this);
238 }
239
240 Region::const_block_iterator Region::block_end() const {
241   return GraphTraits<FlatIt<const Region*> >::nodes_end(this);
242 }
243
244 Region::element_iterator Region::element_begin() {
245   return GraphTraits<Region*>::nodes_begin(this);
246 }
247
248 Region::element_iterator Region::element_end() {
249   return GraphTraits<Region*>::nodes_end(this);
250 }
251
252 Region::const_element_iterator Region::element_begin() const {
253   return GraphTraits<const Region*>::nodes_begin(this);
254 }
255
256 Region::const_element_iterator Region::element_end() const {
257   return GraphTraits<const Region*>::nodes_end(this);
258 }
259
260 Region* Region::getSubRegionNode(BasicBlock *BB) const {
261   Region *R = RI->getRegionFor(BB);
262
263   if (!R || R == this)
264     return 0;
265
266   // If we pass the BB out of this region, that means our code is broken.
267   assert(contains(R) && "BB not in current region!");
268
269   while (contains(R->getParent()) && R->getParent() != this)
270     R = R->getParent();
271
272   if (R->getEntry() != BB)
273     return 0;
274
275   return R;
276 }
277
278 RegionNode* Region::getBBNode(BasicBlock *BB) const {
279   assert(contains(BB) && "Can get BB node out of this region!");
280
281   BBNodeMapT::const_iterator at = BBNodeMap.find(BB);
282
283   if (at != BBNodeMap.end())
284     return at->second;
285
286   RegionNode *NewNode = new RegionNode(const_cast<Region*>(this), BB);
287   BBNodeMap.insert(std::make_pair(BB, NewNode));
288   return NewNode;
289 }
290
291 RegionNode* Region::getNode(BasicBlock *BB) const {
292   assert(contains(BB) && "Can get BB node out of this region!");
293   if (Region* Child = getSubRegionNode(BB))
294     return Child->getNode();
295
296   return getBBNode(BB);
297 }
298
299 void Region::transferChildrenTo(Region *To) {
300   for (iterator I = begin(), E = end(); I != E; ++I) {
301     (*I)->parent = To;
302     To->children.push_back(*I);
303   }
304   children.clear();
305 }
306
307 void Region::addSubRegion(Region *SubRegion) {
308   assert(SubRegion->parent == 0 && "SubRegion already has a parent!");
309   SubRegion->parent = this;
310   // Set up the region node.
311   assert(std::find(children.begin(), children.end(), SubRegion) == children.end()
312          && "Node already exist!");
313   children.push_back(SubRegion);
314 }
315
316
317 Region *Region::removeSubRegion(Region *Child) {
318   assert(Child->parent == this && "Child is not a child of this region!");
319   Child->parent = 0;
320   RegionSet::iterator I = std::find(children.begin(), children.end(), Child);
321   assert(I != children.end() && "Region does not exit. Unable to remove.");
322   children.erase(children.begin()+(I-begin()));
323   return Child;
324 }
325
326 unsigned Region::getDepth() const {
327   unsigned Depth = 0;
328
329   for (Region *R = parent; R != 0; R = R->parent)
330     ++Depth;
331
332   return Depth;
333 }
334
335 void Region::print(raw_ostream &OS, bool print_tree, unsigned level) const {
336   if (print_tree)
337     OS.indent(level*2) << "[" << level << "] " << getNameStr();
338   else
339     OS.indent(level*2) << getNameStr();
340
341   OS << "\n";
342
343
344   if (printStyle != PrintNone) {
345     OS.indent(level*2) << "{\n";
346     OS.indent(level*2 + 2);
347
348     if (printStyle == PrintBB) {
349       for (const_block_iterator I = block_begin(), E = block_end(); I!=E; ++I)
350         OS << **I << ", "; // TODO: remove the last ","
351     } else if (printStyle == PrintRN) {
352       for (const_element_iterator I = element_begin(), E = element_end(); I!=E; ++I)
353         OS << **I << ", "; // TODO: remove the last ",
354     }
355
356     OS << "\n";
357   }
358
359   if (print_tree)
360     for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
361       (*RI)->print(OS, print_tree, level+1);
362
363   if (printStyle != PrintNone)
364     OS.indent(level*2) << "} \n";
365 }
366
367 void Region::dump() const {
368   print(dbgs(), true, getDepth());
369 }
370
371 void Region::clearNodeCache() {
372   BBNodeMap.clear();
373   for (Region::iterator RI = begin(), RE = end(); RI != RE; ++RI)
374     (*RI)->clearNodeCache();
375 }
376
377 //===----------------------------------------------------------------------===//
378 // RegionInfo implementation
379 //
380
381 bool RegionInfo::isCommonDomFrontier(BasicBlock *BB, BasicBlock *entry,
382                                      BasicBlock *exit) const {
383   for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
384     BasicBlock *P = *PI;
385     if (DT->dominates(entry, P) && !DT->dominates(exit, P))
386       return false;
387   }
388   return true;
389 }
390
391 bool RegionInfo::isRegion(BasicBlock *entry, BasicBlock *exit) const {
392   assert(entry && exit && "entry and exit must not be null!");
393   typedef DominanceFrontier::DomSetType DST;
394
395   DST *entrySuccs = &DF->find(entry)->second;
396
397   // Exit is the header of a loop that contains the entry. In this case,
398   // the dominance frontier must only contain the exit.
399   if (!DT->dominates(entry, exit)) {
400     for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
401          SI != SE; ++SI)
402       if (*SI != exit && *SI != entry)
403         return false;
404
405     return true;
406   }
407
408   DST *exitSuccs = &DF->find(exit)->second;
409
410   // Do not allow edges leaving the region.
411   for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
412        SI != SE; ++SI) {
413     if (*SI == exit || *SI == entry)
414       continue;
415     if (exitSuccs->find(*SI) == exitSuccs->end())
416       return false;
417     if (!isCommonDomFrontier(*SI, entry, exit))
418       return false;
419   }
420
421   // Do not allow edges pointing into the region.
422   for (DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end();
423        SI != SE; ++SI)
424     if (DT->properlyDominates(entry, *SI) && *SI != exit)
425       return false;
426
427
428   return true;
429 }
430
431 void RegionInfo::insertShortCut(BasicBlock *entry, BasicBlock *exit,
432                              BBtoBBMap *ShortCut) const {
433   assert(entry && exit && "entry and exit must not be null!");
434
435   BBtoBBMap::iterator e = ShortCut->find(exit);
436
437   if (e == ShortCut->end())
438     // No further region at exit available.
439     (*ShortCut)[entry] = exit;
440   else {
441     // We found a region e that starts at exit. Therefore (entry, e->second)
442     // is also a region, that is larger than (entry, exit). Insert the
443     // larger one.
444     BasicBlock *BB = e->second;
445     (*ShortCut)[entry] = BB;
446   }
447 }
448
449 DomTreeNode* RegionInfo::getNextPostDom(DomTreeNode* N,
450                                         BBtoBBMap *ShortCut) const {
451   BBtoBBMap::iterator e = ShortCut->find(N->getBlock());
452
453   if (e == ShortCut->end())
454     return N->getIDom();
455
456   return PDT->getNode(e->second)->getIDom();
457 }
458
459 bool RegionInfo::isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const {
460   assert(entry && exit && "entry and exit must not be null!");
461
462   unsigned num_successors = succ_end(entry) - succ_begin(entry);
463
464   if (num_successors <= 1 && exit == *(succ_begin(entry)))
465     return true;
466
467   return false;
468 }
469
470 void RegionInfo::updateStatistics(Region *R) {
471   ++numRegions;
472
473   // TODO: Slow. Should only be enabled if -stats is used.
474   if (R->isSimple()) ++numSimpleRegions;
475 }
476
477 Region *RegionInfo::createRegion(BasicBlock *entry, BasicBlock *exit) {
478   assert(entry && exit && "entry and exit must not be null!");
479
480   if (isTrivialRegion(entry, exit))
481     return 0;
482
483   Region *region = new Region(entry, exit, this, DT);
484   BBtoRegion.insert(std::make_pair(entry, region));
485
486  #ifdef XDEBUG
487     region->verifyRegion();
488  #else
489     DEBUG(region->verifyRegion());
490  #endif
491
492   updateStatistics(region);
493   return region;
494 }
495
496 void RegionInfo::findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut) {
497   assert(entry);
498
499   DomTreeNode *N = PDT->getNode(entry);
500
501   if (!N)
502     return;
503
504   Region *lastRegion= 0;
505   BasicBlock *lastExit = entry;
506
507   // As only a BasicBlock that postdominates entry can finish a region, walk the
508   // post dominance tree upwards.
509   while ((N = getNextPostDom(N, ShortCut))) {
510     BasicBlock *exit = N->getBlock();
511
512     if (!exit)
513       break;
514
515     if (isRegion(entry, exit)) {
516       Region *newRegion = createRegion(entry, exit);
517
518       if (lastRegion)
519         newRegion->addSubRegion(lastRegion);
520
521       lastRegion = newRegion;
522       lastExit = exit;
523     }
524
525     // This can never be a region, so stop the search.
526     if (!DT->dominates(entry, exit))
527       break;
528   }
529
530   // Tried to create regions from entry to lastExit.  Next time take a
531   // shortcut from entry to lastExit.
532   if (lastExit != entry)
533     insertShortCut(entry, lastExit, ShortCut);
534 }
535
536 void RegionInfo::scanForRegions(Function &F, BBtoBBMap *ShortCut) {
537   BasicBlock *entry = &(F.getEntryBlock());
538   DomTreeNode *N = DT->getNode(entry);
539
540   // Iterate over the dominance tree in post order to start with the small
541   // regions from the bottom of the dominance tree.  If the small regions are
542   // detected first, detection of bigger regions is faster, as we can jump
543   // over the small regions.
544   for (po_iterator<DomTreeNode*> FI = po_begin(N), FE = po_end(N); FI != FE;
545     ++FI) {
546     findRegionsWithEntry(FI->getBlock(), ShortCut);
547   }
548 }
549
550 Region *RegionInfo::getTopMostParent(Region *region) {
551   while (region->parent)
552     region = region->getParent();
553
554   return region;
555 }
556
557 void RegionInfo::buildRegionsTree(DomTreeNode *N, Region *region) {
558   BasicBlock *BB = N->getBlock();
559
560   // Passed region exit
561   while (BB == region->getExit())
562     region = region->getParent();
563
564   BBtoRegionMap::iterator it = BBtoRegion.find(BB);
565
566   // This basic block is a start block of a region. It is already in the
567   // BBtoRegion relation. Only the child basic blocks have to be updated.
568   if (it != BBtoRegion.end()) {
569     Region *newRegion = it->second;;
570     region->addSubRegion(getTopMostParent(newRegion));
571     region = newRegion;
572   } else {
573     BBtoRegion[BB] = region;
574   }
575
576   for (DomTreeNode::iterator CI = N->begin(), CE = N->end(); CI != CE; ++CI)
577     buildRegionsTree(*CI, region);
578 }
579
580 void RegionInfo::releaseMemory() {
581   BBtoRegion.clear();
582   if (TopLevelRegion)
583     delete TopLevelRegion;
584   TopLevelRegion = 0;
585 }
586
587 RegionInfo::RegionInfo() : FunctionPass(&ID) {
588   TopLevelRegion = 0;
589 }
590
591 RegionInfo::~RegionInfo() {
592   releaseMemory();
593 }
594
595 void RegionInfo::Calculate(Function &F) {
596   // ShortCut a function where for every BB the exit of the largest region
597   // starting with BB is stored. These regions can be threated as single BBS.
598   // This improves performance on linear CFGs.
599   BBtoBBMap ShortCut;
600
601   scanForRegions(F, &ShortCut);
602   BasicBlock *BB = &F.getEntryBlock();
603   buildRegionsTree(DT->getNode(BB), TopLevelRegion);
604 }
605
606 bool RegionInfo::runOnFunction(Function &F) {
607   releaseMemory();
608
609   DT = &getAnalysis<DominatorTree>();
610   PDT = &getAnalysis<PostDominatorTree>();
611   DF = &getAnalysis<DominanceFrontier>();
612
613   TopLevelRegion = new Region(&F.getEntryBlock(), 0, this, DT, 0);
614   updateStatistics(TopLevelRegion);
615
616   Calculate(F);
617
618   return false;
619 }
620
621 void RegionInfo::getAnalysisUsage(AnalysisUsage &AU) const {
622   AU.setPreservesAll();
623   AU.addRequiredTransitive<DominatorTree>();
624   AU.addRequired<PostDominatorTree>();
625   AU.addRequired<DominanceFrontier>();
626 }
627
628 void RegionInfo::print(raw_ostream &OS, const Module *) const {
629   OS << "Region tree:\n";
630   TopLevelRegion->print(OS, true, 0);
631   OS << "End region tree\n";
632 }
633
634 void RegionInfo::verifyAnalysis() const {
635   // Only do verification when user wants to, otherwise this expensive check
636   // will be invoked by PMDataManager::verifyPreservedAnalysis when
637   // a regionpass (marked PreservedAll) finish.
638   if (!VerifyRegionInfo) return;
639
640   TopLevelRegion->verifyRegionNest();
641 }
642
643 // Region pass manager support.
644 Region *RegionInfo::getRegionFor(BasicBlock *BB) const {
645   BBtoRegionMap::const_iterator I=
646     BBtoRegion.find(BB);
647   return I != BBtoRegion.end() ? I->second : 0;
648 }
649
650 Region *RegionInfo::operator[](BasicBlock *BB) const {
651   return getRegionFor(BB);
652 }
653
654
655 BasicBlock *RegionInfo::getMaxRegionExit(BasicBlock *BB) const {
656   BasicBlock *Exit = NULL;
657
658   while (true) {
659     // Get largest region that starts at BB.
660     Region *R = getRegionFor(BB);
661     while (R && R->getParent() && R->getParent()->getEntry() == BB)
662       R = R->getParent();
663
664     // Get the single exit of BB.
665     if (R && R->getEntry() == BB)
666       Exit = R->getExit();
667     else if (++succ_begin(BB) == succ_end(BB))
668       Exit = *succ_begin(BB);
669     else // No single exit exists.
670       return Exit;
671
672     // Get largest region that starts at Exit.
673     Region *ExitR = getRegionFor(Exit);
674     while (ExitR && ExitR->getParent()
675            && ExitR->getParent()->getEntry() == Exit)
676       ExitR = ExitR->getParent();
677
678     for (pred_iterator PI = pred_begin(Exit), PE = pred_end(Exit); PI != PE;
679          ++PI)
680       if (!R->contains(*PI) && !ExitR->contains(*PI))
681         break;
682
683     // This stops infinite cycles.
684     if (DT->dominates(Exit, BB))
685       break;
686
687     BB = Exit;
688   }
689
690   return Exit;
691 }
692
693 Region*
694 RegionInfo::getCommonRegion(Region *A, Region *B) const {
695   assert (A && B && "One of the Regions is NULL");
696
697   if (A->contains(B)) return A;
698
699   while (!B->contains(A))
700     B = B->getParent();
701
702   return B;
703 }
704
705 Region*
706 RegionInfo::getCommonRegion(SmallVectorImpl<Region*> &Regions) const {
707   Region* ret = Regions.back();
708   Regions.pop_back();
709
710   for (SmallVectorImpl<Region*>::const_iterator I = Regions.begin(),
711        E = Regions.end(); I != E; ++I)
712       ret = getCommonRegion(ret, *I);
713
714   return ret;
715 }
716
717 Region*
718 RegionInfo::getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const {
719   Region* ret = getRegionFor(BBs.back());
720   BBs.pop_back();
721
722   for (SmallVectorImpl<BasicBlock*>::const_iterator I = BBs.begin(),
723        E = BBs.end(); I != E; ++I)
724       ret = getCommonRegion(ret, getRegionFor(*I));
725
726   return ret;
727 }
728
729 char RegionInfo::ID = 0;
730 INITIALIZE_PASS(RegionInfo, "regions",
731                 "Detect single entry single exit regions", true, true);
732
733 // Create methods available outside of this file, to use them
734 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
735 // the link time optimization.
736
737 namespace llvm {
738   FunctionPass *createRegionInfoPass() {
739     return new RegionInfo();
740   }
741 }
742