mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[globalisel][docs] Add KnownBits Analysis documentation
Summary: This is largely based off of the slides from the keynote Depends on D69545 Reviewers: volkan, rovka, arsenm Subscribers: wdng, arphaman, Petar.Avramovic, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69644
This commit is contained in:
parent
0aa34f6ffe
commit
76c9170daf
100
docs/GlobalISel/KnownBits.rst
Normal file
100
docs/GlobalISel/KnownBits.rst
Normal file
@ -0,0 +1,100 @@
|
||||
Known Bits Analysis
|
||||
===================
|
||||
|
||||
The Known Bits Analysis pass makes information about the known values of bits
|
||||
available to other passes to enable transformations like those in the examples
|
||||
below. 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:: none
|
||||
|
||||
%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:: none
|
||||
|
||||
; %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:: none
|
||||
|
||||
; %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<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>();
|
||||
}
|
||||
|
||||
Then it's just a matter of fetching the analysis and using it:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
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
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
There are many more API's beyond ``getKnownBits()``. See the `API reference
|
||||
<http://llvm.org/doxygen>`_ for more information
|
@ -63,6 +63,7 @@ More information on specific passes can be found in the following sections:
|
||||
Legalizer
|
||||
RegBankSelect
|
||||
InstructionSelect
|
||||
KnownBits
|
||||
|
||||
.. _progress:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user