diff --git a/juno_samples/schedule_test/src/sched.sch b/juno_samples/schedule_test/src/sched.sch
index 155240248986ea07e32b21b54c209b9782367b33..960dca22481e06f7aaf3875477bc6ed5595159e7 100644
--- a/juno_samples/schedule_test/src/sched.sch
+++ b/juno_samples/schedule_test/src/sched.sch
@@ -40,5 +40,8 @@ fixpoint panic after 2 {
   phi-elim(*);
 }
 
+host(*);
+cpu(first, second);
+
 codegen-prep!(*);
 //xdot[true](*);
diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs
index beaf73e3da5691239a9c36dde45a2d4f593e253f..452c1995ee313e77d787ba7b769788c6e67b1271 100644
--- a/juno_scheduler/src/pm.rs
+++ b/juno_scheduler/src/pm.rs
@@ -668,9 +668,12 @@ fn schedule_interpret(
             }
         },
         ScheduleStmt::AddDevice { device, on } => match on {
-            Selector::Everything() => Err(SchedulerError::SemanticError(
-                "Cannot apply device to everything".to_string(),
-            )),
+            Selector::Everything() => {
+                for func in pm.functions.iter_mut() {
+                    func.device = Some(device.clone());
+                }
+                Ok(false)
+            }
             Selector::Selection(selection) => {
                 let mut changed = false;
                 for func in selection {
@@ -899,6 +902,39 @@ fn construct_selection(pm: &PassManager, selection: Vec<CodeLocation>) -> Vec<Fu
     selected
 }
 
+// Given a selection, constructs the set of functions which are selected (and each must be selected
+// fully)
+fn selection_of_functions(
+    pm: &PassManager,
+    selection: Option<Vec<CodeLocation>>,
+) -> Option<Vec<FunctionID>> {
+    if let Some(selection) = selection {
+        let selection = construct_selection(pm, selection);
+
+        let mut result = vec![];
+
+        for (idx, selected) in selection.into_iter().enumerate() {
+            match selected {
+                FunctionSelection::Nothing() => {}
+                FunctionSelection::Everything() => result.push(FunctionID::new(idx)),
+                FunctionSelection::Labels(_) => {
+                    return None;
+                }
+            }
+        }
+
+        Some(result)
+    } else {
+        Some(
+            pm.functions
+                .iter()
+                .enumerate()
+                .map(|(i, _)| FunctionID::new(i))
+                .collect(),
+        )
+    }
+}
+
 // Given a selection, constructs the set of the nodes selected for a single function, returning the
 // function's id
 fn selection_as_set(
@@ -1006,35 +1042,29 @@ fn run_pass(
 
     match pass {
         Pass::AutoOutline => {
-            if let Some(_) = selection {
+            let Some(funcs) = selection_of_functions(pm, selection) else {
                 return Err(SchedulerError::PassError {
                     pass: "autoOutline".to_string(),
-                    error: "must be applied to the entire module".to_string(),
+                    error: "must be applied to whole functions".to_string(),
                 });
-            }
+            };
 
             pm.make_def_uses();
             let def_uses = pm.def_uses.take().unwrap();
-            let mut editors: Vec<_> = pm
-                .functions
-                .iter_mut()
-                .zip(def_uses.iter())
-                .enumerate()
-                .map(|(idx, (func, def_use))| {
-                    FunctionEditor::new(
-                        func,
-                        FunctionID::new(idx),
-                        &pm.constants,
-                        &pm.dynamic_constants,
-                        &pm.types,
-                        &pm.labels,
-                        def_use,
-                    )
-                })
-                .collect();
-            for editor in editors.iter_mut() {
-                collapse_returns(editor);
-                ensure_between_control_flow(editor);
+
+            for func in funcs.iter() {
+                let mut editor = FunctionEditor::new(
+                    &mut pm.functions[func.idx()],
+                    *func,
+                    &pm.constants,
+                    &pm.dynamic_constants,
+                    &pm.types,
+                    &pm.labels,
+                    &def_uses[func.idx()],
+                );
+                collapse_returns(&mut editor);
+                ensure_between_control_flow(&mut editor);
+                changed |= editor.modified();
             }
             pm.clear_analyses();
 
@@ -1049,51 +1079,49 @@ fn run_pass(
             let doms = pm.doms.take().unwrap();
             let old_num_funcs = pm.functions.len();
 
-            let mut editors: Vec<_> = pm
-                .functions
-                .iter_mut()
-                .zip(def_uses.iter())
-                .enumerate()
-                .map(|(idx, (func, def_use))| {
-                    FunctionEditor::new(
-                        func,
-                        FunctionID::new(idx),
-                        &pm.constants,
-                        &pm.dynamic_constants,
-                        &pm.types,
-                        &pm.labels,
-                        def_use,
-                    )
-                })
-                .collect();
-
             let mut new_funcs = vec![];
-            for (idx, editor) in editors.iter_mut().enumerate() {
+            // Track the names of the old functions and the new function IDs for returning
+            let mut new_func_ids = HashMap::new();
+
+            for func in funcs {
+                let mut editor = FunctionEditor::new(
+                    &mut pm.functions[func.idx()],
+                    func,
+                    &pm.constants,
+                    &pm.dynamic_constants,
+                    &pm.types,
+                    &pm.labels,
+                    &def_uses[func.idx()],
+                );
+
                 let new_func_id = FunctionID::new(old_num_funcs + new_funcs.len());
+
                 let new_func = dumb_outline(
-                    editor,
-                    &typing[idx],
-                    &control_subgraphs[idx],
-                    &doms[idx],
+                    &mut editor,
+                    &typing[func.idx()],
+                    &control_subgraphs[func.idx()],
+                    &doms[func.idx()],
                     new_func_id,
                 );
+                changed |= editor.modified();
+
                 if let Some(new_func) = new_func {
-                    let Value::Record { ref mut fields } = result else {
-                        panic!("AutoOutline produces a record");
-                    };
-                    fields.insert(
-                        new_func.name.clone(),
+                    new_func_ids.insert(
+                        editor.func().name.clone(),
                         Value::HerculesFunction { func: new_func_id },
                     );
                     new_funcs.push(new_func);
                 }
-            }
 
-            for func in pm.functions.iter_mut() {
-                func.delete_gravestones();
+                pm.functions[func.idx()].delete_gravestones();
             }
+
             pm.functions.extend(new_funcs);
             pm.clear_analyses();
+
+            result = Value::Record {
+                fields: new_func_ids,
+            };
         }
         Pass::CCP => {
             assert!(args.is_empty());