<head>
<title>Stacker: An Example Of Using LLVM</title>
<link rel="stylesheet" href="llvm.css" type="text/css">
- <style>
- table, tr, td { border: 2px solid gray }
- table { border-collapse: collapse }
- </style>
</head>
<body>
<li><a href="#comments">Comments</a></li>
<li><a href="#literals">Literals</a></li>
<li><a href="#words">Words</a></li>
- <li><a href="style">Standard Style</a></li>
+ <li><a href="#style">Standard Style</a></li>
<li><a href="#builtins">Built-Ins</a></li>
</ol></li>
<li><a href="#example">Prime: A Complete Example</a></li>
</ol></li>
</ol>
-<div class="doc_text">
-<p><b>Written by <a href="mailto:rspencer@x10sys.com">Reid Spencer</a></b></p>
+<div class="doc_author">
+ <p>Written by <a href="mailto:rspencer@x10sys.com">Reid Spencer</a></p>
</div>
<!-- ======================================================================= -->
classes were derived from the Value class. The full power of that simple
design only became fully understood once I started constructing executable
expressions for Stacker.</p>
+
<p>This really makes your programming go faster. Think about compiling code
for the following C/C++ expression: <code>(a|b)*((x+1)/(y+1))</code>. Assuming
the values are on the stack in the order a, b, x, y, this could be
expressed in stacker as: <code>1 + SWAP 1 + / ROT2 OR *</code>.
-You could write a function using LLVM that computes this expression like this: </p>
-<pre><code>
+You could write a function using LLVM that computes this expression like
+this: </p>
+
+<div class="doc_code"><pre>
Value*
expression(BasicBlock* bb, Value* a, Value* b, Value* x, Value* y )
{
- Instruction* tail = bb->getTerminator();
- ConstantSInt* one = ConstantSInt::get( Type::IntTy, 1);
- BinaryOperator* or1 =
- BinaryOperator::create( Instruction::Or, a, b, "", tail );
- BinaryOperator* add1 =
- BinaryOperator::create( Instruction::Add, x, one, "", tail );
- BinaryOperator* add2 =
- BinaryOperator::create( Instruction::Add, y, one, "", tail );
- BinaryOperator* div1 =
- BinaryOperator::create( Instruction::Div, add1, add2, "", tail);
- BinaryOperator* mult1 =
- BinaryOperator::create( Instruction::Mul, or1, div1, "", tail );
-
+ ConstantSInt* one = ConstantSInt::get(Type::IntTy, 1);
+ BinaryOperator* or1 = BinaryOperator::createOr(a, b, "", bb);
+ BinaryOperator* add1 = BinaryOperator::createAdd(x, one, "", bb);
+ BinaryOperator* add2 = BinaryOperator::createAdd(y, one, "", bb);
+ BinaryOperator* div1 = BinaryOperator::createDiv(add1, add2, "", bb);
+ BinaryOperator* mult1 = BinaryOperator::createMul(or1, div1, "", bb);
return mult1;
}
-</code></pre>
+</pre></div>
+
<p>"Okay, big deal," you say? It is a big deal. Here's why. Note that I didn't
have to tell this function which kinds of Values are being passed in. They could be
<code>Instruction</code>s, <code>Constant</code>s, <code>GlobalVariable</code>s, or
linking.</p>
</div>
<!-- ======================================================================= -->
+<div class="doc_subsection"><a name="style"></a>Standard Style</div>
+<div class="doc_text">
+<p>TODO</p>
+</div>
+<!-- ======================================================================= -->
<div class="doc_subsection"><a name="builtins"></a>Built In Words</div>
<div class="doc_text">
<p>The built-in words of the Stacker language are put in several groups
</ol>
</div>
<div class="doc_text" >
- <table class="doc_table">
-<tr class="doc_table"><td colspan="4">Definition Of Operation Of Built In Words</td></tr>
-<tr class="doc_table"><td colspan="4"><b>LOGICAL OPERATIONS</b></td></tr>
-<tr class="doc_table">
+ <table>
+<tr><th colspan="4">Definition Of Operation Of Built In Words</th></tr>
+<tr><th colspan="4"><b>LOGICAL OPERATIONS</b></th></tr>
+<tr>
<td>Word</td>
<td>Name</td>
<td>Operation</td>
<td>Description</td>
</tr>
-<tr class="doc_table">
+<tr>
<td><</td>
<td>LT</td>
<td>w1 w2 -- b</td>
<td> -- b</td>
<td>The boolean value TRUE (-1) is pushed on to the stack.</td>
</tr>
-<tr><td colspan="4"><b>BITWISE OPERATORS</b></td></tr>
+<tr><th colspan="4"><b>BITWISE OPERATORS</b></th></tr>
<tr>
<td>Word</td>
<td>Name</td>
are bitwise exclusive OR'd together and pushed back on the stack.
For example, The sequence 1 3 XOR yields 2.</td>
</tr>
-<tr><td colspan="4"><b>ARITHMETIC OPERATORS</b></td></tr>
+<tr><th colspan="4"><b>ARITHMETIC OPERATORS</b></th></tr>
<tr>
<td>Word</td>
<td>Name</td>
<td>Two values are popped off the stack. The larger value is pushed back
on to the stack.</td>
</tr>
-<tr><td colspan="4"><b>STACK MANIPULATION OPERATORS</b></td></tr>
+<tr><th colspan="4"><b>STACK MANIPULATION OPERATORS</b></th></tr>
<tr>
<td>Word</td>
<td>Name</td>
how much to rotate. That is, ROLL with n=1 is the same as ROT and
ROLL with n=2 is the same as ROT2.</td>
</tr>
-<tr><td colspan="4"><b>MEMORY OPERATORS</b></td></tr>
+<tr><th colspan="4"><b>MEMORY OPERATORS</b></th></tr>
<tr>
<td>Word</td>
<td>Name</td>
pushed back on the stack so this doesn't count as a "use ptr"
in the FREE idiom.</td>
</tr>
-<tr><td colspan="4"><b>CONTROL FLOW OPERATORS</b></td></tr>
+<tr><th colspan="4"><b>CONTROL FLOW OPERATORS</b></th></tr>
<tr>
<td>Word</td>
<td>Name</td>
the top of stack is decremented to 0 at which the WHILE test fails and control is
transfered to the word after the END.</td>
</tr>
-<tr><td colspan="4"><b>INPUT & OUTPUT OPERATORS</b></td></tr>
+<tr><th colspan="4"><b>INPUT & OUTPUT OPERATORS</b></th></tr>
<tr>
<td>Word</td>
<td>Name</td>
to see instantly the net effect of the definition.</td>
</tr>
</table>
+
</div>
<!-- ======================================================================= -->
<div class="doc_section"> <a name="example">Prime: A Complete Example</a></div>
<li>Write an LLVM pass to compute the correct stack depth needed by the
program. Currently the stack is set to a fixed number which means programs
with large numbers of definitions might fail.</li>
- <li>Enhance to run on 64-bit platforms like SPARC. Right now the size of a
- pointer on 64-bit machines will cause incorrect results because of the
- 32-bit size of a stack element currently supported. This feature was not
- implemented because LLVM needs a union type to be able to support the
- different sizes correctly (portably and efficiently).</li>
<li>Write an LLVM pass to optimize the use of the global stack. The code
emitted currently is somewhat wasteful. It gets cleaned up a lot by existing
passes but more could be done.</li>
- <li>Add -O -O1 -O2 and -O3 optimization switches to the compiler driver to
- allow LLVM optimization without using "opt."</li>
<li>Make the compiler driver use the LLVM linking facilities (with IPO)
before depending on GCC to do the final link.</li>
<li>Clean up parsing. It doesn't handle errors very well.</li>