1 ; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/coroutine.perfscript --binary=%S/Inputs/coroutine.perfbin --output=%t
2 ; RUN: FileCheck %s --input-file %t --check-prefix=CHECK
4 ; Check that the head sample count for ticker is 0.
5 ; CHECK: _Z6tickeri:1566:0
6 ; CHECK-NOT: _Z6tickeri.resume
10 * Inputs/coroutine.perfbin is generated by compiling the following source code:
11 * clang++ coroutine.cpp -std=c++2a -g2 -o coroutine
17 #include <experimental/coroutine>
22 task get_return_object() { return {}; }
23 std::experimental::suspend_never initial_suspend() { return {}; }
24 std::experimental::suspend_never final_suspend() noexcept { return {}; }
26 void unhandled_exception() {}
33 using handle = std::experimental::coroutine_handle<promise_type>;
36 static auto get_return_object_on_allocation_failure() { return generator{nullptr}; }
37 auto get_return_object() { return generator{handle::from_promise(*this)}; }
38 auto initial_suspend() { return std::experimental::suspend_always{}; }
39 auto final_suspend() { return std::experimental::suspend_always{}; }
40 void unhandled_exception() { std::terminate(); }
42 auto yield_value(int value) {
43 current_value = value;
44 return std::experimental::suspend_always{};
47 bool move_next() { return coro ? (coro.resume(), !coro.done()) : false; }
48 int current_value() { return coro.promise().current_value; }
49 generator(generator const &) = delete;
50 generator(generator &&rhs) : coro(rhs.coro) { rhs.coro = nullptr; }
57 generator(handle h) : coro(h) {}
61 generator<int> ticker(int count) {
62 for (int i = 0; i < count; ++i) {
64 uint32_t a = rand() % 10 + 1;
65 uint32_t b = rand() % 10 + 1;
67 for (int i = 0; i < 1500; ++i) {
68 c = ((uint64_t)a) + b;
70 b = c % 2147483648ULL;
77 auto g = ticker(500000);
79 while (g.move_next()) {
80 ans += g.current_value();
82 std::cout << ans << "\n";