From 0d24de788fe596814723a4fb8fe7a18b1dbf67c1 Mon Sep 17 00:00:00 2001 From: Roman Levenstein Date: Wed, 22 Feb 2017 08:01:46 -0800 Subject: [PATCH] [sil-combine] Add peephole: alloc_ref/set_deallocating/dealloc_ref -> remove these instructions Discovered this missing peephole while looking at the performance of #7420 --- lib/SILOptimizer/SILCombiner/SILCombiner.h | 1 + .../SILCombiner/SILCombinerMiscVisitors.cpp | 27 +++++++++++++++++++ test/SILOptimizer/sil_combine.sil | 24 +++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/lib/SILOptimizer/SILCombiner/SILCombiner.h b/lib/SILOptimizer/SILCombiner/SILCombiner.h index 81ff67262f14e..9a335e3369263 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombiner.h +++ b/lib/SILOptimizer/SILCombiner/SILCombiner.h @@ -190,6 +190,7 @@ class SILCombiner : SILInstruction *visitUpcastInst(UpcastInst *UCI); SILInstruction *visitLoadInst(LoadInst *LI); SILInstruction *visitAllocStackInst(AllocStackInst *AS); + SILInstruction *visitAllocRefInst(AllocRefInst *AR); SILInstruction *visitSwitchEnumAddrInst(SwitchEnumAddrInst *SEAI); SILInstruction *visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI); SILInstruction *visitPointerToAddressInst(PointerToAddressInst *PTAI); diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp index a20c9e891c002..bb595095f50ef 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp @@ -391,6 +391,33 @@ SILInstruction *SILCombiner::visitAllocStackInst(AllocStackInst *AS) { return eraseInstFromFunction(*AS); } +SILInstruction *SILCombiner::visitAllocRefInst(AllocRefInst *AR) { + if (!AR) + return nullptr; + // Check if the only uses are deallocating stack or deallocating. + SmallPtrSet ToDelete; + bool HasNonRemovableUses = false; + for (auto UI = AR->use_begin(), UE = AR->use_end(); UI != UE;) { + auto *Op = *UI; + ++UI; + auto *User = Op->getUser(); + if (!isa(User) && !isa(User)) { + HasNonRemovableUses = true; + break; + } + ToDelete.insert(User); + } + + if (HasNonRemovableUses) + return nullptr; + + // Remove the instruction and all its uses. + for (auto *I : ToDelete) + eraseInstFromFunction(*I); + eraseInstFromFunction(*AR); + return nullptr; +} + SILInstruction *SILCombiner::visitLoadInst(LoadInst *LI) { // (load (upcast-ptr %x)) -> (upcast-ref (load %x)) Builder.setCurrentDebugScope(LI->getDebugScope()); diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil index 511a6b2e7da72..47ac9265f5473 100644 --- a/test/SILOptimizer/sil_combine.sil +++ b/test/SILOptimizer/sil_combine.sil @@ -3137,3 +3137,27 @@ bb0(%0 : $VV): return %26 : $() } +// CHECK-LABEL: sil @remove_unused_alloc_ref +// CHECK-NEXT: bb0 +// CHECK-NEXT: %0 = tuple () +// CHECK-NEXT: return %0 : $() +sil @remove_unused_alloc_ref : $@convention(thin) () -> () { +bb0: + %1 = alloc_ref $B + dealloc_ref %1 : $B + %3 = tuple () + return %3 : $() +} + +// CHECK-LABEL: sil @remove_unused_alloc_ref_stack +// CHECK-NEXT: bb0 +// CHECK-NEXT: %0 = tuple () +// CHECK-NEXT: return %0 : $() +sil @remove_unused_alloc_ref_stack : $@convention(thin) () -> () { +bb0: + %1 = alloc_ref [stack] $B + set_deallocating %1 : $B + dealloc_ref [stack] %1 : $B + %3 = tuple () + return %3 : $() +}