Help to understanding a case of innefective allocation sinking

  • From: Alexander Gall <alexander.gall@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Fri, 12 Dec 2014 11:13:21 +0100

I'm trying to understand why the following code (distilled from a
real-word use case) contains an unsunk allocation:

jit.off()
local ffi = require("ffi")
local len = 1024
local mem = ffi.new("uint8_t [?]", len)

jit.on()
jit.flush()
local sum = 0LL
for i = 1, 1e7 do
   for i = 0, len-2, 2 do
      sum = sum + bit.lshift(mem[i]+0LL, 8) + mem[i+1]
   end
end
jit.off()

The attached JIT dump shows two traces. Trace 1 contains the inner
loop connected to trace 2 for the outer loop via exit #3. The unsunk
allocation appears at the start of trace 2

 ---- TRACE 2 IR
0001 rbp      i64 PVAL   #48
0002 [8]    + cdt CNEWI  +11   0001
....              SNAP   #0   [ ---- ---- ---- ---- 0002 ---- ---- ---- ---- ]

If I understand correctly, the "sum" variable is basically stored in
slot #4. Then why does trace 2 use PVAL to refer to it? This appears
to be the only reason for the creation of the cdata object, which is
otherwise unused in the trace. I don't know if it's related, but I'm
also puzzled that index 0002 is marked as being referred to by a PHI
instruction when there is none in that trace. It appears to be
inherited from index 0048 in the parent trace, but why?

The main question is whether the code can be written in a manner that
avoids this effect.

-- 
Alex

Attachment: dump
Description: Binary data

Other related posts: