mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +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 */
 |