mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 23:11:38 +00:00
[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.
This commit is contained in:
parent
4ad84b3786
commit
8433905015
1 changed files with 15 additions and 1 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue