<div dir="ltr">I largely agree with Eli about this...<div><br></div><div>I dislike the exact form of the current proposal because I feel like this shouldn't be a special form of alloca. I really dislike tightly coupled but "independent" instructions that have special rules applied to them.</div><div><br></div><div>But that said, there are other ways of accomplishing the same core thing that directly change the *argument* rather than having special allocas. From inside the function body these look similar to byval arguments today. I think a proposal that essentially integrates an argument passing protocol like byval more effectively into the rest of LLVM might make sense....</div><div><br></div><div>But I come back to Eli's point that it doesn't feel like this carries its weight. My feeling is that pattern matching plus passing arguments in a more natural way (aggregates) so that pattern matching is reasonably straight forward is likely to get the overwhelming majority of the cases you care about. If that is the case, it doesn't seem worth adding a new IR feature (or adding complexity to the current byval feature).</div><div><br></div>One clear way to demonstrate this feature really is needed is to explore pattern matching and report back serious problems along that path.<div><br></div><div>Another clear way (IMO) to demonstrate this feature is worth pursuing is to show how it will subsume and simplify the model of byval we have today.</div><div><br></div><div>Hope this helps,</div><div>-Chandler</div><div><br><div class="gmail_quote"><div dir="ltr">On Tue, Dec 27, 2016 at 4:15 PM Reid Kleckner via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg">To recap, it seems like there are two people so far opposed to this proposal, and tentative support from a number of others. It's not clear to me if I should go ahead with this. I'll try to bug some more people to get more input here.<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">In the meantime, I think I'll implement the simple pattern matching, since that can be done incrementally, and can be simplified afterwards by the IR change, or we can decide to extend it to run at -O0 or handle more complex cases.</div></div><div class="gmail_extra gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg">On Thu, Dec 8, 2016 at 5:05 PM, Reid Kleckner <span dir="ltr" class="gmail_msg"><<a href="mailto:rnk@google.com" class="gmail_msg" target="_blank">rnk@google.com</a>></span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_msg">Clang is currently missing some low-hanging performance and code size opportunities when receiving function parameters. For most scalar parameters, Clang typically emits an alloca and stores the LLVM SSA argument value into the alloca to initialize it. With optimizations, this initialization is often removed, but it stays behind in debug builds and when the user takes the address of a parameter (<a href="https://llvm.org/bugs/show_bug.cgi?id=26328" class="gmail_msg" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=26328</a>). In many cases, the memory allocation and store duplicate work already done by the caller.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Case 1: The parameter is already being passed in memory. In this case, we waste memory and do an extra load and store to copy it into our own alloca. This is very common on 32-bit x86.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Case 2: On Win64, the caller pre-allocates shadow stack slots for all register parameters. This allows the callee to “home” register parameters to ease debugging and the implementation of variadic functions. In this case, the store is not dead, but we fail to use the pre-allocated memory.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Case 3: The parameter is a register parameter in a normal Sys-V ABI. In this case, nothing is wasted. Both the memory and store are needed.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I think we can improve our code for cases 1 and 2 by making it possible to create allocas from parameters, and we can lower this down to a regular stack object with a store in case 3. The syntax for this would look like:</div><div class="gmail_msg">define void @f(i32 %x) {</div><div class="gmail_msg"> %px = alloca i32, argument i32 %x, align 4</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">The semantics are the same as the following:</div><div class="gmail_msg">define void @f(i32 %x) {<br class="gmail_msg"></div><div class="gmail_msg"> %px = alloca i32, align 4</div><div class="gmail_msg"> store i32 %x, i32* %px, align 4</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">It is invalid to make one of these argument allocas dynamic in any way, either by using inalloca, using a dynamic element count, or being outside the entry block.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">If the semantics are the same, it begs the question, why don’t we pattern match the alloca and store to elide dead stores and reuse existing argument stack slots? My main preference for adding a new way to do this is that it gives us simpler and smaller code in debug builds, where we presumably don’t want to do this kind of pattern recognition. My experience with our -O0 codegen is that we do a lot of useless copies to initialize parameters, and this leads to larger output size, which slows things down. Having a more easily recognizable idiom for getting the storage behind parameters if it exists feels like a win.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Changing the semantics of alloca affects a lot of things, but I think it makes sense to extend alloca here rather than a new intrinsic or instruction that can create local variable stack memory that passes would have to reason about. Here’s a list of things we’d need to change off the top of my head:</div><div class="gmail_msg">1. Inliner: When hoisting static allocas to the entry block, the inliner will now strip the argument operand off of allocas and insert the equivalent store at the inlined call site.</div><div class="gmail_msg">2. Mem2reg: Loading from an argument alloca needs to produce the argument value instead of undef.</div><div class="gmail_msg">3. GVN: We need to apply the same logic to GVN and similar store to load forwarding transforms.</div><div class="gmail_msg">4. Instcombine: This transform has some simple store forwarding logic that would need to be updated.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I’m sure there are more, but the changes seem worth it to get at these low hanging opportunities.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">One other questionable side benefit of doing this is that it would make it possible to implement va_start by taking the address of a parameter and doing pointer arithmetic. While that code is fairly invalid, it’s exactly what the MSVC STL headers do for 32-bit x86. If we make this work in Clang, we can remove our stdarg.h and vadefs.h wrapper headers. Users often pass flags that cause clang to skip these wrapper headers, and then they file bugs complaining that va lists don't work.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">At the end of the day, this feels like a straightforward engineering improvement to LLVM, and it feels worth doing to me. Does anyone feel otherwise or have any suggestions?</div></div>
</blockquote></div><br class="gmail_msg"></div>
_______________________________________________<br class="gmail_msg">
LLVM Developers mailing list<br class="gmail_msg">
<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br class="gmail_msg">
</blockquote></div></div></div>