Skip to content
Open
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
6 changes: 6 additions & 0 deletions llvm/include/llvm/Analysis/DependenceAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,12 @@ class DependenceInfo {
Function *F;
SmallVector<const SCEVPredicate *, 4> Assumptions;

/// Cache for delinearized subscripts to avoid recomputation.
/// Maps (Instruction, Loop, AccessFn) -> Subscripts
DenseMap<std::tuple<Instruction *, Loop *, const SCEV *>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the key need to be a tuple? Wouldn't Instruction * or const SCEV * be sufficient?

SmallVector<const SCEV *, 4>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
SmallVector<const SCEV *, 4>>
SmallVector<const SCEV *, 1>>

Consider a smaller SmallVector, maybe even SmallVector<const SCEV *, 0>. DenseMap only uses a fraction of its entries, big item and key objects waste a lot of space.

DelinearizationCache;

/// Subscript - This private struct represents a pair of subscripts from
/// a pair of potentially multi-dimensional array references. We use a
/// vector of them to guide subscript partitioning.
Expand Down
36 changes: 31 additions & 5 deletions llvm/lib/Analysis/DependenceAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3463,11 +3463,37 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,

SmallVector<const SCEV *, 4> SrcSubscripts, DstSubscripts;

if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
SrcSubscripts, DstSubscripts) &&
!tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
SrcSubscripts, DstSubscripts))
return false;
// Check cache for both Src and Dst subscripts
auto SrcCacheKey = std::make_tuple(Src, SrcLoop, SrcAccessFn);
auto DstCacheKey = std::make_tuple(Dst, DstLoop, DstAccessFn);
auto SrcCacheIt = DelinearizationCache.find(SrcCacheKey);
auto DstCacheIt = DelinearizationCache.find(DstCacheKey);
Comment on lines +3469 to +3470
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using try_emplace to avoid repeated hash lookup.

bool SrcCached = (SrcCacheIt != DelinearizationCache.end());
bool DstCached = (DstCacheIt != DelinearizationCache.end());

if (SrcCached && DstCached) {
// Both are cached - use cached values and skip delinearization
SrcSubscripts = SrcCacheIt->second;
DstSubscripts = DstCacheIt->second;
LLVM_DEBUG(dbgs() << " Delinearization cache hit for both Src and Dst\n");
} else {
// At least one is not cached - need to compute both
if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
SrcSubscripts, DstSubscripts) &&
!tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
SrcSubscripts, DstSubscripts))
return false;

// Cache the results
if (!SrcCached) {
DelinearizationCache[SrcCacheKey] = SrcSubscripts;
LLVM_DEBUG(dbgs() << " Cached Src subscripts\n");
}
if (!DstCached) {
DelinearizationCache[DstCacheKey] = DstSubscripts;
LLVM_DEBUG(dbgs() << " Cached Dst subscripts\n");
}
}
Comment on lines +3466 to +3496
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider refactoring into a function for lookup.

Src and Dst computation need to be disentangled or looked up together. tryDelinearizeFixedSize implementes a consistency check, eg. that both have the same dimensions. This isn't guaranteed of they are looked up independently.


assert(isLoopInvariant(SrcBase, SrcLoop) &&
isLoopInvariant(DstBase, DstLoop) &&
Expand Down