]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Implementation of liferange overlap test
authorWolfgang Bumiller <wolfgang.linux@bumiller.com>
Tue, 1 May 2012 10:40:37 +0000 (12:40 +0200)
committerWolfgang Bumiller <wolfgang.linux@bumiller.com>
Tue, 1 May 2012 10:40:37 +0000 (12:40 +0200)
ir.c
ir.h

diff --git a/ir.c b/ir.c
index 720efc9b97bc20d4620a31290da0f5d350b9935c..cbfe304c1fca8ac2c7d4b39f5885a12b84ef10fd 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -558,6 +558,60 @@ bool ir_value_life_merge(ir_value *self, size_t s)
     return ir_value_life_insert(self, i, new_entry);
 }
 
+bool ir_values_overlap(ir_value *a, ir_value *b)
+{
+    /* For any life entry in A see if it overlaps with
+     * any life entry in B.
+     * Note that the life entries are orderes, so we can make a
+     * more efficient algorithm there than naively translating the
+     * statement above.
+     */
+
+    ir_life_entry_t *la, *lb, *enda, *endb;
+
+    /* first of all, if either has no life range, they cannot clash */
+    if (!a->life_count || !b->life_count)
+        return false;
+
+    la = a->life;
+    lb = b->life;
+    enda = la + a->life_count;
+    endb = lb + b->life_count;
+    while (true)
+    {
+        /* check if the entries overlap, for that,
+         * both must start before the other one ends.
+         */
+        if (la->start <= lb->end &&
+            lb->start <= la->end)
+        {
+            return true;
+        }
+
+        /* entries are ordered
+         * one entry is earlier than the other
+         * that earlier entry will be moved forward
+         */
+        if (la->end < lb->end)
+        {
+            /* order: A B, move A forward
+             * check if we hit the end with A
+             */
+            if (++la == enda)
+                break;
+        }
+        else if (lb->end < la->end)
+        {
+            /* order: B A, move B forward
+             * check if we hit the end with B
+             */
+            if (++lb == endb)
+                break;
+        }
+    }
+    return false;
+}
+
 /***********************************************************************
  *IR main operations
  */
diff --git a/ir.h b/ir.h
index 7d77d2979d40725e20a4e0f1a2a5c85277e9e5d1..cbddf71c40cbe4b46a11320a85198d9e133e50ab 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -83,6 +83,8 @@ MEM_VECTOR_PROTO(ir_value, ir_life_entry_t, life);
 bool ir_value_life_merge(ir_value*, size_t);
 /* check if a value lives at a specific point */
 bool ir_value_lives(ir_value*, size_t);
+/* check if the life-range of 2 values overlaps */
+bool ir_values_overlap(ir_value*, ir_value*);
 
 void ir_value_dump(ir_value*, int (*oprintf)(const char*,...));
 void ir_value_dump_life(ir_value *self, int (*oprintf)(const char*,...));