]> granicus.if.org Git - re2c/commitdiff
Merged a couple of slightly different 'topsort' versions into one.
authorUlya Trofimovich <skvadrik@gmail.com>
Sat, 8 Apr 2017 18:37:32 +0000 (19:37 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Sat, 8 Apr 2017 18:37:32 +0000 (19:37 +0100)
re2c/src/dfa/cfg/normalize.cc
re2c/src/dfa/find_state.cc
re2c/src/dfa/tcmd.cc
re2c/src/dfa/tcmd.h

index 4a7104d22cd955689ece3554b6ead277ac9d6ffd..215ff80c146b4ac6d067a195c364af03acf97425 100644 (file)
@@ -27,20 +27,28 @@ void cfg_t::normalization(cfg_t &cfg)
        cfg_bb_t *b = cfg.bblocks, *e = b + cfg.nbbfall;
        for (; b < e; ++b) {
 
-               for (tcmd_t *x = b->cmd, *y; x;) {
+               // We cannot normalize the list of commands as a whole: the
+               // relative order of some commands might be significant.
+               // Therefore we split the list in continuous sublists of
+               // 'copy', 'save without history' and 'save with history'
+               // commands and normalize each sublist in a proper way.
+               tcmd_t **px, **py, *x;
+               for (px = &b->cmd; (x = *px);) {
                        if (tcmd_t::iscopy(x->rhs)) {
-                               for (y = x; x && tcmd_t::iscopy(x->rhs); x = x->next);
-                               normalize(y, x);
+                               for (py = px; (x = *px) && tcmd_t::iscopy(x->rhs); px = &x->next);
+                               *px = NULL;
+                               normalize(*py, NULL);
+                               tcmd_t::topsort(py, indeg);
+                               for (px = py; *px; px = &(*px)->next);
+                               *px = x;
                        } else if (tcmd_t::isset(x)) {
-                               for (y = x; x && tcmd_t::isset(x); x = x->next);
-                               normalize(y, x);
+                               for (py = px; (x = *px) && tcmd_t::isset(x); px = &x->next);
+                               normalize(*py, x);
                        } else {
-                               for (y = x; x && tcmd_t::isadd(x); x = x->next);
+                               for (py = px; (x = *px) && tcmd_t::isadd(x); px = &x->next);
                                // don't normalize, histories may have complex dependencies
                        }
                }
-
-               tcmd_t::topsort(&b->cmd, indeg);
        }
 
        delete[] indeg;
index 9a36b21734ff2a0c704e2eb59cf40f42c950c234..95a854237435ac89586e2d5c290d1cabe33a0347 100644 (file)
@@ -292,7 +292,7 @@ tcmd_t *kernels_t::actions(tcmd_t *acts)
        *pa = acts;
 
        // see note [topological ordering of copy commands]
-       tcmd_t::topsort1(&copy, indeg);
+       tcmd_t::topsort(&copy, indeg);
 
        return copy;
 }
index 2ea2f4d8546cb3fe446677cc0f770eb2902660ce..ec4d29eeee3e5583ef2870bf1c047c2668a2ccd9 100644 (file)
@@ -72,75 +72,13 @@ bool tcmd_t::isadd(const tcmd_t *cmd)
        return !tcmd_t::iscopy(cmd->rhs) && cmd->pred != TAGVER_ZERO;
 }
 
-static tcmd_t **topsort_(tcmd_t **phead, uint32_t *indeg);
-
-void tcmd_t::topsort(tcmd_t **phead, uint32_t *indeg)
-{
-       tcmd_t *x = *phead, **py = phead, **py0;
-
-       for (x = *phead; x;) {
-
-               *py = x;
-               for (; x && !tcmd_t::iscopy(x->rhs); x = x->next) {
-                       py = &x->next;
-               }
-
-               py0 = py;
-               for (; x && tcmd_t::iscopy(x->rhs); x = x->next) {
-                       py = &x->next;
-               }
-               *py = NULL;
-
-               py = topsort_(py0, indeg);
-       }
-}
-
-tcmd_t **topsort_(tcmd_t **phead, uint32_t *indeg)
-{
-       tcmd_t
-               *x0 = *phead, **px, *x,
-               *y0 = NULL, **py, **py1;
-
-       // initialize in-degree
-       for (x = x0; x; x = x->next) {
-               ++indeg[x->rhs];
-       }
-
-       for (py = &y0;;) {
-               // reached end of list
-               if (!x0) break;
-
-               px = &x0;
-               py1 = py;
-               for (x = x0; x; x = x->next) {
-                       if (indeg[x->lhs] == 0) {
-                               --indeg[x->rhs];
-                               *py = x;
-                               py = &x->next;
-                       } else {
-                               *px = x;
-                               px = &x->next;
-                       }
-               }
-               *px = NULL;
-
-               // only cycles left
-               if (py == py1) break;
-       }
-       *py = x0;
-
-       *phead = y0;
-       for (; *py; py = &(*py)->next);
-       return py;
-}
-
 static tagver_t depend(const tcmd_t *x)
 {
        const tagver_t r = x->rhs, h = x->pred;
        return tcmd_t::iscopy(r) ? r : h;
 }
 
-void tcmd_t::topsort1(tcmd_t **phead, uint32_t *indeg)
+void tcmd_t::topsort(tcmd_t **phead, uint32_t *indeg)
 {
        tcmd_t
                *x0 = *phead, **px, *x,
index 93aa63341539d8877aa99788bb03bb7a46ce39a9..1dbd3f8098e9fb0db1258316bfe7c7065e9aefed 100644 (file)
@@ -21,7 +21,6 @@ struct tcmd_t
        static void swap(tcmd_t &x, tcmd_t &y);
        static bool equal(const tcmd_t &x, const tcmd_t &y);
        static void topsort(tcmd_t **phead, uint32_t *indeg);
-       static void topsort1(tcmd_t **phead, uint32_t *indeg);
        static bool iscopy(tagver_t rhs);
        static bool isset(const tcmd_t *cmd);
        static bool isadd(const tcmd_t *cmd);