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; }
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; }
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); } } }