diff --git a/juno_samples/fork_join_tests/src/cpu.sch b/juno_samples/fork_join_tests/src/cpu.sch
index 4cebc0441f73d4577d30b3ef6c037c9e0fa082ee..7c416e904ad5d43a5297496b6de40037f5b9b553 100644
--- a/juno_samples/fork_join_tests/src/cpu.sch
+++ b/juno_samples/fork_join_tests/src/cpu.sch
@@ -15,6 +15,7 @@ cpu(auto.test7);
 cpu(auto.test8);
 
 let test1_cpu = auto.test1;
+rename["test1_cpu"](test1_cpu);
 
 ip-sroa(*);
 sroa(*);
diff --git a/juno_scheduler/src/compile.rs b/juno_scheduler/src/compile.rs
index df72a1a301e899aa29cb6a1c49e35a5145ed18cf..0652f8f260929d3fd27147806520f02af28a0bd6 100644
--- a/juno_scheduler/src/compile.rs
+++ b/juno_scheduler/src/compile.rs
@@ -434,6 +434,11 @@ fn compile_expr(
         parser::Expr::Boolean { span: _, val } => {
             Ok(ExprResult::Expr(ir::ScheduleExp::Boolean { val }))
         }
+        parser::Expr::String { span } => {
+            let string = lexer.span_str(span);
+            let val = string[1..string.len() - 1].to_string();
+            Ok(ExprResult::Expr(ir::ScheduleExp::String { val }))
+        }
         parser::Expr::Field {
             span: _,
             lhs,
diff --git a/juno_scheduler/src/ir.rs b/juno_scheduler/src/ir.rs
index c495f2a65524c3c84654b9833583d6193593c3b1..e92f1d374705a72f090208a3073155507df5915c 100644
--- a/juno_scheduler/src/ir.rs
+++ b/juno_scheduler/src/ir.rs
@@ -83,6 +83,9 @@ pub enum ScheduleExp {
     Boolean {
         val: bool,
     },
+    String {
+        val: String,
+    },
     Field {
         collect: Box<ScheduleExp>,
         field: String,
diff --git a/juno_scheduler/src/lang.l b/juno_scheduler/src/lang.l
index 9d4c34bf8f7e50aaef048c7eba1a22c6f5872a96..afe596b2f3a90fcfb9e8fd1d8c6f5224afc7131f 100644
--- a/juno_scheduler/src/lang.l
+++ b/juno_scheduler/src/lang.l
@@ -46,5 +46,6 @@ stop[\t \n\r]+after  "stop_after"
 [a-zA-Z][a-zA-Z0-9_\-]*! "MACRO"
 [a-zA-Z][a-zA-Z0-9_\-]*  "ID"
 [0-9]+                   "INT"
+\"[a-zA-Z0-9_\-\s\.]*\"  "STRING"
 
 .                     "UNMATCHED"
diff --git a/juno_scheduler/src/lang.y b/juno_scheduler/src/lang.y
index 9cb728428e08b0f77b77be526e2f3e0aa9c86a37..584bf2a4ef1a476669f10de115a5dda38213a695 100644
--- a/juno_scheduler/src/lang.y
+++ b/juno_scheduler/src/lang.y
@@ -1,6 +1,6 @@
 %start Schedule
 
-%avoid_insert "ID" "INT"
+%avoid_insert "ID" "INT" "STRING"
 %expect-unused Unmatched 'UNMATCHED'
 
 %%
@@ -47,6 +47,8 @@ Expr -> Expr
       { Expr::Boolean { span: $span, val: true } }
   | 'false'
       { Expr::Boolean { span: $span, val: false } }
+  | 'STRING'
+      { Expr::String { span: $span } }
   | Expr '.' 'ID'
       { Expr::Field { span: $span, lhs: Box::new($1), field: span_of_tok($3) } }
   | Expr '@' 'ID'
@@ -155,6 +157,7 @@ pub enum Expr {
   Variable    { span: Span },
   Integer     { span: Span },
   Boolean     { span: Span, val: bool },
+  String      { span: Span },
   Field       { span: Span, lhs: Box<Expr>, field: Span },
   BlockExpr   { span: Span, body: Box<OperationList> },
   Record      { span: Span, fields: Vec<(Span, Expr)> },
diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs
index 0df691ead47244cbe42f56b4a23e260494d09e6f..9c51276b82aa52fde5aa8dd13295b69aea7fb064 100644
--- a/juno_scheduler/src/pm.rs
+++ b/juno_scheduler/src/pm.rs
@@ -29,6 +29,7 @@ pub enum Value {
     Selection { selection: Vec<Value> },
     Integer { val: usize },
     Boolean { val: bool },
+    String { val: String },
 }
 
 #[derive(Debug, Copy, Clone)]
@@ -70,6 +71,9 @@ impl Value {
             Value::Boolean { .. } => Err(SchedulerError::SemanticError(
                 "Expected labels, found boolean".to_string(),
             )),
+            Value::String { .. } => Err(SchedulerError::SemanticError(
+                "Expected labels, found string".to_string(),
+            )),
         }
     }
 
@@ -99,6 +103,9 @@ impl Value {
             Value::Boolean { .. } => Err(SchedulerError::SemanticError(
                 "Expected functions, found boolean".to_string(),
             )),
+            Value::String { .. } => Err(SchedulerError::SemanticError(
+                "Expected functions, found string".to_string(),
+            )),
         }
     }
 
@@ -130,6 +137,9 @@ impl Value {
             Value::Boolean { .. } => Err(SchedulerError::SemanticError(
                 "Expected code locations, found boolean".to_string(),
             )),
+            Value::String { .. } => Err(SchedulerError::SemanticError(
+                "Expected code locations, found string".to_string(),
+            )),
         }
     }
 }
@@ -998,6 +1008,7 @@ fn interp_expr(
         }
         ScheduleExp::Integer { val } => Ok((Value::Integer { val: *val }, false)),
         ScheduleExp::Boolean { val } => Ok((Value::Boolean { val: *val }, false)),
+        ScheduleExp::String { val } => Ok((Value::String { val: val.clone() }, false)),
         ScheduleExp::Field { collect, field } => {
             let (lhs, changed) = interp_expr(pm, collect, stringtab, env, functions)?;
             match lhs {
@@ -1005,7 +1016,8 @@ fn interp_expr(
                 | Value::Selection { .. }
                 | Value::Everything { .. }
                 | Value::Integer { .. }
-                | Value::Boolean { .. } => Err(SchedulerError::UndefinedField(field.clone())),
+                | Value::Boolean { .. }
+                | Value::String { .. } => Err(SchedulerError::UndefinedField(field.clone())),
                 Value::JunoFunction { func } => {
                     match pm.labels.borrow().iter().position(|s| s == field) {
                         None => Err(SchedulerError::UndefinedLabel(field.clone())),
@@ -1260,6 +1272,7 @@ fn update_value(
         Value::Everything {} => Some(Value::Everything {}),
         Value::Integer { val } => Some(Value::Integer { val }),
         Value::Boolean { val } => Some(Value::Boolean { val }),
+        Value::String { val } => Some(Value::String { val }),
     }
 }
 
@@ -2193,16 +2206,15 @@ fn run_pass(
         }
         Pass::Rename => {
             assert!(args.len() == 1);
-            let new_name =
-                match args[0] {
-                    Value::String { val } => val,
-                    _ => {
-                        return Err(SchedulerError::PassError {
-                            pass: "rename".to_string(),
-                            error: "expected string argument".to_string(),
-                        });
-                    }
-                };
+            let new_name = match args[0] {
+                Value::String { ref val } => val.clone(),
+                _ => {
+                    return Err(SchedulerError::PassError {
+                        pass: "rename".to_string(),
+                        error: "expected string argument".to_string(),
+                    });
+                }
+            };
             if pm.functions.iter().any(|f| f.name == new_name) {
                 return Err(SchedulerError::PassError {
                     pass: "rename".to_string(),
@@ -2210,8 +2222,9 @@ fn run_pass(
                 });
             }
 
-            if let Some(funcs) = selection_of_functions(pm, selection) 
-                && funcs.len() == 1 {
+            if let Some(funcs) = selection_of_functions(pm, selection)
+                && funcs.len() == 1
+            {
                 let func = funcs[0];
                 pm.functions[func.idx()].name = new_name;
             } else {
@@ -2364,7 +2377,13 @@ fn run_pass(
                 let Some(mut func) = func else {
                     continue;
                 };
-                chunk_all_forks_unguarded(&mut func, fork_join_map, *dim_idx, *tile_size, *tile_order);
+                chunk_all_forks_unguarded(
+                    &mut func,
+                    fork_join_map,
+                    *dim_idx,
+                    *tile_size,
+                    *tile_order,
+                );
                 changed |= func.modified();
             }
             pm.delete_gravestones();