<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[201613] trunk/Websites/webkit.org</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/201613">201613</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-06-02 13:05:08 -0700 (Thu, 02 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Fix typos and make some revisions to the B3 docs
https://bugs.webkit.org/show_bug.cgi?id=158311

Reviewed by Michael Saboff.
        
I found typos and fixed them. Also, I clarified some things:
        
- Is B3 IR platform-agnostic? Sort of. I tried to describe when it is (Values usually behave
  the same way regardless of CPU) and when it isn't (it lets you speak of registers if that's
  what you want to do, for example).
        
- How does isValidForm really get used? You don't really need to create an Inst to use it.
        
- Some other incremental improvements to make the docs clearer.

* docs/b3/assembly-intermediate-representation.html:
* docs/b3/index.html:
* docs/b3/intermediate-representation.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebsiteswebkitorgChangeLog">trunk/Websites/webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsiteswebkitorgdocsb3assemblyintermediaterepresentationhtml">trunk/Websites/webkit.org/docs/b3/assembly-intermediate-representation.html</a></li>
<li><a href="#trunkWebsiteswebkitorgdocsb3indexhtml">trunk/Websites/webkit.org/docs/b3/index.html</a></li>
<li><a href="#trunkWebsiteswebkitorgdocsb3intermediaterepresentationhtml">trunk/Websites/webkit.org/docs/b3/intermediate-representation.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebsiteswebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/ChangeLog (201612 => 201613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/ChangeLog        2016-06-02 19:57:41 UTC (rev 201612)
+++ trunk/Websites/webkit.org/ChangeLog        2016-06-02 20:05:08 UTC (rev 201613)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2016-06-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Fix typos and make some revisions to the B3 docs
+        https://bugs.webkit.org/show_bug.cgi?id=158311
+
+        Reviewed by Michael Saboff.
+        
+        I found typos and fixed them. Also, I clarified some things:
+        
+        - Is B3 IR platform-agnostic? Sort of. I tried to describe when it is (Values usually behave
+          the same way regardless of CPU) and when it isn't (it lets you speak of registers if that's
+          what you want to do, for example).
+        
+        - How does isValidForm really get used? You don't really need to create an Inst to use it.
+        
+        - Some other incremental improvements to make the docs clearer.
+
+        * docs/b3/assembly-intermediate-representation.html:
+        * docs/b3/index.html:
+        * docs/b3/intermediate-representation.html:
+
</ins><span class="cx"> 2016-05-31  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, fix an obvious typo: a missing comma.
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgdocsb3assemblyintermediaterepresentationhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/docs/b3/assembly-intermediate-representation.html (201612 => 201613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/docs/b3/assembly-intermediate-representation.html        2016-06-02 19:57:41 UTC (rev 201612)
+++ trunk/Websites/webkit.org/docs/b3/assembly-intermediate-representation.html        2016-06-02 20:05:08 UTC (rev 201613)
</span><span class="lines">@@ -44,13 +44,12 @@
</span><span class="cx">     
</span><span class="cx">     &lt;p&gt;B3 is designed to be portable to many kinds of CPUs. Currently, it supports x86-64 and ARM64,
</span><span class="cx">       which are quite different from each other. In B3 IR, we expose very few instruction set
</span><del>-      details. Most clients only have to worry about the pointer type varying between Int32 and
-      Int64. It's a goal of B3 IR to ensure that B3 values behave the same way except when the
-      alternative would be prohibitive (like with pointer size or the corner-case behaviors of
-      division). But to effectively compile code to different CPUs, the compiler has to eventually
-      make instruction set details explicit. This is where Air comes in. B3 locks in most
-      CPU-specific details at the moment of conversion to Air, and the Air code is irreversibly tied
-      to some specific CPU.&lt;/p&gt;
</del><ins>+      details. It's a goal of B3 IR to ensure that B3 values behave the same way except when the
+      alternative would be counterproductive (like with pointer size, the corner-case behaviors of
+      division, or calling convention customization). But to effectively compile code to different
+      CPUs, the compiler has to eventually make instruction set details explicit. This is where Air
+      comes in. B3 locks in most CPU-specific details at the moment of conversion to Air, and the Air
+      code is irreversibly tied to some specific CPU.&lt;/p&gt;
</ins><span class="cx">     
</span><span class="cx">     &lt;p&gt;Air is an instruction &lt;i&gt;superset&lt;/i&gt;: it recognizes all of the instructions from all CPUs
</span><span class="cx">       that Air may target. In its lowest-level form, Air is simply a way of describing an assembly
</span><span class="lines">@@ -60,26 +59,33 @@
</span><span class="cx">       &lt;a href=&quot;http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/b3/air/AirTmp.h&quot;&gt;&lt;code&gt;Tmp&lt;/code&gt;&lt;/a&gt;s)
</span><span class="cx">       and abstract
</span><span class="cx">       &lt;a href=&quot;http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/b3/air/AirStackSlot.h&quot;&gt;stack
</span><del>-        slots&lt;/a&gt;.&lt;/p&gt;
</del><ins>+        slots&lt;/a&gt;. A &lt;code&gt;Tmp&lt;/code&gt; object can either hold an unallocated temporary or a
+      register.&lt;/p&gt;
</ins><span class="cx">     
</span><span class="cx">     &lt;h3&gt;Air as an Instruction Superset&lt;/h3&gt;
</span><del>-    &lt;p&gt;It is possible to speak of an x86-64 instruction while compiling for ARM64,
-      for example. Clients of Air, such as the B3 to Air lowering phase, are allowed to pick with any
-      Air opcode and ask if that opcode would be valid on the current CPU. They are also allowed to
-      check if specific forms of any given opcode are valid. This allows clients to optimize for
-      multiple instruction sets by cascading through the possible opcodes that they know of, starting
-      with the one they think is most efficient. Some of those opcodes may only be available on one
-      CPU while others are available everywhere.&lt;/p&gt;
</del><ins>+    &lt;p&gt;Air has syntax to speak of all of the CPU instructions we know about. It is possible to speak
+      of an x86-64 instruction while compiling for ARM64, for example. Clients of Air, such as the B3
+      to Air lowering phase, are allowed to pick any Air opcode and ask if that opcode would be
+      valid on the current CPU. They are also allowed to check if specific forms of any given opcode
+      are valid. This allows clients to optimize for multiple instruction sets by cascading through
+      the possible opcodes that they know of, starting with the one they think is most efficient.
+      Some of those opcodes may only be available on one CPU while others are available
+      everywhere. Instruction selection does not need to know which instructions work on which CPUs;
+      Air will tell you if some instruction happens to not be valid right now for whatever reason.&lt;/p&gt;
</ins><span class="cx">     
</span><span class="cx">     &lt;p&gt;Air opcodes support overloading. For example, the Add32 opcode has both two-operand and
</span><del>-      three-operand overloads, and those overloads have multiple forms: the first operand may or
-      may not be an immediate and depending on the CPU, some of the other operands may or may not
-      be memory addresses. A fundamental Air operation is &lt;code&gt;Inst::isValidForm()&lt;/code&gt;, which
-      tells the client if the instruction's current form is valid on the current CPU. This may
-      return false either because the Inst is not well-formed for any CPU or because it is not
-      valid for the current CPU even though it may be valid on some other CPU. This allows clients
-      to generate Air by experimenting with various different instruction forms before settling on
-      the one that the current CPU supports.&lt;/p&gt;
</del><ins>+      three-operand &lt;i&gt;overloads&lt;/i&gt;, and those overloads have multiple &lt;i&gt;forms&lt;/i&gt;: the first
+      operand may or may not be permitted to be an immediate and depending on the CPU and some of the
+      other operands may or may not be allowed to be memory addresses. We use &lt;i&gt;opcode overload&lt;/i&gt;
+      to refer to all forms of an opcode that share the same number of arguments, and &lt;i&gt;opcode
+        form&lt;/i&gt; to mean the number of arguments and their types. A fundamental Air operation is
+      &lt;code&gt;Inst::isValidForm()&lt;/code&gt;, which tells the client if the instruction's current form is
+      valid on the current CPU. This may return false either because the Inst is not well-formed for
+      any CPU or because it is not valid for the current CPU even though it may be valid on some
+      other CPU. There is also &lt;code&gt;Air::isValidForm()&lt;/code&gt;, which can answer if the form you are
+      intending to use will be valid even if you have not created an &lt;code&gt;Inst&lt;/code&gt; yet. This
+      allows clients to generate Air by experimenting with different forms before settling on the one
+      that the current CPU supports.&lt;/p&gt;
</ins><span class="cx">     
</span><span class="cx">     &lt;h3&gt;Air as a High-Level Assembly&lt;/h3&gt;
</span><span class="cx">     &lt;p&gt;Air doesn't require the client to perform register or stack allocation. Anywhere that Air
</span><span class="lines">@@ -93,12 +99,12 @@
</span><span class="cx">       registers, so it's always possible to determine which registers are live at any point in the
</span><span class="cx">       Air code.&lt;/p&gt;
</span><span class="cx">     
</span><del>-    &lt;p&gt;Air's philosophy allows B3 to use it for converting high-level, CPU-agnostic SSA procedures
-      into code for the current CPU. Air is an instruction superset that allows clients to consider
-      all available instructions on all possible CPUs and query which forms of those instructions are
-      available on the current CPU. Air also supports for high-level concepts like &lt;code&gt;Tmp&lt;/code&gt;s
-      and stack slots, which allows B3 to Air lowering to focus on which instructions to use without
-      worrying about register allocation or stack layout.&lt;/p&gt;
</del><ins>+    &lt;p&gt;Air's philosophy allows B3 to use it for converting high-level, mostly-CPU-agnostic SSA
+      procedures into code for the current CPU. Air is an instruction superset that allows clients to
+      consider all available instructions on all possible CPUs and query which forms of those
+      instructions are available on the current CPU. Air also supports for high-level concepts like
+      &lt;code&gt;Tmp&lt;/code&gt;s and stack slots, which allows B3 to Air lowering to focus on which
+      instructions to use without worrying about register allocation or stack layout.&lt;/p&gt;
</ins><span class="cx">     
</span><span class="cx">     &lt;h2&gt;Args and the Air Execution Model&lt;/h2&gt;
</span><span class="cx">     &lt;p&gt;Air can be thought of as an
</span><span class="lines">@@ -107,7 +113,7 @@
</span><span class="cx">       arguments. The opcode determines what Air will do to the arguments - it may read from them or
</span><span class="cx">       write to them, for example. Orthognality implies that any argument that is read may be either
</span><span class="cx">       a register (or &lt;code&gt;Tmp&lt;/code&gt;), an address, or an immediate; while any argument that is
</span><del>-      written may be either a register or an address. Air constraints orthognality where the target
</del><ins>+      written may be either a register or an address. Air constrains orthognality where the target
</ins><span class="cx">       CPU would. For example, none of Air's target CPUs would support an &lt;code&gt;Add32&lt;/code&gt;
</span><span class="cx">       instruction that loads its sources from memory &lt;i&gt;and&lt;/i&gt; stores its result into memory. Even
</span><span class="cx">       x86 doesn't go that far. Either before or after creating an &lt;code&gt;Inst&lt;/code&gt;, the client can
</span><span class="lines">@@ -186,9 +192,9 @@
</span><span class="cx">       &lt;li&gt;Perform &lt;i&gt;late&lt;/i&gt; actions.&lt;/li&gt;
</span><span class="cx">     &lt;/ol&gt;
</span><span class="cx">     
</span><del>-    &lt;p&gt;Note that the early actions of one instruction happen immediately after the late actions of
</del><ins>+    &lt;p&gt;The early actions of one instruction happen immediately after the late actions of
</ins><span class="cx">       the instruction before it. However, many Air analyses view them as happening at the same time.
</span><del>-      For example, any register usage in the early action of one instruction interfere with the
</del><ins>+      For example, any register usage in the early action of one instruction interferes with the
</ins><span class="cx">       register usage in the late action of the instruction that came before it. All of Air's
</span><span class="cx">       liveness and interference analyses reason about the
</span><span class="cx">       &lt;a href=&quot;https://en.wikipedia.org/wiki/Off-by-one_error#Fencepost_error&quot;&gt;&lt;i&gt;fence posts&lt;/i&gt;&lt;/a&gt;
</span><span class="lines">@@ -245,11 +251,17 @@
</span><span class="cx">       &lt;li&gt;&lt;code&gt;func(%rcx, UseZDef, GP, Width32)&lt;/code&gt;&lt;/li&gt;
</span><span class="cx">     &lt;/ol&gt;
</span><span class="cx">     
</span><ins>+    &lt;p&gt;Air's introspection of &lt;code&gt;Inst&lt;/code&gt;s tends to be quite fast thanks to the use of template
+      specialization and C++ lambdas. The &lt;code&gt;forEachArg()&lt;/code&gt; template method uses an efficient
+      arrangement of switch statements to determine the opcode and overload. If &lt;code&gt;func&lt;/code&gt; is
+      a C++ lambda, we expect &lt;code&gt;forEachArg()&lt;/code&gt; to be specialized for that lambda. Therefore,
+      this idiom avoids virtual dispatch or memory allocation.&lt;/p&gt;
+    
</ins><span class="cx">     &lt;p&gt;Air supports exotic roles, such as late uses and early defs. There is even the
</span><span class="cx">       &lt;code&gt;Scratch&lt;/code&gt; role, which means early def and late use. Speaking of a &lt;code&gt;Tmp&lt;/code&gt;
</span><span class="cx">       in the &lt;code&gt;Scratch&lt;/code&gt; role means that the &lt;code&gt;Tmp&lt;/code&gt; will be assigned a register
</span><span class="cx">       that is guaranteed to not interfere with any of the other registers that the instruction
</span><del>-      speaks of. Late uses and early defs are crucial for patchpoints, which may for example require
</del><ins>+      speaks of. Late uses and early defs are crucial for patchpoints, which may require
</ins><span class="cx">       that one of the incoming values be given a register that does not interfere with whatever
</span><span class="cx">       register is used for the result. This can be expressed either as giving the inputs a late use
</span><span class="cx">       role or by giving the outputs an early def role. The full list of possible roles is:&lt;/p&gt;
</span><span class="lines">@@ -299,7 +311,7 @@
</span><span class="cx">       instruction have to do with arguments, and what happens to each argument during the early and
</span><span class="cx">       late actions is determined by the opcode and the number of arguments (i.e. the overload).
</span><span class="cx">       Clients of Air may create an &lt;code&gt;Inst&lt;/code&gt; with any combination of opcode and arguments
</span><del>-      and then query, using &lt;code&gt;Inst::isValidForm()&lt;/code&gt; if the opcode, overload, and specific
</del><ins>+      and then query, using &lt;code&gt;isValidForm()&lt;/code&gt; if the opcode, overload, and specific
</ins><span class="cx">       arguments are valid for the current CPU.&lt;/p&gt;
</span><span class="cx">     
</span><span class="cx">     &lt;h2&gt;Defining Air&lt;/h2&gt;
</span><span class="lines">@@ -344,6 +356,12 @@
</span><span class="cx">     &lt;p&gt;Prefixing any line with &lt;code&gt;x86:&lt;/code&gt; means that this form is only available on x86
</span><span class="cx">       CPUs, such as x86 or x86-64.&lt;/p&gt;
</span><span class="cx">     
</span><ins>+    &lt;p&gt;Air opcodes are designed to work with JavaScriptCore's existing MacroAssembler. By default, an
+      opcode is automatically given a code generator that calls
+      &lt;code&gt;MacroAssembler::&lt;i&gt;opcodeName&lt;/i&gt;&lt;/code&gt;, where &lt;i&gt;opcodeName&lt;/i&gt; is derived by
+      lower-casing the first letter of the Air opcode name. &lt;code&gt;Add32&lt;/code&gt; becomes
+      &lt;code&gt;MacroAssembler::add32&lt;/code&gt;, for example.&lt;/p&gt;
+    
</ins><span class="cx">     &lt;p&gt;See the header of
</span><span class="cx">       &lt;a href=&quot;http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes&quot;&gt;AirOpcode.opcodes&lt;/a&gt;
</span><span class="cx">       for a complete list of shorthand used by Air's opcode definition language.&lt;/p&gt;
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgdocsb3indexhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/docs/b3/index.html (201612 => 201613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/docs/b3/index.html        2016-06-02 19:57:41 UTC (rev 201612)
+++ trunk/Websites/webkit.org/docs/b3/index.html        2016-06-02 20:05:08 UTC (rev 201613)
</span><span class="lines">@@ -30,7 +30,8 @@
</span><span class="cx">     &lt;p&gt;Here's a simple example of C++ code that uses B3 to generate a function that adds two to
</span><span class="cx">       its argument and returns it:&lt;/p&gt;
</span><span class="cx"> 
</span><del>-    &lt;pre&gt;&lt;code&gt;Procedure proc;
</del><ins>+    &lt;pre&gt;&lt;code&gt;// Create a Procedure that holds our code.
+Procedure proc;
</ins><span class="cx"> BasicBlock* root = proc.addBlock();
</span><span class="cx"> root-&gt;appendNew&amp;lt;ControlValue&amp;gt;(
</span><span class="cx">     proc, Return, Origin(),
</span><span class="lines">@@ -39,10 +40,15 @@
</span><span class="cx">         root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0),
</span><span class="cx">         root-&gt;appendNew&lt;Const64Value&gt;(proc, Origin(), 2)));
</span><span class="cx"> 
</span><ins>+// Have B3 compile the Procedure into code. The code and all of its artifacts (constant pools, jump tables)
+// will stay alive so long as Compilation stays alive.
</ins><span class="cx"> std::unique_ptr&amp;lt;Compilation&amp;gt; compilation = std::make_unique&amp;lt;Compilation&amp;gt;(vm, proc);
</span><ins>+
+// Get a function pointer that we can call. This function pointer points to JIT-generated machine code.
</ins><span class="cx"> int64_t (*function)(int64_t) = bitwise_cast&amp;lt;int64_t (*)(int64_t)&amp;gt;(compilation-&gt;code().executableAddress());
</span><span class="cx"> 
</span><del>-printf(&quot;%lld\n&quot;, function(42)); // prints 44&lt;/code&gt;&lt;/pre&gt;
</del><ins>+// Run it and print the result!
+printf(&quot;%lld\n&quot;, function(42)); // Prints 44.&lt;/code&gt;&lt;/pre&gt;
</ins><span class="cx"> 
</span><span class="cx">     &lt;p&gt;When compiled, the resulting machine code looks like this:&lt;/p&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -62,17 +68,18 @@
</span><span class="cx">     &lt;p&gt;Clients of B3 usually interact with it using
</span><span class="cx">       &lt;a href=&quot;intermediate-representation.html&quot;&gt;B3 IR&lt;/a&gt;.  It's C-like, in the sense that it
</span><span class="cx">       models heap references as integers and does not attempt to verify memory accesses.  It
</span><del>-      enforces static single assignment, or SSA for short.  An SSA program will contain only one
-      assignment to each variable, which makes it trivial to trace from a use of a variable to
-      the operation that defined its value.  B3 IR is designed to be easy to generate and cheap
-      to manipulate.&lt;/p&gt;
</del><ins>+      enforces &lt;a href=&quot;https://en.wikipedia.org/wiki/Static_single_assignment_form&quot;&gt;static single
+        assignment&lt;/a&gt;, or SSA for short.  An SSA program will contain only one assignment to each
+      variable, which makes it trivial to trace from a use of a variable to the operation that
+      defined its value.  B3 IR is designed to be easy to generate and cheap to manipulate.&lt;/p&gt;
</ins><span class="cx"> 
</span><del>-    &lt;p&gt;B3 is designed to be used as a backend for JITs, rather than as a tool that programmers
-      use directly.  Therefore, B3 embraces platform-specific concepts like argument registers,
-      stack frame layout, the frame pointer, and the call argument areas.  It's possible to emit
-      B3 IR that defines completely novel calling conventions, both for callers of the procedure
-      being generated and for callees of the procedure's callsites.  B3 also makes it easy to
-      just emit a C call.  There's an opcode for that.&lt;/p&gt;
</del><ins>+    &lt;p&gt;In most ways, B3 IR is platform-agnostic. However, since B3 is designed to be used as a
+      backend for JITs, it does embrace some platform-specific concepts whenever it is pragmatic to
+      do so. B3 exposes direct control over argument registers, stack frame layout, the frame
+      pointer, and the call argument areas.  It's possible to emit B3 IR that defines completely
+      novel calling conventions, both for callers of the procedure being generated and for callees of
+      the procedure's callsites.  B3 also makes it easy to just emit a C call.  There's an opcode for
+      that.&lt;/p&gt;
</ins><span class="cx"> 
</span><span class="cx">     &lt;p&gt;See &lt;a href=&quot;intermediate-representation.html&quot;&gt;the IR documentation&lt;/a&gt; for more
</span><span class="cx">       info.&lt;/p&gt;
</span><span class="lines">@@ -146,7 +153,7 @@
</span><span class="cx">     Add64 $2, %rdi, %rax, @2
</span><span class="cx">     Ret64 %rax, @3&lt;/code&gt;&lt;/pre&gt;
</span><span class="cx"> 
</span><del>-    &lt;h2&gt;B3-&gt;Air lowering, also known as Instruction Selection&lt;/h2&gt;
</del><ins>+    &lt;h2&gt;B3&amp;rarr;Air lowering, also known as Instruction Selection&lt;/h2&gt;
</ins><span class="cx"> 
</span><span class="cx">     &lt;p&gt;The B3::LowerToAir phase converts B3 into Air by doing pattern-matching.  It processes
</span><span class="cx">       programs backwards.  At each B3 value, it greedily tries to match both the value and as
</span><span class="lines">@@ -193,8 +200,8 @@
</span><span class="cx"> 
</span><span class="cx">     &lt;h2&gt;Code generation&lt;/h2&gt;
</span><span class="cx"> 
</span><del>-    &lt;p&gt;The final form of Air contains no registers or abstract stack slots.  Therefore, it maps
-      directly to machine code.  The final code generation step is a very fast transformation
</del><ins>+    &lt;p&gt;The final form of Air contains no unallocated temporaries or abstract stack slots.  Therefore,
+      it maps directly to machine code.  The final code generation step is a very fast transformation
</ins><span class="cx">       from Air's object-oriented way of representing those instructions to the target's machine
</span><span class="cx">       code.  We use JavaScriptCore's macro assembler for this purpose.&lt;/p&gt;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgdocsb3intermediaterepresentationhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/docs/b3/intermediate-representation.html (201612 => 201613)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-06-02 19:57:41 UTC (rev 201612)
+++ trunk/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-06-02 20:05:08 UTC (rev 201613)
</span><span class="lines">@@ -65,6 +65,16 @@
</span><span class="cx">       &lt;dd&gt;64-bit binary floating point number.&lt;/dd&gt;
</span><span class="cx">     &lt;/dl&gt;
</span><span class="cx"> 
</span><ins>+    &lt;p&gt;B3 does not have a pointer type. Instead, the &lt;code&gt;B3::pointerType()&lt;/code&gt; function will
+      return either Int32 or Int64 depending on which kind of integer can be used to represent a
+      pointer on the current platform. It's not a goal of B3 to support hardware targets that require
+      pointers and integers to be segregated. It's not a goal of B3 to support GC (garbage
+      collection) roots as a separate type, since JSC uses
+      &lt;a href=&quot;http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-88-2.pdf&quot;&gt;Bartlett-style conservative
+        root scanning&lt;/a&gt;. This doesn't preclude any mainstream garbage collection algorithms,
+      including copying, generational, or concurrent collectors, and frees up the compiler to perform
+      more optimizations.&lt;/p&gt;
+
</ins><span class="cx">     &lt;h2&gt;Values&lt;/h2&gt;
</span><span class="cx"> 
</span><span class="cx">     &lt;p&gt;Variables, and the instructions that define them, are represented using the Value object.
</span><span class="lines">@@ -412,11 +422,12 @@
</span><span class="cx">         the CCallValue class.&lt;/dd&gt;
</span><span class="cx"> 
</span><span class="cx">       &lt;dt&gt;T1 Patchpoint([T2, [T3, ...]])&lt;/dt&gt;
</span><del>-      &lt;dd&gt;A Patchpoint is a customizable value.  Patchpoints take zero or more values of any
-        type and return any type.  A Patchpoint's behavior is determined by the generator
-        object.  The generator is a C++ lambda that gets called during code generation.  It gets
-        passed an assembler instance (specifically, CCallHelpers&amp;) and an object describing
-        where to find all of the input values and where to put the result.  Here's an example:
</del><ins>+      &lt;dd&gt;
+        &lt;p&gt;A Patchpoint is a customizable value.  Patchpoints take zero or more values of any
+          type and return any type.  A Patchpoint's behavior is determined by the generator
+          object.  The generator is a C++ lambda that gets called during code generation.  It gets
+          passed an assembler instance (specifically, CCallHelpers&amp;) and an object describing
+          where to find all of the input values and where to put the result.  Here's an example:&lt;/p&gt;
</ins><span class="cx">  
</span><span class="cx">         &lt;pre&gt;&lt;code&gt;PatchpointValue* patchpoint = block-&gt;appendNew&amp;lt;PatchpointValue&amp;gt;(proc, Int32, Origin());
</span><span class="cx"> patchpoint-&gt;append(ConstrainedValue(arg1, ValueRep::SomeRegister));
</span></span></pre>
</div>
</div>

</body>
</html>