[pure-lang-svn] SF.net SVN: pure-lang: [74] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-05-12 06:42:21
|
Revision: 74 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=74&view=rev Author: agraef Date: 2008-05-11 23:42:28 -0700 (Sun, 11 May 2008) Log Message: ----------- Redirect warning and error messages to the logfile. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc pure/trunk/interpreter.hh pure/trunk/lexer.ll Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-12 06:36:42 UTC (rev 73) +++ pure/trunk/ChangeLog 2008-05-12 06:42:28 UTC (rev 74) @@ -1,3 +1,7 @@ +2008-05-12 Albert Graef <Dr....@t-...> + + * Makefile: Redirect warning and error messages to the logfile. + 2008-05-10 Albert Graef <Dr....@t-...> * interpreter.cc (uminop): Handle the value -0x80000000 at the Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-12 06:36:42 UTC (rev 73) +++ pure/trunk/interpreter.cc 2008-05-12 06:42:28 UTC (rev 74) @@ -491,6 +491,38 @@ } } +#if DEBUG>1 +void print_map(ostream& os, const Env *e) +{ + static size_t indent = 0; + string blanks(indent, ' '); + interpreter& interp = *interpreter::g_interp; + os << blanks << ((e->tag>0)?interp.symtab.sym(e->tag).s:"anonymous") + << " (" << (void*)e << ") {\n" << blanks << "XMAP:\n"; + list<VarInfo>::const_iterator xi; + for (xi = e->xtab.begin(); xi != e->xtab.end(); xi++) { + const VarInfo& x = *xi; + assert(x.vtag > 0); + os << blanks << " " << interp.symtab.sym(x.vtag).s << " (#" << x.v << ") " + << (uint32_t)x.idx << ":"; + const path &p = x.p; + for (size_t i = 0; i < p.len(); i++) os << p[i]; + os << endl; + } + for (size_t i = 0, n = e->fmap.size(); i < n; i++) { + os << blanks << "FMAP #" << i << ":\n"; + indent += 2; + map<int32_t,Env>::const_iterator fi; + for (fi = e->fmap[i].begin(); fi != e->fmap[i].end(); fi++) { + const Env& e = fi->second; + print_map(os, &e); + } + indent -= 2; + } + os << blanks << "}\n"; +} +#endif + void interpreter::compile() { using namespace llvm; @@ -506,6 +538,9 @@ if (verbose&verbosity::code) std::cout << *info.m << endl; // regenerate LLVM code (prolog) Env& f = globalfuns[ftag] = Env(ftag, info, false, false); +#if DEBUG>1 + print_map(std::cerr, &f); +#endif push("compile", &f); globalfuns[ftag].f = fun_prolog(symtab.sym(ftag).s); pop(&f); @@ -1527,7 +1562,8 @@ args = e.args; envs = e.envs; argv = e.argv; b = e.b; local = e.local; parent = e.parent; } - fmap = e.fmap; xmap = e.xmap; xtab = e.xtab; prop = e.prop; m = e.m; + fmap = e.fmap; fmap_idx = e.fmap_idx; + xmap = e.xmap; xtab = e.xtab; prop = e.prop; m = e.m; return *this; } @@ -1545,7 +1581,7 @@ interp.JIT->freeMachineCodeForFunction(f); f->dropAllReferences(); if (h != f) h->dropAllReferences(); fp = 0; - fmap.clear(); + fmap.clear(); fmap_idx = 0; to_be_deleted.push_back(f); if (h != f) to_be_deleted.push_back(h); } else { #if DEBUG>2 @@ -1562,7 +1598,8 @@ } fp = 0; // delete all nested environments and reinitialize other body-related data - fmap.clear(); xmap.clear(); xtab.clear(); prop.clear(); m = 0; argv = 0; + fmap.clear(); fmap_idx = 0; + xmap.clear(); xtab.clear(); prop.clear(); m = 0; argv = 0; // now that all references have been removed, delete the function pointers for (list<Function*>::iterator fi = to_be_deleted.begin(); fi != to_be_deleted.end(); fi++) { @@ -1678,36 +1715,6 @@ #endif } -#if DEBUG>1 -void print_map(ostream& os, const Env *e) -{ - static size_t indent = 0; - string blanks(indent, ' '); - interpreter& interp = *interpreter::g_interp; - os << blanks << ((e->tag>0)?interp.symtab.sym(e->tag).s:"anonymous") - << " {\n" << blanks << "XMAP:\n"; - list<VarInfo>::const_iterator xi; - for (xi = e->xtab.begin(); xi != e->xtab.end(); xi++) { - const VarInfo& x = *xi; - assert(x.vtag > 0); - os << blanks << " " << interp.symtab.sym(x.vtag).s << " (#" << x.v << ") " - << (uint32_t)x.idx << ":"; - const path &p = x.p; - for (size_t i = 0; i < p.len(); i++) os << p[i]; - os << endl; - } - os << blanks << "FMAP:\n"; - indent += 2; - map<int32_t,Env>::const_iterator fi; - for (fi = e->fmap.begin(); fi != e->fmap.end(); fi++) { - const Env& e = fi->second; - print_map(os, &e); - } - indent -= 2; - os << blanks << "}\n"; -} -#endif - void Env::build_map(expr x) { // build the maps for a (rhs) expression @@ -1727,8 +1734,8 @@ assert(ei != envstk.end()); fenv = *ei++; } - assert(fenv->fmap.find(x.vtag()) != fenv->fmap.end()); - fenv = &fenv->fmap[x.vtag()]; + assert(fenv->act_fmap().find(x.vtag()) != fenv->act_fmap().end()); + fenv = &fenv->act_fmap()[x.vtag()]; if (!fenv->local) break; // fenv now points to the environment of the (local) function assert(fenv != this && fenv->tag == x.vtag()); @@ -1788,7 +1795,7 @@ if (n == 2 && f.tag() == interp.symtab.catch_sym().f) { expr h = x.xval1().xval2(), y = x.xval2(); push("catch"); - Env& e = fmap[-x.hash()] = Env(0, 0, y, true, true); + Env& e = act_fmap()[-x.hash()] = Env(0, 0, y, true, true); e.build_map(y); e.promote_map(); pop(); build_map(h); @@ -1805,14 +1812,14 @@ break; case EXPR::LAMBDA: { push("lambda"); - Env& e = fmap[-x.hash()] = Env(0, 1, x.xval2(), true, true); + Env& e = act_fmap()[-x.hash()] = Env(0, 1, x.xval2(), true, true); e.build_map(x.xval2()); e.promote_map(); pop(); break; } case EXPR::CASE: { push("case"); - Env& e = fmap[-x.hash()] = Env(0, 1, x.xval(), true, true); + Env& e = act_fmap()[-x.hash()] = Env(0, 1, x.xval(), true, true); e.build_map(*x.rules()); e.promote_map(); pop(); build_map(x.xval()); @@ -1829,13 +1836,13 @@ for (env::const_iterator p = fe->begin(); p != fe->end(); p++) { int32_t ftag = p->first; const env_info& info = p->second; - fmap[ftag] = Env(ftag, info, false, true); + act_fmap()[ftag] = Env(ftag, info, false, true); } // Now recursively build the maps for the child environments. for (env::const_iterator p = fe->begin(); p != fe->end(); p++) { int32_t ftag = p->first; const env_info& info = p->second; - Env& e = fmap[ftag]; + Env& e = act_fmap()[ftag]; e.build_map(info); e.promote_map(); } pop(); @@ -1859,7 +1866,7 @@ rulel::const_iterator s = r; expr y = (++s == end)?x:s->rhs; push("when"); - Env& e = fmap[-y.hash()] = Env(0, 1, y, true, true); + Env& e = act_fmap()[-y.hash()] = Env(0, 1, y, true, true); e.build_map(x, s, end); e.promote_map(); pop(); build_map(r->rhs); @@ -1879,12 +1886,16 @@ { // build the maps for a global function definition assert(info.t == env_info::fun); + // we need a separate submap for each rule + size_t n = info.rules->size(); + fmap.resize(n); rulel::const_iterator r = info.rules->begin(); while (r != info.rules->end()) { build_map(r->rhs); if (!r->qual.is_null()) build_map(r->qual); - r++; + r++; fmap_idx++; } + fmap_idx = 0; #if DEBUG>1 if (!local) print_map(std::cerr, this); #endif @@ -2652,8 +2663,8 @@ Env& act = act_env(); rulel::const_iterator s = r; expr y = (++s == end)?x:s->rhs; - assert(act.fmap.find(-y.hash()) != act.fmap.end()); - Env& e = act.fmap[-y.hash()]; + assert(act.act_fmap().find(-y.hash()) != act.act_fmap().end()); + Env& e = act.act_fmap()[-y.hash()]; push("when", &e); fun_prolog("anonymous"); BasicBlock *bodybb = new BasicBlock("body"); @@ -3069,7 +3080,7 @@ int offs = idx-1; if (idx == 0) { // function in current environment ('with'-bound) - f = &act_env().fmap[tag]; + f = &act_env().act_fmap()[tag]; } else { // function in an outer environment, the de Bruijn index idx tells us // where on the current environment stack it's at @@ -3077,7 +3088,7 @@ size_t i = idx; for (; i > 0; e++, i--) assert(e != envstk.end()); // look up the function in the environment - f = &(*e)->fmap[tag]; + f = &(*e)->act_fmap()[tag]; } if (f->n == n) { // bingo! saturated call @@ -3158,8 +3169,8 @@ // through pure_catch() expr h = x.xval1().xval2(), y = x.xval2(); Env& act = act_env(); - assert(act.fmap.find(-x.hash()) != act.fmap.end()); - Env& e = act.fmap[-x.hash()]; + assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end()); + Env& e = act.act_fmap()[-x.hash()]; push("catch", &e); fun_prolog("anonymous"); e.CreateRet(codegen(y)); @@ -3184,8 +3195,8 @@ // anonymous closure: case EXPR::LAMBDA: { Env& act = act_env(); - assert(act.fmap.find(-x.hash()) != act.fmap.end()); - Env& e = act.fmap[-x.hash()]; + assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end()); + Env& e = act.act_fmap()[-x.hash()]; push("lambda", &e); fun("anonymous", x.pm(), true); pop(&e); @@ -3196,8 +3207,8 @@ // case expression: treated like an anonymous closure (see the lambda case // above) which gets applied to the subject term to be matched Env& act = act_env(); - assert(act.fmap.find(-x.hash()) != act.fmap.end()); - Env& e = act.fmap[-x.hash()]; + assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end()); + Env& e = act.act_fmap()[-x.hash()]; push("case", &e); fun("anonymous", x.pm(), true); pop(&e); @@ -3223,16 +3234,16 @@ // mutually recursive definitions for (p = fe->begin(); p != fe->end(); p++) { int32_t ftag = p->first; - assert(act.fmap.find(ftag) != act.fmap.end()); - Env& e = act.fmap[ftag]; + assert(act.act_fmap().find(ftag) != act.act_fmap().end()); + Env& e = act.act_fmap()[ftag]; push("with", &e); - act.fmap[ftag].f = fun_prolog(symtab.sym(ftag).s); + act.act_fmap()[ftag].f = fun_prolog(symtab.sym(ftag).s); pop(&e); } for (p = fe->begin(); p != fe->end(); p++) { int32_t ftag = p->first; const env_info& info = p->second; - Env& e = act.fmap[ftag]; + Env& e = act.act_fmap()[ftag]; push("with", &e); fun_body(info.m); pop(&e); @@ -3498,7 +3509,7 @@ assert(!envstk.empty()); if (idx == 0) { // function in current environment ('with'-bound) - Env& f = act_env().fmap[tag]; + Env& f = act_env().act_fmap()[tag]; return fbox(f, thunked); } // If we come here, the function is defined in an outer environment. Locate @@ -3508,7 +3519,7 @@ size_t i = idx; for (; i > 0; e++, i--) assert(e != envstk.end()); // look up the function in the environment - Env& f = (*e)->fmap[tag]; + Env& f = (*e)->act_fmap()[tag]; assert(f.f); // Now create the closure. This is essentially just like fbox(), but we are // called inside a nested environment here, and hence the de Bruijn indices @@ -4469,14 +4480,17 @@ Env& f = act_env(); assert(s->tr.empty()); // we're in a final state here const rulev& rules = pm->r; + assert(f.fmap.size() == 1 || f.fmap.size() == rules.size()); const ruleml& rl = s->r; ruleml::const_iterator r = rl.begin(); assert(r != rl.end()); + assert(f.fmap_idx == 0); BasicBlock* rulebb = new BasicBlock(mklabel("rule.state", s->s, rl.front())); f.builder.CreateBr(rulebb); while (r != rl.end()) { const rule& rr = rules[*r]; reduced.insert(*r); + if (f.fmap.size() > 1) f.fmap_idx = *r; f.f->getBasicBlockList().push_back(rulebb); f.builder.SetInsertPoint(rulebb); #if DEBUG>1 @@ -4534,4 +4548,5 @@ f.CreateRet(codegen(rr.rhs)); rulebb = nextbb; } + if (f.fmap.size() > 1) f.fmap_idx = 0; } Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-05-12 06:36:42 UTC (rev 73) +++ pure/trunk/interpreter.hh 2008-05-12 06:42:28 UTC (rev 74) @@ -111,8 +111,14 @@ map<xmap_key,uint32_t > xmap; // info about captured variables list<VarInfo> xtab; - // local function environments - map<int32_t,Env> fmap; + // local function environments; note that there's actually a separate child + // environment for each rule of the parent function (this gets initialized + // to a single empty environment) + vector< map<int32_t,Env> > fmap; + // the current fmap index; this gets updated each time a new rule is added + size_t fmap_idx; + // convenience function to access the current fmap + map<int32_t,Env>& act_fmap() { return fmap[fmap_idx]; } // propagation links for environment variables (pointers to call sites) // e in prop means that there's a call with de Bruijn index prop[e] at e map<Env*,uint8_t> prop; @@ -161,11 +167,11 @@ // default constructor Env() : tag(0), n(0), m(0), l(0), f(0), h(0), fp(0), args(0), envs(0), argv(0), - b(false), local(false), parent(0), refc(0) {} + fmap(1), fmap_idx(0), b(false), local(false), parent(0), refc(0) {} // environment for an anonymous closure with given body x Env(int32_t _tag, uint32_t _n, expr x, bool _b, bool _local = false) : tag(_tag), n(_n), m(0), l(0), f(0), h(0), fp(0), args(n), envs(0), - argv(0), b(_b), local(_local), parent(0), refc(0) + argv(0), fmap(1), fmap_idx(0), b(_b), local(_local), parent(0), refc(0) { if (envstk.empty()) { assert(!local); @@ -179,7 +185,7 @@ // environment for a named closure with given definition info Env(int32_t _tag, const env_info& info, bool _b, bool _local = false) : tag(_tag), n(info.argc), m(0), l(0), f(0), h(0), fp(0), args(n), envs(0), - argv(0), b(_b), local(_local), parent(0), refc(0) + argv(0), fmap(1), fmap_idx(0), b(_b), local(_local), parent(0), refc(0) { if (envstk.empty()) { assert(!local); Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-05-12 06:36:42 UTC (rev 73) +++ pure/trunk/lexer.ll 2008-05-12 06:42:28 UTC (rev 74) @@ -764,9 +764,12 @@ void interpreter::print_defs(ostream& os, const Env& e) { + if (!e.f) return; // not used, probably a shadowed rule if (e.h && e.h != e.f) e.h->print(os); e.f->print(os); - map<int32_t,Env>::const_iterator f; - for (f = e.fmap.begin(); f != e.fmap.end(); f++) - print_defs(os, f->second); + for (size_t i = 0, n = e.fmap.size(); i < n; i++) { + map<int32_t,Env>::const_iterator f; + for (f = e.fmap[i].begin(); f != e.fmap[i].end(); f++) + print_defs(os, f->second); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |