File tree Expand file tree Collapse file tree 2 files changed +32
-0
lines changed
lib/SILOptimizer/Transforms Expand file tree Collapse file tree 2 files changed +32
-0
lines changed Original file line number Diff line number Diff line change @@ -542,6 +542,8 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
542
542
// re-initialization of the source.
543
543
bool needFinalDeinit = copyInst->isTakeOfSrc ();
544
544
545
+ SmallPtrSet<SILInstruction *, 4 > userSet;
546
+
545
547
// Scan all uses of the temporary storage (tempObj) to verify they all refer
546
548
// to the value initialized by this copy. It is sufficient to check that the
547
549
// only users that modify memory are the copy_addr [initialization] and
@@ -550,6 +552,8 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
550
552
for (auto *useOper : tempObj->getUses ()) {
551
553
SILInstruction *user = useOper->getUser ();
552
554
555
+ userSet.insert (user);
556
+
553
557
if (user == copyInst)
554
558
continue ;
555
559
@@ -576,6 +580,16 @@ void TempRValueOptPass::tryOptimizeCopyIntoTemp(CopyAddrInst *copyInst) {
576
580
return ;
577
581
}
578
582
583
+ // Check and return without optimization if we have any users of tempObj that
584
+ // precede the copyInst. This can happen with projections.
585
+ // TODO: We can enable this case if we clone the projections at "load" uses
586
+ for (SILInstruction &inst : llvm::make_range (copyInst->getParent ()->begin (),
587
+ copyInst->getIterator ())) {
588
+ if (userSet.count (&inst)) {
589
+ return ;
590
+ }
591
+ }
592
+
579
593
AliasAnalysis *aa = getPassManager ()->getAnalysis <AliasAnalysis>(getFunction ());
580
594
581
595
// Check if the source is modified within the lifetime of the temporary.
Original file line number Diff line number Diff line change @@ -1847,3 +1847,21 @@ bb0:
1847
1847
dealloc_stack %src : $*MOS
1848
1848
return %instance_3 : $MOS
1849
1849
}
1850
+
1851
+ // CHECK-LABEL: sil [ossa] @dont_optimize_use_before_copy :
1852
+ // CHECK: copy_addr
1853
+ // CHECK-LABEL: } // end sil function 'dont_optimize_use_before_copy'
1854
+ sil [ossa] @dont_optimize_use_before_copy : $@convention(thin) <B> (@in_guaranteed GS<B>, @inout GS<B>) -> () {
1855
+ bb0(%0 : $*GS<B>, %1 : $*GS<B>):
1856
+ %2 = alloc_stack $GS<B>
1857
+ %3 = struct_element_addr %2 : $*GS<B>, #GS._value
1858
+ copy_addr %1 to [init] %2 : $*GS<B>
1859
+ %5 = load [trivial] %3 : $*Builtin.Int64
1860
+ %6 = builtin "cmp_slt_Int64"(%5 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1
1861
+ copy_addr %2 to %1 : $*GS<B>
1862
+ destroy_addr %2 : $*GS<B>
1863
+ dealloc_stack %2 : $*GS<B>
1864
+ %10 = tuple ()
1865
+ return %10 : $()
1866
+ }
1867
+
You can’t perform that action at this time.
0 commit comments