about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2021-04-07 11:52:11 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2021-04-07 11:52:11 +0200
commit53bfc6729ae4a53c8092473452de7a272224df5d (patch)
tree4afae3c9d545328d747076545beb0a1ec85bbdaa
parent1ee0aa9416b9da220d7370007c5e3c402d6714b0 (diff)
downloadrust-53bfc6729ae4a53c8092473452de7a272224df5d.tar.gz
rust-53bfc6729ae4a53c8092473452de7a272224df5d.zip
Centralize all configuration into config.rs
-rw-r--r--Readme.md5
-rw-r--r--docs/env_vars.md15
-rw-r--r--scripts/ext_config.sh2
-rw-r--r--src/backend.rs10
-rw-r--r--src/config.rs66
-rw-r--r--src/driver/aot.rs27
-rw-r--r--src/driver/jit.rs11
-rw-r--r--src/driver/mod.rs4
-rw-r--r--src/lib.rs9
-rw-r--r--src/pretty_clif.rs2
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(),
             },
         )