C opt未适当降低协同程序的LLVM-IR

C opt未适当降低协同程序的LLVM-IR,c,clang,coroutine,llvm-ir,C,Clang,Coroutine,Llvm Ir,我试图理解llvm是如何降低协程的。为此,我创建了一个名为llvm\u intrinsics.c的小型c程序,该程序调用llvm内置: #include <stdio.h> #include <stdlib.h> #include <stddef.h> void* f(int n) { __builtin_coro_id(0, 0, 0, 0); int8_t* hdl = __builtin_coro_begin((int*)malloc(__bu

我试图理解llvm是如何降低协程的。为此,我创建了一个名为
llvm\u intrinsics.c
的小型c程序,该程序调用llvm内置:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

void* f(int n) {
  __builtin_coro_id(0, 0, 0, 0);
  int8_t* hdl = __builtin_coro_begin((int*)malloc(__builtin_coro_size()));
  for (;;) {
    printf("%d\n",++n);
    switch (__builtin_coro_suspend(0)) {
      case 0:
        continue;
      case 1:
        goto CLEANUP;
      default:
        goto SUSPEND;
    }
  }
CLEANUP:
  free(__builtin_coro_free(hdl));
SUSPEND:
  __builtin_coro_end(hdl, 0);
  return hdl;
}

int main() {
  void* hdl = f(4);
  __builtin_coro_resume(hdl);
  __builtin_coro_resume(hdl);
  __builtin_coro_destroy(hdl);
  return 0;
}
clang
当构建C时根本不运行llvm转换过程,因此需要手动运行
opt
。这通常是不幸的,但由于本练习的目的是教学,因此它不是(尚未)一个问题。下面是一个构建脚本,该脚本构建C文件,同时发出中间LLVM-IR文件

#/usr/bin/env bash
set-e
echo“编译为LLVM IR”
clang-fcoroutines ts-emit llvm-S llvm_intrinsics.c-o llvm_intrinsics.ll
#回声“早…”
如果[“$1”=”--opt”];然后
echo“运行所有协同程序通行证”
opt-coro-early-coro-split-coro-elide-coro cleanup llvm_intrinsics.ll-S-o llvm_intrinsics_clean.ll
其他的
回显“运行每个通道”
回声“早…”
opt-coro-early llvm\u intrinsics.ll-S-o llvm\u intrinsics\u early.ll
回显“拆分…”
opt-coro split llvm\u intrinsics\u early.ll-S-o llvm\u intrinsics\u split.ll
回声“Elide…”
opt-coro-elide llvm\u intrinsics\u split.ll-S-o llvm\u intrinsics\u elide.ll
回显“清理…”
opt-coro cleanup llvm\u intrinsics\u elide.ll-S-o llvm\u intrinsics\u clean.ll
fi
echo“编译LLVM”
clang-lm llvm_intrinsics_clean.ll-o llvm_intrinsics
/llvm_本质
当使用此脚本构建和运行
llvm\u intrinsics.c
时,我期望的结果是a)成功构建,而不考虑提供给脚本的参数;b)仅打印
4\n5\n
的可执行文件。然而,它的作用是:

$ ./build.sh
Compiling into LLVM IR
Running each pass
Early..
Split..
Elide..
Cleanup..
Compiling LLVM
fatal error: error in backend: Cannot select: intrinsic %llvm.coro.size
clang-10: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 10.0.1 
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /nix/store/6pzqj9q656vc1msa675k75hmhsrfizsy-clang-10.0.1/bin
clang-10: note: diagnostic msg: PLEASE submit a bug report to  and include the crash backtrace, preprocessed source, and associated run script.
clang-10: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.


$ ./build.sh --holistic-opt | head
Compiling into LLVM IR
Running all coroutine passes
Compiling LLVM
5
6
7
8
9
10
11


换句话说,
opt
无法单独运行这些过程,当它同时运行这些过程时,似乎会运行它们,但会产生错误的结果。因为C++的协同工作很好,我想这和我误解的东西有关。除了
opt
之外,还有其他方法可以运行通行证吗?

如果您没有得到足够的响应,请将此作为一个问题打开-此外,我还要补充一点,coroutine支持较新,如果您尝试一下,clang11/12可能会更好地支持此功能。我尝试了llvm12,不幸的是,同样的问题……opt对它将接受的标志也相当挑剔。确保您通过的优化确实与clang所接受的相同。另外,请确保启用了c++20,但如果不是这样,我怀疑任何东西都不会起作用。除此之外,我又在llvm上提交了一个bug——这是一个很强的变化,你会在那里得到一个深刻的答案,你可以回到这里报告:)我确实报告了,非常感谢
$ ./build.sh
Compiling into LLVM IR
Running each pass
Early..
Split..
Elide..
Cleanup..
Compiling LLVM
fatal error: error in backend: Cannot select: intrinsic %llvm.coro.size
clang-10: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 10.0.1 
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /nix/store/6pzqj9q656vc1msa675k75hmhsrfizsy-clang-10.0.1/bin
clang-10: note: diagnostic msg: PLEASE submit a bug report to  and include the crash backtrace, preprocessed source, and associated run script.
clang-10: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.


$ ./build.sh --holistic-opt | head
Compiling into LLVM IR
Running all coroutine passes
Compiling LLVM
5
6
7
8
9
10
11