Skip to content

Commit ad7a387

Browse files
committed
[NFC] Extract common code for keying off of APInts
1 parent 89c2fa3 commit ad7a387

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

include/swift/Basic/APIntMap.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===--- APIntMap.h - A map with APInts as the keys -------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// LLVM does not allow arbitrary APInts to be the keys of a DenseMap because
14+
// APInts are only comparable if they have the same bit-width. This map
15+
// implementation assumes that its keys will always be constrained to their
16+
// minimum width, so it's not a general-purpose structure, but it does work.
17+
//
18+
//===----------------------------------------------------------------------===//
19+
20+
#ifndef SWIFT_BASIC_APINTMAP_H
21+
#define SWIFT_BASIC_APINTMAP_H
22+
23+
#include "llvm/ADT/APInt.h"
24+
#include "llvm/ADT/DenseMap.h"
25+
#include "swift/Basic/LLVM.h"
26+
27+
namespace swift {
28+
29+
struct WidthPreservingAPIntDenseMapInfo {
30+
// For the special values, we use -1 with a bit-width that isn't minimal
31+
// for the value, then use a parser that always produces values with
32+
// minimal bit-widths so that we don't get a conflict.
33+
static inline APInt getEmptyKey() {
34+
return APInt::getAllOnesValue(/*bitwidth*/2);
35+
}
36+
static inline APInt getTombstoneKey() {
37+
return APInt::getAllOnesValue(/*bitwidth*/3);
38+
}
39+
40+
static unsigned getHashValue(const APInt &Key) {
41+
return static_cast<unsigned>(hash_value(Key));
42+
}
43+
44+
static bool isEqual(const APInt &LHS, const APInt &RHS) {
45+
return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
46+
}
47+
};
48+
49+
template <class Value>
50+
using APIntMap = llvm::DenseMap<APInt, Value, WidthPreservingAPIntDenseMapInfo>;
51+
52+
}
53+
54+
#endif

lib/Sema/TypeCheckSwitchStmt.cpp

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "swift/AST/Pattern.h"
2121
#include "swift/Basic/STLExtras.h"
2222

23-
#include <llvm/ADT/APInt.h>
23+
#include "swift/Basic/APIntMap.h"
2424
#include <llvm/ADT/APFloat.h>
2525

2626
#include <numeric>
@@ -31,22 +31,6 @@ using namespace swift;
3131
#define DEBUG_TYPE "TypeCheckSwitchStmt"
3232

3333
namespace {
34-
struct DenseMapAPIntKeyInfo {
35-
static inline APInt getEmptyKey() { return APInt(); }
36-
37-
static inline APInt getTombstoneKey() {
38-
return APInt::getAllOnesValue(/*bitwidth*/1);
39-
}
40-
41-
static unsigned getHashValue(const APInt &Key) {
42-
return static_cast<unsigned>(hash_value(Key));
43-
}
44-
45-
static bool isEqual(const APInt &LHS, const APInt &RHS) {
46-
return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
47-
}
48-
};
49-
5034
struct DenseMapAPFloatKeyInfo {
5135
static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
5236
static inline APFloat getTombstoneKey() { return APFloat(APFloat::Bogus(), 2); }
@@ -858,7 +842,7 @@ namespace {
858842
TypeChecker &TC;
859843
const SwitchStmt *Switch;
860844
const DeclContext *DC;
861-
llvm::DenseMap<APInt, Expr *, ::DenseMapAPIntKeyInfo> IntLiteralCache;
845+
APIntMap<Expr *> IntLiteralCache;
862846
llvm::DenseMap<APFloat, Expr *, ::DenseMapAPFloatKeyInfo> FloatLiteralCache;
863847
llvm::DenseMap<StringRef, Expr *> StringLiteralCache;
864848

0 commit comments

Comments
 (0)