已知位元分析

「已知位元分析」pass 使其他 passes 可以取得位元已知值的資訊,以啟用如下列範例所示的轉換。 這些資訊是延遲計算的,因此您只需為您使用的部分付費。

範例

一個簡單的範例是轉換

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 仍然具有與轉換前相同的已知位元。 許多轉換都具有此屬性。 主要例外情況是當轉換導致未定義的位元變成已定義為零、一或已定義但未知時。

用法

若要在 pass 中使用「已知位元分析」,首先包含標頭並使用 INITIALIZE_PASS_DEPENDENCY 註冊依賴項。

#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"

...

INITIALIZE_PASS_BEGIN(...)
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
INITIALIZE_PASS_END(...)

並在 getAnalysisUsage 中要求 pass。

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 參考資料 以取得更多資訊