Skip to content

Commit

Permalink
Merge pull request #14386 from xwu/no-mixing
Browse files Browse the repository at this point in the history
[stdlib/Sema] Minor improvements to synthesized hashValue
  • Loading branch information
xwu authored Feb 5, 2018
2 parents 77e417f + 8014793 commit 5b4e3f2
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 22 deletions.
30 changes: 10 additions & 20 deletions lib/Sema/DerivedConformanceEquatableHashable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) {
for (auto elt : enumDecl->getAllElements()) {
// case .<elt>(let a0, let a1, ...):
SmallVector<VarDecl*, 3> payloadVars;
SmallVector<ASTNode, 3> mixExpressions;
SmallVector<ASTNode, 3> combineExprs;

auto payloadPattern = enumElementPayloadSubpattern(elt, 'a', hashValueDecl,
payloadVars);
Expand All @@ -863,7 +863,7 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) {
/*implicit*/ true);
auto assignExpr = new (C) AssignExpr(resultRef, SourceLoc(),
ordinalExpr, /*implicit*/ true);
mixExpressions.emplace_back(ASTNode(assignExpr));
combineExprs.emplace_back(ASTNode(assignExpr));
}

if (!hasNoAssociatedValues) {
Expand All @@ -873,18 +873,14 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) {
auto payloadVarRef = new (C) DeclRefExpr(payloadVar, DeclNameLoc(),
/*implicit*/ true);
// result = _combineHashValues(result, <payloadVar>.hashValue)
auto mixExpr = combineHashValuesAssignmentExpr(C, resultVar,
payloadVarRef);
mixExpressions.emplace_back(ASTNode(mixExpr));
auto combineExpr = combineHashValuesAssignmentExpr(C, resultVar,
payloadVarRef);
combineExprs.emplace_back(ASTNode(combineExpr));
}

// result = _mixInt(result)
auto assignExpr = mixIntAssignmentExpr(C, resultVar);
mixExpressions.emplace_back(ASTNode(assignExpr));
}

auto hasBoundDecls = !payloadVars.empty();
auto body = BraceStmt::create(C, SourceLoc(), mixExpressions, SourceLoc());
auto body = BraceStmt::create(C, SourceLoc(), combineExprs, SourceLoc());
cases.push_back(CaseStmt::create(C, SourceLoc(), labelItem, hasBoundDecls,
SourceLoc(), body));
}
Expand Down Expand Up @@ -963,16 +959,12 @@ deriveBodyHashable_struct_hashValue(AbstractFunctionDecl *hashValueDecl) {
auto selfPropertyExpr = new (C) DotSyntaxCallExpr(propertyRef, SourceLoc(),
selfRef);
// result = _combineHashValues(result, <property>.hashValue)
auto mixExpr = combineHashValuesAssignmentExpr(C, resultVar,
selfPropertyExpr);
statements.emplace_back(ASTNode(mixExpr));
auto combineExpr = combineHashValuesAssignmentExpr(C, resultVar,
selfPropertyExpr);
statements.emplace_back(ASTNode(combineExpr));
}

{
// result = _mixInt(result)
auto assignExpr = mixIntAssignmentExpr(C, resultVar);
statements.push_back(assignExpr);

// return result
auto resultRef = new (C) DeclRefExpr(resultVar, DeclNameLoc(),
/*implicit*/ true,
Expand Down Expand Up @@ -1021,7 +1013,6 @@ deriveHashable_hashValue(TypeChecker &tc, Decl *parentDecl,
// result = _combineHashValues(result, a0.hashValue)
// result = _combineHashValues(result, a1.hashValue)
// }
// result = _mixInt(result)
// return result
// }
// }
Expand All @@ -1030,10 +1021,9 @@ deriveHashable_hashValue(TypeChecker &tc, Decl *parentDecl,
// var x: Int
// var y: String
// @derived var hashValue: Int {
// var result: Int = 0
// var result = 0
// result = _combineHashValues(result, x.hashValue)
// result = _combineHashValues(result, y.hashValue)
// result = _mixInt(result)
// return result
// }
// }
Expand Down
1 change: 0 additions & 1 deletion stdlib/public/core/DoubleWidth.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ extension DoubleWidth : Hashable {
var result = 0
result = _combineHashValues(result, _storage.high.hashValue)
result = _combineHashValues(result, _storage.low.hashValue)
result = _mixInt(result)
return result
}
}
Expand Down
8 changes: 7 additions & 1 deletion stdlib/public/core/Hashing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,13 @@ func _squeezeHashValue(_ hashValue: Int, _ upperBound: Int) -> Int {
@_transparent
public // @testable
func _combineHashValues(_ firstValue: Int, _ secondValue: Int) -> Int {
let magic = 0x9e3779b9 as UInt // Based on the golden ratio.
// Use a magic number based on the golden ratio
// (0x1.9e3779b97f4a7c15f39cc0605cedc8341082276bf3a27251f86c6a11d0c18e95p0).
#if arch(i386) || arch(arm)
let magic = 0x9e3779b9 as UInt
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
let magic = 0x9e3779b97f4a7c15 as UInt
#endif
var x = UInt(bitPattern: firstValue)
x ^= UInt(bitPattern: secondValue) &+ magic &+ (x &<< 6) &+ (x &>> 2)
return Int(bitPattern: x)
Expand Down

0 comments on commit 5b4e3f2

Please sign in to comment.