<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Posts on Just In Time</title>
    <link>https://khagankhan.github.io/posts/</link>
    <description>Recent content in Posts on Just In Time</description>
    <generator>Hugo -- 0.134.2</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 08 Dec 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://khagankhan.github.io/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Be an LLVM contributor: Writing an optimization pattern for LLVM</title>
      <link>https://khagankhan.github.io/posts/llvm-pass/</link>
      <pubDate>Sun, 08 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://khagankhan.github.io/posts/llvm-pass/</guid>
      <description>&lt;h2 id=&#34;llvms-optimizations-are-truly-impressive&#34;&gt;LLVM&amp;rsquo;s Optimizations Are Truly Impressive&lt;/h2&gt;
&lt;p&gt;LLVM performs aggressive optimizations. One of my favorites is the Data Structure Elimination. For example, we want to 1) compute the sum of two integers (&lt;code&gt;get_sum&lt;/code&gt; function), and 2) select one of the two characters based on a condition argument (&lt;code&gt;get_char&lt;/code&gt; function):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c++&#34; data-lang=&#34;c++&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;using&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; std;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; a, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; b) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    vector&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; vec1; &lt;span style=&#34;color:#75715e&#34;&gt;// Create the first vector vec1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    vector&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; vec2; &lt;span style=&#34;color:#75715e&#34;&gt;// Create the second vector vec2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    vec1.push_back(a); &lt;span style=&#34;color:#75715e&#34;&gt;// Push the first argument to vec1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    vec2.push_back(b); &lt;span style=&#34;color:#75715e&#34;&gt;// Push the second argument to vec2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; vec1[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; vec2[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]; &lt;span style=&#34;color:#75715e&#34;&gt;// Return the sum of them
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Create a similar logic for string values
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_char&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; a, &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; b, &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; cond) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    string str1{a};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    string str2{b};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; cond &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; str1[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; str2[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;get_sum&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;lea&lt;/span&gt;     &lt;span style=&#34;color:#66d9ef&#34;&gt;eax&lt;/span&gt;, [&lt;span style=&#34;color:#66d9ef&#34;&gt;rdi&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;rsi&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;ret&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;get_char&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;mov&lt;/span&gt;     &lt;span style=&#34;color:#66d9ef&#34;&gt;eax&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;edi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;test&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;edx&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;edx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;cmove&lt;/span&gt;   &lt;span style=&#34;color:#66d9ef&#34;&gt;eax&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;esi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;ret&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the &lt;code&gt;get_sum&lt;/code&gt; function, the compiler takes advantage of the &lt;code&gt;lea&lt;/code&gt; instruction for the calculation, and for &lt;code&gt;get_char&lt;/code&gt;, it uses &lt;code&gt;cmove&lt;/code&gt; which it usually does to avoid potential misprediction penalties. Despite the vector being created on the heap, LLVM is able to &lt;a href=&#34;https://gcc.godbolt.org/z/z74cThYr9&#34;&gt;optimize both of them away&lt;/a&gt;, whereas GCC fails to do so for the vector but succeeds for string values. This is because small strings are stored on the stack (as explained in Raymond Chen&amp;rsquo;s &lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20230803-00/?p=108532&#34;&gt;excellent post&lt;/a&gt;), while the vector’s data is immediately allocated on the heap (For strings with a length of 15 characters (16 - 1 for the null character), the string is stored on the stack; beyond 15 characters, it is moved to the heap.)&lt;/p&gt;</description>
    </item>
    <item>
      <title>Do parentheses matter for better performance?</title>
      <link>https://khagankhan.github.io/posts/missed-opt/</link>
      <pubDate>Thu, 29 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://khagankhan.github.io/posts/missed-opt/</guid>
      <description>&lt;h1 id=&#34;missed-optimizations-in-llvm&#34;&gt;Missed optimizations in LLVM&lt;/h1&gt;
&lt;p&gt;The book &amp;ldquo;Computer Systems: A Programmer&amp;rsquo;s Perspective&amp;rdquo; warns the readers: &amp;ldquo;When in doubt, put in parentheses!&amp;rdquo;. Despite the authors saying this when talking about precedence issues, it would be applicable to some other cases. If you have ever written in a Lisp-like language you must love them!&lt;/p&gt;
&lt;p&gt;But what would happen if we put some &lt;em&gt;undue&lt;/em&gt; parentheses in our code.&lt;/p&gt;
&lt;p&gt;Let us consider the following C function (&lt;code&gt;sum.c&lt;/code&gt;):&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
