This commit adds a new BPF specific pass named
BPFHoistGetElementPtrLoadsPass. The goal of this pass is to hoist
load instructions to the corresponding getelementptr instructions when
this is deemed safe.
BPF verifier limits access patterns allowed for certain data
types. E.g. struct __sk_buff and struct bpf_sock_ops. For these types
only BASE + static-offset memory loads and stores are allowed.
This is so because offsets of the fields of these structures do not
match real offsets in the running kernel. During BPF program
load/verification loads and stores to the fields of these types are
rewritten so that offsets match real offsets. For this rewrite to
happen static offsets have to be encoded in the instructions.
See kernel/bpf/verifier.c:convert_ctx_access function in the Linux
kernel source tree for details.
During instruction selection phase the following sequence of
instructions:
%x = getelementptr %ptr, %offset %y = load %x
Is translated as a single load instruction with embedded offset,
e.g. LDW %ptr, %offset, which matches access pattern necessary for
the restricted set of types described above (when %offset is static).
However, several optimization passes might sink load instruction or
hoist getelementptr instruction so that the instructions are no
longer in sequence. Examples of such passes are SimplifyCFGPass and
InstCombinePass.
The BPFHoistArgumentAccess undoes sinking of the load / store
instructions by hoisting load/store instructions to predecessor basic
blocks.
This addresses the issue reported in the following thread: