[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