Beispiel #1
0
 forceinline void
 ValSet::add(Space& home, int v) {
   RangeList*  c = fst;
   RangeList** p = &fst;
   while (c != NULL) {
     if (v < c->min()) {
       if (v+1 == c->min()) {
         c->min(v); n++;
         return;
       } else {
         *p = new (home) RangeList(v,v,c); n++; 
         return;
       }
     } else if (v <= c->max()) {
       // Value already included
       return;
     } else if (v == c->max()+1) {
       if ((c->next() != NULL) && (v+1 == c->next()->min())) {
         c->next()->min(c->min());
         *p = c->next();
         c->dispose(home,c);
       } else {
         c->max(v);
       }
       n++;
       return;
     } else {
       // FIXME: HOW TO CAST HERE?
       p = reinterpret_cast<RangeList**>(c->nextRef());
       c = *p;
     }
   }
   *p = new (home) RangeList(v,v,NULL); n++;
   lst = *p;
 }
Beispiel #2
0
 forceinline void
 ValSet::update(Space& home, bool share, ValSet& vs) {
   (void) share;
   if (vs.n > 0) {
     n = vs.n;
     // Count number of ranges
     int m = 0;
     for (RangeList* c = vs.fst; c != NULL; c = c->next())
       m++;
     fst = home.alloc<RangeList>(m);
     lst = fst + (m-1);
     int i=0;
     for (RangeList* c = vs.fst; c != NULL; c = c->next()) {
       fst[i].min(c->min()); fst[i].max(c->max());
       fst[i].next(fst+i+1);
       i++;
     }
     lst->next(NULL);
   }
 }
Beispiel #3
0
 forceinline void
 IntTraceView::prune(Space& home, IntView y, const Delta& d) {
   if (y.range() && (dom->next() == NULL)) {
     dom->min(y.min()); dom->max(y.max());
   } else if (!y.any(d) && (y.max(d)+1 == y.min())) {
     // The lower bound has been adjusted
     if (y.min() > dom->max()) {
       RangeList* p = dom;
       RangeList* l = p->next();
       while ((l != NULL) && (l->max() < y.min())) {
         p=l; l=l->next();
       }
       dom->dispose(home,p);
       dom = l;
     }
     dom->min(y.min());
   } else if (!y.any(d) && (y.max()+1 == y.min(d))) {
     // upper bound has been adjusted
     if ((y.max() <= dom->max()) && (dom->next() == NULL)) {
       dom->max(y.max());
     } else {
       RangeList* p = dom;
       RangeList* l = p->next();
       while ((l != NULL) && (l->min() <= y.max())) {
         p=l; l=l->next();
       }
       p->max(y.max());
       if (p->next() != NULL)
         p->next()->dispose(home);
       p->next(NULL);
     }
   } else {
     // Just copy the domain
     ViewRanges<IntView> yr(y);
     RangeList::overwrite(home,dom,yr);
   }
 }
Beispiel #4
0
  bool
  GLBndSet::include_full(Space& home, int mi, int ma, SetDelta& d) {
    assert(ma >= mi);
    assert(fst() != NULL);

    RangeList* p = NULL;
    RangeList* c = fst();

    while (c != NULL) {
      if (c->max() >= mi-1){
        if (c->min() > ma+1) {  //in a hole before c
          _size+=(ma-mi+1);
          d._glbMin = mi;
          d._glbMax = ma;
          RangeList* q = new (home) RangeList(mi,ma,c);
          if (p==NULL)
            //the new range is the first
            fst(q);
          else
            p->next(q);
          return true;
        }
        //if the range starts before c, update c->min and size
        bool result = false;
        if (c->min()>mi) {
          _size+=(c->min()-mi);
          c->min(mi);
          d._glbMin = mi;
          result = true;
        } else {
          d._glbMin = c->max()+1;
        }
        assert(c->min()<=mi);
        assert(c->max()+1>=mi);
        if (c->max() >= ma) {
          d._glbMax = c->min()-1;
          return result;
        }
        RangeList* q = c;
        //sum up the size of holes eaten
        int prevMax = c->max();
        int growth = 0;
        // invariant: q->min()<=ma+1
        while (q->next() != NULL && q->next()->min() <= ma+1) {
          q = q->next();
          growth += q->min()-prevMax-1;
          prevMax = q->max();
        }
        assert(growth>=0);
        _size+=growth;
        if (q->max() < ma) {
          _size += ma-q->max();
          d._glbMax = ma;
        } else {
          d._glbMax = q->min()-1;
        }
        c->max(std::max(ma,q->max()));
        if (c!=q) {
          RangeList* oldCNext = c->next();
          assert(oldCNext!=NULL); //q would have stayed c if c was last.
          c->next(q->next());
          if (q->next()==NULL){
            assert(q==lst());
            lst(c);
          }
          oldCNext->dispose(home,q);
        }
        return true;
      }
      RangeList* nc = c->next();
      p=c; c=nc;
    }
    //the new range is disjoint from the old domain and we add it as last:
    assert(mi>max()+1);
    RangeList* q = new (home) RangeList(mi, ma, NULL);
    lst()->next(q);
    lst(q);
    _size+= q->width();
    d._glbMin = mi;
    d._glbMax = ma;
    return true;
  }
Beispiel #5
0
  bool
  LUBndSet::exclude_full(Space& home, int mi, int ma, SetDelta& d) {
    assert(ma >= mi);
    assert(mi <= max() && ma >= min() &&
           (mi > min() || ma < max()));
    bool result=false;

    RangeList* p = NULL;
    RangeList* c = fst();
    d._lubMin = Limits::max+1;
    while (c != NULL) {
      if (c->max() >= mi){
        if (c->min() > ma) { return result; } //in a hole

        if (c->min()<mi && c->max() > ma) {  //Range split:
          RangeList* q =
            new (home) RangeList(ma+1,c->max(),c->next());
          c->max(mi-1);
          if (c == lst()) {
            lst(q);
          }
          c->next(q);
          _size -= (ma-mi+1);
          d._lubMin = mi;
          d._lubMax = ma;
          return true;
        }

        if (c->max() > ma) { //start of range clipped, end remains
          d._lubMin = std::min(d._lubMin, c->min());
          d._lubMax = ma;
          _size-=(ma-c->min()+1);
          c->min(ma+1);
          return true;
        }

        if (c->min() < mi) { //end of range clipped, start remains
          _size-=(c->max()-mi+1);
          d._lubMin = mi;
          d._lubMax = c->max();
          c->max(mi-1);
          result=true;
        } else { //range *c destroyed
          d._lubMin = c->min();
          _size-=c->width();
          RangeList *cend = c;
          while ((cend->next()!=NULL) && (cend->next()->max()<=ma)){
            cend = cend->next();
            _size-=cend->width();
          }
          d._lubMax = cend->max();
          if (fst()==c) {
            fst(cend->next());
          } else {
            p->next(cend->next());
          }
          if (lst()==cend) {
            lst(p);
          }
          RangeList* nc=cend->next(); //performs loop step!
          c->dispose(home,cend);
          p=cend;
          c=nc;
          if (c != NULL && c->min() <= ma ) {
            //start of range clipped, end remains
            _size-=(ma-c->min()+1);
            c->min(ma+1);
            d._lubMax = ma;
          }
          return true;
        }
      }
      RangeList *nc = c->next();
      p=c; c=nc;
    }
    return result;
  }
Beispiel #6
0
  bool
  LUBndSet::intersect_full(Space& home, int mi, int ma) {
    RangeList* p = NULL;
    RangeList* c = fst();

    assert(c != NULL); // Never intersect with an empty set

    // Skip ranges that are before mi
    while (c != NULL && c->max() < mi) {
      _size -= c->width();
      RangeList *nc = c->next();
      p=c; c=nc;
    }
    if (c == NULL) {
      // Delete entire domain
      fst()->dispose(home, lst());
      fst(NULL); lst(NULL);
      return true;
    }

    bool changed = false;
    if (c != fst()) {
      fst()->dispose(home, p);
      fst(c);
      p = NULL;
      changed = true;
    }
    // We have found the first range that intersects with [mi,ma]
    if (mi > c->min()) {
      _size -= mi-c->min();
      c->min(mi);
      changed = true;
    }

    while (c != NULL && c->max() <= ma) {
      RangeList *nc = c->next();
      p=c; c=nc;
    }

    if (c == NULL)
      return changed;

    RangeList* newlst = p;
    if (ma >= c->min()) {
      _size -= c->max() - ma;
      c->max(ma);
      newlst = c;
      RangeList* nc = c->next();
      c->next(NULL);
      p=c; c=nc;
    } else if (p != NULL) {
      p->next(NULL);
    }
    if (c != NULL) {
      for (RangeList* cc = c ; cc != NULL; cc = cc->next())
        _size -= cc->width();
      c->dispose(home, lst());
    }
    lst(newlst);
    if (newlst==NULL)
      fst(NULL);
    return true;
  }