From 843390501529299ef7d227f2e32b74e939f0cc99 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 27 Dec 2021 14:25:55 +0900 Subject: [PATCH] [qfcc] Extend reachable to the label node's parents While using just the label node's reachable set was sufficient for a simple swap (t = a; a = b; b = t;), it is not sufficient for read-before-write dependencies such as found in linked-list building: { o = array[ind]; o.next = obj; obj = o; } The assignment to o.next uses obj, but that use is hidden because obj's reachable nodes does not include o thus assigning o to obj causes the array dereference to be assigned directly to obj and thus o.next winds up pointing to o instead of whatever obj was. The parent nodes of obj's node are its users, so any new assigned to obj must come after those parents as well as any node reachable by obj's node. Fixes a runaway loop error when adding a frikbot to the server. --- tools/qfcc/source/dags.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/qfcc/source/dags.c b/tools/qfcc/source/dags.c index fea637564..202c9a51a 100644 --- a/tools/qfcc/source/dags.c +++ b/tools/qfcc/source/dags.c @@ -642,9 +642,23 @@ dagnode_attach_label (dag_t *dag, dagnode_t *n, daglabel_t *l) if (l->dagnode) { dagnode_t *node = l->dagnode; set_remove (node->identifiers, l->number); - if (set_is_member (node->reachable, n->number)) { + + // If the target node (n) is reachable by the label's node or its + // parents, then attaching the label's node to the target node would + // cause the label's node to be written before it used. + set_t *reachable = set_new (); + set_assign (reachable, node->reachable); + for (set_iter_t *node_iter = set_first (node->parents); node_iter; + node_iter = set_next (node_iter)) { + dagnode_t *p = dag->nodes[node_iter->element]; + set_union (reachable, p->reachable); + } + int is_reachable = set_is_member (reachable, n->number); + set_delete (reachable); + if (is_reachable) { return 0; } + set_add (n->edges, node->number); dagnode_set_reachable (dag, n); }