From 281c11776def119b7db13b1bb7655ce67d3091f3 Mon Sep 17 00:00:00 2001
From: Aaron Councilman <aaronjc4@illinois.edu>
Date: Thu, 5 Dec 2024 10:07:11 -0600
Subject: [PATCH] Bug fixes for CCP

---
 Cargo.lock                                | 10 ++++++
 Cargo.toml                                |  1 +
 hercules_opt/src/ccp.rs                   | 40 +++++++++++++++--------
 juno_samples/nested_ccp.jn                | 15 +++++++++
 juno_samples/nested_ccp/Cargo.toml        | 18 ++++++++++
 juno_samples/nested_ccp/build.rs          | 10 ++++++
 juno_samples/nested_ccp/src/main.rs       | 22 +++++++++++++
 juno_samples/nested_ccp/src/nested_ccp.jn | 15 +++++++++
 8 files changed, 117 insertions(+), 14 deletions(-)
 create mode 100644 juno_samples/nested_ccp.jn
 create mode 100644 juno_samples/nested_ccp/Cargo.toml
 create mode 100644 juno_samples/nested_ccp/build.rs
 create mode 100644 juno_samples/nested_ccp/src/main.rs
 create mode 100644 juno_samples/nested_ccp/src/nested_ccp.jn

diff --git a/Cargo.lock b/Cargo.lock
index 1f9d1747..23c5f4c7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -749,6 +749,16 @@ dependencies = [
  "with_builtin_macros",
 ]
 
+[[package]]
+name = "juno_nested_ccp"
+version = "0.1.0"
+dependencies = [
+ "async-std",
+ "hercules_rt",
+ "juno_build",
+ "with_builtin_macros",
+]
+
 [[package]]
 name = "juno_scheduler"
 version = "0.0.1"
diff --git a/Cargo.toml b/Cargo.toml
index a34845f8..bffe0364 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,4 +23,5 @@ members = [
 	"juno_samples/simple3",
 	"juno_samples/matmul",
 	"juno_samples/casts_and_intrinsics",
+	"juno_samples/nested_ccp",
 ]
diff --git a/hercules_opt/src/ccp.rs b/hercules_opt/src/ccp.rs
index dba29f23..692d0f71 100644
--- a/hercules_opt/src/ccp.rs
+++ b/hercules_opt/src/ccp.rs
@@ -53,6 +53,19 @@ impl CCPLattice {
     }
 }
 
+impl ReachabilityLattice {
+    // We define join for the reachability lattice as for data nodes we join the reachability of
+    // its uses since it is unreachable if any of its uses are unreachable
+    fn join(a: &Self, b: &Self) -> Self {
+        match (a, b) {
+            (ReachabilityLattice::Reachable, ReachabilityLattice::Reachable) => {
+                ReachabilityLattice::Reachable
+            }
+            _ => ReachabilityLattice::Unreachable,
+        }
+    }
+}
+
 impl ConstantLattice {
     fn is_top(&self) -> bool {
         *self == ConstantLattice::Top
@@ -274,11 +287,10 @@ pub fn ccp(editor: &mut FunctionEditor, reverse_postorder: &Vec<NodeID>) {
                     // Replace all uses of the single reachable user with the node preceeding the
                     // branch node
                     edit = edit.replace_all_uses(the_reachable_user, control)?;
-                    // Delete all users and the branch node
-                    for user in users {
-                        edit = edit.delete_node(user)?;
-                    }
-                    edit.delete_node(branch_id)
+                    // Mark the reachable user and the branch as unreachable so they'll be deleted
+                    unreachable.insert(the_reachable_user);
+                    unreachable.insert(branch_id);
+                    Ok(edit)
                 });
             }
         }
@@ -629,7 +641,7 @@ fn ccp_flow_function(
             };
 
             CCPLattice {
-                reachability: ReachabilityLattice::meet(left_reachability, right_reachability),
+                reachability: ReachabilityLattice::join(left_reachability, right_reachability),
                 constant: new_constant,
             }
         }
@@ -682,9 +694,9 @@ fn ccp_flow_function(
             };
 
             CCPLattice {
-                reachability: ReachabilityLattice::meet(
+                reachability: ReachabilityLattice::join(
                     first_reachability,
-                    &ReachabilityLattice::meet(second_reachability, third_reachability),
+                    &ReachabilityLattice::join(second_reachability, third_reachability),
                 ),
                 constant: new_constant,
             }
@@ -696,13 +708,13 @@ fn ccp_flow_function(
             dynamic_constants: _,
             args,
         } => CCPLattice {
-            reachability: args.iter().fold(ReachabilityLattice::top(), |val, id| {
-                ReachabilityLattice::meet(&val, &inputs[id.idx()].reachability)
+            reachability: args.iter().fold(ReachabilityLattice::bottom(), |val, id| {
+                ReachabilityLattice::join(&val, &inputs[id.idx()].reachability)
             }),
             constant: ConstantLattice::bottom(),
         },
         Node::IntrinsicCall { intrinsic, args } => {
-            let mut new_reachability = ReachabilityLattice::top();
+            let mut new_reachability = ReachabilityLattice::bottom();
             let mut new_constant = ConstantLattice::top();
             let mut constants = vec![];
             let mut all_constants = true;
@@ -713,7 +725,7 @@ fn ccp_flow_function(
                     ref constant,
                 } = inputs[arg.idx()];
 
-                new_reachability = ReachabilityLattice::meet(&new_reachability, reachability);
+                new_reachability = ReachabilityLattice::join(&new_reachability, reachability);
                 new_constant = ConstantLattice::meet(&new_constant, constant);
 
                 if let ConstantLattice::Constant(constant) = constant {
@@ -908,14 +920,14 @@ fn ccp_flow_function(
             data,
             indices,
         } => {
-            let mut reachability = ReachabilityLattice::meet(
+            let mut reachability = ReachabilityLattice::join(
                 &inputs[collect.idx()].reachability,
                 &inputs[data.idx()].reachability,
             );
             for index in indices.iter() {
                 if let Index::Position(positions) = index {
                     for position in positions.iter() {
-                        reachability = ReachabilityLattice::meet(
+                        reachability = ReachabilityLattice::join(
                             &reachability,
                             &inputs[position.idx()].reachability,
                         );
diff --git a/juno_samples/nested_ccp.jn b/juno_samples/nested_ccp.jn
new file mode 100644
index 00000000..506f0361
--- /dev/null
+++ b/juno_samples/nested_ccp.jn
@@ -0,0 +1,15 @@
+#[entry]
+fn ccp_example() -> f32 {
+  let x : f32 = 2;
+  if x < 3 {
+    x = 1;
+  } else {
+    if x == 1 {
+      x = 4;
+    } else {
+      x = 1;
+    }
+  }
+  if false { for i = 0 to 3 by 1 { } }
+  return x;
+}
diff --git a/juno_samples/nested_ccp/Cargo.toml b/juno_samples/nested_ccp/Cargo.toml
new file mode 100644
index 00000000..8c9b969d
--- /dev/null
+++ b/juno_samples/nested_ccp/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "juno_nested_ccp"
+version = "0.1.0"
+authors = ["Russel Arbore <rarbore2@illinois.edu>"]
+edition = "2021"
+
+[[bin]]
+name = "juno_nested_ccp"
+path = "src/main.rs"
+
+[build-dependencies]
+juno_build = { path = "../../juno_build" }
+
+[dependencies]
+juno_build = { path = "../../juno_build" }
+hercules_rt = { path = "../../hercules_rt" }
+with_builtin_macros = "0.1.0"
+async-std = "*"
diff --git a/juno_samples/nested_ccp/build.rs b/juno_samples/nested_ccp/build.rs
new file mode 100644
index 00000000..0fb54be3
--- /dev/null
+++ b/juno_samples/nested_ccp/build.rs
@@ -0,0 +1,10 @@
+extern crate juno_build;
+use juno_build::JunoCompiler;
+
+fn main() {
+    JunoCompiler::new()
+        .file_in_src("nested_ccp.jn")
+        .unwrap()
+        .build()
+        .unwrap();
+}
diff --git a/juno_samples/nested_ccp/src/main.rs b/juno_samples/nested_ccp/src/main.rs
new file mode 100644
index 00000000..1acea9bf
--- /dev/null
+++ b/juno_samples/nested_ccp/src/main.rs
@@ -0,0 +1,22 @@
+#![feature(future_join)]
+
+extern crate async_std;
+extern crate juno_build;
+extern crate hercules_rt;
+
+juno_build::juno!("nested_ccp");
+
+fn main() {
+    async_std::task::block_on(async {
+        let output = unsafe {
+            ccp_example().await
+        };
+        println!("{}", output);
+        assert_eq!(output, 1.0);
+    });
+}
+
+#[test]
+fn nested_ccp() {
+    main();
+}
diff --git a/juno_samples/nested_ccp/src/nested_ccp.jn b/juno_samples/nested_ccp/src/nested_ccp.jn
new file mode 100644
index 00000000..506f0361
--- /dev/null
+++ b/juno_samples/nested_ccp/src/nested_ccp.jn
@@ -0,0 +1,15 @@
+#[entry]
+fn ccp_example() -> f32 {
+  let x : f32 = 2;
+  if x < 3 {
+    x = 1;
+  } else {
+    if x == 1 {
+      x = 4;
+    } else {
+      x = 1;
+    }
+  }
+  if false { for i = 0 to 3 by 1 { } }
+  return x;
+}
-- 
GitLab