Skip to content

Commit 307959e

Browse files
committed
[IRGen] Don't mark calls to swift_task_alloc as 'readnone'.
Doing so causes later passes to coalesce swift_task_alloc calls.
1 parent c42add9 commit 307959e

File tree

3 files changed

+88
-3
lines changed

3 files changed

+88
-3
lines changed

lib/IRGen/IRGenFunction.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,6 @@ Address IRGenFunction::emitTaskAlloc(llvm::Value *size, Alignment alignment) {
495495
auto *call = Builder.CreateCall(IGM.getTaskAllocFn(), {getAsyncTask(), size});
496496
call->setDoesNotThrow();
497497
call->setCallingConv(IGM.SwiftCC);
498-
call->addAttribute(llvm::AttributeList::FunctionIndex,
499-
llvm::Attribute::ReadNone);
500498
auto address = Address(call, alignment);
501499
return address;
502500
}

test/Concurrency/Runtime/basic_future.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// REQUIRES: executable_test
44
// REQUIRES: concurrency
55
// REQUIRES: OS=macosx
6-
// REQUIRES: CPU=x86_64
6+
// XFAIL: CPU=arm64e
77

88
import Dispatch
99

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-concurrency)
2+
3+
// REQUIRES: executable_test
4+
// REQUIRES: concurrency
5+
// REQUIRES: OS=macosx
6+
// XFAIL: CPU=arm64e
7+
8+
import Dispatch
9+
10+
extension DispatchQueue {
11+
func async<R>(execute: @escaping () async throws -> R) -> Task.Handle<R> {
12+
let handle = Task.runDetached(operation: execute)
13+
14+
// Run the task
15+
_ = { self.async { handle.run() } }()
16+
17+
return handle
18+
}
19+
20+
func async<R>(in group: DispatchGroup,
21+
execute: @escaping () async throws -> R) -> Task.Handle<R> {
22+
let handle = Task.runDetached(operation: execute)
23+
24+
// Run the task
25+
group.enter()
26+
_ = {
27+
self.async {
28+
handle.run()
29+
group.leave()
30+
}
31+
}()
32+
33+
return handle
34+
}
35+
}
36+
37+
func fib(_ n: Int) -> Int {
38+
var first = 0
39+
var second = 1
40+
for _ in 0..<n {
41+
let temp = first
42+
first = second
43+
second = temp + first
44+
}
45+
return first
46+
}
47+
48+
func asyncFib(_ n: Int, group: DispatchGroup, queue: DispatchQueue) async -> Int {
49+
if n == 0 || n == 1 {
50+
return n
51+
}
52+
53+
let first = queue.async(in: group) {
54+
await asyncFib(n - 2, group: group, queue: queue)
55+
}
56+
57+
let second = queue.async(in: group) {
58+
await asyncFib(n - 1, group: group, queue: queue)
59+
}
60+
61+
// Sleep a random amount of time waiting on the result producing a result.
62+
usleep(UInt32.random(in: 0..<100) * 1000)
63+
64+
let result = await try! first.get() + second.get()
65+
66+
// Sleep a random amount of time before producing a result.
67+
usleep(UInt32.random(in: 0..<100) * 1000)
68+
69+
return result
70+
}
71+
72+
func runFibonacci(_ n: Int) {
73+
let queue = DispatchQueue(label: "concurrent", attributes: .concurrent)
74+
let group = DispatchGroup()
75+
76+
var result = 0
77+
_ = queue.async(in: group) {
78+
result = await asyncFib(n, group: group, queue: queue)
79+
}
80+
group.wait()
81+
82+
print()
83+
print("Async fib = \(result), sequential fib = \(fib(n))")
84+
assert(result == fib(n))
85+
}
86+
87+
runFibonacci(15)

0 commit comments

Comments
 (0)