diff --git a/llvm/docs/GlobalISel/KnownBits.rst b/llvm/docs/GlobalISel/KnownBits.rst new file mode 100644 --- /dev/null +++ b/llvm/docs/GlobalISel/KnownBits.rst @@ -0,0 +1,99 @@ +Known Bits Analysis +=================== + +The Known Bits Analysis pass makes information about the known values of bits +available to other passs to enable such transformations. The information is +lazily computed so you should only pay for what you use. + +Examples +-------- + +A simple example is that transforming:: + + a + 1 + +into:: + + a | 1 + +is only valid when the addition doesn't carry. In other words it's only valid +if ``a & 1`` is zero. + +Another example is: + +.. code-block:: llvm-mir-body + + %1:(s32) = G_CONSTANT i32 0xFF0 + %2:(s32) = G_AND %0, %1 + %3:(s32) = G_CONSTANT i32 0x0FF + %4:(s32) = G_AND %2, %3 + +We can use the constants and the definition of ``G_AND`` to determine the known +bits: + +.. code-block:: llvm-mir-body + + ; %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 + +and then use this to simplify the expression: + +.. code-block:: llvm-mir-body + + ; %0 = 0x???????? + %5:(s32) = G_CONSTANT i32 0x0F0 ; %5 = 0x00000FF0 + %4:(s32) = G_AND %0, %5 ; %4 = 0x000000?0 + +Note that ``%4`` still has the same known bits as before the transformation. +Many transformations share this property. The main exception being when the +transform causes undefined bits to become defined to either zero, one, or +defined but unknown. + +Usage +----- + +To use Known Bits Analysis in a pass, first include the header and register the +dependency with ``INITIALIZE_PASS_DEPENDENCY``. + +.. code-block:: c++ + + #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" + + ... + + INITIALIZE_PASS_BEGIN(...) + INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) + INITIALIZE_PASS_END(...) + +and require the pass in ``getAnalysisUsage``. + +.. code-block:: c++ + + void MyPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + // 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(); + } + +Then it's just a matter of fetching the analysis and using it: + +.. code-block:: c++ + + bool MyPass::runOnMachineFunction(MachineFunction &MF) { + ... + GISelKnownBits &KB = getAnalysis().get(MF); + ... + MachineInstr *MI = ...; + KnownBits Known = KB->getKnownBits(MI->getOperand(0).getReg()); + if (Known.Zeros & 1) { + // Bit 0 is known to be zero + } + ... + } + +There are many more API's beyond ``getKnownBits()``. See the `API reference +`_ for more information diff --git a/llvm/docs/GlobalISel/index.rst b/llvm/docs/GlobalISel/index.rst --- a/llvm/docs/GlobalISel/index.rst +++ b/llvm/docs/GlobalISel/index.rst @@ -64,6 +64,7 @@ Legalizer RegBankSelect InstructionSelect + KnownBits .. _progress: