22#define TRITON_ANALYSIS_BUFFER_REGION_H
33
44#include < cstdint>
5+ #include < memory>
56#include < optional>
67#include < set>
78#include < tuple>
1920#include " llvm/ADT/SparseBitVector.h"
2021#include " llvm/ADT/UniqueVector.h"
2122
23+ namespace mlir {
24+ class Allocation ;
25+ class ModuleAllocation ;
26+ } // namespace mlir
27+
2228namespace mlir ::triton::gpu {
2329enum class SharedKind : uint32_t ;
2430}
@@ -121,11 +127,8 @@ struct BufferRegionView {
121127 uint32_t affineCTAOffset = 0 ;
122128 // / Deterministically interned identity of the owning allocation frame.
123129 uint32_t allocationFrame = 0 ;
124-
125- bool intersects (const BufferRegionView &other) const {
126- return allocationFrame == other.allocationFrame &&
127- region.intersects (other.region );
128- }
130+ // / Descriptor allocation supplying these views; null for implicit scratch.
131+ Operation *allocation = nullptr ;
129132
130133 bool contains (const BufferRegionView &other) const {
131134 return allocationFrame == other.allocationFrame &&
@@ -138,7 +141,8 @@ struct BufferRegionView {
138141private:
139142 auto key () const {
140143 return std::tie (allocationFrame, region, storageBase, affineOffset,
141- affinePartitionOffset, affineCTAOffset, partitionBases);
144+ affinePartitionOffset, affineCTAOffset, partitionBases,
145+ allocation);
142146 }
143147
144148public:
@@ -151,9 +155,6 @@ struct BufferRegionView {
151155 }
152156};
153157
154- // / An exact access view, or no view when the physical region is unknown.
155- using BufferRegionAccess = std::optional<BufferRegionView>;
156-
157158// ===----------------------------------------------------------------------===//
158159// Buffer state planning
159160// ===----------------------------------------------------------------------===//
@@ -223,6 +224,20 @@ struct RegionInfo {
223224 }
224225};
225226
227+ // / Complete MAY-views of a descriptor, shared by all of its memory effects.
228+ // / Runtime indices may select several physical views across loop iterations.
229+ // / Addresses, rather than runtime descriptor keys, define the geometry; the
230+ // / memory space distinguishes shared bytes from TMEM's 32-bit storage words.
231+ struct BufferRegionFootprint {
232+ Attribute memorySpace;
233+ RegionInfo regionInfo;
234+ };
235+
236+ // / Prove disjointness only if every candidate pair is disjoint. Missing views
237+ // / and unnormalized allocation frames may overlap, never denote empty storage.
238+ bool mayOverlap (const BufferRegionFootprint *lhs,
239+ const BufferRegionFootprint *rhs);
240+
226241enum class RW { Read, Write };
227242
228243struct MemoryAccess {
@@ -250,6 +265,7 @@ bool hasSharedAccess(Operation *op,
250265//
251266// Produces a RegionInfo lattice for each MemDesc/ptr-like SSA value,
252267// and also collects a global list of all discovered BufferRegions.
268+ // Requires completed allocation analyses or their materialized offsets.
253269//
254270class BufferRegionAnalysis : public dataflow ::SparseForwardDataFlowAnalysis<
255271 dataflow::Lattice<RegionInfo>> {
@@ -258,23 +274,37 @@ class BufferRegionAnalysis : public dataflow::SparseForwardDataFlowAnalysis<
258274 using Base =
259275 dataflow::SparseForwardDataFlowAnalysis<dataflow::Lattice<RegionInfo>>;
260276 using Base::getLatticeElement;
261- using Base::SparseForwardDataFlowAnalysis;
277+ enum class Mode { AllMemory, TensorMemoryOnly };
278+
279+ explicit BufferRegionAnalysis (DataFlowSolver &solver,
280+ Mode mode = Mode::AllMemory,
281+ ModuleAllocation *allocation = nullptr )
282+ : Base(solver), mode(mode), moduleAllocation(allocation) {}
262283
263284 enum RegionType { SHARED_MEMORY , TENSOR_MEMORY , BARRIER , NUM_REGION_TYPES };
264285
265286 const RegionInfo &getRegionInfo (Value value) {
266287 return getLatticeElement (value)->getValue ();
267288 }
268289
269- // / Return every exact view an access may reference. A null view represents
270- // / an unknown region and therefore may alias any other view.
271- llvm::SmallVector<BufferRegionAccess> getAccessRegions (Value value);
290+ // / Return an immutable footprint covering every possible view, owned by this
291+ // / analysis. Call after solver convergence. Return null for unknown geometry
292+ // / or views outside allocationFrame, when set.
293+ const BufferRegionFootprint *
294+ getFootprint (Value value, FunctionOpInterface allocationFrame = {});
295+
296+ // / Describe an operation's allocated shared scratch, including cross-CTA
297+ // / accesses.
298+ const BufferRegionFootprint *getScratchFootprint (Operation *op);
272299
273- // / Translate a callee-local view into the caller's allocation frame.
274- BufferRegionAccess translateToCallsite (BufferRegionAccess view,
275- CallOpInterface call,
276- FunctionOpInterface caller,
277- FunctionOpInterface callee) const ;
300+ // / Translate callee-local views into the caller's allocation frame, caching
301+ // / the complete footprint and preserving views already in other frames.
302+ const BufferRegionFootprint *
303+ translateToCallsite (const BufferRegionFootprint *footprint,
304+ CallOpInterface call, FunctionOpInterface callee);
305+
306+ // / Shared-memory offset of the callee frame in the caller's allocation.
307+ uint32_t getCallOffset (CallOpInterface call) const ;
278308
279309 uint32_t getOperationId (Operation *operation) const {
280310 return operationInterner.idFor (operation);
@@ -313,6 +343,11 @@ class BufferRegionAnalysis : public dataflow::SparseForwardDataFlowAnalysis<
313343 LogicalResult initialize (Operation *top) override ;
314344
315345private:
346+ const Mode mode;
347+ ModuleAllocation *moduleAllocation;
348+
349+ Allocation *getAllocation (Operation *op) const ;
350+
316351 BufferRegionView getAllocView (Value allocation, uint32_t storageBase,
317352 llvm::ArrayRef<uint32_t > partitionBases = {});
318353 BufferRegionView getSubView (Type type, const BufferRegionView &view,
@@ -323,7 +358,15 @@ class BufferRegionAnalysis : public dataflow::SparseForwardDataFlowAnalysis<
323358 // Global registry of all regions
324359 std::set<BufferRegion> usedBufferRegions[NUM_REGION_TYPES ];
325360 bool usedUnknownBufferRegions[NUM_REGION_TYPES ] = {};
326- llvm::DenseMap<std::pair<Type, uint32_t >, AddressSet> footprintCache;
361+ llvm::DenseMap<std::pair<Type, uint32_t >,
362+ llvm::SmallVector<BufferRegion::CTAAddresses, 2 >>
363+ footprintCache;
364+ llvm::DenseMap<Value, std::unique_ptr<BufferRegionFootprint>> valueFootprints;
365+ llvm::DenseMap<Operation *, std::unique_ptr<BufferRegionFootprint>>
366+ scratchFootprints;
367+ llvm::DenseMap<std::pair<const BufferRegionFootprint *, Operation *>,
368+ std::unique_ptr<BufferRegionFootprint>>
369+ callsiteFootprints;
327370 llvm::UniqueVector<Operation *> operationInterner;
328371};
329372
0 commit comments