<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -44,6 +44,11 @@ def ack(m, n)
   end
 end
 
+def tail(n)
+  return if n == 0
+  tail(n-1)
+end
+
 class Class1
   def method1; end
   def method2(x); x; end
@@ -122,6 +127,9 @@ Benchmark.bm(30) do |bm|
     o = Class1.new
     i=0; while i&lt;10000000; o.send(:method1); i+=1; end
   end
+  bm.report('30000000 tail calls') do
+    tail(30000000) 
+  end
 
   # Instance variables.
   bm.report('10000000 ivar read') { bench_ivar_read(10000000) }</diff>
      <filename>bench.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2213,6 +2213,8 @@ RoxorVM::RoxorVM(void)
     fpm-&gt;add(createGVNPass());
     // Simplify the control flow graph (deleting unreachable blocks, etc).
     fpm-&gt;add(createCFGSimplificationPass());
+    // Eliminate tail calls.
+    fpm-&gt;add(createTailCallEliminationPass());
 }
 
 IMP
@@ -3343,16 +3345,17 @@ RoxorCompiler::compile_node(NODE *node)
 			GlobalVariable *old_class = current_opened_class;
 			current_opened_class = new GlobalVariable(
 				RubyObjTy,
-				false,
+				true,
 				GlobalValue::InternalLinkage,
 				nilVal,
 				&quot;current_opened_class&quot;,
 				RoxorCompiler::module);
-			new StoreInst(classVal, current_opened_class, bb);
 
 			std::map&lt;ID, int *&gt; old_ivar_slots_cache = ivar_slots_cache;
 			ivar_slots_cache.clear();
 
+			new StoreInst(classVal, current_opened_class, bb);
+
 			Value *val = compile_node(body-&gt;nd_body);
 
 			BasicBlock::InstListType &amp;list = bb-&gt;getInstList();
@@ -3457,7 +3460,9 @@ rescan_args:
 			params.push_back(compile_node(n-&gt;nd_head));
 		    }
 
-		   return cast&lt;Value&gt;(CallInst::Create(f, params.begin(), params.end(), &quot;&quot;, bb));
+		    CallInst *inst = CallInst::Create(f, params.begin(), params.end(), &quot;&quot;, bb);
+		    inst-&gt;setTailCall(true);
+		    return cast&lt;Value&gt;(inst);
 		}
 
 		// Prepare the dispatcher parameters.</diff>
      <filename>roxor.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -241,3 +241,10 @@ assert '42', %{
   w = 42
   foo { |x, y = :y| p w }
 }
+
+# Tail-call elimination
+assert '42', %{
+  def foo(n); return if n == 0; foo(n-1); end
+  foo(30000000)
+  p 42
+}</diff>
      <filename>test_vm/dispatch.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>35d4238417c52c89a72fd7d5cee52f5367943651</id>
    </parent>
  </parents>
  <author>
    <name>lsansonetti@apple.com</name>
    <email>lsansonetti@apple.com@23306eb0-4c56-4727-a40e-e92c0eb68959</email>
  </author>
  <url>http://github.com/masterkain/macruby/commit/1fc75cae311f9bb46f66156938cff0ebf1daba2c</url>
  <id>1fc75cae311f9bb46f66156938cff0ebf1daba2c</id>
  <committed-date>2009-04-07T18:24:23-07:00</committed-date>
  <authored-date>2009-04-07T18:24:23-07:00</authored-date>
  <message>enabled tail-call elimination

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/experimental@1397 23306eb0-4c56-4727-a40e-e92c0eb68959</message>
  <tree>3e11d84285f1b1278fd3a08701b5dbfe9c1e57c4</tree>
  <committer>
    <name>lsansonetti@apple.com</name>
    <email>lsansonetti@apple.com@23306eb0-4c56-4727-a40e-e92c0eb68959</email>
  </committer>
</commit>
