@@ -48,12 +48,21 @@ static llvm::cl::opt<bool>
4848 llvm::cl::Hidden,
4949 llvm::cl::desc(" Add TBAA tags to local allocations." ));
5050
51+ // Engineering option to triage TBAA tags attachment for accesses
52+ // of allocatable entities.
53+ static llvm::cl::opt<unsigned > localAllocsThreshold (
54+ " local-alloc-tbaa-threshold" , llvm::cl::init(0 ), llvm::cl::ReallyHidden,
55+ llvm::cl::desc(" If present, stops generating TBAA tags for accesses of "
56+ " local allocations after N accesses in a module" ));
57+
5158namespace {
5259
5360// / Shared state per-module
5461class PassState {
5562public:
56- PassState (mlir::DominanceInfo &domInfo) : domInfo(domInfo) {}
63+ PassState (mlir::DominanceInfo &domInfo,
64+ std::optional<unsigned > localAllocsThreshold)
65+ : domInfo(domInfo), localAllocsThreshold(localAllocsThreshold) {}
5766 // / memoised call to fir::AliasAnalysis::getSource
5867 inline const fir::AliasAnalysis::Source &getSource (mlir::Value value) {
5968 if (!analysisCache.contains (value))
@@ -84,6 +93,11 @@ class PassState {
8493 // (e.g. !fir.ref<!fir.type<Derived{f:!fir.box<!fir.heap<f32>>}>>).
8594 bool typeReferencesDescriptor (mlir::Type type);
8695
96+ // Returns true if we can attach a TBAA tag to an access of an allocatable
97+ // entities. It checks if localAllocsThreshold allows the next tag
98+ // attachment.
99+ bool attachLocalAllocTag ();
100+
87101private:
88102 mlir::DominanceInfo &domInfo;
89103 fir::AliasAnalysis analysis;
@@ -103,6 +117,8 @@ class PassState {
103117 // Local pass cache for derived types that contain descriptor
104118 // member(s), to avoid the cost of isRecordWithDescriptorMember().
105119 llvm::DenseSet<mlir::Type> typesContainingDescriptors;
120+
121+ std::optional<unsigned > localAllocsThreshold;
106122};
107123
108124// Process fir.dummy_scope operations in the given func:
@@ -169,6 +185,19 @@ bool PassState::typeReferencesDescriptor(mlir::Type type) {
169185 return false ;
170186}
171187
188+ bool PassState::attachLocalAllocTag () {
189+ if (!localAllocsThreshold)
190+ return true ;
191+ if (*localAllocsThreshold == 0 ) {
192+ LLVM_DEBUG (llvm::dbgs ().indent (2 )
193+ << " WARN: not assigning TBAA tag for an allocated entity access "
194+ " due to the threshold\n " );
195+ return false ;
196+ }
197+ --*localAllocsThreshold;
198+ return true ;
199+ }
200+
172201class AddAliasTagsPass : public fir ::impl::AddAliasTagsBase<AddAliasTagsPass> {
173202public:
174203 void runOnOperation () override ;
@@ -335,16 +364,16 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
335364 LLVM_DEBUG (llvm::dbgs ().indent (2 )
336365 << " WARN: unknown defining op for SourceKind::Allocate " << *op
337366 << " \n " );
338- } else if (source.isPointer ()) {
367+ } else if (source.isPointer () && state. attachLocalAllocTag () ) {
339368 LLVM_DEBUG (llvm::dbgs ().indent (2 )
340369 << " Found reference to allocation at " << *op << " \n " );
341370 tag = state.getFuncTreeWithScope (func, scopeOp).targetDataTree .getTag ();
342- } else if (name) {
371+ } else if (name && state. attachLocalAllocTag () ) {
343372 LLVM_DEBUG (llvm::dbgs ().indent (2 ) << " Found reference to allocation "
344373 << name << " at " << *op << " \n " );
345374 tag = state.getFuncTreeWithScope (func, scopeOp)
346375 .allocatedDataTree .getTag (*name);
347- } else {
376+ } else if (state. attachLocalAllocTag ()) {
348377 LLVM_DEBUG (llvm::dbgs ().indent (2 )
349378 << " WARN: couldn't find a name for allocation " << *op
350379 << " \n " );
@@ -372,7 +401,9 @@ void AddAliasTagsPass::runOnOperation() {
372401 // thinks the pass operates on), then the real work of the pass is done in
373402 // runOnAliasInterface
374403 auto &domInfo = getAnalysis<mlir::DominanceInfo>();
375- PassState state (domInfo);
404+ PassState state (domInfo, localAllocsThreshold.getPosition ()
405+ ? std::optional<unsigned >(localAllocsThreshold)
406+ : std::nullopt );
376407
377408 mlir::ModuleOp mod = getOperation ();
378409 mod.walk (
0 commit comments