@@ -1923,6 +1923,110 @@ bool AccessPath::collectUses(SmallVectorImpl<Operand *> &uses,
1923
1923
return visitAccessPathUses (collector, *this , function);
1924
1924
}
1925
1925
1926
+ // ===----------------------------------------------------------------------===//
1927
+ // MARK: UniqueStorageUseVisitor
1928
+ // ===----------------------------------------------------------------------===//
1929
+
1930
+ struct GatherUniqueStorageUses : public AccessUseVisitor {
1931
+ UniqueStorageUseVisitor &visitor;
1932
+
1933
+ GatherUniqueStorageUses (UniqueStorageUseVisitor &visitor)
1934
+ : AccessUseVisitor(AccessUseType::Overlapping,
1935
+ NestedAccessType::IgnoreAccessBegin),
1936
+ visitor (visitor) {}
1937
+
1938
+ bool visitUse (Operand *use, AccessUseType useTy) override ;
1939
+ };
1940
+
1941
+ bool UniqueStorageUseVisitor::findUses (UniqueStorageUseVisitor &visitor) {
1942
+ assert (visitor.storage .isUniquelyIdentified ());
1943
+
1944
+ GatherUniqueStorageUses gather (visitor);
1945
+ return visitAccessStorageUses (gather, visitor.storage , visitor.function );
1946
+ }
1947
+
1948
+ bool GatherUniqueStorageUses::visitUse (Operand *use, AccessUseType useTy) {
1949
+ unsigned operIdx = use->getOperandNumber ();
1950
+ auto *user = use->getUser ();
1951
+ assert (!user->isTypeDependentOperand (*use));
1952
+
1953
+ // TODO: handle non-escaping partial-applies just like a full apply. The
1954
+ // address uses are the points where the partial apply is invoked.
1955
+ if (FullApplySite apply = FullApplySite::isa (user)) {
1956
+ switch (apply.getArgumentConvention (*use)) {
1957
+ case SILArgumentConvention::Indirect_Inout:
1958
+ case SILArgumentConvention::Indirect_InoutAliasable:
1959
+ case SILArgumentConvention::Indirect_Out:
1960
+ visitor.visitStore (use);
1961
+ break ;
1962
+ case SILArgumentConvention::Indirect_In_Guaranteed:
1963
+ case SILArgumentConvention::Indirect_In:
1964
+ case SILArgumentConvention::Indirect_In_Constant:
1965
+ visitor.visitLoad (use);
1966
+ break ;
1967
+ case SILArgumentConvention::Direct_Unowned:
1968
+ case SILArgumentConvention::Direct_Owned:
1969
+ case SILArgumentConvention::Direct_Guaranteed:
1970
+ // most likely an escape of a box
1971
+ visitor.visitUnknownUse (use);
1972
+ break ;
1973
+ }
1974
+ return true ;
1975
+ }
1976
+ switch (user->getKind ()) {
1977
+ case SILInstructionKind::DestroyAddrInst:
1978
+ case SILInstructionKind::DestroyValueInst:
1979
+ if (useTy == AccessUseType::Exact) {
1980
+ visitor.visitDestroy (use);
1981
+ return true ;
1982
+ }
1983
+ visitor.visitUnknownUse (use);
1984
+ return true ;
1985
+
1986
+ case SILInstructionKind::DebugValueInst:
1987
+ visitor.visitDebugUse (use);
1988
+ return true ;
1989
+
1990
+ case SILInstructionKind::LoadInst:
1991
+ case SILInstructionKind::LoadWeakInst:
1992
+ case SILInstructionKind::LoadUnownedInst:
1993
+ case SILInstructionKind::ExistentialMetatypeInst:
1994
+ visitor.visitLoad (use);
1995
+ return true ;
1996
+
1997
+ case SILInstructionKind::StoreInst:
1998
+ case SILInstructionKind::StoreWeakInst:
1999
+ case SILInstructionKind::StoreUnownedInst:
2000
+ if (operIdx == CopyLikeInstruction::Dest) {
2001
+ visitor.visitStore (use);
2002
+ return true ;
2003
+ }
2004
+ break ;
2005
+
2006
+ case SILInstructionKind::InjectEnumAddrInst:
2007
+ visitor.visitStore (use);
2008
+ return true ;
2009
+
2010
+ case SILInstructionKind::CopyAddrInst:
2011
+ if (operIdx == CopyLikeInstruction::Dest) {
2012
+ visitor.visitStore (use);
2013
+ return true ;
2014
+ }
2015
+ assert (operIdx == CopyLikeInstruction::Src);
2016
+ visitor.visitLoad (use);
2017
+ return true ;
2018
+
2019
+ case SILInstructionKind::DeallocStackInst:
2020
+ visitor.visitDealloc (use);
2021
+ return true ;
2022
+
2023
+ default :
2024
+ break ;
2025
+ }
2026
+ visitor.visitUnknownUse (use);
2027
+ return true ;
2028
+ }
2029
+
1926
2030
// ===----------------------------------------------------------------------===//
1927
2031
// MARK: Helper API for specific formal access patterns
1928
2032
// ===----------------------------------------------------------------------===//
0 commit comments