diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2021-04-07 11:52:11 +0200 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2021-04-07 11:52:11 +0200 |
| commit | 53bfc6729ae4a53c8092473452de7a272224df5d (patch) | |
| tree | 4afae3c9d545328d747076545beb0a1ec85bbdaa | |
| parent | 1ee0aa9416b9da220d7370007c5e3c402d6714b0 (diff) | |
| download | rust-53bfc6729ae4a53c8092473452de7a272224df5d.tar.gz rust-53bfc6729ae4a53c8092473452de7a272224df5d.zip | |
Centralize all configuration into config.rs
| -rw-r--r-- | Readme.md | 5 | ||||
| -rw-r--r-- | docs/env_vars.md | 15 | ||||
| -rw-r--r-- | scripts/ext_config.sh | 2 | ||||
| -rw-r--r-- | src/backend.rs | 10 | ||||
| -rw-r--r-- | src/config.rs | 66 | ||||
| -rw-r--r-- | src/driver/aot.rs | 27 | ||||
| -rw-r--r-- | src/driver/jit.rs | 11 | ||||
| -rw-r--r-- | src/driver/mod.rs | 4 | ||||
| -rw-r--r-- | src/lib.rs | 9 | ||||
| -rw-r--r-- | src/pretty_clif.rs | 2 |
10 files changed, 94 insertions, 57 deletions
diff --git a/Readme.md b/Readme.md index ffe1d9a1e65..08f9373be62 100644 --- a/Readme.md +++ b/Readme.md @@ -44,9 +44,10 @@ This will build your project with rustc_codegen_cranelift instead of the usual L For additional ways to use rustc_codegen_cranelift like the JIT mode see [usage.md](docs/usage.md). -## Env vars +## Configuration -See [env_vars.md](docs/env_vars.md) for all env vars used by rustc_codegen_cranelift. +See the documentation on the `BackendConfig` struct in [config.rs](src/config.rs) for all +configuration options. ## Not yet supported diff --git a/docs/env_vars.md b/docs/env_vars.md deleted file mode 100644 index f7fde1b4f3a..00000000000 --- a/docs/env_vars.md +++ /dev/null @@ -1,15 +0,0 @@ -# List of env vars recognized by cg_clif - -<dl> - <dt>CG_CLIF_JIT_ARGS</dt> - <dd>When JIT mode is enable pass these arguments to the program.</dd> - <dt>CG_CLIF_INCR_CACHE_DISABLED</dt> - <dd>Don't cache object files in the incremental cache. Useful during development of cg_clif - to make it possible to use incremental mode for all analyses performed by rustc without caching - object files when their content should have been changed by a change to cg_clif.</dd> - <dt>CG_CLIF_DISPLAY_CG_TIME</dt> - <dd>If "1", display the time it took to perform codegen for a crate.</dd> - <dt>CG_CLIF_ENABLE_VERIFIER</dt> - <dd>Enable the Cranelift ir verifier for all compilation passes. If not set it will only run once - before passing the clif ir to Cranelift for compilation.</dt> -</dl> diff --git a/scripts/ext_config.sh b/scripts/ext_config.sh index 7971f620df1..3f98d77d76c 100644 --- a/scripts/ext_config.sh +++ b/scripts/ext_config.sh @@ -5,7 +5,7 @@ set -e export CG_CLIF_DISPLAY_CG_TIME=1 -export CG_CLIF_INCR_CACHE_DISABLED=1 +export CG_CLIF_DISABLE_INCR_CACHE=1 export HOST_TRIPLE=$(rustc -vV | grep host | cut -d: -f2 | tr -d " ") export TARGET_TRIPLE=${TARGET_TRIPLE:-$HOST_TRIPLE} diff --git a/src/backend.rs b/src/backend.rs index eb7927fc4ad..eca88dd3172 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -5,13 +5,13 @@ use std::convert::{TryFrom, TryInto}; use rustc_data_structures::fx::FxHashMap; use rustc_session::Session; +use cranelift_codegen::isa::TargetIsa; use cranelift_module::FuncId; +use cranelift_object::{ObjectBuilder, ObjectModule, ObjectProduct}; use object::write::*; use object::{RelocationEncoding, SectionKind, SymbolFlags}; -use cranelift_object::{ObjectBuilder, ObjectModule, ObjectProduct}; - use gimli::SectionId; use crate::debuginfo::{DebugReloc, DebugRelocName}; @@ -113,7 +113,7 @@ impl WriteDebugInfo for ObjectProduct { } pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object)) -> Vec<u8> { - let triple = crate::build_isa(sess).triple().clone(); + let triple = crate::target_triple(sess); let binary_format = match triple.binary_format { target_lexicon::BinaryFormat::Elf => object::BinaryFormat::Elf, @@ -141,9 +141,9 @@ pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object metadata_object.write().unwrap() } -pub(crate) fn make_module(sess: &Session, name: String) -> ObjectModule { +pub(crate) fn make_module(sess: &Session, isa: Box<dyn TargetIsa>, name: String) -> ObjectModule { let mut builder = ObjectBuilder::new( - crate::build_isa(sess), + isa, name + ".o", cranelift_module::default_libcall_names(), ) diff --git a/src/config.rs b/src/config.rs index 9b3259b622e..0cf02e2bbb5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,10 @@ +use std::env; use std::str::FromStr; +fn bool_env_var(key: &str) -> bool { + env::var(key).as_ref().map(|val| &**val) == Ok("1") +} + #[derive(Copy, Clone, Debug)] pub enum CodegenMode { Aot, @@ -7,12 +12,6 @@ pub enum CodegenMode { JitLazy, } -impl Default for CodegenMode { - fn default() -> Self { - CodegenMode::Aot - } -} - impl FromStr for CodegenMode { type Err = String; @@ -26,24 +25,77 @@ impl FromStr for CodegenMode { } } -#[derive(Copy, Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct BackendConfig { + /// Should the crate be AOT compiled or JIT executed. + /// + /// Defaults to AOT compilation. Can be set using `-Cllvm-args=mode=...`. pub codegen_mode: CodegenMode, + + /// When JIT mode is enable pass these arguments to the program. + /// + /// Defaults to the value of `CG_CLIF_JIT_ARGS`. + pub jit_args: Vec<String>, + + /// Display the time it took to perform codegen for a crate. + /// + /// Defaults to true when the `CG_CLIF_DISPLAY_CG_TIME` env var is set to 1 or false otherwise. + /// Can be set using `-Cllvm-args=display_cg_time=...`. + pub display_cg_time: bool, + + /// Enable the Cranelift ir verifier for all compilation passes. If not set it will only run + /// once before passing the clif ir to Cranelift for compilation. + /// + /// Defaults to true when the `CG_CLIF_ENABLE_VERIFIER` env var is set to 1 or when cg_clif is + /// compiled with debug assertions enabled or false otherwise. Can be set using + /// `-Cllvm-args=enable_verifier=...`. + pub enable_verifier: bool, + + /// Don't cache object files in the incremental cache. Useful during development of cg_clif + /// to make it possible to use incremental mode for all analyses performed by rustc without + /// caching object files when their content should have been changed by a change to cg_clif. + /// + /// Defaults to true when the `CG_CLIF_DISABLE_INCR_CACHE` env var is set to 1 or false + /// otherwise. Can be set using `-Cllvm-args=disable_incr_cache=...`. + pub disable_incr_cache: bool, +} + +impl Default for BackendConfig { + fn default() -> Self { + BackendConfig { + codegen_mode: CodegenMode::Aot, + jit_args: { + let args = std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); + args.split(' ').map(|arg| arg.to_string()).collect() + }, + display_cg_time: bool_env_var("CG_CLIF_DISPLAY_CG_TIME"), + enable_verifier: cfg!(debug_assertions) || bool_env_var("CG_CLIF_ENABLE_VERIFIER"), + disable_incr_cache: bool_env_var("CG_CLIF_DISABLE_INCR_CACHE"), + } + } } impl BackendConfig { pub fn from_opts(opts: &[String]) -> Result<Self, String> { + fn parse_bool(name: &str, value: &str) -> Result<bool, String> { + value.parse().map_err(|_| format!("failed to parse value `{}` for {}", value, name)) + } + 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()?, + "display_cg_time" => config.display_cg_time = parse_bool(name, value)?, + "enable_verifier" => config.enable_verifier = parse_bool(name, value)?, + "disable_incr_cache" => config.disable_incr_cache = parse_bool(name, value)?, _ => return Err(format!("Unknown option `{}`", name)), } } else { return Err(format!("Invalid option `{}`", opt)); } } + Ok(config) } } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index ed3bdedddce..6ce174eec81 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -16,12 +16,6 @@ use cranelift_object::ObjectModule; use crate::{prelude::*, BackendConfig}; -fn new_module(tcx: TyCtxt<'_>, name: String) -> ObjectModule { - let module = crate::backend::make_module(tcx.sess, name); - assert_eq!(pointer_ty(tcx), module.target_config().pointer_type()); - module -} - struct ModuleCodegenResult(CompiledModule, Option<(WorkProductId, WorkProduct)>); impl<HCX> HashStable<HCX> for ModuleCodegenResult { @@ -32,6 +26,7 @@ impl<HCX> HashStable<HCX> for ModuleCodegenResult { fn emit_module( tcx: TyCtxt<'_>, + backend_config: &BackendConfig, name: String, kind: ModuleKind, module: ObjectModule, @@ -52,7 +47,7 @@ fn emit_module( tcx.sess.fatal(&format!("error writing object file: {}", err)); } - let work_product = if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() { + let work_product = if backend_config.disable_incr_cache { None } else { rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( @@ -110,11 +105,13 @@ fn module_codegen( let cgu = tcx.codegen_unit(cgu_name); let mono_items = cgu.items_in_deterministic_order(tcx); - let mut module = new_module(tcx, cgu_name.as_str().to_string()); + let isa = crate::build_isa(tcx.sess, &backend_config); + let mut module = crate::backend::make_module(tcx.sess, isa, cgu_name.as_str().to_string()); + assert_eq!(pointer_ty(tcx), module.target_config().pointer_type()); let mut cx = crate::CodegenCx::new( tcx, - backend_config, + backend_config.clone(), &mut module, tcx.sess.opts.debuginfo != DebugInfo::None, ); @@ -144,6 +141,7 @@ fn module_codegen( let codegen_result = emit_module( tcx, + &backend_config, cgu.name().as_str().to_string(), ModuleKind::Regular, module, @@ -193,14 +191,14 @@ pub(super) fn run_aot( } } - let modules = super::time(tcx, "codegen mono items", || { + let modules = super::time(tcx, backend_config.display_cg_time, "codegen mono items", || { cgus.iter() .map(|cgu| { let cgu_reuse = determine_cgu_reuse(tcx, cgu); tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse); match cgu_reuse { - _ if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() => {} + _ if backend_config.disable_incr_cache => {} CguReuse::No => {} CguReuse::PreLto => { return reuse_workproduct_for_cgu(tcx, &*cgu, &mut work_products); @@ -212,7 +210,7 @@ pub(super) fn run_aot( let (ModuleCodegenResult(module, work_product), _) = tcx.dep_graph.with_task( dep_node, tcx, - (backend_config, cgu.name()), + (backend_config.clone(), cgu.name()), module_codegen, rustc_middle::dep_graph::hash_result, ); @@ -228,7 +226,9 @@ pub(super) fn run_aot( tcx.sess.abort_if_errors(); - let mut allocator_module = new_module(tcx, "allocator_shim".to_string()); + let isa = crate::build_isa(tcx.sess, &backend_config); + let mut allocator_module = crate::backend::make_module(tcx.sess, isa, "allocator_shim".to_string()); + assert_eq!(pointer_ty(tcx), allocator_module.target_config().pointer_type()); let mut allocator_unwind_context = UnwindContext::new(tcx, allocator_module.isa(), true); let created_alloc_shim = crate::allocator::codegen(tcx, &mut allocator_module, &mut allocator_unwind_context); @@ -236,6 +236,7 @@ pub(super) fn run_aot( let allocator_module = if created_alloc_shim { let ModuleCodegenResult(module, work_product) = emit_module( tcx, + &backend_config, "allocator_shim".to_string(), ModuleKind::Allocator, allocator_module, diff --git a/src/driver/jit.rs b/src/driver/jit.rs index dbe1ff083f0..e19283af10d 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -27,8 +27,8 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { let imported_symbols = load_imported_symbols_for_jit(tcx); - let mut jit_builder = - JITBuilder::with_isa(crate::build_isa(tcx.sess), cranelift_module::default_libcall_names()); + let isa = crate::build_isa(tcx.sess, &backend_config); + let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names()); jit_builder.hotswap(matches!(backend_config.codegen_mode, CodegenMode::JitLazy)); crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); jit_builder.symbols(imported_symbols); @@ -44,9 +44,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { .into_iter() .collect::<Vec<(_, (_, _))>>(); - let mut cx = crate::CodegenCx::new(tcx, backend_config, &mut jit_module, false); + let mut cx = crate::CodegenCx::new(tcx, backend_config.clone(), &mut jit_module, false); - super::time(tcx, "codegen mono items", || { + super::time(tcx, backend_config.display_cg_time, "codegen mono items", || { super::predefine_mono_items(&mut cx, &mono_items); for (mono_item, _) in mono_items { match mono_item { @@ -87,9 +87,8 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { "Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed" ); - let args = ::std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); let args = std::iter::once(&*tcx.crate_name(LOCAL_CRATE).as_str().to_string()) - .chain(args.split(' ')) + .chain(backend_config.jit_args.iter().map(|arg| &**arg)) .map(|arg| CString::new(arg).unwrap()) .collect::<Vec<_>>(); let mut argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>(); diff --git a/src/driver/mod.rs b/src/driver/mod.rs index d49182a07b7..960e10182d8 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -65,8 +65,8 @@ fn predefine_mono_items<'tcx>( }); } -fn time<R>(tcx: TyCtxt<'_>, name: &'static str, f: impl FnOnce() -> R) -> R { - if std::env::var("CG_CLIF_DISPLAY_CG_TIME").as_ref().map(|val| &**val) == Ok("1") { +fn time<R>(tcx: TyCtxt<'_>, display: bool, name: &'static str, f: impl FnOnce() -> R) -> R { + if display { println!("[{:<30}: {}] start", tcx.crate_name(LOCAL_CRATE), name); let before = std::time::Instant::now(); let res = tcx.sess.time(name, f); diff --git a/src/lib.rs b/src/lib.rs index 77c6247e157..9a417f35ae2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -193,7 +193,7 @@ impl CodegenBackend for CraneliftCodegenBackend { metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box<dyn Any> { - let config = if let Some(config) = self.config { + let config = if let Some(config) = self.config.clone() { config } else { BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args) @@ -237,7 +237,7 @@ fn target_triple(sess: &Session) -> target_lexicon::Triple { sess.target.llvm_target.parse().unwrap() } -fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> { +fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::TargetIsa + 'static> { use target_lexicon::BinaryFormat; let target_triple = crate::target_triple(sess); @@ -245,9 +245,8 @@ fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> { let mut flags_builder = settings::builder(); flags_builder.enable("is_pic").unwrap(); flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided - let enable_verifier = - cfg!(debug_assertions) || std::env::var("CG_CLIF_ENABLE_VERIFIER").is_ok(); - flags_builder.set("enable_verifier", if enable_verifier { "true" } else { "false" }).unwrap(); + let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" }; + flags_builder.set("enable_verifier", enable_verifier).unwrap(); let tls_model = match target_triple.binary_format { BinaryFormat::Elf => "elf_gd", diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index d22ea3772ee..166151ecc70 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -248,7 +248,7 @@ pub(crate) fn write_clif_file<'tcx>( &mut clif, &context.func, &DisplayFunctionAnnotations { - isa: Some(&*crate::build_isa(tcx.sess)), + isa, value_ranges: value_ranges.as_ref(), }, ) |
