Beispiel #1
0
SILValue
LSValue::reduce(LSLocation &Base, SILModule *M, LSLocationValueMap &Values,
                SILInstruction *InsertPt) {
  LSValue::reduceInner(Base, M, Values, InsertPt);
  // Finally materialize and return the forwarding SILValue.
  return Values.begin()->second.materialize(InsertPt);
}
Beispiel #2
0
SILValue LSValue::reduce(LSLocation &Base, SILModule *M,
                         LSLocationValueMap &Values,
                         SILInstruction *InsertPt,
                         TypeExpansionAnalysis *TE) {
  // Walk bottom up the projection tree, try to reason about how to construct
  // a single SILValue out of all the available values for all the memory
  // locations.
  //
  // First, get a list of all the leaf nodes and intermediate nodes for the
  // Base memory location.
  LSLocationList ALocs;
  ProjectionPath &BasePath = Base.getPath().getValue();
  for (const auto &P :
       TE->getTypeExpansionProjectionPaths(Base.getType(), M, TEKind::TENode)) {
    ALocs.push_back(LSLocation(Base.getBase(), P.getValue(), BasePath));
  }

  // Second, go from leaf nodes to their parents. This guarantees that at the
  // point the parent is processed, its children have been processed already.
  for (auto I = ALocs.rbegin(), E = ALocs.rend(); I != E; ++I) {
    // This is a leaf node, we have a value for it.
    //
    // Reached the end of the projection tree, this is a leaf node.
    LSLocationList FirstLevel;
    I->getFirstLevelLSLocations(FirstLevel, M);
    if (FirstLevel.empty())
      continue;

    // If this is a class reference type, we have reached end of the type tree.
    if (I->getType().getClassOrBoundGenericClass())
      continue;

    // This is NOT a leaf node, we need to construct a value for it.

    // There is only 1 children node and its value's projection path is not
    // empty, keep stripping it.
    auto Iter = FirstLevel.begin();
    LSValue &FirstVal = Values[*Iter];
    if (FirstLevel.size() == 1 && !FirstVal.hasEmptyProjectionPath()) {
      Values[*I] = FirstVal.stripLastLevelProjection();
      // We have a value for the parent, remove all the values for children.
      removeLSLocations(Values, FirstLevel);
      continue;
    }
    
    // If there are more than 1 children and all the children nodes have
    // LSValues with the same base and non-empty projection path. we can get
    // away by not extracting value for every single field.
    //
    // Simply create a new node with all the aggregated base value, i.e.
    // stripping off the last level projection.
    bool HasIdenticalValueBase = true;
    SILValue FirstBase = FirstVal.getBase();
    Iter = std::next(Iter);
    for (auto EndIter = FirstLevel.end(); Iter != EndIter; ++Iter) {
      LSValue &V = Values[*Iter];
      HasIdenticalValueBase &= (FirstBase == V.getBase());
    }

    if (FirstLevel.size() > 1 && HasIdenticalValueBase && 
        !FirstVal.hasEmptyProjectionPath()) {
      Values[*I] = FirstVal.stripLastLevelProjection();
      // We have a value for the parent, remove all the values for children.
      removeLSLocations(Values, FirstLevel);
      continue;
    }

    // In 3 cases do we need aggregation.
    //
    // 1. If there is only 1 child and we cannot strip off any projections,
    // that means we need to create an aggregation.
    // 
    // 2. There are multiple children and they have the same base, but empty
    // projection paths.
    //
    // 3. Children have values from different bases, We need to create
    // extractions and aggregation in this case.
    //
    llvm::SmallVector<SILValue, 8> Vals;
    for (auto &X : FirstLevel) {
      Vals.push_back(Values[X].materialize(InsertPt));
    }
    SILBuilder Builder(InsertPt);
    
    // We use an auto-generated SILLocation for now.
    // TODO: make the sil location more precise.
    NullablePtr<swift::SILInstruction> AI =
        Projection::createAggFromFirstLevelProjections(
            Builder, RegularLocation::getAutoGeneratedLocation(), I->getType(),
            Vals);
    // This is the Value for the current node.
    ProjectionPath P;
    Values[*I] = LSValue(SILValue(AI.get()), P);
    removeLSLocations(Values, FirstLevel);

    // Keep iterating until we have reach the top-most level of the projection
    // tree.
    // i.e. the memory location represented by the Base.
  }

  assert(Values.size() == 1 && "Should have a single location this point");

  // Finally materialize and return the forwarding SILValue.
  return Values.begin()->second.materialize(InsertPt);
}
Beispiel #3
0
static inline void removeLSLocations(LSLocationValueMap &Values,
                                     LSLocationList &FirstLevel) {
  for (auto &X : FirstLevel)
    Values.erase(X);
}
Beispiel #4
0
//===----------------------------------------------------------------------===//
//                              Utility Functions
//===----------------------------------------------------------------------===//
static void
removeLSLocations(LSLocationValueMap &Values, LSLocationList &NextLevel) {
  for (auto &X : NextLevel) {
    Values.erase(X);
  }
}