Skip to content

Commit 0f0628b

Browse files
committed
[MLIR][Mem2Reg] Change API to always retry promotion after changes
This commit modifies the Mem2Reg's API to always attempt a full promotion on all the passed in "allocators". This ensures that the pass does not require unnecessary walks over the regions and improves caching benefits.
1 parent a551272 commit 0f0628b

File tree

2 files changed

+39
-29
lines changed

2 files changed

+39
-29
lines changed

mlir/include/mlir/Transforms/Mem2Reg.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#ifndef MLIR_TRANSFORMS_MEM2REG_H
1010
#define MLIR_TRANSFORMS_MEM2REG_H
1111

12-
#include "mlir/IR/PatternMatch.h"
1312
#include "mlir/Interfaces/MemorySlotInterfaces.h"
1413
#include "llvm/ADT/Statistic.h"
1514

@@ -23,8 +22,9 @@ struct Mem2RegStatistics {
2322
llvm::Statistic *newBlockArgumentAmount = nullptr;
2423
};
2524

26-
/// Attempts to promote the memory slots of the provided allocators. Succeeds if
27-
/// at least one memory slot was promoted.
25+
/// Attempts to promote the memory slots of the provided allocators. Iteratively
26+
/// retries the promotion of all slots as promoting one slot might enable
27+
/// subsequent promotions. Succeeds if at least one memory slot was promoted.
2828
LogicalResult
2929
tryToPromoteMemorySlots(ArrayRef<PromotableAllocationOpInterface> allocators,
3030
OpBuilder &builder, const DataLayout &dataLayout,

mlir/lib/Transforms/Mem2Reg.cpp

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -636,20 +636,36 @@ LogicalResult mlir::tryToPromoteMemorySlots(
636636
// lazily and cached to avoid expensive recomputation.
637637
BlockIndexCache blockIndexCache;
638638

639-
for (PromotableAllocationOpInterface allocator : allocators) {
640-
for (MemorySlot slot : allocator.getPromotableSlots()) {
641-
if (slot.ptr.use_empty())
642-
continue;
643-
644-
MemorySlotPromotionAnalyzer analyzer(slot, dominance, dataLayout);
645-
std::optional<MemorySlotPromotionInfo> info = analyzer.computeInfo();
646-
if (info) {
647-
MemorySlotPromoter(slot, allocator, builder, dominance, dataLayout,
648-
std::move(*info), statistics, blockIndexCache)
649-
.promoteSlot();
650-
promotedAny = true;
639+
SmallVector<PromotableAllocationOpInterface> workList(allocators.begin(),
640+
allocators.end());
641+
642+
SmallVector<PromotableAllocationOpInterface> newWorkList;
643+
newWorkList.reserve(workList.size());
644+
while (true) {
645+
for (PromotableAllocationOpInterface allocator : workList) {
646+
for (MemorySlot slot : allocator.getPromotableSlots()) {
647+
if (slot.ptr.use_empty())
648+
continue;
649+
650+
MemorySlotPromotionAnalyzer analyzer(slot, dominance, dataLayout);
651+
std::optional<MemorySlotPromotionInfo> info = analyzer.computeInfo();
652+
if (info) {
653+
MemorySlotPromoter(slot, allocator, builder, dominance, dataLayout,
654+
std::move(*info), statistics, blockIndexCache)
655+
.promoteSlot();
656+
promotedAny = true;
657+
continue;
658+
}
659+
newWorkList.push_back(allocator);
651660
}
652661
}
662+
if (workList.size() == newWorkList.size())
663+
break;
664+
665+
// Swap the vector's backing memory and clear the entries in newWorkList
666+
// afterwards. This ensures that additional heap allocations can be avoided.
667+
workList.swap(newWorkList);
668+
newWorkList.clear();
653669
}
654670

655671
return success(promotedAny);
@@ -677,22 +693,16 @@ struct Mem2Reg : impl::Mem2RegBase<Mem2Reg> {
677693

678694
OpBuilder builder(&region.front(), region.front().begin());
679695

680-
// Promoting a slot can allow for further promotion of other slots,
681-
// promotion is tried until no promotion succeeds.
682-
while (true) {
683-
SmallVector<PromotableAllocationOpInterface> allocators;
684-
// Build a list of allocators to attempt to promote the slots of.
685-
region.walk([&](PromotableAllocationOpInterface allocator) {
686-
allocators.emplace_back(allocator);
687-
});
688-
689-
// Attempt promoting until no promotion succeeds.
690-
if (failed(tryToPromoteMemorySlots(allocators, builder, dataLayout,
691-
dominance, statistics)))
692-
break;
696+
SmallVector<PromotableAllocationOpInterface> allocators;
697+
// Build a list of allocators to attempt to promote the slots of.
698+
region.walk([&](PromotableAllocationOpInterface allocator) {
699+
allocators.emplace_back(allocator);
700+
});
693701

702+
// Attempt promoting as many of the slots as possible.
703+
if (succeeded(tryToPromoteMemorySlots(allocators, builder, dataLayout,
704+
dominance, statistics)))
694705
changed = true;
695-
}
696706
}
697707
if (!changed)
698708
markAllAnalysesPreserved();

0 commit comments

Comments
 (0)