为什么在 LLVM IR 中没有实现除以常数的优化?

Why the optimization, division-by-constant is not implemented in LLVM IR?

根据下面给出的源代码*1和我的实验,LLVM实现了一个将除法改为乘法并右移的转换。

在我的实验中,此优化应用于后端(因为我在 X86 汇编代码而不是 LLVM IR 上看到了更改)。

我知道此更改可能与硬件有关。在我看来,在某些硬件中,乘法和右移可能比单个除法运算符更昂贵。所以这个优化是在后端实现的。

但是当我搜索 DAGCombiner.cpp 时,我看到了一个名为 isIntDivCheap() 的函数。并且在这个函数的定义中,有一些评论指出便宜或昂贵的决定取决于基于代码大小或速度的优化。

也就是说,如果我总是根据速度优化代码,除法将转换为乘法并右移。反之则除法不转换。

另一方面,单次除法总是比乘法和右移慢,否则函数会做更多的事情来决定成本。

那么,如果单个除法总是较慢,为什么这个优化没有在 LLVM IR 中实现?

*1: https://llvm.org/doxygen/DivisionByConstantInfo_8cpp.html

有趣的问题。根据我在 High-level Synthesis (HLS) 编译器的 LLVM 前端工作的经验,您问题的答案在于理解 LLVM IR 和 limitations/scope LLVM IR 阶段的优化。

LLVM 中间表示 (IR) 是连接前端和后端的 backbone,允许 LLVM 解析多种源语言并为多个目标生成代码。因此,在 LLVM IR 阶段,它通常是关于 intent 而不是 full-fledge performance 优化。

Divide-by-constant 优化非常性能驱动。根本不是说 IR 级别的优化与性能关系不大或无关,但是,在 IR 阶段的优化方面存在固有限制,divide-by-constant 是其中之一这些限制。

更准确地说,IR 在 low-level 机器细节和说明中 根深蒂固 不够。如果你观察到 LLVM IR 的优化通常由 analysistransform passes 组成。据我所知,您没有看到 divide-by-constant 在 IR 阶段通过。