问题标签 [llvm-codegen]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
rust - 有没有办法让 Rust 将指针视为非别名,因此它可以将它们标记为 LLVM 优化器的“noalias”?
以下是指针别名的示例:
编译成以下程序集(带-C opt-level=s
):
请注意,x
它被取消引用了两次。LLVM 不会将其视为noalias
. 我的第一个想法是避免在赋值中使用指针,而是使用安全引用(因为那些“遵循 LLVM 的作用域noalias
模型”)给优化器一个提示:
但是,唉,这会产生完全相同的结果。safe_x
仍然被取消引用两次。
我知道这个示例代码很愚蠢。参数可以很容易地更改为&i32
/ &mut i32
,或者我可以只取消引用x
一次并将其存储在用于分配的临时文件中。这里的代码只是一个超级简单的别名测试,我对我的问题所问的更广泛的图景感兴趣。
rust - 如何防止函数调用被优化掉?
如何确保执行没有副作用的函数并且不会在稳定的 Rust 中得到优化?
是否有我可以使用的属性组合,或者我必须调用另一个具有副作用的函数?在需要函数调用的情况下,Rust 标准库是否提供了保证不会被优化掉的廉价函数?
optimization - 我可以强制 Rust 不优化单个函数吗?
我有一个函数,其中 Rust/LLVM 的优化失败并导致恐慌(在发布版本中),而未优化的代码(调试版本)工作正常。如果我比较生成的汇编代码,我什至无法理解优化器试图完成什么。(一个原因可能是这个函数使用了内联汇编器。)
有什么方法可以告诉 Rust 在优化过程中不理会某些功能,还是我必须关闭所有优化?
下面是具体功能:
optimization - 为什么此代码生成的程序集比等效的 C++/Clang 多得多?
我编写了一个简单的 C++ 函数来检查编译器优化:
之后我检查了 Rust 中的等价物:
我使用Godbolt检查汇编器输出。
C++ 代码(由带有 -O3 标志的 clang 编译)的结果如下:
Rust 等价的结果要长得多:
我也尝试了-O
选项,但输出为空(删除了未使用的函数)。
我故意不使用任何库来保持输出干净。请注意两者clang
并rustc
使用 LLVM 作为后端。是什么解释了这种巨大的输出差异?如果它只是禁用优化开关问题,我怎样才能看到优化的输出rustc
?
assembly - 为什么 Rust 优化器不删除那些无用的指令(在 Godbolt Compiler Explorer 上测试)?
我想看看一个小的 Rust 函数的汇编输出:
我使用Godbolt Compiler Explorer来生成和查看程序集(-O
当然是使用标志)。它显示了这个输出:
现在我有点困惑,因为有一些指令似乎没有做任何有用的事情push rbp
:mov rbp, rsp
和pop rbp
. 据我了解,我认为单独执行这三个指令不会有任何副作用。那么为什么 Rust 优化器不删除那些无用的指令呢?
为了比较,我还测试了一个 C++ 版本:
汇编输出(带-O
标志):
事实上,这里缺少上面的那些“无用”指令,正如我对优化输出所期望的那样。
rust - rustc 中的优化级别 `-Os` 和 `-Oz` 有什么作用?
执行rustc -C help
节目(除其他外):
我认为 0 到 3 级相当直观:级别越高,执行的优化就越积极。但是,我不知道s
andz
选项在做什么,也找不到关于它们的 Rust 相关信息。
optimization - LLVM opt mem2reg 没有效果
我目前正在使用 LLVM,并正在尝试编写一些优化器来熟悉 opt 和 clang。我写了一个 test.c 文件如下:
我编译了源代码并生成了 2 个 .ll 文件,一个未优化,一个使用 mem2reg 优化器传递:
两个 .ll 文件都给了我以下输出:
所以看来我的 mem2reg 通行证不起作用!会有什么问题?
c - 如何将函数下的多个相同类型的循环映射到 LLVM IR 中生成的基本块?
如果循环的类型不同,那么我可以很容易地用名称识别它们,但是如果有多个相同类型的循环(比如 5 个while
循环),我如何识别 LLVM IR 中的基本块对应于源代码中的哪个循环?
当我们依次访问代码和 LLVM IR 时,手动识别很容易,但我正在研究如何以编程方式识别相同的内容。
例如,我在 C 中有以下源代码:
当我执行命令时,clang -S -emit-llvm fileName.c
我得到了具有以下内容的 fileName.ll 创建:
现在为给定的源文件创建了两个基本块while.cond
和while.cond1
,我如何识别源代码中哪个基本块用于哪个while循环?
rust - 在发出的 LLVM IR 上执行哪些 LLVM 传递?
如果我用cargo rustc -- --emit=llvm-ir
编译器编译将发出 LLVM IR。
以下是 Rust 使用的 LLVM 通行证。对发出的 IR 执行了哪些 LLVM 传递(如果有)?
有什么方法可以指定在发出 IR 之前要执行哪些传递?
assembly - 为什么 Rust 编译器不能优化掉 Box::downcast 的 Err arm?
我有一个Box<dyn Any>
并且我知道底层类型,所以我想优化Box::downcast()
(源)中的测试。
首先我尝试了std::hint::unreachable_unchecked()
:
和
两者rustc -C opt-level=3
都导致此(省略 40 行):
由于这不是我正在寻找的优化,我尝试了
但这变得更糟(省略了 118 行):
我希望生成这样的代码,这是Ok
来自Box::downcast
:
这导致了这个(省略了零行):
为什么编译器不能以这种方式优化代码?
Godbolt 生成的所有程序集。