Esempio n. 1
0
bool RLEContext::gatherValues(SILBasicBlock *BB, MemLocation &L,
                              MemLocationValueMap &Values,
                              bool UseForwardValOut) {
  MemLocationSet CSLocs;
  MemLocationList Locs;
  MemLocation::expand(L, &BB->getModule(), Locs, getTypeExpansionCache());
  // Are we using the ForwardVal at the end of the basic block or not.
  // If we are collecting values at the end of the basic block, we can
  // use its ForwardValOut.
  //
  BBState &Forwarder = getBBLocState(BB);
  ValueTableMap &OTM = UseForwardValOut ? Forwarder.getForwardValOut()
                                        : Forwarder.getForwardValIn();
  for (auto &X : Locs) {
    Values[X] = OTM[getMemLocationBit(X)];
    if (!Values[X].isCoveringValue())
      continue;
    CSLocs.insert(X);
  }

  // Try to reduce it to the minimum # of locations possible, this will help
  // us to generate as few extractions as possible.
  MemLocation::reduce(L, &BB->getModule(), CSLocs);

  // To handle covering value, we need to go to the predecessors and
  // materialize them there.
  for (auto &X : CSLocs) {
    SILValue V = computePredecessorCoveringValue(BB, X);
    if (!V)
      return false;
    // We've constructed a concrete value for the covering value. Expand and
    // collect the newly created forwardable values.
    MemLocationList Locs;
    LoadStoreValueList Vals;
    MemLocation::expandWithValues(X, V, &BB->getModule(), Locs, Vals);
    for (unsigned i = 0; i < Locs.size(); ++i) {
      Values[Locs[i]] = Vals[i];
      assert(Values[Locs[i]].isValid() && "Invalid load store value");
    }
  }

// Sanity check to make sure we have valid load store values for each
// MemLocation.
#ifndef NDEBUG
  for (auto &X : Locs) {
    (void)X;
    assert(Values[X].isValid() && "Invalid load store value");
  }
#endif
  return true;
}
Esempio n. 2
0
void MemLocation::reduce(MemLocation &Base, SILModule *Mod,
                         MemLocationSet &Locs) {
  // First, construct the MemLocation by appending the projection path from the
  // accessed node to the leaf nodes.
  MemLocationList ALocs;
  ProjectionPathList Paths;
  ProjectionPath::expandTypeIntoLeafProjectionPaths(Base.getType(), Mod, Paths,
                                                    false);
  for (auto &X : Paths) {
    ALocs.push_back(MemLocation::createMemLocation(Base.getBase(), X.getValue(),
                                                   Base.getPath().getValue()));
  }

  // 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) {
    MemLocationList FirstLevel;
    I->getFirstLevelMemLocations(FirstLevel, Mod);
    // 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) {
      if (Locs.find(X) != Locs.end())
        continue;
      Alive = false;
    }

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