mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172025 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			589 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			589 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| /// @file
 | |
| /// IntegersSubsetMapping is mapping from A to B, where
 | |
| /// Items in A is subsets of integers,
 | |
| /// Items in B some pointers (Successors).
 | |
| /// If user which to add another subset for successor that is already
 | |
| /// exists in mapping, IntegersSubsetMapping merges existing subset with
 | |
| /// added one.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
 | |
| #define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
 | |
| 
 | |
| #include "llvm/Support/IntegersSubset.h"
 | |
| #include <list>
 | |
| #include <map>
 | |
| #include <vector>
 | |
| 
 | |
| namespace llvm {
 | |
| 
 | |
| template <class SuccessorClass,
 | |
|           class IntegersSubsetTy = IntegersSubset,
 | |
|           class IntTy = IntItem>
 | |
| class IntegersSubsetMapping {
 | |
|   // FIXME: To much similar iterators typedefs, similar names. 
 | |
|   //        - Rename RangeIterator to the cluster iterator.
 | |
|   //        - Remove unused "add" methods.
 | |
|   //        - Class contents needs cleaning.
 | |
| public:
 | |
|   
 | |
|   typedef IntRange<IntTy> RangeTy;
 | |
|   
 | |
|   struct RangeEx : public RangeTy {
 | |
|     RangeEx() : Weight(1) {}
 | |
|     RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
 | |
|     RangeEx(const RangeTy &R, unsigned W) : RangeTy(R), Weight(W) {}
 | |
|     RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
 | |
|     RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
 | |
|     RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
 | |
|       RangeTy(L, H), Weight(W) {}
 | |
|     unsigned Weight;
 | |
|   };
 | |
| 
 | |
|   typedef std::pair<RangeEx, SuccessorClass*> Cluster;
 | |
| 
 | |
|   typedef std::list<RangeTy> RangesCollection;
 | |
|   typedef typename RangesCollection::iterator RangesCollectionIt;
 | |
|   typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
 | |
|   typedef IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> self;
 | |
|   
 | |
| protected:
 | |
| 
 | |
|   typedef std::list<Cluster> CaseItems;
 | |
|   typedef typename CaseItems::iterator CaseItemIt;
 | |
|   typedef typename CaseItems::const_iterator CaseItemConstIt;
 | |
|   
 | |
|   // TODO: Change unclean CRS prefixes to SubsetMap for example.
 | |
|   typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
 | |
|   typedef typename CRSMap::iterator CRSMapIt;
 | |
| 
 | |
|   struct ClustersCmp {
 | |
|     bool operator()(const Cluster &C1, const Cluster &C2) {
 | |
|       return C1.first < C2.first;
 | |
|     }
 | |
|   };
 | |
|   
 | |
|   CaseItems Items;
 | |
|   bool Sorted;
 | |
|   
 | |
|   bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
 | |
|     return LItem->first.getHigh() >= RItem->first.getLow();
 | |
|   }
 | |
| 
 | |
|   bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
 | |
|     if (LItem->second != RItem->second) {
 | |
|       assert(!isIntersected(LItem, RItem) &&
 | |
|              "Intersected items with different successors!");
 | |
|       return false;
 | |
|     }
 | |
|     APInt RLow = RItem->first.getLow();
 | |
|     if (RLow != APInt::getNullValue(RLow.getBitWidth()))
 | |
|       --RLow;
 | |
|     return LItem->first.getHigh() >= RLow;
 | |
|   }
 | |
|   
 | |
|   void sort() {
 | |
|     if (!Sorted) {
 | |
|       std::vector<Cluster> clustersVector;
 | |
|       clustersVector.reserve(Items.size());
 | |
|       clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
 | |
|       std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
 | |
|       Items.clear();
 | |
|       Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
 | |
|       Sorted = true;
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   enum DiffProcessState {
 | |
|     L_OPENED,
 | |
|     INTERSECT_OPENED,
 | |
|     R_OPENED,
 | |
|     ALL_IS_CLOSED
 | |
|   };
 | |
|   
 | |
|   class DiffStateMachine {
 | |
|     
 | |
|     DiffProcessState State;
 | |
|     IntTy OpenPt;
 | |
|     SuccessorClass *CurrentLSuccessor;
 | |
|     SuccessorClass *CurrentRSuccessor;
 | |
|     
 | |
|     self *LeftMapping;
 | |
|     self *IntersectionMapping;
 | |
|     self *RightMapping;
 | |
| 
 | |
|   public:
 | |
|     
 | |
|     typedef
 | |
|       IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> MappingTy;
 | |
|     
 | |
|     DiffStateMachine(MappingTy *L,
 | |
|                                  MappingTy *Intersection,
 | |
|                                  MappingTy *R) :
 | |
|                                  State(ALL_IS_CLOSED),
 | |
|                                  LeftMapping(L),
 | |
|                                  IntersectionMapping(Intersection),
 | |
|                                  RightMapping(R)
 | |
|                                  {}
 | |
|     
 | |
|     void onLOpen(const IntTy &Pt, SuccessorClass *S) {
 | |
|       switch (State) {
 | |
|       case R_OPENED:
 | |
|         if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping) 
 | |
|           RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
 | |
|         State = INTERSECT_OPENED;
 | |
|         break;
 | |
|       case ALL_IS_CLOSED:
 | |
|         State = L_OPENED;
 | |
|         break;
 | |
|       default:
 | |
|         assert(0 && "Got unexpected point.");
 | |
|         break;
 | |
|       }
 | |
|       CurrentLSuccessor = S;
 | |
|       OpenPt = Pt;
 | |
|     }
 | |
|     
 | |
|     void onLClose(const IntTy &Pt) {
 | |
|       switch (State) {
 | |
|       case L_OPENED:
 | |
|         assert(Pt >= OpenPt &&
 | |
|                "Subset is not sorted or contains overlapped ranges");
 | |
|         if (LeftMapping)
 | |
|           LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
 | |
|         State = ALL_IS_CLOSED;
 | |
|         break;
 | |
|       case INTERSECT_OPENED:
 | |
|         if (IntersectionMapping)
 | |
|           IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
 | |
|         OpenPt = Pt + 1;
 | |
|         State = R_OPENED;
 | |
|         break;
 | |
|       default:
 | |
|         assert(0 && "Got unexpected point.");
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     void onROpen(const IntTy &Pt, SuccessorClass *S) {
 | |
|       switch (State) {
 | |
|       case L_OPENED:
 | |
|         if (Pt > OpenPt && LeftMapping)
 | |
|           LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
 | |
|         State = INTERSECT_OPENED;
 | |
|         break;
 | |
|       case ALL_IS_CLOSED:
 | |
|         State = R_OPENED;
 | |
|         break;
 | |
|       default:
 | |
|         assert(0 && "Got unexpected point.");
 | |
|         break;
 | |
|       }
 | |
|       CurrentRSuccessor = S;
 | |
|       OpenPt = Pt;      
 | |
|     }
 | |
|     
 | |
|     void onRClose(const IntTy &Pt) {
 | |
|       switch (State) {
 | |
|       case R_OPENED:
 | |
|         assert(Pt >= OpenPt &&
 | |
|                "Subset is not sorted or contains overlapped ranges");
 | |
|         if (RightMapping)
 | |
|           RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
 | |
|         State = ALL_IS_CLOSED;
 | |
|         break;
 | |
|       case INTERSECT_OPENED:
 | |
|         if (IntersectionMapping)
 | |
|           IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
 | |
|         OpenPt = Pt + 1;
 | |
|         State = L_OPENED;
 | |
|         break;
 | |
|       default:
 | |
|         assert(0 && "Got unexpected point.");
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     void onLROpen(const IntTy &Pt,
 | |
|                   SuccessorClass *LS,
 | |
|                   SuccessorClass *RS) {
 | |
|       switch (State) {
 | |
|       case ALL_IS_CLOSED:
 | |
|         State = INTERSECT_OPENED;
 | |
|         break;
 | |
|       default:
 | |
|         assert(0 && "Got unexpected point.");
 | |
|         break;
 | |
|       }
 | |
|       CurrentLSuccessor = LS;
 | |
|       CurrentRSuccessor = RS;
 | |
|       OpenPt = Pt;        
 | |
|     }
 | |
|     
 | |
|     void onLRClose(const IntTy &Pt) {
 | |
|       switch (State) {
 | |
|       case INTERSECT_OPENED:
 | |
|         if (IntersectionMapping)
 | |
|           IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
 | |
|         State = ALL_IS_CLOSED;
 | |
|         break;
 | |
|       default:
 | |
|         assert(0 && "Got unexpected point.");
 | |
|         break;        
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     bool isLOpened() { return State == L_OPENED; }
 | |
|     bool isROpened() { return State == R_OPENED; }
 | |
|   };
 | |
| 
 | |
| public:
 | |
|   
 | |
|   // Don't public CaseItems itself. Don't allow edit the Items directly. 
 | |
|   // Just present the user way to iterate over the internal collection
 | |
|   // sharing iterator, begin() and end(). Editing should be controlled by
 | |
|   // factory.
 | |
|   typedef CaseItemIt RangeIterator;
 | |
|   
 | |
|   typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
 | |
|   typedef std::list<Case> Cases;
 | |
|   typedef typename Cases::iterator CasesIt;
 | |
|   
 | |
|   IntegersSubsetMapping() {
 | |
|     Sorted = false;
 | |
|   }
 | |
|   
 | |
|   bool verify() {
 | |
|     RangeIterator DummyErrItem;
 | |
|     return verify(DummyErrItem);
 | |
|   }
 | |
|   
 | |
|   bool verify(RangeIterator& errItem) {
 | |
|     if (Items.empty())
 | |
|       return true;
 | |
|     sort();
 | |
|     for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
 | |
|          j != e; i = j++) {
 | |
|       if (isIntersected(i, j) && i->second != j->second) {
 | |
|         errItem = j;
 | |
|         return false;
 | |
|       }
 | |
|     }
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   bool isOverlapped(self &RHS) {
 | |
|     if (Items.empty() || RHS.empty())
 | |
|       return true;
 | |
|     
 | |
|     for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
 | |
|          el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
 | |
|       
 | |
|       const RangeTy &LRange = L->first;
 | |
|       const RangeTy &RRange = R->first;
 | |
|       
 | |
|       if (LRange.getLow() > RRange.getLow()) {
 | |
|         if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
 | |
|           ++R;
 | |
|         else
 | |
|           return true;
 | |
|       } else if (LRange.getLow() < RRange.getLow()) {
 | |
|         if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
 | |
|           ++L;
 | |
|         else
 | |
|           return true;
 | |
|       } else // iRange.getLow() == jRange.getLow() 
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
|   }
 | |
|    
 | |
|   
 | |
|   void optimize() {
 | |
|     if (Items.size() < 2)
 | |
|       return;
 | |
|     sort();
 | |
|     CaseItems OldItems = Items;
 | |
|     Items.clear();
 | |
|     const IntTy *Low = &OldItems.begin()->first.getLow();
 | |
|     const IntTy *High = &OldItems.begin()->first.getHigh();
 | |
|     unsigned Weight = OldItems.begin()->first.Weight;
 | |
|     SuccessorClass *Successor = OldItems.begin()->second;
 | |
|     for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
 | |
|          j != e; i = j++) {
 | |
|       if (isJoinable(i, j)) {
 | |
|         const IntTy *CurHigh = &j->first.getHigh();
 | |
|         Weight += j->first.Weight;
 | |
|         if (*CurHigh > *High)
 | |
|           High = CurHigh;
 | |
|       } else {
 | |
|         RangeEx R(*Low, *High, Weight);
 | |
|         add(R, Successor);
 | |
|         Low = &j->first.getLow();
 | |
|         High = &j->first.getHigh(); 
 | |
|         Weight = j->first.Weight;
 | |
|         Successor = j->second;
 | |
|       }
 | |
|     }
 | |
|     RangeEx R(*Low, *High, Weight);
 | |
|     add(R, Successor);
 | |
|     // We recollected the Items, but we kept it sorted.
 | |
|     Sorted = true;
 | |
|   }
 | |
|   
 | |
|   /// Adds a constant value.
 | |
|   void add(const IntTy &C, SuccessorClass *S = 0) {
 | |
|     RangeTy R(C);
 | |
|     add(R, S);
 | |
|   }
 | |
|   
 | |
|   /// Adds a range.
 | |
|   void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
 | |
|     RangeTy R(Low, High);
 | |
|     add(R, S);
 | |
|   }
 | |
|   void add(const RangeTy &R, SuccessorClass *S = 0) {
 | |
|     RangeEx REx = R;
 | |
|     add(REx, S);
 | |
|   }   
 | |
|   void add(const RangeEx &R, SuccessorClass *S = 0) {
 | |
|     Items.push_back(std::make_pair(R, S));
 | |
|     Sorted = false;
 | |
|   }  
 | |
|   
 | |
|   /// Adds all ranges and values from given ranges set to the current
 | |
|   /// mapping.
 | |
|   void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0,
 | |
|            unsigned Weight = 0) {
 | |
|     unsigned ItemWeight = 1;
 | |
|     if (Weight)
 | |
|       // Weight is associated with CRS, for now we perform a division to
 | |
|       // get the weight for each item.
 | |
|       ItemWeight = Weight / CRS.getNumItems();
 | |
|     for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
 | |
|       RangeTy R = CRS.getItem(i);
 | |
|       RangeEx REx(R, ItemWeight);
 | |
|       add(REx, S);
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   void add(self& RHS) {
 | |
|     Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
 | |
|   }
 | |
|   
 | |
|   void add(self& RHS, SuccessorClass *S) {
 | |
|     for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
 | |
|       add(i->first, S);
 | |
|   }  
 | |
|   
 | |
|   void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
 | |
|     for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
 | |
|       add(*i, S);
 | |
|   }  
 | |
|   
 | |
|   /// Removes items from set.
 | |
|   void removeItem(RangeIterator i) { Items.erase(i); }
 | |
|   
 | |
|   /// Moves whole case from current mapping to the NewMapping object.
 | |
|   void detachCase(self& NewMapping, SuccessorClass *Succ) {
 | |
|     for (CaseItemIt i = Items.begin(); i != Items.end();)
 | |
|       if (i->second == Succ) {
 | |
|         NewMapping.add(i->first, i->second);
 | |
|         Items.erase(i++);
 | |
|       } else
 | |
|         ++i;
 | |
|   }
 | |
|   
 | |
|   /// Removes all clusters for given successor.
 | |
|   void removeCase(SuccessorClass *Succ) {
 | |
|     for (CaseItemIt i = Items.begin(); i != Items.end();)
 | |
|       if (i->second == Succ) {
 | |
|         Items.erase(i++);
 | |
|       } else
 | |
|         ++i;
 | |
|   }  
 | |
|   
 | |
|   /// Find successor that satisfies given value.
 | |
|   SuccessorClass *findSuccessor(const IntTy& Val) {
 | |
|     for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
 | |
|       if (i->first.isInRange(Val))
 | |
|         return i->second;
 | |
|     }
 | |
|     return 0;
 | |
|   }  
 | |
|   
 | |
|   /// Calculates the difference between this mapping and RHS.
 | |
|   /// THIS without RHS is placed into LExclude,
 | |
|   /// RHS without THIS is placed into RExclude,
 | |
|   /// THIS intersect RHS is placed into Intersection.
 | |
|   void diff(self *LExclude, self *Intersection, self *RExclude,
 | |
|                              const self& RHS) {
 | |
|     
 | |
|     DiffStateMachine Machine(LExclude, Intersection, RExclude);
 | |
|     
 | |
|     CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
 | |
|     while (L != Items.end() && R != RHS.Items.end()) {
 | |
|       const Cluster &LCluster = *L;
 | |
|       const RangeEx &LRange = LCluster.first;
 | |
|       const Cluster &RCluster = *R;
 | |
|       const RangeEx &RRange = RCluster.first;
 | |
|       
 | |
|       if (LRange.getHigh() < RRange.getLow()) {
 | |
|         Machine.onLOpen(LRange.getLow(), LCluster.second);
 | |
|         Machine.onLClose(LRange.getHigh());
 | |
|         ++L;
 | |
|         continue;
 | |
|       }
 | |
|       
 | |
|       if (LRange.getLow() > RRange.getHigh()) {
 | |
|         Machine.onROpen(RRange.getLow(), RCluster.second);
 | |
|         Machine.onRClose(RRange.getHigh());
 | |
|         ++R;
 | |
|         continue;
 | |
|       }
 | |
| 
 | |
|       if (LRange.getLow() < RRange.getLow()) {
 | |
|         // May be opened in previous iteration.
 | |
|         if (!Machine.isLOpened())
 | |
|           Machine.onLOpen(LRange.getLow(), LCluster.second);
 | |
|         Machine.onROpen(RRange.getLow(), RCluster.second);
 | |
|       }
 | |
|       else if (RRange.getLow() < LRange.getLow()) {
 | |
|         if (!Machine.isROpened())
 | |
|           Machine.onROpen(RRange.getLow(), RCluster.second);
 | |
|         Machine.onLOpen(LRange.getLow(), LCluster.second);
 | |
|       }
 | |
|       else
 | |
|         Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
 | |
|       
 | |
|       if (LRange.getHigh() < RRange.getHigh()) {
 | |
|         Machine.onLClose(LRange.getHigh());
 | |
|         ++L;
 | |
|         while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
 | |
|           Machine.onLOpen(L->first.getLow(), L->second);
 | |
|           Machine.onLClose(L->first.getHigh());
 | |
|           ++L;
 | |
|         }
 | |
|       }
 | |
|       else if (RRange.getHigh() < LRange.getHigh()) {
 | |
|         Machine.onRClose(RRange.getHigh());
 | |
|         ++R;
 | |
|         while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
 | |
|           Machine.onROpen(R->first.getLow(), R->second);
 | |
|           Machine.onRClose(R->first.getHigh());
 | |
|           ++R;
 | |
|         }
 | |
|       }
 | |
|       else {
 | |
|         Machine.onLRClose(LRange.getHigh());
 | |
|         ++L;
 | |
|         ++R;
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     if (L != Items.end()) {
 | |
|       if (Machine.isLOpened()) {
 | |
|         Machine.onLClose(L->first.getHigh());
 | |
|         ++L;
 | |
|       }
 | |
|       if (LExclude)
 | |
|         while (L != Items.end()) {
 | |
|           LExclude->add(L->first, L->second);
 | |
|           ++L;
 | |
|         }
 | |
|     } else if (R != RHS.Items.end()) {
 | |
|       if (Machine.isROpened()) {
 | |
|         Machine.onRClose(R->first.getHigh());
 | |
|         ++R;
 | |
|       }
 | |
|       if (RExclude)
 | |
|         while (R != RHS.Items.end()) {
 | |
|           RExclude->add(R->first, R->second);
 | |
|           ++R;
 | |
|         }
 | |
|     }
 | |
|   }  
 | |
|   
 | |
|   /// Builds the finalized case objects.
 | |
|   void getCases(Cases& TheCases, bool PreventMerging = false) {
 | |
|     //FIXME: PreventMerging is a temporary parameter.
 | |
|     //Currently a set of passes is still knows nothing about
 | |
|     //switches with case ranges, and if these passes meet switch
 | |
|     //with complex case that crashs the application.
 | |
|     if (PreventMerging) {
 | |
|       for (RangeIterator i = this->begin(); i != this->end(); ++i) {
 | |
|         RangesCollection SingleRange;
 | |
|         SingleRange.push_back(i->first);
 | |
|         TheCases.push_back(std::make_pair(i->second,
 | |
|                                           IntegersSubsetTy(SingleRange)));
 | |
|       }
 | |
|       return;
 | |
|     }
 | |
|     CRSMap TheCRSMap;
 | |
|     for (RangeIterator i = this->begin(); i != this->end(); ++i)
 | |
|       TheCRSMap[i->second].push_back(i->first);
 | |
|     for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
 | |
|       TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
 | |
|   }
 | |
|   
 | |
|   /// Builds the finalized case objects ignoring successor values, as though
 | |
|   /// all ranges belongs to the same successor.
 | |
|   IntegersSubsetTy getCase() {
 | |
|     RangesCollection Ranges;
 | |
|     for (RangeIterator i = this->begin(); i != this->end(); ++i)
 | |
|       Ranges.push_back(i->first);
 | |
|     return IntegersSubsetTy(Ranges);
 | |
|   }  
 | |
|   
 | |
|   /// Returns pointer to value of case if it is single-numbered or 0
 | |
|   /// in another case.
 | |
|   const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
 | |
|     const IntTy* Res = 0;
 | |
|     for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
 | |
|       if (i->second == Succ) {
 | |
|         if (!i->first.isSingleNumber())
 | |
|           return 0;
 | |
|         if (Res)
 | |
|           return 0;
 | |
|         else 
 | |
|           Res = &(i->first.getLow());
 | |
|       }
 | |
|     return Res;
 | |
|   }  
 | |
|   
 | |
|   /// Returns true if there is no ranges and values inside.
 | |
|   bool empty() const { return Items.empty(); }
 | |
|   
 | |
|   void clear() {
 | |
|     Items.clear();
 | |
|     // Don't reset Sorted flag:
 | |
|     // 1. For empty mapping it matters nothing.
 | |
|     // 2. After first item will added Sorted flag will cleared.
 | |
|   }  
 | |
|   
 | |
|   // Returns number of clusters
 | |
|   unsigned size() const {
 | |
|     return Items.size();
 | |
|   }
 | |
|   
 | |
|   RangeIterator begin() { return Items.begin(); }
 | |
|   RangeIterator end() { return Items.end(); }
 | |
| };
 | |
| 
 | |
| class BasicBlock;
 | |
| typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
 | |
| 
 | |
| }
 | |
| 
 | |
| #endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */
 |