Skip to content

Commit 1578b1c

Browse files
committed
Vendor newer version of cranelift-native
It fixes a bug that caused compilation on 32bit x86 to fail
1 parent ae3aa71 commit 1578b1c

File tree

4 files changed

+273
-2
lines changed

4 files changed

+273
-2
lines changed

compiler/rustc_codegen_cranelift/Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,6 @@ dependencies = [
333333
"cranelift-frontend",
334334
"cranelift-jit",
335335
"cranelift-module",
336-
"cranelift-native",
337336
"cranelift-object",
338337
"gimli",
339338
"indexmap",

compiler/rustc_codegen_cranelift/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ crate-type = ["dylib"]
1818
cranelift-codegen = { version = "0.92", features = ["unwind", "all-arch"] }
1919
cranelift-frontend = { version = "0.92" }
2020
cranelift-module = { version = "0.92" }
21-
cranelift-native = { version = "0.92" }
21+
# NOTE vendored as src/cranelift_native.rs
22+
# FIXME revert back to the external crate with Cranelift 0.93
23+
#cranelift-native = { version = "0.92" }
2224
cranelift-jit = { version = "0.92", optional = true }
2325
cranelift-object = { version = "0.92" }
2426
target-lexicon = "0.12.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
// Vendored from https://github.com/bytecodealliance/wasmtime/blob/b58a197d33f044193c3d608010f5e6ec394ac07e/cranelift/native/src/lib.rs
2+
// which is licensed as
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
// unlike rustc_codegen_cranelift itself.
5+
// FIXME revert back to the external crate with Cranelift 0.93
6+
#![allow(warnings)]
7+
8+
//! Performs autodetection of the host for the purposes of running
9+
//! Cranelift to generate code to run on the same machine.
10+
11+
#![deny(
12+
missing_docs,
13+
trivial_numeric_casts,
14+
unused_extern_crates,
15+
unstable_features
16+
)]
17+
#![warn(unused_import_braces)]
18+
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
19+
#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
20+
#![cfg_attr(
21+
feature = "cargo-clippy",
22+
warn(
23+
clippy::float_arithmetic,
24+
clippy::mut_mut,
25+
clippy::nonminimal_bool,
26+
clippy::map_unwrap_or,
27+
clippy::clippy::print_stdout,
28+
clippy::unicode_not_nfc,
29+
clippy::use_self
30+
)
31+
)]
32+
33+
use cranelift_codegen::isa;
34+
use target_lexicon::Triple;
35+
36+
/// Return an `isa` builder configured for the current host
37+
/// machine, or `Err(())` if the host machine is not supported
38+
/// in the current configuration.
39+
pub fn builder() -> Result<isa::Builder, &'static str> {
40+
builder_with_options(true)
41+
}
42+
43+
/// Return an `isa` builder configured for the current host
44+
/// machine, or `Err(())` if the host machine is not supported
45+
/// in the current configuration.
46+
///
47+
/// Selects the given backend variant specifically; this is
48+
/// useful when more than oen backend exists for a given target
49+
/// (e.g., on x86-64).
50+
pub fn builder_with_options(infer_native_flags: bool) -> Result<isa::Builder, &'static str> {
51+
let mut isa_builder = isa::lookup(Triple::host()).map_err(|err| match err {
52+
isa::LookupError::SupportDisabled => "support for architecture disabled at compile time",
53+
isa::LookupError::Unsupported => "unsupported architecture",
54+
})?;
55+
56+
#[cfg(target_arch = "x86_64")]
57+
{
58+
use cranelift_codegen::settings::Configurable;
59+
60+
if !std::is_x86_feature_detected!("sse2") {
61+
return Err("x86 support requires SSE2");
62+
}
63+
64+
if !infer_native_flags {
65+
return Ok(isa_builder);
66+
}
67+
68+
// These are temporarily enabled by default (see #3810 for
69+
// more) so that a default-constructed `Flags` can work with
70+
// default Wasmtime features. Otherwise, the user must
71+
// explicitly use native flags or turn these on when on x86-64
72+
// platforms to avoid a configuration panic. In order for the
73+
// "enable if detected" logic below to work, we must turn them
74+
// *off* (differing from the default) and then re-enable below
75+
// if present.
76+
isa_builder.set("has_sse3", "false").unwrap();
77+
isa_builder.set("has_ssse3", "false").unwrap();
78+
isa_builder.set("has_sse41", "false").unwrap();
79+
isa_builder.set("has_sse42", "false").unwrap();
80+
81+
if std::is_x86_feature_detected!("sse3") {
82+
isa_builder.enable("has_sse3").unwrap();
83+
}
84+
if std::is_x86_feature_detected!("ssse3") {
85+
isa_builder.enable("has_ssse3").unwrap();
86+
}
87+
if std::is_x86_feature_detected!("sse4.1") {
88+
isa_builder.enable("has_sse41").unwrap();
89+
}
90+
if std::is_x86_feature_detected!("sse4.2") {
91+
isa_builder.enable("has_sse42").unwrap();
92+
}
93+
if std::is_x86_feature_detected!("popcnt") {
94+
isa_builder.enable("has_popcnt").unwrap();
95+
}
96+
if std::is_x86_feature_detected!("avx") {
97+
isa_builder.enable("has_avx").unwrap();
98+
}
99+
if std::is_x86_feature_detected!("avx2") {
100+
isa_builder.enable("has_avx2").unwrap();
101+
}
102+
if std::is_x86_feature_detected!("fma") {
103+
isa_builder.enable("has_fma").unwrap();
104+
}
105+
if std::is_x86_feature_detected!("bmi1") {
106+
isa_builder.enable("has_bmi1").unwrap();
107+
}
108+
if std::is_x86_feature_detected!("bmi2") {
109+
isa_builder.enable("has_bmi2").unwrap();
110+
}
111+
if std::is_x86_feature_detected!("avx512bitalg") {
112+
isa_builder.enable("has_avx512bitalg").unwrap();
113+
}
114+
if std::is_x86_feature_detected!("avx512dq") {
115+
isa_builder.enable("has_avx512dq").unwrap();
116+
}
117+
if std::is_x86_feature_detected!("avx512f") {
118+
isa_builder.enable("has_avx512f").unwrap();
119+
}
120+
if std::is_x86_feature_detected!("avx512vl") {
121+
isa_builder.enable("has_avx512vl").unwrap();
122+
}
123+
if std::is_x86_feature_detected!("avx512vbmi") {
124+
isa_builder.enable("has_avx512vbmi").unwrap();
125+
}
126+
if std::is_x86_feature_detected!("lzcnt") {
127+
isa_builder.enable("has_lzcnt").unwrap();
128+
}
129+
}
130+
131+
#[cfg(target_arch = "aarch64")]
132+
{
133+
use cranelift_codegen::settings::Configurable;
134+
135+
if !infer_native_flags {
136+
return Ok(isa_builder);
137+
}
138+
139+
if std::arch::is_aarch64_feature_detected!("lse") {
140+
isa_builder.enable("has_lse").unwrap();
141+
}
142+
143+
if std::arch::is_aarch64_feature_detected!("paca") {
144+
isa_builder.enable("has_pauth").unwrap();
145+
}
146+
147+
if cfg!(target_os = "macos") {
148+
// Pointer authentication is always available on Apple Silicon.
149+
isa_builder.enable("sign_return_address").unwrap();
150+
// macOS enforces the use of the B key for return addresses.
151+
isa_builder.enable("sign_return_address_with_bkey").unwrap();
152+
}
153+
}
154+
155+
// There is no is_s390x_feature_detected macro yet, so for now
156+
// we use getauxval from the libc crate directly.
157+
#[cfg(all(target_arch = "s390x", target_os = "linux"))]
158+
{
159+
use cranelift_codegen::settings::Configurable;
160+
161+
if !infer_native_flags {
162+
return Ok(isa_builder);
163+
}
164+
165+
let v = unsafe { libc::getauxval(libc::AT_HWCAP) };
166+
const HWCAP_S390X_VXRS_EXT2: libc::c_ulong = 32768;
167+
if (v & HWCAP_S390X_VXRS_EXT2) != 0 {
168+
isa_builder.enable("has_vxrs_ext2").unwrap();
169+
// There is no separate HWCAP bit for mie2, so assume
170+
// that any machine with vxrs_ext2 also has mie2.
171+
isa_builder.enable("has_mie2").unwrap();
172+
}
173+
}
174+
175+
// `is_riscv_feature_detected` is nightly only for now, use
176+
// getauxval from the libc crate directly as a temporary measure.
177+
#[cfg(all(target_arch = "riscv64", target_os = "linux"))]
178+
{
179+
use cranelift_codegen::settings::Configurable;
180+
181+
if !infer_native_flags {
182+
return Ok(isa_builder);
183+
}
184+
185+
let v = unsafe { libc::getauxval(libc::AT_HWCAP) };
186+
187+
const HWCAP_RISCV_EXT_A: libc::c_ulong = 1 << (b'a' - b'a');
188+
const HWCAP_RISCV_EXT_C: libc::c_ulong = 1 << (b'c' - b'a');
189+
const HWCAP_RISCV_EXT_D: libc::c_ulong = 1 << (b'd' - b'a');
190+
const HWCAP_RISCV_EXT_F: libc::c_ulong = 1 << (b'f' - b'a');
191+
const HWCAP_RISCV_EXT_M: libc::c_ulong = 1 << (b'm' - b'a');
192+
const HWCAP_RISCV_EXT_V: libc::c_ulong = 1 << (b'v' - b'a');
193+
194+
if (v & HWCAP_RISCV_EXT_A) != 0 {
195+
isa_builder.enable("has_a").unwrap();
196+
}
197+
198+
if (v & HWCAP_RISCV_EXT_C) != 0 {
199+
isa_builder.enable("has_c").unwrap();
200+
}
201+
202+
if (v & HWCAP_RISCV_EXT_D) != 0 {
203+
isa_builder.enable("has_d").unwrap();
204+
}
205+
206+
if (v & HWCAP_RISCV_EXT_F) != 0 {
207+
isa_builder.enable("has_f").unwrap();
208+
209+
// TODO: There doesn't seem to be a bit associated with this extension
210+
// rust enables it with the `f` extension:
211+
// https://github.com/rust-lang/stdarch/blob/790411f93c4b5eada3c23abb4c9a063fb0b24d99/crates/std_detect/src/detect/os/linux/riscv.rs#L43
212+
isa_builder.enable("has_zicsr").unwrap();
213+
}
214+
215+
if (v & HWCAP_RISCV_EXT_M) != 0 {
216+
isa_builder.enable("has_m").unwrap();
217+
}
218+
219+
if (v & HWCAP_RISCV_EXT_V) != 0 {
220+
isa_builder.enable("has_v").unwrap();
221+
}
222+
223+
// TODO: ZiFencei does not have a bit associated with it
224+
// TODO: Zbkb does not have a bit associated with it
225+
}
226+
227+
// squelch warnings about unused mut/variables on some platforms.
228+
drop(&mut isa_builder);
229+
drop(infer_native_flags);
230+
231+
Ok(isa_builder)
232+
}
233+
234+
#[cfg(test)]
235+
mod tests {
236+
use super::builder;
237+
use cranelift_codegen::isa::CallConv;
238+
use cranelift_codegen::settings;
239+
240+
#[test]
241+
fn test() {
242+
if let Ok(isa_builder) = builder() {
243+
let flag_builder = settings::builder();
244+
let isa = isa_builder
245+
.finish(settings::Flags::new(flag_builder))
246+
.unwrap();
247+
248+
if cfg!(all(target_os = "macos", target_arch = "aarch64")) {
249+
assert_eq!(isa.default_call_conv(), CallConv::AppleAarch64);
250+
} else if cfg!(any(unix, target_os = "nebulet")) {
251+
assert_eq!(isa.default_call_conv(), CallConv::SystemV);
252+
} else if cfg!(windows) {
253+
assert_eq!(isa.default_call_conv(), CallConv::WindowsFastcall);
254+
}
255+
256+
if cfg!(target_pointer_width = "64") {
257+
assert_eq!(isa.pointer_bits(), 64);
258+
} else if cfg!(target_pointer_width = "32") {
259+
assert_eq!(isa.pointer_bits(), 32);
260+
} else if cfg!(target_pointer_width = "16") {
261+
assert_eq!(isa.pointer_bits(), 16);
262+
}
263+
}
264+
}
265+
}
266+
267+
/// Version number of this crate.
268+
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

compiler/rustc_codegen_cranelift/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ mod compiler_builtins;
5757
mod concurrency_limiter;
5858
mod config;
5959
mod constant;
60+
// FIXME revert back to the external crate with Cranelift 0.93
61+
mod cranelift_native;
6062
mod debuginfo;
6163
mod discriminant;
6264
mod driver;

0 commit comments

Comments
 (0)