Skip to content

Commit c834520

Browse files
committed
[simplify-instruction] When eliminating extracts from an aggregate we just constructed, look through ownership insts.
Just an oversight. When used with -enable-ossa-modules, this eliminates the reported ARC traffic issue in: SR-12377 rdar://60832825
1 parent 1f1a03c commit c834520

File tree

2 files changed

+82
-15
lines changed

2 files changed

+82
-15
lines changed

lib/SILOptimizer/Analysis/SimplifyInstruction.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -146,39 +146,43 @@ SILValue InstSimplifier::visitTupleInst(TupleInst *TI) {
146146
return SILValue();
147147
}
148148

149-
SILValue InstSimplifier::visitTupleExtractInst(TupleExtractInst *TEI) {
149+
SILValue InstSimplifier::visitTupleExtractInst(TupleExtractInst *tei) {
150+
auto op = lookThroughOwnershipInsts(tei->getOperand());
151+
150152
// tuple_extract(tuple(x, y), 0) -> x
151-
if (auto *TheTuple = dyn_cast<TupleInst>(TEI->getOperand()))
152-
return TheTuple->getElement(TEI->getFieldIndex());
153+
if (auto *tupleInst = dyn_cast<TupleInst>(op))
154+
return tupleInst->getElement(tei->getFieldIndex());
153155

154156
// tuple_extract(apply([add|sub|...]overflow(x,y)), 0) -> x
155157
// tuple_extract(apply(checked_trunc(ext(x))), 0) -> x
156-
if (TEI->getFieldIndex() == 0)
157-
if (auto *BI = dyn_cast<BuiltinInst>(TEI->getOperand()))
158-
return simplifyOverflowBuiltin(BI);
158+
if (tei->getFieldIndex() == 0)
159+
if (auto *bi = dyn_cast<BuiltinInst>(tei->getOperand()))
160+
return simplifyOverflowBuiltin(bi);
159161

160162
return SILValue();
161163
}
162164

163-
SILValue InstSimplifier::visitStructExtractInst(StructExtractInst *SEI) {
165+
SILValue InstSimplifier::visitStructExtractInst(StructExtractInst *sei) {
166+
auto op = lookThroughOwnershipInsts(sei->getOperand());
167+
164168
// struct_extract(struct(x, y), x) -> x
165-
if (auto *Struct = dyn_cast<StructInst>(SEI->getOperand()))
166-
return Struct->getFieldValue(SEI->getField());
169+
if (auto *si = dyn_cast<StructInst>(op))
170+
return si->getFieldValue(sei->getField());
167171

168172
return SILValue();
169173
}
170174

171175
SILValue
172-
InstSimplifier::
173-
visitUncheckedEnumDataInst(UncheckedEnumDataInst *UEDI) {
176+
InstSimplifier::visitUncheckedEnumDataInst(UncheckedEnumDataInst *uedi) {
174177
// (unchecked_enum_data (enum payload)) -> payload
175-
if (auto *EI = dyn_cast<EnumInst>(UEDI->getOperand())) {
176-
if (EI->getElement() != UEDI->getElement())
178+
auto opt = lookThroughOwnershipInsts(uedi->getOperand());
179+
if (auto *ei = dyn_cast<EnumInst>(opt)) {
180+
if (ei->getElement() != uedi->getElement())
177181
return SILValue();
178182

179-
assert(EI->hasOperand() &&
183+
assert(ei->hasOperand() &&
180184
"Should only get data from an enum with payload.");
181-
return EI->getOperand();
185+
return lookThroughOwnershipInsts(ei->getOperand());
182186
}
183187

184188
return SILValue();

test/SILOptimizer/sil_combine_ossa.sil

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5020,3 +5020,66 @@ bb0:
50205020
return %3 : $Builtin.Word
50215021
}
50225022

5023+
struct Function {
5024+
var impl: (MyInt) -> Double
5025+
}
5026+
5027+
sil @negateFunction : $@convention(thin) (MyInt, @guaranteed Function) -> Double
5028+
5029+
// CHECK-LABEL: sil [ossa] @test_borrow_struct_extract : $@convention(thin) (@guaranteed Function) -> Double {
5030+
// CHECK-NOT: struct_extract
5031+
// CHECK-NOT: struct $Function
5032+
// CHECK: } // end sil function 'test_borrow_struct_extract'
5033+
sil [ossa] @test_borrow_struct_extract : $@convention(thin) (@guaranteed Function) -> Double {
5034+
bb0(%0 : @guaranteed $Function):
5035+
%3 = function_ref @negateFunction : $@convention(thin) (MyInt, @guaranteed Function) -> Double
5036+
%4 = copy_value %0 : $Function
5037+
%5 = partial_apply [callee_guaranteed] %3(%4) : $@convention(thin) (MyInt, @guaranteed Function) -> Double
5038+
%6 = struct $Function (%5 : $@callee_guaranteed (MyInt) -> Double)
5039+
%7 = integer_literal $Builtin.Int32, 0
5040+
%8 = struct $MyInt (%7 : $Builtin.Int32)
5041+
%9 = begin_borrow %6 : $Function
5042+
%12 = struct_extract %9 : $Function, #Function.impl
5043+
%13 = apply %12(%8) : $@callee_guaranteed (MyInt) -> Double
5044+
end_borrow %9 : $Function
5045+
destroy_value %6 : $Function
5046+
return %13 : $Double
5047+
}
5048+
5049+
// CHECK-LABEL: sil [ossa] @test_borrow_tuple_extract : $@convention(thin) (@guaranteed Function) -> Double {
5050+
// CHECK-NOT: tuple_extract
5051+
// CHECK: } // end sil function 'test_borrow_tuple_extract'
5052+
sil [ossa] @test_borrow_tuple_extract : $@convention(thin) (@guaranteed Function) -> Double {
5053+
bb0(%0 : @guaranteed $Function):
5054+
%3 = function_ref @negateFunction : $@convention(thin) (MyInt, @guaranteed Function) -> Double
5055+
%4 = copy_value %0 : $Function
5056+
%5 = partial_apply [callee_guaranteed] %3(%4) : $@convention(thin) (MyInt, @guaranteed Function) -> Double
5057+
%7 = integer_literal $Builtin.Int32, 0
5058+
%8 = struct $MyInt (%7 : $Builtin.Int32)
5059+
%6 = tuple (%5 : $@callee_guaranteed (MyInt) -> Double, %7 : $Builtin.Int32)
5060+
%9 = begin_borrow %6 : $(@callee_guaranteed (MyInt) -> Double, Builtin.Int32)
5061+
%12 = tuple_extract %9 : $(@callee_guaranteed (MyInt) -> Double, Builtin.Int32), 0
5062+
%13 = apply %12(%8) : $@callee_guaranteed (MyInt) -> Double
5063+
end_borrow %9 : $(@callee_guaranteed (MyInt) -> Double, Builtin.Int32)
5064+
destroy_value %6 : $(@callee_guaranteed (MyInt) -> Double, Builtin.Int32)
5065+
return %13 : $Double
5066+
}
5067+
5068+
// CHECK-LABEL: sil [ossa] @test_borrow_unchecked_enum_data : $@convention(thin) (@guaranteed Function) -> Double {
5069+
// CHECK-NOT: unchecked_enum_data
5070+
// CHECK: } // end sil function 'test_borrow_unchecked_enum_data'
5071+
sil [ossa] @test_borrow_unchecked_enum_data : $@convention(thin) (@guaranteed Function) -> Double {
5072+
bb0(%0 : @guaranteed $Function):
5073+
%3 = function_ref @negateFunction : $@convention(thin) (MyInt, @guaranteed Function) -> Double
5074+
%4 = copy_value %0 : $Function
5075+
%5 = partial_apply [callee_guaranteed] %3(%4) : $@convention(thin) (MyInt, @guaranteed Function) -> Double
5076+
%7 = integer_literal $Builtin.Int32, 0
5077+
%8 = struct $MyInt (%7 : $Builtin.Int32)
5078+
%6 = enum $Optional<@callee_guaranteed (MyInt) -> Double>, #Optional.some!enumelt, %5 : $@callee_guaranteed (MyInt) -> Double
5079+
%9 = begin_borrow %6 : $Optional<@callee_guaranteed (MyInt) -> Double>
5080+
%12 = unchecked_enum_data %9 : $Optional<@callee_guaranteed (MyInt) -> Double>, #Optional.some!enumelt
5081+
%13 = apply %12(%8) : $@callee_guaranteed (MyInt) -> Double
5082+
end_borrow %9 : $Optional<@callee_guaranteed (MyInt) -> Double>
5083+
destroy_value %6 : $Optional<@callee_guaranteed (MyInt) -> Double>
5084+
return %13 : $Double
5085+
}

0 commit comments

Comments
 (0)