Following a question on StackOverflow [1], I was wondering if for big allocations, LLVM would "delay" the allocation or rather perform it upfront.<br><br>The following code was thus submitted to the LLVM Try Out page:<br>
<br><pre style="margin-left: 40px;" class="lang-c prettyprint"><code><font style="font-family: times new roman,serif;" size="2"><span class="kwd">void</span><span class="pln"> doSomething</span><span class="pun">(</span><span class="kwd">char</span><span class="pun">*,</span><span class="kwd">char</span><span class="pun">*);</span><span class="pln"><br>
<br></span><span class="kwd">void</span><span class="pln"> function</span><span class="pun">(</span><span class="kwd">bool</span><span class="pln"> b</span><span class="pun">)</span><span class="pln"><br></span><span class="pun">{</span><span class="pln"><br>
    </span><span class="kwd">char</span><span class="pln"> b1</span><span class="pun">[</span><span class="lit">1</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1024</span><span class="pun">];</span><span class="pln"><br>
    </span><span class="kwd">if</span><span class="pun">(</span><span class="pln"> b </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"><br>       </span><span class="kwd">char</span><span class="pln"> b2</span><span class="pun">[</span><span class="lit">1</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1024</span><span class="pun">];</span><span class="pln"><br>
       doSomething</span><span class="pun">(</span><span class="pln">b1</span><span class="pun">,</span><span class="pln"> b2</span><span class="pun">);</span><span class="pln"><br>    </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln"><br>
       </span><span class="kwd">char</span><span class="pln"> b3</span><span class="pun">[</span><span class="lit">512</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1024</span><span class="pun">];</span><span class="pln"><br>
       doSomething</span><span class="pun">(</span><span class="pln">b1</span><span class="pun">,</span><span class="pln"> b3</span><span class="pun">);</span><span class="pln"><br>    </span><span class="pun">}</span><span class="pln"><br>
</span><span class="pun">}<br></span></font></code></pre><pre style="margin-left: 40px;" class="lang-c prettyprint"><code><span class="pln"></span></code></pre>Certainly nothing spectacular.<br><br>I was however quite surprised by the output:<br>
<br><pre style="margin-left: 40px;" class="lang-c prettyprint"><code><font style="font-family: times new roman,serif;" size="2"><span class="pun">;</span><span class="pln"> </span><span class="typ">ModuleID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'/tmp/webcompile/_28066_0.bc'</span><span class="pln"><br>
target datalayout </span><span class="pun">=</span><span class="pln"> </span><span class="str">"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"</span><span class="pln"><br>
target triple </span><span class="pun">=</span><span class="pln"> </span><span class="str">"x86_64-unknown-linux-gnu"</span><span class="pln"><br><br>define </span><span class="kwd">void</span><span class="pln"> </span><span class="lit">@_Z8functionb</span><span class="pun">(</span><span class="pln">i1 zeroext </span><span class="pun">%</span><span class="pln">b</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"><br>
entry</span><span class="pun">:</span><span class="pln"><br>  </span><span class="pun">%</span><span class="pln">b1 </span><span class="pun">=</span><span class="pln"> alloca </span><span class="pun">[</span><span class="lit">1024</span><span class="pln"> x i8</span><span class="pun">],</span><span class="pln"> align </span><span class="lit">1</span><span class="pln">               </span><span class="pun">;</span><span class="pln"> </span><span class="pun"><[</span><span class="lit">1024</span><span class="pln"> x i8</span><span class="pun">]*></span><span class="pln"> </span><span class="pun">[</span><span class="com">#uses=1]</span><span class="pln"><br>
  </span><span class="pun">%</span><span class="pln">b2 </span><span class="pun">=</span><span class="pln"> alloca </span><span class="pun">[</span><span class="lit">1024</span><span class="pln"> x i8</span><span class="pun">],</span><span class="pln"> align </span><span class="lit">1</span><span class="pln">               </span><span class="pun">;</span><span class="pln"> </span><span class="pun"><[</span><span class="lit">1024</span><span class="pln"> x i8</span><span class="pun">]*></span><span class="pln"> </span><span class="pun">[</span><span class="com">#uses=1]</span><span class="pln"><br>
  </span><span class="pun">%</span><span class="pln">b3 </span><span class="pun">=</span><span class="pln"> alloca </span><span class="pun">[</span><span class="lit">524288</span><span class="pln"> x i8</span><span class="pun">],</span><span class="pln"> align </span><span class="lit">1</span><span class="pln">            </span><span class="pun">;</span><span class="pln"> </span><span class="pun"><[</span><span class="lit">524288</span><span class="pln"> x i8</span><span class="pun">]*></span><span class="pln"> </span><span class="pun">[</span><span class="com">#uses=1]</span><span class="pln"><br>
  </span><span class="pun">%</span><span class="pln">arraydecay </span><span class="pun">=</span><span class="pln"> getelementptr inbounds </span><span class="pun">[</span><span class="lit">1024</span><span class="pln"> x i8</span><span class="pun">]*</span><span class="pln"> </span><span class="pun">%</span><span class="pln">b1</span><span class="pun">,</span><span class="pln"> i64 </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> i64 </span><span class="lit">0</span><span class="pln"> </span><span class="pun">;</span><span class="pln"> </span><span class="pun"><</span><span class="pln">i8</span><span class="pun">*></span><span class="pln"> </span><span class="pun">[</span><span class="com">#uses=2]</span><span class="pln"><br>
  br i1 </span><span class="pun">%</span><span class="pln">b</span><span class="pun">,</span><span class="pln"> label </span><span class="pun">%</span><span class="kwd">if</span><span class="pun">.</span><span class="pln">then</span><span class="pun">,</span><span class="pln"> label </span><span class="pun">%</span><span class="kwd">if</span><span class="pun">.</span><span class="kwd">else</span><span class="pln"><br>
<br></span><span class="kwd">if</span><span class="pun">.</span><span class="pln">then</span><span class="pun">:</span><span class="pln">                                          </span><span class="pun">;</span><span class="pln"> preds </span><span class="pun">=</span><span class="pln"> </span><span class="pun">%</span><span class="pln">entry<br>
  </span><span class="pun">%</span><span class="pln">arraydecay2 </span><span class="pun">=</span><span class="pln"> getelementptr inbounds </span><span class="pun">[</span><span class="lit">1024</span><span class="pln"> x i8</span><span class="pun">]*</span><span class="pln"> </span><span class="pun">%</span><span class="pln">b2</span><span class="pun">,</span><span class="pln"> i64 </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> i64 </span><span class="lit">0</span><span class="pln"> </span><span class="pun">;</span><span class="pln"> </span><span class="pun"><</span><span class="pln">i8</span><span class="pun">*></span><span class="pln"> </span><span class="pun">[</span><span class="com">#uses=1]</span><span class="pln"><br>
  call </span><span class="kwd">void</span><span class="pln"> </span><span class="lit">@_Z11doSomethingPcS_</span><span class="pun">(</span><span class="pln">i8</span><span class="pun">*</span><span class="pln"> </span><span class="pun">%</span><span class="pln">arraydecay</span><span class="pun">,</span><span class="pln"> i8</span><span class="pun">*</span><span class="pln"> </span><span class="pun">%</span><span class="pln">arraydecay2</span><span class="pun">)</span><span class="pln"><br>
  ret </span><span class="kwd">void</span><span class="pln"><br><br></span><span class="kwd">if</span><span class="pun">.</span><span class="kwd">else</span><span class="pun">:</span><span class="pln">                                          </span><span class="pun">;</span><span class="pln"> preds </span><span class="pun">=</span><span class="pln"> </span><span class="pun">%</span><span class="pln">entry<br>
  </span><span class="pun">%</span><span class="pln">arraydecay6 </span><span class="pun">=</span><span class="pln"> getelementptr inbounds </span><span class="pun">[</span><span class="lit">524288</span><span class="pln"> x i8</span><span class="pun">]*</span><span class="pln"> </span><span class="pun">%</span><span class="pln">b3</span><span class="pun">,</span><span class="pln"> i64 </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> i64 </span><span class="lit">0</span><span class="pln"> </span><span class="pun">;</span><span class="pln"> </span><span class="pun"><</span><span class="pln">i8</span><span class="pun">*></span><span class="pln"> </span><span class="pun">[</span><span class="com">#uses=1]</span><span class="pln"><br>
  call </span><span class="kwd">void</span><span class="pln"> </span><span class="lit">@_Z11doSomethingPcS_</span><span class="pun">(</span><span class="pln">i8</span><span class="pun">*</span><span class="pln"> </span><span class="pun">%</span><span class="pln">arraydecay</span><span class="pun">,</span><span class="pln"> i8</span><span class="pun">*</span><span class="pln"> </span><span class="pun">%</span><span class="pln">arraydecay6</span><span class="pun">)</span><span class="pln"><br>
  ret </span><span class="kwd">void</span><span class="pln"><br></span><span class="pun">}</span><span class="pln"><br><br>declare </span><span class="kwd">void</span><span class="pln"> </span><span class="lit">@_Z11doSomethingPcS_</span><span class="pun">(</span><span class="pln">i8</span><span class="pun">*,</span><span class="pln"> i8</span><span class="pun">*)</span></font><span class="pln"><br>
</span></code></pre>(Compiled with "Standard" optimizations as C++ code)<br><br>My surprise stems from the fact that Clang/LLVM seems to reserve (at least in its bytecode) space for all temporary variables, not taking into account that some are mutually exclusive. I would have expected the space to be <i>folded</i>. However, since this is LLVM IR, and not the final assembly, and since LLVM IR is strongly typed, it makes sense to keep them separated.<br>
<br>Therefore I was wondering if in the x86 representation (say) these <i>would</i> be folded, and if so what is the name of the Optimization/CodeGen pass responsible ?<br><br>-- Matthieu<br><br>[1] <a href="http://stackoverflow.com/questions/7089035/at-what-moment-is-memory-typically-allocated-for-local-variables-in-c">http://stackoverflow.com/questions/7089035/at-what-moment-is-memory-typically-allocated-for-local-variables-in-c</a><br>