Skip to content

Commit c82f78b

Browse files
committed
AliasAnalysis: handle copy_addr in MemBehaviorVisitor.
Only let copy_addr have side effects if the source or destination really aliases with the address in question.
1 parent 547d527 commit c82f78b

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

lib/SILOptimizer/Analysis/MemoryBehavior.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class MemoryBehaviorVisitor
174174

175175
MemBehavior visitLoadInst(LoadInst *LI);
176176
MemBehavior visitStoreInst(StoreInst *SI);
177+
MemBehavior visitCopyAddrInst(CopyAddrInst *CAI);
177178
MemBehavior visitApplyInst(ApplyInst *AI);
178179
MemBehavior visitTryApplyInst(TryApplyInst *AI);
179180
MemBehavior visitBuiltinInst(BuiltinInst *BI);
@@ -272,6 +273,34 @@ MemBehavior MemoryBehaviorVisitor::visitStoreInst(StoreInst *SI) {
272273
return MemBehavior::MayWrite;
273274
}
274275

276+
MemBehavior MemoryBehaviorVisitor::visitCopyAddrInst(CopyAddrInst *CAI) {
277+
// If it's an assign to the destination, a destructor might be called on the
278+
// old value. This can have any side effects.
279+
// We could also check if it's a trivial type (which cannot have any side
280+
// effect on destruction), but such copy_addr instructions are optimized to
281+
// load/stores anyway, so it's probably not worth it.
282+
if (!CAI->isInitializationOfDest())
283+
return MemBehavior::MayHaveSideEffects;
284+
285+
bool mayWrite = mayAlias(CAI->getDest());
286+
bool mayRead = mayAlias(CAI->getSrc());
287+
288+
if (mayRead) {
289+
if (mayWrite)
290+
return MemBehavior::MayReadWrite;
291+
292+
// A take is modelled as a write. See MemoryBehavior::MayWrite.
293+
if (CAI->isTakeOfSrc())
294+
return MemBehavior::MayReadWrite;
295+
296+
return MemBehavior::MayRead;
297+
}
298+
if (mayWrite)
299+
return MemBehavior::MayWrite;
300+
301+
return MemBehavior::None;
302+
}
303+
275304
MemBehavior MemoryBehaviorVisitor::visitBuiltinInst(BuiltinInst *BI) {
276305
// If our callee is not a builtin, be conservative and return may have side
277306
// effects.

test/SILOptimizer/mem-behavior-all.sil

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,64 @@ bb0(%0 : $*Int64Wrapper):
183183
%8 = tuple ()
184184
return %8 : $()
185185
}
186+
187+
// CHECK-LABEL: @test_copy_addr_initialize
188+
// CHECK: PAIR #0.
189+
// CHECK-NEXT: copy_addr %1 to [initialization] %0 : $*C
190+
// CHECK-NEXT: %0 = argument of bb0 : $*C
191+
// CHECK-NEXT: r=0,w=1,se=1
192+
// CHECK: PAIR #1.
193+
// CHECK-NEXT: copy_addr %1 to [initialization] %0 : $*C
194+
// CHECK-NEXT: %1 = argument of bb0 : $*C
195+
// CHECK-NEXT: r=1,w=0,se=0
196+
// CHECK: PAIR #2.
197+
// CHECK-NEXT: copy_addr %1 to [initialization] %0 : $*C
198+
// CHECK-NEXT: %2 = argument of bb0 : $*C
199+
// CHECK-NEXT: r=0,w=0,se=0
200+
sil @test_copy_addr_initialize : $@convention(thin) (@inout C, @inout C) -> @out C {
201+
bb0(%0 : $*C, %1 : $*C, %2: $*C):
202+
copy_addr %1 to [initialization] %0 : $*C
203+
%6 = tuple ()
204+
return %6 : $()
205+
}
206+
207+
// CHECK-LABEL: @test_copy_addr_assign
208+
// CHECK: PAIR #0.
209+
// CHECK-NEXT: copy_addr %1 to %0 : $*C
210+
// CHECK-NEXT: %0 = argument of bb0 : $*C
211+
// CHECK-NEXT: r=1,w=1,se=1
212+
// CHECK: PAIR #1.
213+
// CHECK-NEXT: copy_addr %1 to %0 : $*C
214+
// CHECK-NEXT: %1 = argument of bb0 : $*C
215+
// CHECK-NEXT: r=1,w=1,se=1
216+
// CHECK: PAIR #2.
217+
// CHECK-NEXT: copy_addr %1 to %0 : $*C
218+
// CHECK-NEXT: %2 = argument of bb0 : $*C
219+
// CHECK-NEXT: r=1,w=1,se=1
220+
sil @test_copy_addr_assign : $@convention(thin) (@inout C, @inout C, @inout C) -> () {
221+
bb0(%0 : $*C, %1 : $*C, %2: $*C):
222+
copy_addr %1 to %0 : $*C
223+
%6 = tuple ()
224+
return %6 : $()
225+
}
226+
227+
// CHECK-LABEL: @test_copy_addr_take
228+
// CHECK: PAIR #0.
229+
// CHECK-NEXT: copy_addr [take] %1 to [initialization] %0 : $*C
230+
// CHECK-NEXT: %0 = argument of bb0 : $*C
231+
// CHECK-NEXT: r=0,w=1,se=1
232+
// CHECK: PAIR #1.
233+
// CHECK-NEXT: copy_addr [take] %1 to [initialization] %0 : $*C
234+
// CHECK-NEXT: %1 = argument of bb0 : $*C
235+
// CHECK-NEXT: r=1,w=1,se=1
236+
// CHECK: PAIR #2.
237+
// CHECK-NEXT: copy_addr [take] %1 to [initialization] %0 : $*C
238+
// CHECK-NEXT: %2 = argument of bb0 : $*C
239+
// CHECK-NEXT: r=0,w=0,se=0
240+
sil @test_copy_addr_take : $@convention(thin) (@in C, @inout C) -> @out C {
241+
bb0(%0 : $*C, %1 : $*C, %2: $*C):
242+
copy_addr [take] %1 to [initialization] %0 : $*C
243+
%6 = tuple ()
244+
return %6 : $()
245+
}
246+

0 commit comments

Comments
 (0)