From d809c9f0b271033c258067a181000a79ed94d49b Mon Sep 17 00:00:00 2001
From: Aaron Councilman <aaronjc4@illinois.edu>
Date: Thu, 5 Dec 2024 12:55:00 -0600
Subject: [PATCH 1/2] Add asserts of reachability to if and match

---
 hercules_opt/src/ccp.rs | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hercules_opt/src/ccp.rs b/hercules_opt/src/ccp.rs
index cf3a0919..c1ae383a 100644
--- a/hercules_opt/src/ccp.rs
+++ b/hercules_opt/src/ccp.rs
@@ -383,8 +383,14 @@ fn ccp_flow_function(
         }),
         // If node has only one output, if doesn't directly handle crossover of
         // reachability and constant propagation. Read handles that.
-        Node::If { control, cond: _ } => inputs[control.idx()].clone(),
-        Node::Match { control, sum: _ } => inputs[control.idx()].clone(),
+        Node::If { control, cond } => {
+            assert!(!inputs[control.idx()].is_reachable() || inputs[cond.idx()].is_reachable());
+            inputs[control.idx()].clone()
+        }
+        Node::Match { control, sum } => {
+            assert!(!inputs[control.idx()].is_reachable() || inputs[sum.idx()].is_reachable());
+            inputs[control.idx()].clone()
+        }
         Node::Fork {
             control,
             factors: _,
-- 
GitLab


From 2fbddb937f8e4f8492dd0831f99dabb74e4a63d9 Mon Sep 17 00:00:00 2001
From: Aaron Councilman <aaronjc4@illinois.edu>
Date: Thu, 5 Dec 2024 12:55:21 -0600
Subject: [PATCH 2/2] Handle reduce correctly in CCP

---
 hercules_opt/src/ccp.rs | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/hercules_opt/src/ccp.rs b/hercules_opt/src/ccp.rs
index c1ae383a..b8eb57ca 100644
--- a/hercules_opt/src/ccp.rs
+++ b/hercules_opt/src/ccp.rs
@@ -432,9 +432,21 @@ fn ccp_flow_function(
         // TODO: At least for now, reduce nodes always produce unknown values.
         Node::Reduce {
             control,
-            init: _,
-            reduct: _,
-        } => inputs[control.idx()].clone(),
+            init,
+            reduct,
+        } => {
+            let reachability = inputs[control.idx()].reachability.clone();
+            if reachability == ReachabilityLattice::Reachable {
+                assert!(inputs[init.idx()].is_reachable());
+                let mut constant = inputs[init.idx()].constant.clone();
+                if inputs[reduct.idx()].is_reachable() {
+                    constant = ConstantLattice::meet(&constant, &inputs[reduct.idx()].constant);
+                }
+                CCPLattice { reachability, constant }
+            } else {
+                CCPLattice { reachability, constant: ConstantLattice::top() }
+            }
+        },
         Node::Return { control, data } => inputs[control.idx()].clone(),
         Node::Parameter { index: _ } => CCPLattice::bottom(),
         // A constant node is the "source" of concrete constant lattice values.
-- 
GitLab