[pure-lang-svn] SF.net SVN: pure-lang: [437] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-07-13 10:25:08
|
Revision: 437 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=437&view=rev Author: agraef Date: 2008-07-13 03:25:17 -0700 (Sun, 13 Jul 2008) Log Message: ----------- Streamline code for list and tuple expressions. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/expr.cc pure/trunk/expr.hh pure/trunk/interpreter.cc pure/trunk/printer.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-07-12 23:16:41 UTC (rev 436) +++ pure/trunk/ChangeLog 2008-07-13 10:25:17 UTC (rev 437) @@ -1,5 +1,9 @@ 2008-07-13 Albert Graef <Dr....@t-...> + * interpreter.cc (codegen): Streamline code for list and tuple + expressions. This works around some severe performance bugs in the + LLVM JIT, which gets awfully slow on deep call graphs. + * interpreter.cc (run): LLVM 2.3 requires that we add the default shared library extension manually. Modified: pure/trunk/expr.cc =================================================================== --- pure/trunk/expr.cc 2008-07-12 23:16:41 UTC (rev 436) +++ pure/trunk/expr.cc 2008-07-13 10:25:17 UTC (rev 437) @@ -170,11 +170,20 @@ { expr x, y; if (is_cons(x, y)) - return !x.is_pair() && y.is_list(); + return y.is_listx(); else return is_nil(); } +bool expr::is_listx() const +{ + expr x, y; + if (is_cons(x, y)) + return !x.is_pair() && y.is_listx(); + else + return is_nil(); +} + bool expr::is_voidx() const { return tag() == interpreter::g_interp->symtab.void_sym().f; @@ -198,14 +207,33 @@ { expr x, y; if (is_cons(x, y)) { - if (x.is_pair()) + xs.push_back(x); + return y.is_listx(xs); + } else if (is_nil()) + return true; + else { + xs.clear(); + return false; + } +} + +bool expr::is_listx(exprl &xs) const +{ + expr x, y; + if (is_cons(x, y)) { + if (x.is_pair()) { + xs.clear(); return false; - else { + } else { xs.push_back(x); - return y.is_list(xs); + return y.is_listx(xs); } - } else - return is_nil(); + } else if (is_nil()) + return true; + else { + xs.clear(); + return false; + } } bool expr::is_pair(expr &x, expr &y) const Modified: pure/trunk/expr.hh =================================================================== --- pure/trunk/expr.hh 2008-07-12 23:16:41 UTC (rev 436) +++ pure/trunk/expr.hh 2008-07-13 10:25:17 UTC (rev 437) @@ -460,6 +460,9 @@ bool is_nil() const; bool is_cons() const; bool is_list() const; + // Check for lists which don't contain tuple elements, so that they can be + // printed in standard list format. + bool is_listx() const; bool is_voidx() const; bool is_pair() const; // This is always true, as we consider a singleton as a tuple, too. Use @@ -467,6 +470,7 @@ bool is_tuple() const { return true; } bool is_cons(expr &x, expr &y) const; bool is_list(exprl &xs) const; + bool is_listx(exprl &xs) const; bool is_pair(expr &x, expr &y) const; // Always true (see note above). Use is_pair() && istuple(xs) to test for a // "real" tuple instead. Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-07-12 23:16:41 UTC (rev 436) +++ pure/trunk/interpreter.cc 2008-07-13 10:25:17 UTC (rev 437) @@ -238,6 +238,12 @@ "pure_pointer", "expr*", 1, "void*"); declare_extern((void*)pure_apply, "pure_apply", "expr*", 2, "expr*", "expr*"); + + declare_extern((void*)pure_listl, + "pure_listl", "expr*", -1, "int"); + declare_extern((void*)pure_tuplel, + "pure_tuplel", "expr*", -1, "int"); + declare_extern((void*)pure_cmp_bigint, "pure_cmp_bigint", "int", 3, "expr*", "int", sizeof(mp_limb_t)==8?"long*":"int*"); @@ -3672,6 +3678,7 @@ interactive session. */ expr f; uint32_t n = count_args(x, f); Value *v; Env *e; + exprl xs; if (f.tag() == EXPR::FVAR && (v = funcall(f.vtag(), f.vidx(), n, x))) // local function call return v; @@ -3701,6 +3708,21 @@ argv.push_back(body); act_env().CreateCall(module->getFunction("pure_new_args"), argv); return call("pure_catch", handler, body); + } else if (x.is_list(xs) || x.is_pair() && x.is_tuple(xs)) { + // optimize the case of proper lists and tuples + size_t i = 0, n = xs.size(); + vector<Value*> argv(n+1); + argv[0] = UInt(n); + for (exprl::iterator it = xs.begin(), end = xs.end(); it != end; it++) + argv[++i] = codegen(*it); + act_env().CreateCall(module->getFunction("pure_new_args"), argv); + return act_env().CreateCall + (module->getFunction(x.is_pair()?"pure_tuplel":"pure_listl"), argv); + vector<Value*> argv1; + argv1.push_back(NullExprPtr); + argv1.insert(argv1.end(), argv.begin(), argv.end()); + act_env().CreateCall(module->getFunction("pure_free_args"), argv1); + return v; } else { // ordinary function application Value *u = codegen(x.xval1()), *v = codegen(x.xval2()); Modified: pure/trunk/printer.cc =================================================================== --- pure/trunk/printer.cc 2008-07-12 23:16:41 UTC (rev 436) +++ pure/trunk/printer.cc 2008-07-13 10:25:17 UTC (rev 437) @@ -84,7 +84,7 @@ case EXPR::APP: { expr u, v, w; prec_t p; - if (x.is_list()) + if (x.is_listx()) return 100; else if (x.is_app(u, v)) if (u.tag() > 0 && (p = sym_nprec(u.tag())) < 100 && p%10 >= 3) @@ -248,7 +248,7 @@ expr u, v, w, y; exprl xs; prec_t p; - if (x.is_list(xs)) { + if (x.is_listx(xs)) { // proper list value size_t n = xs.size(); os << "["; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |