<div dir="ltr"><div>Ah, I see -- the registers left out of the mask are considered clobbered. Got it!<br><br></div><div>At a high level, I'm interested in finding the locations of all values that are live at a given call site.<b> </b>You can think of it like a debugger, e.g. gdb -- I'd like to be able to unwind the stack, frame by frame, and locate all the live values for each function invocation (i.e., where they are in a function's stack frame/register set) at the function call site. I'm currently using DWARF metadata to implement the frame unwinding mechanism, similarly to gdb. I can't use DWARF metadata for live value location information, however, because it only generates location information for named source code variables. I also need to locate compiler-generated temporaries, hence I've been looking at the StackMap intrinsic [1] to provide live value location information. It does most of what I need, but it does not tell me where live values stored in registers are spilled to the stack as part of the function call procedure (whether they be in callee- or caller-saved registers) -- it simply tells me which registers they are stored in before/after the function call procedure. That's the impetus for my question.<br><br></div><div>This is <b>not</b> a problem for callee-saved registers -- these registers are restored from the stack as part of the call frame unwinding procedure detailed in the DWARF standard [2]. However, I'm left trying to find the locations of the live values that were in caller-saved registers and were spilled to the stack as part of the function call procedure (probably during instruction selection/register allocation, I'm not familiar enough with this process). I realize that for a MachineInstr for a given call there are no live values in caller-saved registers (as they would be clobbered and lost), but where on the stack were they saved?<br><br></div><div>In a nutshell, I'm trying to figure out where values that couldn't be placed in callee-saved registers (and that were allocated to caller-saved registers) were spilled to the stack as part of the function call procedure. Hopefully this clarifies things -- thanks!<br></div><div><br>[1] <a href="http://llvm.org/docs/StackMaps.html">http://llvm.org/docs/StackMaps.html</a><br>[2] <a href="http://dwarfstd.org/doc/DWARF4.pdf">http://dwarfstd.org/doc/DWARF4.pdf</a>, page 140<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jun 27, 2016 at 10:28 AM, Rob Lyerly <span dir="ltr"><<a href="mailto:rlyerly@vt.edu" target="_blank">rlyerly@vt.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>Hi Sanjoy,<br><br></div>I'm having trouble finding caller-saved registers using the RegMask operand you've mentioned. As an example, I've got a C function that looks like this:<br><br></div><span style="font-family:monospace,monospace">double recurse(int depth, double val)<br>{<br></span></div><span style="font-family:monospace,monospace"> if(depth < max_depth) return recurse(depth + 1, val * 1.2) + val;<br></span></div><span style="font-family:monospace,monospace"> else return outer_func(val);<br></span><div><div><span style="font-family:monospace,monospace">}</span><br><br></div><div>As a quick refresher, all "xmm" registers are considered caller-saved on x86, hence values stored in these registers should be spilled to the stack before a function call. The generated assembly for branch containing the call to "recurse" with clang/LLVM 3.8 (-O3) on Ubuntu 14.04 looks like this:<br><br><span style="font-family:monospace,monospace">...<br>400694: ff c7 inc %edi # Add 1 to depth<br>400696: f2 0f 10 05 a2 92 05 movsd 0x592a2(%rip),%xmm0 # Move constant 1.2 into xmm0<br>40069d: 00 <br>40069e: f2 0f 59 c1 mulsd %xmm1,%xmm0 # val * 1.2<br>4006a2: f2 0f 11 4d f8 movsd %xmm1,-0x8(%rbp) # Spill val to the stack<br>4006a7: e8 d4 ff ff ff callq 400680 <recurse><br>4006ac: f2 0f 58 45 f8 addsd -0x8(%rbp),%xmm0 # recurse's return value + val<br>4006b1: 48 83 c4 10 add $0x10,%rsp<br>4006b5: 5d pop %rbp<br>4006b6: c3 retq <br>...<br><br></span></div><div><span style="font-family:monospace,monospace"><font face="arial,helvetica,sans-serif">Notice how xmm1 (the storage location of "val", which is live across the call to recurse) is saved onto the stack at an offset of -8 from the base pointer. After the call, "val" (i.e., storage location rbp - 0x8) is used in the addition to calculate the returned value. However, when I print the RegMask operand for the call machine instruction, I get the following:<br><br><font face="monospace,monospace"><regmask %BH %BL %BP %BPL %BX %EBP %EBX %RBP %RBX %R12 %R13 %R14 %R15 %R12B %R13B %R14B %R15B %R12D %R13D %R14D %R15D %R12W %R13W %R14W %R15W><br><br></font></font></span></div><div><span style="font-family:arial,helvetica,sans-serif">I don't see xmm1 as being preserved across this call. Am I missing something? Thanks for your help!</span><span style="font-family:monospace,monospace"><font face="arial,helvetica,sans-serif"><font face="monospace,monospace"><br></font></font></span></div></div></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On Wed, Jun 22, 2016 at 5:01 PM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Rob,<span><br>
<br>
Rob Lyerly via llvm-dev wrote:<br>
> I'm looking for a way to get all the caller-saved registers (both the<br>
> register and the stack slot at which it was saved) for a given function<br>
> call site in the backend. What's the best way to grab this<br>
> information? Is it possible to get this information if I have the<br>
> MachineInstr of the function call? I'm currently targeting the AArch64<br>
> & X86 backends.<br>
<br></span>
You should be able to use the RegMask operand to the MachineInstr to<br>
discover the registers that are preserved or clobbered by the call<br>
according to the calling convention. For reference, you might want to<br>
look at `getRegMask` and `gatherMaximalPreservedRegisters` in<br>
<a href="http://reviews.llvm.org/D21115" rel="noreferrer" target="_blank">http://reviews.llvm.org/D21115</a>.<br>
<br>
As far as discovering the slot to which it is spilled, I have no idea.<br>
CC'ing Matthias for this.<span><font color="#888888"><br>
<br>
-- Sanjoy<br>
</font></span></blockquote></div><br><br clear="all"><br></div></div><span class="">-- <br><div data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div><span>Rob Lyerly</span><br></div><div>Graduate Research Assistant, Systems Software Research Group<br><br></div><div><img src="https://upload.wikimedia.org/wikipedia/en/thumb/2/23/Virginiatechseal.svg/200px-Virginiatechseal.svg.png" height="76" width="75"> <img src="http://www.oocities.org/rainforestwind/divider_black_vertical.jpg" height="75" width="8"><img src="http://www.ece.vt.edu/images/inside-top-ecelogo.png" height="55" width="272"></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
</span></div>
</blockquote></div><br></div>