brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.6 KiB · e75beda Raw
105 lines · cpp
1// This tests that the coroutine heap allocation elision optimization could happen succesfully.2// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -O2 -emit-llvm %s -o - | FileCheck %s3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -O2 -emit-llvm %s \4// RUN:   -fcxx-exceptions -fexceptions -o - | FileCheck %s5 6#include "Inputs/coroutine.h"7#include "Inputs/numeric.h"8 9template <typename T> struct generator {10  struct promise_type {11    T current_value;12    std::suspend_always yield_value(T value) {13      this->current_value = value;14      return {};15    }16    std::suspend_always initial_suspend() { return {}; }17    std::suspend_always final_suspend() noexcept { return {}; }18    generator get_return_object() { return generator{this}; };19    void unhandled_exception() {}20    void return_void() {}21  };22 23  struct iterator {24    std::coroutine_handle<promise_type> _Coro;25    bool _Done;26 27    iterator(std::coroutine_handle<promise_type> Coro, bool Done)28        : _Coro(Coro), _Done(Done) {}29 30    iterator &operator++() {31      _Coro.resume();32      _Done = _Coro.done();33      return *this;34    }35 36    bool operator==(iterator const &_Right) const {37      return _Done == _Right._Done;38    }39 40    bool operator!=(iterator const &_Right) const { return !(*this == _Right); }41    T const &operator*() const { return _Coro.promise().current_value; }42    T const *operator->() const { return &(operator*()); }43  };44 45  iterator begin() {46    p.resume();47    return {p, p.done()};48  }49 50  iterator end() { return {p, true}; }51 52  generator(generator const &) = delete;53  generator(generator &&rhs) : p(rhs.p) { rhs.p = nullptr; }54 55  ~generator() {56    if (p)57      p.destroy();58  }59 60private:61  explicit generator(promise_type *p)62      : p(std::coroutine_handle<promise_type>::from_promise(*p)) {}63 64  std::coroutine_handle<promise_type> p;65};66 67template <typename T>68generator<T> seq() {69  for (T i = {};; ++i)70    co_yield i;71}72 73template <typename T>74generator<T> take_until(generator<T> &g, T limit) {75  for (auto &&v : g)76    if (v < limit)77      co_yield v;78    else79      break;80}81 82template <typename T>83generator<T> multiply(generator<T> &g, T factor) {84  for (auto &&v : g)85    co_yield v *factor;86}87 88template <typename T>89generator<T> add(generator<T> &g, T adder) {90  for (auto &&v : g)91    co_yield v + adder;92}93 94int main() {95  auto s = seq<int>();96  auto t = take_until(s, 10);97  auto m = multiply(t, 2);98  auto a = add(m, 110);99  return std::accumulate(a.begin(), a.end(), 0);100}101 102// CHECK-LABEL: define{{.*}} i32 @main(103//   CHECK: ret i32 1190104//   CHECK-NOT: call{{.*}}_Znwm105