minor tweaks
[oota-llvm.git] / docs / ProgrammersManual.html
index f0f941f58409925cd5872faa3a5259a97af31c2d..a990462c253872967016f288f8b35f1ab517028e 100644 (file)
@@ -54,7 +54,7 @@ option</a></li>
       <li><a href="#dss_vector">&lt;vector&gt;</a></li>
       <li><a href="#dss_deque">&lt;deque&gt;</a></li>
       <li><a href="#dss_list">&lt;list&gt;</a></li>
-      <li><a href="#dss_ilist">llvm/ADT/ilist</a></li>
+      <li><a href="#dss_ilist">llvm/ADT/ilist.h</a></li>
       <li><a href="#dss_other">Other Sequential Container Options</a></li>
     </ul></li>
     <li><a href="#ds_set">Set-Like Containers (std::set, SmallSet, SetVector, etc)</a>
@@ -247,10 +247,9 @@ reference</a> - an excellent reference for the STL and other parts of the
 standard C++ library.</li>
 
 <li><a href="http://www.tempest-sw.com/cpp/">C++ In a Nutshell</a> - This is an
-O'Reilly book in the making.  It has a decent 
-Standard Library
-Reference that rivals Dinkumware's, and is unfortunately no longer free since the book has been 
-published.</li>
+O'Reilly book in the making.  It has a decent Standard Library
+Reference that rivals Dinkumware's, and is unfortunately no longer free since the
+book has been published.</li>
 
 <li><a href="http://www.parashift.com/c++-faq-lite/">C++ Frequently Asked
 Questions</a></li>
@@ -333,7 +332,7 @@ file (note that you very rarely have to include this file directly).</p>
   <dt><tt>cast&lt;&gt;</tt>: </dt>
 
   <dd><p>The <tt>cast&lt;&gt;</tt> operator is a "checked cast" operation. It
-  converts a pointer or reference from a base class to a derived cast, causing
+  converts a pointer or reference from a base class to a derived class, causing
   an assertion failure if it is not really an instance of the right type.  This
   should be used in cases where you have some information that makes you believe
   that something is of the right type.  An example of the <tt>isa&lt;&gt;</tt>
@@ -878,7 +877,7 @@ not invalidate iterator or pointers to other elements in the list.</p>
 
 <!-- _______________________________________________________________________ -->
 <div class="doc_subsubsection">
-  <a name="dss_ilist">llvm/ADT/ilist</a>
+  <a name="dss_ilist">llvm/ADT/ilist.h</a>
 </div>
 
 <div class="doc_text">
@@ -886,15 +885,63 @@ not invalidate iterator or pointers to other elements in the list.</p>
 intrusive, because it requires the element to store and provide access to the
 prev/next pointers for the list.</p>
 
-<p>ilist has the same drawbacks as std::list, and additionally requires an
-ilist_traits implementation for the element type, but it provides some novel
-characteristics.  In particular, it can efficiently store polymorphic objects,
-the traits class is informed when an element is inserted or removed from the
-list, and ilists are guaranteed to support a constant-time splice operation.
-</p>
+<p><tt>ilist</tt> has the same drawbacks as <tt>std::list</tt>, and additionally
+requires an <tt>ilist_traits</tt> implementation for the element type, but it
+provides some novel characteristics.  In particular, it can efficiently store
+polymorphic objects, the traits class is informed when an element is inserted or
+removed from the list, and <tt>ilist</tt>s are guaranteed to support a
+constant-time splice operation.</p>
+
+<p>These properties are exactly what we want for things like
+<tt>Instruction</tt>s and basic blocks, which is why these are implemented with
+<tt>ilist</tt>s.</p>
+
+Related classes of interest are explained in the following subsections:
+    <ul>
+      <li><a href="#dss_ilist_traits">ilist_traits</a></li>
+      <li><a href="#dss_iplist">iplist</a></li>
+      <li><a href="#dss_ilist_node">llvm/ADT/ilist_node.h</a></li>
+    </ul>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="dss_ilist_traits">ilist_traits</a>
+</div>
 
-<p>These properties are exactly what we want for things like Instructions and
-basic blocks, which is why these are implemented with ilists.</p>
+<div class="doc_text">
+<p><tt>ilist_traits&lt;T&gt;</tt> is <tt>ilist&lt;T&gt;</tt>'s customization
+mechanism. <tt>iplist&lt;T&gt;</tt> (and consequently <tt>ilist&lt;T&gt;</tt>)
+publicly derive from this traits class.</p>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="dss_iplist">iplist</a>
+</div>
+
+<div class="doc_text">
+<p><tt>iplist&lt;T&gt;</tt> is <tt>ilist&lt;T&gt;</tt>'s base and as such
+supports a slightly narrower interface. Notably, inserters from
+<tt>T&amp;</tt> are absent.</p>
+
+<p><tt>ilist_traits&lt;T&gt;</tt> is a public base of this class and can be
+used for a wide variety of customizations.</p>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="dss_ilist_node">llvm/ADT/ilist_node.h</a>
+</div>
+
+<div class="doc_text">
+<p><tt>ilist_node&lt;T&gt;</tt> implements a the forward and backward links
+that are expected by the <tt>ilist&lt;T&gt;</tt> (and analogous containers)
+in the default manner.</p>
+
+<p><tt>ilist_node&lt;T&gt;</tt>s are meant to be embedded in the node type
+<tt>T</tt>, usually <tt>T</tt> publicly derives from
+<tt>ilist_node&lt;T&gt;</tt>.</p>
 </div>
 
 <!-- _______________________________________________________________________ -->
@@ -1141,21 +1188,16 @@ factors, and produces a lot of malloc traffic.  It should be avoided.</p>
 
 <p>
 The STL provides several other options, such as std::multiset and the various 
-"hash_set" like containers (whether from C++ TR1 or from the SGI library).</p>
+"hash_set" like containers (whether from C++ TR1 or from the SGI library). We
+never use hash_set and unordered_set because they are generally very expensive 
+(each insertion requires a malloc) and very non-portable.
+</p>
 
 <p>std::multiset is useful if you're not interested in elimination of
 duplicates, but has all the drawbacks of std::set.  A sorted vector (where you 
 don't delete duplicate entries) or some other approach is almost always
 better.</p>
 
-<p>The various hash_set implementations (exposed portably by
-"llvm/ADT/hash_set") is a simple chained hashtable.  This algorithm is as malloc
-intensive as std::set (performing an allocation for each element inserted,
-thus having really high constant factors) but (usually) provides O(1)
-insertion/deletion of elements.  This can be useful if your elements are large
-(thus making the constant-factor cost relatively low) or if comparisons are
-expensive.  Element iteration does not visit elements in a useful order.</p>
-
 </div>
 
 <!-- ======================================================================= -->
@@ -1294,20 +1336,14 @@ another element takes place).</p>
 
 <p>
 The STL provides several other options, such as std::multimap and the various 
-"hash_map" like containers (whether from C++ TR1 or from the SGI library).</p>
+"hash_map" like containers (whether from C++ TR1 or from the SGI library). We
+never use hash_set and unordered_set because they are generally very expensive 
+(each insertion requires a malloc) and very non-portable.</p>
 
 <p>std::multimap is useful if you want to map a key to multiple values, but has
 all the drawbacks of std::map.  A sorted vector or some other approach is almost
 always better.</p>
 
-<p>The various hash_map implementations (exposed portably by
-"llvm/ADT/hash_map") are simple chained hash tables.  This algorithm is as
-malloc intensive as std::map (performing an allocation for each element
-inserted, thus having really high constant factors) but (usually) provides O(1)
-insertion/deletion of elements.  This can be useful if your elements are large
-(thus making the constant-factor cost relatively low) or if comparisons are
-expensive.  Element iteration does not visit elements in a useful order.</p>
-
 </div>
 
 <!-- ======================================================================= -->
@@ -1614,7 +1650,7 @@ class OurFunctionPass : public FunctionPass {
 
     virtual runOnFunction(Function&amp; F) {
       for (Function::iterator b = F.begin(), be = F.end(); b != be; ++b) {
-        for (BasicBlock::iterator i = b-&gt;begin(); ie = b-&gt;end(); i != ie; ++i) {
+        for (BasicBlock::iterator i = b-&gt;begin(), ie = b-&gt;end(); i != ie; ++i) {
           if (<a href="#CallInst">CallInst</a>* callInst = <a href="#isa">dyn_cast</a>&lt;<a
  href="#CallInst">CallInst</a>&gt;(&amp;*i)) {
             // <i>We know we've encountered a call instruction, so we</i>
@@ -1944,9 +1980,9 @@ and <tt>ReplaceInstWithInst</tt>.</p>
 <ul>
   <li><tt>ReplaceInstWithValue</tt>
 
-    <p>This function replaces all uses (within a basic block) of a given
-    instruction with a value, and then removes the original instruction. The
-    following example illustrates the replacement of the result of a particular
+    <p>This function replaces all uses of a given instruction with a value,
+    and then removes the original instruction. The following example
+    illustrates the replacement of the result of a particular
     <tt>AllocaInst</tt> that allocates memory for a single integer with a null
     pointer to an integer.</p>
 
@@ -1956,14 +1992,16 @@ AllocaInst* instToReplace = ...;
 BasicBlock::iterator ii(instToReplace);
 
 ReplaceInstWithValue(instToReplace-&gt;getParent()-&gt;getInstList(), ii,
-                     Constant::getNullValue(PointerType::get(Type::Int32Ty)));
+                     Constant::getNullValue(PointerType::getUnqual(Type::Int32Ty)));
 </pre></div></li>
 
   <li><tt>ReplaceInstWithInst</tt> 
 
     <p>This function replaces a particular instruction with another
-    instruction. The following example illustrates the replacement of one
-    <tt>AllocaInst</tt> with another.</p>
+    instruction, inserting the new instruction into the basic block at the
+    location where the old instruction was, and replacing any uses of the old
+    instruction with the new instruction. The following example illustrates
+    the replacement of one <tt>AllocaInst</tt> with another.</p>
 
 <div class="doc_code">
 <pre>
@@ -2089,7 +2127,7 @@ To build this, use the following LLVM APIs:
 // <i>Create the initial outer struct</i>
 <a href="#PATypeHolder">PATypeHolder</a> StructTy = OpaqueType::get();
 std::vector&lt;const Type*&gt; Elts;
-Elts.push_back(PointerType::get(StructTy));
+Elts.push_back(PointerType::getUnqual(StructTy));
 Elts.push_back(Type::Int32Ty);
 StructType *NewSTy = StructType::get(Elts);
 
@@ -2232,85 +2270,99 @@ insert entries into the symbol table.</p>
 
 <div class="doc_text">
 <p>The <tt><a href="http://llvm.org/doxygen/classllvm_1_1User.html">
-User</a></tt> class provides a base for expressing the ownership of <tt>User</tt>
+User</a></tt> class provides a basis for expressing the ownership of <tt>User</tt>
 towards other <tt><a href="http://llvm.org/doxygen/classllvm_1_1Value.html">
 Value</a></tt>s. The <tt><a href="http://llvm.org/doxygen/classllvm_1_1Use.html">
-Use</a></tt> helper class is employed to do the bookkeeping and facilitate O(1)
+Use</a></tt> helper class is employed to do the bookkeeping and to facilitate <i>O(1)</i>
 addition and removal.</p>
 
-<pre>
-   -----------------------------------------------------------------
-   --- Interaction and relationship between User and Use objects ---
-   -----------------------------------------------------------------
-
+<!-- ______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="Use2User">Interaction and relationship between <tt>User</tt> and <tt>Use</tt> objects</a>
+</div>
 
-A subclass of User can choose between incorporating its Use objects
+<div class="doc_text">
+<p>
+A subclass of <tt>User</tt> can choose between incorporating its <tt>Use</tt> objects
 or refer to them out-of-line by means of a pointer. A mixed variant
-(some Uses inline others hung off) is impractical and breaks the invariant
-that the Use objects belonging to the same User form a contiguous array.
-
-We have 2 different layouts in the User (sub)classes:
-
-Layout a)
-The Use object(s) are inside (resp. at fixed offset) of the User
-object and there are a fixed number of them.
-
-Layout b)
-The Use object(s) are referenced by a pointer to an
-array from the User object and there may be a variable
-number of them.
+(some <tt>Use</tt>s inline others hung off) is impractical and breaks the invariant
+that the <tt>Use</tt> objects belonging to the same <tt>User</tt> form a contiguous array.
+</p>
+</div>
 
-Initially each layout will possess a direct pointer to the
-start of the array of Uses. Though not mandatory for layout a),
+<p>
+We have 2 different layouts in the <tt>User</tt> (sub)classes:
+<ul>
+<li><p>Layout a)
+The <tt>Use</tt> object(s) are inside (resp. at fixed offset) of the <tt>User</tt>
+object and there are a fixed number of them.</p>
+
+<li><p>Layout b)
+The <tt>Use</tt> object(s) are referenced by a pointer to an
+array from the <tt>User</tt> object and there may be a variable
+number of them.</p>
+</ul>
+<p>
+As of v2.4 each layout still possesses a direct pointer to the
+start of the array of <tt>Use</tt>s. Though not mandatory for layout a),
 we stick to this redundancy for the sake of simplicity.
-The User object will also store the number of Use objects it
+The <tt>User</tt> object also stores the number of <tt>Use</tt> objects it
 has. (Theoretically this information can also be calculated
-given the scheme presented below.)
-
-Special forms of allocation operators (operator new)
-will enforce the following memory layouts:
-
-
-#  Layout a) will be modelled by prepending the User object
-#  by the Use[] array.
-#      
-#      ...---.---.---.---.-------...
-#        | P | P | P | P | User
-#      '''---'---'---'---'-------'''
-
-
-#  Layout b) will be modelled by pointing at the Use[] array.
-#      
-#      .-------...
-#      | User
-#      '-------'''
-#          |
-#          v
-#          .---.---.---.---...
-#          | P | P | P | P |
-#          '---'---'---'---'''
+given the scheme presented below.)</p>
+<p>
+Special forms of allocation operators (<tt>operator new</tt>)
+enforce the following memory layouts:</p>
 
-   (In the above figures 'P' stands for the Use** that
-    is stored in each Use object in the member Use::Prev)
+<ul>
+<li><p>Layout a) is modelled by prepending the <tt>User</tt> object by the <tt>Use[]</tt> array.</p>
 
+<pre>
+...---.---.---.---.-------...
+  | P | P | P | P | User
+'''---'---'---'---'-------'''
+</pre>
 
-Since the Use objects will be deprived of the direct pointer to
-their User objects, there must be a fast and exact method to
-recover it. This is accomplished by the following scheme:
+<li><p>Layout b) is modelled by pointing at the <tt>Use[]</tt> array.</p>
+<pre>
+.-------...
+| User
+'-------'''
+    |
+    v
+    .---.---.---.---...
+    | P | P | P | P |
+    '---'---'---'---'''
+</pre>
+</ul>
+<i>(In the above figures '<tt>P</tt>' stands for the <tt>Use**</tt> that
+    is stored in each <tt>Use</tt> object in the member <tt>Use::Prev</tt>)</i>
 
-A bit-encoding in the 2 LSBits of the Use::Prev will allow to find the
-start of the User object:
+<!-- ______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="Waymarking">The waymarking algorithm</a>
+</div>
 
-00 --> binary digit 0
-01 --> binary digit 1
-10 --> stop and calc (s)
-11 --> full stop (S)
+<div class="doc_text">
+<p>
+Since the <tt>Use</tt> objects are deprived of the direct (back)pointer to
+their <tt>User</tt> objects, there must be a fast and exact method to
+recover it. This is accomplished by the following scheme:</p>
+</div>
 
-Given a Use*, all we have to do is to walk till we get
-a stop and we either have a User immediately behind or
+A bit-encoding in the 2 LSBits (least significant bits) of the <tt>Use::Prev</tt> allows to find the
+start of the <tt>User</tt> object:
+<ul>
+<li><tt>00</tt> &mdash;&gt; binary digit 0</li>
+<li><tt>01</tt> &mdash;&gt; binary digit 1</li>
+<li><tt>10</tt> &mdash;&gt; stop and calculate (<tt>s</tt>)</li>
+<li><tt>11</tt> &mdash;&gt; full stop (<tt>S</tt>)</li>
+</ul>
+<p>
+Given a <tt>Use*</tt>, all we have to do is to walk till we get
+a stop and we either have a <tt>User</tt> immediately behind or
 we have to walk to the next stop picking up digits
-and calculating the offset:
-
+and calculating the offset:</p>
+<pre>
 .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.----------------
 | 1 | s | 1 | 0 | 1 | 0 | s | 1 | 1 | 0 | s | 1 | 1 | s | 1 | S | User (or User*)
 '---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'----------------
@@ -2320,14 +2372,24 @@ and calculating the offset:
     |                   |               |______________________>
     |                   |______________________________________>
     |__________________________________________________________>
-
-
+</pre>
+<p>
 Only the significant number of bits need to be stored between the
-stops, so that the worst case is 20 memory accesses when there are
-1000 Use objects.
+stops, so that the <i>worst case is 20 memory accesses</i> when there are
+1000 <tt>Use</tt> objects associated with a <tt>User</tt>.</p>
 
-The following literate Haskell fragment demonstrates the concept:
+<!-- ______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="ReferenceImpl">Reference implementation</a>
+</div>
 
+<div class="doc_text">
+<p>
+The following literate Haskell fragment demonstrates the concept:</p>
+</div>
+
+<div class="doc_code">
+<pre>
 > import Test.QuickCheck
 > 
 > digits :: Int -> [Char] -> [Char]
@@ -2345,13 +2407,16 @@ The following literate Haskell fragment demonstrates the concept:
 > 
 > test = takeLast 40 $ dist 20 []
 > 
+</pre>
+</div>
+<p>
+Printing &lt;test&gt; gives: <tt>"1s100000s11010s10100s1111s1010s110s11s1S"</tt></p>
+<p>
+The reverse algorithm computes the length of the string just by examining
+a certain prefix:</p>
 
-Printing <test> gives: "1s100000s11010s10100s1111s1010s110s11s1S"
-
-The reverse algorithm computes the
-length of the string just by examining
-a certain prefix:
-
+<div class="doc_code">
+<pre>
 > pref :: [Char] -> Int
 > pref "S" = 1
 > pref ('s':'1':rest) = decode 2 1 rest
@@ -2361,44 +2426,64 @@ a certain prefix:
 > decode walk acc ('1':rest) = decode (walk + 1) (acc * 2 + 1) rest
 > decode walk acc _ = walk + acc
 > 
+</pre>
+</div>
+<p>
+Now, as expected, printing &lt;pref test&gt; gives <tt>40</tt>.</p>
+<p>
+We can <i>quickCheck</i> this with following property:</p>
 
-Now, as expected, printing <pref test> gives 40.
-
-We can quickCheck this with following property:
-
+<div class="doc_code">
+<pre>
 > testcase = dist 2000 []
 > testcaseLength = length testcase
 > 
 > identityProp n = n > 0 && n <= testcaseLength ==> length arr == pref arr
 >     where arr = takeLast n testcase
+> 
+</pre>
+</div>
+<p>
+As expected &lt;quickCheck identityProp&gt; gives:</p>
 
-As expected <quickCheck identityProp> gives:
-
+<pre>
 *Main> quickCheck identityProp
 OK, passed 100 tests.
+</pre>
+<p>
+Let's be a bit more exhaustive:</p>
 
-Let's be a bit more exhaustive:
-
+<div class="doc_code">
+<pre>
 > 
 > deepCheck p = check (defaultConfig { configMaxTest = 500 }) p
 > 
+</pre>
+</div>
+<p>
+And here is the result of &lt;deepCheck identityProp&gt;:</p>
 
-And here is the result of <deepCheck identityProp>:
-
+<pre>
 *Main> deepCheck identityProp
 OK, passed 500 tests.
+</pre>
 
+<!-- ______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="Tagging">Tagging considerations</a>
+</div>
 
-To maintain the invariant that the 2 LSBits of each Use** in Use
-never change after being set up, setters of Use::Prev must re-tag the
-new Use** on every modification. Accordingly getters must strip the
-tag bits.
-
-For layout b) instead of the User we will find a pointer (User* with LSBit set).
-Following this pointer brings us to the User. A portable trick will ensure
-that the first bytes of User (if interpreted as a pointer) will never have
-the LSBit set.
-</pre>
+<p>
+To maintain the invariant that the 2 LSBits of each <tt>Use**</tt> in <tt>Use</tt>
+never change after being set up, setters of <tt>Use::Prev</tt> must re-tag the
+new <tt>Use**</tt> on every modification. Accordingly getters must strip the
+tag bits.</p>
+<p>
+For layout b) instead of the <tt>User</tt> we find a pointer (<tt>User*</tt> with LSBit set).
+Following this pointer brings us to the <tt>User</tt>. A portable trick ensures
+that the first bytes of <tt>User</tt> (if interpreted as a pointer) never has
+the LSBit set. (Portability is relying on the fact that all known compilers place the
+<tt>vptr</tt> in the first word of the instances.)</p>
 
 </div>
 
@@ -2443,7 +2528,7 @@ the <tt>lib/VMCore</tt> directory.</p>
 
 <!-- _______________________________________________________________________ -->
 <div class="doc_subsubsection">
-  <a name="m_Value">Important Public Methods</a>
+  <a name="m_Type">Important Public Methods</a>
 </div>
 
 <div class="doc_text">
@@ -2465,7 +2550,7 @@ the <tt>lib/VMCore</tt> directory.</p>
 
 <!-- _______________________________________________________________________ -->
 <div class="doc_subsubsection">
-  <a name="m_Value">Important Derived Types</a>
+  <a name="derivedtypes">Important Derived Types</a>
 </div>
 <div class="doc_text">
 <dl>
@@ -3121,7 +3206,7 @@ is its address (after linking) which is guaranteed to be constant.</p>
     will automatically be inserted into that module's list of
     functions.</p></li>
 
-  <li><tt>bool isExternal()</tt>
+  <li><tt>bool isDeclaration()</tt>
 
     <p>Return whether or not the <tt>Function</tt> has a body defined.  If the
     function is "external", it does not have a body, and thus must be resolved
@@ -3227,11 +3312,12 @@ never change at runtime).</p>
     <p>Create a new global variable of the specified type. If
     <tt>isConstant</tt> is true then the global variable will be marked as
     unchanging for the program. The Linkage parameter specifies the type of
-    linkage (internal, external, weak, linkonce, appending) for the variable. If
-    the linkage is InternalLinkage, WeakLinkage, or LinkOnceLinkage,&nbsp; then
-    the resultant global variable will have internal linkage.  AppendingLinkage
-    concatenates together all instances (in different translation units) of the
-    variable into a single variable but is only applicable to arrays.  &nbsp;See
+    linkage (internal, external, weak, linkonce, appending) for the variable.
+    If the linkage is InternalLinkage, WeakAnyLinkage, WeakODRLinkage,
+    LinkOnceAnyLinkage or LinkOnceODRLinkage,&nbsp; then the resultant
+    global variable will have internal linkage.  AppendingLinkage concatenates
+    together all instances (in different translation units) of the variable
+    into a single variable but is only applicable to arrays.  &nbsp;See
     the <a href="LangRef.html#modulestructure">LLVM Language Reference</a> for
     further details on linkage types. Optionally an initializer, a name, and the
     module to put the variable into may be specified for the global variable as
@@ -3363,9 +3449,9 @@ arguments. An argument has a pointer to the parent Function.</p>
 <hr>
 <address>
   <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
-  src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
+  src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
   <a href="http://validator.w3.org/check/referer"><img
-  src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /></a>
+  src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Strict"></a>
 
   <a href="mailto:dhurjati@cs.uiuc.edu">Dinakar Dhurjati</a> and
   <a href="mailto:sabre@nondot.org">Chris Lattner</a><br>