[LLVMdev] "Machine LICM" for Constants?
Matt Johnson
johnso87 at crhc.illinois.edu
Wed Mar 7 10:38:01 PST 2012
Hi All,
I work on a backend for a target similar to Mips, where large
immediates are loaded into registers with 2 instructions, 1 to load the
MSBits and 1 to load the LSBits. I've noticed a recurring pattern
where, despite low register pressure, these constants will be
rematerialized in every iteration of a loop, rather than being hoisted.
Here's an example using the mips-unknown-unknown target and Clang/LLVM
HEAD. From newlib's implementation of strncat:
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
while (!DETECTNULL (*aligned_s1))
aligned_s1++;
This loop gets lowered under -O3 to:
$BB0_5:
lui $3, 32896
lui $7, 65278
ori $3, $3, 32896 ###### Materialize 0x80808080
lw $8, 4($2)
nop
and $9, $8, $3
ori $7, $7, 65279 ###### Materialize -(0x01010101)
addiu $2, $2, 4
xor $3, $9, $3
addu $7, $8, $7
and $3, $3, $7
beq $3, $zero, $BB0_5
There are a ton of unused caller-saved registers in this small function,
so I expected the constant materialization to be hoisted out of the
tight loop. I'm still learning about the new register allocator and am
not immediately able to make sense of its debug output (and the
'problem' may be elsewhere in any case). I'm happy to post the results
of -debug-only regalloc if they're useful.
Is my desire to hoist the constants out of the loop reasonable? Is
there something I can do (hints or passes in my backend, clang/opt flag,
etc.) to make this happen today? If not, what is the root cause? Maybe
there's no way to hoist things out of a loop once IR is lowered into a
SelectionDAG?
Thanks,
Matt
More information about the llvm-dev
mailing list