]> granicus.if.org Git - re2c/commitdiff
Compact tag versions before doing liveness analysis.
authorUlya Trofimovich <skvadrik@gmail.com>
Mon, 23 Jan 2017 16:38:04 +0000 (16:38 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Mon, 23 Jan 2017 16:38:04 +0000 (16:38 +0000)
After TDFA construction tag versions occupy non-contiguous range
of natural numbers: there may be "holes" between versions. This wastes
space (and time) spent on liveness analysis and subsequent optimization
passes. This commit adds a simple pass that renumbers versions so that
they occupy contiguios range.

re2c/Makefile.am
re2c/src/ir/dfa/cfg/cfg.h
re2c/src/ir/dfa/cfg/compact.cc [new file with mode: 0644]
re2c/src/ir/dfa/cfg/optimize.cc

index 2a8e61da511dece888edb33af5fc0e63d5891ff1..bd24ad3c1653989bced24118aadd1b1ecf5d7d85 100644 (file)
@@ -93,6 +93,7 @@ SRC = \
        src/ir/adfa/dump.cc \
        src/ir/adfa/prepare.cc \
        src/ir/dfa/cfg/cfg.cc \
+       src/ir/dfa/cfg/compact.cc \
        src/ir/dfa/cfg/dce.cc \
        src/ir/dfa/cfg/interfere.cc \
        src/ir/dfa/cfg/liveanal.cc \
index 91db480d699fecab27c673f33821c80ecb42c2b0..b84f916f1e6c6657a3f6dced7f254f03ea5d991e 100644 (file)
@@ -27,6 +27,7 @@ struct cfg_t
 
        explicit cfg_t(dfa_t &a);
        ~cfg_t();
+       static tagver_t compact(const cfg_t &cfg, tagver_t *ver2new);
        static void liveness_analysis(const cfg_t &cfg, bool *live);
        static void dead_code_elimination(cfg_t &cfg, const bool *live);
        static void interference(const cfg_t &cfg, const bool *live, bool *interf);
diff --git a/re2c/src/ir/dfa/cfg/compact.cc b/re2c/src/ir/dfa/cfg/compact.cc
new file mode 100644 (file)
index 0000000..11a3983
--- /dev/null
@@ -0,0 +1,41 @@
+#include "src/ir/dfa/cfg/cfg.h"
+
+namespace re2c
+{
+
+tagver_t cfg_t::compact(const cfg_t &cfg, tagver_t *ver2new)
+{
+       const size_t
+               nver = static_cast<size_t>(cfg.dfa.maxtagver) + 1,
+               ntag = cfg.dfa.vartags.size();
+       const tagver_t *fins = cfg.dfa.finvers;
+       bool *used = new bool[nver];
+
+       std::fill(used, used + nver, false);
+       for (size_t t = 0; t < ntag; ++t) {
+               used[fins[t]] = true;
+       }
+       for (size_t i = 0; i < cfg.nbbfall; ++i) {
+               const cfg_bb_t &b = cfg.bblocks[i];
+
+               for (const tagsave_t *p = b.cmd->save; p; p = p->next) {
+                       used[p->ver] = true;
+               }
+
+               for (const tagcopy_t *p = b.cmd->copy; p; p = p->next) {
+                       used[p->lhs] = used[p->rhs] = true;
+               }
+       }
+
+       tagver_t maxver = 0;
+       for (size_t v = 0; v < nver; ++v) {
+               if (used[v]) {
+                       ver2new[v] = ++maxver;
+               }
+       }
+
+       return maxver;
+}
+
+} // namespace re2c
+
index 8df6bf034398d7345796509e1a8a17e01b26b362..63851b01dabe3ad0a81fcfd01f778cc0873c28cb 100644 (file)
@@ -8,20 +8,26 @@ static void freeze_tags(dfa_t &dfa);
 
 void optimize_tags(dfa_t &dfa)
 {
-       if (dfa.maxtagver > 0) {
+       tagver_t maxver = dfa.maxtagver;
+       if (maxver > 0) {
                cfg_t cfg(dfa);
 
-               const size_t nver = static_cast<size_t>(dfa.maxtagver) + 1;
+               size_t nver = static_cast<size_t>(maxver) + 1;
+               tagver_t *ver2new = new tagver_t[nver];
+
+               maxver = cfg_t::compact(cfg, ver2new);
+               cfg_t::renaming(cfg, ver2new, maxver);
+
+               nver = static_cast<size_t>(maxver) + 1;
                bool *live = new bool[cfg.nbbfin * nver];
                bool *interf = new bool[nver * nver];
-               tagver_t *ver2new = new tagver_t[nver];
 
                static const uint32_t NPASS = 2;
                for (uint32_t n = 0; n < NPASS; ++n) {
                        cfg_t::liveness_analysis(cfg, live);
                        cfg_t::dead_code_elimination(cfg, live);
                        cfg_t::interference(cfg, live, interf);
-                       const tagver_t maxver = cfg_t::variable_allocation(cfg, interf, ver2new);
+                       maxver = cfg_t::variable_allocation(cfg, interf, ver2new);
                        cfg_t::renaming(cfg, ver2new, maxver);
                        cfg_t::normalization(cfg);
                }