Skip to content

Commit d3e64ed

Browse files
authored
Merge pull request #32173 from gottesmm/pr-5e5960b7d932ff90a03c93f1ba6ac111c52d1157
[semantic-arc-opts] Teach semantic-arc-opts how to handle structs with multiple non-trivial values.
2 parents 9357c85 + 3cb33ac commit d3e64ed

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

include/swift/SIL/OwnershipUtils.h

+8
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,10 @@ struct OwnedValueIntroducerKind {
498498
/// branch predecessors.
499499
Phi,
500500

501+
/// An owned value that is from a struct that has multiple operands that are
502+
/// owned.
503+
Struct,
504+
501505
/// An owned value that is a function argument.
502506
FunctionArgument,
503507

@@ -522,6 +526,8 @@ struct OwnedValueIntroducerKind {
522526
return OwnedValueIntroducerKind(Apply);
523527
case ValueKind::BeginApplyResult:
524528
return OwnedValueIntroducerKind(BeginApply);
529+
case ValueKind::StructInst:
530+
return OwnedValueIntroducerKind(Struct);
525531
case ValueKind::SILPhiArgument: {
526532
auto *phiArg = cast<SILPhiArgument>(value);
527533
if (dyn_cast_or_null<TryApplyInst>(phiArg->getSingleTerminator())) {
@@ -614,6 +620,7 @@ struct OwnedValueIntroducer {
614620
case OwnedValueIntroducerKind::TryApply:
615621
case OwnedValueIntroducerKind::LoadTake:
616622
case OwnedValueIntroducerKind::Phi:
623+
case OwnedValueIntroducerKind::Struct:
617624
case OwnedValueIntroducerKind::FunctionArgument:
618625
case OwnedValueIntroducerKind::PartialApplyInit:
619626
case OwnedValueIntroducerKind::AllocBoxInit:
@@ -631,6 +638,7 @@ struct OwnedValueIntroducer {
631638
switch (kind) {
632639
case OwnedValueIntroducerKind::Phi:
633640
return true;
641+
case OwnedValueIntroducerKind::Struct:
634642
case OwnedValueIntroducerKind::Copy:
635643
case OwnedValueIntroducerKind::LoadCopy:
636644
case OwnedValueIntroducerKind::Apply:

lib/SIL/Utils/OwnershipUtils.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ void OwnedValueIntroducerKind::print(llvm::raw_ostream &os) const {
485485
case OwnedValueIntroducerKind::Phi:
486486
os << "Phi";
487487
return;
488+
case OwnedValueIntroducerKind::Struct:
489+
os << "Struct";
490+
return;
488491
case OwnedValueIntroducerKind::FunctionArgument:
489492
os << "FunctionArgument";
490493
return;

lib/SILOptimizer/Transforms/SemanticARCOpts.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class OwnershipPhiOperand {
5454
public:
5555
enum Kind {
5656
Branch,
57+
Struct,
5758
};
5859

5960
private:
@@ -65,6 +66,7 @@ class OwnershipPhiOperand {
6566
static Optional<OwnershipPhiOperand> get(const Operand *op) {
6667
switch (op->getUser()->getKind()) {
6768
case SILInstructionKind::BranchInst:
69+
case SILInstructionKind::StructInst:
6870
return {{const_cast<Operand *>(op)}};
6971
default:
7072
return None;
@@ -75,6 +77,8 @@ class OwnershipPhiOperand {
7577
switch (op->getUser()->getKind()) {
7678
case SILInstructionKind::BranchInst:
7779
return Kind::Branch;
80+
case SILInstructionKind::StructInst:
81+
return Kind::Struct;
7882
default:
7983
llvm_unreachable("unhandled case?!");
8084
}
@@ -100,6 +104,8 @@ class OwnershipPhiOperand {
100104
switch (getKind()) {
101105
case Kind::Branch:
102106
return true;
107+
case Kind::Struct:
108+
return false;
103109
}
104110
}
105111

@@ -113,6 +119,8 @@ class OwnershipPhiOperand {
113119

114120
bool visitResults(function_ref<bool(SILValue)> visitor) const {
115121
switch (getKind()) {
122+
case Kind::Struct:
123+
return visitor(cast<StructInst>(getInst()));
116124
case Kind::Branch: {
117125
auto *br = cast<BranchInst>(getInst());
118126
unsigned opNum = getOperandNumber();
@@ -576,6 +584,11 @@ static SILValue convertIntroducerToGuaranteed(OwnedValueIntroducer introducer) {
576584
phiArg->setOwnershipKind(ValueOwnershipKind::Guaranteed);
577585
return phiArg;
578586
}
587+
case OwnedValueIntroducerKind::Struct: {
588+
auto *si = cast<StructInst>(introducer.value);
589+
si->setOwnershipKind(ValueOwnershipKind::Guaranteed);
590+
return si;
591+
}
579592
case OwnedValueIntroducerKind::Copy:
580593
case OwnedValueIntroducerKind::LoadCopy:
581594
case OwnedValueIntroducerKind::Apply:
@@ -1084,6 +1097,20 @@ static bool getIncomingJoinedLiveRangeOperands(
10841097
});
10851098
}
10861099

1100+
if (auto *svi = dyn_cast<SingleValueInstruction>(joinedLiveRange)) {
1101+
return llvm::all_of(svi->getAllOperands(), [&](const Operand &op) {
1102+
// skip type dependent operands.
1103+
if (op.isTypeDependent())
1104+
return true;
1105+
1106+
auto phiOp = OwnershipPhiOperand::get(&op);
1107+
if (!phiOp)
1108+
return false;
1109+
resultingOperands.push_back(*phiOp);
1110+
return true;
1111+
});
1112+
}
1113+
10871114
llvm_unreachable("Unhandled joined live range?!");
10881115
}
10891116

test/SILOptimizer/semantic-arc-opts.sil

+13
Original file line numberDiff line numberDiff line change
@@ -2548,3 +2548,16 @@ bb1:
25482548
bb2(%39 : @owned $Klass):
25492549
unreachable
25502550
}
2551+
2552+
// CHECK-LABEL: sil [ossa] @struct_with_multiple_nontrivial_operands : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () {
2553+
// CHECK-NOT: copy_value
2554+
// CHECK: } // end sil function 'struct_with_multiple_nontrivial_operands'
2555+
sil [ossa] @struct_with_multiple_nontrivial_operands : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () {
2556+
bb0(%0 : @guaranteed $Builtin.NativeObject, %1 : @guaranteed $Builtin.NativeObject):
2557+
%0a = copy_value %0 : $Builtin.NativeObject
2558+
%1a = copy_value %1 : $Builtin.NativeObject
2559+
%2 = struct $NativeObjectPair(%0a : $Builtin.NativeObject, %1a : $Builtin.NativeObject)
2560+
destroy_value %2 : $NativeObjectPair
2561+
%9999 = tuple()
2562+
return %9999 : $()
2563+
}

0 commit comments

Comments
 (0)