<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/58650>58650</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Compilation time of coroutine grows non-linearly
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          dyzsr
      </td>
    </tr>
</table>

<pre>
    In clang 15.0.3, the compilation time of coroutine seems to grow non-linearly against code size (I have tested on linux and macOS).

Here are the simplified examples I generated.

- `task.h` which defines the coroutine data structures:

``` cpp
#include <coroutine>

struct promise;

struct task : std::coroutine_handle<promise> {
  using promise_type = struct promise;
};

struct promise {
  task get_return_object() { return {task::from_promise(*this)}; }
  std::suspend_always initial_suspend() noexcept { return {}; }
  std::suspend_always final_suspend() noexcept { return {}; }
  void return_void() noexcept {}
  void unhandled_exception() {}
};
```

- `gen.cpp` which generates the coroutine use cases:

``` cpp
#include <cassert>
#include <cstdio>
#include <cstdlib>

int main(int argc, char **argv) {
  assert(argc == 2);
  int n = atoi(argv[1]);
  printf("#include <cstdio>\n");
  printf("#include \"task.h\"\n");
  printf("task t() {\n");
  for (int i = 1; i <= n; i++) printf("int cond_%d = 1;\n", i);
  printf("int val = 0;\n");
  for (int i = 1; i <= n; i++) printf("if (cond_%d) val++;\n", i);
  printf("printf(\"%%d\\n\", val);\n");
  printf("co_return;\n");
  printf("}\n");
  return 0;
}
```

- `test.sh` used to run the test:

``` sh
#!/bin/sh

clang++ -o gen gen.cpp
for i in 2000 4000 6000 8000 10000 12000 14000 16000 18000 20000
do
  printf "n: %d\n" $i
  ./gen $i > a.cpp
  time clang++ -c a.cpp -std=c++20 -stdlib=libc++
  printf "\n"
done
```

The generated `a.cpp` is like:

``` cpp
#include <cstdio>
#include "task.h"
task t() {
int cond_1 = 1;
int cond_2 = 1;
int cond_3 = 1;
...
int val = 0;
if (cond_1) val++;
if (cond_2) val++;
if (cond_3) val++;
...
printf("%d\n", val);
co_return;
}
```

My test result:

```
n: 2000

real    0m2.697s
user    0m2.583s
sys     0m0.105s

n: 4000

real    0m8.662s
user    0m8.314s
sys     0m0.332s

n: 6000

real    0m19.107s
user    0m18.330s
sys     0m0.734s

n: 8000

real    0m35.622s
user    0m34.018s
sys     0m1.436s

n: 10000

real    0m50.344s
user    0m48.158s
sys     0m1.959s

n: 12000

real    1m12.844s
user    1m9.896s
sys     0m2.728s

n: 14000

real    1m57.271s
user    1m52.938s
sys     0m4.076s

n: 16000

real    2m42.044s
user    2m35.904s
sys     0m5.635s

n: 18000

real    3m28.608s
user    3m20.904s
sys     0m7.057s

n: 20000

real    4m6.561s
user    3m56.836s
sys     0m9.012s
```

The compilation speed is really slow for very large coroutines (which can be generated by program in our use cases).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJytV0uT2ygQ_jXyhRoK0Pvgw8TO1OawtYfduwtL2Gajh0sgT5xfv91Ili3JSiaprZrBqB8fTb-AfZ1f118qkhWyOhIeUkZ9T2yIPSmS1eVZF9LquiJWl4rUB6A1dWt1pYhRqjTE1uTY1O-kqquXAsiyKa5EHqWujAXhHOT0d0U8kXwhJ3lRxCpjVU4AEsTbb0RWOSll9tffnkipx7Yee-3GP1SjiIR_NMXo8lzogwZN9U3CXBnyhRxVpRoJcCPFF-JFzErzlZ5gQt5POjuRXB3AOtPv67aHXFpJjG3azLaNMp7_-ggE2t0fyc7nniR8XWVFC_vy_M0A5PmfHxU7RHJu6lIbYH56wkQDAeMVls9xXf91QNudwCkF6G0GhM_Ei3sUQlqjIVY9b2evZzRmS5ZWjbfPLegFH5GdUUdld40Ch1S7ev-vyiwED4KDcqSj4xRFO7sPgLO7rYqir_akDWh0KxP86fGHvZrWnFWV72TxLq-G6EpbLYtdT-4XrGr1LVNnO1n547AQ8t8HvdQ67wV2OH-iP5Vuqy5y-a6TgcK5-24QHgXklmKzBIbcpph2Qwbfkn2awy2EMJPmN7JXGqMae8_dMRecqusfMAu9n6S9riyUssY941Q2xwxbSXaSDTQAgHgF0uXmjt5xvREiQXHMY0xlgdnjDzKIVrkcl7bWnezFCz9xL9yOJc8NyB6c08XSfsJN5bgf0Qs3QOh7iZv_VNuV0EPJPFU41OgR5yXt9sUx-XC6wa_KfXnik_tLR_iok9WQ454I80F3WGWDeku2oe5FFk6LPWr9X7YdUHOwDtmwXC_7USPv887hInRY8IHqPW3TAadLm3gEzOq-nX1EGIvzmUzfKdiorf6khPGoo8YdQlCkOZ6VTVu58kXWYr2Cyq3mPME98bbHmnobyG50B3bnWvJSY3cgt5bh-BhGDZVDBGOMBDhEOCQ4cOZGx-KOxx2TOy6S-93k9dhJEF9R4anVxwQdBfNA38QoGIq2II3guSXvJpHuFjGyPOsEyIvr4dusowvmCK7FbGHsyXNbbrHqjYWTeDkm_4DfhxsDxkfeGqw2cBn5qn65gS63yKFp3GybtYWhY7py4fdKHjPEEsOfMCild4lRkXfUe2nyWV1OJcRPJfznEoMR4346pMq4cLs8fqzOD1TWn1dXPFCQpi0Wa6j7dJkqhmTuxkaBASxlpaBRGpuOCPXZ9MQw8XuiuRpHY5Sz0DxiOOBgCTihUSSmwAn1eTAD9n0xB46WgHkKlsxM5gDtsxl07Adz6GQJ2g9pJGZG-wFlPJlAcxr40RyasyXsEPYZBFPsIKE8nGOnYfoEeyGIvOSCJlNsXqY0SaMJtKCxSJ5AL4SRl2FMRcyn0KGgqT81G9wUP3PJQiRFGQjKpmYLDELKpkkCgfGfZB9fCKVfCsg_loyxgcqeYMeUhfEcWyyEMigjGkZ8Ch1GNPGn7k4hc4bcXmrHjy9MuKRDW4ZWjIvBI9IU8KzEU-yimisp4Mr3cOs12Im6e3EmK7J_7Oz7Kz5tjo0s8fir2-bhigxvzJVa8yiKkjgNhb_K136e-qlcWW0Ltd788MmLL10zeuqu2qZYn6w9u9u3eMPTT9tTu6ewNfgoisvt5wWM6l5Tb9qYFo15C5MoZKvTOtjLPBEJP8T7g4qiMMj9KA5VHMmURXt-WBVyrwqzhjsvHsDqnTgIdwBuV3otmBCcQbYGDDZFM6hFecgzsRd5zJLQC5iCi3lB0Q5aN8dVs3Ym7dujAWahjTV3JlzJ9bFSyi0H-LK1p7pZ59fvplm5hdfO8P8Anopz7g">