14
14
#include " swift/SIL/SILArgument.h"
15
15
#include " swift/SIL/SILBuiltinVisitor.h"
16
16
#include " swift/SIL/SILInstruction.h"
17
+ #include " swift/SIL/SILModule.h"
17
18
#include " swift/SIL/SILVisitor.h"
18
19
19
20
using namespace swift ;
@@ -84,8 +85,8 @@ llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os,
84
85
return os << " Owned" ;
85
86
case ValueOwnershipKind::Guaranteed:
86
87
return os << " Guaranteed" ;
87
- case ValueOwnershipKind::Undef :
88
- return os << " Undef " ;
88
+ case ValueOwnershipKind::Any :
89
+ return os << " Any " ;
89
90
}
90
91
}
91
92
@@ -97,12 +98,12 @@ swift::ValueOwnershipKindMerge(Optional<ValueOwnershipKind> LHS,
97
98
auto LHSVal = LHS.getValue ();
98
99
auto RHSVal = RHS.getValue ();
99
100
100
- // Undef merges with anything.
101
- if (LHSVal == ValueOwnershipKind::Undef ) {
101
+ // Any merges with anything.
102
+ if (LHSVal == ValueOwnershipKind::Any ) {
102
103
return RHSVal;
103
104
}
104
- // Undef merges with anything.
105
- if (RHSVal == ValueOwnershipKind::Undef ) {
105
+ // Any merges with anything.
106
+ if (RHSVal == ValueOwnershipKind::Any ) {
106
107
return LHSVal;
107
108
}
108
109
@@ -117,29 +118,28 @@ namespace {
117
118
118
119
class ValueOwnershipKindVisitor
119
120
: public SILVisitor<ValueOwnershipKindVisitor,
120
- Optional< ValueOwnershipKind> > {
121
+ ValueOwnershipKind> {
121
122
122
123
public:
123
124
ValueOwnershipKindVisitor () = default ;
124
125
~ValueOwnershipKindVisitor () = default ;
125
126
ValueOwnershipKindVisitor (const ValueOwnershipKindVisitor &) = delete ;
126
127
ValueOwnershipKindVisitor (ValueOwnershipKindVisitor &&) = delete ;
127
128
128
- Optional< ValueOwnershipKind> visitForwardingInst (SILInstruction *I);
129
- Optional< ValueOwnershipKind> visitPHISILArgument (SILArgument *Arg);
129
+ ValueOwnershipKind visitForwardingInst (SILInstruction *I);
130
+ ValueOwnershipKind visitPHISILArgument (SILArgument *Arg);
130
131
131
- Optional< ValueOwnershipKind> visitValueBase (ValueBase *V) {
132
+ ValueOwnershipKind visitValueBase (ValueBase *V) {
132
133
llvm_unreachable (" unimplemented method on ValueBaseOwnershipVisitor" );
133
134
}
134
- #define VALUE (Id, Parent ) \
135
- Optional<ValueOwnershipKind> visit##Id(Id *ID);
135
+ #define VALUE (Id, Parent ) ValueOwnershipKind visit##Id(Id *ID);
136
136
#include " swift/SIL/SILNodes.def"
137
137
};
138
138
139
139
} // end anonymous namespace
140
140
141
141
#define CONSTANT_OWNERSHIP_INST (OWNERSHIP, INST ) \
142
- Optional< ValueOwnershipKind> ValueOwnershipKindVisitor::visit##INST##Inst( \
142
+ ValueOwnershipKind ValueOwnershipKindVisitor::visit##INST##Inst( \
143
143
INST##Inst *Arg) { \
144
144
assert (Arg->hasValue () && " Expected to have a result" ); \
145
145
if (ValueOwnershipKind::OWNERSHIP == ValueOwnershipKind::Trivial) { \
@@ -151,9 +151,6 @@ class ValueOwnershipKindVisitor
151
151
}
152
152
CONSTANT_OWNERSHIP_INST (Guaranteed, BeginBorrow)
153
153
CONSTANT_OWNERSHIP_INST(Guaranteed, LoadBorrow)
154
- CONSTANT_OWNERSHIP_INST(Guaranteed, StructExtract)
155
- CONSTANT_OWNERSHIP_INST(Guaranteed, TupleExtract)
156
- CONSTANT_OWNERSHIP_INST(Guaranteed, UncheckedEnumData)
157
154
CONSTANT_OWNERSHIP_INST(Owned, AllocBox)
158
155
CONSTANT_OWNERSHIP_INST(Owned, AllocExistentialBox)
159
156
CONSTANT_OWNERSHIP_INST(Owned, AllocRef)
@@ -192,9 +189,10 @@ CONSTANT_OWNERSHIP_INST(Trivial, MarkFunctionEscape)
192
189
CONSTANT_OWNERSHIP_INST(Trivial, MarkUninitialized)
193
190
CONSTANT_OWNERSHIP_INST(Trivial, MarkUninitializedBehavior)
194
191
CONSTANT_OWNERSHIP_INST(Trivial, Metatype)
195
- CONSTANT_OWNERSHIP_INST(Trivial, ObjCExistentialMetatypeToObject) // Is this right?
196
- CONSTANT_OWNERSHIP_INST(Trivial, ObjCMetatypeToObject) // Is this right?
197
- CONSTANT_OWNERSHIP_INST(Trivial, ObjCProtocol) // Is this right?
192
+ CONSTANT_OWNERSHIP_INST(Trivial,
193
+ ObjCExistentialMetatypeToObject) // Is this right?
194
+ CONSTANT_OWNERSHIP_INST(Trivial, ObjCMetatypeToObject) // Is this right?
195
+ CONSTANT_OWNERSHIP_INST(Trivial, ObjCProtocol) // Is this right?
198
196
CONSTANT_OWNERSHIP_INST(Trivial, ObjCToThickMetatype)
199
197
CONSTANT_OWNERSHIP_INST(Trivial, OpenExistentialAddr)
200
198
CONSTANT_OWNERSHIP_INST(Trivial, OpenExistentialBox)
@@ -233,13 +231,25 @@ CONSTANT_OWNERSHIP_INST(Unowned, UnmanagedToRef)
233
231
CONSTANT_OWNERSHIP_INST(Unowned, UnownedToRef)
234
232
#undef CONSTANT_OWNERSHIP_INST
235
233
234
+ #define CONSTANT_OR_TRIVIAL_OWNERSHIP_INST (OWNERSHIP, INST ) \
235
+ ValueOwnershipKind ValueOwnershipKindVisitor::visit##INST##Inst(INST##Inst *I) { \
236
+ if (I->getType ().isTrivial (I->getModule ())) { \
237
+ return ValueOwnershipKind::Trivial; \
238
+ } \
239
+ return ValueOwnershipKind::OWNERSHIP; \
240
+ }
241
+ CONSTANT_OR_TRIVIAL_OWNERSHIP_INST (Guaranteed, StructExtract)
242
+ CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, TupleExtract)
243
+ CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, UncheckedEnumData)
244
+ #undef CONSTANT_OR_TRIVIAL_OWNERSHIP_INST
245
+
236
246
// These are instructions that do not have any result, so we should never reach
237
247
// this point in the code since we need a SILValue to compute
238
248
// ValueOwnershipKind. We define methods so that all instructions have a method
239
249
// on the visitor (causing the compiler to warn if a new instruction is added
240
250
// within a method being added).
241
251
#define NO_RESULT_OWNERSHIP_INST (INST ) \
242
- Optional< ValueOwnershipKind> ValueOwnershipKindVisitor::visit##INST##Inst( \
252
+ ValueOwnershipKind ValueOwnershipKindVisitor::visit##INST##Inst( \
243
253
INST##Inst *I) { \
244
254
assert (!I->hasValue () && " Expected an instruction without a result" ); \
245
255
llvm_unreachable (" Instruction without a result can not have ownership" ); \
@@ -294,34 +304,58 @@ NO_RESULT_OWNERSHIP_INST(CheckedCastBranch)
294
304
NO_RESULT_OWNERSHIP_INST(CheckedCastAddrBranch)
295
305
#undef NO_RESULT_OWNERSHIP_INST
296
306
297
- // For a forwarding instruction, we loop over all operands and make sure they
298
- // are all the same.
299
- Optional< ValueOwnershipKind>
307
+ // For a forwarding instruction, we loop over all operands and make sure that
308
+ // all non-trivial values have the same ownership .
309
+ ValueOwnershipKind
300
310
ValueOwnershipKindVisitor::visitForwardingInst (SILInstruction *I) {
301
311
ArrayRef<Operand> Ops = I->getAllOperands ();
312
+ // A forwarding inst without operands must be trivial.
302
313
if (Ops.empty ())
303
- llvm_unreachable (" All forwarding insts should have operands" );
304
- Optional<ValueOwnershipKind> Base = Ops[0 ].get ().getOwnershipKind ();
305
- if (!Base)
306
- return None;
307
-
308
- for (const Operand &Op : Ops.slice (1 )) {
309
- if (!(Base = ValueOwnershipKindMerge (Base, Op.get ().getOwnershipKind ()))) {
310
- return None;
314
+ return ValueOwnershipKind::Trivial;
315
+
316
+ // Find the first index where we have a trivial value.
317
+ auto Iter =
318
+ find_if (Ops,
319
+ [](const Operand &Op) -> bool {
320
+ return Op.get ().getOwnershipKind () != ValueOwnershipKind::Trivial;
321
+ });
322
+ // All trivial.
323
+ if (Iter == Ops.end ()) {
324
+ return ValueOwnershipKind::Trivial;
325
+ }
326
+
327
+ // See if we have any Any. If we do, just return that for now.
328
+ if (any_of (Ops,
329
+ [](const Operand &Op) -> bool {
330
+ return Op.get ().getOwnershipKind () == ValueOwnershipKind::Any;
331
+ }))
332
+ return ValueOwnershipKind::Any;
333
+ unsigned Index = std::distance (Ops.begin (), Iter);
334
+
335
+ ValueOwnershipKind Base = Ops[Index].get ().getOwnershipKind ();
336
+
337
+ for (const Operand &Op : Ops.slice (Index+1 )) {
338
+ auto OpKind = Op.get ().getOwnershipKind ();
339
+ if (ValueOwnershipKindMerge (OpKind, ValueOwnershipKind::Trivial))
340
+ continue ;
341
+
342
+ auto MergedValue = ValueOwnershipKindMerge (Base, OpKind);
343
+ if (!MergedValue.hasValue ()) {
344
+ llvm_unreachable (" Forwarding inst with mismatching ownership kinds?!" );
311
345
}
312
346
}
347
+
313
348
return Base;
314
349
}
315
350
316
351
#define FORWARDING_OWNERSHIP_INST (INST ) \
317
- Optional< ValueOwnershipKind> ValueOwnershipKindVisitor::visit##INST##Inst( \
352
+ ValueOwnershipKind ValueOwnershipKindVisitor::visit##INST##Inst( \
318
353
INST##Inst *I) { \
319
354
assert (I->hasValue () && " Expected to have a value" ); \
320
355
return visitForwardingInst (I); \
321
356
}
322
357
FORWARDING_OWNERSHIP_INST (BridgeObjectToRef)
323
358
FORWARDING_OWNERSHIP_INST(ConvertFunction)
324
- FORWARDING_OWNERSHIP_INST(Enum)
325
359
FORWARDING_OWNERSHIP_INST(InitExistentialRef)
326
360
FORWARDING_OWNERSHIP_INST(OpenExistentialRef)
327
361
FORWARDING_OWNERSHIP_INST(RefToBridgeObject)
@@ -334,18 +368,27 @@ FORWARDING_OWNERSHIP_INST(UnconditionalCheckedCast)
334
368
FORWARDING_OWNERSHIP_INST(Upcast)
335
369
#undef FORWARDING_OWNERSHIP_INST
336
370
337
- Optional<ValueOwnershipKind>
371
+ // An enum without payload is trivial. One with non-trivial payload is
372
+ // forwarding.
373
+ ValueOwnershipKind
374
+ ValueOwnershipKindVisitor::visitEnumInst (EnumInst *EI) {
375
+ if (!EI->hasOperand ())
376
+ return ValueOwnershipKind::Trivial;
377
+ return visitForwardingInst (EI);
378
+ }
379
+
380
+ ValueOwnershipKind
338
381
ValueOwnershipKindVisitor::visitSILUndef (SILUndef *Arg) {
339
- return ValueOwnershipKind::Undef ;
382
+ return ValueOwnershipKind::Any ;
340
383
}
341
384
342
- Optional< ValueOwnershipKind>
385
+ ValueOwnershipKind
343
386
ValueOwnershipKindVisitor::visitPHISILArgument (SILArgument *Arg) {
344
387
// For now just return undef.
345
- return ValueOwnershipKind::Undef ;
388
+ return ValueOwnershipKind::Any ;
346
389
}
347
390
348
- Optional< ValueOwnershipKind>
391
+ ValueOwnershipKind
349
392
ValueOwnershipKindVisitor::visitSILArgument (SILArgument *Arg) {
350
393
// If we have a PHI node, we need to look at our predecessors.
351
394
if (!Arg->isFunctionArg ()) {
@@ -378,41 +421,79 @@ ValueOwnershipKindVisitor::visitSILArgument(SILArgument *Arg) {
378
421
}
379
422
380
423
// This is a forwarding instruction through only one of its arguments.
381
- Optional< ValueOwnershipKind>
424
+ ValueOwnershipKind
382
425
ValueOwnershipKindVisitor::visitMarkDependenceInst (MarkDependenceInst *MDI) {
383
426
return MDI->getValue ().getOwnershipKind ();
384
427
}
385
428
386
- Optional< ValueOwnershipKind>
387
- ValueOwnershipKindVisitor::visitApplyInst (ApplyInst *AI ) {
388
- auto Result = AI-> getSingleResult ( );
389
- assert (Result && " SIL for now only has single results " );
390
- switch (Result-> getConvention ()) {
429
+ static ValueOwnershipKind getResultOwnershipKind ( const SILResultInfo &Info,
430
+ SILModule &M ) {
431
+ SILType Ty = M. Types . getLoweredType (Info. getType () );
432
+ bool IsTrivial = Ty. isTrivial (M );
433
+ switch (Info. getConvention ()) {
391
434
case ResultConvention::Indirect:
392
- return None;
435
+ return ValueOwnershipKind::Trivial; // Should this be an Any?
393
436
case ResultConvention::Autoreleased:
394
437
case ResultConvention::Owned:
395
438
return ValueOwnershipKind::Owned;
396
439
case ResultConvention::Unowned:
397
440
case ResultConvention::UnownedInnerPointer:
441
+ if (IsTrivial)
442
+ return ValueOwnershipKind::Trivial;
398
443
return ValueOwnershipKind::Unowned;
399
444
}
400
445
}
401
446
402
- Optional<ValueOwnershipKind>
447
+ ValueOwnershipKind
448
+ ValueOwnershipKindVisitor::visitApplyInst (ApplyInst *AI) {
449
+ SILModule &M = AI->getModule ();
450
+ bool IsTrivial = AI->getType ().isTrivial (M);
451
+ auto Results = AI->getSubstCalleeType ()->getDirectResults ();
452
+ // No results => empty tuple result => Trivial.
453
+ if (Results.empty () || IsTrivial)
454
+ return ValueOwnershipKind::Trivial;
455
+
456
+ // Find the first index where we have a trivial value.
457
+ auto Iter =
458
+ find_if (Results,
459
+ [&M](const SILResultInfo &Info) -> bool {
460
+ return getResultOwnershipKind (Info, M) != ValueOwnershipKind::Trivial;
461
+ });
462
+ // If we have all trivial, then we must be trivial.
463
+ if (Iter == Results.end ())
464
+ return ValueOwnershipKind::Trivial;
465
+
466
+ unsigned Index = std::distance (Results.begin (), Iter);
467
+ ValueOwnershipKind Base = getResultOwnershipKind (Results[Index], M);
468
+
469
+ for (const SILResultInfo &ResultInfo : Results.slice (Index+1 )) {
470
+ auto RKind = getResultOwnershipKind (ResultInfo, M);
471
+ if (ValueOwnershipKindMerge (RKind, ValueOwnershipKind::Trivial))
472
+ continue ;
473
+
474
+ auto MergedValue = ValueOwnershipKindMerge (Base, RKind);
475
+ if (!MergedValue.hasValue ()) {
476
+ llvm_unreachable (" Forwarding inst with mismatching ownership kinds?!" );
477
+ }
478
+ }
479
+
480
+ return Base;
481
+ }
482
+
483
+ ValueOwnershipKind
403
484
ValueOwnershipKindVisitor::visitLoadInst (LoadInst *LI) {
404
485
switch (LI->getOwnershipQualifier ()) {
405
486
case LoadOwnershipQualifier::Take:
406
487
case LoadOwnershipQualifier::Copy:
407
488
return ValueOwnershipKind::Owned;
408
489
case LoadOwnershipQualifier::Unqualified:
409
- return None ;
490
+ return ValueOwnershipKind::Any ;
410
491
case LoadOwnershipQualifier::Trivial:
411
492
return ValueOwnershipKind::Trivial;
412
493
}
413
494
}
414
495
415
- Optional< ValueOwnershipKind> SILValue::getOwnershipKind () const {
496
+ ValueOwnershipKind SILValue::getOwnershipKind () const {
416
497
// Once we have multiple return values, this must be changed.
417
498
return ValueOwnershipKindVisitor ().visit (const_cast <ValueBase *>(Value));
418
499
}
@@ -623,7 +704,7 @@ UNOWNED_OR_TRIVIAL_DEPENDING_ON_RESULT(InsertElement)
623
704
UNOWNED_OR_TRIVIAL_DEPENDING_ON_RESULT(ZeroInitializer)
624
705
#undef UNOWNED_OR_TRIVIAL_DEPENDING_ON_RESULT
625
706
626
- Optional< ValueOwnershipKind>
707
+ ValueOwnershipKind
627
708
ValueOwnershipKindVisitor::visitBuiltinInst (BuiltinInst *BI) {
628
709
// For now, just conservatively say builtins are None. We need to use a
629
710
// builtin in here to guarantee correctness.
0 commit comments