@@ -1025,25 +1025,34 @@ end
1025
1025
1026
1026
# ## from abstractarray.jl
1027
1027
1028
- # In the common case where we have two views into the same parent, aliasing checks
1029
- # are _much_ easier and more important to get right
1030
- function mightalias (A:: SubArray{T,<:Any,P} , B:: SubArray{T,<:Any,P} ) where {T,P}
1031
- if ! _parentsmatch (A. parent, B. parent)
1032
- # We cannot do any better than the usual dataids check
1033
- return ! _isdisjoint (dataids (A), dataids (B))
1034
- end
1035
- # Now we know that A.parent === B.parent. This means that the indices of A
1036
- # and B are the same length and indexing into the same dimensions. We can
1037
- # just walk through them and check for overlaps: O(ndims(A)). We must finally
1038
- # ensure that the indices don't alias with either parent
1039
- return _indicesmightoverlap (A. indices, B. indices) ||
1040
- ! _isdisjoint (dataids (A. parent), _splatmap (dataids, B. indices)) ||
1041
- ! _isdisjoint (dataids (B. parent), _splatmap (dataids, A. indices))
1028
+ function mightalias (A:: SubArray , B:: SubArray )
1029
+ # There are three ways that SubArrays might _problematically_ alias one another:
1030
+ # 1. The parents are the same we can conservatively check if the indices might overlap OR
1031
+ # 2. The parents alias eachother in a more complicated manner (and we can't trace indices) OR
1032
+ # 3. One's parent is used in the other's indices
1033
+ # Note that it's ok for just the indices to alias each other as those should not be mutated,
1034
+ # so we can always do better than the default !_isdisjoint(dataids(A), dataids(B))
1035
+ if isbits (A. parent) || isbits (B. parent)
1036
+ return false # Quick out for immutables
1037
+ elseif _parentsmatch (A. parent, B. parent)
1038
+ # Each SubArray unaliases its own parent from its own indices upon construction, so if
1039
+ # the two parents are the same, then by construction one cannot alias the other's indices
1040
+ # and therefore this is the only test we need to perform:
1041
+ return _indicesmightoverlap (A. indices, B. indices)
1042
+ else
1043
+ A_parent_ids = dataids (A. parent)
1044
+ B_parent_ids = dataids (B. parent)
1045
+ return ! _isdisjoint (A_parent_ids, B_parent_ids) ||
1046
+ ! _isdisjoint (A_parent_ids, _splatmap (dataids, B. indices)) ||
1047
+ ! _isdisjoint (B_parent_ids, _splatmap (dataids, A. indices))
1048
+ end
1042
1049
end
1050
+ # Test if two arrays are backed by exactly the same memory in exactly the same order
1043
1051
_parentsmatch (A:: AbstractArray , B:: AbstractArray ) = A === B
1044
- # Two reshape(::Array)s of the same size aren't `===` because they have different headers
1045
- _parentsmatch (A:: Array , B:: Array ) = pointer (A) == pointer (B) && size (A) == size (B)
1052
+ _parentsmatch (A :: DenseArray , B :: DenseArray ) = elsize (A) == elsize (B) && pointer (A) == pointer (B) && size (A) == size (B)
1053
+ _parentsmatch (A:: StridedArray , B:: StridedArray ) = elsize (A) == elsize (B) && pointer (A) == pointer (B) && strides (A) == strides (B)
1046
1054
1055
+ # Given two SubArrays with the same parent, check if the indices might overlap (returning true if unsure)
1047
1056
_indicesmightoverlap (A:: Tuple{} , B:: Tuple{} ) = true
1048
1057
_indicesmightoverlap (A:: Tuple{} , B:: Tuple ) = error (" malformed subarray" )
1049
1058
_indicesmightoverlap (A:: Tuple , B:: Tuple{} ) = error (" malformed subarray" )
0 commit comments