From 59c554b50ad599cbfc6f832b6942075efe3a0dbe Mon Sep 17 00:00:00 2001
From: David Shah <dave@ds0.me>
Date: Wed, 20 Nov 2019 15:13:28 +0000
Subject: router2: Improve backwards routing of some cases

Signed-off-by: David Shah <dave@ds0.me>
---
 common/router2.cc | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/common/router2.cc b/common/router2.cc
index fcd52bb3..271595ad 100644
--- a/common/router2.cc
+++ b/common/router2.cc
@@ -374,8 +374,34 @@ struct Router2
             t.backwards_queue.pop();
             auto &cwd = wires.at(cursor);
             PipId cpip;
-            if (cwd.bound_nets.count(net->udata))
+            if (cwd.bound_nets.count(net->udata)) {
+                // If we can tack onto existing routing; try that
+                // Only do this if the existing routing is uncontented; however
+                WireId cursor2 = cursor;
+                bool bwd_merge_fail = false;
+                while (wires.at(cursor2).bound_nets.count(net->udata)) {
+                    if (wires.at(cursor2).bound_nets.size() > 1) {
+                        bwd_merge_fail = true;
+                        break;
+                    }
+                    PipId p = wires.at(cursor2).bound_nets.at(net->udata).second;
+                    if (p == PipId())
+                        break;
+                    cursor2 = ctx->getPipSrcWire(p);
+                }
+                if (!bwd_merge_fail && cursor2 == src_wire) {
+                    // Found a path to merge to existing routing; backwards
+                    cursor2 = cursor;
+                    while (wires.at(cursor2).bound_nets.count(net->udata)) {
+                        PipId p = wires.at(cursor2).bound_nets.at(net->udata).second;
+                        if (p == PipId())
+                            break;
+                        cursor2 = ctx->getPipSrcWire(p);
+                        t.backwards_pip[cursor2] = p;
+                    }
+                }
                 cpip = cwd.bound_nets.at(net->udata).second;
+            }
             bool did_something = false;
             for (auto uh : ctx->getPipsUphill(cursor)) {
                 did_something = true;
-- 
cgit v1.2.3