From ca900d6bf88281f944c04f8bf7d82c4004518f87 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 11 Apr 2017 12:14:33 -0700 Subject: [PATCH] Return the whole value list from detach_ebb_args(). Rather than returning the head of a linked list of EBB arguments, just return the whole value list of all the arguments. Delete the next_ebb_arg() method which was only used for traversing that list. --- lib/cretonne/src/ir/dfg.rs | 42 ++++++-------------------- lib/cretonne/src/legalizer/boundary.rs | 8 ++--- 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/lib/cretonne/src/ir/dfg.rs b/lib/cretonne/src/ir/dfg.rs index ffa842e5a5..45485d63e2 100644 --- a/lib/cretonne/src/ir/dfg.rs +++ b/lib/cretonne/src/ir/dfg.rs @@ -751,10 +751,7 @@ impl DataFlowGraph { self.ebbs[ebb].first_arg = new_arg.into(); } else { // We need to find the num-1 argument value and change its next link. - let mut arg = self.ebbs[ebb].first_arg.expect("EBB has no arguments"); - for _ in 1..num { - arg = self.next_ebb_arg(arg).expect("Too few EBB arguments"); - } + let arg = self.ebbs[ebb].args.as_slice(&self.value_lists)[(num - 1) as usize]; if let ExpandedValue::Table(index) = arg.expand() { if let ValueData::Arg { ref mut next, .. } = self.extended_values[index] { assert_eq!(next.expand(), Some(old_arg)); @@ -770,31 +767,15 @@ impl DataFlowGraph { new_arg } - /// Given a value that is known to be an EBB argument, return the next EBB argument. - pub fn next_ebb_arg(&self, arg: Value) -> Option { - if let ExpandedValue::Table(index) = arg.expand() { - if let ValueData::Arg { next, .. } = self.extended_values[index] { - return next.into(); - } - } - panic!("{} is not an EBB argument", arg); - } - - /// Detach all the arguments from `ebb` and return the first one. - /// - /// The whole list of detached arguments can be traversed with `next_ebb_arg`. This method does - /// not return a `Values` iterator since it is often necessary to mutate the DFG while - /// processing the list of arguments. + /// Detach all the arguments from `ebb` and return them as a `ValueList`. /// /// This is a quite low-level operation. Sensible things to do with the detached EBB arguments /// is to put them back on the same EBB with `attach_ebb_arg()` or change them into aliases /// with `change_to_alias()`. - pub fn detach_ebb_args(&mut self, ebb: Ebb) -> Option { - let first = self.ebbs[ebb].first_arg.into(); + pub fn detach_ebb_args(&mut self, ebb: Ebb) -> ValueList { self.ebbs[ebb].first_arg = None.into(); self.ebbs[ebb].last_arg = None.into(); - self.ebbs[ebb].args.clear(&mut self.value_lists); - first + self.ebbs[ebb].args.take() } /// Append an existing argument value to `ebb`. @@ -962,7 +943,7 @@ mod tests { assert_eq!(ebb.to_string(), "ebb0"); assert_eq!(dfg.num_ebb_args(ebb), 0); assert_eq!(dfg.ebb_args(ebb), &[]); - assert_eq!(dfg.detach_ebb_args(ebb), None); + assert!(dfg.detach_ebb_args(ebb).is_empty()); assert_eq!(dfg.num_ebb_args(ebb), 0); assert_eq!(dfg.ebb_args(ebb), &[]); @@ -982,17 +963,14 @@ mod tests { assert_eq!(dfg.value_type(arg2), types::I16); // Swap the two EBB arguments. - let take1 = dfg.detach_ebb_args(ebb).unwrap(); + let vlist = dfg.detach_ebb_args(ebb); assert_eq!(dfg.num_ebb_args(ebb), 0); assert_eq!(dfg.ebb_args(ebb), &[]); - let take2 = dfg.next_ebb_arg(take1).unwrap(); - assert_eq!(take1, arg1); - assert_eq!(take2, arg2); - assert_eq!(dfg.next_ebb_arg(take2), None); - dfg.attach_ebb_arg(ebb, take2); + assert_eq!(vlist.as_slice(&dfg.value_lists), &[arg1, arg2]); + dfg.attach_ebb_arg(ebb, arg2); let arg3 = dfg.append_ebb_arg(ebb, types::I32); - dfg.attach_ebb_arg(ebb, take1); - assert_eq!(dfg.ebb_args(ebb), &[take2, arg3, take1]); + dfg.attach_ebb_arg(ebb, arg1); + assert_eq!(dfg.ebb_args(ebb), &[arg2, arg3, arg1]); } #[test] diff --git a/lib/cretonne/src/legalizer/boundary.rs b/lib/cretonne/src/legalizer/boundary.rs index 19e06b7ba4..42386cab83 100644 --- a/lib/cretonne/src/legalizer/boundary.rs +++ b/lib/cretonne/src/legalizer/boundary.rs @@ -63,10 +63,10 @@ fn legalize_entry_arguments(func: &mut Function, entry: Ebb) { // Process the EBB arguments one at a time, possibly replacing one argument with multiple new // ones. We do this by detaching the entry EBB arguments first. - let mut next_arg = func.dfg.detach_ebb_args(entry); - while let Some(arg) = next_arg { - // Get the next argument before we mutate `arg`. - next_arg = func.dfg.next_ebb_arg(arg); + let ebb_args = func.dfg.detach_ebb_args(entry); + let mut old_arg = 0; + while let Some(arg) = ebb_args.get(old_arg, &func.dfg.value_lists) { + old_arg += 1; let arg_type = func.dfg.value_type(arg); if arg_type == abi_types[abi_arg].value_type {