From: Ulya Trofimovich Date: Mon, 19 Dec 2016 00:06:19 +0000 (+0000) Subject: Removed variable from global scope, simplified bitmaps. X-Git-Tag: 1.0~39^2~187 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b014f14788e61226d6e2e31b06c33ab6ed2b1b96;p=re2c Removed variable from global scope, simplified bitmaps. --- diff --git a/re2c/src/codegen/bitmap.cc b/re2c/src/codegen/bitmap.cc index 16a0668b..64521675 100644 --- a/re2c/src/codegen/bitmap.cc +++ b/re2c/src/codegen/bitmap.cc @@ -9,50 +9,83 @@ namespace re2c { -BitMap *BitMap::first = NULL; - -BitMap::BitMap(const Go *g, const State *x) - : go(g) - , on(x) - , next(first) - , i(0) - , m(0) +static bool matches(const Go *go1, const State *s1, const Go *go2, const State *s2); +static void doGen(const Go *g, const State *s, uint32_t *bm, uint32_t f, uint32_t m); + +bitmaps_t::bitmaps_t(uint32_t n) + : maps() + , ncunit(n) + , buffer(new uint32_t[ncunit]) + , used(false) +{} + +bitmaps_t::~bitmaps_t() { - first = this; + delete[] buffer; } -BitMap::~BitMap() +void bitmaps_t::insert(const Go *go, const State *s) { - delete next; + for (rciter_t i = maps.rbegin(); i != maps.rend(); ++i) { + if (matches(i->go, i->on, go, s)) return; + } + + bitmap_t b = {go, s, 0, 0}; + maps.push_back(b); } -const BitMap *BitMap::find(const Go *g, const State *x) +const bitmap_t *bitmaps_t::find(const Go *go, const State *s) const { - for (const BitMap *b = first; b; b = b->next) - { - if (matches(b->go->span, b->go->nSpans, b->on, g->span, g->nSpans, x)) - { - return b; - } + for (rciter_t i = maps.rbegin(); i != maps.rend(); ++i) { + if (i->on == s && matches(i->go, i->on, go, s)) return &(*i); } - - return new BitMap(g, x); + return NULL; } -const BitMap *BitMap::find(const State *x) +bool bitmaps_t::empty() const { return maps.empty(); } + +void bitmaps_t::gen(OutputFile &o, uint32_t ind) { - for (const BitMap *b = first; b; b = b->next) - { - if (b->on == x) - { - return b; + if (empty() || !used) return; + + Opt &opts = o.opts; + const uint32_t nmap = static_cast(maps.size()); + riter_t b = maps.rbegin(), e = maps.rend(); + + o.wind(ind).ws("static const unsigned char ") + .wstring(opts->yybm).ws("[] = {"); + + for (uint32_t i = 0, t = 1; b != e; i += ncunit, t += 8) { + memset(buffer, 0, ncunit * sizeof(uint32_t)); + + for (uint32_t m = 0x80; b != e && m; m >>= 1, ++b) { + b->i = i; + b->m = m; + doGen(b->go, b->on, buffer, 0, m); + } + + if (nmap > 8) { + o.ws("\n").wind(ind + 1).ws("/* table ").wu32(t).ws(" .. ") + .wu32(std::min(nmap, t + 7)).ws(": ").wu32(i).ws(" */"); + } + + for (uint32_t c = 0; c < ncunit; ++c) { + if (c % 8 == 0) { + o.ws("\n").wind(ind + 1); + } + if (opts->yybmHexTable) { + o.wu32_hex(buffer[c]); + } else { + o.wu32_width(buffer[c], 3); + } + o.ws(", "); } } - return NULL; + o.ws("\n").wind(ind).ws("};\n"); } -static void doGen(const Go *g, const State *s, uint32_t *bm, uint32_t f, uint32_t m) +void doGen(const Go *g, const State *s, uint32_t *bm, uint32_t f, uint32_t m) { Span *b = g->span, *e = &b[g->nSpans]; uint32_t lb = 0; @@ -71,72 +104,13 @@ static void doGen(const Go *g, const State *s, uint32_t *bm, uint32_t f, uint32_ } } -void BitMap::gen(OutputFile & o, uint32_t ind, uint32_t lb, uint32_t ub) -{ - Opt &opts = o.opts; - if (first && bUsedYYBitmap) - { - o.wind(ind).ws("static const unsigned char ").wstring(opts->yybm).ws("[] = {"); - - uint32_t c = 1, n = ub - lb; - const BitMap *cb = first; - - while((cb = cb->next) != NULL) { - ++c; - } - BitMap *b = first; - - uint32_t *bm = new uint32_t[n]; - - for (uint32_t i = 0, t = 1; b; i += n, t += 8) - { - memset(bm, 0, n * sizeof(uint32_t)); - - for (uint32_t m = 0x80; b && m; m >>= 1) - { - b->i = i; - b->m = m; - doGen(b->go, b->on, bm, lb, m); - b = const_cast(b->next); - } - - if (c > 8) - { - o.ws("\n").wind(ind+1).ws("/* table ").wu32(t).ws(" .. ").wu32(std::min(c, t+7)).ws(": ").wu32(i).ws(" */"); - } - - for (uint32_t j = 0; j < n; ++j) - { - if (j % 8 == 0) - { - o.ws("\n").wind(ind+1); - } - - if (opts->yybmHexTable) - { - o.wu32_hex(bm[j]); - } - else - { - o.wu32_width(bm[j], 3); - } - o.ws(", "); - } - } - - o.ws("\n").wind(ind).ws("};\n"); - - delete[] bm; - } -} - // All spans in b1 that lead to s1 are pairwise equal to that in b2 leading to s2 -bool matches(const Span * b1, uint32_t n1, const State * s1, const Span * b2, uint32_t n2, const State * s2) +bool matches(const Go *go1, const State *s1, const Go *go2, const State *s2) { - const Span * e1 = &b1[n1]; - uint32_t lb1 = 0; - const Span * e2 = &b2[n2]; - uint32_t lb2 = 0; + const Span + *b1 = go1->span, *e1 = &b1[go1->nSpans], + *b2 = go2->span, *e2 = &b2[go2->nSpans]; + uint32_t lb1 = 0, lb2 = 0; for (;;) { diff --git a/re2c/src/codegen/bitmap.h b/re2c/src/codegen/bitmap.h index 3c0cc1be..a2f75abf 100644 --- a/re2c/src/codegen/bitmap.h +++ b/re2c/src/codegen/bitmap.h @@ -2,44 +2,47 @@ #define _RE2C_CODEGEN_BITMAP_ #include "src/util/c99_stdint.h" +#include #include "src/util/forbid_copy.h" -namespace re2c -{ +namespace re2c { struct Go; struct Span; class State; class OutputFile; -class BitMap +struct bitmap_t { -public: - static BitMap *first; + const Go *go; + const State *on; + uint32_t i; + uint32_t m; +}; + +class bitmaps_t +{ + typedef std::vector maps_t; + typedef maps_t::reverse_iterator riter_t; + typedef maps_t::const_reverse_iterator rciter_t; - const Go *go; - const State *on; - const BitMap *next; - uint32_t i; - uint32_t m; + maps_t maps; + uint32_t ncunit; + uint32_t *buffer; public: - static const BitMap *find(const Go*, const State*); - static const BitMap *find(const State*); - static void gen(OutputFile &, uint32_t ind, uint32_t, uint32_t); - BitMap(const Go*, const State*); - ~BitMap(); - - FORBID_COPY (BitMap); + bool used; + + explicit bitmaps_t(uint32_t n); + ~bitmaps_t(); + void insert(const Go *go, const State *s); + const bitmap_t *find(const Go *go, const State *s) const; + bool empty() const; + void gen(OutputFile &o, uint32_t ind); + FORBID_COPY(bitmaps_t); }; -bool matches(const Span * b1, uint32_t n1, const State * s1, const Span * b2, uint32_t n2, const State * s2); - -#ifdef _MSC_VER -# pragma warning(disable: 4355) /* 'this' : used in base member initializer list */ -#endif - -} // end namespace re2c +} // namespace re2c #endif // _RE2C_CODEGEN_BITMAP_ diff --git a/re2c/src/codegen/emit_dfa.cc b/re2c/src/codegen/emit_dfa.cc index 8350a7ae..8cef48e1 100644 --- a/re2c/src/codegen/emit_dfa.cc +++ b/re2c/src/codegen/emit_dfa.cc @@ -187,7 +187,7 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra if (output.skeletons.insert (name).second) { emit_start(o, max_fill, name, key_size, def_rule, need_backup, - need_accept, oldstyle_ctxmarker, tagnames, tagvars); + need_accept, oldstyle_ctxmarker, tagnames, tagvars, bitmaps); uint32_t i = 2; emit_body (o, i, used_labels, initial_label); emit_end(o, name, need_backup, oldstyle_ctxmarker); @@ -201,7 +201,7 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra o.ws("\n").wdelay_line_info (); if ((!opts->fFlag && ob.used_yyaccept) || (!opts->fFlag && opts->bEmitYYCh) - || (opts->bFlag && !opts->cFlag && BitMap::first) + || (opts->bFlag && !opts->cFlag && !bitmaps.empty()) || (opts->cFlag && !bWroteCondCheck && opts->gFlag) || (opts->fFlag && !bWroteGetState && opts->gFlag) ) @@ -226,9 +226,9 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra o.ws("\n"); } } - if (opts->bFlag && !opts->cFlag && BitMap::first) + if (opts->bFlag && !opts->cFlag) { - BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256); + bitmaps.gen(o, ind); } if (bProlog) { @@ -260,14 +260,14 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra } o.wstring(opts->condPrefix).wstring(cond).ws(":\n"); } - if (opts->cFlag && opts->bFlag && BitMap::first) + if (opts->cFlag && opts->bFlag && !bitmaps.empty()) { o.wind(ind++).ws("{\n"); - BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256); + bitmaps.gen(o, ind); } // Generate code emit_body (o, ind, used_labels, initial_label); - if (opts->cFlag && opts->bFlag && BitMap::first) + if (opts->cFlag && opts->bFlag && !bitmaps.empty()) { o.wind(--ind).ws("}\n"); } @@ -277,13 +277,6 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra o.wind(--ind).ws("}\n"); } } - - // Cleanup - if (BitMap::first) - { - delete BitMap::first; - BitMap::first = NULL; - } } void genCondTable(OutputFile & o, uint32_t ind, const std::vector & condnames) diff --git a/re2c/src/codegen/go.h b/re2c/src/codegen/go.h index b0d5fbec..fa99ce26 100644 --- a/re2c/src/codegen/go.h +++ b/re2c/src/codegen/go.h @@ -14,7 +14,8 @@ namespace re2c { struct DFA; -class BitMap; +class bitmap_t; +class bitmaps_t; class State; struct If; @@ -137,12 +138,12 @@ struct SwitchIf struct GoBitmap { - const BitMap * bitmap; + const bitmap_t * bitmap; const State * bitmap_state; SwitchIf * hgo; SwitchIf * lgo; GoBitmap (const Span * span, uint32_t nSpans, const Span * hspan, - uint32_t hSpans, const BitMap * bm, const State * bm_state, + uint32_t hSpans, const bitmap_t * bm, const State * bm_state, const State * next, bool sflag); ~GoBitmap (); void emit (OutputFile & o, uint32_t ind, const DFA &dfa); @@ -213,7 +214,7 @@ struct Go Go (); ~Go (); - void init (const State * from, Opt &opts); + void init(const State* from, Opt &opts, bitmaps_t &bitmaps); void emit (OutputFile & o, uint32_t ind, const DFA &dfa); void used_labels (std::set & used); diff --git a/re2c/src/codegen/go_construct.cc b/re2c/src/codegen/go_construct.cc index 47fd4a76..2c056cbc 100644 --- a/re2c/src/codegen/go_construct.cc +++ b/re2c/src/codegen/go_construct.cc @@ -139,7 +139,7 @@ SwitchIf::SwitchIf (const Span * sp, uint32_t nsp, const State * next, bool sfla } GoBitmap::GoBitmap (const Span * span, uint32_t nSpans, const Span * hspan, - uint32_t hSpans, const BitMap * bm, const State * bm_state, + uint32_t hSpans, const bitmap_t * bm, const State * bm_state, const State * next, bool sflag) : bitmap (bm) , bitmap_state (bm_state) @@ -193,7 +193,7 @@ Go::Go () , info () {} -void Go::init (const State * from, Opt &opts) +void Go::init (const State * from, Opt &opts, bitmaps_t &bitmaps) { if (nSpans == 0) { @@ -223,22 +223,20 @@ void Go::init (const State * from, Opt &opts) // initialize bitmaps uint32_t nBitmaps = 0; - const BitMap * bitmap = NULL; - const State * bitmap_state = NULL; - for (uint32_t i = 0; i < nSpans; ++i) - { - if (span[i].to->isBase) - { - const BitMap *b = BitMap::find (span[i].to); - if (b && matches(b->go->span, b->go->nSpans, b->on, span, nSpans, span[i].to)) - { - if (bitmap == NULL) - { - bitmap = b; - bitmap_state = span[i].to; - } - nBitmaps++; + const bitmap_t *bm = NULL; + const State *bms = NULL; + + for (uint32_t i = 0; i < nSpans; ++i) { + const State *s = span[i].to; + if (!s->isBase) continue; + + const bitmap_t *b = bitmaps.find(this, s); + if (b) { + if (bm == NULL) { + bm = b; + bms = s; } + ++nBitmaps; } } @@ -256,8 +254,8 @@ void Go::init (const State * from, Opt &opts) else if (opts->bFlag && (nBitmaps > 0)) { type = BITMAP; - info.bitmap = new GoBitmap (span, nSpans, hspan, hSpans, bitmap, bitmap_state, from->next, opts->sFlag); - bUsedYYBitmap = true; + info.bitmap = new GoBitmap (span, nSpans, hspan, hSpans, bm, bms, from->next, opts->sFlag); + bitmaps.used = true; } else { diff --git a/re2c/src/globals.h b/re2c/src/globals.h index d1bfc51d..4d158ea7 100644 --- a/re2c/src/globals.h +++ b/re2c/src/globals.h @@ -4,7 +4,6 @@ namespace re2c { -extern bool bUsedYYBitmap; extern bool bWroteGetState; extern bool bWroteCondCheck; diff --git a/re2c/src/ir/adfa/adfa.cc b/re2c/src/ir/adfa/adfa.cc index af7d4878..0056fdc5 100644 --- a/re2c/src/ir/adfa/adfa.cc +++ b/re2c/src/ir/adfa/adfa.cc @@ -45,6 +45,7 @@ DFA::DFA , maxtagver (dfa.maxtagver) , def_rule (def) , key_size (key) + , bitmaps (std::min(ubChar, 256u)) { const size_t nstates = dfa.states.size(); const size_t nchars = dfa.nchars; diff --git a/re2c/src/ir/adfa/adfa.h b/re2c/src/ir/adfa/adfa.h index 1bc1f3d8..d5936bd5 100644 --- a/re2c/src/ir/adfa/adfa.h +++ b/re2c/src/ir/adfa/adfa.h @@ -7,6 +7,7 @@ #include #include +#include "src/codegen/bitmap.h" #include "src/codegen/go.h" #include "src/codegen/label.h" #include "src/ir/adfa/action.h" @@ -78,6 +79,7 @@ struct DFA tagver_t maxtagver; const size_t def_rule; const size_t key_size; + bitmaps_t bitmaps; DFA ( const dfa_t &dfa , const std::vector &fill diff --git a/re2c/src/ir/adfa/prepare.cc b/re2c/src/ir/adfa/prepare.cc index 0de6dd97..346e78c4 100644 --- a/re2c/src/ir/adfa/prepare.cc +++ b/re2c/src/ir/adfa/prepare.cc @@ -102,8 +102,6 @@ void DFA::findBaseState() void DFA::prepare (Opt &opts) { - bUsedYYBitmap = false; - // create rule states std::vector rule2state(rules.size()); for (State *s = head; s; s = s->next) { @@ -170,9 +168,8 @@ void DFA::prepare (Opt &opts) s->isBase = true; split(s); - if (opts->bFlag) - { - BitMap::find(&s->next->go, s); + if (opts->bFlag) { + bitmaps.insert(&s->next->go, s); } s = s->next; @@ -184,9 +181,8 @@ void DFA::prepare (Opt &opts) // find ``base'' state, if possible findBaseState(); - for (State * s = head; s; s = s->next) - { - s->go.init (s, opts); + for (State *s = head; s; s = s->next) { + s->go.init(s, opts, bitmaps); } } diff --git a/re2c/src/ir/skeleton/generate_code.cc b/re2c/src/ir/skeleton/generate_code.cc index 406b4535..d306c2c6 100644 --- a/re2c/src/ir/skeleton/generate_code.cc +++ b/re2c/src/ir/skeleton/generate_code.cc @@ -94,7 +94,8 @@ void emit_prolog(OutputFile &o) void emit_start(OutputFile &o, size_t maxfill, const std::string &name, size_t sizeof_key, size_t def, bool backup, bool accept, bool oldstyle_ctxmarker, - const std::set &tagnames, const std::set &tagvars) + const std::set &tagnames, const std::set &tagvars, + bitmaps_t &bitmaps) { Opt &opts = o.opts; const size_t sizeof_cunit = opts->encoding.szCodeUnit(); @@ -284,8 +285,8 @@ void emit_start(OutputFile &o, size_t maxfill, const std::string &name, } o.ws("\n"); - if (opts->bFlag && BitMap::first) { - BitMap::gen(o, 2, 0, std::min(0x100u, opts->encoding.nCodeUnits())); + if (opts->bFlag) { + bitmaps.gen(o, 2); } o.ws("\n"); } diff --git a/re2c/src/ir/skeleton/skeleton.h b/re2c/src/ir/skeleton/skeleton.h index ce1c9919..e9ed4985 100644 --- a/re2c/src/ir/skeleton/skeleton.h +++ b/re2c/src/ir/skeleton/skeleton.h @@ -11,6 +11,7 @@ #include #include +#include "src/codegen/bitmap.h" #include "src/ir/regexp/regexp.h" #include "src/ir/rule.h" #include "src/ir/tcmd.h" @@ -102,7 +103,8 @@ void emit_data(const Skeleton &skel, std::string fname, size_t cunit_size); void emit_prolog(OutputFile & o); void emit_start(OutputFile &o, size_t maxfill, const std::string &name, size_t sizeof_key, size_t def, bool backup, bool accept, bool oldstyle_ctxmarker, - const std::set &tagnames, const std::set &tagvars); + const std::set &tagnames, const std::set &tagvars, + bitmaps_t &bitmaps); void emit_end(OutputFile &o, const std::string &name, bool backup, bool oldstyle_ctxmarker); void emit_epilog(OutputFile &o, const std::set &names); void emit_action(OutputFile &o, uint32_t ind, const DFA &dfa, size_t rid); diff --git a/re2c/src/main.cc b/re2c/src/main.cc index 6760a4e3..f5029811 100644 --- a/re2c/src/main.cc +++ b/re2c/src/main.cc @@ -13,7 +13,6 @@ namespace re2c { -bool bUsedYYBitmap = false; bool bWroteGetState = false; bool bWroteCondCheck = false;