예제 #1
0
bool
LSLocation::reduce(LSLocation Base, SILModule *M, LSLocationSet &Locs) {
  // If this is a class reference type, we have reached end of the type tree.
  if (Base.getType(M).getClassOrBoundGenericClass())
    return Locs.find(Base) != Locs.end();

  // This is a leaf node.
  LSLocationList NextLevel;
  Base.getNextLevelLSLocations(NextLevel, M);
  if (NextLevel.empty())
    return Locs.find(Base) != Locs.end();

  // This is not a leaf node, try to find whether all its children are alive.
  bool Alive = true;
  for (auto &X : NextLevel) {
    Alive &= LSLocation::reduce(X, M, Locs);
  }

  // All next level locations are alive, create the new aggregated location.
  if (Alive) {
    for (auto &X : NextLevel)
      Locs.erase(X);
    Locs.insert(Base);
  }
  return Alive;
}
예제 #2
0
bool RLEContext::gatherLocationValues(SILBasicBlock *BB, LSLocation &L,
                                      LSLocationValueMap &Values,
                                      ValueTableMap &VM) {
  LSLocationSet CSLocs;
  LSLocationList Locs;
  LSLocation::expand(L, &BB->getModule(), Locs, TE);

  auto *Mod = &BB->getModule();
  // Find the locations that this basic block defines and the locations which
  // we do not have a concrete value in the current basic block.
  for (auto &X : Locs) {
    Values[X] = getLSValue(VM[getLSLocationBit(X)]);
    if (!Values[X].isCoveringValue())
      continue;
    CSLocs.insert(X);
  }

  // For locations which we do not have concrete values for in this basic
  // block, try to reduce it to the minimum # of locations possible, this
  // will help us to generate as few SILArguments as possible.
  LSLocation::reduce(L, Mod, CSLocs, TE);

  // To handle covering value, we need to go to the predecessors and
  // materialize them there.
  for (auto &X : CSLocs) {
    SILValue V = computePredecessorLocationValue(BB, X);
    if (!V)
      return false;

    // We've constructed a concrete value for the covering value. Expand and
    // collect the newly created forwardable values.
    LSLocationList Locs;
    LSValueList Vals;
    LSLocation::expand(X, Mod, Locs, TE);
    LSValue::expand(V, Mod, Vals, TE);

    for (unsigned i = 0; i < Locs.size(); ++i) {
      Values[Locs[i]] = Vals[i];
      assert(Values[Locs[i]].isValid() && "Invalid load store value");
    }
  }
  return true;
}
예제 #3
0
void LSLocation::reduce(LSLocation &Base, SILModule *M, LSLocationSet &Locs,
                        TypeExpansionAnalysis *TE) {
  // First, construct the LSLocation by appending the projection path from the
  // accessed node to the leaf nodes.
  LSLocationList Nodes;
  ProjectionPath &BasePath = Base.getPath().getValue();
  for (const auto &P :
       TE->getTypeExpansionProjectionPaths(Base.getType(), M, TEKind::TENode)) {
    Nodes.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 = Nodes.rbegin(), E = Nodes.rend(); I != E; ++I) {
    LSLocationList FirstLevel;
    I->getFirstLevelLSLocations(FirstLevel, M);
    // Reached the end of the projection tree, this is a leaf node.
    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, check whether all its first level children are
    // alive.
    bool Alive = true;
    for (auto &X : FirstLevel) {
      Alive &= Locs.find(X) != Locs.end();
    }

    // All first level locations are alive, create the new aggregated location.
    if (Alive) {
      for (auto &X : FirstLevel)
        Locs.erase(X);
      Locs.insert(*I);
    }
  }
}