<html><head><base href="x-msg://685/"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Feb 14, 2011, at 9:15 AM, Jim Darby wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; "><div style="font-family: 'Sans Serif'; font-size: 8pt; font-weight: 400; font-style: normal; "><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">Hi Chris,</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">Thanks for the pointer to the LLVM tutorial, it's helped immensely.</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">I've been playing around a bit to see how clang generates the IR and it now all makes a lot more sense. However, there's one issue that's causing me a little concern. It all centres around allocating local variables using the alloca operation with block structured code.</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">Using C as an example language, consider the following example program.</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">       <span style="font-family: monospace; ">void</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">    bar ()</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; "> {</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">              extern void called (char *);</span></div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; font-family: monospace; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">                  {</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">                      char x1 [10000];</span></div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; font-family: monospace; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">                      called (x1);</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">           }</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">              {</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">                      char x2 [15000];</span></div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; font-family: monospace; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">                      arse (x2);</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">             }</span></div><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "><span style="font-family: monospace; ">      }</span></div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">Now in C it is possible to overlap the storage for x1 and x2. In fact the stack frame can be considered something like <span style="font-family: monospace; ">union { char x1[10000]; char x2[15000]; }</span>. In the general case the blocks of the same lexical level inside a function can all be considered as forming part of a union. However, I notice the clang generates the space for both x1 and x2 at the same time meaning the above function allocates 25000 bytes on the stack when it only need create 15000.</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">If you put the same code through gcc you'll find it only allocates just over 15000 bytes of local storing (the 15000 plus a little overhead).</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">This has no effect on performance but does have an effect on the amount of stack space a program uses. Now I know that we shouldn't be allocating vast amounts on the stack but the above program is just an example to prove the point.</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">Any thoughts on this one? One potential method is to actually form a union to handle the stack frame and use that explicitly. This has the rather novel effect that all functions would only have a single alloca to create all the local variables.</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">Many thanks for your help,</div><p style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; "></p><div style="white-space: pre-wrap; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; text-indent: 0px; ">Jim.</div></div></span></blockquote></div><br><div>Hi Jim,</div><div><br></div><div>It's best to email llvmdev with general questions, as I get swamped and backlogged frequently.  We don't have a good answer at present to the problem above, but I have some thoughts on the matter here:</div><div><a href="http://nondot.org/sabre/LLVMNotes/MemoryUseMarkers.txt">http://nondot.org/sabre/LLVMNotes/MemoryUseMarkers.txt</a></div><div><br></div><div>We do currently have a hack in the inliner to reuse stack array memory that are inlined from different callees into a common caller. </div><div><br></div><div>-Chris</div></body></html>