已知位分析¶
已知位分析通道使其他通道能够获取有关位已知值的信息,从而启用诸如以下示例中的转换。信息是延迟计算的,因此您只需为使用的部分付费。
示例¶
一个简单的例子是转换
a + 1
为
a | 1
仅在加法不进位时有效。换句话说,仅当a & 1
为零时有效。
另一个例子是
%1:(s32) = G_CONSTANT i32 0xFF0
%2:(s32) = G_AND %0, %1
%3:(s32) = G_CONSTANT i32 0x0FF
%4:(s32) = G_AND %2, %3
我们可以使用常量和G_AND
的定义来确定已知位
; %0 = 0x????????
%1:(s32) = G_CONSTANT i32 0xFF0 ; %1 = 0x00000FF0
%2:(s32) = G_AND %0, %1 ; %2 = 0x00000??0
%3:(s32) = G_CONSTANT i32 0x0FF ; %3 = 0x000000FF
%4:(s32) = G_AND %2, %3 ; %4 = 0x000000?0
然后使用它来简化表达式
; %0 = 0x????????
%5:(s32) = G_CONSTANT i32 0x0F0 ; %5 = 0x00000FF0
%4:(s32) = G_AND %0, %5 ; %4 = 0x000000?0
请注意,%4
在转换前后的已知位仍然相同。许多转换都具有此属性。主要例外情况是转换导致未定义位变为定义为零、一或已定义但未知。
用法¶
要在通道中使用已知位分析,首先包含头文件并使用INITIALIZE_PASS_DEPENDENCY
注册依赖项。
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
...
INITIALIZE_PASS_BEGIN(...)
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
INITIALIZE_PASS_END(...)
并在getAnalysisUsage
中需要该通道。
void MyPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<GISelKnownBitsAnalysis>();
// Optional: If your pass preserves known bits analysis (many do) then
// indicate that it's preserved for re-use by another pass here.
AU.addPreserved<GISelKnownBitsAnalysis>();
}
然后,只需获取分析并使用它即可
bool MyPass::runOnMachineFunction(MachineFunction &MF) {
...
GISelKnownBits &KB = getAnalysis<GISelKnownBitsAnalysis>().get(MF);
...
MachineInstr *MI = ...;
KnownBits Known = KB->getKnownBits(MI->getOperand(0).getReg());
if (Known.Zeros & 1) {
// Bit 0 is known to be zero
}
...
}
除了getKnownBits()
之外,还有更多 API。有关更多信息,请参阅API 参考