[llvm-dev] Why does clang do a memcpy? Is the cast not enough? (ABI function args)

edA-qa mort-ora-y via llvm-dev llvm-dev at lists.llvm.org
Thu Apr 19 22:59:22 PDT 2018


Thanks. That kind of makes sense.

I see that a lot in my code as well: poor IR structures that aren't
worth the effort to clean up since the LLVM passes do such a fine job of it.

Turns out I now have the same copying structure in my ABI support code,
though I use Store instead. :)


On 19/04/18 19:26, David Blaikie wrote:
> I believe the memcpy is there just as a consequence of Clang's design
> - different parts of the compiler own different pieces of this, so in
> some sense one hand doesn't see what the other is doing. Part of it is
> "create an argument" (memcpying the local variable into an unnamed
> value) and then the next part is "oh, but that argument gets passed in
> registers, so decompose it into registers again".
>
> Clang doesn't need to produce perfectly optimal IR - because the
> optimization pipeline of LLVM will clean things up. So in many cases
> it's just easier (& not a significant impediment to performance) to
> have some of these sort of redundancies/oddities in output, and just
> let the LLVM optimization pipeline clean them up later.
>
> On Wed, Apr 18, 2018 at 10:51 AM edA-qa mort-ora-y via llvm-dev
> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
>
>     Yes, but why is it even copying the memory?  It already has a pointer
>     which it can cast and load from -- and does so in other scenarios.
>
>     I'm wondering whether this copying is somehow required and I'm missing
>     something, or it's just an artifact of the clang emitter. That is,
>     could
>     it not omit the memcpy and cast the original variable?
>
>     On 18/04/18 19:43, Krzysztof Parzyszek via llvm-dev wrote:
>     > This is the standard way of copying memory in the IR. Backends can
>     > expand the memcpy into loads/stores if they want.
>     >
>     > -Krzysztof
>     >
>     > On 4/18/2018 12:38 PM, edA-qa mort-ora-y via llvm-dev wrote:
>     >> Yes, I understand that as well (it's what I'm trying to
>     recreate in my
>     >> language now).
>     >>
>     >> I'm really wondering why it does the copy, since from what I
>     can tell it
>     >> could just as easily cast the original value and do the load
>     without the
>     >> memcpy operation.
>     >>
>     >> That is, the question is about the memcpy and extra alloca -- I
>     >> understand what it's doing, just not why it's doing it this way.
>     >>
>     >>
>     >> On 18/04/18 19:33, Krzysztof Parzyszek via llvm-dev wrote:
>     >>> It is a matter of the calling convention. It would specify what
>     >>> structs are passed in registers, and which are passed through
>     stack.
>     >>>
>     >>> -Krzysztof
>     >>>
>     >>> On 4/18/2018 12:28 PM, edA-qa mort-ora-y via llvm-dev wrote:
>     >>>> I understand it's passing by value, that's what I'm testing
>     here. The
>     >>>> question is why does it copy the data rather than just
>     casting and
>     >>>> loading values from the original variable (%v) ?  It seems
>     like the
>     >>>> copying is unnecessary.
>     >>>>
>     >>>> Not all struct's result in the copy, only certain forms --
>     others are
>     >>>> just cast directly as I was expecting. I'm just not clear on
>     what the
>     >>>> differences are, and whether I need to do the same thing.
>     >>>>
>     >>>>
>     >>>> On 18/04/18 19:13, Dimitry Andric wrote:
>     >>>>> On 18 Apr 2018, at 18:40, edA-qa mort-ora-y via llvm-dev
>     >>>>> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>>
>     wrote:
>     >>>>>> I'm implementing function arguments and tested this code in C:
>     >>>>>>
>     >>>>>>       // clang -emit-llvm ll_struct_arg.c -S -o /dev/tty
>     >>>>>>       typedef struct vpt_data {
>     >>>>>>           char a;
>     >>>>>>           int b;
>     >>>>>>           float c;
>     >>>>>>       } vpt_data;
>     >>>>>>
>     >>>>>>       void vpt_test( vpt_data vd ) {
>     >>>>>>       }
>     >>>>>>
>     >>>>>>       int main() {
>     >>>>>>           vpt_data v;
>     >>>>>>           vpt_test(v);
>     >>>>>>       }
>     >>>>>>
>     >>>>>> This emits an odd LLVM structure that casts to the desired
>     struct
>     >>>>>> type,
>     >>>>>> but also memcpy's to a temporary structure. I'm unsure of
>     why the
>     >>>>>> memcpy
>     >>>>>> is done as opposed to just casting directly?
>     >>>>> Because you are passing the parameter by value?  It *should*
>     copy the
>     >>>>> data.  In this particular case it will probably be elided if you
>     >>>>> turn on
>     >>>>> optimization, but it is more logical to pass structs via a const
>     >>>>> reference or pointer.
>     >>>>>
>     >>>>> -Dimitry
>     >>>>>
>     >>>>
>     >>>>
>     >>>>
>     >>>> _______________________________________________
>     >>>> LLVM Developers mailing list
>     >>>> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>     >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>     >>>>
>     >>>
>     >>
>     >
>
>     -- 
>     edA-qa mort-ora-y 
>             http://mortoray.com/
>
>     Creator of the Leaf language
>             http://leaflang.org/
>
>     Streaming algorithms, AI, and design on Twitch
>             https://www.twitch.tv/mortoray
>
>     Twitter
>             edaqa
>
>
>     _______________________________________________
>     LLVM Developers mailing list
>     llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>

-- 
edA-qa mort-ora-y  
	http://mortoray.com/

Creator of the Leaf language
	http://leaflang.org/

Streaming algorithms, AI, and design on Twitch
	https://www.twitch.tv/mortoray

Twitter
	edaqa
	

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180420/adf13e3d/attachment.html>


More information about the llvm-dev mailing list