Example #1
0
  void clearPointerArithmetic() {
    if (ptrAriJoins.isEmpty()) return;
    for (Entry<Pair<ECR, Long>, Pair<ECR, Long>> cell : ptrAriJoins.entrySet()) {
      ECR resECR = findRoot(cell.getKey().fst());
      final ECR origECR = findRoot(cell.getValue().fst());
      long shift = cell.getValue().snd();
      if (shift >= 0) {
        // TODO: could do more precise analysis here.
        collapse(origECR, resECR);
        continue;
      }

      ValueType origType = getType(origECR);
      Parent parent = origType.getParent();
      if (parent.getECRs().isEmpty()) {
        // TODO: could do more precise analysis here.
        collapse(origECR, resECR);
        continue;
      }

      for (ECR parentECR : parent.getECRs()) {
        ValueType parentType = getType(parentECR);
        if (!parentType.isStruct()) {
          IOUtils.errPrinter().pln("WARNING: non-struct parent");
          join(parentECR, origECR);
          continue;
        }

        Map<Range<Long>, ECR> fieldMap = parentType.asStruct().getFieldMap().asMapOfRanges();
        Entry<Range<Long>, ECR> fieldRange =
            Iterables.find(
                fieldMap.entrySet(),
                new Predicate<Entry<Range<Long>, ECR>>() {
                  @Override
                  public boolean apply(Entry<Range<Long>, ECR> input) {
                    return origECR.equals(getLoc(input.getValue()));
                  }
                });
        long low = fieldRange.getKey().lowerEndpoint() + shift;
        Size parentSize = parentType.getSize();
        long size = cell.getKey().snd();
        if (low == 0
            && (parentSize.isBottom() || parentSize.isNumber() && parentSize.getValue() == size)) {
          join(parentECR, resECR);
          continue;
        }

        collapse(origECR, resECR);
      }
    }
  }
Example #2
0
  /**
   * Unify value types <code>t1</code> and <code>t2</code>
   *
   * @param t1
   * @param t2
   * @return a unified value type
   */
  ValueType unify(ValueType t1, ValueType t2) {
    Pair<ValueType, ValueType> pair = swap(t1, t2);
    t1 = pair.fst();
    t2 = pair.snd();
    if (t1.equals(t2)) return t1;
    if (t1.isBottom()) {
      if (t1.hasOpTag()) t2.enableOpTag();
      return t2;
    }

    Parent parent = Parent.getLUB(t1.getParent(), t2.getParent());
    Size size = Size.getLUB(t1.getSize(), t2.getSize());
    boolean hasOpTag = t1.hasOpTag() || t2.hasOpTag();

    switch (t1.getKind()) {
      case BLANK:
        {
          switch (t2.getKind()) {
            case BLANK:
              return ValueType.blank(size, parent, hasOpTag);
            case SIMPLE:
              {
                return ValueType.simple(
                    t2.asSimple().getLoc(), t2.asSimple().getFunc(), size, parent, hasOpTag);
              }
            default:
              { // case STRUCT:
                return ValueType.struct(t2.asStruct().getFieldMap(), size, parent, hasOpTag);
              }
          }
        }
      case SIMPLE:
        {
          switch (t2.getKind()) {
            case SIMPLE:
              {
                ECR loc1 = t1.asSimple().getLoc();
                ECR loc2 = t2.asSimple().getLoc();
                ECR func1 = t1.asSimple().getFunc();
                ECR func2 = t2.asSimple().getFunc();

                ECR loc = join(loc1, loc2);
                ECR func = join(func1, func2);

                return ValueType.simple(loc, func, size, parent, hasOpTag);
              }
            default: // case STRUCT:
              throw new IllegalArgumentException();
          }
        }
      case STRUCT:
        {
          if (ValueTypeKind.STRUCT.equals(t2.getKind())) {
            RangeMap<Long, ECR> map = getCompatibleMap(t1.asStruct(), t2.asStruct());
            return ValueType.struct(map, size, parent, hasOpTag);
          } else {
            throw new IllegalArgumentException();
          }
        }
      default:
        { // Lambda
          assert (t2.isLambda());

          List<ECR> params = Lists.newArrayList();
          Iterator<ECR> paramItr1 = t1.asLambda().getParams().iterator();
          Iterator<ECR> paramItr2 = t2.asLambda().getParams().iterator();
          while (paramItr1.hasNext() && paramItr2.hasNext()) {
            ECR param1 = paramItr1.next();
            ECR param2 = paramItr2.next();
            ECR param = join(param1, param2);
            params.add(param);
          }

          while (paramItr1.hasNext()) params.add(paramItr1.next());
          while (paramItr2.hasNext()) params.add(paramItr2.next());

          ECR ret1 = t1.asLambda().getRet();
          ECR ret2 = t2.asLambda().getRet();
          ECR ret = join(ret1, ret2);

          return ValueType.lam(ret, params, parent);
        }
    }
  }
Example #3
0
  void ccjoin(Size rangeSize, ECR e1, ECR e2) {
    ValueType type1 = getType(e1);
    if (type1.isBottom()) {
      addCCjoin(rangeSize, e1, e2);
      return;
    }

    Size size1 = type1.getSize();
    if (!Size.isLessThan(rangeSize, size1)) {
      addCCjoin(rangeSize, e1, e2);
      expand(e1, rangeSize); // expand(e1) would call setType(e1, ...) and thus ccjoin(e1, e2)
      return;
    }

    if (e1.equals(e2)) return;

    switch (type1.getKind()) {
      case BLANK:
        {
          addCCjoin(rangeSize, e1, e2);
          ValueType type2 = getType(e2);
          switch (type2.getKind()) {
            case BOTTOM:
              setType(e2, ValueType.blank(rangeSize, Parent.getBottom()));
              return;
            default:
              Size size2 = type2.getSize();
              if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize);
              return;
          }
        }
      case SIMPLE:
        {
          ValueType type2 = getType(e2);
          switch (type2.getKind()) {
            case BOTTOM:
              setType(
                  e2,
                  ValueType.simple(
                      type1.asSimple().getLoc(),
                      type1.asSimple().getFunc(),
                      rangeSize,
                      Parent.getBottom(),
                      type2.hasOpTag()));
              return;
            case BLANK:
              {
                setType(
                    e2,
                    ValueType.simple(
                        type1.asSimple().getLoc(),
                        type1.asSimple().getFunc(),
                        type2.getSize(),
                        type2.getParent(),
                        type2.hasOpTag()));
                Size size2 = type2.getSize();
                if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize);
                return;
              }
            case SIMPLE:
              {
                cjoin(type1.asSimple().getLoc(), type2.asSimple().getLoc());
                cjoin(type1.asSimple().getFunc(), type2.asSimple().getFunc());
                Size size2 = type2.getSize();
                if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize);
                return;
              }
            case STRUCT:
              {
                addCCjoin(rangeSize, e1, e2);
                collapseStruct(e2, type2.asStruct());
                return;
              }
            default: // lambda
              return;
          }
        }
      case STRUCT:
        {
          ValueType type2 = getType(e2);
          switch (type2.getKind()) {
            case BOTTOM:
              {
                RangeMap<Long, ECR> fieldMapCopy = FieldRangeMap.create();
                fieldMapCopy.putAll(type1.asStruct().getFieldMap());
                setType(
                    e2,
                    ValueType.struct(
                        fieldMapCopy, rangeSize, Parent.getBottom(), type2.hasOpTag()));
                return;
              }
            case BLANK:
              {
                RangeMap<Long, ECR> fieldMapCopy = FieldRangeMap.create();
                fieldMapCopy.putAll(type1.asStruct().getFieldMap());
                Size size2 = type2.getSize();
                setType(
                    e2, ValueType.struct(fieldMapCopy, size2, type2.getParent(), type2.hasOpTag()));
                if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize);
                return;
              }
            case SIMPLE:
              {
                addCCjoin(rangeSize, e1, e2);
                Size size2 = type2.getSize();
                if (!Size.isLessThan(rangeSize, size2)) expand(e2, rangeSize);
                for (ECR elemECR : type1.asStruct().getFieldMap().asMapOfRanges().values()) {
                  ValueType elemType = getType(elemECR);
                  Size elemSize = elemType.getSize();
                  ccjoin(elemSize, elemECR, e2);
                }
                return;
              }
            case STRUCT:
              {
                throw new IllegalArgumentException();
                //				Size size2 = type2.getSize();
                //				if(!Size.isLessThan(rangeSize, size2)) {
                //					addCCjoin(rangeSize, e1, e2);
                //					expand(e2, rangeSize); return;
                //				}
                //
                //				ValueType unifyStructType = unify(type1, type2); // unify structure type
                // eagerly
                //				setType(e1, unifyStructType);
                //				setType(e2, unifyStructType);
                //				return;
              }
            default:
              return; // lambda
          }
        }
      default:
        return; // lambda
    }
  }