LLD Support for Basic Block Sections
This is part of the Propeller framework to do post link code layout optimizations. Please see the RFC here: https://groups.google.com/forum/#!msg/llvm-dev/ef3mKzAdJ7U/1shV64BYBAAJ and the detailed RFC doc here: https://github.com/google/llvm-propeller/blob/plo-dev/Propeller_RFC.pdf
This is one in the series of patches for Propeller.
This patch adds lld support for basic block sections and performs relaxations after the basic blocks have been reordered.
After the linker has reordered the basic block sections according to the desired sequence, it runs a relaxation pass to optimize jump instructions. Currently, the compiler emits the long form of all jump instructions . AMD64 ISA supports variants of jump instructions with one byte offset or a four byte offset. The compiler generates jump instructions with R_X86_64 32-bit PC relative relocations. We would like to use a new relocation type for these jump instructions as it makes it easy and accurate while relaxing these instructions.
A new relocation type for jmp instructions which need to be relaxed makes it easy and accurate when the linker tries to find these instructions. Our current method peeks back to look at the opcode of the relocation type that could correspond to jmp instructions.
The relaxation pass does threetwo things:
First, it deletes all explicit fall-through direct jump instructions between adjacent basic blocks. This is done by discarding the tail of the basic block section.
Second, it shrinks jump instructions whose offsets can fit in a smaller equivalent jump instruction. The AMD64 ISA supports variants of jump instructions with either a one byte offset or a four byte offset. Shorter jump instructions are preferred where possible to reduce code size. The jump instructions are shrunk by using jump relocations. Jump relocations are used to modify the opcode of the jump instruction. Jump relocations contain three values, instruction offset, jump type and size. There is a one to one correspondence between jump relocations and jump instructions. While writing this jump instruction out to the final binary, the linker uses the jump relocation to determine the opcode and the size of the modified jump instruction. These new relocations are required because the input object files are memory-mapped without write permissions and directly modifying the object files requires copying these sections.If there are consecutive jump instructions, Copying a large number of basic block sections significantly bloats memory and we have invented jump relocations as a simple solution to avoid this bloatit checks if the first conditional jump can be inverted to convert the second into a fall through and delete the second.
Third,The jump instructions are relaxed by using jump instruction mods, something like relocations. the relaxation pass replaces a twoThese are used to modify the opcode of the jump instruction sequence. Jump instruction mods contain three values, JX and JY instruction offset, with just one jump instruction if JX is a conditional branch whose target is the adjacent basic blocktype and JY is a direct branchsize. This can be done by replacing the two jump instructions with a single jump instruction which has as the inverse op-code of JX as its op-codeWhile writing this jump instruction out to the final binary, andthe linker uses the target of JY as its branch targetjump instruction mod to determine the opcode and the size of the modified jump instruction. This change is also made using a jump relocation at the appropriate code offset in that section.
ese mods are required because the input object files are memory-mapped without write permissions and directly modifying the object files requires copying these sections. Copying a large number of basic block sections significantly bloats memory.