[llvm-bugs] [Bug 39806] New: coroutines generator optimization
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Nov 27 03:29:20 PST 2018
https://bugs.llvm.org/show_bug.cgi?id=39806
Bug ID: 39806
Summary: coroutines generator optimization
Product: libraries
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: enhancement
Priority: P
Component: Common Code Generator Code
Assignee: unassignedbugs at nondot.org
Reporter: trass3r at gmail.com
CC: llvm-bugs at lists.llvm.org
Just saw this code: https://arbmind.github.io/2018-cogen-en/#61.1
https://godbolt.org/z/dT5KBO
#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
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181127/7c43bdc5/attachment.html>
More information about the llvm-bugs
mailing list