Skip to content

Commit

Permalink
Rename reduceWithValues to LSValue::reduce
Browse files Browse the repository at this point in the history
  • Loading branch information
trentxintong committed Dec 13, 2015
1 parent 75f5c77 commit 3b62b2f
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 108 deletions.
32 changes: 19 additions & 13 deletions include/swift/SIL/SILValueProjection.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ using ValueTableMap = llvm::SmallMapVector<unsigned, unsigned, 8>;
/// SILValue through a SILArgument.
///
/// Given a set of LSLocations and their available LSValues,
/// reduceWithValues will create the forwarding SILValue by merging them while
/// reduce will create the forwarding SILValue by merging them while
/// creating as few value extraction and aggregation as possible.
///
/// NOTE: ProjectionPath in LSValue could be replaced by the
Expand Down Expand Up @@ -358,6 +358,24 @@ class LSValue : public SILValueProjection {
static void expand(SILValue Base, SILModule *Mod, LSValueList &Vals,
TypeExpansionAnalysis *TE);

/// Given a memory location and a map between the expansions of the location
/// and their corresponding values, try to come up with a single SILValue this
/// location holds. This may involve extracting and aggregating available
/// values.
///
/// NOTE: reduce assumes that every component of the location has an concrete
/// (i.e. not coverings set) available value in LocAndVal.
///
/// TODO: we do not really need the llvm::DenseMap<LSLocation, LSValue> here
/// we only need a map between the projection tree of a SILType and the value
/// each leaf node takes. This will be implemented once ProjectionPath memory
/// cost is reduced and made copyable (its copy constructor is deleted at the
/// momemt).
static SILValue reduce(LSLocation &Base, SILModule *Mod,
LSLocationValueMap &LocAndVal,
SILInstruction *InsertPt,
TypeExpansionAnalysis *TE);

/// Enumerate the given LSValue.
static void enumerateLSValue(SILModule *M, SILValue Val,
std::vector<LSValue> &Vault,
Expand Down Expand Up @@ -494,18 +512,6 @@ class LSLocation : public SILValueProjection {
static void reduce(LSLocation &Base, SILModule *Mod, LSLocationSet &Locs,
TypeExpansionAnalysis *TE);

/// Given a memory location and a map between the expansions of the location
/// and their corresponding values, try to come up with a single SILValue this
/// location holds. This may involve extracting and aggregating available
/// values.
///
/// NOTE: reduceValues assumes that every component of the location has an
/// concrete (i.e. not coverings set) available value in LocAndVal.
static SILValue reduceWithValues(LSLocation &Base, SILModule *Mod,
LSLocationValueMap &LocAndVal,
SILInstruction *InsertPt,
TypeExpansionAnalysis *TE);

/// Enumerate the given Mem LSLocation.
static void enumerateLSLocation(SILModule *M, SILValue Mem,
std::vector<LSLocation> &LSLocationVault,
Expand Down
184 changes: 93 additions & 91 deletions lib/SIL/SILValueProjection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,99 @@ void LSValue::expand(SILValue Base, SILModule *M, LSValueList &Vals,
}
}

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.
//
// If there are more than 1 children and all the children nodes have
// LSValues with the same base. 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;
auto Iter = FirstLevel.begin();
LSValue &FirstVal = Values[*Iter];
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 (HasIdenticalValueBase &&
(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;
}

// In 2 cases do we need aggregation.
//
// 1. If there is only 1 child and we can not strip off any projections,
// that means we need to create an aggregation.
//
// 2. 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);
NullablePtr<swift::SILInstruction> AI =
Projection::createAggFromFirstLevelProjections(
Builder, InsertPt->getLoc(), 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);
}


void LSValue::enumerateLSValue(SILModule *M, SILValue Val,
std::vector<LSValue> &Vault,
LSValueIndexMap &ValToBit,
Expand Down Expand Up @@ -217,97 +310,6 @@ void LSLocation::reduce(LSLocation &Base, SILModule *M, LSLocationSet &Locs,
}
}

SILValue LSLocation::reduceWithValues(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.
//
// If there are more than 1 children and all the children nodes have
// LSValues with the same base. 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;
auto Iter = FirstLevel.begin();
LSValue &FirstVal = Values[*Iter];
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 (HasIdenticalValueBase &&
(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;
}

// In 2 cases do we need aggregation.
//
// 1. If there is only 1 child and we can not strip off any projections,
// that means we need to create an aggregation.
//
// 2. 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);
NullablePtr<swift::SILInstruction> AI =
Projection::createAggFromFirstLevelProjections(
Builder, InsertPt->getLoc(), 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);
}

void LSLocation::enumerateLSLocation(SILModule *M, SILValue Mem,
std::vector<LSLocation> &LV,
Expand Down
7 changes: 3 additions & 4 deletions lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,8 @@ SILValue BlockState::computeForwardingValues(RLEContext &Ctx, LSLocation &L,
// Second, reduce the available values into a single SILValue we can use to
// forward.
SILValue TheForwardingValue;
TheForwardingValue = LSLocation::reduceWithValues(
L, &ParentBB->getModule(), Values, InsertPt, Ctx.getTE());
TheForwardingValue = LSValue::reduce(L, &ParentBB->getModule(), Values,
InsertPt, Ctx.getTE());
/// Return the forwarding value.
return TheForwardingValue;
}
Expand All @@ -453,8 +453,7 @@ bool BlockState::setupRLE(RLEContext &Ctx, SILInstruction *I, SILValue Mem) {
// Reduce the available values into a single SILValue we can use to forward.
SILModule *Mod = &I->getModule();
SILValue TheForwardingValue;
TheForwardingValue =
LSLocation::reduceWithValues(L, Mod, Values, I, Ctx.getTE());
TheForwardingValue = LSValue::reduce(L, Mod, Values, I, Ctx.getTE());
if (!TheForwardingValue)
return false;

Expand Down

0 comments on commit 3b62b2f

Please sign in to comment.