[pure-lang-svn] SF.net SVN: pure-lang: [138] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-05-27 04:28:34
|
Revision: 138 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=138&view=rev Author: agraef Date: 2008-05-26 21:28:33 -0700 (Mon, 26 May 2008) Log Message: ----------- Experimental support for tail-recursive short-circuit logical operators (&& and ||). Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc pure/trunk/interpreter.hh Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-26 20:25:34 UTC (rev 137) +++ pure/trunk/ChangeLog 2008-05-27 04:28:33 UTC (rev 138) @@ -1,3 +1,11 @@ +2008-05-27 Albert Graef <Dr....@t-...> + + * interpreter.cc (toplevel_codegen): Experimental support for + tail-recursive short-circuit logical operators (&& and ||). Note + that this makes these operations behave slightly differently (more + like if-then-else) if they form the right-hand side of an + equation. But the advantages seem to outweigh the semantic quirks. + 2008-05-26 Albert Graef <Dr....@t-...> * interpreter.cc, runtime.cc: Overhaul of the shadow stack Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-26 20:25:34 UTC (rev 137) +++ pure/trunk/interpreter.cc 2008-05-27 04:28:33 UTC (rev 138) @@ -3225,11 +3225,51 @@ void interpreter::toplevel_codegen(expr x) { +#if USE_FASTCC assert(!x.is_null()); - if (x.tag() == EXPR::COND) + if (x.tag() == EXPR::COND) { toplevel_cond(x.xval1(), x.xval2(), x.xval3()); - else - act_env().CreateRet(codegen(x)); + return; + } + Env& e = act_env(); +#if TAILOPS + Builder& b = act_builder(); + expr f; uint32_t n = count_args(x, f); + if (n == 2 && x.ttag() == EXPR::INT && + x.xval1().xval2().ttag() != EXPR::DBL && + x.xval2().ttag() != EXPR::DBL) { + if (f.ftag() == symtab.or_sym().f) { + Value *u = get_int(x.xval1().xval2()); + Value *condv = b.CreateICmpNE(u, Zero, "cond"); + BasicBlock *iftruebb = new BasicBlock("iftrue"); + BasicBlock *iffalsebb = new BasicBlock("iffalse"); + b.CreateCondBr(condv, iftruebb, iffalsebb); + e.f->getBasicBlockList().push_back(iftruebb); + b.SetInsertPoint(iftruebb); + e.CreateRet(ibox(One)); + e.f->getBasicBlockList().push_back(iffalsebb); + b.SetInsertPoint(iffalsebb); + toplevel_codegen(x.xval2()); + } else if (f.ftag() == symtab.and_sym().f) { + Value *u = get_int(x.xval1().xval2()); + Value *condv = b.CreateICmpNE(u, Zero, "cond"); + BasicBlock *iftruebb = new BasicBlock("iftrue"); + BasicBlock *iffalsebb = new BasicBlock("iffalse"); + b.CreateCondBr(condv, iftruebb, iffalsebb); + e.f->getBasicBlockList().push_back(iffalsebb); + b.SetInsertPoint(iffalsebb); + e.CreateRet(ibox(Zero)); + e.f->getBasicBlockList().push_back(iftruebb); + b.SetInsertPoint(iftruebb); + toplevel_codegen(x.xval2()); + } else + e.CreateRet(codegen(x)); + } else +#endif + e.CreateRet(codegen(x)); +#else + act_env().CreateRet(codegen(x)); +#endif } Value *interpreter::codegen(expr x) Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-05-26 20:25:34 UTC (rev 137) +++ pure/trunk/interpreter.hh 2008-05-27 04:28:33 UTC (rev 138) @@ -28,6 +28,11 @@ /* Experimental support for the "fast" calling convention which is needed to get tail call elimination. */ #define USE_FASTCC 1 +/* Experimental support for tail-recursive short-circuit logical operators (&& + and ||). This will only have an effect if USE_FASTCC is enabled. Note that + if you disable this option, && and || will still be short-curcuit, they + just won't be tail-recursive in their second operand any more. */ +#define TAILOPS 1 using namespace std; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |