Skip to content

Commit 11df7a8

Browse files
authored
Merge pull request #30293 from gottesmm/pr-55fe1cfe477ee888a3b18c3923c34ce370d6fea8
[temp-rvalue] Teach how to optimize unchecked_take_enum_data_addr of an Optional type.
2 parents 086d70b + dae4c0b commit 11df7a8

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

lib/SIL/SILVerifier.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,19 @@ struct ImmutableAddressUseVerifier {
615615
llvm::copy(result->getUses(), std::back_inserter(worklist));
616616
}
617617
break;
618+
case SILInstructionKind::UncheckedTakeEnumDataAddrInst: {
619+
auto type =
620+
cast<UncheckedTakeEnumDataAddrInst>(inst)->getOperand()->getType();
621+
if (type.getOptionalObjectType()) {
622+
for (auto result : inst->getResults()) {
623+
llvm::copy(result->getUses(), std::back_inserter(worklist));
624+
}
625+
break;
626+
}
627+
llvm::errs() << "Unhandled, unexpected instruction: " << *inst;
628+
llvm_unreachable("invoking standard assertion failure");
629+
break;
630+
}
618631
default:
619632
llvm::errs() << "Unhandled, unexpected instruction: " << *inst;
620633
llvm_unreachable("invoking standard assertion failure");

lib/SILOptimizer/Transforms/TempRValueElimination.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,20 @@ bool TempRValueOptPass::collectLoads(
227227
}
228228
return collectLoadsFromProjection(oeai, srcAddr, loadInsts);
229229
}
230+
case SILInstructionKind::UncheckedTakeEnumDataAddrInst: {
231+
// In certain cases, unchecked_take_enum_data_addr invalidates the
232+
// underlying memory, so by default we can not look through it... but this
233+
// is not true in the case of Optional. This is an important case for us to
234+
// handle, so handle it here.
235+
auto *utedai = cast<UncheckedTakeEnumDataAddrInst>(user);
236+
if (!utedai->getOperand()->getType().getOptionalObjectType()) {
237+
LLVM_DEBUG(llvm::dbgs()
238+
<< " Temp use may write/destroy its source" << *utedai);
239+
return false;
240+
}
241+
242+
return collectLoadsFromProjection(utedai, srcAddr, loadInsts);
243+
}
230244
case SILInstructionKind::StructElementAddrInst:
231245
case SILInstructionKind::TupleElementAddrInst: {
232246
return collectLoadsFromProjection(cast<SingleValueInstruction>(user),

test/SILOptimizer/temp_rvalue_opt_ossa.sil

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,3 +1075,52 @@ bb0(%0 : @owned $GS<Builtin.NativeObject>):
10751075
%v = tuple ()
10761076
return %v : $()
10771077
}
1078+
1079+
////////////////////////////////////////
1080+
// Unchecked Take Enum Data Addr Inst //
1081+
////////////////////////////////////////
1082+
1083+
// Make sure we only handle this in the copy_addr case. With time, we should
1084+
// also handle the store case.
1085+
//
1086+
// CHECK-LABEL: sil [ossa] @unchecked_take_enum_data_addr_rvalue_simple : $@convention(thin) <B> (@in_guaranteed Optional<GS<B>>, @inout Optional<GS<B>>) -> () {
1087+
// CHECK-NOT: alloc_stack
1088+
// CHECK: } // end sil function 'unchecked_take_enum_data_addr_rvalue_simple'
1089+
sil [ossa] @unchecked_take_enum_data_addr_rvalue_simple : $@convention(thin) <B> (@in_guaranteed Optional<GS<B>>, @inout Optional<GS<B>>) -> () {
1090+
bb0(%0 : $*Optional<GS<B>>, %1 : $*Optional<GS<B>>):
1091+
%0a = unchecked_take_enum_data_addr %0 : $*Optional<GS<B>>, #Optional.some!enumelt.1
1092+
%2 = struct_element_addr %0a : $*GS<B>, #GS._value
1093+
%3 = load [trivial] %2 : $*Builtin.Int64
1094+
%4 = alloc_stack $Optional<GS<B>>
1095+
copy_addr %1 to [initialization] %4 : $*Optional<GS<B>>
1096+
%4a = unchecked_take_enum_data_addr %4 : $*Optional<GS<B>>, #Optional.some!enumelt.1
1097+
%6 = struct_element_addr %4a : $*GS<B>, #GS._value
1098+
%7 = load [trivial] %6 : $*Builtin.Int64
1099+
%8 = builtin "cmp_slt_Int64"(%3 : $Builtin.Int64, %7 : $Builtin.Int64) : $Builtin.Int1
1100+
destroy_addr %4 : $*Optional<GS<B>>
1101+
dealloc_stack %4 : $*Optional<GS<B>>
1102+
%9999 = tuple()
1103+
return %9999 : $()
1104+
}
1105+
1106+
// We do not support this today, since I am still bringing up store support.
1107+
//
1108+
// CHECK-LABEL: sil [ossa] @unchecked_take_enum_data_addr_store_rvalue_simple : $@convention(thin) (@in_guaranteed Optional<GS<Klass>>, @owned Optional<GS<Klass>>) -> () {
1109+
// CHECK: alloc_stack
1110+
// CHECK: } // end sil function 'unchecked_take_enum_data_addr_store_rvalue_simple'
1111+
sil [ossa] @unchecked_take_enum_data_addr_store_rvalue_simple : $@convention(thin) (@in_guaranteed Optional<GS<Klass>>, @owned Optional<GS<Klass>>) -> () {
1112+
bb0(%0 : $*Optional<GS<Klass>>, %1 : @owned $Optional<GS<Klass>>):
1113+
%0a = unchecked_take_enum_data_addr %0 : $*Optional<GS<Klass>>, #Optional.some!enumelt.1
1114+
%2 = struct_element_addr %0a : $*GS<Klass>, #GS._value
1115+
%3 = load [trivial] %2 : $*Builtin.Int64
1116+
%4 = alloc_stack $Optional<GS<Klass>>
1117+
store %1 to [init] %4 : $*Optional<GS<Klass>>
1118+
%4a = unchecked_take_enum_data_addr %4 : $*Optional<GS<Klass>>, #Optional.some!enumelt.1
1119+
%6 = struct_element_addr %4a : $*GS<Klass>, #GS._value
1120+
%7 = load [trivial] %6 : $*Builtin.Int64
1121+
%8 = builtin "cmp_slt_Int64"(%3 : $Builtin.Int64, %7 : $Builtin.Int64) : $Builtin.Int1
1122+
destroy_addr %4 : $*Optional<GS<Klass>>
1123+
dealloc_stack %4 : $*Optional<GS<Klass>>
1124+
%9999 = tuple()
1125+
return %9999 : $()
1126+
}

0 commit comments

Comments
 (0)