From: helly Date: Sun, 14 May 2006 13:38:26 +0000 (+0000) Subject: - Add threshold control for -g style code generation X-Git-Tag: 0.13.6~345 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3fe8a2674e2832cdeb6c4e85865905c8fabb3fbb;p=re2c - Add threshold control for -g style code generation --- diff --git a/code.cc b/code.cc index 376d298d..ee8bd0c5 100644 --- a/code.cc +++ b/code.cc @@ -539,7 +539,7 @@ void Accept::emit(std::ostream &o, uint ind, bool &readCh) const { bUsedYYAccept = true; - if (gFlag) + if (gFlag && mapRules.size() >= cGotoThreshold) { o << indent(ind++) << "{\n"; o << indent(ind++) << "static void *yytarget[" << mapRules.size() << "] = {\n"; @@ -891,77 +891,102 @@ void Go::genBase(std::ostream &o, uint ind, const State *from, const State *next } } -void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) +void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) const { - if (gFlag || wFlag) + const char * sYych = readCh ? "(yych = *YYCURSOR)" : "yych"; + + readCh = false; + if (wFlag) + { + o << indent(ind) << "if(" << sYych <<" & 0xFF00) {\n"; + genBase(o, ind+1, from, next, readCh, 1); + o << indent(ind++) << "} else {\n"; + sYych = "yych"; + } + else { - if (wSpans == ~0u) + o << indent(ind++) << "{\n"; + } + o << indent(ind++) << "static void *yytarget[256] = {\n"; + o << indent(ind); + + uint ch = 0; + for (uint i = 0; i < lSpans; ++i) + { + vUsedLabels.insert(span[i].to->label); + for(; ch < span[i].ub; ++ch) { - wSpans = 0; - lSpans = 1; - for (uint p = 0; p < nSpans; p++) + o << "&&yy" << span[i].to->label; + if (ch == 255) { - if (span[p].ub > 0xFF) - { - wSpans++; - } - if (span[p].ub < 0x100) - { - lSpans++; - } + o << "\n"; + i = lSpans; + break; + } + else if (ch % 8 == 7) + { + o << ",\n" << indent(ind); + } + else + { + o << "," << space(span[i].to->label); } - } - else - { - lSpans = nSpans; } } + o << indent(--ind) << "};\n"; + o << indent(ind) << "goto *yytarget[" << sYych << "];\n"; + o << indent(--ind) << "}\n"; +} - if (gFlag && lSpans >= 16) +void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) +{ + if ((gFlag || wFlag) && wSpans == ~0u) { - const char * sYych = readCh ? "(yych = *YYCURSOR)" : "yych"; - - readCh = false; - if (wFlag) - { - o << indent(ind) << "if(" << sYych <<" & 0xFF00) {\n"; - genBase(o, ind+1, from, next, readCh, 1); - o << indent(ind++) << "} else {\n"; - sYych = "yych"; - } - else - { - o << indent(ind++) << "{\n"; - } - o << indent(ind++) << "static void *yytarget[256] = {\n"; - o << indent(ind); - - uint ch = 0; - for (uint i = 0; i < lSpans; ++i) + uint nBitmaps = 0; + std::set vTargets; + wSpans = 0; + lSpans = 1; + dSpans = 0; + for (uint i = 0; i < nSpans; ++i) { - vUsedLabels.insert(span[i].to->label); - for(; ch < span[i].ub; ++ch) + if (span[i].ub > 0xFF) { - o << "&&yy" << span[i].to->label; - if (ch == 255) - { - o << "\n"; - i = lSpans; - break; - } - else if (ch % 8 == 7) + wSpans++; + } + if (span[i].ub < 0x100 || !wFlag) + { + lSpans++; + + State *to = span[i].to; + + if (to && to->isBase) { - o << ",\n" << indent(ind); + const BitMap *b = BitMap::find(to); + const char * sYych; + + if (b && matches(b->go, b->on, this, to)) + { + nBitmaps++; + } + else + { + dSpans++; + vTargets.insert(to->label); + } } else { - o << "," << space(span[i].to->label); + dSpans++; + vTargets.insert(to->label); } } } - o << indent(--ind) << "};\n"; - o << indent(ind) << "goto *yytarget[" << sYych << "];\n"; - o << indent(--ind) << "}\n"; + lTargets = vTargets.size() >> nBitmaps; + } + + if (gFlag && (lTargets >= cGotoThreshold || dSpans >= cGotoThreshold)) + { + genCpGoto(o, ind, from, next, readCh); return; } else if (bFlag) @@ -1649,6 +1674,10 @@ void Scanner::config(const Str& cfg, int num) { bUseYYFill = num != 0; } + else if (cfg.to_string() == "cgoto:threshold") + { + cGotoThreshold = num; + } else { fatal("unrecognized configuration name or illegal integer value"); diff --git a/dfa.h b/dfa.h index 626f3e2a..42563f30 100644 --- a/dfa.h +++ b/dfa.h @@ -175,14 +175,18 @@ public: : nSpans(0) , wSpans(~0u) , lSpans(~0u) + , dSpans(~0u) + , lTargets(~0u) , span(NULL) { } public: - uint nSpans; - uint wSpans; - uint lSpans; + uint nSpans; // number of spans + uint wSpans; // number of spans in wide mode + uint lSpans; // number of low (non wide) spans + uint dSpans; // number of decision spans (decide between g and b mode) + uint lTargets; Span *span; public: @@ -191,6 +195,7 @@ public: void genLinear(std::ostream&, uint ind, const State *from, const State *next, bool &readCh, uint mask) const; void genBinary(std::ostream&, uint ind, const State *from, const State *next, bool &readCh, uint mask) const; void genSwitch(std::ostream&, uint ind, const State *from, const State *next, bool &readCh, uint mask) const; + void genCpGoto(std::ostream&, uint ind, const State *from, const State *next, bool &readCh) const; void compact(); void unmap(Go*, const State*); }; diff --git a/globals.h b/globals.h index 610d4097..b8645c42 100644 --- a/globals.h +++ b/globals.h @@ -34,6 +34,7 @@ extern bool bUseStartLabel; extern std::string startLabelName; extern uint maxFill; extern uint next_label; +extern uint cGotoThreshold; /* configurations */ extern uint topIndent; diff --git a/main.cc b/main.cc index 4106015f..9435c029 100644 --- a/main.cc +++ b/main.cc @@ -44,6 +44,7 @@ bool bUseYYFill = true; std::string startLabelName; uint maxFill = 1; uint next_label = 0; +uint cGotoThreshold = 9; uint topIndent = 0; std::string indString("\t"); @@ -83,7 +84,7 @@ static const mbo_opt_struct OPTIONS[] = static void usage() { - cerr << "usage: re2c [-bdefhisvVw1] [-o file] file\n" + cerr << "usage: re2c [-bdefghisvVw1] [-o file] file\n" "\n" "-? -h --help Display this info.\n" "\n" @@ -101,7 +102,7 @@ static void usage() "\n" "-f --storable-state Generate a scanner that supports storable states.\n" "\n" - "-g --computed-gotos Implies -b. Generate computed goto code (only useable \n" + "-g --computed-gotos Implies -b. Generate computed goto code (only useable\n" " with gcc).\n" "\n" "-i --no-debug-info Do not generate '#line' info (usefull for versioning).\n" @@ -118,8 +119,9 @@ static void usage() "-w --wide-chars Create a parser that supports wide chars (UCS-2). This\n" " implies -s and cannot be used together with -e switch.\n" "\n" - "-1 --single-pass Force two pass generation, allows YYMAXFILL generation\n" - " prior to last re2c block.\n" + "-1 --single-pass Force single pass generation, this cannot be combined\n" + " with -f and disables YYMAXFILL generation prior to last\n" + " re2c block.\n" ; }