-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
RCStateTransition.h
139 lines (109 loc) · 4.67 KB
/
RCStateTransition.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//===--- RCStateTransition.h ------------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_RCSTATETRANSITION_H
#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_RCSTATETRANSITION_H
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILInstruction.h"
#include "llvm/ADT/SmallPtrSet.h"
#include <cstdint>
namespace swift {
class RCIdentityFunctionInfo;
class ConsumedArgToEpilogueReleaseMatcher;
} // end swift namespace
//===----------------------------------------------------------------------===//
// RCStateTransitionKind
//===----------------------------------------------------------------------===//
namespace swift {
/// The kind of a RCStateTransition.
enum class RCStateTransitionKind : uint8_t {
#define KIND(K) K,
#define ABSTRACT_VALUE(Name, StartKind, EndKind) \
Name ## _Start = StartKind, Name ## _End = EndKind,
#include "RCStateTransition.def"
};
/// \returns the RCStateTransitionKind corresponding to \p V.
RCStateTransitionKind getRCStateTransitionKind(ValueBase *V);
/// Define predicates to test for RCStateTransition abstract value kinds.
#define ABSTRACT_VALUE(Name, Start, End) \
bool isRCStateTransition ## Name(RCStateTransitionKind Kind); \
static inline bool isRCStateTransition ## Name(ValueBase *V) { \
return isRCStateTransition ## Name(getRCStateTransitionKind(V)); \
}
#define KIND(Name) \
static inline bool isRCStateTransition ## Name(ValueBase *V) { \
return RCStateTransitionKind::Name == getRCStateTransitionKind(V); \
}
#include "RCStateTransition.def"
//===----------------------------------------------------------------------===//
// RCStateTransition
//===----------------------------------------------------------------------===//
class RefCountState;
/// Represents a transition in the RC history of a ref count.
class RCStateTransition {
friend class RefCountState;
/// An RCStateTransition can represent either an RC end point (i.e. an initial
/// or terminal RC transition) or a ptr set of Mutators.
ValueBase *EndPoint;
llvm::SmallPtrSet<SILInstruction *, 2> Mutators;
RCStateTransitionKind Kind;
// Should only be constructed be default RefCountState.
RCStateTransition() {}
public:
~RCStateTransition() {}
RCStateTransition(const RCStateTransition &R);
RCStateTransition(SILInstruction *I) {
Kind = getRCStateTransitionKind(I);
if (isRCStateTransitionEndPoint(Kind)) {
EndPoint = I;
return;
}
if (isRCStateTransitionMutator(Kind)) {
Mutators.insert(I);
return;
}
// Unknown kind.
}
RCStateTransition(SILArgument *A)
: EndPoint(A), Kind(RCStateTransitionKind::StrongEntrance) {
assert(A->hasConvention(ParameterConvention::Direct_Owned) &&
"Expected owned argument");
}
RCStateTransitionKind getKind() const { return Kind; }
/// Define test functions for the various abstract categorizations we have.
#define ABSTRACT_VALUE(Name, StartKind, EndKind) bool is ## Name() const;
#include "RCStateTransition.def"
/// Return true if this Transition is a mutator transition that contains I.
bool containsMutator(SILInstruction *I) const {
assert(isMutator() && "This should only be called if we are of mutator "
"kind");
return Mutators.count(I);
}
using mutator_range = iterator_range<decltype(Mutators)::iterator>;
using const_mutator_range = iterator_range<decltype(Mutators)::const_iterator>;
/// Returns a Range of Mutators. Asserts if this transition is not a mutator
/// transition.
mutator_range getMutators() const {
assert(isMutator() && "This should never be called given mutators");
return {Mutators.begin(), Mutators.end()};
}
/// Return true if Inst is an instruction that causes a transition that can be
/// paired with this transition.
bool matchingInst(SILInstruction *Inst) const;
/// Attempt to merge \p Other into \p this. Returns true if we succeeded,
/// false otherwise.
bool merge(const RCStateTransition &Other);
};
} // end swift namespace
namespace llvm {
raw_ostream &operator<<(raw_ostream &os, swift::RCStateTransitionKind Kind);
} // end llvm namespace
#endif