From add0dc9c12126071dfa6753a6baa29644c485351 Mon Sep 17 00:00:00 2001
From: Aaron Councilman <aaronjc4@illinois.edu>
Date: Wed, 2 Apr 2025 14:26:07 -0500
Subject: [PATCH] Only use zero collection constants in Juno

---
 juno_frontend/src/codegen.rs | 129 ++++++++++++++++++++++-------------
 1 file changed, 80 insertions(+), 49 deletions(-)

diff --git a/juno_frontend/src/codegen.rs b/juno_frontend/src/codegen.rs
index 0902bc61..cc314304 100644
--- a/juno_frontend/src/codegen.rs
+++ b/juno_frontend/src/codegen.rs
@@ -380,14 +380,7 @@ impl CodeGenerator<'_> {
                 (self.build_union(*tag, value, union_type), block)
             }
             Expr::Constant { val, .. } => {
-                let const_id = self.build_constant(val, types);
-
-                let mut val = self.builder.allocate_node();
-                let val_node = val.id();
-                val.build_constant(const_id);
-                self.builder.add_node(val);
-
-                (val_node, cur_block)
+                (self.build_constant(val, types), cur_block)
             }
             Expr::Zero { typ } => {
                 let type_id = types.lower_type(&mut self.builder.builder, *typ);
@@ -676,49 +669,87 @@ impl CodeGenerator<'_> {
         &mut self,
         (lit, typ): &semant::Constant,
         types: &mut TypeSolverInst<'a>,
-    ) -> ConstantID {
-        match lit {
-            Literal::Unit => self.builder.builder.create_constant_prod(vec![].into()),
-            Literal::Bool(val) => self.builder.builder.create_constant_bool(*val),
-            Literal::Integer(val) => {
-                let p = types.as_numeric_type(&mut self.builder.builder, *typ);
-                match p {
-                    Primitive::I8 => self.builder.builder.create_constant_i8(*val as i8),
-                    Primitive::I16 => self.builder.builder.create_constant_i16(*val as i16),
-                    Primitive::I32 => self.builder.builder.create_constant_i32(*val as i32),
-                    Primitive::I64 => self.builder.builder.create_constant_i64(*val as i64),
-                    Primitive::U8 => self.builder.builder.create_constant_u8(*val as u8),
-                    Primitive::U16 => self.builder.builder.create_constant_u16(*val as u16),
-                    Primitive::U32 => self.builder.builder.create_constant_u32(*val as u32),
-                    Primitive::U64 => self.builder.builder.create_constant_u64(*val as u64),
-                    Primitive::F32 => self.builder.builder.create_constant_f32(*val as f32),
-                    Primitive::F64 => self.builder.builder.create_constant_f64(*val as f64),
-                    _ => panic!("Internal error in build_constant for integer"),
+    ) -> NodeID {
+        let const_id =
+            match lit {
+                Literal::Unit => {
+                    let type_id = types.lower_type(&mut self.builder.builder, *typ);
+                    self.builder.builder.create_constant_zero(type_id)
                 }
-            }
-            Literal::Float(val) => {
-                let p = types.as_numeric_type(&mut self.builder.builder, *typ);
-                match p {
-                    Primitive::F32 => self.builder.builder.create_constant_f32(*val as f32),
-                    Primitive::F64 => self.builder.builder.create_constant_f64(*val as f64),
-                    _ => panic!("Internal error in build_constant for float"),
+                Literal::Bool(val) => self.builder.builder.create_constant_bool(*val),
+                Literal::Integer(val) => {
+                    let p = types.as_numeric_type(&mut self.builder.builder, *typ);
+                    match p {
+                        Primitive::I8 => self.builder.builder.create_constant_i8(*val as i8),
+                        Primitive::I16 => self.builder.builder.create_constant_i16(*val as i16),
+                        Primitive::I32 => self.builder.builder.create_constant_i32(*val as i32),
+                        Primitive::I64 => self.builder.builder.create_constant_i64(*val as i64),
+                        Primitive::U8 => self.builder.builder.create_constant_u8(*val as u8),
+                        Primitive::U16 => self.builder.builder.create_constant_u16(*val as u16),
+                        Primitive::U32 => self.builder.builder.create_constant_u32(*val as u32),
+                        Primitive::U64 => self.builder.builder.create_constant_u64(*val as u64),
+                        Primitive::F32 => self.builder.builder.create_constant_f32(*val as f32),
+                        Primitive::F64 => self.builder.builder.create_constant_f64(*val as f64),
+                        _ => panic!("Internal error in build_constant for integer"),
+                    }
                 }
-            }
-            Literal::Tuple(vals) => {
-                let mut constants = vec![];
-                for val in vals {
-                    constants.push(self.build_constant(val, types));
+                Literal::Float(val) => {
+                    let p = types.as_numeric_type(&mut self.builder.builder, *typ);
+                    match p {
+                        Primitive::F32 => self.builder.builder.create_constant_f32(*val as f32),
+                        Primitive::F64 => self.builder.builder.create_constant_f64(*val as f64),
+                        _ => panic!("Internal error in build_constant for float"),
+                    }
                 }
-                self.builder.builder.create_constant_prod(constants.into())
-            }
-            Literal::Sum(tag, val) => {
-                let constant = self.build_constant(val, types);
-                let type_id = types.lower_type(&mut self.builder.builder, *typ);
-                self.builder
-                    .builder
-                    .create_constant_sum(type_id, *tag as u32, constant)
-                    .unwrap()
-            }
-        }
+                Literal::Tuple(vals) => {
+                    let type_id = types.lower_type(&mut self.builder.builder, *typ);
+                    let zero_const = self.builder.builder.create_constant_zero(type_id);
+
+                    let mut zero_node = self.builder.allocate_node();
+                    let zero_id = zero_node.id();
+                    zero_node.build_constant(zero_const);
+                    self.builder.add_node(zero_node);
+
+                    let mut cur_node = zero_id;
+                    for (idx, val) in vals.iter().enumerate() {
+                        let index = self.builder.builder.create_field_index(idx);
+                        let val_id = self.build_constant(val, types);
+
+                        let mut write = self.builder.allocate_node();
+                        let write_id = write.id();
+                        write.build_write(cur_node, val_id, vec![index].into());
+                        self.builder.add_node(write);
+
+                        cur_node = write_id;
+                    }
+                    return cur_node;
+                }
+                Literal::Sum(tag, val) => {
+                    let type_id = types.lower_type(&mut self.builder.builder, *typ);
+                    let zero_const = self.builder.builder.create_constant_zero(type_id);
+
+                    let mut zero_node = self.builder.allocate_node();
+                    let zero_id = zero_node.id();
+                    zero_node.build_constant(zero_const);
+                    self.builder.add_node(zero_node);
+
+                    let val_id = self.build_constant(val, types);
+                    let tag_index = self.builder.builder.create_variant_index(*tag);
+
+                    let mut write = self.builder.allocate_node();
+                    let write_id = write.id();
+                    write.build_write(zero_id, val_id, vec![tag_index].into());
+                    self.builder.add_node(write);
+
+                    return write_id;
+                }
+            };
+
+        let mut const_node = self.builder.allocate_node();
+        let node_id = const_node.id();
+        const_node.build_constant(const_id);
+        self.builder.add_node(const_node);
+
+        node_id
     }
 }
-- 
GitLab