Skip to content

Revert "[LoadStoreVectorizer] Postprocess and merge equivalence classes" #119657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 0 additions & 123 deletions llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,6 @@ class Vectorizer {
Instruction *ChainElem, Instruction *ChainBegin,
const DenseMap<Instruction *, APInt /*OffsetFromLeader*/> &ChainOffsets);

/// Merges the equivalence classes if they have underlying objects that differ
/// by one level of indirection (i.e., one is a getelementptr and the other is
/// the base pointer in that getelementptr).
void mergeEquivalenceClasses(EquivalenceClassMap &EQClasses) const;

/// Collects loads and stores grouped by "equivalence class", where:
/// - all elements in an eq class are a load or all are a store,
/// - they all load/store the same element size (it's OK to have e.g. i8 and
Expand Down Expand Up @@ -1310,123 +1305,6 @@ std::optional<APInt> Vectorizer::getConstantOffsetSelects(
return std::nullopt;
}

void Vectorizer::mergeEquivalenceClasses(EquivalenceClassMap &EQClasses) const {
if (EQClasses.size() < 2) // There is nothing to merge.
return;

// The reduced key has all elements of the ECClassKey except the underlying
// object. Check that EqClassKey has 4 elements and define the reduced key.
static_assert(std::tuple_size_v<EqClassKey> == 4,
"EqClassKey has changed - EqClassReducedKey needs changes too");
using EqClassReducedKey =
std::tuple<std::tuple_element_t<1, EqClassKey> /* AddrSpace */,
std::tuple_element_t<2, EqClassKey> /* Element size */,
std::tuple_element_t<3, EqClassKey> /* IsLoad; */>;
using ECReducedKeyToUnderlyingObjectMap =
MapVector<EqClassReducedKey,
SmallPtrSet<std::tuple_element_t<0, EqClassKey>, 4>>;

// Form a map from the reduced key (without the underlying object) to the
// underlying objects: 1 reduced key to many underlying objects, to form
// groups of potentially merge-able equivalence classes.
ECReducedKeyToUnderlyingObjectMap RedKeyToUOMap;
bool FoundPotentiallyOptimizableEC = false;
for (const auto &EC : EQClasses) {
const auto &Key = EC.first;
EqClassReducedKey RedKey{std::get<1>(Key), std::get<2>(Key),
std::get<3>(Key)};
RedKeyToUOMap[RedKey].insert(std::get<0>(Key));
if (RedKeyToUOMap[RedKey].size() > 1)
FoundPotentiallyOptimizableEC = true;
}
if (!FoundPotentiallyOptimizableEC)
return;

LLVM_DEBUG({
dbgs() << "LSV: mergeEquivalenceClasses: before merging:\n";
for (const auto &EC : EQClasses) {
dbgs() << " Key: ([" << std::get<0>(EC.first)
<< "]: " << *std::get<0>(EC.first) << ", " << std::get<1>(EC.first)
<< ", " << std::get<2>(EC.first) << ", "
<< static_cast<int>(std::get<3>(EC.first)) << ")\n";
for (const auto &Inst : EC.second)
dbgs() << "\tInst: " << *Inst << '\n';
}
});
LLVM_DEBUG({
dbgs() << "LSV: mergeEquivalenceClasses: RedKeyToUOMap:\n";
for (const auto &RedKeyToUO : RedKeyToUOMap) {
dbgs() << " Reduced key: (" << std::get<0>(RedKeyToUO.first) << ", "
<< std::get<1>(RedKeyToUO.first) << ", "
<< static_cast<int>(std::get<2>(RedKeyToUO.first)) << ") --> "
<< RedKeyToUO.second.size() << " underlying objects:\n";
for (auto UObject : RedKeyToUO.second)
dbgs() << " [" << UObject << "]: " << *UObject << '\n';
}
});

using UObjectToUObjectMap = DenseMap<const Value *, const Value *>;

// Compute the ultimate targets for a set of underlying objects.
auto GetUltimateTargets =
[](SmallPtrSetImpl<const Value *> &UObjects) -> UObjectToUObjectMap {
UObjectToUObjectMap IndirectionMap;
for (const auto *UObject : UObjects) {
const unsigned MaxLookupDepth = 1; // look for 1-level indirections only
const auto *UltimateTarget = getUnderlyingObject(UObject, MaxLookupDepth);
if (UltimateTarget != UObject)
IndirectionMap[UObject] = UltimateTarget;
}
UObjectToUObjectMap UltimateTargetsMap;
for (const auto *UObject : UObjects) {
auto Target = UObject;
auto It = IndirectionMap.find(Target);
for (; It != IndirectionMap.end(); It = IndirectionMap.find(Target))
Target = It->second;
UltimateTargetsMap[UObject] = Target;
}
return UltimateTargetsMap;
};

// For each item in RedKeyToUOMap, if it has more than one underlying object,
// try to merge the equivalence classes.
for (auto &[RedKey, UObjects] : RedKeyToUOMap) {
if (UObjects.size() < 2)
continue;
auto UTMap = GetUltimateTargets(UObjects);
for (const auto &[UObject, UltimateTarget] : UTMap) {
if (UObject == UltimateTarget)
continue;

EqClassKey KeyFrom{UObject, std::get<0>(RedKey), std::get<1>(RedKey),
std::get<2>(RedKey)};
EqClassKey KeyTo{UltimateTarget, std::get<0>(RedKey), std::get<1>(RedKey),
std::get<2>(RedKey)};
const auto &VecFrom = EQClasses[KeyFrom];
const auto &VecTo = EQClasses[KeyTo];
SmallVector<Instruction *, 8> MergedVec;
std::merge(VecFrom.begin(), VecFrom.end(), VecTo.begin(), VecTo.end(),
std::back_inserter(MergedVec),
[](Instruction *A, Instruction *B) {
return A && B && A->comesBefore(B);
});
EQClasses[KeyTo] = std::move(MergedVec);
EQClasses.erase(KeyFrom);
}
}
LLVM_DEBUG({
dbgs() << "LSV: mergeEquivalenceClasses: after merging:\n";
for (const auto &EC : EQClasses) {
dbgs() << " Key: ([" << std::get<0>(EC.first)
<< "]: " << *std::get<0>(EC.first) << ", " << std::get<1>(EC.first)
<< ", " << std::get<2>(EC.first) << ", "
<< static_cast<int>(std::get<3>(EC.first)) << ")\n";
for (const auto &Inst : EC.second)
dbgs() << "\tInst: " << *Inst << '\n';
}
});
}

EquivalenceClassMap
Vectorizer::collectEquivalenceClasses(BasicBlock::iterator Begin,
BasicBlock::iterator End) {
Expand Down Expand Up @@ -1499,7 +1377,6 @@ Vectorizer::collectEquivalenceClasses(BasicBlock::iterator Begin,
.emplace_back(&I);
}

mergeEquivalenceClasses(Ret);
return Ret;
}

Expand Down
142 changes: 0 additions & 142 deletions llvm/test/Transforms/LoadStoreVectorizer/X86/massive_indirection.ll

This file was deleted.

Loading