<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - coroutines generator optimization"
href="https://bugs.llvm.org/show_bug.cgi?id=39806">39806</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>coroutines generator optimization
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Common Code Generator Code
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>trass3r@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Just saw this code: <a href="https://arbmind.github.io/2018-cogen-en/#61.1">https://arbmind.github.io/2018-cogen-en/#61.1</a>
<a href="https://godbolt.org/z/dT5KBO">https://godbolt.org/z/dT5KBO</a>
#include <experimental/coroutine>
namespace coro = std::experimental;
template<class T>
struct Generator {
using element_type = T;
struct Promise;
using promise_type = Promise;
using Handle = coro::coroutine_handle<Promise>;
struct Promise {
T current_m;
auto get_return_object() noexcept {
return Generator{Handle::from_promise(*this)};
}
auto initial_suspend() noexcept {
return coro::suspend_always{};
}
auto final_suspend() noexcept {
return coro::suspend_always{};
}
auto yield_value(T value) noexcept {
current_m = std::move(value);
return coro::suspend_always{};
}
auto return_void() noexcept {}
auto unhandled_exception() noexcept {}
};
auto operator*() const -> const T & {
return h.promise().current_m;
}
auto operator-> () const -> const T * {
return &h.promise().current_m;
}
auto move() -> T {
return std::move(h.promise().current_m);
}
operator bool() const { return h && !h.done(); }
auto operator++() -> Generator & {
if (h) h.resume();
return *this;
}
struct End {};
static auto end() -> End { return {}; }
auto begin() {
struct Iterator {
using iterator_category =
std::input_iterator_tag;
using difference_type = ptrdiff_t;
using value_type = T;
using reference = T const &;
using pointer = T const *;
Generator &gen;
auto operator*() const -> const T & {
return *gen;
}
auto operator++() -> Iterator & {
++gen;
return *this;
}
bool operator==(End) const { return !gen; }
bool operator!=(End) const { return gen; }
};
return Iterator{++(*this)};
}
~Generator() {
if (h) h.destroy();
}
Generator() = delete;
Generator(const Generator &) = delete;
Generator(Generator &&o) noexcept
: h(o.h) {
o.h = {};
}
auto operator=(const Generator &) = delete;
auto operator=(Generator &&) = delete;
private:
Generator(Handle h)
: h(h) {}
private:
Handle h;
};
inline auto iota(size_t n) -> Generator<size_t> {
for (auto i = 0u; i < n; ++i)
co_yield i;
}
template<size_t N>
auto fixedSum() {
auto sum = 0u;
for (auto v : iota(N + 1)) sum += v;
return sum;
}
auto test() {
return fixedSum<100>();
}
auto dynSum(size_t n) {
auto sum = 0u;
for (auto v : iota(n + 1))
sum += v;
return sum;
}
auto simpleSum(size_t n) {
auto sum = 0u;
for (auto v = 0; v <= n; ++v)
sum += v;
return sum;
}
# clang -std=c++2a -O3 -stdlib=libc++ -fcoroutines-ts
test(): # @test()
mov eax, 5050
ret
dynSum(unsigned long): # @dynSum(unsigned long)
add rdi, 1
sete cl
je .LBB1_1
xor eax, eax
xor esi, esi
.LBB1_4: # =>This Inner Loop Header: Depth=1
mov edx, esi
add eax, esi
mov esi, 0
test cl, 1
mov ecx, 0
jne .LBB1_4
add edx, 1
xor ecx, ecx
mov esi, edx
cmp rdi, rdx
ja .LBB1_4
ret
.LBB1_1:
xor eax, eax
ret
simpleSum(unsigned long): # @simpleSum(unsigned long)
mov rax, rdi
lea rcx, [rdi - 1]
imul rcx, rdi
shr rcx
add eax, ecx
ret</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>