Commits

Arnold Schwaighofer committed d6cd798de26
stdlib: Add array.props.isNative/needsElementTypeCheck calls This enables high-level SIL optimizations to speculatively specialize loops into 'fast native swift array' loops vs standard array loops. This commits adds two semantic calls to Arrays.swift. @semantics("array.props.isNative") func _getArrayPropertyIsNative() -> Bool @semantics("array.props.needsElementTypeCheck") func _getArrayPropertyNeedsElementTypeCheck() -> Bool checkSubscript and getElement get extra arguments to pass in the result of above function calls. This also allow us to communicate that an array that was made mutable is always native. The array subscript getter is changed to use the result of these new calls: public subscript(index: Int) -> Element { get { let isNative = _getArrayPropertyIsNative() let needsTypeCheck = _getArrayPropertyNeedsElementTypeCheck() _checkSubscript(index, isNative) return _getElement(index, isNative, needsTypeCheck) } mutableAddressWithPinnedNativeOwner { _makeMutableAndUniqueOrPinned() // When an array was made mutable we know it is a backed by a native // array buffer. _checkSubscript(index, true) return (_getElementAddress(index), Builtin.tryPin(Builtin.castToNativeObject(_buffer.owner))) } } High-level SIL optimizations will now see a loop like this: func f(inout a : A[AClass]) { for i in 0..a.count { let b = a.props.isNative() .. += _getElement(a, i, b) } } After proving that ‘a’ does not escape other than to known safe functions, the optimizer hoists the array property calls out of the loop in a loop versioned on the array property. func f(inout a : A[AClass]) { let b2 = a.props.isNative() if (!b2) { for i in 0..a.count { .. += _getElement(a, i, false) } } else { for i in 0..a.count { let b = a.props.isNative .. += _getElement(a, i, b) } } } rdar://17955309 Swift SVN r25698