On Tue, 25 Jun 2019 at 13:22, Tim Northover <t.p.northover at gmail.com> wrote:> The only way I can think of to reliably detect the direction is using > an __attribute__((noinline)) function to compare locals from two > different, nested frames (even that's iffy though on a semantic > level). If there turned out to be a compelling enough use-case, an > intrinsic could be added to get the result more efficiently.Actually, (uintptr_t)__builtin_frame_address(0) < (uintptr_t)__builtin_frame_address(1) would probably work too. Cheers. Tim.
Thanks for all the detailed replies.> You can't rely on x and y being laid out in any particular order evenduring multiple calls to stack_direction within a single compilation But according to the assembly being generated, there is a fixed layout on the stack. I agree, the code is pretty ambiguous. But it should be well defined within the compiler. If it changes from compilation unit to compilation unit, so be it, at least given some specific instance of the function, it should be a constant.> If there turned out to be a compelling enough use-case, an intrinsiccould be added to get the result more efficiently. We need this operation in Ruby, and generally in coroutines to know how to layout the stack. Some architectures decided it would be a great idea for the stack to grow upwards. - Where to put guard page. - What should be the initial stack pointer. - How to alloca for custom stack allocations. Thanks Samuel -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190626/ee6be6b9/attachment.html>
> Actually, (uintptr_t)__builtin_frame_address(0) <(uintptr_t)__builtin_frame_address(1) would probably work too. I tried it but it doesn't seem to generate a constant either. https://godbolt.org/z/Z5HyEu>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190626/ebe8f587/attachment.html>
On Tue, 25 Jun 2019 at 22:10, Samuel Williams <space.ship.traveller at gmail.com> wrote:> But according to the assembly being generated, there is a fixed layout on the stack. I agree, the code is pretty ambiguous. But it should be well defined within the compiler.Only in the sense that the compiler tries to be deterministic between invocations. Detecting actual stack growth direction from that snippet is fundamentally broken. LLVM could perfectly legitimately fix a seed and call rand() to decide which of x & y to put first. More likely is that inlining and stack slot colouring would perturb them.> If it changes from compilation unit to compilation unit, so be it, at least given some specific instance of the function, it should be a constant.Even within a translation unit it can vary. The claim is just about true if you include static call-stack as part of an "instance", but you still don't get anything you can reason about in any kind of wider context.> We need this operation in Ruby, and generally in coroutines to know how to layout the stack. Some architectures decided it would be a great idea for the stack to grow upwards.None of the uses listed look compelling enough to optimize to me. It strikes me as an easily cacheable property at best, at worst one the interpreter/JIT should know statically before it even thinks about generating code.> I tried it but it doesn't seem to generate a constant either. https://godbolt.org/z/Z5HyEuI wouldn't expect it to. It has a higher probability of representing a meaningful fact about the platform than the original though. Cheers. Tim.