Skip to content

Commit 997bb9f

Browse files
eecksteinatrick
authored andcommitted
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. (cherry picked from commit c82f78b)
1 parent 64d091d commit 997bb9f

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
@@ -173,6 +173,7 @@ class MemoryBehaviorVisitor
173173

174174
MemBehavior visitLoadInst(LoadInst *LI);
175175
MemBehavior visitStoreInst(StoreInst *SI);
176+
MemBehavior visitCopyAddrInst(CopyAddrInst *CAI);
176177
MemBehavior visitApplyInst(ApplyInst *AI);
177178
MemBehavior visitTryApplyInst(TryApplyInst *AI);
178179
MemBehavior visitBuiltinInst(BuiltinInst *BI);
@@ -270,6 +271,34 @@ MemBehavior MemoryBehaviorVisitor::visitStoreInst(StoreInst *SI) {
270271
return MemBehavior::MayWrite;
271272
}
272273

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