[pure-lang-svn] SF.net SVN: pure-lang:[461] pure/trunk
Status: Beta
Brought to you by:
agraef
|
From: <ag...@us...> - 2008-08-10 20:21:17
|
Revision: 461
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=461&view=rev
Author: agraef
Date: 2008-08-10 20:21:23 +0000 (Sun, 10 Aug 2008)
Log Message:
-----------
Optimize toplevel expressions to avoid unnecessary evaluations of constants.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/expr.cc
pure/trunk/expr.hh
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
pure/trunk/test/test015.log
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/ChangeLog 2008-08-10 20:21:23 UTC (rev 461)
@@ -1,5 +1,8 @@
2008-08-10 Albert Graef <Dr....@t-...>
+ * interpreter.cc (doeval, dodefn): Optimize the case of toplevel
+ evaluations and variable definitions of constant expressions.
+
* interpreter.cc (codegen): Fixed memory leak caused by the new
list and tuple code. Reported by Jiri Spitz.
Modified: pure/trunk/expr.cc
===================================================================
--- pure/trunk/expr.cc 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/expr.cc 2008-08-10 20:21:23 UTC (rev 461)
@@ -196,6 +196,15 @@
u.tag() == interpreter::g_interp->symtab.pair_sym().f;
}
+bool expr::is_tuplex() const
+{
+ expr x, y;
+ if (is_pair(x, y))
+ return !x.is_pair() && y.is_tuplex();
+ else
+ return true;
+}
+
bool expr::is_cons(expr &x, expr &y) const
{
expr u, v;
@@ -254,6 +263,23 @@
}
}
+bool expr::is_tuplex(exprl &xs) const
+{
+ expr x, y;
+ if (is_pair(x, y))
+ if (x.is_pair()) {
+ xs.clear();
+ return false;
+ } else {
+ xs.push_back(x);
+ return y.is_tuplex(xs);
+ }
+ else {
+ xs.push_back(*this);
+ return true;
+ }
+}
+
env_info::env_info(const env_info& e) : t(e.t), temp(e.temp) {
switch (t) {
case none:
Modified: pure/trunk/expr.hh
===================================================================
--- pure/trunk/expr.hh 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/expr.hh 2008-08-10 20:21:23 UTC (rev 461)
@@ -468,6 +468,8 @@
// This is always true, as we consider a singleton as a tuple, too. Use
// is_pair() to test for a "real" tuple instead.
bool is_tuple() const { return true; }
+ // Check for proper (normalized) tuples.
+ bool is_tuplex() const;
bool is_cons(expr &x, expr &y) const;
bool is_list(exprl &xs) const;
bool is_listx(exprl &xs) const;
@@ -475,6 +477,7 @@
// Always true (see note above). Use is_pair() && istuple(xs) to test for a
// "real" tuple instead.
bool is_tuple(exprl &xs) const;
+ bool is_tuplex(exprl &xs) const;
};
/* Rules of the form: lhs -> rhs [if qual]. */
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/interpreter.cc 2008-08-10 20:21:23 UTC (rev 461)
@@ -3062,6 +3062,58 @@
return act_builder().CreateLoad(fptrvar);
}
+pure_expr *interpreter::const_value(expr x)
+{
+ switch (x.tag()) {
+ // constants:
+ case EXPR::INT:
+ return pure_int(x.ival());
+ case EXPR::BIGINT:
+ return pure_mpz(x.zval());
+ case EXPR::DBL:
+ return pure_double(x.dval());
+ case EXPR::STR:
+ return pure_string_dup(x.sval());
+ case EXPR::PTR:
+ return pure_pointer(x.pval());
+ default: {
+ exprl xs;
+ if (x.tag() > 0) {
+ env::const_iterator it = globenv.find(x.tag());
+ map<int32_t,GlobalVar>::iterator v;
+ if (externals.find(x.tag()) != externals.end())
+ return 0;
+ else if (it == globenv.end())
+ // unbound symbol
+ return pure_const(x.tag());
+ else if (it->second.t == env_info::fvar &&
+ (v = globalvars.find(x.tag())) != globalvars.end())
+ // variable
+ return v->second.x;
+ else
+ return 0;
+ } else if (x.is_list(xs) || x.is_pair() && x.is_tuplex(xs)) {
+ // proper lists and tuples
+ size_t i, n = xs.size();
+ pure_expr **xv = (pure_expr**)malloc(n*sizeof(pure_expr*));
+ if (!xv) return 0;
+ exprl::iterator it = xs.begin(), end = xs.end();
+ for (i = 0; it != end; i++, it++)
+ if ((xv[i] = const_value(*it)) == 0) {
+ for (size_t j = 0; j < i; j++)
+ pure_freenew(xv[j]);
+ free(xv);
+ return 0;
+ }
+ pure_expr *res = (x.is_pair()?pure_tuplev:pure_listv)(n, xv);
+ free(xv);
+ return res;
+ } else
+ return 0;
+ }
+ }
+}
+
pure_expr *interpreter::doeval(expr x, pure_expr*& e)
{
char test;
@@ -3069,8 +3121,15 @@
e = pure_const(symtab.segfault_sym().f);
return 0;
}
- // Create an anonymous function to call in order to evaluate the target
- // expression.
+ e = 0;
+ // First check whether the value is actually a constant, then we can skip
+ // the compilation step.
+ clock_t t0 = clock();
+ pure_expr *res = const_value(x);
+ if (interactive && stats) clocks = clock()-t0;
+ if (res) return res;
+ // Not a constant value. Create an anonymous function to call in order to
+ // evaluate the target expression.
/* NOTE: The environment is allocated dynamically, so that its child
environments survive for the entire lifetime of any embedded closures,
which might still be called at a later time. */
@@ -3090,9 +3149,8 @@
// JIT the function.
f.fp = JIT->getPointerToFunction(f.f);
assert(f.fp);
- e = 0;
- clock_t t0 = clock();
- pure_expr *res = pure_invoke(f.fp, &e);
+ t0 = clock();
+ res = pure_invoke(f.fp, &e);
if (interactive && stats) clocks = clock()-t0;
// Get rid of our anonymous function.
JIT->freeMachineCodeForFunction(f.f);
@@ -3107,6 +3165,15 @@
return res;
}
+static pure_expr *pure_subterm(pure_expr *x, const path& p)
+{
+ for (size_t i = 0, n = p.len(); i < n; i++) {
+ assert(x->tag == EXPR::APP);
+ x = x->data.x[p[i]?1:0];
+ }
+ return x;
+}
+
pure_expr *interpreter::dodefn(env vars, expr lhs, expr rhs, pure_expr*& e)
{
char test;
@@ -3114,8 +3181,44 @@
e = pure_const(symtab.segfault_sym().f);
return 0;
}
- // Create an anonymous function to call in order to evaluate the rhs
- // expression, match against the lhs and bind variables in lhs accordingly.
+ e = 0;
+ // First check whether the value is actually a constant, then we can skip
+ // the compilation step.
+ clock_t t0 = clock();
+ pure_expr *res = const_value(rhs);
+ if (res) {
+ matcher m(rule(lhs, rhs));
+ if (m.match(rhs)) {
+ // Bind the variables.
+ for (env::const_iterator it = vars.begin(); it != vars.end(); ++it) {
+ int32_t tag = it->first;
+ const env_info& info = it->second;
+ assert(info.t == env_info::lvar && info.p);
+ // find the subterm at info.p
+ pure_expr *x = pure_subterm(res, *info.p);
+ // store the value in a global variable of the same name
+ const symbol& sym = symtab.sym(tag);
+ GlobalVar& v = globalvars[tag];
+ if (!v.v) {
+ v.v = new GlobalVariable
+ (ExprPtrTy, false, GlobalVariable::ExternalLinkage, 0, sym.s,
+ module);
+ JIT->addGlobalMapping(v.v, &v.x);
+ }
+ if (v.x) pure_free(v.x);
+ v.x = pure_new(x);
+ }
+ } else {
+ // Failed match, bail out.
+ pure_freenew(res);
+ res = e = 0;
+ }
+ if (interactive && stats) clocks = clock()-t0;
+ return res;
+ }
+ // Not a constant value. Create an anonymous function to call in order to
+ // evaluate the rhs expression, match against the lhs and bind variables in
+ // lhs accordingly.
Env *save_fptr = fptr;
fptr = new Env(0, 0, rhs, false); fptr->refc = 1;
Env &f = *fptr;
@@ -3176,9 +3279,8 @@
// JIT the function.
f.fp = JIT->getPointerToFunction(f.f);
assert(f.fp);
- e = 0;
- clock_t t0 = clock();
- pure_expr *res = pure_invoke(f.fp, &e);
+ t0 = clock();
+ res = pure_invoke(f.fp, &e);
if (interactive && stats) clocks = clock()-t0;
// Get rid of our anonymous function.
JIT->freeMachineCodeForFunction(f.f);
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/interpreter.hh 2008-08-10 20:21:23 UTC (rev 461)
@@ -485,6 +485,7 @@
Env *find_stacked(int32_t tag);
Env& act_env() { assert(!envstk.empty()); return *envstk.front(); }
Builder& act_builder() { return act_env().builder; }
+ pure_expr *const_value(expr x);
pure_expr *doeval(expr x, pure_expr*& e);
pure_expr *dodefn(env vars, expr lhs, expr rhs, pure_expr*& e);
llvm::Value *codegen(expr x);
Modified: pure/trunk/test/test015.log
===================================================================
--- pure/trunk/test/test015.log 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/test/test015.log 2008-08-10 20:21:23 UTC (rev 461)
@@ -1,9 +1,3 @@
-{
- rule #0: randlist = [52,72,26,78,46,19,44,72,96,75,46,86,13,84,1,94,67,79,14,61,90,77,36,94,88,44,16,42,47,3,60,79,18,52,89,30,94,38,93,91,33,53,70,97,76,75,9,85,17,1,41,29,37,41,13,38,29,2,23,3,22,52,49,88,77,5,11,54,34,45,58,58,6,81,40,58,19,89,17,20,11,15,99,68,81,64,32,73,82,72,65,35,61,41,81,77,27,4,60,51,63,18,27,45,64,74,41,61,61,85,18,30,2,0,95,99,20,60,93,55,54,43,44,30,20,21,4,20,57,91,41,65,35,58,39,3,28,9,44,92,92,60,86,1,68,84,12,5,1,39,86,1,92,88,66,65,7,9,0,52,78,65,54,79,72,25,25,13,48,46,10,50,85,1,82,96,1,92,6,3,19,27,44,64,15,48,64,53,35,39,72,72,30,10,91,74,23,65,36,2,84,4,5,42,47,50,98,60,91,75,71,97,2,26,1,8,15,11,75,93,12,59,12,59,6,25,41,94,35,1,97,76,86,40,86,3,20,42,98,56,57,46,46,76,30,41,9,13,69,18,89,73,30,14,82,44,59,97,50,89,72,26,45,26,96,1,94,90,9,52,8,79,86,9,88,0,20,47,64,93,9,57,50,65,89,73,68,80,24,76,76,54,48,41,7,52,50,75,13,0,76,10,96,8,11,89,74,21,58,24,88,39,5,92,45,87,23,48,57,85,21,92,3,40,5,10,52,57,11,4,50,72,49,34,3,36,91,50,86,92,1,28,23,71,10,77,24,43,59,51,76,72,80,74,50,81,5,57,86,55,82,12,71,0,3,29,67,30,43,27,12,13,10,41,82,26,14,1,22,35,76,42,68,52,32,14,37,74,72,73,17,55,68,87,55,34,53,96,92,75,68,33,36,70,66,39,1,40,66,21,8,61,1,21,20,37,39,29,52,79,39,72,69,63,12,73,16,2,21,17,17,52,31,90,44,7,13,53,64,84,96,34,36,71,4,12,25,96,83,68,68,80,52,58,68,46,75,27,31,6,14,47,23,94,33,26,17,87,86,47,21,77,10,20,23,16,26,80,10,25,87,21,66,62,79,34,63,25,3,80,40,43,75,78,48,71,38,2,41,90,61,83,75,60,86,40,23,58,10,49,84,70,10,69,3,42,73,27,33,31,21,60,57,7,47,16,29,65,99,9,5,2,93,6,71,55,41,98,46,69,68,53,57,54,60,37,89,24,41,57,29,83,26,26,49,6,10,23,61,70,25,80,12,40,80,16,44,69,2,54,50,91,43,86,83,66,87,91,15,9,67,13,89,31,7,58,21,69,30,80,87,74,57,86,84,64,9,62,80,93,44,10,94,85,13,84,68,55,98,34,75,20,42,85,2,25,53,62,77,62,79,11,88,77,85,47,77,28,29,19,29,47,31,40,59,41,86,4,4,76,43,49,53,95,45,96,38,46,3,33,86,94,70,24,19,86,69,16,85,18,6,91,31,19,28,99,24,84,42,45,71,50,30,34,0,82,36,87,27,60,76,21,19,37,65,20,42,43,5,87,66,30,11,92,93,41,21,69,28,29,63,54,58,74,6,95,72,8,96,10,9,44,38,71,93,29,94,17,2,38,94,71,46,33,82,58,89,70,91,89,63,35,6,79,62,45,74,29,62,52,79,69,23,20,57,55,90,98,43,40,1,47,54,4,47,72,23,35,96,7,15,17,67,19,74,8,97,31,70,51,89,91,14,69,82,74,99,83,77,66,66,24,13,58,37,17,99,59,75,99,61,9,8,86,55,56,22,55,81,58,73,29,91,47,15,16,73,82,97,4,7,72,53,92,7,23,92,30,72,99,25,48,12,51,99,85,31,42,59,32,45,46,86,55,63,5,46,21,45,9,72,86,17,76,28,35,96,0,25,26,87,9,89,32,80,72,47,26,48,50,95,63,6,61,43,21,1,43,90,57,35,25,30,89,3,84,5,72,1,15,9,36,55,67,31,51,81,79,84,52,56,40,77,91,66,9,83,39,1,22,72,23,64,0,97,9,6,54,66,18,51,18,99,6,94,59,54,92,8,32,9,24,87,67,67,23,80,56,57,60,53,90,89,57,82,2,45,28,57,21,7,20,76,57,85,80,69,59,31,34,74,83,1,45,31,39,19,69,43,84,6,35,91,52,99,52,86,75,50,21,46,2,0,7,55,50,49,58,13,88,6,91,72,1,89,69,50,83,88,21,54,72,54,82,48,47,2,31,70,39]
- state 0: #0
- <var> state 1
- state 1: #0
-}
let randlist = [52,72,26,78,46,19,44,72,96,75,46,86,13,84,1,94,67,79,14,61,90,77,36,94,88,44,16,42,47,3,60,79,18,52,89,30,94,38,93,91,33,53,70,97,76,75,9,85,17,1,41,29,37,41,13,38,29,2,23,3,22,52,49,88,77,5,11,54,34,45,58,58,6,81,40,58,19,89,17,20,11,15,99,68,81,64,32,73,82,72,65,35,61,41,81,77,27,4,60,51,63,18,27,45,64,74,41,61,61,85,18,30,2,0,95,99,20,60,93,55,54,43,44,30,20,21,4,20,57,91,41,65,35,58,39,3,28,9,44,92,92,60,86,1,68,84,12,5,1,39,86,1,92,88,66,65,7,9,0,52,78,65,54,79,72,25,25,13,48,46,10,50,85,1,82,96,1,92,6,3,19,27,44,64,15,48,64,53,35,39,72,72,30,10,91,74,23,65,36,2,84,4,5,42,47,50,98,60,91,75,71,97,2,26,1,8,15,11,75,93,12,59,12,59,6,25,41,94,35,1,97,76,86,40,86,3,20,42,98,56,57,46,46,76,30,41,9,13,69,18,89,73,30,14,82,44,59,97,50,89,72,26,45,26,96,1,94,90,9,52,8,79,86,9,88,0,20,47,64,93,9,57,50,65,89,73,68,80,24,76,76,54,48,41,7,52,50,75,13,0,76,10,96,8,11,89,74,21,58,24,88,39,5,92,45,87,23,48,57,85,21,92,3,40,5,10,52,57,11,4,50,72,49,34,3,36,91,50,86,92,1,28,23,71,10,77,24,43,59,51,76,72,80,74,50,81,5,57,86,55,82,12,71,0,3,29,67,30,43,27,12,13,10,41,82,26,14,1,22,35,76,42,68,52,32,14,37,74,72,73,17,55,68,87,55,34,53,96,92,75,68,33,36,70,66,39,1,40,66,21,8,61,1,21,20,37,39,29,52,79,39,72,69,63,12,73,16,2,21,17,17,52,31,90,44,7,13,53,64,84,96,34,36,71,4,12,25,96,83,68,68,80,52,58,68,46,75,27,31,6,14,47,23,94,33,26,17,87,86,47,21,77,10,20,23,16,26,80,10,25,87,21,66,62,79,34,63,25,3,80,40,43,75,78,48,71,38,2,41,90,61,83,75,60,86,40,23,58,10,49,84,70,10,69,3,42,73,27,33,31,21,60,57,7,47,16,29,65,99,9,5,2,93,6,71,55,41,98,46,69,68,53,57,54,60,37,89,24,41,57,29,83,26,26,49,6,10,23,61,70,25,80,12,40,80,16,44,69,2,54,50,91,43,86,83,66,87,91,15,9,67,13,89,31,7,58,21,69,30,80,87,74,57,86,84,64,9,62,80,93,44,10,94,85,13,84,68,55,98,34,75,20,42,85,2,25,53,62,77,62,79,11,88,77,85,47,77,28,29,19,29,47,31,40,59,41,86,4,4,76,43,49,53,95,45,96,38,46,3,33,86,94,70,24,19,86,69,16,85,18,6,91,31,19,28,99,24,84,42,45,71,50,30,34,0,82,36,87,27,60,76,21,19,37,65,20,42,43,5,87,66,30,11,92,93,41,21,69,28,29,63,54,58,74,6,95,72,8,96,10,9,44,38,71,93,29,94,17,2,38,94,71,46,33,82,58,89,70,91,89,63,35,6,79,62,45,74,29,62,52,79,69,23,20,57,55,90,98,43,40,1,47,54,4,47,72,23,35,96,7,15,17,67,19,74,8,97,31,70,51,89,91,14,69,82,74,99,83,77,66,66,24,13,58,37,17,99,59,75,99,61,9,8,86,55,56,22,55,81,58,73,29,91,47,15,16,73,82,97,4,7,72,53,92,7,23,92,30,72,99,25,48,12,51,99,85,31,42,59,32,45,46,86,55,63,5,46,21,45,9,72,86,17,76,28,35,96,0,25,26,87,9,89,32,80,72,47,26,48,50,95,63,6,61,43,21,1,43,90,57,35,25,30,89,3,84,5,72,1,15,9,36,55,67,31,51,81,79,84,52,56,40,77,91,66,9,83,39,1,22,72,23,64,0,97,9,6,54,66,18,51,18,99,6,94,59,54,92,8,32,9,24,87,67,67,23,80,56,57,60,53,90,89,57,82,2,45,28,57,21,7,20,76,57,85,80,69,59,31,34,74,83,1,45,31,39,19,69,43,84,6,35,91,52,99,52,86,75,50,21,46,2,0,7,55,50,49,58,13,88,6,91,72,1,89,69,50,83,88,21,54,72,54,82,48,47,2,31,70,39];
{
rule #0: a = set (1..10)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|