* Cranelift: remove non-egraphs optimization pipeline and `use_egraphs` option. This PR removes the LICM, GVN, and preopt passes, and associated support pieces, from `cranelift-codegen`. Not to worry, we still have optimizations: the egraph framework subsumes all of these, and has been on by default since #5181. A few decision points: - Filetests for the legacy LICM, GVN and simple_preopt were removed too. As we built optimizations in the egraph framework we wrote new tests for the equivalent functionality, and many of the old tests were testing specific behaviors in the old implementations that may not be relevant anymore. However if folks prefer I could take a different approach here and try to port over all of the tests. - The corresponding filetest modes (commands) were deleted too. The `test alias_analysis` mode remains, but no longer invokes a separate GVN first (since there is no separate GVN that will not also do alias analysis) so the tests were tweaked slightly to work with that. The egrpah testsuite also covers alias analysis. - The `divconst_magic_numbers` module is removed since it's unused without `simple_preopt`, though this is the one remaining optimization we still need to build in the egraphs framework, pending #5908. The magic numbers will live forever in git history so removing this in the meantime is not a major issue IMHO. - The `use_egraphs` setting itself was removed at both the Cranelift and Wasmtime levels. It has been marked deprecated for a few releases now (Wasmtime 6.0, 7.0, upcoming 8.0, and corresponding Cranelift versions) so I think this is probably OK. As an alternative if anyone feels strongly, we could leave the setting and make it a no-op. * Update test outputs for remaining test differences.
107 lines
3.0 KiB
Rust
107 lines
3.0 KiB
Rust
// This file is taken from the Rust compiler: src/librustc_data_structures/fx.rs
|
|
|
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
use super::{HashMap, HashSet};
|
|
use core::default::Default;
|
|
use core::hash::{BuildHasherDefault, Hash, Hasher};
|
|
use core::ops::BitXor;
|
|
|
|
pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;
|
|
pub type FxHashSet<V> = HashSet<V, BuildHasherDefault<FxHasher>>;
|
|
|
|
#[allow(non_snake_case)]
|
|
pub fn FxHashMap<K: Hash + Eq, V>() -> FxHashMap<K, V> {
|
|
HashMap::default()
|
|
}
|
|
|
|
/// A speedy hash algorithm for use within rustc. The hashmap in liballoc
|
|
/// by default uses SipHash which isn't quite as speedy as we want. In the
|
|
/// compiler we're not really worried about DOS attempts, so we use a fast
|
|
/// non-cryptographic hash.
|
|
///
|
|
/// This is the same as the algorithm used by Firefox -- which is a homespun
|
|
/// one not based on any widely-known algorithm -- though modified to produce
|
|
/// 64-bit hash values instead of 32-bit hash values. It consistently
|
|
/// out-performs an FNV-based hash within rustc itself -- the collision rate is
|
|
/// similar or slightly worse than FNV, but the speed of the hash function
|
|
/// itself is much higher because it works on up to 8 bytes at a time.
|
|
pub struct FxHasher {
|
|
hash: usize,
|
|
}
|
|
|
|
#[cfg(target_pointer_width = "32")]
|
|
const K: usize = 0x9e3779b9;
|
|
#[cfg(target_pointer_width = "64")]
|
|
const K: usize = 0x517cc1b727220a95;
|
|
|
|
impl Default for FxHasher {
|
|
#[inline]
|
|
fn default() -> Self {
|
|
Self { hash: 0 }
|
|
}
|
|
}
|
|
|
|
impl FxHasher {
|
|
#[inline]
|
|
fn add_to_hash(&mut self, i: usize) {
|
|
self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K);
|
|
}
|
|
}
|
|
|
|
impl Hasher for FxHasher {
|
|
#[inline]
|
|
fn write(&mut self, bytes: &[u8]) {
|
|
for byte in bytes {
|
|
let i = *byte;
|
|
self.add_to_hash(i as usize);
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
fn write_u8(&mut self, i: u8) {
|
|
self.add_to_hash(i as usize);
|
|
}
|
|
|
|
#[inline]
|
|
fn write_u16(&mut self, i: u16) {
|
|
self.add_to_hash(i as usize);
|
|
}
|
|
|
|
#[inline]
|
|
fn write_u32(&mut self, i: u32) {
|
|
self.add_to_hash(i as usize);
|
|
}
|
|
|
|
#[cfg(target_pointer_width = "32")]
|
|
#[inline]
|
|
fn write_u64(&mut self, i: u64) {
|
|
self.add_to_hash(i as usize);
|
|
self.add_to_hash((i >> 32) as usize);
|
|
}
|
|
|
|
#[cfg(target_pointer_width = "64")]
|
|
#[inline]
|
|
fn write_u64(&mut self, i: u64) {
|
|
self.add_to_hash(i as usize);
|
|
}
|
|
|
|
#[inline]
|
|
fn write_usize(&mut self, i: usize) {
|
|
self.add_to_hash(i);
|
|
}
|
|
|
|
#[inline]
|
|
fn finish(&self) -> u64 {
|
|
self.hash as u64
|
|
}
|
|
}
|