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;
*pa = acts;
// see note [topological ordering of copy commands]
- tcmd_t::topsort1(©, indeg);
+ tcmd_t::topsort(©, indeg);
return copy;
}
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,
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);