Hi llvmdev, I'm trying to figure how llvm remembers stack slots allotted to callee saved registers on x86. In particular, llvm pushes registers in decreasing order of FrameIdxs [1], so the offsets they get (as returned by MFI->getObjectOffset) don't directly correspond to their actual stack locations. In X86FrameLowering's emitCalleeSavedFrameMoves, when emitting DWARF information, this discrepancy gets fixed up by subtracting the offset reported by MFI->getObjectOffset from the minimum offset for any CSR (this is done by the "Offset = MaxOffset - Offset + saveAreaOffset;" line). Is there a reason why llvm doesn't keep around the offsets in the right order from very beginning, by pushing the CSRs in increasing order of FrameIdxs? [1]: in fact, the way X86FrameLowering's spillCalleeSavedRegisters and PEI's calculateCalleeSavedRegisters are set up, I don't see a reason why the FrameIdxs and the generated push instructions have any relation at all. It seems that the code relies on MFI->CreateStackObject returning sequential integers. Thanks! -- Sanjoy
Pasi Parviainen
2014-May-30 23:04 UTC
[LLVMdev] Question about callee saved registers in x86
On 28.5.2014 2:57, Sanjoy Das wrote:> Hi llvmdev, > > I'm trying to figure how llvm remembers stack slots allotted to callee > saved registers on x86. In particular, llvm pushes registers in > decreasing order of FrameIdxs [1], so the offsets they get (as > returned by MFI->getObjectOffset) don't directly correspond to their > actual stack locations. In X86FrameLowering's > emitCalleeSavedFrameMoves, when emitting DWARF information, this > discrepancy gets fixed up by subtracting the offset reported by > MFI->getObjectOffset from the minimum offset for any CSR (this is done > by the "Offset = MaxOffset - Offset + saveAreaOffset;" line). Is > there a reason why llvm doesn't keep around the offsets in the right > order from very beginning, by pushing the CSRs in increasing order of > FrameIdxs?Now, that you mention it, I remember being down to the same rabbit hole. With certain calling conventions (coldcc, I think it was which can for sure expose this for x86), it is possible to generate invalid CFI directives for the registers in a frame. Especially when XMM registers must be preserved along with general purpose registers. And the reason for this was the offset fixing logic within emitCalleeSavedFrameMoves, which breaks when fixing offset for XMM registers. To fix this disparity, I concluded that it could be done by reversing definition order of general purpose registers within X86CallingConv.td for all calling conventions, since llvm prefers to use push/pop model for storing GPR:s (for x86). With this change stack slots and registers would have 1:1 mapping, without extra offset calculations and emitCalleeSavedFrameMoves could be simplified by removing extra magic to determine slots, and to generate correct CFI directives in unusual cases.> [1]: in fact, the way X86FrameLowering's spillCalleeSavedRegisters and > PEI's calculateCalleeSavedRegisters are set up, I don't see a reason > why the FrameIdxs and the generated push instructions have any > relation at all. It seems that the code relies on > MFI->CreateStackObject returning sequential integers. > > Thanks! > -- Sanjoy > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Hi Pasi, Do you have a broken test case lying around? If you do, I'll start work on a fix for this using that as the test case. Thanks, -- Sanjoy On May 30, 2014, at 4:04 PM, Pasi Parviainen <pasi.parviainen at iki.fi> wrote:> On 28.5.2014 2:57, Sanjoy Das wrote: >> Hi llvmdev, >> >> I'm trying to figure how llvm remembers stack slots allotted to callee >> saved registers on x86. In particular, llvm pushes registers in >> decreasing order of FrameIdxs [1], so the offsets they get (as >> returned by MFI->getObjectOffset) don't directly correspond to their >> actual stack locations. In X86FrameLowering's >> emitCalleeSavedFrameMoves, when emitting DWARF information, this >> discrepancy gets fixed up by subtracting the offset reported by >> MFI->getObjectOffset from the minimum offset for any CSR (this is done >> by the "Offset = MaxOffset - Offset + saveAreaOffset;" line). Is >> there a reason why llvm doesn't keep around the offsets in the right >> order from very beginning, by pushing the CSRs in increasing order of >> FrameIdxs? > > Now, that you mention it, I remember being down to the same rabbit hole. With certain calling conventions (coldcc, I think it was which can for sure expose this for x86), it is possible to generate invalid CFI directives for the registers in a frame. Especially when XMM registers must be preserved along with general purpose registers. And the reason for this was the offset fixing logic within emitCalleeSavedFrameMoves, which breaks when fixing offset for XMM registers. > > To fix this disparity, I concluded that it could be done by reversing definition order of general purpose registers within X86CallingConv.td for all calling conventions, since llvm prefers to use push/pop model for storing GPR:s (for x86). With this change stack slots and registers would have 1:1 mapping, without extra offset calculations and emitCalleeSavedFrameMoves could be simplified by removing extra magic to determine slots, and to generate correct CFI directives in unusual cases. > >> [1]: in fact, the way X86FrameLowering's spillCalleeSavedRegisters and >> PEI's calculateCalleeSavedRegisters are set up, I don't see a reason >> why the FrameIdxs and the generated push instructions have any >> relation at all. It seems that the code relies on >> MFI->CreateStackObject returning sequential integers. >> >> Thanks! >> -- Sanjoy >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Pasi Parviainen
2014-May-30 23:48 UTC
[LLVMdev] Question about callee saved registers in x86
On 31.5.2014 2:04, Pasi Parviainen wrote:> On 28.5.2014 2:57, Sanjoy Das wrote: >> Hi llvmdev, >> >> I'm trying to figure how llvm remembers stack slots allotted to callee >> saved registers on x86. In particular, llvm pushes registers in >> decreasing order of FrameIdxs [1], so the offsets they get (as >> returned by MFI->getObjectOffset) don't directly correspond to their >> actual stack locations. In X86FrameLowering's >> emitCalleeSavedFrameMoves, when emitting DWARF information, this >> discrepancy gets fixed up by subtracting the offset reported by >> MFI->getObjectOffset from the minimum offset for any CSR (this is done >> by the "Offset = MaxOffset - Offset + saveAreaOffset;" line). Is >> there a reason why llvm doesn't keep around the offsets in the right >> order from very beginning, by pushing the CSRs in increasing order of >> FrameIdxs? > > Now, that you mention it, I remember being down to the same rabbit hole. > With certain calling conventions (coldcc, I think it was which can for > sure expose this for x86), it is possible to generate invalid CFI > directives for the registers in a frame. Especially when XMM registers > must be preserved along with general purpose registers. And the reason > for this was the offset fixing logic within emitCalleeSavedFrameMoves, > which breaks when fixing offset for XMM registers. > > To fix this disparity, I concluded that it could be done by reversing > definition order of general purpose registers within X86CallingConv.td > for all calling conventions, since llvm prefers to use push/pop model > for storing GPR:s (for x86). With this change stack slots and registers > would have 1:1 mapping, without extra offset calculations and > emitCalleeSavedFrameMoves could be simplified by removing extra magic to > determine slots, and to generate correct CFI directives in unusual cases.Now that checking out some old experimental code to solve this, it also seems to require to reversing the order of XMM/YMM registers within calling convention definitions in X86CallingConv.td, and to do other minor changes to account for these.>> [1]: in fact, the way X86FrameLowering's spillCalleeSavedRegisters and >> PEI's calculateCalleeSavedRegisters are set up, I don't see a reason >> why the FrameIdxs and the generated push instructions have any >> relation at all. It seems that the code relies on >> MFI->CreateStackObject returning sequential integers. >> >> Thanks! >> -- Sanjoy >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >