<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>evan.musing &#60;&#60; current &#187; awesomeness</title>
	<atom:link href="http://blog.fallingsnow.net/category/awesomeness/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.fallingsnow.net</link>
	<description>life and tech stuff by Evan Phoenix</description>
	<lastBuildDate>Mon, 30 Nov 2009 05:39:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.fallingsnow.net' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/5a9b0b6f691c857857dd1bf6d5bf9dc4?s=96&#038;d=http://s2.wp.com/i/buttonw-com.png</url>
		<title>evan.musing &#60;&#60; current &#187; awesomeness</title>
		<link>http://blog.fallingsnow.net</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.fallingsnow.net/osd.xml" title="evan.musing &#60;&#60; current" />
	<atom:link rel='hub' href='http://blog.fallingsnow.net/?pushpress=hub'/>
		<item>
		<title>Fixing colors in Terminal.app on 10.6</title>
		<link>http://blog.fallingsnow.net/2009/08/28/fixing-colors-in-terminal-app-on-10-6/</link>
		<comments>http://blog.fallingsnow.net/2009/08/28/fixing-colors-in-terminal-app-on-10-6/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 02:08:30 +0000</pubDate>
		<dc:creator>evanphx</dc:creator>
				<category><![CDATA[awesomeness]]></category>
		<category><![CDATA[colors]]></category>
		<category><![CDATA[Snow Leopard]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://evanphx.wordpress.com/?p=92</guid>
		<description><![CDATA[It&#8217;s Snow Leopard day zero, so of course I had to upgrade. All in all, everything is great. (Especially the multiple monitor window migration fix!) But the #1 thing that annoys me about all OS X releases in the colors in Terminal.app. They&#8217;re pretty much unusable on a dark background (especially the blue). For some [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fallingsnow.net&amp;blog=1516804&amp;post=92&amp;subd=evanphx&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s Snow Leopard day zero, so of course I had to upgrade. All in all, everything is great. (Especially the multiple monitor window migration fix!)</p>
<p>But the #1 thing that annoys me about all OS X releases in the colors in Terminal.app. They&#8217;re pretty much unusable on a dark background (especially the blue). For some time, there have been hacks to fix the problem. Well of course these hacks didn&#8217;t work on 10.6 anymore.</p>
<p>Never one to shy away from the problem, I dove in. And we have success!</p>
<p>Here&#8217;s how to make it work:</p>
<ul>
<li>Find Terminal.app in Finder (/Applications/Utilities), right click, &#8220;Get Info&#8221;</li>
<li>There is a checkbox &#8220;Open in 32-bit mode&#8221;, <strong>Check it!</strong></li>
<li>Install SIMBL. Plugsuit was installed on my machine before, it freaks out because of the 10.6 changes. SIMBL silently just works or doesn&#8217;t.</li>
<li>Get <a href="http://cloud.github.com/downloads/evanphx/terminalcolours/TerminalColours-SL.tar.gz">My updated TerminalColours SIMBL plugin</a>. See <a href="http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal">the original post</a> for details on how to install it.</li>
<li>Restart Terminal.app</li>
<li>Enjoy your readable colors!</li>
</ul>
<p>This works because InputManagers still work in 32bit mode, but not 64bit mode. So by forcing Terminal.app to run in 32bit mode, SIMBL can still hook in. I just had to update TerminalColours to swizzle a new method that 10.6 uses to pick colors.</p>
<p>Hope you enjoy!</p>
<p><strong>Update:</strong> I&#8217;ve changed the tar.gz download link to one that should work better.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/evanphx.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/evanphx.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/evanphx.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/evanphx.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/evanphx.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/evanphx.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/evanphx.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/evanphx.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/evanphx.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/evanphx.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/evanphx.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/evanphx.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/evanphx.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/evanphx.wordpress.com/92/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fallingsnow.net&amp;blog=1516804&amp;post=92&amp;subd=evanphx&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fallingsnow.net/2009/08/28/fixing-colors-in-terminal-app-on-10-6/feed/</wfw:commentRss>
		<slash:comments>70</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/540cb3b3712ffe045113cb03bab616a2?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">evanphx</media:title>
		</media:content>
	</item>
		<item>
		<title>Simple VM JIT with LLVM</title>
		<link>http://blog.fallingsnow.net/2008/05/23/simple-vm-jit-with-llvm/</link>
		<comments>http://blog.fallingsnow.net/2008/05/23/simple-vm-jit-with-llvm/#comments</comments>
		<pubDate>Sat, 24 May 2008 01:03:54 +0000</pubDate>
		<dc:creator>evanphx</dc:creator>
				<category><![CDATA[CS]]></category>
		<category><![CDATA[LLVM]]></category>

		<guid isPermaLink="false">http://evanphx.wordpress.com/?p=46</guid>
		<description><![CDATA[I&#8217;ve been investigating using LLVM for Rubinius, so I&#8217;ve been doing some very small scale experiments. I typically do this on most projects, to get a mental handle on the problem. In doing this, I&#8217;ve written a very tiny VM to play with how LLVM handles it. Here is the breakdown of the entire VM: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fallingsnow.net&amp;blog=1516804&amp;post=46&amp;subd=evanphx&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;ve been investigating using <a href="http://llvm.org">LLVM</a> for <a href="http://rubini.us">Rubinius</a>, so I&#8217;ve been doing some very small scale experiments. I typically do this on most projects, to get a mental handle on the problem.
</p>
<p>
In doing this, I&#8217;ve written a very tiny VM to play with how LLVM handles it. Here is the breakdown of the entire VM:</p>
<ul>
<li>Only operates on <em>int</em>s.
<li>Uses numbered registers for operations.
<li>3 Instructions:
<ol start="0">
<li><b>set(reg, val)</b> Set register number <em>reg</em> to integer value <em>val</em></li>
<li><b>add(result, reg, val)</b> Add register <em>reg</em> to <em>val</em> and put the result in </em>result</em></li>
<li><b>show(reg)</b> Print out the contents of register <em>reg</em></li>
</ol>
</li>
</ul>
<p>
Pretty trivial. Not turing complete because there is no branching. But it&#8217;s simple enough to explore how to handle bytecode in LLVM.
</p>
<p><h3>Sample Program</h3>
<p>So, I&#8217;ve written a sample program, encoded directly as bytecode:</p>
<pre>
  [ 0, 0, 3,
    1, 0, 0, 4,
    2, 0 ]
</pre>
<p>
This is:</p>
<ul>
<li>Set register <em>0</em> to <em>3</em></li>
<li>Add register <em>0</em> to <em>4</em> and put the result in register <em>0</em></li>
<li>Show register <em>0</em></li>
</ul>
<p>
Again, totally trivial. Should just output 7.
</p>
<p><h3>C Switch</h3>
<p>So, the VM Design 101 way is to build a C switch statement to interpret each bytecode and perform it&#8217;s operations. It would look like this, given that <em>int ops[]</em> contains the above integer sequence for the program:<br />

<pre>
void add(int* ops, int* registers) {
  registers[ops[1]] = registers[ops[2]] + ops[3];
}

void set(int* ops, int* registers) {
  registers[ops[1]] = ops[2];
}

void show(int* ops, int* registers) {
  printf("=&gt; %d\n", registers[ops[1]]);
}

void run(int* ops, int* registers) {
  switch(*ops) {
  case 0:
	set(ops, registers);
	ops += 3;
    break;
  case 1:
	add(ops, registers);
	ops += 4;
    break;
  case 2:
	show(ops, registers);
    return;
  }
}
</pre>
<p>
Very easy. We increments ops to move forward, using ops as a pointer to the current instruction. This is how every VM starts. But this code is very slow when compared to machine code because it obscures the execution flow from the CPU. And besides, this doesn&#8217;t use LLVM, the whole point of this post.
</p>
<h3>A static result&#8230;</h3>
<p>As we look at the code that was run, we see that the program is set, add, then show. Lets pretend for a sec that given the above functions, we want to perform the same operation, we&#8217;d write:</p>
<pre>
void my_program() {
  int registers[2] = {0, 0};
  int program[10] = [ 0, 0, 3,
                      1, 0, 0, 4,
                      2, 0 ]

  int* ops = (int*)program;

  set(ops, registers);
  ops += 3;
  add(ops, registers);
  ops += 4;
  show(ops, registers);
  ops += 2;
}
</pre>
<p>
So, <em>my_program</em> would perform the same operations as your bytecode above, and considerable faster because we avoid all the overhead the switch statement.
</p>
<p><h3>Combining the 2</h3>
<p>If you look at the bytecode, than the at the hand written C, we can see that there there is a programmatic way to go from our array of numbers to the C code.</p>
<p>
A common approach that people have taken in the past to actually write a C code emitter, that would parse the integers once, spit out a .c file, which you&#8217;d compile, then run. This works ok for some situations, but it doesn&#8217;t allow for any kind of dynamic abilities to run code. And besides, it doesn&#8217;t use LLVM.
</p>
<p>
The idea is to write a function thats takes as input the array of numbers and dynamically builds the equivalent of the above C function. And thats where LLVM comes in.
</p>
<p><h4>Part 1: importing the functions</h4>
<p>A key part to this scheme is to have the add/set/show functions we defined above available to LLVM. Doing so lets us use our normal tools to write the each instruction as a small operation that can easily be tested. So, given that we have put those 3 functions into ops.c, we run:<br />
<code>llvm-gcc -emit-llvm -O3 -c ops.c</code>, which generates <em>ops.o</em> as a LLVM bitcode file. Using <code>llvm-dis &lt; ops.o</code> we see it contains:</p>
<pre>
@.str = internal constant [7 x i8] c"=&gt; %dA0"		;  [#uses=1]

define void @add(i32* %ops, i32* %registers) nounwind  {
entry:
	%tmp1 = getelementptr i32* %ops, i32 1		;  [#uses=1]
	%tmp2 = load i32* %tmp1, align 4		;  [#uses=1]
	%tmp4 = getelementptr i32* %ops, i32 2		;  [#uses=1]
	%tmp5 = load i32* %tmp4, align 4		;  [#uses=1]
	%tmp7 = getelementptr i32* %registers, i32 %tmp5		;  [#uses=1]
	%tmp8 = load i32* %tmp7, align 4		;  [#uses=1]
	%tmp10 = getelementptr i32* %ops, i32 3		;  [#uses=1]
	%tmp11 = load i32* %tmp10, align 4		;  [#uses=1]
	%tmp12 = add i32 %tmp11, %tmp8		;  [#uses=1]
	%tmp14 = getelementptr i32* %registers, i32 %tmp2		;  [#uses=1]
	store i32 %tmp12, i32* %tmp14, align 4
	ret void
}

define void @set(i32* %ops, i32* %registers) nounwind  {
entry:
	%tmp1 = getelementptr i32* %ops, i32 1		;  [#uses=1]
	%tmp2 = load i32* %tmp1, align 4		;  [#uses=1]
	%tmp4 = getelementptr i32* %ops, i32 2		;  [#uses=1]
	%tmp5 = load i32* %tmp4, align 4		;  [#uses=1]
	%tmp7 = getelementptr i32* %registers, i32 %tmp2		;  [#uses=1]
	store i32 %tmp5, i32* %tmp7, align 4
	ret void
}

declare i32 @printf(i8*, ...) nounwind 

define void @show(i32* %ops, i32* %registers) nounwind  {
entry:
	%tmp1 = getelementptr i32* %ops, i32 1		;  [#uses=1]
	%tmp2 = load i32* %tmp1, align 4		;  [#uses=1]
	%tmp4 = getelementptr i32* %registers, i32 %tmp2		;  [#uses=1]
	%tmp5 = load i32* %tmp4, align 4		;  [#uses=1]
	%tmp7 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([7 x i8]* @.str, i32 0, i32 0), i32 %tmp5 ) nounwind 		;  [#uses=0]
	ret void
}
</pre>
<p>
Now we have our functions ready for easy importing.
</p>
<p><h4>Phase 2: LLVM C++ API</h4>
<p>When I did this experiment, I decided that the function that, given an array of ints, would drive the LLVM, wasn&#8217;t necessary. After all, all I was concerned was if the output of that process would actually work. So instead, I hand wrote a function that uses the LLVM C++ api the same way it would be if this were dynamic:</p>
<pre>
Function* create(Module** out) {
  std::string error;
  Module* jit;

  // Load in the bitcode file containing the functions for each
  // bytecode operation.
  if(MemoryBuffer* buffer = MemoryBuffer::getFile("ops.o", &amp;error)) {
    jit = ParseBitcodeFile(buffer, &amp;error);
    delete buffer;
  }

  // Pull out references to them.
  Function* set =  jit-&gt;getFunction(std::string("set"));
  Function* add =  jit-&gt;getFunction(std::string("add"));
  Function* show = jit-&gt;getFunction(std::string("show"));

  // Now, begin building our new function, which calls the
  // above functions.
  Function* body = cast&lt;Function&gt;(jit-&gt;getOrInsertFunction("body",
        Type::VoidTy,
        PointerType::getUnqual(Type::Int32Ty),
        PointerType::getUnqual(Type::Int32Ty), (Type*)0));

  // Our function will be passed the ops pointer and the
  // registers pointer, just like before.
  Function::arg_iterator args = body-&gt;arg_begin();
  Value* ops = args++;
  ops-&gt;setName("ops");
  Value* registers = args++;
  registers-&gt;setName("registers");

  BasicBlock *bb = BasicBlock::Create("entry", body);

  // Set up our arguments to be passed to set.
  std::vector&lt;Value*&gt; params;
  params.push_back(ops);
  params.push_back(registers);

  // Call out to set, passing ops and registers down
  CallInst* call = CallInst::Create(set, params.begin(), params.end(), "", bb);
  ConstantInt* const_3 = ConstantInt::get(APInt(32,  "3", 10));
  ConstantInt* const_4 = ConstantInt::get(APInt(32,  "4", 10));

  // add 3 to the ops pointer.
  GetElementPtrInst* ptr1 = GetElementPtrInst::Create(ops, const_3, "tmp3", bb);

  // Setup and call add, notice we pass down the updated ops pointer
  // rather than the original, so that we've moved down.
  std::vector&lt;Value*&gt; params2;
  params2.push_back(ptr1);
  params2.push_back(registers);
  CallInst* call2 = CallInst::Create(add, params2.begin(), params2.end(), "", bb);

  // Push the ops pointer down another 4.
  GetElementPtrInst* ptr2 = GetElementPtrInst::Create(ops, const_4, "tmp3", bb);

  // Setup and call show.
  std::vector&lt;Value*&gt; params3;
  params3.push_back(ptr2);
  params3.push_back(registers);
  CallInst* call3 = CallInst::Create(show, params3.begin(), params3.end(), "", bb);

  // And we're done!
  ReturnInst::Create(bb);

  *out = jit;
  return body;
}
</pre>
<p>
Now, lets write a function that calls <code>create()</code> and executes the result:</p>
<pre>
int main() {
  // The registers.
  int registers[2] = {0, 0};

  // Our program.
  int program[20] = {0, 0, 3,
                     1, 0, 0, 4,
                     2, 0};

  int* ops = (int*)program;

  // Create our function and give us the Module and Function back.
  Module* jit;
  Function* func = create(&amp;jit);

  // Add in optimizations. These were taken from a list that 'opt', LLVMs optimization tool, uses.
  PassManager p;

  /* Comment out optimize
  p.add(new TargetData(jit));
  p.add(createVerifierPass());
  p.add(createLowerSetJmpPass());
  p.add(createRaiseAllocationsPass());
  p.add(createCFGSimplificationPass());
  p.add(createPromoteMemoryToRegisterPass());
  p.add(createGlobalOptimizerPass());
  p.add(createGlobalDCEPass());
  p.add(createFunctionInliningPass());
  */

  // Run these optimizations on our Module
  p.run(*jit);

  // Setup for JIT
  ExistingModuleProvider* mp = new ExistingModuleProvider(jit);
  ExecutionEngine* engine = ExecutionEngine::create(mp);

  // Show us what we've created!
  std::cout &lt;&lt; "Created\n" &lt;&lt; *jit;

  // Have our function JIT'd into machine code and return. We cast it to a particular C function pointer signature so we can call in nicely.
  void (*fp)(int*, int*) = (void (*)(int*, int*))engine-&gt;getPointerToFunction(func);

  // Call what we've created!
  fp(ops, registers);
}
</pre>
<p>We drive our create() function and then execute the result. As you can see, we&#8217;ve commented out all optimizations as a first try. The output from running this is:</p>
<pre>
&lt;snip same LLVM as before&gt;

define void @body(i32* %ops, i32* %registers) {
entry:
	call void @set( i32* %ops, i32* %registers )
	%tmp3 = getelementptr i32* %ops, i32 3		;  [#uses=1]
	call void @add( i32* %tmp3, i32* %registers )
	%tmp31 = getelementptr i32* %ops, i32 4		;  [#uses=1]
	call void @show( i32* %tmp31, i32* %registers )
	ret void
}
=&gt; 7
</pre>
<p>Hey! Look at that! It runs! And we can see what it ran. We see it perform the calls to our functions that implement each opcode. Going back, it would be easily to write a function that dynamically drivers the LLVM C++ API to generate this code, it&#8217;s simply one call per bytecode, mapped directly.<br />
Even if that were all that LLVM let us do, it would be worth it, but&#8230;
</p>
<p><h3>Wait, there&#8217;s more!</h3>
<p>Before, we ran without optimizations to keep the output simple, lets see what happens we turn them on:</p>
<pre>
define void @body(i32* %ops, i32* %registers) {
entry:
	%tmp1.i = getelementptr i32* %ops, i32 1		;  [#uses=1]
	%tmp2.i = load i32* %tmp1.i, align 4		;  [#uses=1]
	%tmp4.i = getelementptr i32* %ops, i32 2		;  [#uses=1]
	%tmp5.i = load i32* %tmp4.i, align 4		;  [#uses=1]
	%tmp7.i = getelementptr i32* %registers, i32 %tmp2.i		;  [#uses=1]
	store i32 %tmp5.i, i32* %tmp7.i, align 4
	%tmp3 = getelementptr i32* %ops, i32 3		;  [#uses=3]
	%tmp1.i7 = getelementptr i32* %tmp3, i32 1		;  [#uses=1]
	%tmp2.i8 = load i32* %tmp1.i7, align 4		;  [#uses=1]
	%tmp4.i9 = getelementptr i32* %tmp3, i32 2		;  [#uses=1]
	%tmp5.i10 = load i32* %tmp4.i9, align 4		;  [#uses=1]
	%tmp7.i11 = getelementptr i32* %registers, i32 %tmp5.i10		;  [#uses=1]
	%tmp8.i = load i32* %tmp7.i11, align 4		;  [#uses=1]
	%tmp10.i = getelementptr i32* %tmp3, i32 3		;  [#uses=1]
	%tmp11.i = load i32* %tmp10.i, align 4		;  [#uses=1]
	%tmp12.i = add i32 %tmp11.i, %tmp8.i		;  [#uses=1]
	%tmp14.i = getelementptr i32* %registers, i32 %tmp2.i8		;  [#uses=1]
	store i32 %tmp12.i, i32* %tmp14.i, align 4
	%tmp31 = getelementptr i32* %ops, i32 4		;  [#uses=1]
	%tmp1.i2 = getelementptr i32* %tmp31, i32 1		;  [#uses=1]
	%tmp2.i3 = load i32* %tmp1.i2, align 4		;  [#uses=1]
	%tmp4.i4 = getelementptr i32* %registers, i32 %tmp2.i3		;  [#uses=1]
	%tmp5.i5 = load i32* %tmp4.i4, align 4		;  [#uses=1]
	%tmp7.i6 = call i32 (i8*, ...)* @printf( i8* getelementptr ([7 x i8]* @.str, i32 0, i32 0), i32 %tmp5.i5 ) nounwind 		;  [#uses=0]
	ret void
}
=&gt; 7
</pre>
<p><b>WOW!</b> Now we&#8217;re cooking with hot flaming nuclear power! LLVM has the extra mile and rather than just calling our functions that implement each instruction, it&#8217;s inlined all that code directly into our dynamically generated function! This means A LOT of additional overhead is discarded because, since our functions themselves did simple operations like store into memory or add 2 numbers, that code is now run a lot more quickly.</p>
<p>
It&#8217;s commonly known that inlining can dramatically improve performance because it eliminates the over head of function calls (spilling and reload registers, stack frames, etc). And LLVM has just given us a powerful form of that for free.<br />
This doesn&#8217;t allow for inlining across things like the kind of method call that Ruby does, but it puts us on the track to being able to feed LLVM enough information to do just that.
</p>
<p>
LLVM is an amazing piece of software. I can&#8217;t wait to start using it more.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/evanphx.wordpress.com/46/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/evanphx.wordpress.com/46/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/evanphx.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/evanphx.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/evanphx.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/evanphx.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/evanphx.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/evanphx.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/evanphx.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/evanphx.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/evanphx.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/evanphx.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/evanphx.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/evanphx.wordpress.com/46/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/evanphx.wordpress.com/46/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/evanphx.wordpress.com/46/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.fallingsnow.net&amp;blog=1516804&amp;post=46&amp;subd=evanphx&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.fallingsnow.net/2008/05/23/simple-vm-jit-with-llvm/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/540cb3b3712ffe045113cb03bab616a2?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">evanphx</media:title>
		</media:content>
	</item>
	</channel>
</rss>