Closed
Bug 461065
Opened 16 years ago
Closed 11 years ago
Unwanted, incorrect spills when using LIR_ret and LIR_j loops
Categories
(Core Graveyard :: Nanojit, enhancement)
Core Graveyard
Nanojit
Tracking
(Not tracked)
RESOLVED
WONTFIX
Future
People
(Reporter: dmandelin, Unassigned)
References
Details
This appears in the same test case/output as bug 460892. I'm using LIR_ret to exit the compiled code because I don't need any of the extra side exit machinery but I do want to return a value. I'm getting a spill of a value used inside a loop with a short lifetime. I think it's related to the way callee-save registers are handled, which may be the real bug.
I've copied enough debug output here to show the problem. This is from the end of my nanojit debug output for the fragment. At the top, you can see "restore add2", so add2 was selected for spilling at that point. (add2 is defined about 3 instructions up from here.) My diagnosis as to why add2 is spilled:
- The jnl instruction at the top calls unionRegisterState with its target, 0x25fff3.
- At the target, the register state is: ebx(param1) esi(param2) edi(param3). This is because LIR_ret sets up the state this way, but doesn't generate restore code for any of these values, so they must be held in the registers at this point.
- add2 had earlier (lower in the output) had ebx selected for its result, because the register state was empty at the loop back edge.
- So now we generate a spill for add2 (which we don't want, because it's used inside a loop), and the restore of add2 still clobbers ebx anyway. This can't be right.
I'm not sure what's supposed to be happening here, but the key problem seems to be:
- LIR_j loop back edges have empty state. Clearly this is going to be a problem for the allocator unless the state really is empty.
- LIR_ret puts all the callee-save registers into the state, so any exit to a LIR_ret from a loop is going to go wrong.
----------------------------------------------------------------------------
jnl 0x25fff3 eax(state) ebx(param1) esi(param2) edi(param3)
restore add2
mov ebx,-20(ebp) eax(state)
sti state[0] = add2
mov 0(eax),ebx eax(state) ebx(add2)
j -> label1
Loop j -> label1
jmp 0x0
0x25fff3:
label3:
0
xor eax,eax ebx(param1) esi(param2) edi(param3)
ret 0
jmp 0x25fffc
1
x1: x -> 0x3036b0 sp+0 rp+0
jmp 0x260fb7
--------------------------------------- exit block (LIR_xt|LIR_xf)
0x260fb7:
restore param3
mov edi,-16(ebp)
restore param2
mov esi,-12(ebp) edi(param3)
restore param1
mov ebx,-8(ebp) esi(param2) edi(param3)
restore state
mov ecx,-4(ebp) ebx(param1) esi(param2) edi(param3)
mov eax,2494420
mov edx,3159792
mov esp,ebp
jmp 0x25fffc
--------------------------------------- end exit block SID 0
epilogue:
0x25fffc:
mov esp,ebp
pop ebp
ret
Updated•15 years ago
|
OS: Mac OS X → All
Hardware: x86 → All
Target Milestone: --- → Future
Updated•15 years ago
|
Severity: normal → enhancement
Updated•15 years ago
|
Component: JIT Compiler (NanoJIT) → Nanojit
Product: Tamarin → Core
QA Contact: nanojit → nanojit
Comment 1•15 years ago
|
||
pile on: i've seen this be severe on PPC which has lots of registers. Probably also not great on ARM/x64 which have 16, either.
We really dont want unionRegisterState, when we're in a cold block, joining to a branch in hot code. we'd rather spill in the cold block in this case. For exits, this could be as easy as just using "intersect" instead of "union". for LIR_jt/jf, there's not enough info in LIR to distinguish.
Assignee | ||
Updated•11 years ago
|
Product: Core → Core Graveyard
![]() |
||
Comment 2•11 years ago
|
||
Nanojit has been dead for several years. Its Bugzilla component has been moved to the graveyard (bug 984276).
I checked all the open bugs. They're all uninteresting, so I'm WONTFIXing them all. Apologies for the bugspam.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → WONTFIX
You need to log in
before you can comment on or make changes to this bug.
Description
•