or
```bash
-$ $cg_clif_dir/build/bin/cg_clif --jit my_crate.rs
+$ $cg_clif_dir/build/bin/cg_clif -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs
```
### Shell
```bash
function jit_naked() {
- echo "$@" | $cg_clif_dir/build/bin/cg_clif - --jit
+ echo "$@" | $cg_clif_dir/build/bin/cg_clif - -Cllvm-args=mode=jit -Cprefer-dynamic
}
function jit() {
shift || true
if [[ "$cmd" = "jit" ]]; then
-cargo "+${TOOLCHAIN}" rustc "$@" -- --jit
+cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit -Cprefer-dynamic
else
cargo "+${TOOLCHAIN}" "$cmd" "$@"
fi
pushd $(dirname "$0")/../
source build/config.sh
popd
-PROFILE=$1 OUTPUT=$2 exec $RUSTC $RUSTFLAGS --jit $0
+PROFILE=$1 OUTPUT=$2 exec $RUSTC $RUSTFLAGS -Cllvm-args=mode=jit -Cprefer-dynamic $0
#*/
//! This program filters away uninteresting samples and trims uninteresting frames for stackcollapse
if [[ "$JIT_SUPPORTED" = "1" ]]; then
echo "[JIT] mini_core_hello_world"
- CG_CLIF_JIT_ARGS="abc bcd" $MY_RUSTC --jit example/mini_core_hello_world.rs --cfg jit --target "$HOST_TRIPLE"
+ CG_CLIF_JIT_ARGS="abc bcd" $MY_RUSTC -Cllvm-args=mode=jit -Cprefer-dynamic example/mini_core_hello_world.rs --cfg jit --target "$HOST_TRIPLE"
else
echo "[JIT] mini_core_hello_world (skipped)"
fi
if [[ "$JIT_SUPPORTED" = "1" ]]; then
echo "[JIT] std_example"
- $MY_RUSTC --jit example/std_example.rs --target "$HOST_TRIPLE"
+ $MY_RUSTC -Cllvm-args=mode=jit -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
else
echo "[JIT] std_example (skipped)"
fi
let mut callbacks = CraneliftPassesCallbacks::default();
rustc_driver::install_ice_hook();
let exit_code = rustc_driver::catch_with_exit_code(|| {
- let mut use_jit = false;
-
- let mut args = std::env::args_os()
+ let args = std::env::args_os()
.enumerate()
.map(|(i, arg)| {
arg.into_string().unwrap_or_else(|arg| {
)
})
})
- .filter(|arg| {
- if arg == "--jit" {
- use_jit = true;
- false
- } else {
- true
- }
- })
.collect::<Vec<_>>();
- if use_jit {
- args.push("-Cprefer-dynamic".to_string());
- }
let mut run_compiler = rustc_driver::RunCompiler::new(&args, &mut callbacks);
run_compiler.set_make_codegen_backend(Some(Box::new(move |_| {
- Box::new(rustc_codegen_cranelift::CraneliftCodegenBackend {
- config: rustc_codegen_cranelift::BackendConfig { use_jit },
- })
+ Box::new(rustc_codegen_cranelift::CraneliftCodegenBackend { config: None })
})));
run_compiler.run()
});
let mut run_compiler = rustc_driver::RunCompiler::new(&args, &mut callbacks);
if use_clif {
run_compiler.set_make_codegen_backend(Some(Box::new(move |_| {
- Box::new(rustc_codegen_cranelift::CraneliftCodegenBackend {
- config: rustc_codegen_cranelift::BackendConfig { use_jit: false },
- })
+ Box::new(rustc_codegen_cranelift::CraneliftCodegenBackend { config: None })
})));
}
run_compiler.run()
let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id);
- println!("Rustc codegen cranelift will JIT run the executable, because --jit was passed");
+ println!("Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed");
let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
unsafe { ::std::mem::transmute(finalized_main) };
use rustc_middle::mir::mono::{Linkage as RLinkage, MonoItem, Visibility};
use crate::prelude::*;
+use crate::CodegenMode;
mod aot;
#[cfg(feature = "jit")]
) -> Box<dyn Any> {
tcx.sess.abort_if_errors();
- if config.use_jit {
- let is_executable = tcx
- .sess
- .crate_types()
- .contains(&rustc_session::config::CrateType::Executable);
- if !is_executable {
- tcx.sess.fatal("can't jit non-executable crate");
- }
+ match config.codegen_mode {
+ CodegenMode::Aot => aot::run_aot(tcx, metadata, need_metadata_module),
+ CodegenMode::Jit => {
+ let is_executable = tcx
+ .sess
+ .crate_types()
+ .contains(&rustc_session::config::CrateType::Executable);
+ if !is_executable {
+ tcx.sess.fatal("can't jit non-executable crate");
+ }
- #[cfg(feature = "jit")]
- let _: ! = jit::run_jit(tcx);
+ #[cfg(feature = "jit")]
+ let _: ! = jit::run_jit(tcx);
- #[cfg(not(feature = "jit"))]
- tcx.sess
- .fatal("jit support was disabled when compiling rustc_codegen_cranelift");
+ #[cfg(not(feature = "jit"))]
+ tcx.sess
+ .fatal("jit support was disabled when compiling rustc_codegen_cranelift");
+ }
}
-
- aot::run_aot(tcx, metadata, need_metadata_module)
}
fn predefine_mono_items<'tcx>(
associated_type_bounds,
never_type,
try_blocks,
- hash_drain_filter
+ hash_drain_filter,
+ str_split_once
)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
extern crate rustc_driver;
use std::any::Any;
+use std::str::FromStr;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults;
}
#[derive(Copy, Clone, Debug)]
+pub enum CodegenMode {
+ Aot,
+ Jit,
+}
+
+impl Default for CodegenMode {
+ fn default() -> Self {
+ CodegenMode::Aot
+ }
+}
+
+impl FromStr for CodegenMode {
+ type Err = String;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ "aot" => Ok(CodegenMode::Aot),
+ "jit" => Ok(CodegenMode::Jit),
+ _ => Err(format!("Unknown codegen mode `{}`", s)),
+ }
+ }
+}
+
+#[derive(Copy, Clone, Debug, Default)]
pub struct BackendConfig {
- pub use_jit: bool,
+ pub codegen_mode: CodegenMode,
+}
+
+impl BackendConfig {
+ fn from_opts(opts: &[String]) -> Result<Self, String> {
+ let mut config = BackendConfig::default();
+ for opt in opts {
+ if let Some((name, value)) = opt.split_once('=') {
+ match name {
+ "mode" => config.codegen_mode = value.parse()?,
+ _ => return Err(format!("Unknown option `{}`", name)),
+ }
+ } else {
+ return Err(format!("Invalid option `{}`", opt));
+ }
+ }
+ Ok(config)
+ }
}
pub struct CraneliftCodegenBackend {
- pub config: BackendConfig,
+ pub config: Option<BackendConfig>,
}
impl CodegenBackend for CraneliftCodegenBackend {
metadata: EncodedMetadata,
need_metadata_module: bool,
) -> Box<dyn Any> {
- let res = driver::codegen_crate(tcx, metadata, need_metadata_module, self.config);
+ let config = if let Some(config) = self.config {
+ config
+ } else {
+ BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
+ .unwrap_or_else(|err| tcx.sess.fatal(&err))
+ };
+ let res = driver::codegen_crate(tcx, metadata, need_metadata_module, config);
rustc_symbol_mangling::test::report_symbol_names(tcx);
/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
- Box::new(CraneliftCodegenBackend {
- config: BackendConfig { use_jit: false },
- })
+ Box::new(CraneliftCodegenBackend { config: None })
}