Skip to content

Commit 304d2be

Browse files
authored
Merge pull request #7580 from swiftix/effects-readonly
Do not automatically map Swfit @effects(readonly) to LLVM's readonly attribute
2 parents fa21e00 + 1180c3d commit 304d2be

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,8 +1697,21 @@ static bool isReadOnlyFunction(SILFunction *f) {
16971697
return false;
16981698

16991699
auto Eff = f->getEffectsKind();
1700-
return Eff == EffectsKind::ReadNone ||
1701-
Eff == EffectsKind::ReadOnly;
1700+
1701+
// Swift's readonly does not automatically match LLVM's readonly.
1702+
// Swift SIL optimizer relies on @effects(readonly) to remove e.g.
1703+
// dead code remaining from initializers of strings or dictionaries
1704+
// of variables that are not used. But those initializers are often
1705+
// not really readonly in terms of LLVM IR. For example, the
1706+
// Dictionary.init() is marked as @effects(readonly) in Swift, but
1707+
// it does invoke reference-counting operations.
1708+
if (Eff == EffectsKind::ReadOnly || Eff == EffectsKind::ReadNone) {
1709+
// TODO: Analyze the body of function f and return true if it is
1710+
// really readonly.
1711+
return false;
1712+
}
1713+
1714+
return false;
17021715
}
17031716

17041717
static clang::GlobalDecl getClangGlobalDeclForFunction(const clang::Decl *decl) {

test/IRGen/readonly.sil

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,32 @@ sil @XXX_ctor : $@convention(method) (@owned XXX) -> @owned XXX
1212

1313
// CHECK: target datalayout
1414

15-
// No @owned or @out parameters -- function is read only at LLVM level
15+
// No @owned or @out parameters -- function is not read only at LLVM level,
16+
// because Swift level read only attribute is not automatically mapped
17+
// to the LLVM read only attribute, unless IRGen can prove by analyzing
18+
// the function body that this function is really read only.
1619

17-
// CHECK: ; Function Attrs: readonly
18-
// CHECK-NEXT: define{{( protected)?}} swiftcc void @function_foo(
20+
// CHECK-NOT: ; Function Attrs: readonly
21+
// CHECK: define{{( protected)?}} swiftcc void @function_foo(
1922
sil [readonly] @function_foo : $@convention(thin) (Int) -> () {
2023
bb0(%0 : $Int):
2124
%1 = tuple ()
2225
return %1 : $()
2326
}
2427

28+
// No @owned or @out parameters -- function is not read only at LLVM level,
29+
// because Swift level read none attribute is not automatically mapped
30+
// to the LLVM read only attribute, unless IRGen can prove by analyzing
31+
// the function body that this function is really read only or read none.
32+
33+
// CHECK-NOT: ; Function Attrs: readonly
34+
// CHECK: define{{( protected)?}} swiftcc void @function_foo2(
35+
sil [readnone] @function_foo2 : $@convention(thin) (Int) -> () {
36+
bb0(%0 : $Int):
37+
%1 = tuple ()
38+
return %1 : $()
39+
}
40+
2541
// There's an @owned parameter, and destructors can call arbitrary code
2642
// -- function is not read only at LLVM level
2743

0 commit comments

Comments
 (0)