Skip to content

Commit 29fcb2e

Browse files
authored
Merge pull request swiftlang#22927 from gottesmm/pr-476ad464db62e88edd7927623bac98b8e266587c
2 parents f38e6b4 + 98ed241 commit 29fcb2e

File tree

4 files changed

+316
-8
lines changed

4 files changed

+316
-8
lines changed

include/swift/SIL/DynamicCasts.h

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#define SWIFT_SIL_DYNAMICCASTS_H
2020

2121
#include "swift/Basic/ProfileCounter.h"
22+
#include "swift/SIL/SILInstruction.h"
23+
#include "swift/SIL/SILModule.h"
2224
#include "swift/SIL/SILValue.h"
2325

2426
namespace swift {
@@ -95,6 +97,242 @@ CanType getNSBridgedClassOfCFClass(ModuleDecl *M, CanType type);
9597

9698
/// Does the type conform to Error.
9799
bool isError(ModuleDecl *M, CanType Ty);
100+
101+
struct SILDynamicCastKind {
102+
enum innerty : std::underlying_type<SILInstructionKind>::type {
103+
#define DYNAMICCAST_INST(ID, PARENT) ID = unsigned(SILInstructionKind::ID),
104+
#include "swift/SIL/SILNodes.def"
105+
} value;
106+
107+
explicit SILDynamicCastKind(SILInstructionKind kind) {
108+
auto newValue = SILDynamicCastKind::fromNodeKindHelper(kind);
109+
assert(newValue && "Non cast passed into SILDynamicCastKind");
110+
value = newValue.getValue();
111+
}
112+
113+
SILDynamicCastKind(innerty value) : value(value) {}
114+
operator innerty() const { return value; }
115+
116+
static Optional<SILDynamicCastKind> fromNodeKind(SILInstructionKind kind) {
117+
if (auto innerTyOpt = SILDynamicCastKind::fromNodeKindHelper(kind))
118+
return SILDynamicCastKind(*innerTyOpt);
119+
return None;
120+
}
121+
122+
private:
123+
static Optional<innerty> fromNodeKindHelper(SILInstructionKind kind) {
124+
switch (kind) {
125+
#define DYNAMICCAST_INST(ID, PARENT) \
126+
case SILInstructionKind::ID: \
127+
return SILDynamicCastKind::ID;
128+
#include "swift/SIL/SILNodes.def"
129+
default:
130+
return None;
131+
}
132+
}
133+
};
134+
135+
struct SILDynamicCastInst {
136+
SILInstruction *inst;
137+
138+
public:
139+
SILDynamicCastInst() : inst(nullptr) {}
140+
141+
explicit SILDynamicCastInst(SILInstruction *inst) : inst(inst) {
142+
assert(classof(inst) && "not a dynamic cast?!");
143+
}
144+
145+
static bool classof(const SILInstruction *inst) {
146+
return bool(SILDynamicCastKind::fromNodeKind(inst->getKind()));
147+
}
148+
149+
#define DYNAMICCAST_INST(ID, PARENT) \
150+
SILDynamicCastInst(ID *i) : inst(i) {}
151+
#include "swift/SIL/SILNodes.def"
152+
153+
static SILDynamicCastInst getAs(SILNode *node) {
154+
auto *i = dyn_cast<SILInstruction>(node);
155+
if (!i)
156+
return SILDynamicCastInst();
157+
auto kind = SILDynamicCastKind::fromNodeKind(i->getKind());
158+
if (!kind)
159+
return SILDynamicCastInst();
160+
switch (kind.getValue()) {
161+
#define DYNAMICCAST_INST(ID, PARENT) \
162+
case SILDynamicCastKind::ID: \
163+
return SILDynamicCastInst(cast<ID>(node));
164+
#include "swift/SIL/SILNodes.def"
165+
}
166+
}
167+
168+
SILDynamicCastKind getKind() const {
169+
return SILDynamicCastKind(inst->getKind());
170+
}
171+
172+
explicit operator bool() const { return inst != nullptr; }
173+
174+
SILInstruction *getInstruction() const { return inst; }
175+
176+
CastConsumptionKind getConsumptionKind() const {
177+
switch (getKind()) {
178+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
179+
case SILDynamicCastKind::CheckedCastBranchInst:
180+
case SILDynamicCastKind::CheckedCastValueBranchInst:
181+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
182+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
183+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
184+
llvm_unreachable("unsupported query");
185+
}
186+
}
187+
188+
SILBasicBlock *getSuccessBlock() {
189+
switch (getKind()) {
190+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
191+
case SILDynamicCastKind::CheckedCastBranchInst:
192+
case SILDynamicCastKind::CheckedCastValueBranchInst:
193+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
194+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
195+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
196+
llvm_unreachable("Unsupported query");
197+
}
198+
}
199+
200+
const SILBasicBlock *getSuccessBlock() const {
201+
return const_cast<SILDynamicCastInst &>(*this).getSuccessBlock();
202+
}
203+
204+
SILBasicBlock *getFailureBlock() {
205+
switch (getKind()) {
206+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
207+
case SILDynamicCastKind::CheckedCastBranchInst:
208+
case SILDynamicCastKind::CheckedCastValueBranchInst:
209+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
210+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
211+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
212+
llvm_unreachable("Unsupported query");
213+
}
214+
}
215+
216+
const SILBasicBlock *getFailureBlock() const {
217+
return const_cast<SILDynamicCastInst &>(*this).getFailureBlock();
218+
}
219+
220+
SILValue getSource() const {
221+
switch (getKind()) {
222+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
223+
case SILDynamicCastKind::CheckedCastBranchInst:
224+
case SILDynamicCastKind::CheckedCastValueBranchInst:
225+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
226+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
227+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
228+
llvm_unreachable("unsupported");
229+
}
230+
}
231+
232+
// Returns the success value.
233+
SILValue getDest() const {
234+
switch (getKind()) {
235+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
236+
case SILDynamicCastKind::CheckedCastBranchInst:
237+
case SILDynamicCastKind::CheckedCastValueBranchInst:
238+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
239+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
240+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
241+
llvm_unreachable("unimplemented");
242+
}
243+
}
244+
245+
CanType getSourceType() const {
246+
switch (getKind()) {
247+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
248+
case SILDynamicCastKind::CheckedCastBranchInst:
249+
case SILDynamicCastKind::CheckedCastValueBranchInst:
250+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
251+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
252+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
253+
llvm_unreachable("unsupported");
254+
}
255+
}
256+
257+
SILType getLoweredSourceType() const {
258+
switch (getKind()) {
259+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
260+
case SILDynamicCastKind::CheckedCastBranchInst:
261+
case SILDynamicCastKind::CheckedCastValueBranchInst:
262+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
263+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
264+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
265+
llvm_unreachable("unsupported");
266+
}
267+
}
268+
269+
CanType getTargetType() const {
270+
switch (getKind()) {
271+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
272+
case SILDynamicCastKind::CheckedCastBranchInst:
273+
case SILDynamicCastKind::CheckedCastValueBranchInst:
274+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
275+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
276+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
277+
llvm_unreachable("unimplemented");
278+
}
279+
}
280+
281+
SILType getLoweredTargetType() const {
282+
switch (getKind()) {
283+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
284+
case SILDynamicCastKind::CheckedCastBranchInst:
285+
case SILDynamicCastKind::CheckedCastValueBranchInst:
286+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
287+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
288+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
289+
llvm_unreachable("unsupported");
290+
}
291+
}
292+
293+
bool isSourceTypeExact() const {
294+
switch (getKind()) {
295+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
296+
case SILDynamicCastKind::CheckedCastBranchInst:
297+
case SILDynamicCastKind::CheckedCastValueBranchInst:
298+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
299+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
300+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
301+
llvm_unreachable("unsupported");
302+
}
303+
}
304+
305+
SILLocation getLocation() const { return inst->getLoc(); }
306+
307+
SILModule &getModule() const { return inst->getModule(); }
308+
309+
DynamicCastFeasibility classifyDynamicCast() const {
310+
return swift::classifyDynamicCast(
311+
getModule().getSwiftModule(), getSourceType(), getTargetType(),
312+
isSourceTypeExact(), getModule().isWholeModule());
313+
}
314+
315+
bool isBridgingCast() const {
316+
// Bridging casts cannot be further simplified.
317+
auto TargetIsBridgeable = getTargetType()->isBridgeableObjectType();
318+
auto SourceIsBridgeable = getSourceType()->isBridgeableObjectType();
319+
320+
return TargetIsBridgeable != SourceIsBridgeable;
321+
}
322+
323+
bool isConditionalCast() const {
324+
switch (getKind()) {
325+
case SILDynamicCastKind::CheckedCastAddrBranchInst:
326+
case SILDynamicCastKind::CheckedCastBranchInst:
327+
case SILDynamicCastKind::CheckedCastValueBranchInst:
328+
case SILDynamicCastKind::UnconditionalCheckedCastAddrInst:
329+
case SILDynamicCastKind::UnconditionalCheckedCastInst:
330+
case SILDynamicCastKind::UnconditionalCheckedCastValueInst:
331+
llvm_unreachable("unsupported");
332+
}
333+
}
334+
};
335+
98336
} // end namespace swift
99337

100338
#endif

0 commit comments

Comments
 (0)