Skip to content

Commit 1c9b77e

Browse files
authored
Merge pull request #61566 from hamishknight/countdown
2 parents 649f09f + b4d4137 commit 1c9b77e

File tree

8 files changed

+260
-101
lines changed

8 files changed

+260
-101
lines changed

include/swift/SIL/SILProfiler.h

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -31,6 +31,53 @@ class SILCoverageMap;
3131
class SILFunction;
3232
class SILModule;
3333

34+
/// A reference to a given profiler counter.
35+
class ProfileCounterRef final {
36+
public:
37+
enum class Kind : uint8_t {
38+
/// References an ASTNode.
39+
// TODO: This is the currently the only kind, but it will be expanded in
40+
// the future for e.g top-level entry and error branches.
41+
Node
42+
};
43+
44+
private:
45+
friend struct llvm::DenseMapInfo<ProfileCounterRef>;
46+
47+
ASTNode Node;
48+
Kind RefKind;
49+
50+
ProfileCounterRef(ASTNode node, Kind kind) : Node(node), RefKind(kind) {}
51+
52+
public:
53+
/// A profile counter that is associated with a given ASTNode.
54+
static ProfileCounterRef node(ASTNode node) {
55+
assert(node && "Must have non-null ASTNode");
56+
return ProfileCounterRef(node, Kind::Node);
57+
}
58+
59+
/// Retrieve the corresponding location of the counter.
60+
SILLocation getLocation() const;
61+
62+
SWIFT_DEBUG_DUMP;
63+
void dump(raw_ostream &OS) const;
64+
65+
/// A simpler dump output for inline printing.
66+
void dumpSimple(raw_ostream &OS) const;
67+
68+
friend bool operator==(const ProfileCounterRef &lhs,
69+
const ProfileCounterRef &rhs) {
70+
return lhs.Node == rhs.Node && lhs.RefKind == rhs.RefKind;
71+
}
72+
friend bool operator!=(const ProfileCounterRef &lhs,
73+
const ProfileCounterRef &rhs) {
74+
return !(lhs == rhs);
75+
}
76+
friend llvm::hash_code hash_value(const ProfileCounterRef &ref) {
77+
return llvm::hash_combine(ref.Node, ref.RefKind);
78+
}
79+
};
80+
3481
/// SILProfiler - Maps AST nodes to profile counters.
3582
class SILProfiler : public SILAllocated<SILProfiler> {
3683
private:
@@ -52,9 +99,9 @@ class SILProfiler : public SILAllocated<SILProfiler> {
5299

53100
unsigned NumRegionCounters = 0;
54101

55-
llvm::DenseMap<ASTNode, unsigned> RegionCounterMap;
102+
llvm::DenseMap<ProfileCounterRef, unsigned> RegionCounterMap;
56103

57-
llvm::DenseMap<ASTNode, ProfileCounter> RegionLoadedCounterMap;
104+
llvm::DenseMap<ProfileCounterRef, ProfileCounter> RegionLoadedCounterMap;
58105

59106
llvm::DenseMap<ASTNode, ASTNode> RegionCondToParentMap;
60107

@@ -71,6 +118,10 @@ class SILProfiler : public SILAllocated<SILProfiler> {
71118
/// Check if the function is set up for profiling.
72119
bool hasRegionCounters() const { return NumRegionCounters != 0; }
73120

121+
/// Get the execution count corresponding to \p Ref from a profile, if one
122+
/// is available.
123+
ProfileCounter getExecutionCount(ProfileCounterRef Ref);
124+
74125
/// Get the execution count corresponding to \p Node from a profile, if one
75126
/// is available.
76127
ProfileCounter getExecutionCount(ASTNode Node);
@@ -88,8 +139,10 @@ class SILProfiler : public SILAllocated<SILProfiler> {
88139
/// Get the number of region counters.
89140
unsigned getNumRegionCounters() const { return NumRegionCounters; }
90141

91-
/// Get the mapping from \c ASTNode to its corresponding profile counter.
92-
const llvm::DenseMap<ASTNode, unsigned> &getRegionCounterMap() const {
142+
/// Get the mapping from a \c ProfileCounterRef to its corresponding
143+
/// profile counter.
144+
const llvm::DenseMap<ProfileCounterRef, unsigned> &
145+
getRegionCounterMap() const {
93146
return RegionCounterMap;
94147
}
95148

@@ -100,4 +153,27 @@ class SILProfiler : public SILAllocated<SILProfiler> {
100153

101154
} // end namespace swift
102155

156+
namespace llvm {
157+
using swift::ProfileCounterRef;
158+
using swift::ASTNode;
159+
160+
template <> struct DenseMapInfo<ProfileCounterRef> {
161+
static inline ProfileCounterRef getEmptyKey() {
162+
return ProfileCounterRef(DenseMapInfo<ASTNode>::getEmptyKey(),
163+
ProfileCounterRef::Kind::Node);
164+
}
165+
static inline ProfileCounterRef getTombstoneKey() {
166+
return ProfileCounterRef(DenseMapInfo<ASTNode>::getTombstoneKey(),
167+
ProfileCounterRef::Kind::Node);
168+
}
169+
static unsigned getHashValue(const ProfileCounterRef &ref) {
170+
return hash_value(ref);
171+
}
172+
static bool isEqual(const ProfileCounterRef &lhs,
173+
const ProfileCounterRef &rhs) {
174+
return lhs == rhs;
175+
}
176+
};
177+
} // end namespace llvm
178+
103179
#endif // SWIFT_SIL_PROFILER_H

0 commit comments

Comments
 (0)