diff --git a/.travis.yml b/.travis.yml index 15152f6823..b213bd1010 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,16 @@ addons: install: - pip3 install --user --upgrade mypy flake8 - mypy --version - - travis_wait ./check-rustfmt.sh --install +before_script: + - cargo uninstall rustfmt || true + - cargo install --list + - rustup toolchain install stable + - rustup component add --toolchain=stable rustfmt-preview + - rustup component list --toolchain=stable + - rustup show + - rustfmt +stable --version || echo fail + - rustup update + - rustfmt +stable --version script: ./test-all.sh cache: cargo: true diff --git a/check-rustfmt.sh b/check-rustfmt.sh deleted file mode 100755 index 9a49e8bac5..0000000000 --- a/check-rustfmt.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -set -euo pipefail - -# Usage: check-rustfmt.sh [--install] -# -# Check that the desired version of rustfmt is installed. -# -# Rustfmt is still immature enough that its formatting decisions can change -# between versions. This makes it difficult to enforce a certain style in a -# test script since not all developers will upgrade rustfmt at the same time. -# To work around this, we only verify formatting when a specific version of -# rustfmt is installed. -# -# Exits 0 if the right version of rustfmt is installed, 1 otherwise. -# -# With the --install option, also tries to install the right version. - -# This version should always be bumped to the newest version available that -# works with stable Rust. -# ... but not 0.10.0, since it's the same as 0.9.0 except for a deprecation -# error (and it requires --force to disable the error and enable normal -# operation, however that doesn't appear to be possible through "cargo fmt"). -VERS="0.9.0" - -if cargo install --list | tee /dev/null | grep -q "^rustfmt v$VERS"; then - exit 0 -fi - -if [[ ${1:-""} != "--install" ]]; then - echo "********************************************************************" - echo "* Please install rustfmt v$VERS to verify formatting. *" - echo "* If a newer version of rustfmt is available, update this script. *" - echo "********************************************************************" - echo "$0 --install" - sleep 1 - exit 1 -fi - -echo "Installing rustfmt v$VERS." -cargo install --force --vers="$VERS" rustfmt diff --git a/cranelift/format-all.sh b/cranelift/format-all.sh index a99da7db09..1e27718801 100755 --- a/cranelift/format-all.sh +++ b/cranelift/format-all.sh @@ -8,4 +8,4 @@ cd $(dirname "$0") # Make sure we can find rustfmt. export PATH="$PATH:$HOME/.cargo/bin" -exec cargo fmt --all -- "$@" +exec cargo +stable fmt --all -- "$@" diff --git a/cranelift/src/cat.rs b/cranelift/src/cat.rs index c4890ffb24..a906214730 100644 --- a/cranelift/src/cat.rs +++ b/cranelift/src/cat.rs @@ -18,12 +18,8 @@ pub fn run(files: &[String]) -> CommandResult { } fn cat_one(filename: &str) -> CommandResult { - let buffer = read_to_string(&filename).map_err( - |e| format!("{}: {}", filename, e), - )?; - let items = parse_functions(&buffer).map_err( - |e| format!("{}: {}", filename, e), - )?; + let buffer = read_to_string(&filename).map_err(|e| format!("{}: {}", filename, e))?; + let items = parse_functions(&buffer).map_err(|e| format!("{}: {}", filename, e))?; for (idx, func) in items.into_iter().enumerate() { if idx != 0 { diff --git a/cranelift/src/compile.rs b/cranelift/src/compile.rs index def23bf7de..560c9f3497 100644 --- a/cranelift/src/compile.rs +++ b/cranelift/src/compile.rs @@ -1,10 +1,10 @@ //! CLI tool to read Cretonne IR files and compile them into native code. use capstone::prelude::*; +use cretonne_codegen::Context; use cretonne_codegen::isa::TargetIsa; use cretonne_codegen::print_errors::pretty_error; use cretonne_codegen::settings::FlagsOrIsa; -use cretonne_codegen::Context; use cretonne_codegen::{binemit, ir}; use cretonne_reader::parse_test; use std::path::Path; @@ -80,9 +80,7 @@ fn handle_module( name: &str, fisa: FlagsOrIsa, ) -> Result<(), String> { - let buffer = read_to_string(&path).map_err( - |e| format!("{}: {}", name, e), - )?; + let buffer = read_to_string(&path).map_err(|e| format!("{}: {}", name, e))?; let test_file = parse_test(&buffer).map_err(|e| format!("{}: {}", name, e))?; // If we have an isa from the command-line, use that. Otherwise if the @@ -154,12 +152,10 @@ fn get_disassembler(isa: &TargetIsa) -> Result { } } "arm32" => Capstone::new().arm().mode(arch::arm::ArchMode::Arm).build(), - "arm64" => { - Capstone::new() - .arm64() - .mode(arch::arm64::ArchMode::Arm) - .build() - } + "arm64" => Capstone::new() + .arm64() + .mode(arch::arm64::ArchMode::Arm) + .build(), _ => return Err(String::from("Unknown ISA")), }; diff --git a/cranelift/src/cton-util.rs b/cranelift/src/cton-util.rs index 1ae6991dfb..3723cbecda 100644 --- a/cranelift/src/cton-util.rs +++ b/cranelift/src/cton-util.rs @@ -1,14 +1,8 @@ #![deny(trivial_numeric_casts)] #![warn(unused_import_braces, unstable_features, unused_extern_crates)] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - unicode_not_nfc, - use_self, - ))] +#![cfg_attr(feature = "cargo-clippy", + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, unicode_not_nfc, use_self))] #[macro_use] extern crate cfg_if; @@ -134,9 +128,7 @@ fn cton_util() -> CommandResult { ); #[cfg(not(feature = "wasm"))] - let result = Err( - "Error: cton-util was compiled without wasm support.".to_owned(), - ); + let result = Err("Error: cton-util was compiled without wasm support.".to_owned()); result } else { diff --git a/cranelift/src/print_cfg.rs b/cranelift/src/print_cfg.rs index f078c7ee54..28c8a81100 100644 --- a/cranelift/src/print_cfg.rs +++ b/cranelift/src/print_cfg.rs @@ -19,12 +19,8 @@ pub fn run(files: &[String]) -> CommandResult { } fn print_cfg(filename: &str) -> CommandResult { - let buffer = read_to_string(filename).map_err( - |e| format!("{}: {}", filename, e), - )?; - let items = parse_functions(&buffer).map_err( - |e| format!("{}: {}", filename, e), - )?; + let buffer = read_to_string(filename).map_err(|e| format!("{}: {}", filename, e))?; + let items = parse_functions(&buffer).map_err(|e| format!("{}: {}", filename, e))?; for (idx, func) in items.into_iter().enumerate() { if idx != 0 { diff --git a/cranelift/src/rsfilecheck.rs b/cranelift/src/rsfilecheck.rs index 6269ed226b..b2b1c66ba8 100644 --- a/cranelift/src/rsfilecheck.rs +++ b/cranelift/src/rsfilecheck.rs @@ -22,14 +22,14 @@ pub fn run(files: &[String], verbose: bool) -> CommandResult { } let mut buffer = String::new(); - io::stdin().read_to_string(&mut buffer).map_err(|e| { - format!("stdin: {}", e) - })?; + io::stdin() + .read_to_string(&mut buffer) + .map_err(|e| format!("stdin: {}", e))?; if verbose { - let (success, explain) = checker.explain(&buffer, NO_VARIABLES).map_err( - |e| e.to_string(), - )?; + let (success, explain) = checker + .explain(&buffer, NO_VARIABLES) + .map_err(|e| e.to_string())?; print!("{}", explain); if success { println!("OK"); @@ -37,27 +37,25 @@ pub fn run(files: &[String], verbose: bool) -> CommandResult { } else { Err("Check failed".to_string()) } - } else if checker.check(&buffer, NO_VARIABLES).map_err( - |e| e.to_string(), - )? + } else if checker + .check(&buffer, NO_VARIABLES) + .map_err(|e| e.to_string())? { Ok(()) } else { - let (_, explain) = checker.explain(&buffer, NO_VARIABLES).map_err( - |e| e.to_string(), - )?; + let (_, explain) = checker + .explain(&buffer, NO_VARIABLES) + .map_err(|e| e.to_string())?; print!("{}", explain); Err("Check failed".to_string()) } } fn read_checkfile(filename: &str) -> Result { - let buffer = read_to_string(&filename).map_err( - |e| format!("{}: {}", filename, e), - )?; + let buffer = read_to_string(&filename).map_err(|e| format!("{}: {}", filename, e))?; let mut builder = CheckerBuilder::new(); - builder.text(&buffer).map_err( - |e| format!("{}: {}", filename, e), - )?; + builder + .text(&buffer) + .map_err(|e| format!("{}: {}", filename, e))?; Ok(builder.finish()) } diff --git a/cranelift/test-all.sh b/cranelift/test-all.sh index 2f25e26f33..fcdf7e57c4 100755 --- a/cranelift/test-all.sh +++ b/cranelift/test-all.sh @@ -23,9 +23,19 @@ function banner { } # Run rustfmt if we have it. -if $topdir/check-rustfmt.sh; then - banner "Rust formatting" - $topdir/format-all.sh --write-mode=diff +banner "Rust formatting" +if command -v rustfmt > /dev/null; then + # In newer versions of rustfmt, replace --write-mode=diff with --check. + if ! $topdir/format-all.sh --write-mode=diff ; then + echo "Formatting diffs detected! Run \"cargo fmt --all\" to correct." + exit 1 + fi +else + echo "rustfmt not available; formatting not checked!" + echo + echo "If you are using rustup, rustfmt can be installed via" + echo "\"rustup component add --toolchain=stable rustfmt-preview\", or see" + echo "https://github.com/rust-lang-nursery/rustfmt for more information." fi # Check if any Python files have changed since we last checked them. diff --git a/lib/codegen/build.rs b/lib/codegen/build.rs index 87d4b754ae..7e58b0d012 100644 --- a/lib/codegen/build.rs +++ b/lib/codegen/build.rs @@ -67,9 +67,7 @@ fn main() { .arg("--out-dir") .arg(out_dir) .status() - .expect( - "Failed to launch second-level build script; is python installed?", - ); + .expect("Failed to launch second-level build script; is python installed?"); if !status.success() { process::exit(status.code().unwrap()); } @@ -132,16 +130,14 @@ impl Isa { /// Returns isa targets to configure conditional compilation. fn isa_targets(cretonne_targets: Option<&str>, target_triple: &str) -> Result, String> { match cretonne_targets { - Some("native") => { - Isa::from_arch(target_triple.split('-').next().unwrap()) - .map(|isa| vec![isa]) - .ok_or_else(|| { - format!( - "no supported isa found for target triple `{}`", - target_triple - ) - }) - } + Some("native") => Isa::from_arch(target_triple.split('-').next().unwrap()) + .map(|isa| vec![isa]) + .ok_or_else(|| { + format!( + "no supported isa found for target triple `{}`", + target_triple + ) + }), Some(targets) => { let unknown_isa_targets = targets .split(',') diff --git a/lib/codegen/src/abi.rs b/lib/codegen/src/abi.rs index 5f1452159b..66dcf7f8f1 100644 --- a/lib/codegen/src/abi.rs +++ b/lib/codegen/src/abi.rs @@ -62,16 +62,14 @@ impl ValueConversion { ValueConversion::IntSplit => ty.half_width().expect("Integer type too small to split"), ValueConversion::VectorSplit => ty.half_vector().expect("Not a vector"), ValueConversion::IntBits => Type::int(ty.bits()).expect("Bad integer size"), - ValueConversion::Sext(nty) | - ValueConversion::Uext(nty) => nty, + ValueConversion::Sext(nty) | ValueConversion::Uext(nty) => nty, } } /// Is this a split conversion that results in two arguments? pub fn is_split(self) -> bool { match self { - ValueConversion::IntSplit | - ValueConversion::VectorSplit => true, + ValueConversion::IntSplit | ValueConversion::VectorSplit => true, _ => false, } } diff --git a/lib/codegen/src/bforest/map.rs b/lib/codegen/src/bforest/map.rs index 7cfa824a43..270d186230 100644 --- a/lib/codegen/src/bforest/map.rs +++ b/lib/codegen/src/bforest/map.rs @@ -2,9 +2,9 @@ use super::{Comparator, Forest, Node, NodeData, NodePool, Path, INNER_SIZE}; use packed_option::PackedOption; -use std::marker::PhantomData; #[cfg(test)] use std::fmt; +use std::marker::PhantomData; #[cfg(test)] use std::string::String; @@ -50,7 +50,9 @@ where { /// Create a new empty forest. pub fn new() -> Self { - Self { nodes: NodePool::new() } + Self { + nodes: NodePool::new(), + } } /// Clear all maps in the forest. @@ -101,9 +103,9 @@ where /// Get the value stored for `key`. pub fn get(&self, key: K, forest: &MapForest, comp: &C) -> Option { - self.root.expand().and_then(|root| { - Path::default().find(key, root, &forest.nodes, comp) - }) + self.root + .expand() + .and_then(|root| Path::default().find(key, root, &forest.nodes, comp)) } /// Look up the value stored for `key`. @@ -292,30 +294,30 @@ where /// /// If the cursor is already pointing at the first entry, leave it there and return `None`. pub fn prev(&mut self) -> Option<(K, V)> { - self.root.expand().and_then( - |root| self.path.prev(root, self.pool), - ) + self.root + .expand() + .and_then(|root| self.path.prev(root, self.pool)) } /// Get the current key, or `None` if the cursor is at the end. pub fn key(&self) -> Option { - self.path.leaf_pos().and_then(|(node, entry)| { - self.pool[node].unwrap_leaf().0.get(entry).cloned() - }) + self.path + .leaf_pos() + .and_then(|(node, entry)| self.pool[node].unwrap_leaf().0.get(entry).cloned()) } /// Get the current value, or `None` if the cursor is at the end. pub fn value(&self) -> Option { - self.path.leaf_pos().and_then(|(node, entry)| { - self.pool[node].unwrap_leaf().1.get(entry).cloned() - }) + self.path + .leaf_pos() + .and_then(|(node, entry)| self.pool[node].unwrap_leaf().1.get(entry).cloned()) } /// Get a mutable reference to the current value, or `None` if the cursor is at the end. pub fn value_mut(&mut self) -> Option<&mut V> { - self.path.leaf_pos().and_then(move |(node, entry)| { - self.pool[node].unwrap_leaf_mut().1.get_mut(entry) - }) + self.path + .leaf_pos() + .and_then(move |(node, entry)| self.pool[node].unwrap_leaf_mut().1.get_mut(entry)) } /// Move this cursor to `key`. diff --git a/lib/codegen/src/bforest/node.rs b/lib/codegen/src/bforest/node.rs index d47a16283b..b529816afb 100644 --- a/lib/codegen/src/bforest/node.rs +++ b/lib/codegen/src/bforest/node.rs @@ -362,16 +362,18 @@ impl NodeData { /// right sibling node is returned. pub fn balance(&mut self, crit_key: F::Key, rhs: &mut Self) -> Option { match (self, rhs) { - (&mut NodeData::Inner { - size: ref mut l_size, - keys: ref mut l_keys, - tree: ref mut l_tree, - }, - &mut NodeData::Inner { - size: ref mut r_size, - keys: ref mut r_keys, - tree: ref mut r_tree, - }) => { + ( + &mut NodeData::Inner { + size: ref mut l_size, + keys: ref mut l_keys, + tree: ref mut l_tree, + }, + &mut NodeData::Inner { + size: ref mut r_size, + keys: ref mut r_keys, + tree: ref mut r_tree, + }, + ) => { let l_ents = usize::from(*l_size) + 1; let r_ents = usize::from(*r_size) + 1; let ents = l_ents + r_ents; @@ -408,16 +410,18 @@ impl NodeData { Some(new_crit) } } - (&mut NodeData::Leaf { - size: ref mut l_size, - keys: ref mut l_keys, - vals: ref mut l_vals, - }, - &mut NodeData::Leaf { - size: ref mut r_size, - keys: ref mut r_keys, - vals: ref mut r_vals, - }) => { + ( + &mut NodeData::Leaf { + size: ref mut l_size, + keys: ref mut l_keys, + vals: ref mut l_vals, + }, + &mut NodeData::Leaf { + size: ref mut r_size, + keys: ref mut r_keys, + vals: ref mut r_vals, + }, + ) => { let l_ents = usize::from(*l_size); let l_keys = l_keys.borrow_mut(); let l_vals = l_vals.borrow_mut(); @@ -677,11 +681,7 @@ mod test { assert!(leaf.try_leaf_insert(2, 'c', SetValue())); assert_eq!(leaf.to_string(), "[ a b c d ]"); for i in 4..15 { - assert!(leaf.try_leaf_insert( - usize::from(i), - ('a' as u8 + i) as char, - SetValue(), - )); + assert!(leaf.try_leaf_insert(usize::from(i), ('a' as u8 + i) as char, SetValue())); } assert_eq!(leaf.to_string(), "[ a b c d e f g h i j k l m n o ]"); @@ -779,21 +779,13 @@ mod test { fn leaf_balance() { let mut lhs = NodeData::::leaf('a', SetValue()); for i in 1..6 { - assert!(lhs.try_leaf_insert( - usize::from(i), - ('a' as u8 + i) as char, - SetValue(), - )); + assert!(lhs.try_leaf_insert(usize::from(i), ('a' as u8 + i) as char, SetValue())); } assert_eq!(lhs.to_string(), "[ a b c d e f ]"); let mut rhs = NodeData::::leaf('0', SetValue()); for i in 1..8 { - assert!(rhs.try_leaf_insert( - usize::from(i), - ('0' as u8 + i) as char, - SetValue(), - )); + assert!(rhs.try_leaf_insert(usize::from(i), ('0' as u8 + i) as char, SetValue())); } assert_eq!(rhs.to_string(), "[ 0 1 2 3 4 5 6 7 ]"); diff --git a/lib/codegen/src/bforest/path.rs b/lib/codegen/src/bforest/path.rs index 3ed91ee09a..e845c6a9a2 100644 --- a/lib/codegen/src/bforest/path.rs +++ b/lib/codegen/src/bforest/path.rs @@ -303,9 +303,9 @@ impl Path { // When inserting into an inner node (`ins_node.is_some()`), we must point to a valid // entry in the current node since the new entry is inserted *after* the insert // location. - if entry > split.lhs_entries || - (entry == split.lhs_entries && - (split.lhs_entries > split.rhs_entries || ins_node.is_some())) + if entry > split.lhs_entries + || (entry == split.lhs_entries + && (split.lhs_entries > split.rhs_entries || ins_node.is_some())) { node = rhs_node; entry -= split.lhs_entries; @@ -406,7 +406,9 @@ impl Path { let crit_node = self.node[crit_level]; match pool[crit_node] { - NodeData::Inner { size, ref mut keys, .. } => { + NodeData::Inner { + size, ref mut keys, .. + } => { debug_assert!(crit_kidx < size); keys[usize::from(crit_kidx)] = crit_key; } @@ -436,7 +438,10 @@ impl Path { // Discard the root node if it has shrunk to a single sub-tree. let mut ns = 0; - while let NodeData::Inner { size: 0, ref tree, .. } = pool[self.node[ns]] { + while let NodeData::Inner { + size: 0, ref tree, .. + } = pool[self.node[ns]] + { ns += 1; self.node[ns] = tree[0]; } @@ -616,9 +621,8 @@ impl Path { /// Update the critical key for the right sibling node at `level`. fn update_right_crit_key(&self, level: usize, crit_key: F::Key, pool: &mut NodePool) { - let bl = self.right_sibling_branch_level(level, pool).expect( - "No right sibling exists", - ); + let bl = self.right_sibling_branch_level(level, pool) + .expect("No right sibling exists"); match pool[self.node[bl]] { NodeData::Inner { ref mut keys, .. } => { keys[usize::from(self.entry[bl])] = crit_key; diff --git a/lib/codegen/src/bforest/pool.rs b/lib/codegen/src/bforest/pool.rs index d543991312..e6b08e4f1c 100644 --- a/lib/codegen/src/bforest/pool.rs +++ b/lib/codegen/src/bforest/pool.rs @@ -2,9 +2,9 @@ use super::{Forest, Node, NodeData}; use entity::PrimaryMap; -use std::ops::{Index, IndexMut}; #[cfg(test)] use std::fmt; +use std::ops::{Index, IndexMut}; /// A pool of nodes, including a free list. pub(super) struct NodePool { @@ -51,7 +51,9 @@ impl NodePool { pub fn free_node(&mut self, node: Node) { // Quick check for a double free. debug_assert!(!self.nodes[node].is_free(), "{} is already free", node); - self.nodes[node] = NodeData::Free { next: self.freelist }; + self.nodes[node] = NodeData::Free { + next: self.freelist, + }; self.freelist = Some(node); } diff --git a/lib/codegen/src/bforest/set.rs b/lib/codegen/src/bforest/set.rs index 667cd133e2..8371fd3bc6 100644 --- a/lib/codegen/src/bforest/set.rs +++ b/lib/codegen/src/bforest/set.rs @@ -2,9 +2,9 @@ use super::{Comparator, Forest, Node, NodeData, NodePool, Path, SetValue, INNER_SIZE}; use packed_option::PackedOption; -use std::marker::PhantomData; #[cfg(test)] use std::fmt; +use std::marker::PhantomData; #[cfg(test)] use std::string::String; @@ -47,7 +47,9 @@ where { /// Create a new empty forest. pub fn new() -> Self { - Self { nodes: NodePool::new() } + Self { + nodes: NodePool::new(), + } } /// Clear all sets in the forest. @@ -232,16 +234,16 @@ where /// /// If the cursor is already pointing at the first element, leave it there and return `None`. pub fn prev(&mut self) -> Option { - self.root.expand().and_then(|root| { - self.path.prev(root, self.pool).map(|(k, _)| k) - }) + self.root + .expand() + .and_then(|root| self.path.prev(root, self.pool).map(|(k, _)| k)) } /// Get the current element, or `None` if the cursor is at the end. pub fn elem(&self) -> Option { - self.path.leaf_pos().and_then(|(node, entry)| { - self.pool[node].unwrap_leaf().0.get(entry).cloned() - }) + self.path + .leaf_pos() + .and_then(|(node, entry)| self.pool[node].unwrap_leaf().0.get(entry).cloned()) } /// Move this cursor to `elem`. diff --git a/lib/codegen/src/binemit/mod.rs b/lib/codegen/src/binemit/mod.rs index 653e38c9ed..4a95ed4eb7 100644 --- a/lib/codegen/src/binemit/mod.rs +++ b/lib/codegen/src/binemit/mod.rs @@ -7,7 +7,7 @@ mod memorysink; mod relaxation; mod shrink; -pub use self::memorysink::{MemoryCodeSink, RelocSink, TrapSink, NullTrapSink}; +pub use self::memorysink::{MemoryCodeSink, NullTrapSink, RelocSink, TrapSink}; pub use self::relaxation::relax_branches; pub use self::shrink::shrink_instructions; pub use regalloc::RegDiversions; diff --git a/lib/codegen/src/binemit/relaxation.rs b/lib/codegen/src/binemit/relaxation.rs index 93c6afedec..7003df1eb0 100644 --- a/lib/codegen/src/binemit/relaxation.rs +++ b/lib/codegen/src/binemit/relaxation.rs @@ -78,8 +78,8 @@ pub fn relax_branches(func: &mut Function, isa: &TargetIsa) -> Result(4 | 8 | 256 | 1024); assert!( - !s4.contains(0) && !s4.contains(1) && !s4.contains(4) && !s4.contains(5) && - !s4.contains(6) && !s4.contains(7) && !s4.contains(9) && !s4.contains(11) + !s4.contains(0) && !s4.contains(1) && !s4.contains(4) && !s4.contains(5) + && !s4.contains(6) && !s4.contains(7) && !s4.contains(9) + && !s4.contains(11) ); assert!(s4.contains(2) && s4.contains(3) && s4.contains(8) && s4.contains(10)); } diff --git a/lib/codegen/src/context.rs b/lib/codegen/src/context.rs index b383160703..b9f7511865 100644 --- a/lib/codegen/src/context.rs +++ b/lib/codegen/src/context.rs @@ -24,8 +24,8 @@ use preopt::do_preopt; use regalloc; use result::{CtonError, CtonResult}; use settings::{FlagsOrIsa, OptLevel}; -use std::vec::Vec; use simple_gvn::do_simple_gvn; +use std::vec::Vec; use timing; use unreachable_code::eliminate_unreachable_code; use verifier; @@ -251,11 +251,8 @@ impl Context { /// Compute the loop analysis. pub fn compute_loop_analysis(&mut self) { - self.loop_analysis.compute( - &self.func, - &self.cfg, - &self.domtree, - ) + self.loop_analysis + .compute(&self.func, &self.cfg, &self.domtree) } /// Compute the control flow graph and dominator tree. @@ -292,12 +289,8 @@ impl Context { /// Run the register allocator. pub fn regalloc(&mut self, isa: &TargetIsa) -> CtonResult { - self.regalloc.run( - isa, - &mut self.func, - &self.cfg, - &mut self.domtree, - ) + self.regalloc + .run(isa, &mut self.func, &self.cfg, &mut self.domtree) } /// Insert prologue and epilogues after computing the stack frame layout. diff --git a/lib/codegen/src/cursor.rs b/lib/codegen/src/cursor.rs index 6842d8b348..e905545675 100644 --- a/lib/codegen/src/cursor.rs +++ b/lib/codegen/src/cursor.rs @@ -246,9 +246,11 @@ pub trait Cursor { let new_pos = if let Some(next) = self.layout().next_inst(inst) { CursorPosition::At(next) } else { - CursorPosition::After(self.layout().inst_ebb(inst).expect( - "current instruction removed?", - )) + CursorPosition::After( + self.layout() + .inst_ebb(inst) + .expect("current instruction removed?"), + ) }; self.set_position(new_pos); } @@ -413,9 +415,11 @@ pub trait Cursor { self.set_position(At(next)); Some(next) } else { - let pos = After(self.layout().inst_ebb(inst).expect( - "current instruction removed?", - )); + let pos = After( + self.layout() + .inst_ebb(inst) + .expect("current instruction removed?"), + ); self.set_position(pos); None } @@ -465,9 +469,11 @@ pub trait Cursor { self.set_position(At(prev)); Some(prev) } else { - let pos = Before(self.layout().inst_ebb(inst).expect( - "current instruction removed?", - )); + let pos = Before( + self.layout() + .inst_ebb(inst) + .expect("current instruction removed?"), + ); self.set_position(pos); None } @@ -746,11 +752,9 @@ impl<'c, 'f> ir::InstInserterBase<'c> for &'c mut EncCursor<'f> { // Assign an encoding. // XXX Is there a way to describe this error to the user? #[cfg_attr(feature = "cargo-clippy", allow(match_wild_err_arm))] - match self.isa.encode( - &self.func, - &self.func.dfg[inst], - ctrl_typevar, - ) { + match self.isa + .encode(&self.func, &self.func.dfg[inst], ctrl_typevar) + { Ok(e) => self.func.encodings[inst] = e, Err(_) => panic!("can't encode {}", self.display_inst(inst)), } diff --git a/lib/codegen/src/dbg.rs b/lib/codegen/src/dbg.rs index 8dd47f625d..e1f62198f8 100644 --- a/lib/codegen/src/dbg.rs +++ b/lib/codegen/src/dbg.rs @@ -126,7 +126,7 @@ macro_rules! dbg { #[cfg(not(feature = "std"))] #[macro_export] macro_rules! dbg { - ($($arg:tt)+) => {} + ($($arg:tt)+) => {}; } /// Helper for printing lists. diff --git a/lib/codegen/src/dce.rs b/lib/codegen/src/dce.rs index 895b922dd7..797e905c6d 100644 --- a/lib/codegen/src/dce.rs +++ b/lib/codegen/src/dce.rs @@ -13,9 +13,8 @@ use timing; /// Test whether the given opcode is unsafe to even consider for DCE. fn trivially_unsafe_for_dce(opcode: Opcode) -> bool { - opcode.is_call() || opcode.is_branch() || opcode.is_terminator() || - opcode.is_return() || opcode.can_trap() || opcode.other_side_effects() || - opcode.can_store() + opcode.is_call() || opcode.is_branch() || opcode.is_terminator() || opcode.is_return() + || opcode.can_trap() || opcode.other_side_effects() || opcode.can_store() } /// Preserve instructions with used result values. @@ -51,9 +50,8 @@ pub fn do_dce(func: &mut Function, domtree: &mut DominatorTree) { { let data = &pos.func.dfg[inst]; let opcode = data.opcode(); - if trivially_unsafe_for_dce(opcode) || - is_load_with_defined_trapping(opcode, &data) || - any_inst_results_used(inst, &live, &pos.func.dfg) + if trivially_unsafe_for_dce(opcode) || is_load_with_defined_trapping(opcode, &data) + || any_inst_results_used(inst, &live, &pos.func.dfg) { for arg in pos.func.dfg.inst_args(inst) { let v = pos.func.dfg.resolve_aliases(*arg); diff --git a/lib/codegen/src/divconst_magic_numbers.rs b/lib/codegen/src/divconst_magic_numbers.rs index 8a848711a4..a56ed730d4 100644 --- a/lib/codegen/src/divconst_magic_numbers.rs +++ b/lib/codegen/src/divconst_magic_numbers.rs @@ -167,10 +167,10 @@ pub fn magicS32(d: i32) -> MS32 { MS32 { mulBy: (if d < 0 { - u32::wrapping_neg(q2 + 1) - } else { - q2 + 1 - }) as i32, + u32::wrapping_neg(q2 + 1) + } else { + q2 + 1 + }) as i32, shiftBy: p - 32, } } @@ -210,10 +210,10 @@ pub fn magicS64(d: i64) -> MS64 { MS64 { mulBy: (if d < 0 { - u64::wrapping_neg(q2 + 1) - } else { - q2 + 1 - }) as i64, + u64::wrapping_neg(q2 + 1) + } else { + q2 + 1 + }) as i64, shiftBy: p - 64, } } diff --git a/lib/codegen/src/dominator_tree.rs b/lib/codegen/src/dominator_tree.rs index 0e48ce8d81..c8dec582aa 100644 --- a/lib/codegen/src/dominator_tree.rs +++ b/lib/codegen/src/dominator_tree.rs @@ -101,9 +101,8 @@ impl DominatorTree { { let a = a.into(); let b = b.into(); - self.rpo_cmp_ebb(layout.pp_ebb(a), layout.pp_ebb(b)).then( - layout.cmp(a, b), - ) + self.rpo_cmp_ebb(layout.pp_ebb(a), layout.pp_ebb(b)) + .then(layout.cmp(a, b)) } /// Returns `true` if `a` dominates `b`. @@ -145,9 +144,7 @@ impl DominatorTree { let (mut ebb_b, mut inst_b) = match b.into() { ExpandedProgramPoint::Ebb(ebb) => (ebb, None), ExpandedProgramPoint::Inst(inst) => ( - layout.inst_ebb(inst).expect( - "Instruction not in layout.", - ), + layout.inst_ebb(inst).expect("Instruction not in layout."), Some(inst), ), }; @@ -163,7 +160,11 @@ impl DominatorTree { ebb_b = layout.inst_ebb(idom).expect("Dominator got removed."); inst_b = Some(idom); } - if a == ebb_b { inst_b } else { None } + if a == ebb_b { + inst_b + } else { + None + } } /// Compute the common dominator of two basic blocks. @@ -418,14 +419,13 @@ impl DominatorTree { // Get an iterator with just the reachable, already visited predecessors to `ebb`. // Note that during the first pass, `rpo_number` is 1 for reachable blocks that haven't // been visited yet, 0 for unreachable blocks. - let mut reachable_preds = cfg.pred_iter(ebb).filter(|&(pred, _)| { - self.nodes[pred].rpo_number > 1 - }); + let mut reachable_preds = cfg.pred_iter(ebb) + .filter(|&(pred, _)| self.nodes[pred].rpo_number > 1); // The RPO must visit at least one predecessor before this node. - let mut idom = reachable_preds.next().expect( - "EBB node must have one reachable predecessor", - ); + let mut idom = reachable_preds + .next() + .expect("EBB node must have one reachable predecessor"); for pred in reachable_preds { idom = self.common_dominator(idom, pred, layout); @@ -450,11 +450,10 @@ impl DominatorTree { } // We use the RPO comparison on the postorder list so we invert the operands of the // comparison - let old_ebb_postorder_index = - self.postorder - .as_slice() - .binary_search_by(|probe| self.rpo_cmp_ebb(old_ebb, *probe)) - .expect("the old ebb is not declared to the dominator tree"); + let old_ebb_postorder_index = self.postorder + .as_slice() + .binary_search_by(|probe| self.rpo_cmp_ebb(old_ebb, *probe)) + .expect("the old ebb is not declared to the dominator tree"); let new_ebb_rpo = self.insert_after_rpo(old_ebb, old_ebb_postorder_index, new_ebb); self.nodes[new_ebb] = DomNode { rpo_number: new_ebb_rpo, @@ -471,11 +470,10 @@ impl DominatorTree { // If there is no gaps in RPo numbers to insert this new number, we iterate // forward in RPO numbers and backwards in the postorder list of EBBs, renumbering the Ebbs // until we find a gap - for (¤t_ebb, current_rpo) in - self.postorder[0..ebb_postorder_index].iter().rev().zip( - inserted_rpo_number + - 1.., - ) + for (¤t_ebb, current_rpo) in self.postorder[0..ebb_postorder_index] + .iter() + .rev() + .zip(inserted_rpo_number + 1..) { if self.nodes[current_ebb].rpo_number < current_rpo { // There is no gap, we renumber @@ -644,9 +642,8 @@ impl DominatorTreePreorder { { let a = a.into(); let b = b.into(); - self.pre_cmp_ebb(layout.pp_ebb(a), layout.pp_ebb(b)).then( - layout.cmp(a, b), - ) + self.pre_cmp_ebb(layout.pp_ebb(a), layout.pp_ebb(b)) + .then(layout.cmp(a, b)) } /// Compare two value defs according to the dominator tree pre-order. @@ -658,9 +655,8 @@ impl DominatorTreePreorder { pub fn pre_cmp_def(&self, a: Value, b: Value, func: &Function) -> Ordering { let da = func.dfg.value_def(a); let db = func.dfg.value_def(b); - self.pre_cmp(da, db, &func.layout).then_with( - || da.num().cmp(&db.num()), - ) + self.pre_cmp(da, db, &func.layout) + .then_with(|| da.num().cmp(&db.num())) } } diff --git a/lib/codegen/src/flowgraph.rs b/lib/codegen/src/flowgraph.rs index 66f377ce35..a954b73ac1 100644 --- a/lib/codegen/src/flowgraph.rs +++ b/lib/codegen/src/flowgraph.rs @@ -128,10 +128,9 @@ impl ControlFlowGraph { // our iteration over successors. let mut successors = mem::replace(&mut self.data[ebb].successors, Default::default()); for succ in successors.iter(&self.succ_forest) { - self.data[succ].predecessors.retain( - &mut self.pred_forest, - |_, &mut e| e != ebb, - ); + self.data[succ] + .predecessors + .retain(&mut self.pred_forest, |_, &mut e| e != ebb); } successors.clear(&mut self.succ_forest); } @@ -149,17 +148,12 @@ impl ControlFlowGraph { } fn add_edge(&mut self, from: BasicBlock, to: Ebb) { - self.data[from.0].successors.insert( - to, - &mut self.succ_forest, - &(), - ); - self.data[to].predecessors.insert( - from.1, - from.0, - &mut self.pred_forest, - &(), - ); + self.data[from.0] + .successors + .insert(to, &mut self.succ_forest, &()); + self.data[to] + .predecessors + .insert(from.1, from.0, &mut self.pred_forest, &()); } /// Get an iterator over the CFG predecessors to `ebb`. diff --git a/lib/codegen/src/ir/dfg.rs b/lib/codegen/src/ir/dfg.rs index c2f07beb25..4fde255e82 100644 --- a/lib/codegen/src/ir/dfg.rs +++ b/lib/codegen/src/ir/dfg.rs @@ -166,9 +166,9 @@ impl DataFlowGraph { /// Get the type of a value. pub fn value_type(&self, v: Value) -> Type { match self.values[v] { - ValueData::Inst { ty, .. } | - ValueData::Param { ty, .. } | - ValueData::Alias { ty, .. } => ty, + ValueData::Inst { ty, .. } + | ValueData::Param { ty, .. } + | ValueData::Alias { ty, .. } => ty, } } @@ -235,11 +235,9 @@ impl DataFlowGraph { // This also avoids the creation of loops. let original = self.resolve_aliases(src); debug_assert_ne!( - dest, - original, + dest, original, "Aliasing {} to {} would create a loop", - dest, - src + dest, src ); let ty = self.value_type(original); debug_assert_eq!( @@ -267,8 +265,7 @@ impl DataFlowGraph { /// pub fn replace_with_aliases(&mut self, dest_inst: Inst, src_inst: Inst) { debug_assert_ne!( - dest_inst, - src_inst, + dest_inst, src_inst, "Replacing {} with itself would create a loop", dest_inst ); @@ -342,8 +339,7 @@ impl ValueDef { /// this value. pub fn num(self) -> usize { match self { - ValueDef::Result(_, n) | - ValueDef::Param(_, n) => n, + ValueDef::Result(_, n) | ValueDef::Param(_, n) => n, } } } @@ -574,9 +570,9 @@ impl DataFlowGraph { /// /// Panics if the instruction doesn't support arguments. pub fn append_inst_arg(&mut self, inst: Inst, new_arg: Value) { - let mut branch_values = self.insts[inst].take_value_list().expect( - "the instruction doesn't have value arguments", - ); + let mut branch_values = self.insts[inst] + .take_value_list() + .expect("the instruction doesn't have value arguments"); branch_values.push(new_arg, &mut self.value_lists); self.insts[inst].put_value_list(branch_values) } @@ -585,9 +581,9 @@ impl DataFlowGraph { /// /// This function panics if the instruction doesn't have any result. pub fn first_result(&self, inst: Inst) -> Value { - self.results[inst].first(&self.value_lists).expect( - "Instruction has no results", - ) + self.results[inst] + .first(&self.value_lists) + .expect("Instruction has no results") } /// Test if `inst` has any result values currently. @@ -653,9 +649,11 @@ impl DataFlowGraph { } else if constraints.requires_typevar_operand() { // Not all instruction formats have a designated operand, but in that case // `requires_typevar_operand()` should never be true. - self.value_type(self[inst].typevar_operand(&self.value_lists).expect( - "Instruction format doesn't have a designated operand, bad opcode.", - )) + self.value_type( + self[inst] + .typevar_operand(&self.value_lists) + .expect("Instruction format doesn't have a designated operand, bad opcode."), + ) } else { self.value_type(self.first_result(inst)) } @@ -721,13 +719,16 @@ impl DataFlowGraph { } else { panic!("{} must be an EBB parameter", val); }; - self.ebbs[ebb].params.swap_remove( - num as usize, - &mut self.value_lists, - ); + self.ebbs[ebb] + .params + .swap_remove(num as usize, &mut self.value_lists); if let Some(last_arg_val) = self.ebbs[ebb].params.get(num as usize, &self.value_lists) { // We update the position of the old last arg. - if let ValueData::Param { num: ref mut old_num, .. } = self.values[last_arg_val] { + if let ValueData::Param { + num: ref mut old_num, + .. + } = self.values[last_arg_val] + { *old_num = num; } else { panic!("{} should be an Ebb parameter", last_arg_val); @@ -744,27 +745,25 @@ impl DataFlowGraph { } else { panic!("{} must be an EBB parameter", val); }; - self.ebbs[ebb].params.remove( - num as usize, - &mut self.value_lists, - ); + self.ebbs[ebb] + .params + .remove(num as usize, &mut self.value_lists); for index in num..(self.num_ebb_params(ebb) as u16) { match self.values[self.ebbs[ebb] - .params - .get(index as usize, &self.value_lists) - .unwrap()] { + .params + .get(index as usize, &self.value_lists) + .unwrap()] + { ValueData::Param { ref mut num, .. } => { *num -= 1; } - _ => { - panic!( - "{} must be an EBB parameter", - self.ebbs[ebb] - .params - .get(index as usize, &self.value_lists) - .unwrap() - ) - } + _ => panic!( + "{} must be an EBB parameter", + self.ebbs[ebb] + .params + .get(index as usize, &self.value_lists) + .unwrap() + ), } } } @@ -835,7 +834,9 @@ struct EbbData { impl EbbData { fn new() -> Self { - Self { params: ValueList::new() } + Self { + params: ValueList::new(), + } } } @@ -878,9 +879,9 @@ impl DataFlowGraph { "this function is only for assigning types to previously invalid values" ); match self.values[v] { - ValueData::Inst { ref mut ty, .. } | - ValueData::Param { ref mut ty, .. } | - ValueData::Alias { ref mut ty, .. } => *ty = t, + ValueData::Inst { ref mut ty, .. } + | ValueData::Param { ref mut ty, .. } + | ValueData::Alias { ref mut ty, .. } => *ty = t, } } diff --git a/lib/codegen/src/ir/entities.rs b/lib/codegen/src/ir/entities.rs index 30c7cd3fb4..73e0984245 100644 --- a/lib/codegen/src/ir/entities.rs +++ b/lib/codegen/src/ir/entities.rs @@ -32,7 +32,11 @@ impl Ebb { /// /// This method is for use by the parser. pub fn with_number(n: u32) -> Option { - if n < u32::MAX { Some(Ebb(n)) } else { None } + if n < u32::MAX { + Some(Ebb(n)) + } else { + None + } } } @@ -124,7 +128,11 @@ impl FuncRef { /// /// This method is for use by the parser. pub fn with_number(n: u32) -> Option { - if n < u32::MAX { Some(FuncRef(n)) } else { None } + if n < u32::MAX { + Some(FuncRef(n)) + } else { + None + } } } @@ -138,7 +146,11 @@ impl SigRef { /// /// This method is for use by the parser. pub fn with_number(n: u32) -> Option { - if n < u32::MAX { Some(SigRef(n)) } else { None } + if n < u32::MAX { + Some(SigRef(n)) + } else { + None + } } } @@ -152,7 +164,11 @@ impl Heap { /// /// This method is for use by the parser. pub fn with_number(n: u32) -> Option { - if n < u32::MAX { Some(Heap(n)) } else { None } + if n < u32::MAX { + Some(Heap(n)) + } else { + None + } } } diff --git a/lib/codegen/src/ir/extfunc.rs b/lib/codegen/src/ir/extfunc.rs index 95f86be8fd..a4abc8bfc4 100644 --- a/lib/codegen/src/ir/extfunc.rs +++ b/lib/codegen/src/ir/extfunc.rs @@ -384,8 +384,7 @@ mod tests { CallConv::SystemV, CallConv::WindowsFastcall, CallConv::Baldrdash, - ] - { + ] { assert_eq!(Ok(cc), cc.to_string().parse()) } } diff --git a/lib/codegen/src/ir/function.rs b/lib/codegen/src/ir/function.rs index 10350c506c..d15e539214 100644 --- a/lib/codegen/src/ir/function.rs +++ b/lib/codegen/src/ir/function.rs @@ -10,7 +10,7 @@ use ir::{DataFlowGraph, ExternalName, Layout, Signature}; use ir::{Ebb, ExtFuncData, FuncRef, GlobalVar, GlobalVarData, Heap, HeapData, JumpTable, JumpTableData, SigRef, StackSlot, StackSlotData}; use ir::{EbbOffsets, InstEncodings, JumpTables, SourceLocs, StackSlots, ValueLocations}; -use isa::{EncInfo, Legalize, TargetIsa, Encoding}; +use isa::{EncInfo, Encoding, Legalize, TargetIsa}; use settings::CallConv; use std::fmt; use write::write_function; @@ -151,9 +151,9 @@ impl Function { /// Returns the value of the last `purpose` parameter, or `None` if no such parameter exists. pub fn special_param(&self, purpose: ir::ArgumentPurpose) -> Option { let entry = self.layout.entry_block().expect("Function is empty"); - self.signature.special_param_index(purpose).map(|i| { - self.dfg.ebb_params(entry)[i] - }) + self.signature + .special_param_index(purpose) + .map(|i| self.dfg.ebb_params(entry)[i]) } /// Get an iterator over the instructions in `ebb`, including offsets and encoded instruction diff --git a/lib/codegen/src/ir/immediates.rs b/lib/codegen/src/ir/immediates.rs index 32b64dabf8..fbc2637d0a 100644 --- a/lib/codegen/src/ir/immediates.rs +++ b/lib/codegen/src/ir/immediates.rs @@ -192,10 +192,12 @@ impl FromStr for Uimm32 { // Parse a decimal or hexadecimal `Uimm32`, formatted as above. fn from_str(s: &str) -> Result { - parse_i64(s).and_then(|x| if 0 <= x && x <= i64::from(u32::MAX) { - Ok(Uimm32(x as u32)) - } else { - Err("Uimm32 out of range") + parse_i64(s).and_then(|x| { + if 0 <= x && x <= i64::from(u32::MAX) { + Ok(Uimm32(x as u32)) + } else { + Err("Uimm32 out of range") + } }) } } @@ -259,12 +261,12 @@ impl FromStr for Offset32 { if !(s.starts_with('-') || s.starts_with('+')) { return Err("Offset must begin with sign"); } - parse_i64(s).and_then(|x| if i64::from(i32::MIN) <= x && - x <= i64::from(i32::MAX) - { - Ok(Self::new(x as i32)) - } else { - Err("Offset out of range") + parse_i64(s).and_then(|x| { + if i64::from(i32::MIN) <= x && x <= i64::from(i32::MAX) { + Ok(Self::new(x as i32)) + } else { + Err("Offset out of range") + } }) } } @@ -447,18 +449,16 @@ fn parse_float(s: &str, w: u8, t: u8) -> Result { Err(_) => return Err("Bad exponent"), } } - _ => { - match ch.to_digit(16) { - Some(digit) => { - digits += 1; - if digits > 16 { - return Err("Too many digits"); - } - significand = (significand << 4) | u64::from(digit); + _ => match ch.to_digit(16) { + Some(digit) => { + digits += 1; + if digits > 16 { + return Err("Too many digits"); } - None => return Err("Invalid character"), + significand = (significand << 4) | u64::from(digit); } - } + None => return Err("Invalid character"), + }, } } @@ -546,9 +546,7 @@ impl Ieee32 { let n = n.into(); debug_assert!(n < 32); debug_assert!(23 + 1 - n < 32); - Self::with_bits( - (1u32 << (32 - 1)) | Self::pow2(n - 1).0 | (1u32 << (23 + 1 - n)), - ) + Self::with_bits((1u32 << (32 - 1)) | Self::pow2(n - 1).0 | (1u32 << (23 + 1 - n))) } /// Return self negated. @@ -609,9 +607,7 @@ impl Ieee64 { let n = n.into(); debug_assert!(n < 64); debug_assert!(52 + 1 - n < 64); - Self::with_bits( - (1u64 << (64 - 1)) | Self::pow2(n - 1).0 | (1u64 << (52 + 1 - n)), - ) + Self::with_bits((1u64 << (64 - 1)) | Self::pow2(n - 1).0 | (1u64 << (52 + 1 - n))) } /// Return self negated. diff --git a/lib/codegen/src/ir/instructions.rs b/lib/codegen/src/ir/instructions.rs index e1db66099b..32b4681b8b 100644 --- a/lib/codegen/src/ir/instructions.rs +++ b/lib/codegen/src/ir/instructions.rs @@ -178,13 +178,13 @@ impl InstructionData { destination, ref args, .. - } | - InstructionData::BranchFloat { + } + | InstructionData::BranchFloat { destination, ref args, .. - } | - InstructionData::Branch { + } + | InstructionData::Branch { destination, ref args, .. @@ -208,11 +208,11 @@ impl InstructionData { /// Multi-destination branches like `br_table` return `None`. pub fn branch_destination(&self) -> Option { match *self { - InstructionData::Jump { destination, .. } | - InstructionData::Branch { destination, .. } | - InstructionData::BranchInt { destination, .. } | - InstructionData::BranchFloat { destination, .. } | - InstructionData::BranchIcmp { destination, .. } => Some(destination), + InstructionData::Jump { destination, .. } + | InstructionData::Branch { destination, .. } + | InstructionData::BranchInt { destination, .. } + | InstructionData::BranchFloat { destination, .. } + | InstructionData::BranchIcmp { destination, .. } => Some(destination), InstructionData::BranchTable { .. } => None, _ => { debug_assert!(!self.opcode().is_branch()); @@ -227,11 +227,26 @@ impl InstructionData { /// Multi-destination branches like `br_table` return `None`. pub fn branch_destination_mut(&mut self) -> Option<&mut Ebb> { match *self { - InstructionData::Jump { ref mut destination, .. } | - InstructionData::Branch { ref mut destination, .. } | - InstructionData::BranchInt { ref mut destination, .. } | - InstructionData::BranchFloat { ref mut destination, .. } | - InstructionData::BranchIcmp { ref mut destination, .. } => Some(destination), + InstructionData::Jump { + ref mut destination, + .. + } + | InstructionData::Branch { + ref mut destination, + .. + } + | InstructionData::BranchInt { + ref mut destination, + .. + } + | InstructionData::BranchFloat { + ref mut destination, + .. + } + | InstructionData::BranchIcmp { + ref mut destination, + .. + } => Some(destination), InstructionData::BranchTable { .. } => None, _ => { debug_assert!(!self.opcode().is_branch()); @@ -245,12 +260,12 @@ impl InstructionData { /// Any instruction that can call another function reveals its call signature here. pub fn analyze_call<'a>(&'a self, pool: &'a ValueListPool) -> CallInfo<'a> { match *self { - InstructionData::Call { func_ref, ref args, .. } => { - CallInfo::Direct(func_ref, args.as_slice(pool)) - } - InstructionData::CallIndirect { sig_ref, ref args, .. } => { - CallInfo::Indirect(sig_ref, &args.as_slice(pool)[1..]) - } + InstructionData::Call { + func_ref, ref args, .. + } => CallInfo::Direct(func_ref, args.as_slice(pool)), + InstructionData::CallIndirect { + sig_ref, ref args, .. + } => CallInfo::Indirect(sig_ref, &args.as_slice(pool)[1..]), _ => { debug_assert!(!self.opcode().is_call()); CallInfo::NotACall @@ -512,12 +527,16 @@ impl OperandConstraint { LaneOf => Bound(ctrl_type.lane_type()), AsBool => Bound(ctrl_type.as_bool()), HalfWidth => Bound(ctrl_type.half_width().expect("invalid type for half_width")), - DoubleWidth => Bound(ctrl_type.double_width().expect( - "invalid type for double_width", - )), - HalfVector => Bound(ctrl_type.half_vector().expect( - "invalid type for half_vector", - )), + DoubleWidth => Bound( + ctrl_type + .double_width() + .expect("invalid type for double_width"), + ), + HalfVector => Bound( + ctrl_type + .half_vector() + .expect("invalid type for half_vector"), + ), DoubleVector => Bound(ctrl_type.by(2).expect("invalid type for double_vector")), } } diff --git a/lib/codegen/src/ir/jumptable.rs b/lib/codegen/src/ir/jumptable.rs index 90b18b1bfe..17706d5959 100644 --- a/lib/codegen/src/ir/jumptable.rs +++ b/lib/codegen/src/ir/jumptable.rs @@ -90,9 +90,9 @@ impl JumpTableData { /// Checks if any of the entries branch to `ebb`. pub fn branches_to(&self, ebb: Ebb) -> bool { - self.table.iter().any(|target_ebb| { - target_ebb.expand() == Some(ebb) - }) + self.table + .iter() + .any(|target_ebb| target_ebb.expand() == Some(ebb)) } /// Access the whole table as a mutable slice. diff --git a/lib/codegen/src/ir/layout.rs b/lib/codegen/src/ir/layout.rs index 2e3ac89903..1e1110a3d8 100644 --- a/lib/codegen/src/ir/layout.rs +++ b/lib/codegen/src/ir/layout.rs @@ -90,7 +90,11 @@ fn midpoint(a: SequenceNumber, b: SequenceNumber) -> Option { debug_assert!(a < b); // Avoid integer overflow. let m = a + (b - a) / 2; - if m > a { Some(m) } else { None } + if m > a { + Some(m) + } else { + None + } } #[test] @@ -178,9 +182,8 @@ impl Layout { /// Assign a valid sequence number to `inst` such that the numbers are still monotonic. This may /// require renumbering. fn assign_inst_seq(&mut self, inst: Inst) { - let ebb = self.inst_ebb(inst).expect( - "inst must be inserted before assigning an seq", - ); + let ebb = self.inst_ebb(inst) + .expect("inst must be inserted before assigning an seq"); // Get the sequence number immediately before `inst`. let prev_seq = match self.insts[inst].prev.expand() { @@ -566,9 +569,8 @@ impl Layout { /// Insert `inst` before the instruction `before` in the same EBB. pub fn insert_inst(&mut self, inst: Inst, before: Inst) { debug_assert_eq!(self.inst_ebb(inst), None); - let ebb = self.inst_ebb(before).expect( - "Instruction before insertion point not in the layout", - ); + let ebb = self.inst_ebb(before) + .expect("Instruction before insertion point not in the layout"); let after = self.insts[before].prev; { let inst_node = &mut self.insts[inst]; @@ -641,9 +643,8 @@ impl Layout { /// i4 /// ``` pub fn split_ebb(&mut self, new_ebb: Ebb, before: Inst) { - let old_ebb = self.inst_ebb(before).expect( - "The `before` instruction must be in the layout", - ); + let old_ebb = self.inst_ebb(before) + .expect("The `before` instruction must be in the layout"); debug_assert!(!self.is_ebb_inserted(new_ebb)); // Insert new_ebb after old_ebb. diff --git a/lib/codegen/src/ir/libcall.rs b/lib/codegen/src/ir/libcall.rs index 8b8e2a0599..26440d4235 100644 --- a/lib/codegen/src/ir/libcall.rs +++ b/lib/codegen/src/ir/libcall.rs @@ -1,9 +1,9 @@ //! Naming well-known routines in the runtime library. -use ir::{types, Opcode, Type, Inst, Function, FuncRef, ExternalName, Signature, AbiParam, - ExtFuncData, ArgumentPurpose}; +use ir::{types, AbiParam, ArgumentPurpose, ExtFuncData, ExternalName, FuncRef, Function, Inst, + Opcode, Signature, Type}; +use isa::{RegUnit, TargetIsa}; use settings::CallConv; -use isa::{TargetIsa, RegUnit}; use std::fmt; use std::str::FromStr; @@ -82,24 +82,20 @@ impl LibCall { /// Returns `None` if no well-known library routine name exists for that instruction. pub fn for_inst(opcode: Opcode, ctrl_type: Type) -> Option { Some(match ctrl_type { - types::F32 => { - match opcode { - Opcode::Ceil => LibCall::CeilF32, - Opcode::Floor => LibCall::FloorF32, - Opcode::Trunc => LibCall::TruncF32, - Opcode::Nearest => LibCall::NearestF32, - _ => return None, - } - } - types::F64 => { - match opcode { - Opcode::Ceil => LibCall::CeilF64, - Opcode::Floor => LibCall::FloorF64, - Opcode::Trunc => LibCall::TruncF64, - Opcode::Nearest => LibCall::NearestF64, - _ => return None, - } - } + types::F32 => match opcode { + Opcode::Ceil => LibCall::CeilF32, + Opcode::Floor => LibCall::FloorF32, + Opcode::Trunc => LibCall::TruncF32, + Opcode::Nearest => LibCall::NearestF32, + _ => return None, + }, + types::F64 => match opcode { + Opcode::Ceil => LibCall::CeilF64, + Opcode::Floor => LibCall::FloorF64, + Opcode::Trunc => LibCall::TruncF64, + Opcode::Nearest => LibCall::NearestF64, + _ => return None, + }, _ => return None, }) } @@ -127,9 +123,8 @@ pub fn get_probestack_funcref( arg_reg: RegUnit, isa: &TargetIsa, ) -> FuncRef { - find_funcref(LibCall::Probestack, func).unwrap_or_else(|| { - make_funcref_for_probestack(func, reg_type, arg_reg, isa) - }) + find_funcref(LibCall::Probestack, func) + .unwrap_or_else(|| make_funcref_for_probestack(func, reg_type, arg_reg, isa)) } /// Get the existing function reference for `libcall` in `func` if it exists. diff --git a/lib/codegen/src/ir/mod.rs b/lib/codegen/src/ir/mod.rs index 3ee7dc9176..daca83cc3a 100644 --- a/lib/codegen/src/ir/mod.rs +++ b/lib/codegen/src/ir/mod.rs @@ -33,7 +33,7 @@ pub use ir::heap::{HeapBase, HeapData, HeapStyle}; pub use ir::instructions::{InstructionData, Opcode, ValueList, ValueListPool, VariableArgs}; pub use ir::jumptable::JumpTableData; pub use ir::layout::Layout; -pub use ir::libcall::{LibCall, get_libcall_funcref, get_probestack_funcref}; +pub use ir::libcall::{get_libcall_funcref, get_probestack_funcref, LibCall}; pub use ir::memflags::MemFlags; pub use ir::progpoint::{ExpandedProgramPoint, ProgramOrder, ProgramPoint}; pub use ir::sourceloc::SourceLoc; diff --git a/lib/codegen/src/ir/valueloc.rs b/lib/codegen/src/ir/valueloc.rs index 7f68e09792..e4762c778f 100644 --- a/lib/codegen/src/ir/valueloc.rs +++ b/lib/codegen/src/ir/valueloc.rs @@ -66,12 +66,10 @@ impl<'a> fmt::Display for DisplayValueLoc<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.0 { ValueLoc::Unassigned => write!(f, "-"), - ValueLoc::Reg(ru) => { - match self.1 { - Some(regs) => write!(f, "{}", regs.display_regunit(ru)), - None => write!(f, "%{}", ru), - } - } + ValueLoc::Reg(ru) => match self.1 { + Some(regs) => write!(f, "{}", regs.display_regunit(ru)), + None => write!(f, "%{}", ru), + }, ValueLoc::Stack(ss) => write!(f, "{}", ss), } } @@ -153,12 +151,10 @@ impl<'a> fmt::Display for DisplayArgumentLoc<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.0 { ArgumentLoc::Unassigned => write!(f, "-"), - ArgumentLoc::Reg(ru) => { - match self.1 { - Some(regs) => write!(f, "{}", regs.display_regunit(ru)), - None => write!(f, "%{}", ru), - } - } + ArgumentLoc::Reg(ru) => match self.1 { + Some(regs) => write!(f, "{}", regs.display_regunit(ru)), + None => write!(f, "%{}", ru), + }, ArgumentLoc::Stack(offset) => write!(f, "{}", offset), } } diff --git a/lib/codegen/src/isa/arm64/abi.rs b/lib/codegen/src/isa/arm64/abi.rs index 4bd9aad7be..79b7a97cd7 100644 --- a/lib/codegen/src/isa/arm64/abi.rs +++ b/lib/codegen/src/isa/arm64/abi.rs @@ -17,7 +17,11 @@ pub fn legalize_signature( /// Get register class for a type appearing in a legalized signature. pub fn regclass_for_abi_type(ty: ir::Type) -> RegClass { - if ty.is_int() { GPR } else { FPR } + if ty.is_int() { + GPR + } else { + FPR + } } /// Get the set of allocatable registers for `func`. diff --git a/lib/codegen/src/isa/constraints.rs b/lib/codegen/src/isa/constraints.rs index b9a4838a9d..7c5da6032d 100644 --- a/lib/codegen/src/isa/constraints.rs +++ b/lib/codegen/src/isa/constraints.rs @@ -30,16 +30,14 @@ impl OperandConstraint { /// counterpart operand has the same value location. pub fn satisfied(&self, loc: ValueLoc) -> bool { match self.kind { - ConstraintKind::Reg | - ConstraintKind::Tied(_) => { + ConstraintKind::Reg | ConstraintKind::Tied(_) => { if let ValueLoc::Reg(reg) = loc { self.regclass.contains(reg) } else { false } } - ConstraintKind::FixedReg(reg) | - ConstraintKind::FixedTied(reg) => { + ConstraintKind::FixedReg(reg) | ConstraintKind::FixedTied(reg) => { loc == ValueLoc::Reg(reg) && self.regclass.contains(reg) } ConstraintKind::Stack => { diff --git a/lib/codegen/src/isa/encoding.rs b/lib/codegen/src/isa/encoding.rs index c13c4de40d..6bb7e30aec 100644 --- a/lib/codegen/src/isa/encoding.rs +++ b/lib/codegen/src/isa/encoding.rs @@ -122,10 +122,9 @@ impl EncInfo { /// /// Returns 0 for illegal encodings. pub fn bytes(&self, enc: Encoding) -> CodeOffset { - self.sizing.get(enc.recipe()).map_or( - 0, - |s| CodeOffset::from(s.bytes), - ) + self.sizing + .get(enc.recipe()) + .map_or(0, |s| CodeOffset::from(s.bytes)) } /// Get the branch range that is supported by `enc`, if any. diff --git a/lib/codegen/src/isa/mod.rs b/lib/codegen/src/isa/mod.rs index 7b21e68d28..d9f4851e68 100644 --- a/lib/codegen/src/isa/mod.rs +++ b/lib/codegen/src/isa/mod.rs @@ -142,11 +142,8 @@ impl settings::Configurable for Builder { /// legalize it? /// /// The `Encodings` iterator returns a legalization function to call. -pub type Legalize = fn(ir::Inst, - &mut ir::Function, - &mut flowgraph::ControlFlowGraph, - &TargetIsa) - -> bool; +pub type Legalize = + fn(ir::Inst, &mut ir::Function, &mut flowgraph::ControlFlowGraph, &TargetIsa) -> bool; /// Methods that are specialized to a target ISA. Implies a Display trait that shows the /// shared flags, as well as any isa-specific flags. diff --git a/lib/codegen/src/isa/registers.rs b/lib/codegen/src/isa/registers.rs index 7defead608..a78dfac60c 100644 --- a/lib/codegen/src/isa/registers.rs +++ b/lib/codegen/src/isa/registers.rs @@ -89,10 +89,12 @@ impl RegBank { None } } - }.and_then(|offset| if offset < self.units { - Some(offset + self.first_unit) - } else { - None + }.and_then(|offset| { + if offset < self.units { + Some(offset + self.first_unit) + } else { + None + } }) } diff --git a/lib/codegen/src/isa/riscv/abi.rs b/lib/codegen/src/isa/riscv/abi.rs index ebc4a67fab..f45dd31426 100644 --- a/lib/codegen/src/isa/riscv/abi.rs +++ b/lib/codegen/src/isa/riscv/abi.rs @@ -117,17 +117,21 @@ pub fn legalize_signature( /// Get register class for a type appearing in a legalized signature. pub fn regclass_for_abi_type(ty: Type) -> RegClass { - if ty.is_float() { FPR } else { GPR } + if ty.is_float() { + FPR + } else { + GPR + } } pub fn allocatable_registers(_func: &ir::Function, isa_flags: &settings::Flags) -> RegisterSet { let mut regs = RegisterSet::new(); regs.take(GPR, GPR.unit(0)); // Hard-wired 0. - // %x1 is the link register which is available for allocation. + // %x1 is the link register which is available for allocation. regs.take(GPR, GPR.unit(2)); // Stack pointer. regs.take(GPR, GPR.unit(3)); // Global pointer. regs.take(GPR, GPR.unit(4)); // Thread pointer. - // TODO: %x8 is the frame pointer. Reserve it? + // TODO: %x8 is the frame pointer. Reserve it? // Remove %x16 and up for RV32E. if isa_flags.enable_e() { diff --git a/lib/codegen/src/isa/stack.rs b/lib/codegen/src/isa/stack.rs index 91df090cb4..eefa523ae3 100644 --- a/lib/codegen/src/isa/stack.rs +++ b/lib/codegen/src/isa/stack.rs @@ -35,9 +35,9 @@ impl StackRef { /// Get a reference to `ss` using the stack pointer as a base. pub fn sp(ss: StackSlot, frame: &StackSlots) -> Self { - let size = frame.frame_size.expect( - "Stack layout must be computed before referencing stack slots", - ); + let size = frame + .frame_size + .expect("Stack layout must be computed before referencing stack slots"); let slot = &frame[ss]; let offset = if slot.kind == StackSlotKind::OutgoingArg { // Outgoing argument slots have offsets relative to our stack pointer. diff --git a/lib/codegen/src/isa/x86/abi.rs b/lib/codegen/src/isa/x86/abi.rs index 15b7d94654..e7511482ca 100644 --- a/lib/codegen/src/isa/x86/abi.rs +++ b/lib/codegen/src/isa/x86/abi.rs @@ -6,8 +6,8 @@ use cursor::{Cursor, CursorPosition, EncCursor}; use ir; use ir::immediates::Imm64; use ir::stackslot::{StackOffset, StackSize}; -use ir::{AbiParam, ArgumentExtension, ArgumentLoc, ArgumentPurpose, InstBuilder, ValueLoc, - get_probestack_funcref}; +use ir::{get_probestack_funcref, AbiParam, ArgumentExtension, ArgumentLoc, ArgumentPurpose, + InstBuilder, ValueLoc}; use isa::{RegClass, RegUnit, TargetIsa}; use regalloc::RegisterSet; use result; @@ -97,7 +97,8 @@ impl ArgAssigner for Args { RU::r14 } else { RU::rsi - } as RegUnit).into() + } as RegUnit) + .into() } // This is SpiderMonkey's `WasmTableCallSigReg`. ArgumentPurpose::SignatureId => return ArgumentLoc::Reg(RU::rbx as RegUnit).into(), @@ -235,8 +236,8 @@ fn callee_saved_gprs_used(flags: &shared_settings::Flags, func: &ir::Function) - for ebb in &func.layout { for inst in func.layout.ebb_insts(ebb) { match func.dfg[inst] { - ir::instructions::InstructionData::RegMove { dst, .. } | - ir::instructions::InstructionData::RegFill { dst, .. } => { + ir::instructions::InstructionData::RegMove { dst, .. } + | ir::instructions::InstructionData::RegFill { dst, .. } => { if !used.is_avail(GPR, dst) { used.free(GPR, dst); } @@ -431,10 +432,8 @@ fn insert_common_prologue( pos.func.locations[fp] = ir::ValueLoc::Reg(RU::rbp as RegUnit); pos.ins().x86_push(fp); - pos.ins().copy_special( - RU::rsp as RegUnit, - RU::rbp as RegUnit, - ); + pos.ins() + .copy_special(RU::rsp as RegUnit, RU::rbp as RegUnit); for reg in csrs.iter(GPR) { // Append param to entry EBB @@ -449,8 +448,8 @@ fn insert_common_prologue( // Allocate stack frame storage. if stack_size > 0 { - if isa.flags().probestack_enabled() && - stack_size > (1 << isa.flags().probestack_size_log2()) + if isa.flags().probestack_enabled() + && stack_size > (1 << isa.flags().probestack_size_log2()) { // Emit a stack probe. let rax = RU::rax as RegUnit; @@ -464,8 +463,8 @@ fn insert_common_prologue( let callee = get_probestack_funcref(pos.func, reg_type, rax, isa); // Make the call. - let call = if !isa.flags().is_pic() && isa.flags().is_64bit() && - !pos.func.dfg.ext_funcs[callee].colocated + let call = if !isa.flags().is_pic() && isa.flags().is_64bit() + && !pos.func.dfg.ext_funcs[callee].colocated { // 64-bit non-PIC non-colocated calls need to be legalized to call_indirect. // Use r11 as it may be clobbered under all supported calling conventions. diff --git a/lib/codegen/src/isa/x86/enc_tables.rs b/lib/codegen/src/isa/x86/enc_tables.rs index 01c9ede2f0..4c964ad802 100644 --- a/lib/codegen/src/isa/x86/enc_tables.rs +++ b/lib/codegen/src/isa/x86/enc_tables.rs @@ -84,11 +84,8 @@ fn expand_sdivrem( // Explicitly check for overflow: Trap when x == INT_MIN. debug_assert!(avoid_div_traps, "Native trapping divide handled above"); let f = pos.ins().ifcmp_imm(x, -1 << (ty.lane_bits() - 1)); - pos.ins().trapif( - IntCC::Equal, - f, - ir::TrapCode::IntegerOverflow, - ); + pos.ins() + .trapif(IntCC::Equal, f, ir::TrapCode::IntegerOverflow); // x / -1 = -x. pos.ins().irsub_imm(x, 0) }; @@ -348,11 +345,8 @@ fn expand_fcvt_to_sint( let mut pos = FuncCursor::new(func).after_inst(inst); pos.use_srcloc(inst); - let is_done = pos.ins().icmp_imm( - IntCC::NotEqual, - result, - 1 << (ty.lane_bits() - 1), - ); + let is_done = pos.ins() + .icmp_imm(IntCC::NotEqual, result, 1 << (ty.lane_bits() - 1)); pos.ins().brnz(is_done, done, &[]); // We now have the following possibilities: @@ -364,10 +358,8 @@ fn expand_fcvt_to_sint( // Check for NaN. let is_nan = pos.ins().fcmp(FloatCC::Unordered, x, x); - pos.ins().trapnz( - is_nan, - ir::TrapCode::BadConversionToInteger, - ); + pos.ins() + .trapnz(is_nan, ir::TrapCode::BadConversionToInteger); // Check for case 1: INT_MIN is the correct result. // Determine the smallest floating point number that would convert to INT_MIN. @@ -376,14 +368,12 @@ fn expand_fcvt_to_sint( let flimit = match xty { // An f32 can represent `i16::min_value() - 1` exactly with precision to spare, so // there are values less than -2^(N-1) that convert correctly to INT_MIN. - ir::types::F32 => { - pos.ins().f32const(if output_bits < 32 { - overflow_cc = FloatCC::LessThanOrEqual; - Ieee32::fcvt_to_sint_negative_overflow(output_bits) - } else { - Ieee32::pow2(output_bits - 1).neg() - }) - } + ir::types::F32 => pos.ins().f32const(if output_bits < 32 { + overflow_cc = FloatCC::LessThanOrEqual; + Ieee32::fcvt_to_sint_negative_overflow(output_bits) + } else { + Ieee32::pow2(output_bits - 1).neg() + }), ir::types::F64 => { // An f64 can represent `i32::min_value() - 1` exactly with precision to spare, so // there are values less than -2^(N-1) that convert correctly to INT_MIN. @@ -458,12 +448,8 @@ fn expand_fcvt_to_uint( _ => panic!("Can't convert {}", xty), }; let is_large = pos.ins().ffcmp(x, pow2nm1); - pos.ins().brff( - FloatCC::GreaterThanOrEqual, - is_large, - large, - &[], - ); + pos.ins() + .brff(FloatCC::GreaterThanOrEqual, is_large, large, &[]); // We need to generate a specific trap code when `x` is NaN, so reuse the flags from the // previous comparison. @@ -476,12 +462,8 @@ fn expand_fcvt_to_uint( // Now we know that x < 2^(N-1) and not NaN. let sres = pos.ins().x86_cvtt2si(ty, x); let is_neg = pos.ins().ifcmp_imm(sres, 0); - pos.ins().brif( - IntCC::SignedGreaterThanOrEqual, - is_neg, - done, - &[sres], - ); + pos.ins() + .brif(IntCC::SignedGreaterThanOrEqual, is_neg, done, &[sres]); pos.ins().trap(ir::TrapCode::IntegerOverflow); // Handle the case where x >= 2^(N-1) and not NaN. @@ -489,11 +471,8 @@ fn expand_fcvt_to_uint( let adjx = pos.ins().fsub(x, pow2nm1); let lres = pos.ins().x86_cvtt2si(ty, adjx); let is_neg = pos.ins().ifcmp_imm(lres, 0); - pos.ins().trapif( - IntCC::SignedLessThan, - is_neg, - ir::TrapCode::IntegerOverflow, - ); + pos.ins() + .trapif(IntCC::SignedLessThan, is_neg, ir::TrapCode::IntegerOverflow); let lfinal = pos.ins().iadd_imm(lres, 1 << (ty.lane_bits() - 1)); // Recycle the original instruction as a jump. diff --git a/lib/codegen/src/iterators.rs b/lib/codegen/src/iterators.rs index 0524343028..220b90da0c 100644 --- a/lib/codegen/src/iterators.rs +++ b/lib/codegen/src/iterators.rs @@ -87,8 +87,7 @@ mod tests { vec![] ); assert_eq!( - [] - .iter() + [].iter() .cloned() .adjacent_pairs() .collect::>(), diff --git a/lib/codegen/src/legalizer/boundary.rs b/lib/codegen/src/legalizer/boundary.rs index 61f07884ca..3c0a198f7f 100644 --- a/lib/codegen/src/legalizer/boundary.rs +++ b/lib/codegen/src/legalizer/boundary.rs @@ -133,8 +133,7 @@ fn legalize_entry_params(func: &mut Function, entry: Ebb) { } // The callee-save parameters should not appear until after register allocation is // done. - ArgumentPurpose::FramePointer | - ArgumentPurpose::CalleeSaved => { + ArgumentPurpose::FramePointer | ArgumentPurpose::CalleeSaved => { panic!("Premature callee-saved arg {}", arg); } // These can be meaningfully added by `legalize_signature()`. @@ -174,9 +173,8 @@ fn legalize_inst_results(pos: &mut FuncCursor, mut get_abi_type: ResTyp where ResType: FnMut(&Function, usize) -> AbiParam, { - let call = pos.current_inst().expect( - "Cursor must point to a call instruction", - ); + let call = pos.current_inst() + .expect("Cursor must point to a call instruction"); // We theoretically allow for call instructions that return a number of fixed results before // the call return values. In practice, it doesn't happen. @@ -377,8 +375,8 @@ fn check_call_signature(dfg: &DataFlowGraph, inst: Inst) -> Result<(), SigRef> { }; let sig = &dfg.signatures[sig_ref]; - if check_arg_types(dfg, args, &sig.params[..]) && - check_arg_types(dfg, dfg.inst_results(inst), &sig.returns[..]) + if check_arg_types(dfg, args, &sig.params[..]) + && check_arg_types(dfg, dfg.inst_results(inst), &sig.returns[..]) { // All types check out. Ok(()) @@ -407,14 +405,13 @@ fn legalize_inst_arguments( ) where ArgType: FnMut(&Function, usize) -> AbiParam, { - let inst = pos.current_inst().expect( - "Cursor must point to a call instruction", - ); + let inst = pos.current_inst() + .expect("Cursor must point to a call instruction"); // Lift the value list out of the call instruction so we modify it. - let mut vlist = pos.func.dfg[inst].take_value_list().expect( - "Call must have a value list", - ); + let mut vlist = pos.func.dfg[inst] + .take_value_list() + .expect("Call must have a value list"); // The value list contains all arguments to the instruction, including the callee on an // indirect call which isn't part of the call arguments that must match the ABI signature. @@ -544,8 +541,8 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph .iter() .rev() .take_while(|&rt| { - rt.purpose == ArgumentPurpose::Link || rt.purpose == ArgumentPurpose::StructReturn || - rt.purpose == ArgumentPurpose::VMContext + rt.purpose == ArgumentPurpose::Link || rt.purpose == ArgumentPurpose::StructReturn + || rt.purpose == ArgumentPurpose::VMContext }) .count(); let abi_args = func.signature.returns.len() - special_args; @@ -570,9 +567,9 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph let mut vlist = pos.func.dfg[inst].take_value_list().unwrap(); for arg in &pos.func.signature.returns[abi_args..] { match arg.purpose { - ArgumentPurpose::Link | - ArgumentPurpose::StructReturn | - ArgumentPurpose::VMContext => {} + ArgumentPurpose::Link + | ArgumentPurpose::StructReturn + | ArgumentPurpose::VMContext => {} ArgumentPurpose::Normal => panic!("unexpected return value {}", arg), _ => panic!("Unsupported special purpose return value {}", arg), } @@ -587,10 +584,9 @@ pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph .expect("No matching special purpose argument."); // Get the corresponding entry block value and add it to the return instruction's // arguments. - let val = pos.func.dfg.ebb_params( - pos.func.layout.entry_block().unwrap(), - ) - [idx]; + let val = pos.func + .dfg + .ebb_params(pos.func.layout.entry_block().unwrap())[idx]; debug_assert_eq!(pos.func.dfg.value_type(val), arg.value_type); vlist.push(val, &mut pos.func.dfg.value_lists); } @@ -630,12 +626,12 @@ fn spill_entry_params(func: &mut Function, entry: Ebb) { /// or calls between writing the stack slots and the call instruction. Writing the slots earlier /// could help reduce register pressure before the call. fn spill_call_arguments(pos: &mut FuncCursor) -> bool { - let inst = pos.current_inst().expect( - "Cursor must point to a call instruction", - ); - let sig_ref = pos.func.dfg.call_signature(inst).expect( - "Call instruction expected.", - ); + let inst = pos.current_inst() + .expect("Cursor must point to a call instruction"); + let sig_ref = pos.func + .dfg + .call_signature(inst) + .expect("Call instruction expected."); // Start by building a list of stack slots and arguments to be replaced. // This requires borrowing `pos.func.dfg`, so we can't change anything. diff --git a/lib/codegen/src/legalizer/call.rs b/lib/codegen/src/legalizer/call.rs index ed499f53f3..d2e0ca542e 100644 --- a/lib/codegen/src/legalizer/call.rs +++ b/lib/codegen/src/legalizer/call.rs @@ -51,10 +51,7 @@ pub fn expand_call( ); } - func.dfg.replace(inst).CallIndirect( - ir::Opcode::CallIndirect, - ptr_ty, - sig, - new_args, - ); + func.dfg + .replace(inst) + .CallIndirect(ir::Opcode::CallIndirect, ptr_ty, sig, new_args); } diff --git a/lib/codegen/src/legalizer/globalvar.rs b/lib/codegen/src/legalizer/globalvar.rs index 9c6e701cf2..d8fd0b94b7 100644 --- a/lib/codegen/src/legalizer/globalvar.rs +++ b/lib/codegen/src/legalizer/globalvar.rs @@ -34,9 +34,8 @@ pub fn expand_global_addr( /// Expand a `global_addr` instruction for a vmctx global. fn vmctx_addr(inst: ir::Inst, func: &mut ir::Function, offset: i64) { // Get the value representing the `vmctx` argument. - let vmctx = func.special_param(ir::ArgumentPurpose::VMContext).expect( - "Missing vmctx parameter", - ); + let vmctx = func.special_param(ir::ArgumentPurpose::VMContext) + .expect("Missing vmctx parameter"); // Simply replace the `global_addr` instruction with an `iadd_imm`, reusing the result value. func.dfg.replace(inst).iadd_imm(vmctx, offset); diff --git a/lib/codegen/src/legalizer/heap.rs b/lib/codegen/src/legalizer/heap.rs index b3a595833f..3b0b5dfd1c 100644 --- a/lib/codegen/src/legalizer/heap.rs +++ b/lib/codegen/src/legalizer/heap.rs @@ -67,30 +67,21 @@ fn dynamic_addr( let oob; if size == 1 { // `offset > bound - 1` is the same as `offset >= bound`. - oob = pos.ins().icmp( - IntCC::UnsignedGreaterThanOrEqual, - offset, - bound, - ); + oob = pos.ins() + .icmp(IntCC::UnsignedGreaterThanOrEqual, offset, bound); } else if size <= min_size { // We know that bound >= min_size, so here we can compare `offset > bound - size` without // wrapping. let adj_bound = pos.ins().iadd_imm(bound, -size); - oob = pos.ins().icmp( - IntCC::UnsignedGreaterThan, - offset, - adj_bound, - ); + oob = pos.ins() + .icmp(IntCC::UnsignedGreaterThan, offset, adj_bound); } else { // We need an overflow check for the adjusted offset. let size_val = pos.ins().iconst(offset_ty, size); let (adj_offset, overflow) = pos.ins().iadd_cout(offset, size_val); pos.ins().trapnz(overflow, ir::TrapCode::HeapOutOfBounds); - oob = pos.ins().icmp( - IntCC::UnsignedGreaterThan, - adj_offset, - bound, - ); + oob = pos.ins() + .icmp(IntCC::UnsignedGreaterThan, adj_offset, bound); } pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); @@ -137,17 +128,11 @@ fn static_addr( let oob = if limit & 1 == 1 { // Prefer testing `offset >= limit - 1` when limit is odd because an even number is // likely to be a convenient constant on ARM and other RISC architectures. - pos.ins().icmp_imm( - IntCC::UnsignedGreaterThanOrEqual, - offset, - limit - 1, - ) + pos.ins() + .icmp_imm(IntCC::UnsignedGreaterThanOrEqual, offset, limit - 1) } else { - pos.ins().icmp_imm( - IntCC::UnsignedGreaterThan, - offset, - limit, - ) + pos.ins() + .icmp_imm(IntCC::UnsignedGreaterThan, offset, limit) }; pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); } diff --git a/lib/codegen/src/legalizer/libcall.rs b/lib/codegen/src/legalizer/libcall.rs index fd7dd17e7e..70982da3cb 100644 --- a/lib/codegen/src/legalizer/libcall.rs +++ b/lib/codegen/src/legalizer/libcall.rs @@ -1,18 +1,18 @@ //! Expanding instructions as runtime library calls. use ir; -use ir::{InstBuilder, get_libcall_funcref}; -use std::vec::Vec; +use ir::{get_libcall_funcref, InstBuilder}; use isa::TargetIsa; +use std::vec::Vec; /// Try to expand `inst` as a library call, returning true is successful. pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function, isa: &TargetIsa) -> bool { // Does the opcode/ctrl_type combo even have a well-known runtime library name. - let libcall = - match ir::LibCall::for_inst(func.dfg[inst].opcode(), func.dfg.ctrl_typevar(inst)) { - Some(lc) => lc, - None => return false, - }; + let libcall = match ir::LibCall::for_inst(func.dfg[inst].opcode(), func.dfg.ctrl_typevar(inst)) + { + Some(lc) => lc, + None => return false, + }; // Now we convert `inst` to a call. First save the arguments. let mut args = Vec::new(); diff --git a/lib/codegen/src/legalizer/mod.rs b/lib/codegen/src/legalizer/mod.rs index 9be4975a00..95a6666b2d 100644 --- a/lib/codegen/src/legalizer/mod.rs +++ b/lib/codegen/src/legalizer/mod.rs @@ -27,9 +27,9 @@ mod heap; mod libcall; mod split; +use self::call::expand_call; use self::globalvar::expand_global_addr; use self::heap::expand_heap_addr; -use self::call::expand_call; use self::libcall::expand_as_libcall; /// Legalize `inst` for `isa`. Return true if any changes to the code were diff --git a/lib/codegen/src/legalizer/split.rs b/lib/codegen/src/legalizer/split.rs index 8f82166db8..99babd4a27 100644 --- a/lib/codegen/src/legalizer/split.rs +++ b/lib/codegen/src/legalizer/split.rs @@ -134,9 +134,9 @@ fn split_any( pos.func.dfg.display_inst(inst, None) ); let fixed_args = branch_opc.constraints().fixed_value_arguments(); - let mut args = pos.func.dfg[inst].take_value_list().expect( - "Branches must have value lists.", - ); + let mut args = pos.func.dfg[inst] + .take_value_list() + .expect("Branches must have value lists."); let num_args = args.len(&pos.func.dfg.value_lists); // Get the old value passed to the EBB argument we're repairing. let old_arg = args.get(fixed_args + repair.num, &pos.func.dfg.value_lists) @@ -236,12 +236,9 @@ fn split_value( // Note that it is safe to move `pos` here since `reuse` was set above, so we don't // need to insert a split instruction before returning. pos.goto_first_inst(ebb); - pos.ins().with_result(value).Binary( - concat, - split_type, - lo, - hi, - ); + pos.ins() + .with_result(value) + .Binary(concat, split_type, lo, hi); // Finally, splitting the EBB parameter is not enough. We also have to repair all // of the predecessor instructions that branch here. diff --git a/lib/codegen/src/lib.rs b/lib/codegen/src/lib.rs index 05fe7c03df..9636d317b0 100644 --- a/lib/codegen/src/lib.rs +++ b/lib/codegen/src/lib.rs @@ -31,17 +31,9 @@ redundant_field_names, useless_let_if_seq, len_without_is_empty))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] - +#![cfg_attr(feature = "cargo-clippy", + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] // Turns on no_std and alloc features if std is not available. #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc))] @@ -90,7 +82,6 @@ pub use entity::packed_option; mod abi; mod bitset; -mod nan_canonicalization; mod constant_hash; mod context; mod dce; @@ -99,6 +90,7 @@ mod fx; mod iterators; mod legalizer; mod licm; +mod nan_canonicalization; mod partition_slice; mod postopt; mod predicates; @@ -115,11 +107,11 @@ mod write; /// This replaces `std` in builds with `core`. #[cfg(not(feature = "std"))] mod std { + pub use alloc::{boxed, string, vec}; pub use core::*; - pub use alloc::{boxed, vec, string}; pub mod collections { - pub use hashmap_core::{HashMap, HashSet}; - pub use hashmap_core::map as hash_map; pub use alloc::BTreeSet; + pub use hashmap_core::map as hash_map; + pub use hashmap_core::{HashMap, HashSet}; } } diff --git a/lib/codegen/src/licm.rs b/lib/codegen/src/licm.rs index f52d192000..5771e89fb1 100644 --- a/lib/codegen/src/licm.rs +++ b/lib/codegen/src/licm.rs @@ -132,9 +132,9 @@ fn change_branch_jump_destination(inst: Inst, new_ebb: Ebb, func: &mut Function) /// Test whether the given opcode is unsafe to even consider for LICM. fn trivially_unsafe_for_licm(opcode: Opcode) -> bool { - opcode.can_load() || opcode.can_store() || opcode.is_call() || opcode.is_branch() || - opcode.is_terminator() || opcode.is_return() || - opcode.can_trap() || opcode.other_side_effects() || opcode.writes_cpu_flags() + opcode.can_load() || opcode.can_store() || opcode.is_call() || opcode.is_branch() + || opcode.is_terminator() || opcode.is_return() || opcode.can_trap() + || opcode.other_side_effects() || opcode.writes_cpu_flags() } /// Test whether the given instruction is loop-invariant. diff --git a/lib/codegen/src/nan_canonicalization.rs b/lib/codegen/src/nan_canonicalization.rs index 20877c3e18..0db8c12056 100644 --- a/lib/codegen/src/nan_canonicalization.rs +++ b/lib/codegen/src/nan_canonicalization.rs @@ -3,11 +3,11 @@ //! that will replace nondeterministic NaN's with a single canonical NaN value. use cursor::{Cursor, FuncCursor}; -use ir::{Function, Inst, InstBuilder, InstructionData, Opcode, Value}; use ir::condcodes::FloatCC; use ir::immediates::{Ieee32, Ieee64}; use ir::types; use ir::types::Type; +use ir::{Function, Inst, InstBuilder, InstructionData, Opcode, Value}; use timing; // Canonical 32-bit and 64-bit NaN values. @@ -33,13 +33,13 @@ pub fn do_nan_canonicalization(func: &mut Function) { fn is_fp_arith(pos: &mut FuncCursor, inst: Inst) -> bool { match pos.func.dfg[inst] { InstructionData::Unary { opcode, .. } => { - opcode == Opcode::Ceil || opcode == Opcode::Floor || opcode == Opcode::Nearest || - opcode == Opcode::Sqrt || opcode == Opcode::Trunc + opcode == Opcode::Ceil || opcode == Opcode::Floor || opcode == Opcode::Nearest + || opcode == Opcode::Sqrt || opcode == Opcode::Trunc } InstructionData::Binary { opcode, .. } => { - opcode == Opcode::Fadd || opcode == Opcode::Fdiv || opcode == Opcode::Fmax || - opcode == Opcode::Fmin || opcode == Opcode::Fmul || - opcode == Opcode::Fsub + opcode == Opcode::Fadd || opcode == Opcode::Fdiv || opcode == Opcode::Fmax + || opcode == Opcode::Fmin || opcode == Opcode::Fmul + || opcode == Opcode::Fsub } InstructionData::Ternary { opcode, .. } => opcode == Opcode::Fma, _ => false, @@ -59,11 +59,9 @@ fn add_nan_canon_seq(pos: &mut FuncCursor, inst: Inst) { // the canonical NaN value if `val` is NaN, assign the result to `inst`. let is_nan = pos.ins().fcmp(FloatCC::NotEqual, new_res, new_res); let canon_nan = insert_nan_const(pos, val_type); - pos.ins().with_result(val).select( - is_nan, - canon_nan, - new_res, - ); + pos.ins() + .with_result(val) + .select(is_nan, canon_nan, new_res); pos.prev_inst(); // Step backwards so the pass does not skip instructions. } diff --git a/lib/codegen/src/postopt.rs b/lib/codegen/src/postopt.rs index 50661f4cc1..517621bef5 100644 --- a/lib/codegen/src/postopt.rs +++ b/lib/codegen/src/postopt.rs @@ -7,7 +7,7 @@ use ir::condcodes::{CondCode, FloatCC, IntCC}; use ir::dfg::ValueDef; use ir::immediates::{Imm64, Offset32}; use ir::instructions::{Opcode, ValueList}; -use ir::{Ebb, Function, Inst, InstBuilder, InstructionData, Value, Type, MemFlags}; +use ir::{Ebb, Function, Inst, InstBuilder, InstructionData, MemFlags, Type, Value}; use isa::TargetIsa; use timing; @@ -135,12 +135,10 @@ fn optimize_cpu_flags( if info.invert_branch_cond { cond = cond.inverse(); } - pos.func.dfg.replace(info.br_inst).brif( - cond, - flags, - info.destination, - &args, - ); + pos.func + .dfg + .replace(info.br_inst) + .brif(cond, flags, info.destination, &args); } CmpBrKind::IcmpImm { mut cond, imm } => { let flags = pos.ins().ifcmp_imm(info.cmp_arg, imm); @@ -148,12 +146,10 @@ fn optimize_cpu_flags( if info.invert_branch_cond { cond = cond.inverse(); } - pos.func.dfg.replace(info.br_inst).brif( - cond, - flags, - info.destination, - &args, - ); + pos.func + .dfg + .replace(info.br_inst) + .brif(cond, flags, info.destination, &args); } CmpBrKind::Fcmp { mut cond, arg } => { let flags = pos.ins().ffcmp(info.cmp_arg, arg); @@ -161,12 +157,10 @@ fn optimize_cpu_flags( if info.invert_branch_cond { cond = cond.inverse(); } - pos.func.dfg.replace(info.br_inst).brff( - cond, - flags, - info.destination, - &args, - ); + pos.func + .dfg + .replace(info.br_inst) + .brff(cond, flags, info.destination, &args); } } let ok = pos.func.update_encoding(info.cmp_inst, isa).is_ok(); @@ -175,7 +169,6 @@ fn optimize_cpu_flags( debug_assert!(ok); } - struct MemOpInfo { opcode: Opcode, inst: Inst, @@ -326,8 +319,6 @@ fn optimize_complex_addresses(pos: &mut EncCursor, inst: Inst, isa: &TargetIsa) debug_assert!(ok); } - - //---------------------------------------------------------------------- // // The main post-opt pass. @@ -343,10 +334,8 @@ pub fn do_postopt(func: &mut Function, isa: &TargetIsa) { optimize_cpu_flags(&mut pos, inst, last_flags_clobber, isa); // Track the most recent seen instruction that clobbers the flags. - if let Some(constraints) = - isa.encoding_info().operand_constraints( - pos.func.encodings[inst], - ) + if let Some(constraints) = isa.encoding_info() + .operand_constraints(pos.func.encodings[inst]) { if constraints.clobbers_flags { last_flags_clobber = Some(inst) diff --git a/lib/codegen/src/preopt.rs b/lib/codegen/src/preopt.rs index cbe7484fd0..ead49b9486 100644 --- a/lib/codegen/src/preopt.rs +++ b/lib/codegen/src/preopt.rs @@ -137,27 +137,25 @@ fn get_div_info(inst: Inst, dfg: &DataFlowGraph) -> Option { /// cannot do any transformation, in which case `inst` is left unchanged. fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCursor, inst: Inst) { let isRem = match *divrem_info { - DivRemByConstInfo::DivU32(_, _) | - DivRemByConstInfo::DivU64(_, _) | - DivRemByConstInfo::DivS32(_, _) | - DivRemByConstInfo::DivS64(_, _) => false, - DivRemByConstInfo::RemU32(_, _) | - DivRemByConstInfo::RemU64(_, _) | - DivRemByConstInfo::RemS32(_, _) | - DivRemByConstInfo::RemS64(_, _) => true, + DivRemByConstInfo::DivU32(_, _) + | DivRemByConstInfo::DivU64(_, _) + | DivRemByConstInfo::DivS32(_, _) + | DivRemByConstInfo::DivS64(_, _) => false, + DivRemByConstInfo::RemU32(_, _) + | DivRemByConstInfo::RemU64(_, _) + | DivRemByConstInfo::RemS32(_, _) + | DivRemByConstInfo::RemS64(_, _) => true, }; match *divrem_info { // -------------------- U32 -------------------- // U32 div, rem by zero: ignore - DivRemByConstInfo::DivU32(_n1, 0) | - DivRemByConstInfo::RemU32(_n1, 0) => {} + DivRemByConstInfo::DivU32(_n1, 0) | DivRemByConstInfo::RemU32(_n1, 0) => {} // U32 div by 1: identity // U32 rem by 1: zero - DivRemByConstInfo::DivU32(n1, 1) | - DivRemByConstInfo::RemU32(n1, 1) => { + DivRemByConstInfo::DivU32(n1, 1) | DivRemByConstInfo::RemU32(n1, 1) => { if isRem { pos.func.dfg.replace(inst).iconst(I32, 0); } else { @@ -166,8 +164,9 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso } // U32 div, rem by a power-of-2 - DivRemByConstInfo::DivU32(n1, d) | - DivRemByConstInfo::RemU32(n1, d) if d.is_power_of_two() => { + DivRemByConstInfo::DivU32(n1, d) | DivRemByConstInfo::RemU32(n1, d) + if d.is_power_of_two() => + { debug_assert!(d >= 2); // compute k where d == 2^k let k = d.trailing_zeros(); @@ -181,8 +180,7 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso } // U32 div, rem by non-power-of-2 - DivRemByConstInfo::DivU32(n1, d) | - DivRemByConstInfo::RemU32(n1, d) => { + DivRemByConstInfo::DivU32(n1, d) | DivRemByConstInfo::RemU32(n1, d) => { debug_assert!(d >= 3); let MU32 { mulBy, @@ -223,13 +221,11 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso // -------------------- U64 -------------------- // U64 div, rem by zero: ignore - DivRemByConstInfo::DivU64(_n1, 0) | - DivRemByConstInfo::RemU64(_n1, 0) => {} + DivRemByConstInfo::DivU64(_n1, 0) | DivRemByConstInfo::RemU64(_n1, 0) => {} // U64 div by 1: identity // U64 rem by 1: zero - DivRemByConstInfo::DivU64(n1, 1) | - DivRemByConstInfo::RemU64(n1, 1) => { + DivRemByConstInfo::DivU64(n1, 1) | DivRemByConstInfo::RemU64(n1, 1) => { if isRem { pos.func.dfg.replace(inst).iconst(I64, 0); } else { @@ -238,8 +234,9 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso } // U64 div, rem by a power-of-2 - DivRemByConstInfo::DivU64(n1, d) | - DivRemByConstInfo::RemU64(n1, d) if d.is_power_of_two() => { + DivRemByConstInfo::DivU64(n1, d) | DivRemByConstInfo::RemU64(n1, d) + if d.is_power_of_two() => + { debug_assert!(d >= 2); // compute k where d == 2^k let k = d.trailing_zeros(); @@ -253,8 +250,7 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso } // U64 div, rem by non-power-of-2 - DivRemByConstInfo::DivU64(n1, d) | - DivRemByConstInfo::RemU64(n1, d) => { + DivRemByConstInfo::DivU64(n1, d) | DivRemByConstInfo::RemU64(n1, d) => { debug_assert!(d >= 3); let MU64 { mulBy, @@ -295,15 +291,14 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso // -------------------- S32 -------------------- // S32 div, rem by zero or -1: ignore - DivRemByConstInfo::DivS32(_n1, -1) | - DivRemByConstInfo::RemS32(_n1, -1) | - DivRemByConstInfo::DivS32(_n1, 0) | - DivRemByConstInfo::RemS32(_n1, 0) => {} + DivRemByConstInfo::DivS32(_n1, -1) + | DivRemByConstInfo::RemS32(_n1, -1) + | DivRemByConstInfo::DivS32(_n1, 0) + | DivRemByConstInfo::RemS32(_n1, 0) => {} // S32 div by 1: identity // S32 rem by 1: zero - DivRemByConstInfo::DivS32(n1, 1) | - DivRemByConstInfo::RemS32(n1, 1) => { + DivRemByConstInfo::DivS32(n1, 1) | DivRemByConstInfo::RemS32(n1, 1) => { if isRem { pos.func.dfg.replace(inst).iconst(I32, 0); } else { @@ -311,8 +306,7 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso } } - DivRemByConstInfo::DivS32(n1, d) | - DivRemByConstInfo::RemS32(n1, d) => { + DivRemByConstInfo::DivS32(n1, d) | DivRemByConstInfo::RemS32(n1, d) => { if let Some((isNeg, k)) = isPowerOf2_S32(d) { // k can be 31 only in the case that d is -2^31. debug_assert!(k >= 1 && k <= 31); @@ -372,15 +366,14 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso // -------------------- S64 -------------------- // S64 div, rem by zero or -1: ignore - DivRemByConstInfo::DivS64(_n1, -1) | - DivRemByConstInfo::RemS64(_n1, -1) | - DivRemByConstInfo::DivS64(_n1, 0) | - DivRemByConstInfo::RemS64(_n1, 0) => {} + DivRemByConstInfo::DivS64(_n1, -1) + | DivRemByConstInfo::RemS64(_n1, -1) + | DivRemByConstInfo::DivS64(_n1, 0) + | DivRemByConstInfo::RemS64(_n1, 0) => {} // S64 div by 1: identity // S64 rem by 1: zero - DivRemByConstInfo::DivS64(n1, 1) | - DivRemByConstInfo::RemS64(n1, 1) => { + DivRemByConstInfo::DivS64(n1, 1) | DivRemByConstInfo::RemS64(n1, 1) => { if isRem { pos.func.dfg.replace(inst).iconst(I64, 0); } else { @@ -388,8 +381,7 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso } } - DivRemByConstInfo::DivS64(n1, d) | - DivRemByConstInfo::RemS64(n1, d) => { + DivRemByConstInfo::DivS64(n1, d) | DivRemByConstInfo::RemS64(n1, d) => { if let Some((isNeg, k)) = isPowerOf2_S64(d) { // k can be 63 only in the case that d is -2^63. debug_assert!(k >= 1 && k <= 63); @@ -483,12 +475,10 @@ fn simplify(pos: &mut FuncCursor, inst: Inst) { _ => return, }; let ty = pos.func.dfg.ctrl_typevar(inst); - pos.func.dfg.replace(inst).BinaryImm( - new_opcode, - ty, - imm, - args[0], - ); + pos.func + .dfg + .replace(inst) + .BinaryImm(new_opcode, ty, imm, args[0]); } } else if let ValueDef::Result(iconst_inst, _) = pos.func.dfg.value_def(args[0]) { if let InstructionData::UnaryImm { @@ -501,12 +491,10 @@ fn simplify(pos: &mut FuncCursor, inst: Inst) { _ => return, }; let ty = pos.func.dfg.ctrl_typevar(inst); - pos.func.dfg.replace(inst).BinaryImm( - new_opcode, - ty, - imm, - args[1], - ); + pos.func + .dfg + .replace(inst) + .BinaryImm(new_opcode, ty, imm, args[1]); } } } @@ -522,9 +510,12 @@ fn simplify(pos: &mut FuncCursor, inst: Inst) { } } } - InstructionData::CondTrap { .. } | - InstructionData::Branch { .. } | - InstructionData::Ternary { opcode: Opcode::Select, .. } => { + InstructionData::CondTrap { .. } + | InstructionData::Branch { .. } + | InstructionData::Ternary { + opcode: Opcode::Select, + .. + } => { // Fold away a redundant `bint`. let maybe = { let args = pos.func.dfg.inst_args(inst); diff --git a/lib/codegen/src/regalloc/affinity.rs b/lib/codegen/src/regalloc/affinity.rs index a8fa423049..44d3dbb11b 100644 --- a/lib/codegen/src/regalloc/affinity.rs +++ b/lib/codegen/src/regalloc/affinity.rs @@ -90,8 +90,7 @@ impl Affinity { Affinity::Reg(rc) => { // If the preferred register class is a subclass of the constraint, there's no need // to change anything. - if constraint.kind != ConstraintKind::Stack && - !constraint.regclass.has_subclass(rc) + if constraint.kind != ConstraintKind::Stack && !constraint.regclass.has_subclass(rc) { // If the register classes don't overlap, `intersect` returns `Unassigned`, and // we just keep our previous affinity. @@ -120,12 +119,10 @@ impl<'a> fmt::Display for DisplayAffinity<'a> { match self.0 { Affinity::Unassigned => write!(f, "unassigned"), Affinity::Stack => write!(f, "stack"), - Affinity::Reg(rci) => { - match self.1 { - Some(regs) => write!(f, "{}", regs.rc(rci)), - None => write!(f, "{}", rci), - } - } + Affinity::Reg(rci) => match self.1 { + Some(regs) => write!(f, "{}", regs.rc(rci)), + None => write!(f, "{}", rci), + }, } } } diff --git a/lib/codegen/src/regalloc/coalescing.rs b/lib/codegen/src/regalloc/coalescing.rs index 5cd0815e5b..dd77b41937 100644 --- a/lib/codegen/src/regalloc/coalescing.rs +++ b/lib/codegen/src/regalloc/coalescing.rs @@ -196,8 +196,7 @@ impl<'a> Context<'a> { pred_inst, pred_ebb, self.liveness.context(&self.func.layout), - ) - { + ) { self.isolate_param(ebb, param); } } @@ -219,8 +218,8 @@ impl<'a> Context<'a> { // pre-spilled, and the rest of the virtual register would be forced to spill to the // `incoming_arg` stack slot too. if let ir::ValueDef::Param(def_ebb, def_num) = self.func.dfg.value_def(arg) { - if Some(def_ebb) == self.func.layout.entry_block() && - self.func.signature.params[def_num].location.is_stack() + if Some(def_ebb) == self.func.layout.entry_block() + && self.func.signature.params[def_num].location.is_stack() { dbg!("-> isolating function stack parameter {}", arg); let new_arg = self.isolate_arg(pred_ebb, pred_inst, argnum, arg); @@ -303,16 +302,11 @@ impl<'a> Context<'a> { &self.encinfo .operand_constraints(pos.func.encodings[inst]) .expect("Bad copy encoding") - .outs - [0], + .outs[0], ); self.liveness.create_dead(new_val, ebb, affinity); - self.liveness.extend_locally( - new_val, - ebb, - inst, - &pos.func.layout, - ); + self.liveness + .extend_locally(new_val, ebb, inst, &pos.func.layout); new_val } @@ -353,16 +347,11 @@ impl<'a> Context<'a> { &self.encinfo .operand_constraints(pos.func.encodings[inst]) .expect("Bad copy encoding") - .outs - [0], + .outs[0], ); self.liveness.create_dead(copy, inst, affinity); - self.liveness.extend_locally( - copy, - pred_ebb, - pred_inst, - &pos.func.layout, - ); + self.liveness + .extend_locally(copy, pred_ebb, pred_inst, &pos.func.layout); pos.func.dfg.inst_variable_args_mut(pred_inst)[argnum] = copy; @@ -422,12 +411,9 @@ impl<'a> Context<'a> { let node = Node::value(value, 0, self.func); // Push this value and get the nearest dominating def back. - let parent = match self.forest.push_node( - node, - self.func, - self.domtree, - self.preorder, - ) { + let parent = match self.forest + .push_node(node, self.func, self.domtree, self.preorder) + { None => continue, Some(n) => n, }; @@ -525,12 +511,8 @@ impl<'a> Context<'a> { // Can't merge because of interference. Insert a copy instead. let pred_ebb = self.func.layout.pp_ebb(pred_inst); let new_arg = self.isolate_arg(pred_ebb, pred_inst, argnum, arg); - self.virtregs.insert_single( - param, - new_arg, - self.func, - self.preorder, - ); + self.virtregs + .insert_single(param, new_arg, self.func, self.preorder); } } @@ -564,12 +546,8 @@ impl<'a> Context<'a> { // Restrict the virtual copy nodes we look at and key the `set_id` and `value` properties // of the nodes. Set_id 0 will be `param` and set_id 1 will be `arg`. - self.vcopies.set_filter( - [param, arg], - func, - self.virtregs, - preorder, - ); + self.vcopies + .set_filter([param, arg], func, self.virtregs, preorder); // Now create an ordered sequence of dom-forest nodes from three sources: The two virtual // registers and the filtered virtual copies. @@ -625,8 +603,8 @@ impl<'a> Context<'a> { // Check if the parent value interferes with the virtual copy. let inst = node.def.unwrap_inst(); - if node.set_id != parent.set_id && - self.liveness[parent.value].reaches_use(inst, node.ebb, ctx) + if node.set_id != parent.set_id + && self.liveness[parent.value].reaches_use(inst, node.ebb, ctx) { dbg!( " - interference: {} overlaps vcopy at {}:{}", @@ -649,8 +627,8 @@ impl<'a> Context<'a> { // Both node and parent are values, so check for interference. debug_assert!(node.is_value() && parent.is_value()); - if node.set_id != parent.set_id && - self.liveness[parent.value].overlaps_def(node.def, node.ebb, ctx) + if node.set_id != parent.set_id + && self.liveness[parent.value].overlaps_def(node.def, node.ebb, ctx) { // The two values are interfering. dbg!(" - interference: {} overlaps def of {}", parent, node.value); @@ -945,9 +923,8 @@ impl VirtualCopies { } // Reorder the predecessor branches as required by the dominator forest. - self.branches.sort_unstable_by(|&(a, _), &(b, _)| { - preorder.pre_cmp(a, b, &func.layout) - }); + self.branches + .sort_unstable_by(|&(a, _), &(b, _)| preorder.pre_cmp(a, b, &func.layout)); } /// Get the next unmerged parameter value. @@ -1097,9 +1074,9 @@ where let ord = match (self.a.peek(), self.b.peek()) { (Some(a), Some(b)) => { let layout = self.layout; - self.preorder.pre_cmp_ebb(a.ebb, b.ebb).then_with(|| { - layout.cmp(a.def, b.def) - }) + self.preorder + .pre_cmp_ebb(a.ebb, b.ebb) + .then_with(|| layout.cmp(a.def, b.def)) } (Some(_), None) => cmp::Ordering::Less, (None, Some(_)) => cmp::Ordering::Greater, diff --git a/lib/codegen/src/regalloc/coloring.rs b/lib/codegen/src/regalloc/coloring.rs index d080213ade..aa7cbbeb47 100644 --- a/lib/codegen/src/regalloc/coloring.rs +++ b/lib/codegen/src/regalloc/coloring.rs @@ -51,10 +51,10 @@ use isa::{regs_overlap, RegClass, RegInfo, RegUnit}; use packed_option::PackedOption; use regalloc::RegDiversions; use regalloc::affinity::Affinity; -use regalloc::register_set::RegisterSet; use regalloc::live_value_tracker::{LiveValue, LiveValueTracker}; use regalloc::liveness::Liveness; use regalloc::liverange::{LiveRange, LiveRangeContext}; +use regalloc::register_set::RegisterSet; use regalloc::solver::{Solver, SolverError}; use std::mem; use timing; @@ -142,9 +142,10 @@ impl Coloring { impl<'a> Context<'a> { /// Run the coloring algorithm. fn run(&mut self, tracker: &mut LiveValueTracker) { - self.cur.func.locations.resize( - self.cur.func.dfg.num_values(), - ); + self.cur + .func + .locations + .resize(self.cur.func.dfg.num_values()); // Visit blocks in reverse post-order. We need to ensure that at least one predecessor has // been visited before each EBB. That guarantees that the EBB arguments have been colored. @@ -372,10 +373,8 @@ impl<'a> Context<'a> { // Update the global register set which has no diversions. if !lv.is_local { - regs.global.free( - rc, - self.cur.func.locations[lv.value].unwrap_reg(), - ); + regs.global + .free(rc, self.cur.func.locations[lv.value].unwrap_reg()); } } } @@ -500,20 +499,14 @@ impl<'a> Context<'a> { // already in a register. let cur_reg = self.divert.reg(value, &self.cur.func.locations); match op.kind { - ConstraintKind::FixedReg(regunit) | - ConstraintKind::FixedTied(regunit) => { + ConstraintKind::FixedReg(regunit) | ConstraintKind::FixedTied(regunit) => { // Add the fixed constraint even if `cur_reg == regunit`. // It is possible that we will want to convert the value to a variable later, // and this identity assignment prevents that from happening. - self.solver.reassign_in( - value, - op.regclass, - cur_reg, - regunit, - ); + self.solver + .reassign_in(value, op.regclass, cur_reg, regunit); } - ConstraintKind::Reg | - ConstraintKind::Tied(_) => { + ConstraintKind::Reg | ConstraintKind::Tied(_) => { if !op.regclass.contains(cur_reg) { self.solver.add_var(value, op.regclass, cur_reg); } @@ -541,8 +534,7 @@ impl<'a> Context<'a> { for (op, &value) in constraints.iter().zip(self.cur.func.dfg.inst_args(inst)) { match op.kind { - ConstraintKind::Reg | - ConstraintKind::Tied(_) => { + ConstraintKind::Reg | ConstraintKind::Tied(_) => { let cur_reg = self.divert.reg(value, &self.cur.func.locations); // This is the opposite condition of `program_input_constraints()`. if op.regclass.contains(cur_reg) { @@ -556,9 +548,9 @@ impl<'a> Context<'a> { } } } - ConstraintKind::FixedReg(_) | - ConstraintKind::FixedTied(_) | - ConstraintKind::Stack => {} + ConstraintKind::FixedReg(_) + | ConstraintKind::FixedTied(_) + | ConstraintKind::Stack => {} } } } @@ -651,9 +643,9 @@ impl<'a> Context<'a> { Pred: FnMut(&LiveRange, LiveRangeContext) -> bool, { for rdiv in self.divert.all() { - let lr = self.liveness.get(rdiv.value).expect( - "Missing live range for diverted register", - ); + let lr = self.liveness + .get(rdiv.value) + .expect("Missing live range for diverted register"); if pred(lr, self.liveness.context(&self.cur.func.layout)) { if let Affinity::Reg(rci) = lr.affinity { let rc = self.reginfo.rc(rci); @@ -703,8 +695,7 @@ impl<'a> Context<'a> { ) { for (op, lv) in constraints.iter().zip(defs) { match op.kind { - ConstraintKind::FixedReg(reg) | - ConstraintKind::FixedTied(reg) => { + ConstraintKind::FixedReg(reg) | ConstraintKind::FixedTied(reg) => { self.add_fixed_output(lv.value, op.regclass, reg, throughs); if !lv.is_local && !global_regs.is_avail(op.regclass, reg) { dbg!( @@ -716,9 +707,7 @@ impl<'a> Context<'a> { *replace_global_defines = true; } } - ConstraintKind::Reg | - ConstraintKind::Tied(_) | - ConstraintKind::Stack => {} + ConstraintKind::Reg | ConstraintKind::Tied(_) | ConstraintKind::Stack => {} } } } @@ -801,9 +790,9 @@ impl<'a> Context<'a> { ) { for (op, lv) in constraints.iter().zip(defs) { match op.kind { - ConstraintKind::FixedReg(_) | - ConstraintKind::FixedTied(_) | - ConstraintKind::Stack => continue, + ConstraintKind::FixedReg(_) + | ConstraintKind::FixedTied(_) + | ConstraintKind::Stack => continue, ConstraintKind::Reg => { self.solver.add_def(lv.value, op.regclass, !lv.is_local); } @@ -816,8 +805,7 @@ impl<'a> Context<'a> { op.regclass, self.divert.reg(arg, &self.cur.func.locations), !lv.is_local, - ) - { + ) { // The value we're tied to has been assigned to a fixed register. // We need to make sure that fixed output register is compatible with the // global register set. @@ -881,8 +869,8 @@ impl<'a> Context<'a> { // not actually constrained by the instruction. We just want it out of the way. let toprc2 = self.reginfo.toprc(rci); let reg2 = self.divert.reg(lv.value, &self.cur.func.locations); - if rc.contains(reg2) && self.solver.can_add_var(lv.value, toprc2, reg2) && - !self.is_live_on_outgoing_edge(lv.value) + if rc.contains(reg2) && self.solver.can_add_var(lv.value, toprc2, reg2) + && !self.is_live_on_outgoing_edge(lv.value) { self.solver.add_through_var(lv.value, toprc2, reg2); return true; @@ -911,10 +899,10 @@ impl<'a> Context<'a> { } Table(jt) => { let lr = &self.liveness[value]; - !lr.is_local() && - self.cur.func.jump_tables[jt].entries().any(|(_, ebb)| { - lr.is_livein(ebb, ctx) - }) + !lr.is_local() + && self.cur.func.jump_tables[jt] + .entries() + .any(|(_, ebb)| lr.is_livein(ebb, ctx)) } } } @@ -940,7 +928,9 @@ impl<'a> Context<'a> { for m in self.solver.moves() { match *m { - Reg { value, from, to, .. } => { + Reg { + value, from, to, .. + } => { self.divert.regmove(value, from, to); self.cur.ins().regmove(value, from, to); } @@ -951,10 +941,10 @@ impl<'a> Context<'a> { .. } => { debug_assert_eq!(slot[to_slot].expand(), None, "Overwriting slot in use"); - let ss = self.cur.func.stack_slots.get_emergency_slot( - self.cur.func.dfg.value_type(value), - &slot[0..spills], - ); + let ss = self.cur + .func + .stack_slots + .get_emergency_slot(self.cur.func.dfg.value_type(value), &slot[0..spills]); slot[to_slot] = ss.into(); self.divert.regspill(value, from, ss); self.cur.ins().regspill(value, from, ss); @@ -1013,8 +1003,7 @@ impl<'a> Context<'a> { if match self.cur.func.dfg.value_def(lv.value) { ValueDef::Result(i, _) => i != inst, _ => true, - } - { + } { break; } if lv.is_local || !lv.affinity.is_reg() { @@ -1072,10 +1061,8 @@ impl<'a> Context<'a> { }; regs.input.free(rc, loc.unwrap_reg()); if !lv.is_local { - regs.global.free( - rc, - self.cur.func.locations[lv.value].unwrap_reg(), - ); + regs.global + .free(rc, self.cur.func.locations[lv.value].unwrap_reg()); } } } @@ -1096,11 +1083,10 @@ fn program_input_abi( ) { for (abi, &value) in abi_types.iter().zip(func.dfg.inst_variable_args(inst)) { if let ArgumentLoc::Reg(reg) = abi.location { - if let Affinity::Reg(rci) = - liveness - .get(value) - .expect("ABI register must have live range") - .affinity + if let Affinity::Reg(rci) = liveness + .get(value) + .expect("ABI register must have live range") + .affinity { let rc = reginfo.rc(rci); let cur_reg = divert.reg(value, &func.locations); diff --git a/lib/codegen/src/regalloc/context.rs b/lib/codegen/src/regalloc/context.rs index cb29963e89..ce1d68a096 100644 --- a/lib/codegen/src/regalloc/context.rs +++ b/lib/codegen/src/regalloc/context.rs @@ -140,13 +140,8 @@ impl Context { } // Pass: Coloring. - self.coloring.run( - isa, - func, - domtree, - &mut self.liveness, - &mut self.tracker, - ); + self.coloring + .run(isa, func, domtree, &mut self.liveness, &mut self.tracker); if isa.flags().enable_verifier() { verify_context(func, cfg, domtree, isa)?; diff --git a/lib/codegen/src/regalloc/diversion.rs b/lib/codegen/src/regalloc/diversion.rs index 1a747fc7e6..3572acd543 100644 --- a/lib/codegen/src/regalloc/diversion.rs +++ b/lib/codegen/src/regalloc/diversion.rs @@ -46,7 +46,9 @@ pub struct RegDiversions { impl RegDiversions { /// Create a new empty diversion tracker. pub fn new() -> Self { - Self { current: Vec::new() } + Self { + current: Vec::new(), + } } /// Clear the tracker, preparing for a new EBB. @@ -152,11 +154,10 @@ impl RegDiversions { /// /// Returns the `to` location of the removed diversion. pub fn remove(&mut self, value: Value) -> Option { - self.current.iter().position(|d| d.value == value).map( - |i| { - self.current.swap_remove(i).to - }, - ) + self.current + .iter() + .position(|d| d.value == value) + .map(|i| self.current.swap_remove(i).to) } /// Return an object that can display the diversions. diff --git a/lib/codegen/src/regalloc/live_value_tracker.rs b/lib/codegen/src/regalloc/live_value_tracker.rs index 12bda20ff4..2665c245c1 100644 --- a/lib/codegen/src/regalloc/live_value_tracker.rs +++ b/lib/codegen/src/regalloc/live_value_tracker.rs @@ -187,15 +187,15 @@ impl LiveValueTracker { // If the immediate dominator exits, we must have a stored list for it. This is a // requirement to the order EBBs are visited: All dominators must have been processed // before the current EBB. - let idom_live_list = self.idom_sets.get(&idom).expect( - "No stored live set for dominator", - ); + let idom_live_list = self.idom_sets + .get(&idom) + .expect("No stored live set for dominator"); let ctx = liveness.context(layout); // Get just the values that are live-in to `ebb`. for &value in idom_live_list.as_slice(&self.idom_pool) { - let lr = liveness.get(value).expect( - "Immediate dominator value has no live range", - ); + let lr = liveness + .get(value) + .expect("Immediate dominator value has no live range"); // Check if this value is live-in here. if let Some(endpoint) = lr.livein_local_end(ebb, ctx) { @@ -217,17 +217,13 @@ impl LiveValueTracker { // This is a dead EBB parameter which is not even live into the first // instruction in the EBB. debug_assert_eq!( - local_ebb, - ebb, + local_ebb, ebb, "EBB parameter live range ends at wrong EBB header" ); // Give this value a fake endpoint that is the first instruction in the EBB. // We expect it to be removed by calling `drop_dead_args()`. - self.live.push( - value, - layout.first_inst(ebb).expect("Empty EBB"), - lr, - ); + self.live + .push(value, layout.first_inst(ebb).expect("Empty EBB"), lr); } } } diff --git a/lib/codegen/src/regalloc/liveness.rs b/lib/codegen/src/regalloc/liveness.rs index faf35f6a1f..959e48183a 100644 --- a/lib/codegen/src/regalloc/liveness.rs +++ b/lib/codegen/src/regalloc/liveness.rs @@ -179,7 +179,7 @@ use entity::SparseMap; use flowgraph::ControlFlowGraph; use ir::dfg::ValueDef; use ir::{Ebb, Function, Inst, Layout, ProgramPoint, Value}; -use isa::{EncInfo, TargetIsa, OperandConstraint}; +use isa::{EncInfo, OperandConstraint, TargetIsa}; use regalloc::affinity::Affinity; use regalloc::liverange::{LiveRange, LiveRangeContext, LiveRangeForest}; use std::mem; @@ -217,9 +217,9 @@ fn get_or_create<'a>( .map(Affinity::new) .or_else(|| { // If this is a call, get the return value affinity. - func.dfg.call_signature(inst).map(|sig| { - Affinity::abi(&func.dfg.signatures[sig].returns[rnum], isa) - }) + func.dfg + .call_signature(inst) + .map(|sig| Affinity::abi(&func.dfg.signatures[sig].returns[rnum], isa)) }) .unwrap_or_default(); } @@ -336,9 +336,8 @@ impl Liveness { where PP: Into, { - let old = self.ranges.insert( - LiveRange::new(value, def.into(), affinity), - ); + let old = self.ranges + .insert(LiveRange::new(value, def.into(), affinity)); debug_assert!(old.is_none(), "{} already has a live range", value); } diff --git a/lib/codegen/src/regalloc/liverange.rs b/lib/codegen/src/regalloc/liverange.rs index d9ccc4fac5..a1e73b6206 100644 --- a/lib/codegen/src/regalloc/liverange.rs +++ b/lib/codegen/src/regalloc/liverange.rs @@ -249,13 +249,12 @@ impl GenLiveRange { // // We're assuming here that `to` never precedes `def_begin` in the same EBB, but we can't // check it without a method for getting `to`'s EBB. - if order.cmp(ebb, self.def_end) != Ordering::Greater && - order.cmp(to, self.def_begin) != Ordering::Less + if order.cmp(ebb, self.def_end) != Ordering::Greater + && order.cmp(to, self.def_begin) != Ordering::Less { let to_pp = to.into(); debug_assert_ne!( - to_pp, - self.def_begin, + to_pp, self.def_begin, "Can't use value in the defining instruction." ); if order.cmp(to, self.def_end) == Ordering::Greater { @@ -411,8 +410,8 @@ impl GenLiveRange { } // Check for an overlap with the local range. - if ctx.order.cmp(def, self.def_begin) != Ordering::Less && - ctx.order.cmp(def, self.def_end) == Ordering::Less + if ctx.order.cmp(def, self.def_begin) != Ordering::Less + && ctx.order.cmp(def, self.def_end) == Ordering::Less { return true; } @@ -427,8 +426,8 @@ impl GenLiveRange { /// Check if this live range reaches a use at `user` in `ebb`. pub fn reaches_use(&self, user: Inst, ebb: Ebb, ctx: LiveRangeContext) -> bool { // Check for an overlap with the local range. - if ctx.order.cmp(user, self.def_begin) == Ordering::Greater && - ctx.order.cmp(user, self.def_end) != Ordering::Greater + if ctx.order.cmp(user, self.def_begin) == Ordering::Greater + && ctx.order.cmp(user, self.def_end) != Ordering::Greater { return true; } @@ -535,8 +534,8 @@ mod tests { } assert!( - self.cmp(lr.def_end, begin) == Ordering::Less || - self.cmp(lr.def_begin, end) == Ordering::Greater, + self.cmp(lr.def_end, begin) == Ordering::Less + || self.cmp(lr.def_begin, end) == Ordering::Greater, "Interval can't overlap the def EBB" ); diff --git a/lib/codegen/src/regalloc/mod.rs b/lib/codegen/src/regalloc/mod.rs index 1444874b83..dbec691602 100644 --- a/lib/codegen/src/regalloc/mod.rs +++ b/lib/codegen/src/regalloc/mod.rs @@ -2,11 +2,11 @@ //! //! This module contains data structures and algorithms used for register allocation. -pub mod register_set; pub mod coloring; pub mod live_value_tracker; pub mod liveness; pub mod liverange; +pub mod register_set; pub mod virtregs; mod affinity; @@ -18,6 +18,6 @@ mod reload; mod solver; mod spilling; -pub use self::register_set::RegisterSet; pub use self::context::Context; pub use self::diversion::RegDiversions; +pub use self::register_set::RegisterSet; diff --git a/lib/codegen/src/regalloc/pressure.rs b/lib/codegen/src/regalloc/pressure.rs index 49eb224e6d..355fce582e 100644 --- a/lib/codegen/src/regalloc/pressure.rs +++ b/lib/codegen/src/regalloc/pressure.rs @@ -114,9 +114,10 @@ impl Pressure { } // Compute per-class limits from `usable`. - for (toprc, rc) in p.toprc.iter_mut().take_while(|t| t.num_toprcs > 0).zip( - reginfo.classes, - ) + for (toprc, rc) in p.toprc + .iter_mut() + .take_while(|t| t.num_toprcs > 0) + .zip(reginfo.classes) { toprc.limit = usable.iter(rc).len() as u32; toprc.width = rc.width; @@ -203,16 +204,16 @@ impl Pressure { /// /// This does not check if there are enough registers available. pub fn take(&mut self, rc: RegClass) { - self.toprc.get_mut(rc.toprc as usize).map( - |t| t.base_count += 1, - ); + self.toprc + .get_mut(rc.toprc as usize) + .map(|t| t.base_count += 1); } /// Free a register in `rc`. pub fn free(&mut self, rc: RegClass) { - self.toprc.get_mut(rc.toprc as usize).map( - |t| t.base_count -= 1, - ); + self.toprc + .get_mut(rc.toprc as usize) + .map(|t| t.base_count -= 1); } /// Reset all counts to 0, both base and transient. @@ -229,9 +230,9 @@ impl Pressure { pub fn take_transient(&mut self, rc: RegClass) -> Result<(), RegClassMask> { let mask = self.check_avail(rc); if mask == 0 { - self.toprc.get_mut(rc.toprc as usize).map(|t| { - t.transient_count += 1 - }); + self.toprc + .get_mut(rc.toprc as usize) + .map(|t| t.transient_count += 1); Ok(()) } else { Err(mask) diff --git a/lib/codegen/src/regalloc/register_set.rs b/lib/codegen/src/regalloc/register_set.rs index 59f312150e..b297578cae 100644 --- a/lib/codegen/src/regalloc/register_set.rs +++ b/lib/codegen/src/regalloc/register_set.rs @@ -104,9 +104,10 @@ impl RegisterSet { /// /// This assumes that unused bits are 1. pub fn interferes_with(&self, other: &Self) -> bool { - self.avail.iter().zip(&other.avail).any( - |(&x, &y)| (x | y) != !0, - ) + self.avail + .iter() + .zip(&other.avail) + .any(|(&x, &y)| (x | y) != !0) } /// Intersect this set of registers with `other`. This has the effect of removing any register @@ -203,9 +204,10 @@ impl<'a> fmt::Display for DisplayRegisterSet<'a> { bank.names .get(offset as usize) .and_then(|name| name.chars().nth(1)) - .unwrap_or_else( - || char::from_digit(u32::from(offset % 10), 10).unwrap(), - ) + .unwrap_or_else(|| char::from_digit( + u32::from(offset % 10), + 10 + ).unwrap()) )?; } } diff --git a/lib/codegen/src/regalloc/reload.rs b/lib/codegen/src/regalloc/reload.rs index 9397d1a606..ff204a4fd9 100644 --- a/lib/codegen/src/regalloc/reload.rs +++ b/lib/codegen/src/regalloc/reload.rs @@ -166,10 +166,10 @@ impl<'a> Context<'a> { if arg.affinity.is_stack() { // An incoming register parameter was spilled. Replace the parameter value // with a temporary register value that is immediately spilled. - let reg = self.cur.func.dfg.replace_ebb_param( - arg.value, - abi.value_type, - ); + let reg = self.cur + .func + .dfg + .replace_ebb_param(arg.value, abi.value_type); let affinity = Affinity::abi(&abi, self.cur.isa); self.liveness.create_dead(reg, ebb, affinity); self.insert_spill(ebb, arg.value, reg); @@ -199,9 +199,9 @@ impl<'a> Context<'a> { self.cur.use_srcloc(inst); // Get the operand constraints for `inst` that we are trying to satisfy. - let constraints = self.encinfo.operand_constraints(encoding).expect( - "Missing instruction encoding", - ); + let constraints = self.encinfo + .operand_constraints(encoding) + .expect("Missing instruction encoding"); // Identify reload candidates. debug_assert!(self.candidates.is_empty()); @@ -226,12 +226,8 @@ impl<'a> Context<'a> { // Create a live range for the new reload. let affinity = Affinity::Reg(cand.regclass.into()); self.liveness.create_dead(reg, fill, affinity); - self.liveness.extend_locally( - reg, - ebb, - inst, - &self.cur.func.layout, - ); + self.liveness + .extend_locally(reg, ebb, inst, &self.cur.func.layout); } // Rewrite instruction arguments. @@ -280,19 +276,18 @@ impl<'a> Context<'a> { // Same thing for spilled call return values. let retvals = &defs[constraints.outs.len()..]; if !retvals.is_empty() { - let sig = self.cur.func.dfg.call_signature(inst).expect( - "Extra results on non-call instruction", - ); + let sig = self.cur + .func + .dfg + .call_signature(inst) + .expect("Extra results on non-call instruction"); for (i, lv) in retvals.iter().enumerate() { let abi = self.cur.func.dfg.signatures[sig].returns[i]; debug_assert!(abi.location.is_reg()); if lv.affinity.is_stack() { let reg = self.cur.func.dfg.replace_result(lv.value, abi.value_type); - self.liveness.create_dead( - reg, - inst, - Affinity::abi(&abi, self.cur.isa), - ); + self.liveness + .create_dead(reg, inst, Affinity::abi(&abi, self.cur.isa)); self.insert_spill(ebb, lv.value, reg); } } @@ -355,12 +350,8 @@ impl<'a> Context<'a> { // Update live ranges. self.liveness.move_def_locally(stack, inst); - self.liveness.extend_locally( - reg, - ebb, - inst, - &self.cur.func.layout, - ); + self.liveness + .extend_locally(reg, ebb, inst, &self.cur.func.layout); } } diff --git a/lib/codegen/src/regalloc/solver.rs b/lib/codegen/src/regalloc/solver.rs index 80c7f862e2..33217eab86 100644 --- a/lib/codegen/src/regalloc/solver.rs +++ b/lib/codegen/src/regalloc/solver.rs @@ -297,8 +297,7 @@ impl Move { #[cfg_attr(feature = "cargo-clippy", allow(wrong_self_convention))] fn from_reg(&self) -> Option<(RegClass, RegUnit)> { match *self { - Move::Reg { rc, from, .. } | - Move::Spill { rc, from, .. } => Some((rc, from)), + Move::Reg { rc, from, .. } | Move::Spill { rc, from, .. } => Some((rc, from)), Move::Fill { .. } => None, } } @@ -306,8 +305,7 @@ impl Move { /// Get the "to" register and register class, if possible. fn to_reg(&self) -> Option<(RegClass, RegUnit)> { match *self { - Move::Reg { rc, to, .. } | - Move::Fill { rc, to, .. } => Some((rc, to)), + Move::Reg { rc, to, .. } | Move::Fill { rc, to, .. } => Some((rc, to)), Move::Spill { .. } => None, } } @@ -316,8 +314,7 @@ impl Move { fn replace_to_reg(&mut self, new: RegUnit) -> RegUnit { mem::replace( match *self { - Move::Reg { ref mut to, .. } | - Move::Fill { ref mut to, .. } => to, + Move::Reg { ref mut to, .. } | Move::Fill { ref mut to, .. } => to, Move::Spill { .. } => panic!("No to register in a spill {}", self), }, new, @@ -348,18 +345,14 @@ impl Move { /// Get the value being moved. fn value(&self) -> Value { match *self { - Move::Reg { value, .. } | - Move::Fill { value, .. } | - Move::Spill { value, .. } => value, + Move::Reg { value, .. } | Move::Fill { value, .. } | Move::Spill { value, .. } => value, } } /// Get the associated register class. fn rc(&self) -> RegClass { match *self { - Move::Reg { rc, .. } | - Move::Fill { rc, .. } | - Move::Spill { rc, .. } => rc, + Move::Reg { rc, .. } | Move::Fill { rc, .. } | Move::Spill { rc, .. } => rc, } } } @@ -372,46 +365,40 @@ impl fmt::Display for Move { from, to, rc, - } => { - write!( - f, - "{}:{}({} -> {})", - value, - rc, - rc.info.display_regunit(from), - rc.info.display_regunit(to) - ) - } + } => write!( + f, + "{}:{}({} -> {})", + value, + rc, + rc.info.display_regunit(from), + rc.info.display_regunit(to) + ), Move::Spill { value, from, to_slot, rc, - } => { - write!( - f, - "{}:{}({} -> slot {})", - value, - rc, - rc.info.display_regunit(from), - to_slot - ) - } + } => write!( + f, + "{}:{}({} -> slot {})", + value, + rc, + rc.info.display_regunit(from), + to_slot + ), Move::Fill { value, from_slot, to, rc, - } => { - write!( - f, - "{}:{}(slot {} -> {})", - value, - rc, - from_slot, - rc.info.display_regunit(to) - ) - } + } => write!( + f, + "{}:{}(slot {} -> {})", + value, + rc, + from_slot, + rc.info.display_regunit(to) + ), } } } @@ -824,9 +811,8 @@ impl Solver { /// This is similar to `add_var`, except the value doesn't have a prior register assignment. pub fn add_def(&mut self, value: Value, constraint: RegClass, is_global: bool) { debug_assert!(self.inputs_done); - self.vars.push( - Variable::new_def(value, constraint, is_global), - ); + self.vars + .push(Variable::new_def(value, constraint, is_global)); } /// Clear the `is_global` flag on all solver variables. @@ -992,9 +978,8 @@ impl Solver { // Convert all of the fixed register assignments into moves, but omit the ones that are // already in the right register. - self.moves.extend(self.assignments.values().filter_map( - Move::with_assignment, - )); + self.moves + .extend(self.assignments.values().filter_map(Move::with_assignment)); if !(self.moves.is_empty()) { dbg!("collect_moves: {}", DisplayList(&self.moves)); @@ -1029,8 +1014,7 @@ impl Solver { if let Some(j) = self.moves[i..].iter().position(|m| match m.to_reg() { Some((rc, reg)) => avail.is_avail(rc, reg), None => true, - }) - { + }) { // This move can be executed now. self.moves.swap(i, i + j); let m = &self.moves[i]; @@ -1164,9 +1148,11 @@ mod tests { // Get a register class by name. fn rc_by_name(reginfo: &RegInfo, name: &str) -> RegClass { - reginfo.classes.iter().find(|rc| rc.name == name).expect( - "Can't find named register class.", - ) + reginfo + .classes + .iter() + .find(|rc| rc.name == name) + .expect("Can't find named register class.") } // Construct a register move. diff --git a/lib/codegen/src/regalloc/spilling.rs b/lib/codegen/src/regalloc/spilling.rs index 34eb48a031..65d43e7cb3 100644 --- a/lib/codegen/src/regalloc/spilling.rs +++ b/lib/codegen/src/regalloc/spilling.rs @@ -125,10 +125,8 @@ impl<'a> Context<'a> { self.process_spills(tracker); while let Some(inst) = self.cur.next_inst() { - if let Some(constraints) = - self.encinfo.operand_constraints( - self.cur.func.encodings[inst], - ) + if let Some(constraints) = self.encinfo + .operand_constraints(self.cur.func.encodings[inst]) { self.visit_inst(inst, ebb, constraints, tracker); } else { @@ -283,13 +281,11 @@ impl<'a> Context<'a> { dbg!("Need {} reg from {} throughs", op.regclass, throughs.len()); match self.spill_candidate(mask, throughs) { Some(cand) => self.spill_reg(cand), - None => { - panic!( - "Ran out of {} registers for {}", - op.regclass, - self.cur.display_inst(inst) - ) - } + None => panic!( + "Ran out of {} registers for {}", + op.regclass, + self.cur.display_inst(inst) + ), } } } @@ -349,12 +345,11 @@ impl<'a> Context<'a> { .constraints() .fixed_value_arguments(); let args = self.cur.func.dfg.inst_variable_args(inst); - for (idx, (abi, &arg)) in - self.cur.func.dfg.signatures[sig] - .params - .iter() - .zip(args) - .enumerate() + for (idx, (abi, &arg)) in self.cur.func.dfg.signatures[sig] + .params + .iter() + .zip(args) + .enumerate() { if abi.location.is_reg() { let (rci, spilled) = match self.liveness[arg].affinity { @@ -393,9 +388,9 @@ impl<'a> Context<'a> { } else if ru.fixed { // This is a fixed register use which doesn't necessarily require a copy. // Make a copy only if this is not the first use of the value. - self.reg_uses.get(i.wrapping_sub(1)).map_or(false, |ru2| { - ru2.value == ru.value - }) + self.reg_uses + .get(i.wrapping_sub(1)) + .map_or(false, |ru2| ru2.value == ru.value) } else { false }; @@ -430,13 +425,11 @@ impl<'a> Context<'a> { ) } { Some(cand) => self.spill_reg(cand), - None => { - panic!( - "Ran out of {} registers when inserting copy before {}", - rc, - self.cur.display_inst(inst) - ) - } + None => panic!( + "Ran out of {} registers when inserting copy before {}", + rc, + self.cur.display_inst(inst) + ), } } } @@ -501,9 +494,10 @@ impl<'a> Context<'a> { } // Assign a spill slot for the whole virtual register. - let ss = self.cur.func.stack_slots.make_spill_slot( - self.cur.func.dfg.value_type(value), - ); + let ss = self.cur + .func + .stack_slots + .make_spill_slot(self.cur.func.dfg.value_type(value)); for &v in self.virtregs.congruence_class(&value) { self.liveness.spill(v); self.cur.func.locations[v] = ValueLoc::Stack(ss); diff --git a/lib/codegen/src/regalloc/virtregs.rs b/lib/codegen/src/regalloc/virtregs.rs index 58c7c380de..dbd4dceae7 100644 --- a/lib/codegen/src/regalloc/virtregs.rs +++ b/lib/codegen/src/regalloc/virtregs.rs @@ -101,10 +101,8 @@ impl VirtRegs { where 'a: 'b, { - self.get(*value).map_or_else( - || ref_slice(value), - |vr| self.values(vr), - ) + self.get(*value) + .map_or_else(|| ref_slice(value), |vr| self.values(vr)) } /// Check if `a` and `b` belong to the same congruence class. @@ -153,9 +151,9 @@ impl VirtRegs { }); // Determine the insertion position for `single`. - let index = match self.values(vreg).binary_search_by( - |&v| preorder.pre_cmp_def(v, single, func), - ) { + let index = match self.values(vreg) + .binary_search_by(|&v| preorder.pre_cmp_def(v, single, func)) + { Ok(_) => panic!("{} already in {}", single, vreg), Err(i) => i, }; @@ -181,9 +179,9 @@ impl VirtRegs { /// Allocate a new empty virtual register. fn alloc(&mut self) -> VirtReg { - self.unused_vregs.pop().unwrap_or_else(|| { - self.vregs.push(Default::default()) - }) + self.unused_vregs + .pop() + .unwrap_or_else(|| self.vregs.push(Default::default())) } /// Unify `values` into a single virtual register. diff --git a/lib/codegen/src/result.rs b/lib/codegen/src/result.rs index 9d347e351a..483b975ff4 100644 --- a/lib/codegen/src/result.rs +++ b/lib/codegen/src/result.rs @@ -12,10 +12,7 @@ pub enum CtonError { /// This always represents a bug, either in the code that generated IR for Cretonne, or a bug /// in Cretonne itself. #[fail(display = "Verifier error: {}", _0)] - Verifier( - #[cause] - verifier::Error - ), + Verifier(#[cause] verifier::Error), /// An implementation limit was exceeded. /// diff --git a/lib/codegen/src/settings.rs b/lib/codegen/src/settings.rs index 422eedc342..85a3a46b2f 100644 --- a/lib/codegen/src/settings.rs +++ b/lib/codegen/src/settings.rs @@ -22,9 +22,9 @@ use constant_hash::{probe, simple_hash}; use isa::TargetIsa; +use std::boxed::Box; use std::fmt; use std::result; -use std::boxed::Box; use std::str; /// A string-based configurator for settings groups. diff --git a/lib/codegen/src/simple_gvn.rs b/lib/codegen/src/simple_gvn.rs index ae8dd387d6..141199b3d9 100644 --- a/lib/codegen/src/simple_gvn.rs +++ b/lib/codegen/src/simple_gvn.rs @@ -9,9 +9,9 @@ use timing; /// Test whether the given opcode is unsafe to even consider for GVN. fn trivially_unsafe_for_gvn(opcode: Opcode) -> bool { - opcode.is_call() || opcode.is_branch() || opcode.is_terminator() || - opcode.is_return() || opcode.can_trap() || opcode.other_side_effects() || - opcode.can_store() || opcode.can_load() || opcode.writes_cpu_flags() + opcode.is_call() || opcode.is_branch() || opcode.is_terminator() || opcode.is_return() + || opcode.can_trap() || opcode.other_side_effects() || opcode.can_store() + || opcode.can_load() || opcode.writes_cpu_flags() } /// Perform simple GVN on `func`. diff --git a/lib/codegen/src/stack_layout.rs b/lib/codegen/src/stack_layout.rs index 3b07ee154a..e40499f976 100644 --- a/lib/codegen/src/stack_layout.rs +++ b/lib/codegen/src/stack_layout.rs @@ -55,9 +55,9 @@ pub fn layout_stack(frame: &mut StackSlots, alignment: StackSize) -> Result { + StackSlotKind::SpillSlot + | StackSlotKind::ExplicitSlot + | StackSlotKind::EmergencySlot => { // Determine the smallest alignment of any explicit or spill slot. min_align = slot.alignment(min_align); } @@ -73,20 +73,19 @@ pub fn layout_stack(frame: &mut StackSlots, alignment: StackSize) -> Result { + StackSlotKind::SpillSlot + | StackSlotKind::ExplicitSlot + | StackSlotKind::EmergencySlot => { if slot.alignment(alignment) != min_align { continue; } } - StackSlotKind::IncomingArg | - StackSlotKind::OutgoingArg => continue, + StackSlotKind::IncomingArg | StackSlotKind::OutgoingArg => continue, } - offset = offset.checked_sub(slot.size as StackOffset).ok_or( - CtonError::ImplLimitExceeded, - )?; + offset = offset + .checked_sub(slot.size as StackOffset) + .ok_or(CtonError::ImplLimitExceeded)?; // Aligning the negative offset can never cause overflow. We're only clearing bits. offset &= -(min_align as StackOffset); @@ -98,9 +97,9 @@ pub fn layout_stack(frame: &mut StackSlots, alignment: StackSize) -> Result CssaVerifier<'a> { } // Enforce topological ordering of defs in the virtual register. - if self.preorder.dominates(def_ebb, prev_ebb) && - self.domtree.dominates(def, prev_def, &self.func.layout) + if self.preorder.dominates(def_ebb, prev_ebb) + && self.domtree.dominates(def, prev_def, &self.func.layout) { return err!( val, @@ -112,8 +112,8 @@ impl<'a> CssaVerifier<'a> { let prev_def: ExpandedProgramPoint = self.func.dfg.value_def(prev_val).into(); let prev_ebb = self.func.layout.pp_ebb(prev_def); - if self.preorder.dominates(prev_ebb, def_ebb) && - self.domtree.dominates(prev_def, def, &self.func.layout) + if self.preorder.dominates(prev_ebb, def_ebb) + && self.domtree.dominates(prev_def, def, &self.func.layout) { let ctx = self.liveness.context(&self.func.layout); if self.liveness[prev_val].overlaps_def(def, def_ebb, ctx) { diff --git a/lib/codegen/src/verifier/liveness.rs b/lib/codegen/src/verifier/liveness.rs index eeb041c88a..167225f24f 100644 --- a/lib/codegen/src/verifier/liveness.rs +++ b/lib/codegen/src/verifier/liveness.rs @@ -127,8 +127,8 @@ impl<'a> LivenessVerifier<'a> { let ctx = self.liveness.context(&self.func.layout); // Check if `inst` is in the def range, not including the def itself. - if ctx.order.cmp(lr.def(), inst) == Ordering::Less && - ctx.order.cmp(inst, lr.def_local_end()) != Ordering::Greater + if ctx.order.cmp(lr.def(), inst) == Ordering::Less + && ctx.order.cmp(inst, lr.def_local_end()) != Ordering::Greater { return true; } diff --git a/lib/codegen/src/verifier/locations.rs b/lib/codegen/src/verifier/locations.rs index 7fdfcf96ce..89e2b09e9a 100644 --- a/lib/codegen/src/verifier/locations.rs +++ b/lib/codegen/src/verifier/locations.rs @@ -89,9 +89,9 @@ impl<'a> LocationVerifier<'a> { enc: isa::Encoding, divert: &RegDiversions, ) -> Result { - let constraints = self.encinfo.operand_constraints(enc).expect( - "check_enc_constraints requires a legal encoding", - ); + let constraints = self.encinfo + .operand_constraints(enc) + .expect("check_enc_constraints requires a legal encoding"); if constraints.satisfied(inst, divert, self.func) { return Ok(()); @@ -235,8 +235,8 @@ impl<'a> LocationVerifier<'a> { /// Update diversions to reflect the current instruction and check their consistency. fn update_diversions(&self, inst: ir::Inst, divert: &mut RegDiversions) -> Result { let (arg, src) = match self.func.dfg[inst] { - ir::InstructionData::RegMove { arg, src, .. } | - ir::InstructionData::RegSpill { arg, src, .. } => (arg, ir::ValueLoc::Reg(src)), + ir::InstructionData::RegMove { arg, src, .. } + | ir::InstructionData::RegSpill { arg, src, .. } => (arg, ir::ValueLoc::Reg(src)), ir::InstructionData::RegFill { arg, src, .. } => (arg, ir::ValueLoc::Stack(src)), _ => return Ok(()), }; @@ -275,12 +275,10 @@ impl<'a> LocationVerifier<'a> { let dfg = &self.func.dfg; match dfg.analyze_branch(inst) { - NotABranch => { - panic!( - "No branch information for {}", - dfg.display_inst(inst, self.isa) - ) - } + NotABranch => panic!( + "No branch information for {}", + dfg.display_inst(inst, self.isa) + ), SingleDest(ebb, _) => { for d in divert.all() { let lr = &liveness[d.value]; diff --git a/lib/codegen/src/verifier/mod.rs b/lib/codegen/src/verifier/mod.rs index 490222272e..f8644034b2 100644 --- a/lib/codegen/src/verifier/mod.rs +++ b/lib/codegen/src/verifier/mod.rs @@ -237,9 +237,8 @@ impl<'a> Verifier<'a> { let fixed_results = inst_data.opcode().constraints().fixed_results(); // var_results is 0 if we aren't a call instruction - let var_results = dfg.call_signature(inst).map_or(0, |sig| { - dfg.signatures[sig].returns.len() - }); + let var_results = dfg.call_signature(inst) + .map_or(0, |sig| dfg.signatures[sig].returns.len()); let total_results = fixed_results + var_results; // All result values for multi-valued instructions are created @@ -281,23 +280,23 @@ impl<'a> Verifier<'a> { destination, ref args, .. - } | - Branch { + } + | Branch { destination, ref args, .. - } | - BranchInt { + } + | BranchInt { destination, ref args, .. - } | - BranchFloat { + } + | BranchFloat { destination, ref args, .. - } | - BranchIcmp { + } + | BranchIcmp { destination, ref args, .. @@ -308,19 +307,22 @@ impl<'a> Verifier<'a> { BranchTable { table, .. } => { self.verify_jump_table(inst, table)?; } - Call { func_ref, ref args, .. } => { + Call { + func_ref, ref args, .. + } => { self.verify_func_ref(inst, func_ref)?; self.verify_value_list(inst, args)?; } - CallIndirect { sig_ref, ref args, .. } => { + CallIndirect { + sig_ref, ref args, .. + } => { self.verify_sig_ref(inst, sig_ref)?; self.verify_value_list(inst, args)?; } FuncAddr { func_ref, .. } => { self.verify_func_ref(inst, func_ref)?; } - StackLoad { stack_slot, .. } | - StackStore { stack_slot, .. } => { + StackLoad { stack_slot, .. } | StackStore { stack_slot, .. } => { self.verify_stack_slot(inst, stack_slot)?; } UnaryGlobalVar { global_var, .. } => { @@ -343,31 +345,31 @@ impl<'a> Verifier<'a> { } // Exhaustive list so we can't forget to add new formats - Unary { .. } | - UnaryImm { .. } | - UnaryIeee32 { .. } | - UnaryIeee64 { .. } | - UnaryBool { .. } | - Binary { .. } | - BinaryImm { .. } | - Ternary { .. } | - InsertLane { .. } | - ExtractLane { .. } | - IntCompare { .. } | - IntCompareImm { .. } | - IntCond { .. } | - FloatCompare { .. } | - FloatCond { .. } | - IntSelect { .. } | - Load { .. } | - Store { .. } | - RegMove { .. } | - CopySpecial { .. } | - Trap { .. } | - CondTrap { .. } | - IntCondTrap { .. } | - FloatCondTrap { .. } | - NullAry { .. } => {} + Unary { .. } + | UnaryImm { .. } + | UnaryIeee32 { .. } + | UnaryIeee64 { .. } + | UnaryBool { .. } + | Binary { .. } + | BinaryImm { .. } + | Ternary { .. } + | InsertLane { .. } + | ExtractLane { .. } + | IntCompare { .. } + | IntCompareImm { .. } + | IntCond { .. } + | FloatCompare { .. } + | FloatCond { .. } + | IntSelect { .. } + | Load { .. } + | Store { .. } + | RegMove { .. } + | CopySpecial { .. } + | Trap { .. } + | CondTrap { .. } + | IntCondTrap { .. } + | FloatCondTrap { .. } + | NullAry { .. } => {} } Ok(()) @@ -480,11 +482,8 @@ impl<'a> Verifier<'a> { } // Defining instruction dominates the instruction that uses the value. if is_reachable { - if !self.expected_domtree.dominates( - def_inst, - loc_inst, - &self.func.layout, - ) + if !self.expected_domtree + .dominates(def_inst, loc_inst, &self.func.layout) { return err!(loc_inst, "uses value from non-dominating {}", def_inst); } @@ -513,12 +512,9 @@ impl<'a> Verifier<'a> { ); } // The defining EBB dominates the instruction using this value. - if is_reachable && - !self.expected_domtree.dominates( - ebb, - loc_inst, - &self.func.layout, - ) + if is_reachable + && !self.expected_domtree + .dominates(ebb, loc_inst, &self.func.layout) { return err!(loc_inst, "uses value arg from non-dominating {}", ebb); } @@ -542,13 +538,11 @@ impl<'a> Verifier<'a> { Ok(()) } } - ValueDef::Param(_, _) => { - err!( - loc_inst, - "instruction result {} is not defined by the instruction", - v - ) - } + ValueDef::Param(_, _) => err!( + loc_inst, + "instruction result {} is not defined by the instruction", + v + ), } } @@ -576,12 +570,11 @@ impl<'a> Verifier<'a> { "incorrect number of Ebbs in postorder traversal" ); } - for (index, (&test_ebb, &true_ebb)) in - domtree - .cfg_postorder() - .iter() - .zip(self.expected_domtree.cfg_postorder().iter()) - .enumerate() + for (index, (&test_ebb, &true_ebb)) in domtree + .cfg_postorder() + .iter() + .zip(self.expected_domtree.cfg_postorder().iter()) + .enumerate() { if test_ebb != true_ebb { return err!( @@ -595,11 +588,8 @@ impl<'a> Verifier<'a> { } // We verify rpo_cmp on pairs of adjacent ebbs in the postorder for (&prev_ebb, &next_ebb) in domtree.cfg_postorder().iter().adjacent_pairs() { - if self.expected_domtree.rpo_cmp( - prev_ebb, - next_ebb, - &self.func.layout, - ) != Ordering::Greater + if self.expected_domtree + .rpo_cmp(prev_ebb, next_ebb, &self.func.layout) != Ordering::Greater { return err!( next_ebb, @@ -737,9 +727,11 @@ impl<'a> Verifier<'a> { fn typecheck_variable_args(&self, inst: Inst) -> Result { match self.func.dfg.analyze_branch(inst) { BranchInfo::SingleDest(ebb, _) => { - let iter = self.func.dfg.ebb_params(ebb).iter().map(|&v| { - self.func.dfg.value_type(v) - }); + let iter = self.func + .dfg + .ebb_params(ebb) + .iter() + .map(|&v| self.func.dfg.value_type(v)); self.typecheck_variable_args_iterator(inst, iter)?; } BranchInfo::Table(table) => { @@ -761,16 +753,18 @@ impl<'a> Verifier<'a> { match self.func.dfg[inst].analyze_call(&self.func.dfg.value_lists) { CallInfo::Direct(func_ref, _) => { let sig_ref = self.func.dfg.ext_funcs[func_ref].signature; - let arg_types = self.func.dfg.signatures[sig_ref].params.iter().map(|a| { - a.value_type - }); + let arg_types = self.func.dfg.signatures[sig_ref] + .params + .iter() + .map(|a| a.value_type); self.typecheck_variable_args_iterator(inst, arg_types)?; self.check_outgoing_args(inst, sig_ref)?; } CallInfo::Indirect(sig_ref, _) => { - let arg_types = self.func.dfg.signatures[sig_ref].params.iter().map(|a| { - a.value_type - }); + let arg_types = self.func.dfg.signatures[sig_ref] + .params + .iter() + .map(|a| a.value_type); self.typecheck_variable_args_iterator(inst, arg_types)?; self.check_outgoing_args(inst, sig_ref)?; } @@ -1047,8 +1041,7 @@ impl<'a> Verifier<'a> { &self.func, &self.func.dfg[inst], self.func.dfg.ctrl_typevar(inst), - ) - { + ) { if !possible_encodings.is_empty() { possible_encodings.push_str(", "); multiple_encodings = true; @@ -1119,8 +1112,7 @@ impl<'a> Verifier<'a> { fn verify_return_at_end(&self) -> Result { for ebb in self.func.layout.ebbs() { let inst = self.func.layout.last_inst(ebb).unwrap(); - if self.func.dfg[inst].opcode().is_return() && - Some(ebb) != self.func.layout.last_ebb() + if self.func.dfg[inst].opcode().is_return() && Some(ebb) != self.func.layout.last_ebb() { return err!(inst, "Internal return not allowed with return_at_end=1"); } @@ -1155,8 +1147,8 @@ impl<'a> Verifier<'a> { mod tests { use super::{Error, Verifier}; use entity::EntityList; - use ir::instructions::{InstructionData, Opcode}; use ir::Function; + use ir::instructions::{InstructionData, Opcode}; use settings; macro_rules! assert_err_with_msg { diff --git a/lib/codegen/src/write.rs b/lib/codegen/src/write.rs index 9a5be48b6f..1bd7bc3b3c 100644 --- a/lib/codegen/src/write.rs +++ b/lib/codegen/src/write.rs @@ -346,10 +346,12 @@ pub fn write_operands( write_ebb_args(w, &args[2..]) } BranchTable { arg, table, .. } => write!(w, " {}, {}", arg, table), - Call { func_ref, ref args, .. } => { - write!(w, " {}({})", func_ref, DisplayValues(args.as_slice(pool))) - } - CallIndirect { sig_ref, ref args, .. } => { + Call { + func_ref, ref args, .. + } => write!(w, " {}({})", func_ref, DisplayValues(args.as_slice(pool))), + CallIndirect { + sig_ref, ref args, .. + } => { let args = args.as_slice(pool); write!( w, @@ -360,7 +362,9 @@ pub fn write_operands( ) } FuncAddr { func_ref, .. } => write!(w, " {}", func_ref), - StackLoad { stack_slot, offset, .. } => write!(w, " {}{}", stack_slot, offset), + StackLoad { + stack_slot, offset, .. + } => write!(w, " {}{}", stack_slot, offset), StackStore { arg, stack_slot, @@ -368,7 +372,9 @@ pub fn write_operands( .. } => write!(w, " {}, {}{}", arg, stack_slot, offset), HeapAddr { heap, arg, imm, .. } => write!(w, " {}, {}, {}", heap, arg, imm), - Load { flags, arg, offset, .. } => write!(w, "{} {}{}", flags, arg, offset), + Load { + flags, arg, offset, .. + } => write!(w, "{} {}{}", flags, arg, offset), LoadComplex { flags, ref args, @@ -383,7 +389,6 @@ pub fn write_operands( DisplayValuesWithDelimiter(&args, '+'), offset ) - } Store { flags, @@ -452,8 +457,12 @@ pub fn write_operands( } Trap { code, .. } => write!(w, " {}", code), CondTrap { arg, code, .. } => write!(w, " {}, {}", arg, code), - IntCondTrap { cond, arg, code, .. } => write!(w, " {} {}, {}", cond, arg, code), - FloatCondTrap { cond, arg, code, .. } => write!(w, " {} {}, {}", cond, arg, code), + IntCondTrap { + cond, arg, code, .. + } => write!(w, " {} {}, {}", cond, arg, code), + FloatCondTrap { + cond, arg, code, .. + } => write!(w, " {} {}, {}", cond, arg, code), } } diff --git a/lib/entity/src/lib.rs b/lib/entity/src/lib.rs index 693e5d4f8c..6b27064c7d 100644 --- a/lib/entity/src/lib.rs +++ b/lib/entity/src/lib.rs @@ -33,19 +33,10 @@ #![warn(unused_import_braces)] #![cfg_attr(feature = "std", warn(unstable_features))] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))] #![cfg_attr(feature = "cargo-clippy", - allow(new_without_default, new_without_default_derive))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] - + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] // Turns on no_std and alloc features if std is not available. #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc))] diff --git a/lib/entity/src/map.rs b/lib/entity/src/map.rs index 8c09cd6486..ad8dca7e01 100644 --- a/lib/entity/src/map.rs +++ b/lib/entity/src/map.rs @@ -1,10 +1,10 @@ //! Densely numbered entity references as mapping keys. -use {EntityRef, Iter, IterMut, Keys}; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; use std::slice; use std::vec::Vec; +use {EntityRef, Iter, IterMut, Keys}; /// A mapping `K -> V` for densely indexed entity references. /// diff --git a/lib/entity/src/packed_option.rs b/lib/entity/src/packed_option.rs index 869c57bb0d..a33d9ed58e 100644 --- a/lib/entity/src/packed_option.rs +++ b/lib/entity/src/packed_option.rs @@ -33,7 +33,11 @@ impl PackedOption { /// Expand the packed option into a normal `Option`. pub fn expand(self) -> Option { - if self.is_none() { None } else { Some(self.0) } + if self.is_none() { + None + } else { + Some(self.0) + } } /// Maps a `PackedOption` to `Option` by applying a function to a contained value. diff --git a/lib/entity/src/primary.rs b/lib/entity/src/primary.rs index 805ccc6866..36b76f09d6 100644 --- a/lib/entity/src/primary.rs +++ b/lib/entity/src/primary.rs @@ -1,9 +1,9 @@ //! Densely numbered entity references as mapping keys. -use {EntityRef, Iter, IterMut, Keys}; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; use std::slice; use std::vec::Vec; +use {EntityRef, Iter, IterMut, Keys}; /// A primary mapping `K -> V` allocating dense entity references. /// diff --git a/lib/entity/src/set.rs b/lib/entity/src/set.rs index 392813401c..21f518eb66 100644 --- a/lib/entity/src/set.rs +++ b/lib/entity/src/set.rs @@ -1,8 +1,8 @@ //! Densely numbered entity references as set keys. -use {EntityRef, Keys}; use std::marker::PhantomData; use std::vec::Vec; +use {EntityRef, Keys}; /// A set of `K` for densely indexed entity references. /// diff --git a/lib/entity/src/sparse.rs b/lib/entity/src/sparse.rs index 95d0bba41b..28cbd80ad8 100644 --- a/lib/entity/src/sparse.rs +++ b/lib/entity/src/sparse.rs @@ -7,11 +7,11 @@ //! > Briggs, Torczon, *An efficient representation for sparse sets*, //! ACM Letters on Programming Languages and Systems, Volume 2, Issue 1-4, March-Dec. 1993. -use {EntityMap, EntityRef}; use std::mem; use std::slice; use std::u32; use std::vec::Vec; +use {EntityMap, EntityRef}; /// Trait for extracting keys from values stored in a `SparseMap`. /// diff --git a/lib/faerie/src/backend.rs b/lib/faerie/src/backend.rs index d338daf89b..571ed1db77 100644 --- a/lib/faerie/src/backend.rs +++ b/lib/faerie/src/backend.rs @@ -1,13 +1,13 @@ //! Defines `FaerieBackend`. use container; -use cretonne_codegen::binemit::{Addend, CodeOffset, Reloc, RelocSink, NullTrapSink}; +use cretonne_codegen::binemit::{Addend, CodeOffset, NullTrapSink, Reloc, RelocSink}; use cretonne_codegen::isa::TargetIsa; use cretonne_codegen::{self, binemit, ir}; -use cretonne_module::{Backend, DataContext, Linkage, ModuleNamespace, Init, DataDescription, - ModuleError}; -use failure::Error; +use cretonne_module::{Backend, DataContext, DataDescription, Init, Linkage, ModuleError, + ModuleNamespace}; use faerie; +use failure::Error; use std::fs::File; use target; use traps::{FaerieTrapManifest, FaerieTrapSink}; @@ -33,7 +33,6 @@ pub struct FaerieBuilder { libcall_names: Box String>, } - impl FaerieBuilder { /// Create a new `FaerieBuilder` using the given Cretonne target, that /// can be passed to @@ -89,7 +88,6 @@ impl FaerieBuilder { } } - /// A `FaerieBackend` implements `Backend` and emits ".o" files using the `faerie` library. pub struct FaerieBackend { isa: Box, @@ -192,9 +190,9 @@ impl Backend for FaerieBackend { } } - self.artifact.define(name, code).expect( - "inconsistent declaration", - ); + self.artifact + .define(name, code) + .expect("inconsistent declaration"); Ok(FaerieCompiledFunction {}) } @@ -239,8 +237,7 @@ impl Backend for FaerieBackend { } for &(offset, id, addend) in data_relocs { debug_assert_eq!( - addend, - 0, + addend, 0, "faerie doesn't support addends in data section relocations yet" ); let to = &namespace.get_data_decl(&data_decls[id]).name; @@ -253,9 +250,9 @@ impl Backend for FaerieBackend { .map_err(|e| ModuleError::Backend(format!("{}", e)))?; } - self.artifact.define(name, bytes).expect( - "inconsistent declaration", - ); + self.artifact + .define(name, bytes) + .expect("inconsistent declaration"); Ok(FaerieCompiledData {}) } @@ -346,25 +343,20 @@ fn translate_function_linkage(linkage: Linkage) -> faerie::Decl { fn translate_data_linkage(linkage: Linkage, writable: bool) -> faerie::Decl { match linkage { Linkage::Import => faerie::Decl::DataImport, - Linkage::Local => { - faerie::Decl::Data { - global: false, - writeable: writable, - } - } - Linkage::Export => { - faerie::Decl::Data { - global: true, - writeable: writable, - } - } + Linkage::Local => faerie::Decl::Data { + global: false, + writeable: writable, + }, + Linkage::Export => faerie::Decl::Data { + global: true, + writeable: writable, + }, Linkage::Preemptible => { unimplemented!("faerie doesn't support preemptible globals yet"); } } } - struct FaerieRelocSink<'a> { format: container::Format, artifact: &'a mut faerie::Artifact, diff --git a/lib/faerie/src/lib.rs b/lib/faerie/src/lib.rs index b56a3836f3..6cec1c9e52 100644 --- a/lib/faerie/src/lib.rs +++ b/lib/faerie/src/lib.rs @@ -5,18 +5,10 @@ #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] #![warn(unused_import_braces, unstable_features)] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))] #![cfg_attr(feature = "cargo-clippy", - allow(new_without_default, new_without_default_derive))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] extern crate cretonne_codegen; extern crate cretonne_module; @@ -29,5 +21,5 @@ mod container; mod target; pub mod traps; -pub use backend::{FaerieBuilder, FaerieBackend, FaerieProduct, FaerieTrapCollection}; +pub use backend::{FaerieBackend, FaerieBuilder, FaerieProduct, FaerieTrapCollection}; pub use container::Format; diff --git a/lib/faerie/src/target.rs b/lib/faerie/src/target.rs index ac597fe1a9..d6e3749430 100644 --- a/lib/faerie/src/target.rs +++ b/lib/faerie/src/target.rs @@ -13,8 +13,9 @@ pub fn translate(isa: &isa::TargetIsa) -> Result { }), "arm32" => Ok(Target::ARMv7), "arm64" => Ok(Target::ARM64), - _ => Err(ModuleError::Backend( - format!("unsupported faerie isa: {}", name), - )), + _ => Err(ModuleError::Backend(format!( + "unsupported faerie isa: {}", + name + ))), } } diff --git a/lib/faerie/src/traps.rs b/lib/faerie/src/traps.rs index 3874583ee7..e9526b757e 100644 --- a/lib/faerie/src/traps.rs +++ b/lib/faerie/src/traps.rs @@ -1,7 +1,7 @@ //! Faerie trap manifests record every `TrapCode` that cretonne outputs during code generation, //! for every function in the module. This data may be useful at runtime. -use cretonne_codegen::{ir, binemit}; +use cretonne_codegen::{binemit, ir}; /// Record of the arguments cretonne passes to `TrapSink::trap` pub struct FaerieTrapSite { @@ -23,7 +23,6 @@ pub struct FaerieTrapSink { pub sites: Vec, } - impl FaerieTrapSink { /// Create an empty `FaerieTrapSink` pub fn new(name: &str, code_size: u32) -> Self { diff --git a/lib/filetests/src/concurrent.rs b/lib/filetests/src/concurrent.rs index ac45624114..d9ee4f3c07 100644 --- a/lib/filetests/src/concurrent.rs +++ b/lib/filetests/src/concurrent.rs @@ -47,9 +47,7 @@ impl ConcurrentRunner { heartbeat_thread(reply_tx.clone()); let handles = (0..num_cpus::get()) - .map(|num| { - worker_thread(num, request_mutex.clone(), reply_tx.clone()) - }) + .map(|num| worker_thread(num, request_mutex.clone(), reply_tx.clone())) .collect(); Self { @@ -101,8 +99,10 @@ impl ConcurrentRunner { fn heartbeat_thread(replies: Sender) -> thread::JoinHandle<()> { thread::Builder::new() .name("heartbeat".to_string()) - .spawn(move || while replies.send(Reply::Tick).is_ok() { - thread::sleep(Duration::from_secs(1)); + .spawn(move || { + while replies.send(Reply::Tick).is_ok() { + thread::sleep(Duration::from_secs(1)); + } }) .unwrap() } diff --git a/lib/filetests/src/lib.rs b/lib/filetests/src/lib.rs index 30a2edc68c..e0dca34cc2 100644 --- a/lib/filetests/src/lib.rs +++ b/lib/filetests/src/lib.rs @@ -9,14 +9,9 @@ type_complexity, // Rustfmt 0.9.0 is at odds with this lint: block_in_if_condition_stmt))] -#![cfg_attr(feature="cargo-clippy", warn( - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - unicode_not_nfc, - use_self, - ))] +#![cfg_attr(feature = "cargo-clippy", + warn(mut_mut, nonminimal_bool, option_map_unwrap_or, option_map_unwrap_or_else, + unicode_not_nfc, use_self))] #[macro_use(dbg)] extern crate cretonne_codegen; diff --git a/lib/filetests/src/runner.rs b/lib/filetests/src/runner.rs index d4865b92e9..1e544ba0aa 100644 --- a/lib/filetests/src/runner.rs +++ b/lib/filetests/src/runner.rs @@ -40,15 +40,13 @@ impl Display for QueueEntry { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let p = self.path.to_string_lossy(); match self.state { - State::Done(Ok(dur)) => { - write!( - f, - "{}.{:03} {}", - dur.as_secs(), - dur.subsec_nanos() / 1_000_000, - p - ) - } + State::Done(Ok(dur)) => write!( + f, + "{}.{:03} {}", + dur.as_secs(), + dur.subsec_nanos() / 1_000_000, + p + ), State::Done(Err(ref e)) => write!(f, "FAIL {}: {}", p, e), _ => write!(f, "{}", p), } @@ -180,7 +178,11 @@ impl TestRunner { /// Report on the next in-order job, if it's done. fn report_job(&self) -> bool { let jobid = self.reported_tests; - if let Some(&QueueEntry { state: State::Done(ref result), .. }) = self.tests.get(jobid) { + if let Some(&QueueEntry { + state: State::Done(ref result), + .. + }) = self.tests.get(jobid) + { if self.verbose || result.is_err() { println!("{}", self.tests[jobid]); } @@ -283,7 +285,10 @@ impl TestRunner { let mut times = self.tests .iter() .filter_map(|entry| match *entry { - QueueEntry { state: State::Done(Ok(dur)), .. } => Some(dur), + QueueEntry { + state: State::Done(Ok(dur)), + .. + } => Some(dur), _ => None, }) .collect::>(); @@ -312,10 +317,12 @@ impl TestRunner { } for t in self.tests.iter().filter(|entry| match **entry { - QueueEntry { state: State::Done(Ok(dur)), .. } => dur > cut, + QueueEntry { + state: State::Done(Ok(dur)), + .. + } => dur > cut, _ => false, - }) - { + }) { println!("slow: {}", t) } } diff --git a/lib/filetests/src/runone.rs b/lib/filetests/src/runone.rs index 5389cfdb95..7688785a57 100644 --- a/lib/filetests/src/runone.rs +++ b/lib/filetests/src/runone.rs @@ -129,15 +129,11 @@ fn run_one_test<'a>( // Should we run the verifier before this test? if !context.verified && test.needs_verifier() { - verify_function(&func, context.flags_or_isa()).map_err( - |e| { - pretty_verifier_error(&func, isa, &e) - }, - )?; + verify_function(&func, context.flags_or_isa()) + .map_err(|e| pretty_verifier_error(&func, isa, &e))?; context.verified = true; } - test.run(func, context).map_err( - |e| format!("{}: {}", name, e), - ) + test.run(func, context) + .map_err(|e| format!("{}: {}", name, e)) } diff --git a/lib/filetests/src/subtest.rs b/lib/filetests/src/subtest.rs index 2ed560cb3f..18904d99b9 100644 --- a/lib/filetests/src/subtest.rs +++ b/lib/filetests/src/subtest.rs @@ -70,16 +70,16 @@ pub trait SubTest { /// Run filecheck on `text`, using directives extracted from `context`. pub fn run_filecheck(text: &str, context: &Context) -> Result<()> { let checker = build_filechecker(context)?; - if checker.check(text, NO_VARIABLES).map_err(|e| { - format!("filecheck: {}", e) - })? + if checker + .check(text, NO_VARIABLES) + .map_err(|e| format!("filecheck: {}", e))? { Ok(()) } else { // Filecheck mismatch. Emit an explanation as output. - let (_, explain) = checker.explain(text, NO_VARIABLES).map_err(|e| { - format!("explain: {}", e) - })?; + let (_, explain) = checker + .explain(text, NO_VARIABLES) + .map_err(|e| format!("explain: {}", e))?; Err(format!("filecheck failed:\n{}{}", checker, explain)) } } @@ -89,14 +89,14 @@ pub fn build_filechecker(context: &Context) -> Result { let mut builder = CheckerBuilder::new(); // Preamble comments apply to all functions. for comment in context.preamble_comments { - builder.directive(comment.text).map_err(|e| { - format!("filecheck: {}", e) - })?; + builder + .directive(comment.text) + .map_err(|e| format!("filecheck: {}", e))?; } for comment in &context.details.comments { - builder.directive(comment.text).map_err(|e| { - format!("filecheck: {}", e) - })?; + builder + .directive(comment.text) + .map_err(|e| format!("filecheck: {}", e))?; } Ok(builder.finish()) } diff --git a/lib/filetests/src/test_binemit.rs b/lib/filetests/src/test_binemit.rs index 332ef3e574..f6a91f61a1 100644 --- a/lib/filetests/src/test_binemit.rs +++ b/lib/filetests/src/test_binemit.rs @@ -138,9 +138,9 @@ impl SubTest for TestBinEmit { &func.dfg[inst], func.dfg.ctrl_typevar(inst), ).filter(|e| { - let recipe_constraints = &encinfo.constraints[e.recipe()]; - recipe_constraints.satisfied(inst, &divert, &func) - }); + let recipe_constraints = &encinfo.constraints[e.recipe()]; + recipe_constraints.satisfied(inst, &divert, &func) + }); if opt_level == OptLevel::Best { // Get the smallest legal encoding @@ -149,8 +149,7 @@ impl SubTest for TestBinEmit { // If not optimizing, just use the first encoding. legal_encodings.next() } - } - { + } { func.encodings[inst] = enc; } } @@ -159,9 +158,8 @@ impl SubTest for TestBinEmit { } // Relax branches and compute EBB offsets based on the encodings. - let code_size = binemit::relax_branches(&mut func, isa).map_err(|e| { - pretty_error(&func, context.isa, e) - })?; + let code_size = binemit::relax_branches(&mut func, isa) + .map_err(|e| pretty_error(&func, context.isa, e))?; // Collect all of the 'bin:' directives on instructions. let mut bins = HashMap::new(); @@ -181,8 +179,7 @@ impl SubTest for TestBinEmit { _ => { return Err(format!( "'bin:' directive on non-inst {}: {}", - comment.entity, - comment.text + comment.entity, comment.text )) } } @@ -198,8 +195,7 @@ impl SubTest for TestBinEmit { divert.clear(); // Correct header offsets should have been computed by `relax_branches()`. assert_eq!( - sink.offset, - func.offsets[ebb], + sink.offset, func.offsets[ebb], "Inconsistent {} header offset", ebb ); @@ -211,9 +207,10 @@ impl SubTest for TestBinEmit { // Send legal encodings into the emitter. if enc.is_legal() { // Generate a better error message if output locations are not specified. - if let Some(&v) = func.dfg.inst_results(inst).iter().find(|&&v| { - !func.locations[v].is_assigned() - }) + if let Some(&v) = func.dfg + .inst_results(inst) + .iter() + .find(|&&v| !func.locations[v].is_assigned()) { return Err(format!( "Missing register/stack slot for {} in {}", @@ -239,9 +236,10 @@ impl SubTest for TestBinEmit { if !enc.is_legal() { // A possible cause of an unencoded instruction is a missing location for // one of the input operands. - if let Some(&v) = func.dfg.inst_args(inst).iter().find(|&&v| { - !func.locations[v].is_assigned() - }) + if let Some(&v) = func.dfg + .inst_args(inst) + .iter() + .find(|&&v| !func.locations[v].is_assigned()) { return Err(format!( "Missing register/stack slot for {} in {}", @@ -287,8 +285,7 @@ impl SubTest for TestBinEmit { if sink.offset != code_size { return Err(format!( "Expected code size {}, got {}", - code_size, - sink.offset + code_size, sink.offset )); } diff --git a/lib/filetests/src/test_compile.rs b/lib/filetests/src/test_compile.rs index c4b737bfc6..f9b5deebd8 100644 --- a/lib/filetests/src/test_compile.rs +++ b/lib/filetests/src/test_compile.rs @@ -3,8 +3,8 @@ //! The `compile` test command runs each function through the full code generator pipeline use cretonne_codegen; -use cretonne_codegen::{binemit, ir}; use cretonne_codegen::print_errors::pretty_error; +use cretonne_codegen::{binemit, ir}; use cretonne_reader::TestCommand; use std::borrow::Cow; use std::fmt::Write; @@ -41,9 +41,9 @@ impl SubTest for TestCompile { let mut comp_ctx = cretonne_codegen::Context::new(); comp_ctx.func = func.into_owned(); - let code_size = comp_ctx.compile(isa).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, e) - })?; + let code_size = comp_ctx + .compile(isa) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, e))?; dbg!( "Generated {} bytes of code:\n{}", @@ -62,15 +62,13 @@ impl SubTest for TestCompile { if sink.offset != code_size { return Err(format!( "Expected code size {}, got {}", - code_size, - sink.offset + code_size, sink.offset )); } // Run final code through filecheck. let mut text = String::new(); - write!(&mut text, "{}", &comp_ctx.func.display(Some(isa))) - .map_err(|e| e.to_string())?; + write!(&mut text, "{}", &comp_ctx.func.display(Some(isa))).map_err(|e| e.to_string())?; run_filecheck(&text, context) } } diff --git a/lib/filetests/src/test_dce.rs b/lib/filetests/src/test_dce.rs index 14d535aca4..13bad80a7f 100644 --- a/lib/filetests/src/test_dce.rs +++ b/lib/filetests/src/test_dce.rs @@ -40,14 +40,12 @@ impl SubTest for TestDCE { comp_ctx.flowgraph(); comp_ctx.compute_loop_analysis(); - comp_ctx.dce(context.flags_or_isa()).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, Into::into(e)) - })?; + comp_ctx + .dce(context.flags_or_isa()) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?; let mut text = String::new(); - write!(&mut text, "{}", &comp_ctx.func).map_err( - |e| e.to_string(), - )?; + write!(&mut text, "{}", &comp_ctx.func).map_err(|e| e.to_string())?; run_filecheck(&text, context) } } diff --git a/lib/filetests/src/test_domtree.rs b/lib/filetests/src/test_domtree.rs index 8bf4a36cfe..cdc2a37ae4 100644 --- a/lib/filetests/src/test_domtree.rs +++ b/lib/filetests/src/test_domtree.rs @@ -55,8 +55,7 @@ impl SubTest for TestDomtree { _ => { return Err(format!( "annotation on non-inst {}: {}", - comment.entity, - comment.text + comment.entity, comment.text )) } }; @@ -77,17 +76,14 @@ impl SubTest for TestDomtree { return Err(format!( "mismatching idoms for {}:\n\ want: {}, got: {}", - src_ebb, - inst, - got_inst + src_ebb, inst, got_inst )); } None => { return Err(format!( "mismatching idoms for {}:\n\ want: {}, got: unreachable", - src_ebb, - inst + src_ebb, inst )); } _ => {} @@ -98,16 +94,16 @@ impl SubTest for TestDomtree { // Now we know that everything in `expected` is consistent with `domtree`. // All other EBB's should be either unreachable or the entry block. - for ebb in func.layout.ebbs().skip(1).filter( - |ebb| !expected.contains_key(ebb), - ) + for ebb in func.layout + .ebbs() + .skip(1) + .filter(|ebb| !expected.contains_key(ebb)) { if let Some(got_inst) = domtree.idom(ebb) { return Err(format!( "mismatching idoms for renumbered {}:\n\ want: unrechable, got: {}", - ebb, - got_inst + ebb, got_inst )); } } diff --git a/lib/filetests/src/test_legalizer.rs b/lib/filetests/src/test_legalizer.rs index cb24ba44a5..d86720612e 100644 --- a/lib/filetests/src/test_legalizer.rs +++ b/lib/filetests/src/test_legalizer.rs @@ -41,13 +41,12 @@ impl SubTest for TestLegalizer { let isa = context.isa.expect("legalizer needs an ISA"); comp_ctx.compute_cfg(); - comp_ctx.legalize(isa).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, e) - })?; + comp_ctx + .legalize(isa) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, e))?; let mut text = String::new(); - write!(&mut text, "{}", &comp_ctx.func.display(Some(isa))) - .map_err(|e| e.to_string())?; + write!(&mut text, "{}", &comp_ctx.func.display(Some(isa))).map_err(|e| e.to_string())?; run_filecheck(&text, context) } } diff --git a/lib/filetests/src/test_licm.rs b/lib/filetests/src/test_licm.rs index 3add99b1ab..a125da484f 100644 --- a/lib/filetests/src/test_licm.rs +++ b/lib/filetests/src/test_licm.rs @@ -40,14 +40,12 @@ impl SubTest for TestLICM { comp_ctx.flowgraph(); comp_ctx.compute_loop_analysis(); - comp_ctx.licm(context.flags_or_isa()).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, Into::into(e)) - })?; + comp_ctx + .licm(context.flags_or_isa()) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?; let mut text = String::new(); - write!(&mut text, "{}", &comp_ctx.func).map_err( - |e| e.to_string(), - )?; + write!(&mut text, "{}", &comp_ctx.func).map_err(|e| e.to_string())?; run_filecheck(&text, context) } } diff --git a/lib/filetests/src/test_postopt.rs b/lib/filetests/src/test_postopt.rs index 14c0060e6d..2813a1562c 100644 --- a/lib/filetests/src/test_postopt.rs +++ b/lib/filetests/src/test_postopt.rs @@ -37,14 +37,12 @@ impl SubTest for TestPostopt { let isa = context.isa.expect("postopt needs an ISA"); comp_ctx.flowgraph(); - comp_ctx.postopt(isa).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, Into::into(e)) - })?; + comp_ctx + .postopt(isa) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?; let mut text = String::new(); - write!(&mut text, "{}", &comp_ctx.func).map_err( - |e| e.to_string(), - )?; + write!(&mut text, "{}", &comp_ctx.func).map_err(|e| e.to_string())?; run_filecheck(&text, context) } } diff --git a/lib/filetests/src/test_preopt.rs b/lib/filetests/src/test_preopt.rs index f4c53ce267..7d5609b6a0 100644 --- a/lib/filetests/src/test_preopt.rs +++ b/lib/filetests/src/test_preopt.rs @@ -37,14 +37,12 @@ impl SubTest for TestPreopt { let isa = context.isa.expect("preopt needs an ISA"); comp_ctx.flowgraph(); - comp_ctx.preopt(isa).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, Into::into(e)) - })?; + comp_ctx + .preopt(isa) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?; let mut text = String::new(); - write!(&mut text, "{}", &comp_ctx.func).map_err( - |e| e.to_string(), - )?; + write!(&mut text, "{}", &comp_ctx.func).map_err(|e| e.to_string())?; run_filecheck(&text, context) } } diff --git a/lib/filetests/src/test_regalloc.rs b/lib/filetests/src/test_regalloc.rs index 5010c84ad4..3ff5134ca4 100644 --- a/lib/filetests/src/test_regalloc.rs +++ b/lib/filetests/src/test_regalloc.rs @@ -46,17 +46,16 @@ impl SubTest for TestRegalloc { comp_ctx.compute_cfg(); // TODO: Should we have an option to skip legalization? - comp_ctx.legalize(isa).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, e) - })?; + comp_ctx + .legalize(isa) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, e))?; comp_ctx.compute_domtree(); - comp_ctx.regalloc(isa).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, e) - })?; + comp_ctx + .regalloc(isa) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, e))?; let mut text = String::new(); - write!(&mut text, "{}", &comp_ctx.func.display(Some(isa))) - .map_err(|e| e.to_string())?; + write!(&mut text, "{}", &comp_ctx.func.display(Some(isa))).map_err(|e| e.to_string())?; run_filecheck(&text, context) } } diff --git a/lib/filetests/src/test_simple_gvn.rs b/lib/filetests/src/test_simple_gvn.rs index 467559eecb..54ccab6d5b 100644 --- a/lib/filetests/src/test_simple_gvn.rs +++ b/lib/filetests/src/test_simple_gvn.rs @@ -39,14 +39,12 @@ impl SubTest for TestSimpleGVN { comp_ctx.func = func.into_owned(); comp_ctx.flowgraph(); - comp_ctx.simple_gvn(context.flags_or_isa()).map_err(|e| { - pretty_error(&comp_ctx.func, context.isa, Into::into(e)) - })?; + comp_ctx + .simple_gvn(context.flags_or_isa()) + .map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?; let mut text = String::new(); - write!(&mut text, "{}", &comp_ctx.func).map_err( - |e| e.to_string(), - )?; + write!(&mut text, "{}", &comp_ctx.func).map_err(|e| e.to_string())?; run_filecheck(&text, context) } } diff --git a/lib/filetests/src/test_verifier.rs b/lib/filetests/src/test_verifier.rs index 514e988936..7b8c606ced 100644 --- a/lib/filetests/src/test_verifier.rs +++ b/lib/filetests/src/test_verifier.rs @@ -54,29 +54,24 @@ impl SubTest for TestVerifier { } match verify_function(func, context.flags_or_isa()) { - Ok(_) => { - match expected { - None => Ok(()), - Some((_, msg)) => Err(format!("passed, expected error: {}", msg)), - } - } - Err(got) => { - match expected { - None => Err(format!("verifier pass, got {}", got)), - Some((want_loc, want_msg)) if got.message.contains(want_msg) => { - if want_loc == got.location { - Ok(()) - } else { - Err(format!( - "correct error reported on {}, but wanted {}", - got.location, - want_loc - )) - } + Ok(_) => match expected { + None => Ok(()), + Some((_, msg)) => Err(format!("passed, expected error: {}", msg)), + }, + Err(got) => match expected { + None => Err(format!("verifier pass, got {}", got)), + Some((want_loc, want_msg)) if got.message.contains(want_msg) => { + if want_loc == got.location { + Ok(()) + } else { + Err(format!( + "correct error reported on {}, but wanted {}", + got.location, want_loc + )) } - Some(_) => Err(format!("mismatching error: {}", got)), } - } + Some(_) => Err(format!("mismatching error: {}", got)), + }, } } } diff --git a/lib/frontend/src/frontend.rs b/lib/frontend/src/frontend.rs index 20aac932ce..2688a1055a 100644 --- a/lib/frontend/src/frontend.rs +++ b/lib/frontend/src/frontend.rs @@ -141,7 +141,7 @@ where // instruction being inserted to add related info to the DFG and the SSA building system, // and perform debug sanity checks. fn build(self, data: InstructionData, ctrl_typevar: Type) -> (Inst, &'short mut DataFlowGraph) { -// We only insert the Ebb in the layout when an instruction is added to it + // We only insert the Ebb in the layout when an instruction is added to it self.builder.ensure_inserted_ebb(); let inst = self.builder.func.dfg.make_inst(data.clone()); @@ -154,17 +154,17 @@ where if data.opcode().is_branch() { match data.branch_destination() { Some(dest_ebb) => { -// If the user has supplied jump arguments we must adapt the arguments of -// the destination ebb + // If the user has supplied jump arguments we must adapt the arguments of + // the destination ebb self.builder.declare_successor(dest_ebb, inst); } None => { -// branch_destination() doesn't detect jump_tables -// If jump table we declare all entries successor + // branch_destination() doesn't detect jump_tables + // If jump table we declare all entries successor if let InstructionData::BranchTable { table, .. } = data { -// Unlike all other jumps/branches, jump tables are -// capable of having the same successor appear -// multiple times, so we must deduplicate. + // Unlike all other jumps/branches, jump tables are + // capable of having the same successor appear + // multiple times, so we must deduplicate. let mut unique = EntitySet::::new(); for dest_ebb in self.builder .func @@ -273,8 +273,8 @@ where pub fn switch_to_block(&mut self, ebb: Ebb) { // First we check that the previous block has been filled. debug_assert!( - self.position.is_default() || self.is_unreachable() || self.is_pristine() || - self.is_filled(), + self.position.is_default() || self.is_unreachable() || self.is_pristine() + || self.is_filled(), "you have to fill your block before switching" ); // We cannot switch to a filled block @@ -324,12 +324,9 @@ where var ) }); - self.func_ctx.ssa.use_var( - self.func, - var, - ty, - self.position.basic_block.unwrap(), - ) + self.func_ctx + .ssa + .use_var(self.func, var, ty, self.position.basic_block.unwrap()) }; self.handle_ssa_side_effects(side_effects); val @@ -339,23 +336,19 @@ where /// the same as the type registered for the variable. pub fn def_var(&mut self, var: Variable, val: Value) { debug_assert_eq!( - *self.func_ctx.types.get(var).unwrap_or_else(|| { - panic!( - "variable {:?} is used but its type has not been declared", - var - ) - }), + *self.func_ctx.types.get(var).unwrap_or_else(|| panic!( + "variable {:?} is used but its type has not been declared", + var + )), self.func.dfg.value_type(val), "declared type of variable {:?} doesn't match type of value {}", var, val ); - self.func_ctx.ssa.def_var( - var, - val, - self.position.basic_block.unwrap(), - ); + self.func_ctx + .ssa + .def_var(var, val, self.position.basic_block.unwrap()); } /// Creates a jump table in the function, to be used by `br_table` instructions. @@ -460,15 +453,17 @@ where pub fn finalize(&mut self) { // Check that all the `Ebb`s are filled and sealed. debug_assert!( - self.func_ctx.ebbs.iter().all(|(ebb, ebb_data)| { - ebb_data.pristine || self.func_ctx.ssa.is_sealed(ebb) - }), + self.func_ctx + .ebbs + .iter() + .all(|(ebb, ebb_data)| ebb_data.pristine || self.func_ctx.ssa.is_sealed(ebb)), "all blocks should be sealed before dropping a FunctionBuilder" ); debug_assert!( - self.func_ctx.ebbs.values().all(|ebb_data| { - ebb_data.pristine || ebb_data.filled - }), + self.func_ctx + .ebbs + .values() + .all(|ebb_data| ebb_data.pristine || ebb_data.filled), "all blocks should be filled before dropping a FunctionBuilder" ); @@ -527,16 +522,14 @@ where /// **Note:** You are responsible for maintaining the coherence with the arguments of /// other jump instructions. pub fn change_jump_destination(&mut self, inst: Inst, new_dest: Ebb) { - let old_dest = self.func.dfg[inst].branch_destination_mut().expect( - "you want to change the jump destination of a non-jump instruction", - ); + let old_dest = self.func.dfg[inst] + .branch_destination_mut() + .expect("you want to change the jump destination of a non-jump instruction"); let pred = self.func_ctx.ssa.remove_ebb_predecessor(*old_dest, inst); *old_dest = new_dest; - self.func_ctx.ssa.declare_ebb_predecessor( - new_dest, - pred, - inst, - ); + self.func_ctx + .ssa + .declare_ebb_predecessor(new_dest, pred, inst); } /// Returns `true` if and only if the current `Ebb` is sealed and has no predecessors declared. @@ -547,8 +540,8 @@ where None => false, Some(entry) => self.position.ebb.unwrap() == entry, }; - !is_entry && self.func_ctx.ssa.is_sealed(self.position.ebb.unwrap()) && - self.func_ctx + !is_entry && self.func_ctx.ssa.is_sealed(self.position.ebb.unwrap()) + && self.func_ctx .ssa .predecessors(self.position.ebb.unwrap()) .is_empty() @@ -582,9 +575,11 @@ where Variable: EntityRef + Debug, { fn move_to_next_basic_block(&mut self) { - self.position.basic_block = PackedOption::from(self.func_ctx.ssa.declare_ebb_body_block( - self.position.basic_block.unwrap(), - )); + self.position.basic_block = PackedOption::from( + self.func_ctx + .ssa + .declare_ebb_body_block(self.position.basic_block.unwrap()), + ); } fn fill_current_block(&mut self) { diff --git a/lib/frontend/src/lib.rs b/lib/frontend/src/lib.rs index b9880c9696..ad0760dc25 100644 --- a/lib/frontend/src/lib.rs +++ b/lib/frontend/src/lib.rs @@ -131,16 +131,9 @@ #![warn(unused_import_braces)] #![cfg_attr(feature = "std", warn(unstable_features))] #![cfg_attr(feature = "cargo-clippy", allow(new_without_default))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] +#![cfg_attr(feature = "cargo-clippy", + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc))] diff --git a/lib/frontend/src/ssa.rs b/lib/frontend/src/ssa.rs index d13b9f3d75..578264ef3a 100644 --- a/lib/frontend/src/ssa.rs +++ b/lib/frontend/src/ssa.rs @@ -102,11 +102,10 @@ impl BlockData { BlockData::EbbHeader(ref mut data) => { // This a linear complexity operation but the number of predecessors is low // in all non-pathological cases - let pred: usize = - data.predecessors - .iter() - .position(|pair| pair.1 == inst) - .expect("the predecessor you are trying to remove is not declared"); + let pred: usize = data.predecessors + .iter() + .position(|pair| pair.1 == inst) + .expect("the predecessor you are trying to remove is not declared"); data.predecessors.swap_remove(pred).0 } } @@ -173,9 +172,9 @@ where /// Tests whether an `SSABuilder` is in a cleared state. pub fn is_empty(&self) -> bool { - self.variables.is_empty() && self.blocks.is_empty() && self.ebb_headers.is_empty() && - self.calls.is_empty() && - self.results.is_empty() && self.side_effects.is_empty() + self.variables.is_empty() && self.blocks.is_empty() && self.ebb_headers.is_empty() + && self.calls.is_empty() && self.results.is_empty() + && self.side_effects.is_empty() } } @@ -493,15 +492,16 @@ where /// Initiate use lookups in all predecessors of `dest_ebb`, and arrange for a call /// to `finish_predecessors_lookup` once they complete. fn begin_predecessors_lookup(&mut self, temp_arg_val: Value, dest_ebb: Ebb) { - self.calls.push(Call::FinishPredecessorsLookup( - temp_arg_val, - dest_ebb, - )); + self.calls + .push(Call::FinishPredecessorsLookup(temp_arg_val, dest_ebb)); // Iterate over the predecessors. let mut calls = mem::replace(&mut self.calls, Vec::new()); - calls.extend(self.predecessors(dest_ebb).iter().rev().map(|&(pred, _)| { - Call::UseVar(pred) - })); + calls.extend( + self.predecessors(dest_ebb) + .iter() + .rev() + .map(|&(pred, _)| Call::UseVar(pred)), + ); self.calls = calls; } @@ -584,16 +584,15 @@ where .get(*pred_block) .unwrap() .unwrap(); - if let Some((middle_ebb, middle_block, middle_jump_inst)) = - self.append_jump_argument( - func, - *last_inst, - *pred_block, - dest_ebb, - pred_val, - temp_arg_var, - ) - { + let jump_arg = self.append_jump_argument( + func, + *last_inst, + *pred_block, + dest_ebb, + pred_val, + temp_arg_var, + ); + if let Some((middle_ebb, middle_block, middle_jump_inst)) = jump_arg { *pred_block = middle_block; *last_inst = middle_jump_inst; self.side_effects.split_ebbs_created.push(middle_ebb); diff --git a/lib/module/src/backend.rs b/lib/module/src/backend.rs index aa6439690d..82b7e3295a 100644 --- a/lib/module/src/backend.rs +++ b/lib/module/src/backend.rs @@ -2,8 +2,8 @@ use DataContext; use Linkage; -use ModuleNamespace; use ModuleError; +use ModuleNamespace; use cretonne_codegen::Context; use cretonne_codegen::isa::TargetIsa; use cretonne_codegen::{binemit, ir}; diff --git a/lib/module/src/data_context.rs b/lib/module/src/data_context.rs index 3f9c9f8061..ef327fce88 100644 --- a/lib/module/src/data_context.rs +++ b/lib/module/src/data_context.rs @@ -1,7 +1,7 @@ //! Defines `DataContext`. +use cretonne_codegen::binemit::{Addend, CodeOffset}; use cretonne_codegen::entity::PrimaryMap; -use cretonne_codegen::binemit::{CodeOffset, Addend}; use cretonne_codegen::ir; /// This specifies how data is to be initialized. @@ -145,8 +145,8 @@ impl DataContext { #[cfg(test)] mod tests { - use {DataContext, Writability, Init}; use cretonne_codegen::ir; + use {DataContext, Init, Writability}; #[test] fn basic_data_context() { @@ -202,7 +202,9 @@ mod tests { assert_eq!(description.writable, Writability::Readonly); assert_eq!( description.init, - Init::Bytes { contents: contents_clone.into_boxed_slice() } + Init::Bytes { + contents: contents_clone.into_boxed_slice() + } ); assert_eq!(description.function_decls.len(), 0); assert_eq!(description.data_decls.len(), 0); diff --git a/lib/module/src/lib.rs b/lib/module/src/lib.rs index 5ada469555..d7f9118288 100644 --- a/lib/module/src/lib.rs +++ b/lib/module/src/lib.rs @@ -3,18 +3,10 @@ #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] #![warn(unused_import_braces, unstable_features)] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))] #![cfg_attr(feature = "cargo-clippy", - allow(new_without_default, new_without_default_derive))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] #[macro_use] extern crate cretonne_codegen; @@ -28,5 +20,5 @@ mod data_context; mod module; pub use backend::Backend; -pub use data_context::{DataContext, Writability, DataDescription, Init}; -pub use module::{DataId, FuncId, FuncOrDataId, Linkage, Module, ModuleNamespace, ModuleError}; +pub use data_context::{DataContext, DataDescription, Init, Writability}; +pub use module::{DataId, FuncId, FuncOrDataId, Linkage, Module, ModuleError, ModuleNamespace}; diff --git a/lib/module/src/module.rs b/lib/module/src/module.rs index 409adf97c9..d9a7c7fda9 100644 --- a/lib/module/src/module.rs +++ b/lib/module/src/module.rs @@ -42,7 +42,6 @@ impl From for ir::ExternalName { } } - /// Linkage refers to where an entity is defined and who can see it. #[derive(Copy, Clone, PartialEq, Eq)] pub enum Linkage { @@ -60,19 +59,15 @@ impl Linkage { fn merge(a: Self, b: Self) -> Self { match a { Linkage::Export => Linkage::Export, - Linkage::Preemptible => { - match b { - Linkage::Export => Linkage::Export, - _ => Linkage::Preemptible, - } - } - Linkage::Local => { - match b { - Linkage::Export => Linkage::Export, - Linkage::Preemptible => Linkage::Preemptible, - _ => Linkage::Local, - } - } + Linkage::Preemptible => match b { + Linkage::Export => Linkage::Export, + _ => Linkage::Preemptible, + }, + Linkage::Local => match b { + Linkage::Export => Linkage::Export, + Linkage::Preemptible => Linkage::Preemptible, + _ => Linkage::Local, + }, Linkage::Import => b, } } @@ -94,7 +89,6 @@ impl Linkage { } } - /// A declared name may refer to either a function or data declaration #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] pub enum FuncOrDataId { @@ -360,19 +354,17 @@ where // TODO: Can we avoid allocating names so often? use std::collections::hash_map::Entry::*; match self.names.entry(name.to_owned()) { - Occupied(entry) => { - match *entry.get() { - FuncOrDataId::Func(id) => { - let existing = &mut self.contents.functions[id]; - existing.merge(linkage); - self.backend.declare_function(name, existing.decl.linkage); - Ok(id) - } - FuncOrDataId::Data(..) => Err( - ModuleError::IncompatibleDeclaration(name.to_owned()), - ), + Occupied(entry) => match *entry.get() { + FuncOrDataId::Func(id) => { + let existing = &mut self.contents.functions[id]; + existing.merge(linkage); + self.backend.declare_function(name, existing.decl.linkage); + Ok(id) } - } + FuncOrDataId::Data(..) => { + Err(ModuleError::IncompatibleDeclaration(name.to_owned())) + } + }, Vacant(entry) => { let id = self.contents.functions.push(ModuleFunction { decl: FunctionDeclaration { @@ -400,24 +392,19 @@ where // TODO: Can we avoid allocating names so often? use std::collections::hash_map::Entry::*; match self.names.entry(name.to_owned()) { - Occupied(entry) => { - match *entry.get() { - FuncOrDataId::Data(id) => { - let existing = &mut self.contents.data_objects[id]; - existing.merge(linkage, writable); - self.backend.declare_data( - name, - existing.decl.linkage, - existing.decl.writable, - ); - Ok(id) - } - - FuncOrDataId::Func(..) => Err( - ModuleError::IncompatibleDeclaration(name.to_owned()), - ), + Occupied(entry) => match *entry.get() { + FuncOrDataId::Data(id) => { + let existing = &mut self.contents.data_objects[id]; + existing.merge(linkage, writable); + self.backend + .declare_data(name, existing.decl.linkage, existing.decl.writable); + Ok(id) } - } + + FuncOrDataId::Func(..) => { + Err(ModuleError::IncompatibleDeclaration(name.to_owned())) + } + }, Vacant(entry) => { let id = self.contents.data_objects.push(ModuleData { decl: DataDeclaration { @@ -535,9 +522,9 @@ where "imported data cannot contain references" ); self.backend.write_data_funcaddr( - &mut info.compiled.as_mut().expect( - "`data` must refer to a defined data object", - ), + &mut info.compiled + .as_mut() + .expect("`data` must refer to a defined data object"), offset, what, ); @@ -558,9 +545,9 @@ where "imported data cannot contain references" ); self.backend.write_data_dataaddr( - &mut info.compiled.as_mut().expect( - "`data` must refer to a defined data object", - ), + &mut info.compiled + .as_mut() + .expect("`data` must refer to a defined data object"), offset, what, addend, @@ -577,10 +564,12 @@ where "imported function cannot be finalized" ); self.backend.finalize_function( - info.compiled.as_ref().expect( - "function must be compiled before it can be finalized", - ), - &ModuleNamespace:: { contents: &self.contents }, + info.compiled + .as_ref() + .expect("function must be compiled before it can be finalized"), + &ModuleNamespace:: { + contents: &self.contents, + }, ) }; self.contents.functions[func].finalized = true; @@ -597,10 +586,12 @@ where "imported data cannot be finalized" ); self.backend.finalize_data( - info.compiled.as_ref().expect( - "data object must be compiled before it can be finalized", - ), - &ModuleNamespace:: { contents: &self.contents }, + info.compiled + .as_ref() + .expect("data object must be compiled before it can be finalized"), + &ModuleNamespace:: { + contents: &self.contents, + }, ) }; self.contents.data_objects[data].finalized = true; @@ -614,20 +605,24 @@ where for info in self.contents.functions.values() { if info.decl.linkage.is_definable() && !info.finalized { self.backend.finalize_function( - info.compiled.as_ref().expect( - "function must be compiled before it can be finalized", - ), - &ModuleNamespace:: { contents: &self.contents }, + info.compiled + .as_ref() + .expect("function must be compiled before it can be finalized"), + &ModuleNamespace:: { + contents: &self.contents, + }, ); } } for info in self.contents.data_objects.values() { if info.decl.linkage.is_definable() && !info.finalized { self.backend.finalize_data( - info.compiled.as_ref().expect( - "data object must be compiled before it can be finalized", - ), - &ModuleNamespace:: { contents: &self.contents }, + info.compiled + .as_ref() + .expect("data object must be compiled before it can be finalized"), + &ModuleNamespace:: { + contents: &self.contents, + }, ); } } diff --git a/lib/native/src/lib.rs b/lib/native/src/lib.rs index 734c33d1f6..54fa134503 100644 --- a/lib/native/src/lib.rs +++ b/lib/native/src/lib.rs @@ -4,18 +4,10 @@ #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] #![warn(unused_import_braces, unstable_features)] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))] #![cfg_attr(feature = "cargo-clippy", - allow(new_without_default, new_without_default_derive))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] #![cfg_attr(not(feature = "std"), no_std)] extern crate cretonne_codegen; diff --git a/lib/reader/src/isaspec.rs b/lib/reader/src/isaspec.rs index 85b08df368..852a05b646 100644 --- a/lib/reader/src/isaspec.rs +++ b/lib/reader/src/isaspec.rs @@ -41,21 +41,17 @@ where { for opt in iter.map(TestOption::new) { match opt { - TestOption::Flag(name) => { - match config.enable(name) { - Ok(_) => {} - Err(SetError::BadName) => return err!(loc, "unknown flag '{}'", opt), - Err(_) => return err!(loc, "not a boolean flag: '{}'", opt), - } - } - TestOption::Value(name, value) => { - match config.set(name, value) { - Ok(_) => {} - Err(SetError::BadName) => return err!(loc, "unknown setting '{}'", opt), - Err(SetError::BadType) => return err!(loc, "invalid setting type: '{}'", opt), - Err(SetError::BadValue) => return err!(loc, "invalid setting value: '{}'", opt), - } - } + TestOption::Flag(name) => match config.enable(name) { + Ok(_) => {} + Err(SetError::BadName) => return err!(loc, "unknown flag '{}'", opt), + Err(_) => return err!(loc, "not a boolean flag: '{}'", opt), + }, + TestOption::Value(name, value) => match config.set(name, value) { + Ok(_) => {} + Err(SetError::BadName) => return err!(loc, "unknown setting '{}'", opt), + Err(SetError::BadType) => return err!(loc, "invalid setting type: '{}'", opt), + Err(SetError::BadValue) => return err!(loc, "invalid setting value: '{}'", opt), + }, } } Ok(()) diff --git a/lib/reader/src/lexer.rs b/lib/reader/src/lexer.rs index 17b99249fb..53a0ef8496 100644 --- a/lib/reader/src/lexer.rs +++ b/lib/reader/src/lexer.rs @@ -15,35 +15,35 @@ use std::u16; #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum Token<'a> { Comment(&'a str), - LPar, // '(' - RPar, // ')' - LBrace, // '{' - RBrace, // '}' - LBracket, // '[' - RBracket, // ']' - Minus, // '-' - Plus, // '+' - Comma, // ',' - Dot, // '.' - Colon, // ':' - Equal, // '=' - Arrow, // '->' - Float(&'a str), // Floating point immediate - Integer(&'a str), // Integer immediate - Type(types::Type), // i32, f32, b32x4, ... - Value(Value), // v12, v7 - Ebb(Ebb), // ebb3 - StackSlot(u32), // ss3 - GlobalVar(u32), // gv3 - Heap(u32), // heap2 - JumpTable(u32), // jt2 - FuncRef(u32), // fn2 - SigRef(u32), // sig2 - UserRef(u32), // u345 - Name(&'a str), // %9arbitrary_alphanum, %x3, %0, %function ... + LPar, // '(' + RPar, // ')' + LBrace, // '{' + RBrace, // '}' + LBracket, // '[' + RBracket, // ']' + Minus, // '-' + Plus, // '+' + Comma, // ',' + Dot, // '.' + Colon, // ':' + Equal, // '=' + Arrow, // '->' + Float(&'a str), // Floating point immediate + Integer(&'a str), // Integer immediate + Type(types::Type), // i32, f32, b32x4, ... + Value(Value), // v12, v7 + Ebb(Ebb), // ebb3 + StackSlot(u32), // ss3 + GlobalVar(u32), // gv3 + Heap(u32), // heap2 + JumpTable(u32), // jt2 + FuncRef(u32), // fn2 + SigRef(u32), // sig2 + UserRef(u32), // u345 + Name(&'a str), // %9arbitrary_alphanum, %x3, %0, %function ... HexSequence(&'a str), // #89AF - Identifier(&'a str), // Unrecognized identifier (opcode, enumerator, ...) - SourceLoc(&'a str), // @00c7 + Identifier(&'a str), // Unrecognized identifier (opcode, enumerator, ...) + SourceLoc(&'a str), // @00c7 } /// A `Token` with an associated location. @@ -162,7 +162,9 @@ impl<'a> Lexer<'a> { // Get the location corresponding to `lookahead`. fn loc(&self) -> Location { - Location { line_number: self.line_number } + Location { + line_number: self.line_number, + } } // Starting from `lookahead`, are we looking at `prefix`? @@ -317,9 +319,8 @@ impl<'a> Lexer<'a> { token( split_entity_name(text) .and_then(|(prefix, number)| { - Self::numbered_entity(prefix, number).or_else(|| { - Self::value_type(text, prefix, number) - }) + Self::numbered_entity(prefix, number) + .or_else(|| Self::value_type(text, prefix, number)) }) .unwrap_or_else(|| match text { "iflags" => Token::Type(types::IFLAGS), diff --git a/lib/reader/src/lib.rs b/lib/reader/src/lib.rs index 3527bbf587..b623035249 100644 --- a/lib/reader/src/lib.rs +++ b/lib/reader/src/lib.rs @@ -6,18 +6,10 @@ #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] #![warn(unused_import_braces, unstable_features)] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))] #![cfg_attr(feature = "cargo-clippy", - allow(new_without_default, new_without_default_derive))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] extern crate cretonne_codegen; diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index 40af898efc..8fadf88566 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -30,9 +30,7 @@ use testfile::{Comment, Details, TestFile}; /// Any test commands or ISA declarations are ignored. pub fn parse_functions(text: &str) -> Result> { let _tt = timing::parse_text(); - parse_test(text).map(|file| { - file.functions.into_iter().map(|(func, _)| func).collect() - }) + parse_test(text).map(|file| file.functions.into_iter().map(|(func, _)| func).collect()) } /// Parse the entire `text` as a test case file. @@ -124,9 +122,8 @@ impl<'a> Context<'a> { // Allocate a new stack slot. fn add_ss(&mut self, ss: StackSlot, data: StackSlotData, loc: &Location) -> Result<()> { while self.function.stack_slots.next_key().index() <= ss.index() { - self.function.create_stack_slot( - StackSlotData::new(StackSlotKind::SpillSlot, 0), - ); + self.function + .create_stack_slot(StackSlotData::new(StackSlotKind::SpillSlot, 0)); } self.function.stack_slots[ss] = data; self.map.def_ss(ss, loc) @@ -169,7 +166,9 @@ impl<'a> Context<'a> { base: HeapBase::ReservedReg, min_size: Imm64::new(0), guard_size: Imm64::new(0), - style: HeapStyle::Static { bound: Imm64::new(0) }, + style: HeapStyle::Static { + bound: Imm64::new(0), + }, }); } self.function.heaps[heap] = data; @@ -188,9 +187,8 @@ impl<'a> Context<'a> { // Allocate a new signature. fn add_sig(&mut self, sig: SigRef, data: Signature, loc: &Location) -> Result<()> { while self.function.dfg.signatures.next_key().index() <= sig.index() { - self.function.import_signature( - Signature::new(CallConv::Fast), - ); + self.function + .import_signature(Signature::new(CallConv::Fast)); } self.function.dfg.signatures[sig] = data; self.map.def_sig(sig, loc) @@ -325,9 +323,9 @@ impl<'a> Parser<'a> { debug_assert!(self.gathering_comments); let entity = entity.into(); self.comments.extend( - self.gathered_comments.drain(..).map(|text| { - Comment { entity, text } - }), + self.gathered_comments + .drain(..) + .map(|text| Comment { entity, text }), ); self.gathering_comments = false; } @@ -501,9 +499,8 @@ impl<'a> Parser<'a> { self.consume(); // Lexer just gives us raw text that looks like an integer. // Parse it as a u8 to check for overflow and other issues. - text.parse().map_err( - |_| self.error("expected u8 decimal immediate"), - ) + text.parse() + .map_err(|_| self.error("expected u8 decimal immediate")) } else { err!(self.loc, err_msg) } @@ -516,9 +513,8 @@ impl<'a> Parser<'a> { self.consume(); // Lexer just gives us raw text that looks like an integer. // Parse it as a i32 to check for overflow and other issues. - text.parse().map_err( - |_| self.error("expected i32 decimal immediate"), - ) + text.parse() + .map_err(|_| self.error("expected i32 decimal immediate")) } else { err!(self.loc, err_msg) } @@ -619,9 +615,8 @@ impl<'a> Parser<'a> { // The only error we anticipate from this parse is overflow, the lexer should // already have ensured that the string doesn't contain invalid characters, and // isn't empty or negative. - u16::from_str_radix(bits_str, 16).map_err(|_| { - self.error("the hex sequence given overflows the u16 type") - }) + u16::from_str_radix(bits_str, 16) + .map_err(|_| self.error("the hex sequence given overflows the u16 type")) } else { err!(self.loc, err_msg) } @@ -632,16 +627,11 @@ impl<'a> Parser<'a> { if let Some(Token::Name(name)) = self.token() { self.consume(); match isa { - Some(isa) => { - isa.register_info().parse_regunit(name).ok_or_else(|| { - self.error("invalid register name") - }) - } - None => { - name.parse().map_err( - |_| self.error("invalid register number"), - ) - } + Some(isa) => isa.register_info() + .parse_regunit(name) + .ok_or_else(|| self.error("invalid register name")), + None => name.parse() + .map_err(|_| self.error("invalid register number")), } } else { match isa { @@ -725,9 +715,7 @@ impl<'a> Parser<'a> { isaspec::parse_options(words, &mut isa_builder, &self.loc)?; // Construct a trait object with the aggregate settings. - isas.push(isa_builder.finish( - settings::Flags::new(flag_builder.clone()), - )); + isas.push(isa_builder.finish(settings::Flags::new(flag_builder.clone()))); } _ => break, } @@ -791,10 +779,7 @@ impl<'a> Parser<'a> { let mut ctx = Context::new(Function::with_name_signature(name, sig), unique_isa); // function ::= "function" name signature * "{" preamble function-body "}" - self.match_token( - Token::LBrace, - "expected '{' before function body", - )?; + self.match_token(Token::LBrace, "expected '{' before function body")?; self.token(); self.claim_gathered_comments(AnyEntity::Function); @@ -804,10 +789,7 @@ impl<'a> Parser<'a> { // function ::= "function" name signature "{" preamble * function-body "}" self.parse_function_body(&mut ctx)?; // function ::= "function" name signature "{" preamble function-body * "}" - self.match_token( - Token::RBrace, - "expected '}' after function body", - )?; + self.match_token(Token::RBrace, "expected '}' after function body")?; // Collect any comments following the end of the function, then stop gathering comments. self.start_gathering_comments(); @@ -833,9 +815,8 @@ impl<'a> Parser<'a> { match self.token() { Some(Token::Name(s)) => { self.consume(); - s.parse().map_err( - |_| self.error("invalid test case or libcall name"), - ) + s.parse() + .map_err(|_| self.error("invalid test case or libcall name")) } Some(Token::UserRef(namespace)) => { self.consume(); @@ -844,9 +825,9 @@ impl<'a> Parser<'a> { self.consume(); match self.token() { Some(Token::Integer(index_str)) => { - let index: u32 = u32::from_str_radix(index_str, 10).map_err(|_| { - self.error("the integer given overflows the u32 type") - })?; + let index: u32 = u32::from_str_radix(index_str, 10).map_err( + |_| self.error("the integer given overflows the u32 type"), + )?; self.consume(); Ok(ExternalName::user(namespace, index)) } @@ -868,18 +849,12 @@ impl<'a> Parser<'a> { // Calling convention defaults to `fast`, but can be changed. let mut sig = Signature::new(CallConv::Fast); - self.match_token( - Token::LPar, - "expected function signature: ( args... )", - )?; + self.match_token(Token::LPar, "expected function signature: ( args... )")?; // signature ::= "(" * [abi-param-list] ")" ["->" retlist] [callconv] if self.token() != Some(Token::RPar) { sig.params = self.parse_abi_param_list(unique_isa)?; } - self.match_token( - Token::RPar, - "expected ')' after function arguments", - )?; + self.match_token(Token::RPar, "expected ')' after function arguments")?; if self.optional(Token::Arrow) { sig.returns = self.parse_abi_param_list(unique_isa)?; } @@ -1001,41 +976,33 @@ impl<'a> Parser<'a> { Some(Token::StackSlot(..)) => { self.start_gathering_comments(); let loc = self.loc; - self.parse_stack_slot_decl().and_then(|(ss, dat)| { - ctx.add_ss(ss, dat, &loc) - }) + self.parse_stack_slot_decl() + .and_then(|(ss, dat)| ctx.add_ss(ss, dat, &loc)) } Some(Token::GlobalVar(..)) => { self.start_gathering_comments(); - self.parse_global_var_decl().and_then(|(gv, dat)| { - ctx.add_gv(gv, dat, &self.loc) - }) + self.parse_global_var_decl() + .and_then(|(gv, dat)| ctx.add_gv(gv, dat, &self.loc)) } Some(Token::Heap(..)) => { self.start_gathering_comments(); - self.parse_heap_decl().and_then(|(heap, dat)| { - ctx.add_heap(heap, dat, &self.loc) - }) + self.parse_heap_decl() + .and_then(|(heap, dat)| ctx.add_heap(heap, dat, &self.loc)) } Some(Token::SigRef(..)) => { self.start_gathering_comments(); - self.parse_signature_decl(ctx.unique_isa).and_then( - |(sig, dat)| { - ctx.add_sig(sig, dat, &self.loc) - }, - ) + self.parse_signature_decl(ctx.unique_isa) + .and_then(|(sig, dat)| ctx.add_sig(sig, dat, &self.loc)) } Some(Token::FuncRef(..)) => { self.start_gathering_comments(); - self.parse_function_decl(ctx).and_then(|(fn_, dat)| { - ctx.add_fn(fn_, dat, &self.loc) - }) + self.parse_function_decl(ctx) + .and_then(|(fn_, dat)| ctx.add_fn(fn_, dat, &self.loc)) } Some(Token::JumpTable(..)) => { self.start_gathering_comments(); - self.parse_jump_table_decl().and_then(|(jt, dat)| { - ctx.add_jt(jt, dat, &self.loc) - }) + self.parse_jump_table_decl() + .and_then(|(jt, dat)| ctx.add_jt(jt, dat, &self.loc)) } // More to come.. _ => return Ok(()), @@ -1052,10 +1019,7 @@ impl<'a> Parser<'a> { // | "outgoing_arg" fn parse_stack_slot_decl(&mut self) -> Result<(StackSlot, StackSlotData)> { let ss = self.match_ss("expected stack slot number: ss«n»")?; - self.match_token( - Token::Equal, - "expected '=' in stack slot declaration", - )?; + self.match_token(Token::Equal, "expected '=' in stack slot declaration")?; let kind = self.match_enum("expected stack slot kind")?; // stack-slot-decl ::= StackSlot(ss) "=" stack-slot-kind * Bytes {"," stack-slot-flag} @@ -1095,10 +1059,7 @@ impl<'a> Parser<'a> { fn parse_global_var_decl(&mut self) -> Result<(GlobalVar, GlobalVarData)> { let gv = self.match_gv("expected global variable number: gv«n»")?; - self.match_token( - Token::Equal, - "expected '=' in global variable declaration", - )?; + self.match_token(Token::Equal, "expected '=' in global variable declaration")?; let data = match self.match_any_identifier("expected global variable kind")? { "vmctx" => { @@ -1106,15 +1067,9 @@ impl<'a> Parser<'a> { GlobalVarData::VMContext { offset } } "deref" => { - self.match_token( - Token::LPar, - "expected '(' in 'deref' global variable decl", - )?; + self.match_token(Token::LPar, "expected '(' in 'deref' global variable decl")?; let base = self.match_gv("expected global variable: gv«n»")?; - self.match_token( - Token::RPar, - "expected ')' in 'deref' global variable decl", - )?; + self.match_token(Token::RPar, "expected ')' in 'deref' global variable decl")?; let offset = self.optional_offset32()?; GlobalVarData::Deref { base, offset } } @@ -1146,10 +1101,7 @@ impl<'a> Parser<'a> { // fn parse_heap_decl(&mut self) -> Result<(Heap, HeapData)> { let heap = self.match_heap("expected heap number: heap«n»")?; - self.match_token( - Token::Equal, - "expected '=' in heap declaration", - )?; + self.match_token(Token::Equal, "expected '=' in heap declaration")?; let style_name = self.match_any_identifier("expected 'static' or 'dynamic'")?; @@ -1216,10 +1168,7 @@ impl<'a> Parser<'a> { unique_isa: Option<&TargetIsa>, ) -> Result<(SigRef, Signature)> { let sig = self.match_sig("expected signature number: sig«n»")?; - self.match_token( - Token::Equal, - "expected '=' in signature decl", - )?; + self.match_token(Token::Equal, "expected '=' in signature decl")?; let data = self.parse_signature(unique_isa)?; // Collect any trailing comments. @@ -1241,10 +1190,7 @@ impl<'a> Parser<'a> { // fn parse_function_decl(&mut self, ctx: &mut Context) -> Result<(FuncRef, ExtFuncData)> { let fn_ = self.match_fn("expected function number: fn«n»")?; - self.match_token( - Token::Equal, - "expected '=' in function decl", - )?; + self.match_token(Token::Equal, "expected '=' in function decl")?; let loc = self.loc; @@ -1260,9 +1206,9 @@ impl<'a> Parser<'a> { // function-decl ::= FuncRef(fnref) "=" ["colocated"] name * signature let sig = self.parse_signature(ctx.unique_isa)?; let sigref = ctx.function.import_signature(sig); - ctx.map.def_entity(sigref.into(), &loc).expect( - "duplicate SigRef entities created", - ); + ctx.map + .def_entity(sigref.into(), &loc) + .expect("duplicate SigRef entities created"); ExtFuncData { name, signature: sigref, @@ -1299,10 +1245,7 @@ impl<'a> Parser<'a> { // jump-table-decl ::= * JumpTable(jt) "=" "jump_table" jt-entry {"," jt-entry} fn parse_jump_table_decl(&mut self) -> Result<(JumpTable, JumpTableData)> { let jt = self.match_jt()?; - self.match_token( - Token::Equal, - "expected '=' in jump_table decl", - )?; + self.match_token(Token::Equal, "expected '=' in jump_table decl")?; self.match_identifier("jump_table", "expected 'jump_table'")?; let mut data = JumpTableData::new(); @@ -1393,10 +1336,7 @@ impl<'a> Parser<'a> { if !self.optional(Token::Colon) { // ebb-header ::= Ebb(ebb) [ * ebb-params ] ":" self.parse_ebb_params(ctx, ebb)?; - self.match_token( - Token::Colon, - "expected ':' after EBB parameters", - )?; + self.match_token(Token::Colon, "expected ':' after EBB parameters")?; } // Collect any trailing comments. @@ -1405,13 +1345,12 @@ impl<'a> Parser<'a> { // extended-basic-block ::= ebb-header * { instruction } while match self.token() { - Some(Token::Value(_)) | - Some(Token::Identifier(_)) | - Some(Token::LBracket) | - Some(Token::SourceLoc(_)) => true, + Some(Token::Value(_)) + | Some(Token::Identifier(_)) + | Some(Token::LBracket) + | Some(Token::SourceLoc(_)) => true, _ => false, - } - { + } { let srcloc = self.optional_srcloc()?; let (encoding, result_locations) = self.parse_instruction_encoding(ctx)?; @@ -1434,25 +1373,11 @@ impl<'a> Parser<'a> { } Some(Token::Equal) => { self.consume(); - self.parse_instruction( - &results, - srcloc, - encoding, - result_locations, - ctx, - ebb, - )?; + self.parse_instruction(&results, srcloc, encoding, result_locations, ctx, ebb)?; } _ if !results.is_empty() => return err!(self.loc, "expected -> or ="), _ => { - self.parse_instruction( - &results, - srcloc, - encoding, - result_locations, - ctx, - ebb, - )? + self.parse_instruction(&results, srcloc, encoding, result_locations, ctx, ebb)? } } } @@ -1466,10 +1391,7 @@ impl<'a> Parser<'a> { // ebb-params ::= * "(" ebb-param { "," ebb-param } ")" fn parse_ebb_params(&mut self, ctx: &mut Context, ebb: Ebb) -> Result<()> { // ebb-params ::= * "(" ebb-param { "," ebb-param } ")" - self.match_token( - Token::LPar, - "expected '(' before EBB parameters", - )?; + self.match_token(Token::LPar, "expected '(' before EBB parameters")?; // ebb-params ::= "(" * ebb-param { "," ebb-param } ")" self.parse_ebb_param(ctx, ebb)?; @@ -1481,10 +1403,7 @@ impl<'a> Parser<'a> { } // ebb-params ::= "(" ebb-param { "," ebb-param } * ")" - self.match_token( - Token::RPar, - "expected ')' after EBB parameters", - )?; + self.match_token(Token::RPar, "expected ')' after EBB parameters")?; Ok(()) } @@ -1499,10 +1418,7 @@ impl<'a> Parser<'a> { let v = self.match_value("EBB argument must be a value")?; let v_location = self.loc; // ebb-param ::= Value(v) * ":" Type(t) arg-loc? - self.match_token( - Token::Colon, - "expected ':' after EBB argument", - )?; + self.match_token(Token::Colon, "expected ':' after EBB argument")?; // ebb-param ::= Value(v) ":" * Type(t) arg-loc? while ctx.function.dfg.num_values() <= v.index() { @@ -1518,10 +1434,7 @@ impl<'a> Parser<'a> { if self.optional(Token::LBracket) { let loc = self.parse_value_location(ctx)?; ctx.function.locations[v] = loc; - self.match_token( - Token::RBracket, - "expected ']' after value location", - )?; + self.match_token(Token::RBracket, "expected ']' after value location")?; } Ok(()) @@ -1573,9 +1486,7 @@ impl<'a> Parser<'a> { if self.optional(Token::LBracket) { // encoding_literal ::= "-" | Identifier HexSequence if !self.optional(Token::Minus) { - let recipe = self.match_any_identifier( - "expected instruction encoding or '-'", - )?; + let recipe = self.match_any_identifier("expected instruction encoding or '-'")?; let bits = self.match_hex16("expected a hex sequence")?; if let Some(recipe_index) = ctx.find_recipe_index(recipe) { @@ -1645,10 +1556,9 @@ impl<'a> Parser<'a> { } let dest = self.match_value("expected value alias")?; - ctx.function.dfg.make_value_alias_for_parser( - dest, - results[0], - ); + ctx.function + .dfg + .make_value_alias_for_parser(dest, results[0]); ctx.map.def_value(results[0], &self.loc)?; ctx.aliases.push(results[0]); Ok(()) @@ -1703,22 +1613,16 @@ impl<'a> Parser<'a> { // We still need to check that the number of result values in the source matches the opcode // or function call signature. We also need to create values with the right type for all // the instruction results. - let ctrl_typevar = self.infer_typevar( - ctx, - opcode, - explicit_ctrl_type, - &inst_data, - )?; + let ctrl_typevar = self.infer_typevar(ctx, opcode, explicit_ctrl_type, &inst_data)?; let inst = ctx.function.dfg.make_inst(inst_data); - let num_results = ctx.function.dfg.make_inst_results_for_parser( - inst, - ctrl_typevar, - results, - ); + let num_results = + ctx.function + .dfg + .make_inst_results_for_parser(inst, ctrl_typevar, results); ctx.function.layout.append_inst(inst, ebb); - ctx.map.def_entity(inst.into(), &opcode_loc).expect( - "duplicate inst references created", - ); + ctx.map + .def_entity(inst.into(), &opcode_loc) + .expect("duplicate inst references created"); if !srcloc.is_default() { ctx.function.srclocs[inst] = srcloc; @@ -1750,9 +1654,11 @@ impl<'a> Parser<'a> { } if let Some(result_locations) = result_locations { - for (&value, loc) in ctx.function.dfg.inst_results(inst).iter().zip( - result_locations, - ) + for (&value, loc) in ctx.function + .dfg + .inst_results(inst) + .iter() + .zip(result_locations) { ctx.function.locations[value] = loc; } @@ -1887,7 +1793,6 @@ impl<'a> Parser<'a> { } Ok(args) - } // Parse an optional value list enclosed in parantheses. @@ -1898,10 +1803,7 @@ impl<'a> Parser<'a> { let args = self.parse_value_list()?; - self.match_token( - Token::RPar, - "expected ')' after arguments", - )?; + self.match_token(Token::RPar, "expected ')' after arguments")?; Ok(args) } @@ -1944,10 +1846,7 @@ impl<'a> Parser<'a> { } InstructionFormat::Binary => { let lhs = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let rhs = self.match_value("expected SSA value second operand")?; InstructionData::Binary { opcode, @@ -1956,13 +1855,8 @@ impl<'a> Parser<'a> { } InstructionFormat::BinaryImm => { let lhs = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; - let rhs = self.match_imm64( - "expected immediate integer second operand", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; + let rhs = self.match_imm64("expected immediate integer second operand")?; InstructionData::BinaryImm { opcode, arg: lhs, @@ -1973,15 +1867,9 @@ impl<'a> Parser<'a> { // Names here refer to the `select` instruction. // This format is also use by `fma`. let ctrl_arg = self.match_value("expected SSA value control operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let true_arg = self.match_value("expected SSA value true operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let false_arg = self.match_value("expected SSA value false operand")?; InstructionData::Ternary { opcode, @@ -2008,10 +1896,7 @@ impl<'a> Parser<'a> { } InstructionFormat::Branch => { let ctrl_arg = self.match_value("expected SSA value control operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let ebb_num = self.match_ebb("expected branch destination EBB")?; let args = self.parse_opt_value_list()?; InstructionData::Branch { @@ -2023,10 +1908,7 @@ impl<'a> Parser<'a> { InstructionFormat::BranchInt => { let cond = self.match_enum("expected intcc condition code")?; let arg = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let ebb_num = self.match_ebb("expected branch destination EBB")?; let args = self.parse_opt_value_list()?; InstructionData::BranchInt { @@ -2039,10 +1921,7 @@ impl<'a> Parser<'a> { InstructionFormat::BranchFloat => { let cond = self.match_enum("expected floatcc condition code")?; let arg = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let ebb_num = self.match_ebb("expected branch destination EBB")?; let args = self.parse_opt_value_list()?; InstructionData::BranchFloat { @@ -2055,15 +1934,9 @@ impl<'a> Parser<'a> { InstructionFormat::BranchIcmp => { let cond = self.match_enum("expected intcc condition code")?; let lhs = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let rhs = self.match_value("expected SSA value second operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let ebb_num = self.match_ebb("expected branch destination EBB")?; let args = self.parse_opt_value_list()?; InstructionData::BranchIcmp { @@ -2075,25 +1948,16 @@ impl<'a> Parser<'a> { } InstructionFormat::BranchTable => { let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let table = self.match_jt()?; ctx.check_jt(table, &self.loc)?; InstructionData::BranchTable { opcode, arg, table } } InstructionFormat::InsertLane => { let lhs = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let lane = self.match_uimm8("expected lane number")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let rhs = self.match_value("expected SSA value last operand")?; InstructionData::InsertLane { opcode, @@ -2103,20 +1967,14 @@ impl<'a> Parser<'a> { } InstructionFormat::ExtractLane => { let arg = self.match_value("expected SSA value last operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let lane = self.match_uimm8("expected lane number")?; InstructionData::ExtractLane { opcode, lane, arg } } InstructionFormat::IntCompare => { let cond = self.match_enum("expected intcc condition code")?; let lhs = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let rhs = self.match_value("expected SSA value second operand")?; InstructionData::IntCompare { opcode, @@ -2127,10 +1985,7 @@ impl<'a> Parser<'a> { InstructionFormat::IntCompareImm => { let cond = self.match_enum("expected intcc condition code")?; let lhs = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let rhs = self.match_imm64("expected immediate second operand")?; InstructionData::IntCompareImm { opcode, @@ -2147,10 +2002,7 @@ impl<'a> Parser<'a> { InstructionFormat::FloatCompare => { let cond = self.match_enum("expected floatcc condition code")?; let lhs = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let rhs = self.match_value("expected SSA value second operand")?; InstructionData::FloatCompare { opcode, @@ -2166,15 +2018,9 @@ impl<'a> Parser<'a> { InstructionFormat::IntSelect => { let cond = self.match_enum("expected intcc condition code")?; let guard = self.match_value("expected SSA value first operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let v_true = self.match_value("expected SSA value second operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let v_false = self.match_value("expected SSA value third operand")?; InstructionData::IntSelect { opcode, @@ -2185,15 +2031,9 @@ impl<'a> Parser<'a> { InstructionFormat::Call => { let func_ref = self.match_fn("expected function reference")?; ctx.check_fn(func_ref, &self.loc)?; - self.match_token( - Token::LPar, - "expected '(' before arguments", - )?; + self.match_token(Token::LPar, "expected '(' before arguments")?; let args = self.parse_value_list()?; - self.match_token( - Token::RPar, - "expected ')' after arguments", - )?; + self.match_token(Token::RPar, "expected ')' after arguments")?; InstructionData::Call { opcode, func_ref, @@ -2203,20 +2043,11 @@ impl<'a> Parser<'a> { InstructionFormat::CallIndirect => { let sig_ref = self.match_sig("expected signature reference")?; ctx.check_sig(sig_ref, &self.loc)?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let callee = self.match_value("expected SSA value callee operand")?; - self.match_token( - Token::LPar, - "expected '(' before arguments", - )?; + self.match_token(Token::LPar, "expected '(' before arguments")?; let args = self.parse_value_list()?; - self.match_token( - Token::RPar, - "expected ')' after arguments", - )?; + self.match_token(Token::RPar, "expected ')' after arguments")?; InstructionData::CallIndirect { opcode, sig_ref, @@ -2240,10 +2071,7 @@ impl<'a> Parser<'a> { } InstructionFormat::StackStore => { let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let ss = self.match_ss("expected stack slot number: ss«n»")?; ctx.check_ss(ss, &self.loc)?; let offset = self.optional_offset32()?; @@ -2257,15 +2085,9 @@ impl<'a> Parser<'a> { InstructionFormat::HeapAddr => { let heap = self.match_heap("expected heap identifier")?; ctx.check_heap(heap, &self.loc)?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let arg = self.match_value("expected SSA value heap address")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let imm = self.match_uimm32("expected 32-bit integer size")?; InstructionData::HeapAddr { opcode, @@ -2299,10 +2121,7 @@ impl<'a> Parser<'a> { InstructionFormat::Store => { let flags = self.optional_memflags(); let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let addr = self.match_value("expected SSA value address")?; let offset = self.optional_offset32()?; InstructionData::Store { @@ -2316,10 +2135,7 @@ impl<'a> Parser<'a> { InstructionFormat::StoreComplex => { let flags = self.optional_memflags(); let src = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let args = self.parse_value_sequence()?; let offset = self.optional_offset32()?; InstructionData::StoreComplex { @@ -2331,15 +2147,9 @@ impl<'a> Parser<'a> { } InstructionFormat::RegMove => { let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let src = self.match_regunit(ctx.unique_isa)?; - self.match_token( - Token::Arrow, - "expected '->' between register units", - )?; + self.match_token(Token::Arrow, "expected '->' between register units")?; let dst = self.match_regunit(ctx.unique_isa)?; InstructionData::RegMove { opcode, @@ -2350,24 +2160,15 @@ impl<'a> Parser<'a> { } InstructionFormat::CopySpecial => { let src = self.match_regunit(ctx.unique_isa)?; - self.match_token( - Token::Arrow, - "expected '->' between register units", - )?; + self.match_token(Token::Arrow, "expected '->' between register units")?; let dst = self.match_regunit(ctx.unique_isa)?; InstructionData::CopySpecial { opcode, src, dst } } InstructionFormat::RegSpill => { let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let src = self.match_regunit(ctx.unique_isa)?; - self.match_token( - Token::Arrow, - "expected '->' before destination stack slot", - )?; + self.match_token(Token::Arrow, "expected '->' before destination stack slot")?; let dst = self.match_ss("expected stack slot number: ss«n»")?; ctx.check_ss(dst, &self.loc)?; InstructionData::RegSpill { @@ -2379,10 +2180,7 @@ impl<'a> Parser<'a> { } InstructionFormat::RegFill => { let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let src = self.match_ss("expected stack slot number: ss«n»")?; ctx.check_ss(src, &self.loc)?; self.match_token( @@ -2403,20 +2201,14 @@ impl<'a> Parser<'a> { } InstructionFormat::CondTrap => { let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let code = self.match_enum("expected trap code")?; InstructionData::CondTrap { opcode, arg, code } } InstructionFormat::IntCondTrap => { let cond = self.match_enum("expected intcc condition code")?; let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let code = self.match_enum("expected trap code")?; InstructionData::IntCondTrap { opcode, @@ -2428,10 +2220,7 @@ impl<'a> Parser<'a> { InstructionFormat::FloatCondTrap => { let cond = self.match_enum("expected floatcc condition code")?; let arg = self.match_value("expected SSA value operand")?; - self.match_token( - Token::Comma, - "expected ',' between operands", - )?; + self.match_token(Token::Comma, "expected ',' between operands")?; let code = self.match_enum("expected trap code")?; InstructionData::FloatCondTrap { opcode, @@ -2448,9 +2237,9 @@ impl<'a> Parser<'a> { #[cfg(test)] mod tests { use super::*; + use cretonne_codegen::ir::StackSlotKind; use cretonne_codegen::ir::entities::AnyEntity; use cretonne_codegen::ir::types; - use cretonne_codegen::ir::StackSlotKind; use cretonne_codegen::ir::{ArgumentExtension, ArgumentPurpose}; use cretonne_codegen::settings::CallConv; use error::Error; @@ -2695,7 +2484,8 @@ mod tests { isa riscv function %foo() system_v {}", ).unwrap() - .isa_spec { + .isa_spec + { IsaSpec::None(_) => panic!("Expected some ISA"), IsaSpec::Some(v) => { assert_eq!(v.len(), 1); diff --git a/lib/reader/src/sourcemap.rs b/lib/reader/src/sourcemap.rs index a4bc1954c1..8bd44fb6d6 100644 --- a/lib/reader/src/sourcemap.rs +++ b/lib/reader/src/sourcemap.rs @@ -65,62 +65,62 @@ impl SourceMap { /// Returns the entity reference corresponding to `name`, if it exists. pub fn lookup_str(&self, name: &str) -> Option { split_entity_name(name).and_then(|(ent, num)| match ent { - "v" => { - Value::with_number(num).and_then(|v| if !self.contains_value(v) { + "v" => Value::with_number(num).and_then(|v| { + if !self.contains_value(v) { None } else { Some(v.into()) - }) - } - "ebb" => { - Ebb::with_number(num).and_then(|ebb| if !self.contains_ebb(ebb) { + } + }), + "ebb" => Ebb::with_number(num).and_then(|ebb| { + if !self.contains_ebb(ebb) { None } else { Some(ebb.into()) - }) - } - "ss" => { - StackSlot::with_number(num).and_then(|ss| if !self.contains_ss(ss) { + } + }), + "ss" => StackSlot::with_number(num).and_then(|ss| { + if !self.contains_ss(ss) { None } else { Some(ss.into()) - }) - } - "gv" => { - GlobalVar::with_number(num).and_then(|gv| if !self.contains_gv(gv) { + } + }), + "gv" => GlobalVar::with_number(num).and_then(|gv| { + if !self.contains_gv(gv) { None } else { Some(gv.into()) - }) - } - "heap" => { - Heap::with_number(num).and_then(|heap| if !self.contains_heap(heap) { + } + }), + "heap" => Heap::with_number(num).and_then(|heap| { + if !self.contains_heap(heap) { None } else { Some(heap.into()) - }) - } - "sig" => { - SigRef::with_number(num).and_then(|sig| if !self.contains_sig(sig) { + } + }), + "sig" => SigRef::with_number(num).and_then(|sig| { + if !self.contains_sig(sig) { None } else { Some(sig.into()) - }) - } - "fn" => { - FuncRef::with_number(num).and_then(|fn_| if !self.contains_fn(fn_) { + } + }), + "fn" => FuncRef::with_number(num).and_then(|fn_| { + if !self.contains_fn(fn_) { None } else { Some(fn_.into()) - }) - } - "jt" => { - JumpTable::with_number(num).and_then(|jt| if !self.contains_jt(jt) { + } + }), + "jt" => JumpTable::with_number(num).and_then(|jt| { + if !self.contains_jt(jt) { None } else { Some(jt.into()) - }) - } + } + }), _ => None, }) } @@ -134,7 +134,9 @@ impl SourceMap { impl SourceMap { /// Create a new empty `SourceMap`. pub fn new() -> Self { - Self { locations: HashMap::new() } + Self { + locations: HashMap::new(), + } } /// Define the value `entity`. diff --git a/lib/simplejit/src/backend.rs b/lib/simplejit/src/backend.rs index 1fcfd8f93e..873578e708 100644 --- a/lib/simplejit/src/backend.rs +++ b/lib/simplejit/src/backend.rs @@ -1,17 +1,17 @@ //! Defines `SimpleJITBackend`. -use cretonne_codegen::binemit::{Addend, CodeOffset, Reloc, RelocSink, NullTrapSink}; +use cretonne_codegen::binemit::{Addend, CodeOffset, NullTrapSink, Reloc, RelocSink}; use cretonne_codegen::isa::TargetIsa; use cretonne_codegen::{self, ir, settings}; -use cretonne_module::{Backend, DataContext, Linkage, ModuleNamespace, Writability, - DataDescription, Init, ModuleError}; +use cretonne_module::{Backend, DataContext, DataDescription, Init, Linkage, ModuleError, + ModuleNamespace, Writability}; use cretonne_native; +use libc; +use memory::Memory; use std::ffi::CString; use std::ptr; -use libc; #[cfg(windows)] use winapi; -use memory::Memory; /// A builder for `SimpleJITBackend`. pub struct SimpleJITBuilder { @@ -119,9 +119,9 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { code_size: u32, ) -> Result { let size = code_size as usize; - let ptr = self.code_memory.allocate(size).expect( - "TODO: handle OOM etc.", - ); + let ptr = self.code_memory + .allocate(size) + .expect("TODO: handle OOM etc."); let mut reloc_sink = SimpleJITRelocSink::new(); // Ignore traps for now. For now, frontends should just avoid generating code // that traps. @@ -152,16 +152,12 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { let size = init.size(); let storage = match writable { - Writability::Readonly => { - self.writable_memory.allocate(size).expect( - "TODO: handle OOM etc.", - ) - } - Writability::Writable => { - self.writable_memory.allocate(size).expect( - "TODO: handle OOM etc.", - ) - } + Writability::Readonly => self.writable_memory + .allocate(size) + .expect("TODO: handle OOM etc."), + Writability::Writable => self.writable_memory + .allocate(size) + .expect("TODO: handle OOM etc."), }; match *init { @@ -262,20 +258,25 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { Reloc::Abs4 => { // TODO: Handle overflow. #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))] - unsafe { write_unaligned(at as *mut u32, what as u32) }; + unsafe { + write_unaligned(at as *mut u32, what as u32) + }; } Reloc::Abs8 => { #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))] - unsafe { write_unaligned(at as *mut u64, what as u64) }; + unsafe { + write_unaligned(at as *mut u64, what as u64) + }; } Reloc::X86PCRel4 => { // TODO: Handle overflow. let pcrel = ((what as isize) - (at as isize)) as i32; #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))] - unsafe { write_unaligned(at as *mut i32, pcrel) }; + unsafe { + write_unaligned(at as *mut i32, pcrel) + }; } - Reloc::X86GOTPCRel4 | - Reloc::X86PLTRel4 => panic!("unexpected PIC relocation"), + Reloc::X86GOTPCRel4 | Reloc::X86PLTRel4 => panic!("unexpected PIC relocation"), _ => unimplemented!(), } } @@ -322,15 +323,19 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { Reloc::Abs4 => { // TODO: Handle overflow. #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))] - unsafe { write_unaligned(at as *mut u32, what as u32) }; + unsafe { + write_unaligned(at as *mut u32, what as u32) + }; } Reloc::Abs8 => { #[cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))] - unsafe { write_unaligned(at as *mut u64, what as u64) }; + unsafe { + write_unaligned(at as *mut u64, what as u64) + }; + } + Reloc::X86PCRel4 | Reloc::X86GOTPCRel4 | Reloc::X86PLTRel4 => { + panic!("unexpected text relocation in data") } - Reloc::X86PCRel4 | - Reloc::X86GOTPCRel4 | - Reloc::X86PLTRel4 => panic!("unexpected text relocation in data"), _ => unimplemented!(), } } diff --git a/lib/simplejit/src/lib.rs b/lib/simplejit/src/lib.rs index 92c088cd71..90ee03d9d5 100644 --- a/lib/simplejit/src/lib.rs +++ b/lib/simplejit/src/lib.rs @@ -3,25 +3,17 @@ #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] #![warn(unused_import_braces, unstable_features)] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))] #![cfg_attr(feature = "cargo-clippy", - allow(new_without_default, new_without_default_derive))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] extern crate cretonne_codegen; extern crate cretonne_module; extern crate cretonne_native; extern crate errno; -extern crate region; extern crate libc; +extern crate region; #[cfg(target_os = "windows")] extern crate winapi; @@ -29,4 +21,4 @@ extern crate winapi; mod backend; mod memory; -pub use backend::{SimpleJITBuilder, SimpleJITBackend}; +pub use backend::{SimpleJITBackend, SimpleJITBuilder}; diff --git a/lib/simplejit/src/memory.rs b/lib/simplejit/src/memory.rs index 3ec2995372..b856c19009 100644 --- a/lib/simplejit/src/memory.rs +++ b/lib/simplejit/src/memory.rs @@ -1,8 +1,8 @@ -use std::mem; -use std::ptr; use errno; use libc; use region; +use std::mem; +use std::ptr; /// Round `size` up to the nearest multiple of `page_size`. fn round_up_to_page_size(size: usize, page_size: usize) -> usize { @@ -91,10 +91,8 @@ impl Memory { } fn finish_current(&mut self) { - self.allocations.push(mem::replace( - &mut self.current, - PtrLen::new(), - )); + self.allocations + .push(mem::replace(&mut self.current, PtrLen::new())); self.position = 0; } @@ -136,9 +134,8 @@ impl Memory { for &PtrLen { ptr, len } in &self.allocations[self.executable..] { if len != 0 { unsafe { - region::protect(ptr, len, region::Protection::Read).expect( - "unable to make memory readonly", - ); + region::protect(ptr, len, region::Protection::Read) + .expect("unable to make memory readonly"); } } } diff --git a/lib/umbrella/src/lib.rs b/lib/umbrella/src/lib.rs index cc1a3e1697..ebfb0c731e 100644 --- a/lib/umbrella/src/lib.rs +++ b/lib/umbrella/src/lib.rs @@ -3,18 +3,10 @@ #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] #![warn(unused_import_braces, unstable_features)] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))] #![cfg_attr(feature = "cargo-clippy", - allow(new_without_default, new_without_default_derive))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] /// Provide these crates, renamed to reduce stutter. pub extern crate cretonne_codegen as codegen; @@ -25,14 +17,13 @@ pub extern crate cretonne_frontend as frontend; pub mod prelude { pub use codegen; pub use codegen::entity::EntityRef; - pub use codegen::ir::{AbiParam, InstBuilder, Value, Ebb, Signature, Type, JumpTableData, - MemFlags, ExtFuncData, GlobalVarData, StackSlotData, StackSlotKind, - TrapCode}; - pub use codegen::ir::types; - pub use codegen::ir::condcodes::{IntCC, FloatCC}; + pub use codegen::ir::condcodes::{FloatCC, IntCC}; pub use codegen::ir::immediates::{Ieee32, Ieee64, Imm64}; - pub use codegen::settings::{self, Configurable, CallConv}; + pub use codegen::ir::types; + pub use codegen::ir::{AbiParam, Ebb, ExtFuncData, GlobalVarData, InstBuilder, JumpTableData, + MemFlags, Signature, StackSlotData, StackSlotKind, TrapCode, Type, Value}; pub use codegen::isa; + pub use codegen::settings::{self, CallConv, Configurable}; - pub use frontend::{FunctionBuilderContext, FunctionBuilder, Variable}; + pub use frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; } diff --git a/lib/wasm/src/code_translator.rs b/lib/wasm/src/code_translator.rs index dbe23c4d15..60eaf8f853 100644 --- a/lib/wasm/src/code_translator.rs +++ b/lib/wasm/src/code_translator.rs @@ -194,10 +194,9 @@ pub fn translate_operator( let frame = state.control_stack.pop().unwrap(); if !builder.is_unreachable() || !builder.is_pristine() { let return_count = frame.num_return_values(); - builder.ins().jump( - frame.following_code(), - state.peekn(return_count), - ); + builder + .ins() + .jump(frame.following_code(), state.peekn(return_count)); } builder.switch_to_block(frame.following_code()); builder.seal_block(frame.following_code()); @@ -206,9 +205,9 @@ pub fn translate_operator( builder.seal_block(header) } state.stack.truncate(frame.original_stack_size()); - state.stack.extend_from_slice( - builder.ebb_params(frame.following_code()), - ); + state + .stack + .extend_from_slice(builder.ebb_params(frame.following_code())); } /**************************** Branch instructions ********************************* * The branch instructions all have as arguments a target nesting level, which @@ -244,10 +243,9 @@ pub fn translate_operator( }; (return_count, frame.br_destination()) }; - builder.ins().jump( - br_destination, - state.peekn(return_count), - ); + builder + .ins() + .jump(br_destination, state.peekn(return_count)); state.popn(return_count); state.reachable = false; } @@ -392,67 +390,86 @@ pub fn translate_operator( let heap_index = reserved as MemoryIndex; let heap = state.get_heap(builder.func, reserved, environ); let val = state.pop1(); - state.push1(environ.translate_grow_memory( - builder.cursor(), - heap_index, - heap, - val, - )?) + state.push1(environ.translate_grow_memory(builder.cursor(), heap_index, heap, val)?) } Operator::CurrentMemory { reserved } => { let heap_index = reserved as MemoryIndex; let heap = state.get_heap(builder.func, reserved, environ); - state.push1(environ.translate_current_memory( - builder.cursor(), - heap_index, - heap, - )?); + state.push1(environ.translate_current_memory(builder.cursor(), heap_index, heap)?); } /******************************* Load instructions *********************************** * Wasm specifies an integer alignment flag but we drop it in Cretonne. * The memory base address is provided by the environment. * TODO: differentiate between 32 bit and 64 bit architecture, to put the uextend or not ************************************************************************************/ - Operator::I32Load8U { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I32Load8U { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Uload8, I32, builder, state, environ); } - Operator::I32Load16U { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I32Load16U { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Uload16, I32, builder, state, environ); } - Operator::I32Load8S { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I32Load8S { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Sload8, I32, builder, state, environ); } - Operator::I32Load16S { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I32Load16S { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Sload16, I32, builder, state, environ); } - Operator::I64Load8U { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I64Load8U { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Uload8, I64, builder, state, environ); } - Operator::I64Load16U { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I64Load16U { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Uload16, I64, builder, state, environ); } - Operator::I64Load8S { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I64Load8S { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Sload8, I64, builder, state, environ); } - Operator::I64Load16S { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I64Load16S { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Sload16, I64, builder, state, environ); } - Operator::I64Load32S { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I64Load32S { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Sload32, I64, builder, state, environ); } - Operator::I64Load32U { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I64Load32U { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Uload32, I64, builder, state, environ); } - Operator::I32Load { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I32Load { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Load, I32, builder, state, environ); } - Operator::F32Load { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::F32Load { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Load, F32, builder, state, environ); } - Operator::I64Load { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I64Load { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Load, I64, builder, state, environ); } - Operator::F64Load { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::F64Load { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_load(offset, ir::Opcode::Load, F64, builder, state, environ); } /****************************** Store instructions *********************************** @@ -460,21 +477,39 @@ pub fn translate_operator( * The memory base address is provided by the environment. * TODO: differentiate between 32 bit and 64 bit architecture, to put the uextend or not ************************************************************************************/ - Operator::I32Store { memarg: MemoryImmediate { flags: _, offset } } | - Operator::I64Store { memarg: MemoryImmediate { flags: _, offset } } | - Operator::F32Store { memarg: MemoryImmediate { flags: _, offset } } | - Operator::F64Store { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I32Store { + memarg: MemoryImmediate { flags: _, offset }, + } + | Operator::I64Store { + memarg: MemoryImmediate { flags: _, offset }, + } + | Operator::F32Store { + memarg: MemoryImmediate { flags: _, offset }, + } + | Operator::F64Store { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_store(offset, ir::Opcode::Store, builder, state, environ); } - Operator::I32Store8 { memarg: MemoryImmediate { flags: _, offset } } | - Operator::I64Store8 { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I32Store8 { + memarg: MemoryImmediate { flags: _, offset }, + } + | Operator::I64Store8 { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_store(offset, ir::Opcode::Istore8, builder, state, environ); } - Operator::I32Store16 { memarg: MemoryImmediate { flags: _, offset } } | - Operator::I64Store16 { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I32Store16 { + memarg: MemoryImmediate { flags: _, offset }, + } + | Operator::I64Store16 { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_store(offset, ir::Opcode::Istore16, builder, state, environ); } - Operator::I64Store32 { memarg: MemoryImmediate { flags: _, offset } } => { + Operator::I64Store32 { + memarg: MemoryImmediate { flags: _, offset }, + } => { translate_store(offset, ir::Opcode::Istore32, builder, state, environ); } /****************************** Nullary Operators ************************************/ @@ -495,8 +530,7 @@ pub fn translate_operator( let arg = state.pop1(); state.push1(builder.ins().ctz(arg)); } - Operator::I32Popcnt | - Operator::I64Popcnt => { + Operator::I32Popcnt | Operator::I64Popcnt => { let arg = state.pop1(); state.push1(builder.ins().popcnt(arg)); } @@ -512,28 +546,23 @@ pub fn translate_operator( let val = state.pop1(); state.push1(builder.ins().ireduce(I32, val)); } - Operator::F32Sqrt | - Operator::F64Sqrt => { + Operator::F32Sqrt | Operator::F64Sqrt => { let arg = state.pop1(); state.push1(builder.ins().sqrt(arg)); } - Operator::F32Ceil | - Operator::F64Ceil => { + Operator::F32Ceil | Operator::F64Ceil => { let arg = state.pop1(); state.push1(builder.ins().ceil(arg)); } - Operator::F32Floor | - Operator::F64Floor => { + Operator::F32Floor | Operator::F64Floor => { let arg = state.pop1(); state.push1(builder.ins().floor(arg)); } - Operator::F32Trunc | - Operator::F64Trunc => { + Operator::F32Trunc | Operator::F64Trunc => { let arg = state.pop1(); state.push1(builder.ins().trunc(arg)); } - Operator::F32Nearest | - Operator::F64Nearest => { + Operator::F32Nearest | Operator::F64Nearest => { let arg = state.pop1(); state.push1(builder.ins().nearest(arg)); } @@ -545,23 +574,19 @@ pub fn translate_operator( let arg = state.pop1(); state.push1(builder.ins().fneg(arg)); } - Operator::F64ConvertUI64 | - Operator::F64ConvertUI32 => { + Operator::F64ConvertUI64 | Operator::F64ConvertUI32 => { let val = state.pop1(); state.push1(builder.ins().fcvt_from_uint(F64, val)); } - Operator::F64ConvertSI64 | - Operator::F64ConvertSI32 => { + Operator::F64ConvertSI64 | Operator::F64ConvertSI32 => { let val = state.pop1(); state.push1(builder.ins().fcvt_from_sint(F64, val)); } - Operator::F32ConvertSI64 | - Operator::F32ConvertSI32 => { + Operator::F32ConvertSI64 | Operator::F32ConvertSI32 => { let val = state.pop1(); state.push1(builder.ins().fcvt_from_sint(F32, val)); } - Operator::F32ConvertUI64 | - Operator::F32ConvertUI32 => { + Operator::F32ConvertUI64 | Operator::F32ConvertUI32 => { let val = state.pop1(); state.push1(builder.ins().fcvt_from_uint(F32, val)); } @@ -573,34 +598,30 @@ pub fn translate_operator( let val = state.pop1(); state.push1(builder.ins().fdemote(F32, val)); } - Operator::I64TruncSF64 | - Operator::I64TruncSF32 => { + Operator::I64TruncSF64 | Operator::I64TruncSF32 => { let val = state.pop1(); state.push1(builder.ins().fcvt_to_sint(I64, val)); } - Operator::I32TruncSF64 | - Operator::I32TruncSF32 => { + Operator::I32TruncSF64 | Operator::I32TruncSF32 => { let val = state.pop1(); state.push1(builder.ins().fcvt_to_sint(I32, val)); } - Operator::I64TruncUF64 | - Operator::I64TruncUF32 => { + Operator::I64TruncUF64 | Operator::I64TruncUF32 => { let val = state.pop1(); state.push1(builder.ins().fcvt_to_uint(I64, val)); } - Operator::I32TruncUF64 | - Operator::I32TruncUF32 => { + Operator::I32TruncUF64 | Operator::I32TruncUF32 => { let val = state.pop1(); state.push1(builder.ins().fcvt_to_uint(I32, val)); } - Operator::I64TruncSSatF64 | - Operator::I64TruncSSatF32 | - Operator::I32TruncSSatF64 | - Operator::I32TruncSSatF32 | - Operator::I64TruncUSatF64 | - Operator::I64TruncUSatF32 | - Operator::I32TruncUSatF64 | - Operator::I32TruncUSatF32 => { + Operator::I64TruncSSatF64 + | Operator::I64TruncSSatF32 + | Operator::I32TruncSSatF64 + | Operator::I32TruncSSatF32 + | Operator::I64TruncUSatF64 + | Operator::I64TruncUSatF32 + | Operator::I32TruncUSatF64 + | Operator::I32TruncUSatF32 => { panic!("proposed saturating conversion operators not yet supported"); } Operator::F32ReinterpretI32 => { @@ -670,23 +691,19 @@ pub fn translate_operator( let (arg1, arg2) = state.pop2(); state.push1(builder.ins().ishl(arg1, arg2)); } - Operator::I32ShrS | - Operator::I64ShrS => { + Operator::I32ShrS | Operator::I64ShrS => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().sshr(arg1, arg2)); } - Operator::I32ShrU | - Operator::I64ShrU => { + Operator::I32ShrU | Operator::I64ShrU => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().ushr(arg1, arg2)); } - Operator::I32Rotl | - Operator::I64Rotl => { + Operator::I32Rotl | Operator::I64Rotl => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().rotl(arg1, arg2)); } - Operator::I32Rotr | - Operator::I64Rotr => { + Operator::I32Rotr | Operator::I64Rotr => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().rotr(arg1, arg2)); } @@ -714,23 +731,19 @@ pub fn translate_operator( let (arg1, arg2) = state.pop2(); state.push1(builder.ins().fdiv(arg1, arg2)); } - Operator::I32DivS | - Operator::I64DivS => { + Operator::I32DivS | Operator::I64DivS => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().sdiv(arg1, arg2)); } - Operator::I32DivU | - Operator::I64DivU => { + Operator::I32DivU | Operator::I64DivU => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().udiv(arg1, arg2)); } - Operator::I32RemS | - Operator::I64RemS => { + Operator::I32RemS | Operator::I64RemS => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().srem(arg1, arg2)); } - Operator::I32RemU | - Operator::I64RemU => { + Operator::I32RemU | Operator::I64RemU => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().urem(arg1, arg2)); } @@ -742,8 +755,7 @@ pub fn translate_operator( let (arg1, arg2) = state.pop2(); state.push1(builder.ins().fmax(arg1, arg2)); } - Operator::F32Copysign | - Operator::F64Copysign => { + Operator::F32Copysign | Operator::F64Copysign => { let (arg1, arg2) = state.pop2(); state.push1(builder.ins().fcopysign(arg1, arg2)); } @@ -789,72 +801,72 @@ pub fn translate_operator( Operator::F32Le | Operator::F64Le => { translate_fcmp(FloatCC::LessThanOrEqual, builder, state) } - Operator::Wake { .. } | - Operator::I32Wait { .. } | - Operator::I64Wait { .. } | - Operator::I32AtomicLoad { .. } | - Operator::I64AtomicLoad { .. } | - Operator::I32AtomicLoad8U { .. } | - Operator::I32AtomicLoad16U { .. } | - Operator::I64AtomicLoad8U { .. } | - Operator::I64AtomicLoad16U { .. } | - Operator::I64AtomicLoad32U { .. } | - Operator::I32AtomicStore { .. } | - Operator::I64AtomicStore { .. } | - Operator::I32AtomicStore8 { .. } | - Operator::I32AtomicStore16 { .. } | - Operator::I64AtomicStore8 { .. } | - Operator::I64AtomicStore16 { .. } | - Operator::I64AtomicStore32 { .. } | - Operator::I32AtomicRmwAdd { .. } | - Operator::I64AtomicRmwAdd { .. } | - Operator::I32AtomicRmw8UAdd { .. } | - Operator::I32AtomicRmw16UAdd { .. } | - Operator::I64AtomicRmw8UAdd { .. } | - Operator::I64AtomicRmw16UAdd { .. } | - Operator::I64AtomicRmw32UAdd { .. } | - Operator::I32AtomicRmwSub { .. } | - Operator::I64AtomicRmwSub { .. } | - Operator::I32AtomicRmw8USub { .. } | - Operator::I32AtomicRmw16USub { .. } | - Operator::I64AtomicRmw8USub { .. } | - Operator::I64AtomicRmw16USub { .. } | - Operator::I64AtomicRmw32USub { .. } | - Operator::I32AtomicRmwAnd { .. } | - Operator::I64AtomicRmwAnd { .. } | - Operator::I32AtomicRmw8UAnd { .. } | - Operator::I32AtomicRmw16UAnd { .. } | - Operator::I64AtomicRmw8UAnd { .. } | - Operator::I64AtomicRmw16UAnd { .. } | - Operator::I64AtomicRmw32UAnd { .. } | - Operator::I32AtomicRmwOr { .. } | - Operator::I64AtomicRmwOr { .. } | - Operator::I32AtomicRmw8UOr { .. } | - Operator::I32AtomicRmw16UOr { .. } | - Operator::I64AtomicRmw8UOr { .. } | - Operator::I64AtomicRmw16UOr { .. } | - Operator::I64AtomicRmw32UOr { .. } | - Operator::I32AtomicRmwXor { .. } | - Operator::I64AtomicRmwXor { .. } | - Operator::I32AtomicRmw8UXor { .. } | - Operator::I32AtomicRmw16UXor { .. } | - Operator::I64AtomicRmw8UXor { .. } | - Operator::I64AtomicRmw16UXor { .. } | - Operator::I64AtomicRmw32UXor { .. } | - Operator::I32AtomicRmwXchg { .. } | - Operator::I64AtomicRmwXchg { .. } | - Operator::I32AtomicRmw8UXchg { .. } | - Operator::I32AtomicRmw16UXchg { .. } | - Operator::I64AtomicRmw8UXchg { .. } | - Operator::I64AtomicRmw16UXchg { .. } | - Operator::I64AtomicRmw32UXchg { .. } | - Operator::I32AtomicRmwCmpxchg { .. } | - Operator::I64AtomicRmwCmpxchg { .. } | - Operator::I32AtomicRmw8UCmpxchg { .. } | - Operator::I32AtomicRmw16UCmpxchg { .. } | - Operator::I64AtomicRmw8UCmpxchg { .. } | - Operator::I64AtomicRmw16UCmpxchg { .. } | - Operator::I64AtomicRmw32UCmpxchg { .. } => { + Operator::Wake { .. } + | Operator::I32Wait { .. } + | Operator::I64Wait { .. } + | Operator::I32AtomicLoad { .. } + | Operator::I64AtomicLoad { .. } + | Operator::I32AtomicLoad8U { .. } + | Operator::I32AtomicLoad16U { .. } + | Operator::I64AtomicLoad8U { .. } + | Operator::I64AtomicLoad16U { .. } + | Operator::I64AtomicLoad32U { .. } + | Operator::I32AtomicStore { .. } + | Operator::I64AtomicStore { .. } + | Operator::I32AtomicStore8 { .. } + | Operator::I32AtomicStore16 { .. } + | Operator::I64AtomicStore8 { .. } + | Operator::I64AtomicStore16 { .. } + | Operator::I64AtomicStore32 { .. } + | Operator::I32AtomicRmwAdd { .. } + | Operator::I64AtomicRmwAdd { .. } + | Operator::I32AtomicRmw8UAdd { .. } + | Operator::I32AtomicRmw16UAdd { .. } + | Operator::I64AtomicRmw8UAdd { .. } + | Operator::I64AtomicRmw16UAdd { .. } + | Operator::I64AtomicRmw32UAdd { .. } + | Operator::I32AtomicRmwSub { .. } + | Operator::I64AtomicRmwSub { .. } + | Operator::I32AtomicRmw8USub { .. } + | Operator::I32AtomicRmw16USub { .. } + | Operator::I64AtomicRmw8USub { .. } + | Operator::I64AtomicRmw16USub { .. } + | Operator::I64AtomicRmw32USub { .. } + | Operator::I32AtomicRmwAnd { .. } + | Operator::I64AtomicRmwAnd { .. } + | Operator::I32AtomicRmw8UAnd { .. } + | Operator::I32AtomicRmw16UAnd { .. } + | Operator::I64AtomicRmw8UAnd { .. } + | Operator::I64AtomicRmw16UAnd { .. } + | Operator::I64AtomicRmw32UAnd { .. } + | Operator::I32AtomicRmwOr { .. } + | Operator::I64AtomicRmwOr { .. } + | Operator::I32AtomicRmw8UOr { .. } + | Operator::I32AtomicRmw16UOr { .. } + | Operator::I64AtomicRmw8UOr { .. } + | Operator::I64AtomicRmw16UOr { .. } + | Operator::I64AtomicRmw32UOr { .. } + | Operator::I32AtomicRmwXor { .. } + | Operator::I64AtomicRmwXor { .. } + | Operator::I32AtomicRmw8UXor { .. } + | Operator::I32AtomicRmw16UXor { .. } + | Operator::I64AtomicRmw8UXor { .. } + | Operator::I64AtomicRmw16UXor { .. } + | Operator::I64AtomicRmw32UXor { .. } + | Operator::I32AtomicRmwXchg { .. } + | Operator::I64AtomicRmwXchg { .. } + | Operator::I32AtomicRmw8UXchg { .. } + | Operator::I32AtomicRmw16UXchg { .. } + | Operator::I64AtomicRmw8UXchg { .. } + | Operator::I64AtomicRmw16UXchg { .. } + | Operator::I64AtomicRmw32UXchg { .. } + | Operator::I32AtomicRmwCmpxchg { .. } + | Operator::I64AtomicRmwCmpxchg { .. } + | Operator::I32AtomicRmw8UCmpxchg { .. } + | Operator::I32AtomicRmw16UCmpxchg { .. } + | Operator::I64AtomicRmw8UCmpxchg { .. } + | Operator::I64AtomicRmw16UCmpxchg { .. } + | Operator::I64AtomicRmw32UCmpxchg { .. } => { panic!("proposed thread operators not yet supported"); } }) @@ -876,8 +888,7 @@ fn translate_unreachable_operator( // so we don't have any branches anywhere. state.push_if(ir::Inst::reserved_value(), ir::Ebb::reserved_value(), 0); } - Operator::Loop { ty: _ } | - Operator::Block { ty: _ } => { + Operator::Loop { ty: _ } | Operator::Block { ty: _ } => { state.push_block(ir::Ebb::reserved_value(), 0); } Operator::Else => { @@ -919,7 +930,9 @@ fn translate_unreachable_operator( // And loops can't have branches to the end. false } - ControlStackFrame::If { reachable_from_top, .. } => { + ControlStackFrame::If { + reachable_from_top, .. + } => { // A reachable if without an else has a branch from the top // directly to the bottom. reachable_from_top @@ -998,13 +1011,9 @@ fn translate_load( // alignment immediate says it's aligned, because WebAssembly's immediate // field is just a hint, while Cretonne's aligned flag needs a guarantee. let flags = MemFlags::new(); - let (load, dfg) = builder.ins().Load( - opcode, - result_ty, - flags, - offset.into(), - base, - ); + let (load, dfg) = builder + .ins() + .Load(opcode, result_ty, flags, offset.into(), base); state.push1(dfg.first_result(load)); } @@ -1024,14 +1033,9 @@ fn translate_store( let (base, offset) = get_heap_addr(heap, addr32, offset, environ.native_pointer(), builder); // See the comments in `translate_load` about the flags. let flags = MemFlags::new(); - builder.ins().Store( - opcode, - val_ty, - flags, - offset.into(), - val, - base, - ); + builder + .ins() + .Store(opcode, val_ty, flags, offset.into(), val, base); } fn translate_icmp( diff --git a/lib/wasm/src/environ/dummy.rs b/lib/wasm/src/environ/dummy.rs index 90f1af3b5a..8eae69fc2b 100644 --- a/lib/wasm/src/environ/dummy.rs +++ b/lib/wasm/src/environ/dummy.rs @@ -165,7 +165,9 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ base: ir::HeapBase::GlobalVar(gv), min_size: 0.into(), guard_size: 0x8000_0000.into(), - style: ir::HeapStyle::Static { bound: 0x1_0000_0000.into() }, + style: ir::HeapStyle::Static { + bound: 0x1_0000_0000.into(), + }, }) } @@ -224,11 +226,9 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ args.extend(call_args.iter().cloned(), &mut pos.func.dfg.value_lists); args.push(vmctx, &mut pos.func.dfg.value_lists); - Ok( - pos.ins() - .CallIndirect(ir::Opcode::CallIndirect, VOID, sig_ref, args) - .0, - ) + Ok(pos.ins() + .CallIndirect(ir::Opcode::CallIndirect, VOID, sig_ref, args) + .0) } fn translate_call( @@ -301,10 +301,9 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { "Imported functions must be declared first" ); self.info.functions.push(Exportable::new(sig_index)); - self.info.imported_funcs.push(( - String::from(module), - String::from(field), - )); + self.info + .imported_funcs + .push((String::from(module), String::from(field))); } fn get_num_func_imports(&self) -> usize { @@ -353,33 +352,27 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { } fn declare_func_export(&mut self, func_index: FunctionIndex, name: &'data str) { - self.info.functions[func_index].export_names.push( - String::from( - name, - ), - ); + self.info.functions[func_index] + .export_names + .push(String::from(name)); } fn declare_table_export(&mut self, table_index: TableIndex, name: &'data str) { - self.info.tables[table_index].export_names.push( - String::from(name), - ); + self.info.tables[table_index] + .export_names + .push(String::from(name)); } fn declare_memory_export(&mut self, memory_index: MemoryIndex, name: &'data str) { - self.info.memories[memory_index].export_names.push( - String::from( - name, - ), - ); + self.info.memories[memory_index] + .export_names + .push(String::from(name)); } fn declare_global_export(&mut self, global_index: GlobalIndex, name: &'data str) { - self.info.globals[global_index].export_names.push( - String::from( - name, - ), - ); + self.info.globals[global_index] + .export_names + .push(String::from(name)); } fn declare_start_func(&mut self, func_index: FunctionIndex) { @@ -395,11 +388,8 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment { let sig = func_environ.vmctx_sig(self.get_func_type(function_index)); let mut func = ir::Function::with_name_signature(name, sig); let reader = wasmparser::BinaryReader::new(body_bytes); - self.trans.translate_from_reader( - reader, - &mut func, - &mut func_environ, - )?; + self.trans + .translate_from_reader(reader, &mut func, &mut func_environ)?; func }; self.func_bytecode_sizes.push(body_bytes.len()); diff --git a/lib/wasm/src/func_translator.rs b/lib/wasm/src/func_translator.rs index ed693af4bf..fbac424fef 100644 --- a/lib/wasm/src/func_translator.rs +++ b/lib/wasm/src/func_translator.rs @@ -135,16 +135,16 @@ fn parse_local_decls( num_params: usize, ) -> WasmResult<()> { let mut next_local = num_params; - let local_count = reader.read_local_count().map_err(|e| { - WasmError::from_binary_reader_error(e) - })?; + let local_count = reader + .read_local_count() + .map_err(|e| WasmError::from_binary_reader_error(e))?; let mut locals_total = 0; for _ in 0..local_count { builder.set_srcloc(cur_srcloc(reader)); - let (count, ty) = reader.read_local_decl(&mut locals_total).map_err(|e| { - WasmError::from_binary_reader_error(e) - })?; + let (count, ty) = reader + .read_local_decl(&mut locals_total) + .map_err(|e| WasmError::from_binary_reader_error(e))?; declare_locals(builder, count, ty, &mut next_local); } @@ -195,9 +195,9 @@ fn parse_function_body( // Keep going until the final `End` operator which pops the outermost block. while !state.control_stack.is_empty() { builder.set_srcloc(cur_srcloc(&reader)); - let op = reader.read_operator().map_err(|e| { - WasmError::from_binary_reader_error(e) - })?; + let op = reader + .read_operator() + .map_err(|e| WasmError::from_binary_reader_error(e))?; translate_operator(op, builder, state, environ)?; } @@ -246,11 +246,13 @@ mod tests { // (i32.add (get_local 0) (i32.const 1)) // ) const BODY: [u8; 7] = [ - 0x00, // local decl count - 0x20, 0x00, // get_local 0 - 0x41, 0x01, // i32.const 1 - 0x6a, // i32.add - 0x0b, // end + 0x00, // local decl count + 0x20, + 0x00, // get_local 0 + 0x41, + 0x01, // i32.const 1 + 0x6a, // i32.add + 0x0b, // end ]; let mut trans = FuncTranslator::new(); @@ -276,12 +278,14 @@ mod tests { // (return (i32.add (get_local 0) (i32.const 1))) // ) const BODY: [u8; 8] = [ - 0x00, // local decl count - 0x20, 0x00, // get_local 0 - 0x41, 0x01, // i32.const 1 - 0x6a, // i32.add - 0x0f, // return - 0x0b, // end + 0x00, // local decl count + 0x20, + 0x00, // get_local 0 + 0x41, + 0x01, // i32.const 1 + 0x6a, // i32.add + 0x0f, // return + 0x0b, // end ]; let mut trans = FuncTranslator::new(); @@ -312,16 +316,22 @@ mod tests { // ) // ) const BODY: [u8; 16] = [ - 0x01, // 1 local decl. - 0x01, 0x7f, // 1 i32 local. - 0x03, 0x7f, // loop i32 - 0x20, 0x00, // get_local 0 - 0x41, 0x01, // i32.const 0 - 0x6a, // i32.add - 0x21, 0x00, // set_local 0 - 0x0c, 0x00, // br 0 - 0x0b, // end - 0x0b, // end + 0x01, // 1 local decl. + 0x01, + 0x7f, // 1 i32 local. + 0x03, + 0x7f, // loop i32 + 0x20, + 0x00, // get_local 0 + 0x41, + 0x01, // i32.const 0 + 0x6a, // i32.add + 0x21, + 0x00, // set_local 0 + 0x0c, + 0x00, // br 0 + 0x0b, // end + 0x0b, // end ]; let mut trans = FuncTranslator::new(); diff --git a/lib/wasm/src/lib.rs b/lib/wasm/src/lib.rs index 87d1d87ee2..9842f36852 100644 --- a/lib/wasm/src/lib.rs +++ b/lib/wasm/src/lib.rs @@ -13,19 +13,10 @@ #![warn(unused_import_braces)] #![cfg_attr(feature = "std", warn(unstable_features))] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] +#![cfg_attr(feature = "cargo-clippy", allow(new_without_default, new_without_default_derive))] #![cfg_attr(feature = "cargo-clippy", - allow(new_without_default, new_without_default_derive))] -#![cfg_attr(feature="cargo-clippy", warn( - float_arithmetic, - mut_mut, - nonminimal_bool, - option_map_unwrap_or, - option_map_unwrap_or_else, - print_stdout, - unicode_not_nfc, - use_self, - ))] - + warn(float_arithmetic, mut_mut, nonminimal_bool, option_map_unwrap_or, + option_map_unwrap_or_else, print_stdout, unicode_not_nfc, use_self))] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc))] @@ -62,12 +53,12 @@ pub use translation_utils::{FunctionIndex, Global, GlobalIndex, GlobalInit, Memo #[cfg(not(feature = "std"))] mod std { - pub use alloc::vec; pub use alloc::string; - pub use core::{u32, i32, str, cmp}; + pub use alloc::vec; pub use core::fmt; pub use core::option; + pub use core::{cmp, str, i32, u32}; pub mod collections { - pub use hashmap_core::{HashMap, map as hash_map}; + pub use hashmap_core::{map as hash_map, HashMap}; } } diff --git a/lib/wasm/src/module_translator.rs b/lib/wasm/src/module_translator.rs index 683517e7f5..835a26fb3f 100644 --- a/lib/wasm/src/module_translator.rs +++ b/lib/wasm/src/module_translator.rs @@ -28,42 +28,72 @@ pub fn translate_module<'data>( let mut next_input = ParserInput::Default; loop { match *parser.read_with_input(next_input) { - ParserState::BeginSection { code: SectionCode::Type, .. } => { + ParserState::BeginSection { + code: SectionCode::Type, + .. + } => { parse_function_signatures(&mut parser, environ)?; next_input = ParserInput::Default; } - ParserState::BeginSection { code: SectionCode::Import, .. } => { + ParserState::BeginSection { + code: SectionCode::Import, + .. + } => { parse_import_section(&mut parser, environ)?; next_input = ParserInput::Default; } - ParserState::BeginSection { code: SectionCode::Function, .. } => { + ParserState::BeginSection { + code: SectionCode::Function, + .. + } => { parse_function_section(&mut parser, environ)?; next_input = ParserInput::Default; } - ParserState::BeginSection { code: SectionCode::Table, .. } => { + ParserState::BeginSection { + code: SectionCode::Table, + .. + } => { parse_table_section(&mut parser, environ)?; } - ParserState::BeginSection { code: SectionCode::Memory, .. } => { + ParserState::BeginSection { + code: SectionCode::Memory, + .. + } => { parse_memory_section(&mut parser, environ)?; next_input = ParserInput::Default; } - ParserState::BeginSection { code: SectionCode::Global, .. } => { + ParserState::BeginSection { + code: SectionCode::Global, + .. + } => { parse_global_section(&mut parser, environ)?; next_input = ParserInput::Default; } - ParserState::BeginSection { code: SectionCode::Export, .. } => { + ParserState::BeginSection { + code: SectionCode::Export, + .. + } => { parse_export_section(&mut parser, environ)?; next_input = ParserInput::Default; } - ParserState::BeginSection { code: SectionCode::Start, .. } => { + ParserState::BeginSection { + code: SectionCode::Start, + .. + } => { parse_start_section(&mut parser, environ)?; next_input = ParserInput::Default; } - ParserState::BeginSection { code: SectionCode::Element, .. } => { + ParserState::BeginSection { + code: SectionCode::Element, + .. + } => { parse_elements_section(&mut parser, environ)?; next_input = ParserInput::Default; } - ParserState::BeginSection { code: SectionCode::Code, .. } => { + ParserState::BeginSection { + code: SectionCode::Code, + .. + } => { // The code section begins break; } @@ -71,10 +101,16 @@ pub fn translate_module<'data>( next_input = ParserInput::Default; } ParserState::EndWasm => return Ok(()), - ParserState::BeginSection { code: SectionCode::Data, .. } => { + ParserState::BeginSection { + code: SectionCode::Data, + .. + } => { parse_data_section(&mut parser, environ)?; } - ParserState::BeginSection { code: SectionCode::Custom { .. }, .. } => { + ParserState::BeginSection { + code: SectionCode::Custom { .. }, + .. + } => { // Ignore unknown custom sections. next_input = ParserInput::SkipSection; } @@ -92,15 +128,16 @@ pub fn translate_module<'data>( } let mut reader = parser.create_binary_reader(); let size = reader.bytes_remaining(); - environ.define_function_body( - reader.read_bytes(size).map_err(|e| { - WasmError::from_binary_reader_error(e) - })?, - )?; + environ.define_function_body(reader + .read_bytes(size) + .map_err(|e| WasmError::from_binary_reader_error(e))?)?; } loop { match *parser.read() { - ParserState::BeginSection { code: SectionCode::Data, .. } => { + ParserState::BeginSection { + code: SectionCode::Data, + .. + } => { parse_data_section(&mut parser, environ)?; } ParserState::EndWasm => break, diff --git a/lib/wasm/src/sections_translator.rs b/lib/wasm/src/sections_translator.rs index 222433fafb..99a0051121 100644 --- a/lib/wasm/src/sections_translator.rs +++ b/lib/wasm/src/sections_translator.rs @@ -26,21 +26,19 @@ pub fn parse_function_signatures( match *parser.read() { ParserState::EndSection => break, ParserState::TypeSectionEntry(FuncType { - form: wasmparser::Type::Func, - ref params, - ref returns, - }) => { + form: wasmparser::Type::Func, + ref params, + ref returns, + }) => { let mut sig = Signature::new(environ.flags().call_conv()); sig.params.extend(params.iter().map(|ty| { - let cret_arg: ir::Type = type_to_type(ty).expect( - "only numeric types are supported in function signatures", - ); + let cret_arg: ir::Type = type_to_type(ty) + .expect("only numeric types are supported in function signatures"); AbiParam::new(cret_arg) })); sig.returns.extend(returns.iter().map(|ty| { - let cret_arg: ir::Type = type_to_type(ty).expect( - "only numeric types are supported in function signatures", - ); + let cret_arg: ir::Type = type_to_type(ty) + .expect("only numeric types are supported in function signatures"); AbiParam::new(cret_arg) })); environ.declare_signature(&sig); @@ -72,10 +70,11 @@ pub fn parse_import_section<'data>( environ.declare_func_import(sig as SignatureIndex, module_name, field_name); } ParserState::ImportSectionEntry { - ty: ImportSectionEntryType::Memory(MemoryType { - limits: ref memlimits, - shared, - }), + ty: + ImportSectionEntryType::Memory(MemoryType { + limits: ref memlimits, + shared, + }), .. } => { environ.declare_memory(Memory { @@ -85,7 +84,8 @@ pub fn parse_import_section<'data>( }); } ParserState::ImportSectionEntry { - ty: ImportSectionEntryType::Global(ref ty), .. + ty: ImportSectionEntryType::Global(ref ty), + .. } => { environ.declare_global(Global { ty: type_to_type(&ty.content_type).unwrap(), @@ -94,17 +94,16 @@ pub fn parse_import_section<'data>( }); } ParserState::ImportSectionEntry { - ty: ImportSectionEntryType::Table(ref tab), .. - } => { - environ.declare_table(Table { - ty: match type_to_type(&tab.element_type) { - Ok(t) => TableElementType::Val(t), - Err(()) => TableElementType::Func(), - }, - size: tab.limits.initial as usize, - maximum: tab.limits.maximum.map(|x| x as usize), - }) - } + ty: ImportSectionEntryType::Table(ref tab), + .. + } => environ.declare_table(Table { + ty: match type_to_type(&tab.element_type) { + Ok(t) => TableElementType::Val(t), + Err(()) => TableElementType::Func(), + }, + size: tab.limits.initial as usize, + maximum: tab.limits.maximum.map(|x| x as usize), + }), ParserState::EndSection => break, ParserState::Error(e) => return Err(WasmError::from_binary_reader_error(e)), ref s => panic!("unexpected section content: {:?}", s), @@ -325,16 +324,14 @@ pub fn parse_data_section<'data>( pub fn parse_table_section(parser: &mut Parser, environ: &mut ModuleEnvironment) -> WasmResult<()> { loop { match *parser.read() { - ParserState::TableSectionEntry(ref table) => { - environ.declare_table(Table { - ty: match type_to_type(&table.element_type) { - Ok(t) => TableElementType::Val(t), - Err(()) => TableElementType::Func(), - }, - size: table.limits.initial as usize, - maximum: table.limits.maximum.map(|x| x as usize), - }) - } + ParserState::TableSectionEntry(ref table) => environ.declare_table(Table { + ty: match type_to_type(&table.element_type) { + Ok(t) => TableElementType::Val(t), + Err(()) => TableElementType::Func(), + }, + size: table.limits.initial as usize, + maximum: table.limits.maximum.map(|x| x as usize), + }), ParserState::EndSection => break, ParserState::Error(e) => return Err(WasmError::from_binary_reader_error(e)), ref s => panic!("unexpected section content: {:?}", s), diff --git a/lib/wasm/src/state.rs b/lib/wasm/src/state.rs index c322906c95..b0bb4f5c7a 100644 --- a/lib/wasm/src/state.rs +++ b/lib/wasm/src/state.rs @@ -47,54 +47,78 @@ pub enum ControlStackFrame { impl ControlStackFrame { pub fn num_return_values(&self) -> usize { match *self { - ControlStackFrame::If { num_return_values, .. } | - ControlStackFrame::Block { num_return_values, .. } | - ControlStackFrame::Loop { num_return_values, .. } => num_return_values, + ControlStackFrame::If { + num_return_values, .. + } + | ControlStackFrame::Block { + num_return_values, .. + } + | ControlStackFrame::Loop { + num_return_values, .. + } => num_return_values, } } pub fn following_code(&self) -> Ebb { match *self { - ControlStackFrame::If { destination, .. } | - ControlStackFrame::Block { destination, .. } | - ControlStackFrame::Loop { destination, .. } => destination, + ControlStackFrame::If { destination, .. } + | ControlStackFrame::Block { destination, .. } + | ControlStackFrame::Loop { destination, .. } => destination, } } pub fn br_destination(&self) -> Ebb { match *self { - ControlStackFrame::If { destination, .. } | - ControlStackFrame::Block { destination, .. } => destination, + ControlStackFrame::If { destination, .. } + | ControlStackFrame::Block { destination, .. } => destination, ControlStackFrame::Loop { header, .. } => header, } } pub fn original_stack_size(&self) -> usize { match *self { - ControlStackFrame::If { original_stack_size, .. } | - ControlStackFrame::Block { original_stack_size, .. } | - ControlStackFrame::Loop { original_stack_size, .. } => original_stack_size, + ControlStackFrame::If { + original_stack_size, + .. + } + | ControlStackFrame::Block { + original_stack_size, + .. + } + | ControlStackFrame::Loop { + original_stack_size, + .. + } => original_stack_size, } } pub fn is_loop(&self) -> bool { match *self { - ControlStackFrame::If { .. } | - ControlStackFrame::Block { .. } => false, + ControlStackFrame::If { .. } | ControlStackFrame::Block { .. } => false, ControlStackFrame::Loop { .. } => true, } } pub fn exit_is_branched_to(&self) -> bool { match *self { - ControlStackFrame::If { exit_is_branched_to, .. } | - ControlStackFrame::Block { exit_is_branched_to, .. } => exit_is_branched_to, + ControlStackFrame::If { + exit_is_branched_to, + .. + } + | ControlStackFrame::Block { + exit_is_branched_to, + .. + } => exit_is_branched_to, ControlStackFrame::Loop { .. } => false, } } pub fn set_branched_to_exit(&mut self) { match *self { - ControlStackFrame::If { ref mut exit_is_branched_to, .. } | - ControlStackFrame::Block { ref mut exit_is_branched_to, .. } => { - *exit_is_branched_to = true + ControlStackFrame::If { + ref mut exit_is_branched_to, + .. } + | ControlStackFrame::Block { + ref mut exit_is_branched_to, + .. + } => *exit_is_branched_to = true, ControlStackFrame::Loop { .. } => {} } } @@ -258,9 +282,9 @@ impl TranslationState { environ: &mut FE, ) -> GlobalValue { let index = index as GlobalIndex; - *self.globals.entry(index).or_insert_with( - || environ.make_global(func, index), - ) + *self.globals + .entry(index) + .or_insert_with(|| environ.make_global(func, index)) } /// Get the `Heap` reference that should be used to access linear memory `index`. @@ -272,9 +296,9 @@ impl TranslationState { environ: &mut FE, ) -> ir::Heap { let index = index as MemoryIndex; - *self.heaps.entry(index).or_insert_with( - || environ.make_heap(func, index), - ) + *self.heaps + .entry(index) + .or_insert_with(|| environ.make_heap(func, index)) } /// Get the `SigRef` reference that should be used to make an indirect call with signature diff --git a/lib/wasm/src/translation_utils.rs b/lib/wasm/src/translation_utils.rs index 0089c5a75d..3ed13899e6 100644 --- a/lib/wasm/src/translation_utils.rs +++ b/lib/wasm/src/translation_utils.rs @@ -96,10 +96,10 @@ pub fn f64_translation(x: wasmparser::Ieee64) -> ir::immediates::Ieee64 { pub fn num_return_values(ty: wasmparser::Type) -> usize { match ty { wasmparser::Type::EmptyBlockType => 0, - wasmparser::Type::I32 | - wasmparser::Type::F32 | - wasmparser::Type::I64 | - wasmparser::Type::F64 => 1, + wasmparser::Type::I32 + | wasmparser::Type::F32 + | wasmparser::Type::I64 + | wasmparser::Type::F64 => 1, _ => panic!("unsupported return value type"), } } diff --git a/lib/wasm/tests/wasm_testsuite.rs b/lib/wasm/tests/wasm_testsuite.rs index 3492c7bd89..a5d5badaed 100644 --- a/lib/wasm/tests/wasm_testsuite.rs +++ b/lib/wasm/tests/wasm_testsuite.rs @@ -56,21 +56,19 @@ fn handle_module(path: &Path, flags: &Flags) { None => { panic!("the file extension is not wasm or wat"); } - Some(ext) => { - match ext.to_str() { - Some("wasm") => read_file(path).expect("error reading wasm file"), - Some("wat") => { - let wat = read_file(path).expect("error reading wat file"); - match wat2wasm(&wat) { - Ok(wasm) => wasm, - Err(e) => { - panic!("error converting wat to wasm: {:?}", e); - } + Some(ext) => match ext.to_str() { + Some("wasm") => read_file(path).expect("error reading wasm file"), + Some("wat") => { + let wat = read_file(path).expect("error reading wat file"); + match wat2wasm(&wat) { + Ok(wasm) => wasm, + Err(e) => { + panic!("error converting wat to wasm: {:?}", e); } } - None | Some(&_) => panic!("the file extension for {:?} is not wasm or wat", path), } - } + None | Some(&_) => panic!("the file extension for {:?} is not wasm or wat", path), + }, }; let mut dummy_environ = DummyEnvironment::with_flags(flags.clone()); translate_module(&data, &mut dummy_environ).unwrap();