@@ -263,12 +263,29 @@ class PassState {
263263 IntervalTy interval;
264264 };
265265
266- const StorageDesc *getStorageDesc (mlir::Operation *op) {
266+ // Fills in declToStorageMap on the first invocation.
267+ // Returns a storage descriptor for the given op (if registered
268+ // in declToStorageMap).
269+ const StorageDesc *computeStorageDesc (mlir::Operation *op) {
270+ if (!op)
271+ return nullptr ;
272+
273+ // TODO: it should be safe to run collectPhysicalStorageAliasSets()
274+ // on the parent func.func instead of the module, since the TBAA
275+ // tags use different roots per function. This may provide better
276+ // results for storages that have members with descriptors
277+ // in one function but not the others.
278+ if (!declToStorageMapComputed)
279+ collectPhysicalStorageAliasSets (op->getParentOfType <mlir::ModuleOp>());
280+ return getStorageDesc (op);
281+ }
282+
283+ private:
284+ const StorageDesc *getStorageDesc (mlir::Operation *op) const {
267285 auto it = declToStorageMap.find (op);
268286 return it == declToStorageMap.end () ? nullptr : &it->second ;
269287 }
270288
271- private:
272289 StorageDesc &getMutableStorageDesc (mlir::Operation *op) {
273290 auto it = declToStorageMap.find (op);
274291 assert (it != declToStorageMap.end ());
@@ -303,6 +320,9 @@ class PassState {
303320 // A map between fir::FortranVariableStorageOpInterface operations
304321 // and their storage descriptors.
305322 llvm::DenseMap<mlir::Operation *, StorageDesc> declToStorageMap;
323+ // declToStorageMapComputed is set to true after declToStorageMap
324+ // is initialized by collectPhysicalStorageAliasSets().
325+ bool declToStorageMapComputed = false ;
306326};
307327
308328// Process fir.dummy_scope operations in the given func:
@@ -468,6 +488,9 @@ void PassState::collectPhysicalStorageAliasSets(mlir::Operation *op) {
468488 return mlir::WalkResult::advance ();
469489 });
470490
491+ // Mark the map as computed before any early exits below.
492+ declToStorageMapComputed = true ;
493+
471494 if (seenUnknownStorage && seenDeclWithDescriptor) {
472495 declToStorageMap.clear ();
473496 return ;
@@ -703,7 +726,7 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
703726 mlir::dyn_cast_or_null<fir::FortranVariableStorageOpInterface>(
704727 instantiationPoint);
705728 const PassState::StorageDesc *storageDesc =
706- state.getStorageDesc (instantiationPoint);
729+ state.computeStorageDesc (instantiationPoint);
707730
708731 if (storageDesc) {
709732 // This is a variable that is part of a known physical storage
@@ -834,8 +857,6 @@ void AddAliasTagsPass::runOnOperation() {
834857 ? std::optional<unsigned >(localAllocsThreshold)
835858 : std::nullopt );
836859
837- state.collectPhysicalStorageAliasSets (module );
838-
839860 module .walk (
840861 [&](fir::FirAliasTagOpInterface op) { runOnAliasInterface (op, state); });
841862
0 commit comments