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 3 4; Check that the head sample count for ticker is 0. 5; CHECK: _Z6tickeri:1566:0 6; CHECK-NOT: _Z6tickeri.resume 7 8 9/* 10 * Inputs/coroutine.perfbin is generated by compiling the following source code: 11 * clang++ coroutine.cpp -std=c++2a -g2 -o coroutine 12 */ 13 14#include <cstdint> 15#include <cstdlib> 16#include <ctime> 17#include <experimental/coroutine> 18#include <iostream> 19 20struct task { 21 struct promise_type { 22 task get_return_object() { return {}; } 23 std::experimental::suspend_never initial_suspend() { return {}; } 24 std::experimental::suspend_never final_suspend() noexcept { return {}; } 25 void return_void() {} 26 void unhandled_exception() {} 27 }; 28}; 29 30template <typename T> 31struct generator { 32 struct promise_type; 33 using handle = std::experimental::coroutine_handle<promise_type>; 34 struct promise_type { 35 int current_value; 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(); } 41 void return_void() {} 42 auto yield_value(int value) { 43 current_value = value; 44 return std::experimental::suspend_always{}; 45 } 46 }; 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; } 51 ~generator() { 52 if (coro) 53 coro.destroy(); 54 } 55 56private: 57 generator(handle h) : coro(h) {} 58 handle coro; 59}; 60 61generator<int> ticker(int count) { 62 for (int i = 0; i < count; ++i) { 63 srand(time(NULL)); 64 uint32_t a = rand() % 10 + 1; 65 uint32_t b = rand() % 10 + 1; 66 uint64_t c = 0; 67 for (int i = 0; i < 1500; ++i) { 68 c = ((uint64_t)a) + b; 69 a = b; 70 b = c % 2147483648ULL; 71 } 72 co_yield a; 73 } 74} 75 76int main() { 77 auto g = ticker(500000); 78 uint64_t ans = 0; 79 while (g.move_next()) { 80 ans += g.current_value(); 81 } 82 std::cout << ans << "\n"; 83} 84