CreateFixedSpillStackObject marked the created objects as immutable. This is an error, since spill stack objects are stored to, while immutable objects are assumed to never change during the function execution.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
At least per documentation, spill slots should be created via CreateSpillStackObject. I think you may be fixing the wrong bug. Even if not silently disabling all optimization for existing callers is not acceptable.
I'm not quite sure that's right: Some ABIs have fixed-offset spill slots (e.g. PowerPC). Calling a spill slot immutable seems odd anyway, given that, by definition, you store into it. Also, they have isAliased == false regardless.
What documentation are you referring to?
Second of all, the rest of your comment sounds strange given my description of the problem. It is exactly that optimizations taking advantage of the "immutable" flag should not be taking place, given that these slots are not immutable.
In the same header:
/// Create a new statically sized stack object that represents a spill slot,
/// returning a nonnegative identifier to represent it. int CreateSpillStackObject(uint64_t Size, unsigned Alignment);
I also confirmed that the register allocator (via VirtRegMap::createSpillSlot) does use this interface.
Second of all, the rest of your comment sounds strange given my description of the problem. It is exactly that optimizations taking advantage of the "immutable" flag should not be taking place, given that these slots are not immutable.
My point is that while *spill slots* are clearly not immutable, there are other stack slots created by the same interface you modified which are. Disabling optimization of those slots is clearly not okay.
Hal, I think we have a terminology problem here. To me a "spill slot" is one created by the register allocator when spilling vregs. Are you saying that PowerPC has preassigned offsets which the register allocator must use? Or are you referring to something else entirely?
That same header has
/// Create a spill slot at a fixed location on the stack. /// Returns an index with a negative value. int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset);
My point is that while *spill slots* are clearly not immutable, there are other stack slots created by the same interface you modified which are. Disabling optimization of those slots is clearly not okay.
Spill slot is a stack slot that is not aliased to anything else. Fixed spill slot is a spill slot with a specified offset (i.e. its position in the frame is fixed).
Edit: My change modifies the CreateFixedSpillStackObject. It affects a subset of all spill slots, not even all of them: the inclusion that your concern states is reversed.
Fair enough. Yes, PowerPC has these, for callee-saved-register saving, and CreateFixedSpillStackObject is not used for those. CreateFixedSpillStackObject is only used by Hexagon and by x86. x86 uses this function in X86FrameLowering::assignCalleeSavedSpillSlots for assigning CSR spill slots. Hexagon seems to do the same (in HexagonFrameLowering::assignCalleeSavedSpillSlots).
My understanding is that this matters only when you have post-RA scheduling. Without post-RA scheduling, these slots are "effectively immutable", since they're stored to in the prologue and loaded in the epilogue, and that code isn't re-scheduled. With post-RA scheduling, this code might be re-scheduled, and it is important to actually consider whether the stores in the prologue might write to the slots being read by the epilogue code. This consideration won't happen if the slot is "immutable" (because, if it is immutable, then the store must be irrelevant). Krzysztof, did I understand the situation correctly?
If my understanding is correct, this seems like the right fix. It seems unlikely to affect performance on targets other than Hexagon and non-server-class x86 cores (i.e. Atom) where post-RA scheduling might be enabled.
Gah! I reread your patch and realized I'd misread it originally. I thought you were changing "CreateFixedObject" not "CreateFixedSpillStackObject". All of my comments are off base, apologies for misleading the discussion.
Hal, thanks for the context. As I replied separately, I'd misread the change, but your explanation provided a good amount of context which is great to understand anyways.
Yes, exactly. I'd only add that the problem can also occur during packetization (as a matter of fact, that's where I discovered it).