我正在研究 LLVM IR 的新通道优化,这取决于 SLP 矢量器的工作原理。
https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp.
我知道 SLP 在对代码进行向量化之前有一些步骤。它收集候选种子(存储指令),它构建一棵树,使用存储指令中的这些候选者形成超级节点,直到达到加载指令或 const 值。之后,它使用 costModel 函数遍历树,累积每个超级节点的矢量化成本。最后,如果成本为负,则代码将被矢量化。
所以我有这两个玩具示例:
拳头很容易矢量化:
a[i] = b[i] *c[i] + a[i];
a[i+1] = b[i+1]*c[i+1] + a[i+1];
a[i+2] = b[i+2]*c[i+2] + a[i+2];
a[i+3] = b[i+3]*c[i+3] + a[i+3];
第二个不是:
a[i] = b[i] *c[i] + a[i-1];
a[i+1] = b[i+1]*c[i+1] + a[i];
a[i+2] = b[i+2]*c[i+2] + a[i+1];
a[i+3] = b[i+3]*c[i+3] + a[i+2];
我理解为什么第二个代码不可矢量化,但我无法理解 SLP 如何检查它。我进行了一些调试,这不是成本模型。这些说明不会出现在树中。
不幸的是,理解这种代码仍然超出了我的能力范围,而且它的文档也很少,所以我需要更了解 LLVM 的 IR 基础设施如何工作的人的帮助。
谢谢
a[i] = b[i] *c[i] + a[i-1];
a[i+1] = b[i+1]*c[i+1] + a[i];
a[i+2] = b[i+2]*c[i+2] + a[i+1];
a[i+3] = b[i+3]*c[i+3] + a[i+2];
看起来这里存在先写后读的依赖关系,即使 SLP 对其进行矢量化,也可能不会有利可图,可能是提取的成本导致矢量化无利可图。这只是我到目前为止的假设,如果我错了,请纠正我。