mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This function mixes the bits in the hash value, which improves Dictionary performance for keys with bad hashes. PrecommitBenchmark changes with greater than 7% difference: ``````````Dictionary2`,```1456.00`,```1508.00`,```1502.00`,````624.00`,````607.00`,````592.00`,`864.00`,``145.9% ``````````Dictionary3`,```1379.00`,```1439.00`,```1408.00`,````585.00`,````567.00`,````552.00`,`827.00`,``149.8% ````````````Histogram`,````850.00`,````849.00`,````851.00`,```1053.00`,```1049.00`,```1048.00`,`199.00`,``-19.0% ````````````````Prims`,```1999.00`,```2005.00`,```2018.00`,```1734.00`,```1689.00`,```1701.00`,`310.00`,```18.4% ``````````StrSplitter`,```2365.00`,```2334.00`,```2316.00`,```1979.00`,```1997.00`,```2000.00`,`337.00`,```17.0% ```````````````TwoSum`,```1551.00`,```1568.00`,```1556.00`,```1771.00`,```1741.00`,```1716.00`,`165.00`,```-9.6% Regressions are in benchmarks that use `Int` as dictionary key: we are just doing more work than previously (hashing an `Int` was an identity function). rdar://17962402 Swift SVN r21142
161 lines
5.0 KiB
Swift
161 lines
5.0 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Definitions that make elements of Builtin usable in real
|
|
// code without gobs of boilerplate. These APIs will probably *not*
|
|
// be exposed outside the stdlib.
|
|
|
|
@transparent public
|
|
func sizeof<T>(_:T.Type) -> Int {
|
|
return Int(Builtin.sizeof(T.self))
|
|
}
|
|
|
|
@transparent public
|
|
func sizeofValue<T>(_:T) -> Int {
|
|
return sizeof(T.self)
|
|
}
|
|
|
|
@transparent public
|
|
func alignof<T>(_:T.Type) -> Int {
|
|
return Int(Builtin.alignof(T.self))
|
|
}
|
|
|
|
@transparent public
|
|
func alignofValue<T>(_:T) -> Int {
|
|
return alignof(T.self)
|
|
}
|
|
|
|
// Like the builtin strideof, but never returns zero
|
|
@transparent public
|
|
func strideof<T>(_:T.Type) -> Int {
|
|
return Int(Builtin.strideof_nonzero(T.self))
|
|
}
|
|
|
|
@transparent public
|
|
func strideofValue<T>(_:T) -> Int {
|
|
return strideof(T.self)
|
|
}
|
|
|
|
func _roundUpToAlignment(offset: Int, alignment: Int) -> Int {
|
|
_sanityCheck(offset >= 0)
|
|
_sanityCheck(alignment > 0)
|
|
_sanityCheck(_isPowerOf2(alignment))
|
|
// Note, given that offset is >= 0, and alignment > 0, we don't
|
|
// need to underflow check the -1, as it can never underflow.
|
|
let x = (offset + alignment &- 1)
|
|
// Note, as alignment is a power of 2, we'll use masking to efficiently
|
|
// get the aligned value
|
|
return x & ~(alignment &- 1)
|
|
}
|
|
|
|
@transparent
|
|
func _canBeClass<T>(_: T.Type) -> Bool {
|
|
return Bool(Builtin.canBeClass(T.self))
|
|
}
|
|
|
|
@availability(*,unavailable,message="it has been renamed 'unsafeBitCast' and has acquired an explicit target type parameter")
|
|
@transparent public
|
|
func reinterpretCast<T, U>(var x: T) -> U {
|
|
_precondition(sizeof(T.self) == sizeof(U.self),
|
|
"can't reinterpretCast values of different sizes")
|
|
return UnsafeMutablePointer<U>(Builtin.addressof(&x)).memory
|
|
}
|
|
|
|
/// A brutal bit-cast of something to anything of the same size
|
|
@transparent public
|
|
func unsafeBitCast<T, U>(var x: T, _: U.Type) -> U {
|
|
_precondition(sizeof(T.self) == sizeof(U.self),
|
|
"can't unsafeBitCast between types of different sizes")
|
|
return UnsafeMutablePointer<U>(Builtin.addressof(&x)).memory
|
|
}
|
|
|
|
/// `unsafeBitCast` something to `AnyObject`
|
|
@transparent public
|
|
func _reinterpretCastToAnyObject<T>(x: T) -> AnyObject {
|
|
return unsafeBitCast(x, AnyObject.self)
|
|
}
|
|
|
|
@transparent
|
|
func ==(lhs: Builtin.NativeObject, rhs: Builtin.NativeObject) -> Bool {
|
|
return unsafeBitCast(lhs, Int.self) == unsafeBitCast(rhs, Int.self)
|
|
}
|
|
|
|
@transparent
|
|
func !=(lhs: Builtin.NativeObject, rhs: Builtin.NativeObject) -> Bool {
|
|
return !(lhs == rhs)
|
|
}
|
|
|
|
@transparent
|
|
func ==(lhs: Builtin.RawPointer, rhs: Builtin.RawPointer) -> Bool {
|
|
return unsafeBitCast(lhs, Int.self) == unsafeBitCast(rhs, Int.self)
|
|
}
|
|
|
|
@transparent
|
|
func !=(lhs: Builtin.RawPointer, rhs: Builtin.RawPointer) -> Bool {
|
|
return !(lhs == rhs)
|
|
}
|
|
|
|
/// Tell the optimizer that this code is unreachable if condition is
|
|
/// known at compile-time to be true. If condition is false, or true
|
|
/// but not a compile-time constant, this call has no effect.
|
|
@transparent internal
|
|
func _unreachable(condition: Bool = true) {
|
|
if condition {
|
|
// FIXME: use a parameterized version of Builtin.unreachable when
|
|
// <rdar://problem/16806232> is closed.
|
|
Builtin.unreachable()
|
|
}
|
|
}
|
|
|
|
/// Tell the optimizer that this code is unreachable if this builtin is
|
|
/// reachable after constant folding build configuration builtins.
|
|
@transparent @noreturn internal
|
|
func _conditionallyUnreachable() {
|
|
Builtin.conditionallyUnreachable()
|
|
}
|
|
|
|
@asmname("swift_isClassOrObjCExistential")
|
|
func _swift_isClassOrObjCExistential<T>(x: T.Type) -> Bool
|
|
|
|
/// Returns true iff T is a class type or an @objc existential such as
|
|
/// AnyObject
|
|
internal func _isClassOrObjCExistential<T>(x: T.Type) -> Bool {
|
|
return _canBeClass(x)
|
|
// FIXME: Dirty hack; see <rdar://problem/16823238>
|
|
&& sizeof(x) == sizeof(AnyObject)
|
|
&& _swift_isClassOrObjCExistential(x)
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Branch hints
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Use @semantics to indicate that the optimizer recognizes the
|
|
// semantics of these function calls. This won't be necessary with
|
|
// mandatory generic inlining.
|
|
|
|
@transparent @semantics("branchhint") internal
|
|
func _branchHint<C: BooleanType>(actual: C, expected: Bool) -> Bool {
|
|
return Bool(Builtin.int_expect_Int1(actual.boolValue.value, expected.value))
|
|
}
|
|
|
|
@transparent @semantics("fastpath") public
|
|
func _fastPath<C: BooleanType>(x: C) -> Bool {
|
|
return _branchHint(x.boolValue, true)
|
|
}
|
|
|
|
@transparent @semantics("slowpath") public
|
|
func _slowPath<C: BooleanType>(x: C) -> Bool {
|
|
return _branchHint(x.boolValue, false)
|
|
}
|
|
|