mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SILOptimizer: Pipe through TypeExpansionContext
This commit is contained in:
@@ -31,10 +31,9 @@ removeLSLocations(LSLocationValueMap &Values, LSLocationList &NextLevel) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LSValue
|
||||
//===----------------------------------------------------------------------===//
|
||||
void
|
||||
LSValue::expand(SILValue Base, SILModule *M, LSValueList &Vals,
|
||||
TypeExpansionAnalysis *TE) {
|
||||
for (const auto &P : TE->getTypeExpansion((*Base).getType(), M)) {
|
||||
void LSValue::expand(SILValue Base, SILModule *M, TypeExpansionContext context,
|
||||
LSValueList &Vals, TypeExpansionAnalysis *TE) {
|
||||
for (const auto &P : TE->getTypeExpansion((*Base).getType(), M, context)) {
|
||||
Vals.push_back(LSValue(Base, P.getValue()));
|
||||
}
|
||||
}
|
||||
@@ -42,18 +41,20 @@ LSValue::expand(SILValue Base, SILModule *M, LSValueList &Vals,
|
||||
void
|
||||
LSValue::reduceInner(LSLocation &Base, SILModule *M, LSLocationValueMap &Values,
|
||||
SILInstruction *InsertPt) {
|
||||
TypeExpansionContext context(*InsertPt->getFunction());
|
||||
|
||||
// If this is a class reference type, we have reached end of the type tree.
|
||||
if (Base.getType(M).getClassOrBoundGenericClass())
|
||||
if (Base.getType(M, context).getClassOrBoundGenericClass())
|
||||
return;
|
||||
|
||||
// This a don't expand node.
|
||||
if (!shouldExpand(*M, Base.getType(M))) {
|
||||
if (!shouldExpand(*M, Base.getType(M, context))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a leaf node, we must have a value for it.
|
||||
LSLocationList NextLevel;
|
||||
Base.getNextLevelLSLocations(NextLevel, M);
|
||||
Base.getNextLevelLSLocations(NextLevel, M, context);
|
||||
if (NextLevel.empty())
|
||||
return;
|
||||
|
||||
@@ -117,11 +118,10 @@ LSValue::reduceInner(LSLocation &Base, SILModule *M, LSLocationValueMap &Values,
|
||||
NullablePtr<swift::SingleValueInstruction> AI =
|
||||
Projection::createAggFromFirstLevelProjections(
|
||||
Builder, RegularLocation::getAutoGeneratedLocation(),
|
||||
Base.getType(M).getObjectType(),
|
||||
Vals);
|
||||
Base.getType(M, context).getObjectType(), Vals);
|
||||
|
||||
// This is the Value for the current base.
|
||||
ProjectionPath P(Base.getType(M));
|
||||
ProjectionPath P(Base.getType(M, context));
|
||||
Values[Base] = LSValue(SILValue(AI.get()), P);
|
||||
removeLSLocations(Values, NextLevel);
|
||||
}
|
||||
@@ -163,11 +163,11 @@ LSLocation::isMayAliasLSLocation(const LSLocation &RHS, AliasAnalysis *AA) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LSLocation::getNextLevelLSLocations(LSLocationList &Locs, SILModule *Mod) {
|
||||
SILType Ty = getType(Mod);
|
||||
void LSLocation::getNextLevelLSLocations(LSLocationList &Locs, SILModule *Mod,
|
||||
TypeExpansionContext context) {
|
||||
SILType Ty = getType(Mod, context);
|
||||
llvm::SmallVector<Projection, 8> Out;
|
||||
Projection::getFirstLevelProjections(Ty, *Mod, Out);
|
||||
Projection::getFirstLevelProjections(Ty, *Mod, context, Out);
|
||||
for (auto &X : Out) {
|
||||
ProjectionPath P((*Base).getType());
|
||||
P.append(Path.getValue());
|
||||
@@ -176,22 +176,23 @@ LSLocation::getNextLevelLSLocations(LSLocationList &Locs, SILModule *Mod) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LSLocation::expand(LSLocation Base, SILModule *M, LSLocationList &Locs,
|
||||
TypeExpansionAnalysis *TE) {
|
||||
void LSLocation::expand(LSLocation Base, SILModule *M,
|
||||
TypeExpansionContext context, LSLocationList &Locs,
|
||||
TypeExpansionAnalysis *TE) {
|
||||
const ProjectionPath &BasePath = Base.getPath().getValue();
|
||||
for (const auto &P : TE->getTypeExpansion(Base.getType(M), M)) {
|
||||
for (const auto &P :
|
||||
TE->getTypeExpansion(Base.getType(M, context), M, context)) {
|
||||
Locs.push_back(LSLocation(Base.getBase(), BasePath, P.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the sub-locations of \p Base in \p SubLocations.
|
||||
/// Returns false if this is not possible or too complex.
|
||||
static bool
|
||||
getSubLocations(LSLocationList &SubLocations, LSLocation Base, SILModule *M,
|
||||
const LSLocationList &Locs) {
|
||||
static bool getSubLocations(LSLocationList &SubLocations, LSLocation Base,
|
||||
SILModule *M, TypeExpansionContext context,
|
||||
const LSLocationList &Locs) {
|
||||
// If this is a class reference type, we have reached end of the type tree.
|
||||
if (Base.getType(M).getClassOrBoundGenericClass())
|
||||
if (Base.getType(M, context).getClassOrBoundGenericClass())
|
||||
return false;
|
||||
|
||||
// Don't expand if it would be too complex. As Locs is a list (and not a set)
|
||||
@@ -199,27 +200,28 @@ getSubLocations(LSLocationList &SubLocations, LSLocation Base, SILModule *M,
|
||||
// Usually Locs is small anyway, because we limit expansion to 6 members.
|
||||
// But with deeply nested types we could run in a corner case where Locs is
|
||||
// large.
|
||||
if (!shouldExpand(*M, Base.getType(M)) || Locs.size() >= 8) {
|
||||
if (!shouldExpand(*M, Base.getType(M, context)) || Locs.size() >= 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is a leaf node.
|
||||
Base.getNextLevelLSLocations(SubLocations, M);
|
||||
Base.getNextLevelLSLocations(SubLocations, M, context);
|
||||
return !SubLocations.empty();
|
||||
}
|
||||
|
||||
/// Replaces \p SubLocations with \p Base in \p Locs if all sub-locations are
|
||||
/// alive, i.e. present in \p Locs.
|
||||
static bool
|
||||
replaceSubLocations(LSLocation Base, SILModule *M, LSLocationList &Locs,
|
||||
const LSLocationList &SubLocations) {
|
||||
static bool replaceSubLocations(LSLocation Base, SILModule *M,
|
||||
TypeExpansionContext context,
|
||||
LSLocationList &Locs,
|
||||
const LSLocationList &SubLocations) {
|
||||
// Find whether all its children of Base are alive.
|
||||
bool Alive = true;
|
||||
for (auto &X : SubLocations) {
|
||||
// Recurse into the next level.
|
||||
LSLocationList NextInnerLevel;
|
||||
if (getSubLocations(NextInnerLevel, X, M, Locs)) {
|
||||
Alive &= replaceSubLocations(X, M, Locs, NextInnerLevel);
|
||||
if (getSubLocations(NextInnerLevel, X, M, context, Locs)) {
|
||||
Alive &= replaceSubLocations(X, M, context, Locs, NextInnerLevel);
|
||||
} else {
|
||||
Alive &= is_contained(Locs, X);
|
||||
}
|
||||
@@ -237,18 +239,19 @@ replaceSubLocations(LSLocation Base, SILModule *M, LSLocationList &Locs,
|
||||
return true;
|
||||
}
|
||||
|
||||
void LSLocation::reduce(LSLocation Base, SILModule *M, LSLocationList &Locs) {
|
||||
void LSLocation::reduce(LSLocation Base, SILModule *M,
|
||||
TypeExpansionContext context, LSLocationList &Locs) {
|
||||
LSLocationList SubLocations;
|
||||
if (getSubLocations(SubLocations, Base, M, Locs))
|
||||
replaceSubLocations(Base, M, Locs, SubLocations);
|
||||
if (getSubLocations(SubLocations, Base, M, context, Locs))
|
||||
replaceSubLocations(Base, M, context, Locs, SubLocations);
|
||||
}
|
||||
|
||||
void
|
||||
LSLocation::enumerateLSLocation(SILModule *M, SILValue Mem,
|
||||
std::vector<LSLocation> &Locations,
|
||||
LSLocationIndexMap &IndexMap,
|
||||
LSLocationBaseMap &BaseMap,
|
||||
TypeExpansionAnalysis *TypeCache) {
|
||||
void LSLocation::enumerateLSLocation(TypeExpansionContext context, SILModule *M,
|
||||
SILValue Mem,
|
||||
std::vector<LSLocation> &Locations,
|
||||
LSLocationIndexMap &IndexMap,
|
||||
LSLocationBaseMap &BaseMap,
|
||||
TypeExpansionAnalysis *TypeCache) {
|
||||
// We have processed this SILValue before.
|
||||
if (BaseMap.find(Mem) != BaseMap.end())
|
||||
return;
|
||||
@@ -272,7 +275,7 @@ LSLocation::enumerateLSLocation(SILModule *M, SILValue Mem,
|
||||
// Expand the given Mem into individual fields and add them to the
|
||||
// locationvault.
|
||||
LSLocationList Locs;
|
||||
LSLocation::expand(L, M, Locs, TypeCache);
|
||||
LSLocation::expand(L, M, context, Locs, TypeCache);
|
||||
for (auto &Loc : Locs) {
|
||||
if (IndexMap.find(Loc) != IndexMap.end())
|
||||
continue;
|
||||
@@ -292,14 +295,16 @@ LSLocation::enumerateLSLocations(SILFunction &F,
|
||||
for (auto &B : F) {
|
||||
for (auto &I : B) {
|
||||
if (auto *LI = dyn_cast<LoadInst>(&I)) {
|
||||
enumerateLSLocation(&I.getModule(), LI->getOperand(), Locations,
|
||||
IndexMap, BaseMap, TypeCache);
|
||||
enumerateLSLocation(F.getTypeExpansionContext(), &I.getModule(),
|
||||
LI->getOperand(), Locations, IndexMap, BaseMap,
|
||||
TypeCache);
|
||||
++LSCount.first;
|
||||
continue;
|
||||
}
|
||||
if (auto *SI = dyn_cast<StoreInst>(&I)) {
|
||||
enumerateLSLocation(&I.getModule(), SI->getDest(), Locations,
|
||||
IndexMap, BaseMap, TypeCache);
|
||||
enumerateLSLocation(F.getTypeExpansionContext(), &I.getModule(),
|
||||
SI->getDest(), Locations, IndexMap, BaseMap,
|
||||
TypeCache);
|
||||
++LSCount.second;
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user