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

    <tr>
        <th>Summary</th>
        <td>
            Coroutine compilation time possibly affected by array bounds checking
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

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

<pre>
    The compilation time problem of c++20 coroutine still exists in clang 16.0.2, after the fix to #58650.

Here shows the comparison of 2 scenarios (`a2.cpp` and `a3.app`).

- `gen2.cpp` generates use cases that possibly enable bounds checking.

``` c++
#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 <vector>\n");
 printf("#include \"task.h\"\n");
  printf("task t() {\n");
 printf("std::vector<int> v(%d);\n", n);
  printf("int val = 0;\n");
  for (int i = 1; i <= n; i++) printf("if (v[%d]) val++;\n", i);
  printf("printf(\"%%d\\n\", val);\n");
 printf("co_return;\n");
  printf("}\n");
  return 0;
}
```

- `gen3.cpp` generates use cases that try to avoid bounds checking.

``` c++
#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 <vector>\n");
  printf("#include \"task.h\"\n");
  printf("task t() {\n");
 printf("std::vector<int> v(%d);\n", n);
  printf("int val = 0;\n");
  printf("auto foo = [&](int i) { if (v[i]) val++; };\n");
  for (int i = 1; i <= n; i++) printf("foo(%d);\n", i);
 printf("printf(\"%%d\\n\", val);\n");
 printf("co_return;\n");
  printf("}\n");
  return 0;
}
```

Generated files:

- `a2.cpp` is like:

``` c++
#include <cstdio>
#include <vector>
#include "task.h"
task t() {
std::vector<int> v(100000);
int val = 0;
if (v[1]) val++;
if (v[2]) val++;
if (v[3]) val++;
if (v[4]) val++;
...
if (v[99999]) val++;
if (v[100000]) val++;
printf("%d\n", val);
co_return;
}
```

- `a3.cpp` is like:

``` c++
#include <cstdio>
#include <vector>
#include "task.h"
task t() {
std::vector<int> v(100000);
int val = 0;
auto foo = [&](int i) { if (v[i]) val++; };
foo(1);
foo(2);
foo(3);
...
foo(99999);
foo(100000);
printf("%d\n", val);
co_return;
}
```

Test scripts:

- `test2.sh`

``` sh
#!/bin/sh

clang++ -o gen2 gen2.cpp
for i in 20000 40000 60000 80000 100000
do
  printf "n: %d\n" $i
 ./gen2 $i > a2.cpp
  time clang++ -c a2.cpp -std=c++20 -stdlib=libc++
 printf "\n"
done
```

- `test3.sh`

``` sh
#!/bin/sh

clang++ -o gen3 gen3.cpp
for i in 20000 40000 60000 80000 100000
do
  printf "n: %d\n" $i
  ./gen3 $i > a3.cpp
 time clang++ -c a3.cpp -std=c++20 -stdlib=libc++
  printf "\n"
done
```

Comparison:

- **test2**

```
n: 20000

real    0m7.986s
user    0m7.537s
sys 0m0.430s

n: 40000

real    0m24.699s
user    0m23.221s
sys 0m1.420s

n: 60000

real    1m2.934s
user 0m57.135s
sys     0m5.651s

n: 80000

real 1m46.364s
user    1m36.321s
sys     0m9.787s

n: 100000

real    2m51.611s
user    2m40.468s
sys 0m10.736s
```

- **test3**

```
n: 20000

real 0m2.319s
user    0m2.194s
sys     0m0.120s

n: 40000

real 0m5.908s
user    0m5.227s
sys     0m0.667s

n: 60000

real    0m10.007s
user    0m9.271s
sys 0m0.712s

n: 80000

real    0m13.532s
user    0m11.979s
sys 0m1.522s

n: 100000

real    0m26.432s
user 0m23.669s
sys     0m2.697s
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkWN2SozoOfhrnRtUuW-b3IhfdyfbuA8z9lgMm8Q7gFHZ6p_fpt2xIAgGm-5wzcy5mUl00kaVPsvRJwUhr9bFVakviFxLvN_LiTqbblu__s93mYMr37ZeTgsI0Z11Lp00LTjcKzp051KoBU0FB8IXgCzIoTGcuTrcKrNN1Deqbts6CbqGoZXsEnlBGkeAOZOVUB-6koNLfwBkgKOIsiRklbE_Yc3_9l-oU2JP5rw2qPgjZaWta7xbBFqqVnTYWCGYkYRJpcT6ThIFsS_ACQWUQEMwnwE9-9ajam8FRtaqTTlm4WAWFtMq7lA7Oxlp9qN9BtfJQKziYS1taKE6q-Krb4wTVOwp_15QMYhS6LepLqYCIXSGtVZ0j4h-Lq9aV2nxnsdaH-2q46tZBI3VLMPO3sjsWPsPFSXZA8Jngs-yObwRzIOkQEcAQBGZeHYjYE7EHJJgTcdPxaK1fA-mM7nXfSPzCSbyfaJ473brK1wBxbTvxrg2rYwfrdm-qcKZbsVszi3cE0Un7lZ76-w-demVw4b7PzgferCuJeCbi-RrfTre-kvAW1uNysLzC7KBdd-7T-ybrkGA2thobVMYXMRRWB01OxEu43flvbfg2kA3zKX7lLX3BQmShZt7hoD0JU6-Heb_vc4pxD7cL5oNs1wPnK9sY4xXm351yl65d2_KkvOl-UadH6NPWt0K6f-jBpXYXH7a76979NJJvRpe_SK__0Fb_u3v9t2r2sYG8OAOVMcEi9HASatGPgmELcO9xvdDg4Lvixw-Wypi1DOjVbP4KY-Sfw9QoodK1sp4dj0Pm_giiLdT6q3pQ-tzY-N5guLfLbPHWEIj94ozyQfpdYnPmP-M0zajbS2_M40s_LQ86-Akd8QmdaFWHUvqonPvPJ0CHLa8pTidQ4Gw7Y2vQnHDysz9LUvwmjPmREy0A9nOIjz33IpyLxFh040q_1vNkZjLf189jwhdlHdii02e3OFacsg6pPT2Y3blhT7fiEuQEXw_-IeH1Ju6j8oewPpfwZPxDEMLtEDTsvAPtz2vo9w5RuCbhmoXrkJSgXJrprPV0aol4hlFugGCkBzVK8DX49DLw9JEj19CfKycxFoMGPAUG7u8nzafr49G-1odJY4yCudZniLZVH_WiT7P4CWkWcHv4_PlpvuZZjPI88r2cZvGH0_wn87y7neHnPA8PsIHq_e1iDfqvIQF4T1J_7ZSsAQBYk9I8S2wvvVjVXaWxSAepfbfAGkYjwewYIyBH68gY0STPZ9AoKCKfYHMa4QJ2sobNG6S5iMbQrIlTykU8wu3dxTSJ-Rw7W8TmTZRQkUQPQfNGJFRMgu7Bc5pm6Rx8TMpp5NjEnCacPzjAJmI0SrJpVhhNxbU0a614Y4L4K0xgDVLBF2pFeR7Nds0oXyrXMhV8BXKWzaBjipguQCfJQkJXmRCyxFg6g88ppvyBwCnHzxKhhxY0FjiD5pzmaf5A4BgXsNd5wBpMaDQFD62RJPksKUiTPH3kwabcijIXudyoLU8yjHgq4nhz2qZpFnPOqlJURVEc8jirMqWSUom0UDGTG71FhoJFGHPGch7TqEq4qBKRHFLFMlGRiKlG6prW9VtDTXfcaGsvapugiLJNLQ-qtteXoN3WKz0dLkdLIlZr6-zdzGlXq-3u9q5z_m70-s5QVpUq_Hnh8A6y6-T74yuFzaWrtyfnzuFXH1_95NbudDnQwjQEX73P4d_TuTP_UYUj-BritgRfQ-j_DwAA___pOKN3">