<div dir="ltr"><div dir="auto"><div>Sorry for this incredibly long response. It's just that probably about 90% of all beginner questions seem to be related to unfamiliarity with the same set of basic concepts (which, to be honest, are very poorly known outside the compiler/toolchain community, so that unfamiliarity is totally expected). By providing a more elaborated answer I'm trying to write something that hopefully helps many other people understand these concepts better.</div><div><br></div><div>Broadly speaking, it may be useful to follow this approach when facing a question while learning about LLVM:</div><div><br></div><div>1. If you are starting from C++ code and trying to understand how it is lowered, run `clang++ -emit-llvm -O0` and create a C file that produces essentially the same LLVM IR when passed to `clang -emit-llvm -O0`. This should always be possible, except perhaps things related to exception handling and some things you probably don't care about like how to put a function in a comdat or give it certain linkage. If you can't figure out how to do that, the answer is probably:</div><div>1.a. in the C++ ABI <a href="https://itanium-cxx-abi.github.io/cxx-abi/abi.html">https://itanium-cxx-abi.github.io/cxx-abi/abi.html</a> (home page: <a href="https://itanium-cxx-abi.github.io/cxx-abi/">https://itanium-cxx-abi.github.io/cxx-abi/</a>) or</div><div>1.b. it is a general C++ language question which you can probably find information about in <a href="http://en.cppreference.com/w/">http://en.cppreference.com/w/</a> (or the language standard if you want to look at it).</div><div><br></div><div>Those are fairly dense reference material, but you should at least browse around them a bit (and do web searches, especially for general C++ language questions) to refine your question.</div><div><br></div><div>2. If your question wasn't related to something C++ specific, then you now have a C file and want to know something about how it is lowered to LLVM IR. To make sure you have a basic understanding of LLVM IR concepts and the relationship between C and LLVM IR, I would recommend watching this video: <a href="https://www.youtube.com/watch?v=haQ2cijhvhE">https://www.youtube.com/watch?v=haQ2cijhvhE</a></div><div><br></div><div><br></div><div>3. It's likely that you started with a single question at the beginning and now have broken it down into multiple more specific questions that are much more likely to be answered if you ask them on llvm-dev (or cfe-dev if the question is very narrowly C++ specific, though for general C++ language questions StackOverflow might be better).</div><div><br></div><div><br></div><div>Another useful resource might be to skim these two videos, which talk about C++ coroutines (and their implementation in LLVM), which are a feature that cuts across the C++, C, and LLVM IR levels (and a little bit about machine level in the second video):</div><div><a href="https://www.youtube.com/watch?v=8C8NnE1Dg4A">https://www.youtube.com/watch?v=8C8NnE1Dg4A</a></div><div><a href="https://www.youtube.com/watch?v=Ztr8QvMhqmQ">https://www.youtube.com/watch?v=Ztr8QvMhqmQ</a></div><div>You don't need to actually understand what the videos are talking about in detail, but it is useful to see how Gor talks about the same thing to two very different audiences. The first video is to an audience at CppCon which is mostly C++ language users (and people familiar with C-like aspects of C++ programming), but not necessarily familiar with compilers. The second video is to an audience of LLVM developers, and so it doesn't worry about mentioning lots of LLVM-specific details or using compiler/toolchain terminology and concepts. By comparing the two videos, it should give some insight about which things are easier to think about at different levels of analysis, which things work similarly and can be explained at multiple levels of analysis, and which things only matter at a particular level of analysis. For example, the high-level description of the coroutine splitting process can be done pretty much the same at LLVM IR level or at the C level (with some intrinsics). You'll also notice that even when talking to an audience of LLVM developers, many things in the presentation are still described at the C level.</div><div>Coroutines are also interesting in that part of the language-level semantic lowering (the coroutine splitting) happens inside the optimizer at LLVM IR level instead of in the frontend for various reasons. Having an optimization pass that is *semantically required* is unusual, but otherwise this is conceptually similar to the "alloca trick" I talk about below that Clang uses for local variables (SROA / mem2reg are not *semantically required for correctness*, but they are needed for any reasonable performance, so the situation is still pretty analogous).</div><div><br><div class="gmail_extra"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Jun 1, 2017 6:47 AM, "Dimitri Racordon via llvm-dev" <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br type="attribution"><blockquote class="gmail-m_-8504643926560801705quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">



<div style="word-wrap:break-word">
<div>Thanks for this comprehensive answer!</div>
<div>I’m slowly but surely to understand better about all this.</div>
<div><br>
</div>
<div>
<blockquote type="cite">That may sound scary,</blockquote>
<br>
</div>
<div>Yes it does! That said, I’m not sure need to care that much about the C++ ABI, as I don’t plan on linking my IR with C++ directly. It is very interesting to see how it works though, as I’ll probably need to solve the same kind of problems for
 my own frontend language.</div><div class="gmail-m_-8504643926560801705quoted-text">
<div><br>
</div>
<div>
<blockquote type="cite">
<div>The result of an alloca is a pointer to the stack frame of the current function, so returning it doesn't make sense (like returning the address of a local variable in C). Again, this problem isn't really related to LLVM per se and the easiest
 way to think about it is in terms of how to lower to C.</div>
<div>Decisions about object destruction are up to the frontend. At the C or LLVM level they just turn into function calls or whatever you use to implement the semantics that the frontend requires. In other words, if you want an object to be destroyed,
 it's up to your frontend to emit code to perform the destruction wherever the destruction is expected to occur.</div>
</blockquote>
</div>
<div><br>
</div>
</div><div>I understand my second question was probably very unclear. When I said “destroyed”, I wasn’t talking about calls to C++ (or any other frontend language) destructors, but more about what is happening to the memory that was stack allocated. Let’s
 consider the following IR:</div>
<div><br>
</div>
<div>
<div><font face="Menlo">define i32 @f() {</font></div>
<div><font face="Menlo">entry:</font></div>
<div><font face="Menlo">  %0 = alloca i32</font></div>
<div><font face="Menlo">  store i32 123, i32* %0</font></div>
<div><font face="Menlo">  %1 = load i32, i32* %0</font></div>
<div><font face="Menlo">  ret i32 %1</font></div>
<div><font face="Menlo">}</font></div>
<div><font face="Menlo"><br>
</font></div>
<div><font face="Menlo">define i32 @main() {</font></div>
<div><font face="Menlo">entry:</font></div>
<div><font face="Menlo">  %0 = alloca i32</font></div>
<div><font face="Menlo">  %1 = call i32 @f()</font></div>
<div><font face="Menlo">  store i32 %1, i32* %0</font></div>
<div><font face="Menlo">  %2 = load i32, i32* %0</font></div>
<div><font face="Menlo">  ret i32 %2</font></div>
<div><font face="Menlo">}</font></div>
</div>
<div><br>
</div>
<div>As I understand it, f will allocate a new 32 bit memory space on its stack frame, and stores the value 123 in it. But what I’m not sure about is what’s happening to that alloca when f returns.<br><br></div></div></blockquote></div></div></div><div dir="auto"><br></div><div>The alloca is part of `f`'s  stack frame, so when `f` returns it is gone. That memory can never be accessed again (obviously at the machine level it is still there and will probably be overwritten by a future function call, but as far as LLVM IR semantics (or C) it cannot be accessed again). To phrase this in terms of C, you are essentially asking about what happens to the memory pointed to by `p` in the function `bar` after it returns (and I think you already know the answer at the C level; the answer is the same at the LLVM IR level).</div><div dir="auto"><br></div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> If the alloca is in the frame of f, then the value stored at that location should be deallocated (which is what I meant by "destroyed") when f returns, and so I don’t understand what makes the `store i32 %1, i32* %0` successfully storing 123 in the alloca of the main function.</blockquote><div dir="auto"><br></div><div>The store inside `f` does not affect the alloca inside the main function. The main function takes the value returned by the call and stores the value itself. The return value of `f` is an i32 value that you can think of as held in a register at the hardware level and returned by value. In the callee (`@f`) the value 123 happens to have been stored to and loaded back from an alloca, but that doesn't matter after it returns (and indeed, the alloca's memory is deallocated when `@f` returns). Also, you'll notice that the optimizer will happily reduce `@f` to just `ret i32 123` or something like that and delete the load, store, and alloca.</div><div><br></div><div>I'm guessing that part of this confusion is that you were seeing Clang produce a ton of alloca's. You may wonder *why* clang generates all these alloca's (and you may have noticed the optimizer will just fold them away). This is one place where the semantics of C and LLVM IR differ substantially, so thinking in terms of C won't lead to the right conclusion.</div><div><br></div><div>The fundamental abstraction in C of data is essentially that every variable is assumed to be an object in memory (more precisely, this is what the term "lvalue" in C refers to; if you want to get super technical about this and related concepts in C/C++ a reference is <a href="http://en.cppreference.com/w/cpp/language/value_category">http://en.cppreference.com/w/cpp/language/value_category</a>). For example, you can take the address of any variable.</div><div><br></div><div>For example, these two functions are identical</div><div><br></div><div>int foo() {<br></div><div>  int x = 123;</div><div>  return x;</div><div>}</div><div><br></div><div>int bar() {</div><div>  int x = 123;</div><div>  int *p = &x;</div><div>  return *p;<br>}</div><div><br></div><div>Also, in C/C++, variables are mutable. For example, this function is also identical to the previous functions:</div><div><br></div><div>int baz() {</div><div>  int x = 123;</div><div>  x = 42;</div><div>  x = 123;</div><div>  return x;</div><div>}</div><div><br></div><div>However, in LLVM IR, when you see something like `%2 = add i32 %1, %0` or `%2 = load i32, i32* %0`, the thing designated by `%2` is *very* different. You cannot take the address of `%2` and you cannot mutate the thing designated by `%2`. You can think of `%2` as a name for a node in a data flow graph (in fact, `%2` is represented in the LLVM libraries as an llvm::Value; %2 is a *name* for an llvm::Value). There's more about this perhaps subtle point from 10:40 to 11:40 in Chandler's video <a href="https://www.youtube.com/watch?v=haQ2cijhvhE">https://www.youtube.com/watch?v=haQ2cijhvhE</a>, though you will probably find the first 20 minutes or so very relevant to this conversation (and I would recommend watching the whole video).</div><div><br></div><div>(Sometimes it is also useful to think of LLVM's values as "SSA registers", i.e. registers that can only be assigned in one place. Don't think about them as general mutable storage locations though)<br></div><div><br></div><div>So Clang has this problem: how do I accurately translate the semantics of code written in C/C++ (which semantically involves operations on objects in memory) to LLVM IR, which revolves around nodes in a data flow graph (whose SSA values have no notion of semantically being in a "storage location"; they are just names for llvm::Value's that the LLVM libraries operate on, which are (roughly) nodes in a data flow / control flow graph). </div><div><br></div><div>The answer is that Clang models C/C++ semantics of local variables by explicitly using alloca to create temporary in-memory storage locations. Then the correspondence between the generated LLVM IR and the C/C++ semantics is easy to get right. This requires inserting a lot of loads and stores from allocas just to access the values (e.g. needing two loads, an add, and a store to do `c = a + b`), but it is worth it because it simplifies Clang's lowering from C/C++ to LLVM IR.</div><div><br></div><div>You may be thinking: in `foo` above, at the C/C++ level it is easy to see that `x` could be kept in a register instead of a memory location on the stack, and it is only assigned once, so it could be directly lowered into an LLVM IR value instead of kept in memory in an alloca. It turns out that it is actually very difficult to do this analysis in Clang, at least in any reasonable generality. It turns out that there are standard compiler algorithms (generally known as "SSA construction") that can "easily" and quickly (e.g. linear time) do the analysis and transformation needed to optimally (or close to optimally) get rid of all the allocas. The discovery of an efficient algorithm to do this was actually a revolution in compilers precisely because it allows an SSA representation like LLVM IR to be efficiently constructed from input languages with mutable storage locations (especially in the presence of control flow, which requires deciding where to insert a special type of instruction called a "phi node" to model when a local variable is mutated along multiple control flow paths).</div><div>The `mem2reg` pass (and it's more sophisticated cousin, `sroa`) are the passes in LLVM that do this. </div><div><br></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail-m_-8504643926560801705quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>If I had to make a guess, I would say the value pointed by %0 in f is copied to the alloca pointed by %0 in main (which is what I meant by “copy from the runtime of the callee to that of the caller”).</div><div><br></div></div></blockquote></div></div></div><div dir="auto"><br></div><div>You are correct in the sense that @f loads the value (`%1 = load i32, i32* %0`), then returns it (`ret i32 %1`), then control returns to main and `%1 = call i32 @f()` finishes executing, then @main stores the value %1 into %0 `store i32 %1, i32* %0`.</div><div>There is no magic here connected to the alloca's; you're explicitly seeing every operation done on those memory locations (which are distinct memory locations). The only thing that could perhaps be considered "magic" are the details of how the LLVM backends generate machine code so that the value passed to the `ret` becomes available to the caller. But the semantics at the LLVM IR level are straightforward: the value of the call instruction (%1 in main) is the same as the value passed to the `ret` in the callee (%1 in f).</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> With primitive types such as i32, this probably doesn't matter, since they would fit in a CPU register, but what if %0 was an alloca for a very large struct? I guess that’s what RVO is all about optimising, but I’d like to confirm that assumption.</blockquote><div><br></div></div><div dir="auto">Are you asking about ABI details or LLVM IR semantics?</div><div dir="auto"><br></div><div dir="auto"><div dir="auto">"RVO" doesn't enter the picture here because we are at LLVM IR level. There is no RVO at the LLVM IR level because RVO refers to a concept that exists only at the C++ language level (in the abstract; it's not part of the ABI). In fact, if you look on the wikipedia page for RVO, you'll see that RVO can change a well-defined program's console output (i.e. the number of times it prints `A copy was made.`). RVO is a specific case where the C++ language standard (the semantics of the language in the abstract; this has nothing to do with the ABI) permit the compiler to change the output of a well-defined program, and the set of situations where this transformation is allowed is defined in terms of the abstract language semantics, which are only available to the C++ frontend (which has complete language-level semantic information). This is a case where thinking about LLVM IR in terms of C code is accurate: if you are lowering C++ to C, then as part of that conversion RVO is performed, and there is no concept of RVO at the C level.</div><div><br></div></div><div dir="auto">Semantically at the LLVM IR level a struct return type is returned by value (i.e. copied) exactly like an i32. `%1` in `@main` represents a value with the same bit pattern and size as `%1` in `@f`; this is true regardless of the size of `%1` in `@f`. The alloca inside main is irrelevant to this. The alloca only matters because the value of `%1` inside `@main` is stored into the memory it points to by an explicit store instruction, but that is just a store like any other store (it sets the bits in memory at the address pointed at by %0 to the bits of the value of %1; the memory address happens to be an alloca that is allocated in the current stack frame).</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">If you are wondering about the low-level details of how `%1` in `@f` ends up in `%1` in `@main` when the call happens at runtime, then that's a bit more complicated and depends on the processor-specific ABI. At the processor ABI level, a struct return type of an LLVM IR function is returned by value in registers (just like in C). Like I mentioned, there's a list of designated return registers (on x86-64 there are two such registers), with specially allocated stack memory to act as extra "registers" beyond the two designated hardware registers (if necessary). This specially allocated stack memory is not explicitly visible at the LLVM IR level and comes into existence in the LLVM backend as LLVM IR is translated into a form closer to machine level.</div><div><br></div><div>The exact ABI details of a function call at the LLVM IR level has quite a rabbit hole that you probably don't care about. E.g. there is `sret`, `byval`, and `inalloca` (<a href="http://llvm.org/docs/LangRef.html#parameter-attributes">http://llvm.org/docs/LangRef.html#parameter-attributes</a>) or calling conventions (<a href="http://llvm.org/docs/LangRef.html#calling-conventions">http://llvm.org/docs/LangRef.html#calling-conventions</a>) which control very low-level details of the mapping to the processor-specific ABI.</div><div><br></div><div><br></div><div><br></div><div>Another related thing (specifically related to C++):</div><div><br></div><div>The fact that the processor specific registers (or special stack memory representing extra "registers") is not explicitly visible at the LLVM IR level is not an issue when lowering C where all structs are POD (Plain Old Data). That is why I said that you can think about this particular issue entirely in terms of lowering C++ to C. In C++, a struct can define constructors/destructors that allow it to maintain complex internal invariants. In particular, it can maintain internal invariants that depend on it being in memory, so the C++ language ABI cannot say that such structs are passed "by value" in registers. For example,</div><div><br></div><div><div>struct Foo {</div><div>  Foo(const Foo &foo) {</div><div>    this->x = foo.x;</div><div>    this->p = &this->x;</div><div>  }</div><div>  int x;</div><div>  int *p;</div><div>};</div></div><div><br></div><div>As part of a simple function like the following, the struct Foo that is returned "by value", but if you think about it in terms of lowering C++ to C (or LLVM IR), it actually involves a call to a copy constructor:</div><div><div><br></div><div>Foo getFoo(Foo &f) {</div><div>  return f;</div><div>}</div></div><div><br></div><div>(look at the generated LLVM IR: <a href="https://godbolt.org/g/VbwwJr">https://godbolt.org/g/VbwwJr</a>)</div><div><br></div><div>This struct `Foo` cannot be returned by value "in registers" because it maintains an internal invariant that depends on being in memory (`p` points at `x`). Due to this language-level semantic detail, what would `p` be set to if this struct were returned in registers? (and it does fit in registers on x86-64 actually) </div><div><br></div><div>Because this is a language ABI requirement, all compilers must implement it identically in order to produce machine code that can be linked together. Therefore, it cannot depend on "how smart" each compiler's optimizer is and is defined at the C++ language level. For example, you don't want compiler's disagreeing about whether getFoo will return in registers or in memory depending on whether they optimize this branch (which eliminates Foo's dependence on its own address, therefore allowing it to in theory be returned in registers):</div><div><br></div><div><div>struct Foo {</div><div>  Foo(const Foo &foo) {</div><div>    this->x = foo.x;</div><div>    if ((foo.x ^ foo.x) != 0) // Always false.</div><div>      this->p = &this->x;</div><div>    else</div><div>      this->p = nullptr;</div><div>  }</div><div>  int x;</div><div>  int *p;</div><div>};</div></div><div><br></div><div>Thus, the rules frequently require things to be passed via explicit pointer out-parameters even if they in theory could be passed in registers. For example, the requirement preventing Foo from being passed in registers in <a href="https://itanium-cxx-abi.github.io/cxx-abi/abi.html#return-value">https://itanium-cxx-abi.github.io/cxx-abi/abi.html#return-value</a> applies to structs that are "non-trivial for the purposes of calls" which basically means "did you manually write a copy/move constructor or destructor for this class".</div><div><br></div><div>As an interesting factoid, this prevents std::unique_ptr from being passed in registers, even though it is just a single pointer and doesn't depend on its own address, so could in theory be passed in registers. So converting an old-style:</div><div><br></div><div>Qux *createQux(); </div><div><br></div><div>to a modern-style:</div><div><br></div><div>std::unique_ptr<Qux> createQux();<br></div><div><br></div><div>is actually a slight (probably negligible) pessimization, because the ABI requirement prevents the latter from being returned in registers. The optimizer is actually smart enough to optimize this and instead pass the std::unique_ptr in registers, but the fact that it must "agree with other compilers" about it means it has its hands tied and has to follow the ABI. However, if you compile with link-time optimization, the compiler can verify that it is seeing every possible use of createQux and change them all at once to use registers instead. If createQux is `static`, the compiler can also verify that it is seeing every possible user and perform this optimization. Also, if createQux is inlined, the cost will obviously go away.</div><div><br></div><div>The ABI actually prevents the optimizer from passing the std::unique_ptr in registers, simply because all compilers (or different versions of the same compiler, or assembly language programmers) must agree on whether it is passed in registers or not for their code to be compatible. So when people say that std::unique_ptr has "zero overhead" you can now tell them that they are technically wrong (they are right in practice though, because except for ABI limitations compilers optimize std::unique_ptr extremely well).</div><div><br></div><div>As you can see, this is one case where the lowest-level hardware realities (like passing things in registers or not) require consideration at the language semantic level. This is one aspect that makes ABI's have a very deep rabbit hole and lots of details, because the lowest-level details can have high-level effects. They also want to be high-performance, but they sometimes must sacrifice that for compatibility or to avoid being infeasibly complex.</div><div><br></div><div>-- Sean Silva</div><div><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail-m_-8504643926560801705quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word">
<div><br>
</div>
<div>Once again, I apologise for my poor knowledge of these kind of low-level semantics.</div><div class="gmail-m_-8504643926560801705quoted-text">
<div><br>
</div>
<div>Best,</div>
<br>
<div>
<div style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word">
Dimitri Racordon<br>
CUI, Université de Genève<br>
7, route de Drize, CH-1227 Carouge - Switzerland<br>
Phone: <a href="tel:+41%2022%20379%2001%2024" value="+41223790124" target="_blank">+41 22 379 01 24</a>
<div><br>
</div>
</div>
</div>
</div></div>

<br>______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div></div></div>
</div>