about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-17 21:22:48 +0000
committerbors <bors@rust-lang.org>2020-05-17 21:22:48 +0000
commit5f472813dfa3f4c380a7a24e350d3e6a5a66ae7c (patch)
tree1f88e9eb84127e4efdc3c72a42b90656d4f05255
parentd79f1bd31a1401b5d08096fcdf9a9eb23ddf95df (diff)
parent59187f97713b8c9d54a4697dfe736037ddc22f8a (diff)
downloadrust-5f472813dfa3f4c380a7a24e350d3e6a5a66ae7c.tar.gz
rust-5f472813dfa3f4c380a7a24e350d3e6a5a66ae7c.zip
Auto merge of #72248 - petrochenkov:codemodel, r=Amanieu
Cleanup and document `-C code-model`

r? @Amanieu
-rw-r--r--src/doc/rustc/src/codegen-options/index.md20
-rw-r--r--src/librustc_codegen_llvm/back/write.rs35
-rw-r--r--src/librustc_codegen_llvm/lib.rs2
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs4
-rw-r--r--src/librustc_interface/tests.rs4
-rw-r--r--src/librustc_session/config.rs7
-rw-r--r--src/librustc_session/options.rs17
-rw-r--r--src/librustc_session/session.rs7
-rw-r--r--src/librustc_target/spec/mod.rs54
-rw-r--r--src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs4
-rw-r--r--src/librustc_target/spec/riscv64gc_unknown_none_elf.rs4
-rw-r--r--src/librustc_target/spec/riscv64imac_unknown_none_elf.rs4
-rw-r--r--src/librustc_target/spec/x86_64_linux_kernel.rs4
-rw-r--r--src/librustc_target/spec/x86_64_unknown_uefi.rs4
-rw-r--r--src/rustllvm/PassWrapper.cpp12
15 files changed, 125 insertions, 57 deletions
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index c638f88057a..9180f48bd94 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -9,9 +9,25 @@ This option is deprecated and does nothing.
 
 ## code-model
 
-This option lets you choose which code model to use.
+This option lets you choose which code model to use. \
+Code models put constraints on address ranges that the program and its symbols may use. \
+With smaller address ranges machine instructions
+may be able to use use more compact addressing modes.
 
-To find the valid options for this flag, run `rustc --print code-models`.
+The specific ranges depend on target architectures and addressing modes available to them. \
+For x86 more detailed description of its code models can be found in
+[System V Application Binary Interface](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf)
+specification.
+
+Supported values for this option are:
+
+<!-- - `tiny` - Tiny code model. -->
+- `small` - Small code model. This is the default model for majority of supported targets.
+- `kernel` - Kernel code model.
+- `medium` - Medium code model.
+- `large` - Large code model.
+
+Supported values can also be discovered by running `rustc --print code-models`.
 
 ## codegen-units
 
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index a08235b304d..6ed9cd69738 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -24,7 +24,7 @@ use rustc_middle::bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{self, Lto, OutputType, Passes, Sanitizer, SwitchWithOptPath};
 use rustc_session::Session;
-use rustc_target::spec::RelocModel;
+use rustc_target::spec::{CodeModel, RelocModel};
 
 use libc::{c_char, c_int, c_uint, c_void, size_t};
 use std::ffi::CString;
@@ -35,13 +35,6 @@ use std::slice;
 use std::str;
 use std::sync::Arc;
 
-pub const CODE_GEN_MODEL_ARGS: &[(&str, llvm::CodeModel)] = &[
-    ("small", llvm::CodeModel::Small),
-    ("kernel", llvm::CodeModel::Kernel),
-    ("medium", llvm::CodeModel::Medium),
-    ("large", llvm::CodeModel::Large),
-];
-
 pub fn llvm_err(handler: &rustc_errors::Handler, msg: &str) -> FatalError {
     match llvm::last_error() {
         Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
@@ -114,6 +107,17 @@ fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
     }
 }
 
+fn to_llvm_code_model(code_model: Option<CodeModel>) -> llvm::CodeModel {
+    match code_model {
+        Some(CodeModel::Tiny) => llvm::CodeModel::Tiny,
+        Some(CodeModel::Small) => llvm::CodeModel::Small,
+        Some(CodeModel::Kernel) => llvm::CodeModel::Kernel,
+        Some(CodeModel::Medium) => llvm::CodeModel::Medium,
+        Some(CodeModel::Large) => llvm::CodeModel::Large,
+        None => llvm::CodeModel::None,
+    }
+}
+
 pub fn target_machine_factory(
     sess: &Session,
     optlvl: config::OptLevel,
@@ -126,20 +130,7 @@ pub fn target_machine_factory(
     let ffunction_sections = sess.target.target.options.function_sections;
     let fdata_sections = ffunction_sections;
 
-    let code_model_arg =
-        sess.opts.cg.code_model.as_ref().or(sess.target.target.options.code_model.as_ref());
-
-    let code_model = match code_model_arg {
-        Some(s) => match CODE_GEN_MODEL_ARGS.iter().find(|arg| arg.0 == s) {
-            Some(x) => x.1,
-            _ => {
-                sess.err(&format!("{:?} is not a valid code model", code_model_arg));
-                sess.abort_if_errors();
-                bug!();
-            }
-        },
-        None => llvm::CodeModel::None,
-    };
+    let code_model = to_llvm_code_model(sess.code_model());
 
     let features = attributes::llvm_target_features(sess).collect::<Vec<_>>();
     let mut singlethread = sess.target.target.options.singlethread;
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 63af60e14db..6afd4278451 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -208,7 +208,7 @@ impl CodegenBackend for LlvmCodegenBackend {
             }
             PrintRequest::CodeModels => {
                 println!("Available code models:");
-                for &(name, _) in back::write::CODE_GEN_MODEL_ARGS.iter() {
+                for name in &["small", "kernel", "medium", "large"] {
                     println!("    {}", name);
                 }
                 println!();
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 713cb2324f7..21dfc113351 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -458,9 +458,7 @@ pub enum RelocModel {
 #[derive(Copy, Clone)]
 #[repr(C)]
 pub enum CodeModel {
-    // FIXME: figure out if this variant is needed at all.
-    #[allow(dead_code)]
-    Other,
+    Tiny,
     Small,
     Kernel,
     Medium,
diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs
index 68b749e1084..5e17660f4c6 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -15,7 +15,7 @@ use rustc_session::{build_session, Session};
 use rustc_span::edition::{Edition, DEFAULT_EDITION};
 use rustc_span::symbol::sym;
 use rustc_span::SourceFileHashAlgorithm;
-use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy};
+use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy};
 use rustc_target::spec::{RelocModel, RelroLevel, TlsModel};
 use std::collections::{BTreeMap, BTreeSet};
 use std::iter::FromIterator;
@@ -411,7 +411,7 @@ fn test_codegen_options_tracking_hash() {
 
     // Make sure that changing a [TRACKED] option changes the hash.
     // This list is in alphabetical order.
-    tracked!(code_model, Some(String::from("code model")));
+    tracked!(code_model, Some(CodeModel::Large));
     tracked!(debug_assertions, Some(true));
     tracked!(debuginfo, 0xdeadbeef);
     tracked!(embed_bitcode, false);
diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs
index 402ed054be4..5f34a39db05 100644
--- a/src/librustc_session/config.rs
+++ b/src/librustc_session/config.rs
@@ -1324,10 +1324,6 @@ fn collect_print_requests(
         prints.push(PrintRequest::TargetFeatures);
         cg.target_feature = String::new();
     }
-    if cg.code_model.as_ref().map_or(false, |s| s == "help") {
-        prints.push(PrintRequest::CodeModels);
-        cg.code_model = None;
-    }
 
     prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
         "crate-name" => PrintRequest::CrateName,
@@ -2010,7 +2006,7 @@ crate mod dep_tracking {
     use crate::utils::NativeLibraryKind;
     use rustc_feature::UnstableFeatures;
     use rustc_span::edition::Edition;
-    use rustc_target::spec::{MergeFunctions, PanicStrategy, RelocModel};
+    use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel};
     use rustc_target::spec::{RelroLevel, TargetTriple, TlsModel};
     use std::collections::hash_map::DefaultHasher;
     use std::collections::BTreeMap;
@@ -2060,6 +2056,7 @@ crate mod dep_tracking {
     impl_dep_tracking_hash_via_hash!(Option<Vec<String>>);
     impl_dep_tracking_hash_via_hash!(Option<MergeFunctions>);
     impl_dep_tracking_hash_via_hash!(Option<RelocModel>);
+    impl_dep_tracking_hash_via_hash!(Option<CodeModel>);
     impl_dep_tracking_hash_via_hash!(Option<TlsModel>);
     impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
     impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs
index e2c82a397c7..a8d213a8663 100644
--- a/src/librustc_session/options.rs
+++ b/src/librustc_session/options.rs
@@ -5,9 +5,8 @@ use crate::lint;
 use crate::search_paths::SearchPath;
 use crate::utils::NativeLibraryKind;
 
-use rustc_target::spec::TargetTriple;
-use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy};
-use rustc_target::spec::{RelocModel, RelroLevel, TlsModel};
+use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy};
+use rustc_target::spec::{RelocModel, RelroLevel, TargetTriple, TlsModel};
 
 use rustc_feature::UnstableFeatures;
 use rustc_span::edition::Edition;
@@ -269,6 +268,8 @@ macro_rules! options {
         pub const parse_src_file_hash: &str = "either `md5` or `sha1`";
         pub const parse_relocation_model: &str =
             "one of supported relocation models (`rustc --print relocation-models`)";
+        pub const parse_code_model: &str =
+            "one of supported code models (`rustc --print code-models`)";
         pub const parse_tls_model: &str =
             "one of supported TLS models (`rustc --print tls-models`)";
         pub const parse_target_feature: &str = parse_string;
@@ -621,6 +622,14 @@ macro_rules! options {
             true
         }
 
+        fn parse_code_model(slot: &mut Option<CodeModel>, v: Option<&str>) -> bool {
+            match v.and_then(|s| CodeModel::from_str(s).ok()) {
+                Some(code_model) => *slot = Some(code_model),
+                _ => return false,
+            }
+            true
+        }
+
         fn parse_tls_model(slot: &mut Option<TlsModel>, v: Option<&str>) -> bool {
             match v.and_then(|s| TlsModel::from_str(s).ok()) {
                 Some(tls_model) => *slot = Some(tls_model),
@@ -676,7 +685,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
 
     ar: String = (String::new(), parse_string, [UNTRACKED],
         "this option is deprecated and does nothing"),
-    code_model: Option<String> = (None, parse_opt_string, [TRACKED],
+    code_model: Option<CodeModel> = (None, parse_code_model, [TRACKED],
         "choose the code model to use (`rustc --print code-models` for details)"),
     codegen_units: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
         "divide crate into N units to optimize in parallel"),
diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs
index cb5bd37442a..847b07f0e46 100644
--- a/src/librustc_session/session.rs
+++ b/src/librustc_session/session.rs
@@ -23,7 +23,8 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported
 use rustc_span::edition::Edition;
 use rustc_span::source_map::{self, FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
 use rustc_span::{SourceFileHashAlgorithm, Symbol};
-use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target, TargetTriple, TlsModel};
+use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
+use rustc_target::spec::{Target, TargetTriple, TlsModel};
 
 use std::cell::{self, RefCell};
 use std::env;
@@ -625,6 +626,10 @@ impl Session {
         self.opts.cg.relocation_model.unwrap_or(self.target.target.options.relocation_model)
     }
 
+    pub fn code_model(&self) -> Option<CodeModel> {
+        self.opts.cg.code_model.or(self.target.target.options.code_model)
+    }
+
     pub fn tls_model(&self) -> TlsModel {
         self.opts.debugging_opts.tls_model.unwrap_or(self.target.target.options.tls_model)
     }
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index c7b2023ddca..49b33059b63 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -306,6 +306,43 @@ impl ToJson for RelocModel {
 }
 
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum CodeModel {
+    Tiny,
+    Small,
+    Kernel,
+    Medium,
+    Large,
+}
+
+impl FromStr for CodeModel {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<CodeModel, ()> {
+        Ok(match s {
+            // "tiny" => CodeModel::Tiny, // Not exposed to users right now.
+            "small" => CodeModel::Small,
+            "kernel" => CodeModel::Kernel,
+            "medium" => CodeModel::Medium,
+            "large" => CodeModel::Large,
+            _ => return Err(()),
+        })
+    }
+}
+
+impl ToJson for CodeModel {
+    fn to_json(&self) -> Json {
+        match *self {
+            CodeModel::Tiny => "tiny",
+            CodeModel::Small => "small",
+            CodeModel::Kernel => "kernel",
+            CodeModel::Medium => "medium",
+            CodeModel::Large => "large",
+        }
+        .to_json()
+    }
+}
+
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum TlsModel {
     GeneralDynamic,
     LocalDynamic,
@@ -699,7 +736,8 @@ pub struct TargetOptions {
     /// -relocation-model=$relocation_model`. Defaults to `Pic`.
     pub relocation_model: RelocModel,
     /// Code model to use. Corresponds to `llc -code-model=$code_model`.
-    pub code_model: Option<String>,
+    /// Defaults to `None` which means "inherited from the base LLVM target".
+    pub code_model: Option<CodeModel>,
     /// TLS model to use. Options are "global-dynamic" (default), "local-dynamic", "initial-exec"
     /// and "local-exec". This is similar to the -ftls-model option in GCC/Clang.
     pub tls_model: TlsModel,
@@ -1114,6 +1152,18 @@ impl Target {
                     Some(Ok(()))
                 })).unwrap_or(Ok(()))
             } );
+            ($key_name:ident, CodeModel) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
+                    match s.parse::<CodeModel>() {
+                        Ok(code_model) => base.options.$key_name = Some(code_model),
+                        _ => return Some(Err(format!("'{}' is not a valid code model. \
+                                                      Run `rustc --print code-models` to \
+                                                      see the list of supported values.", s))),
+                    }
+                    Some(Ok(()))
+                })).unwrap_or(Ok(()))
+            } );
             ($key_name:ident, TlsModel) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
@@ -1266,7 +1316,7 @@ impl Target {
         key!(only_cdylib, bool);
         key!(executables, bool);
         key!(relocation_model, RelocModel)?;
-        key!(code_model, optional);
+        key!(code_model, CodeModel)?;
         key!(tls_model, TlsModel)?;
         key!(disable_redzone, bool);
         key!(eliminate_frame_pointer, bool);
diff --git a/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs b/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs
index 638e6770ebf..715449d74ce 100644
--- a/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs
+++ b/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{CodeModel, LinkerFlavor, Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
     Ok(Target {
@@ -14,7 +14,7 @@ pub fn target() -> TargetResult {
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
             abi_blacklist: super::riscv_base::abi_blacklist(),
-            code_model: Some("medium".to_string()),
+            code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".to_string(),
             features: "+m,+a,+f,+d,+c".to_string(),
             llvm_abiname: "lp64d".to_string(),
diff --git a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs b/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
index 9dbbcb1f4bd..7376a14e951 100644
--- a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel};
+use crate::spec::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel};
 use crate::spec::{Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
             executables: true,
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
-            code_model: Some("medium".to_string()),
+            code_model: Some(CodeModel::Medium),
             emit_debug_gdb_scripts: false,
             abi_blacklist: super::riscv_base::abi_blacklist(),
             eliminate_frame_pointer: false,
diff --git a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
index 7e9390561a7..a3b0eb5334f 100644
--- a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
@@ -1,5 +1,5 @@
+use crate::spec::{CodeModel, Target, TargetOptions, TargetResult};
 use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel};
-use crate::spec::{Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
     Ok(Target {
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
             executables: true,
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
-            code_model: Some("medium".to_string()),
+            code_model: Some(CodeModel::Medium),
             emit_debug_gdb_scripts: false,
             abi_blacklist: super::riscv_base::abi_blacklist(),
             eliminate_frame_pointer: false,
diff --git a/src/librustc_target/spec/x86_64_linux_kernel.rs b/src/librustc_target/spec/x86_64_linux_kernel.rs
index 89070c99e39..65bb97d84aa 100644
--- a/src/librustc_target/spec/x86_64_linux_kernel.rs
+++ b/src/librustc_target/spec/x86_64_linux_kernel.rs
@@ -1,7 +1,7 @@
 // This defines the amd64 target for the Linux Kernel. See the linux-kernel-base module for
 // generic Linux kernel options.
 
-use crate::spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{CodeModel, LinkerFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::linux_kernel_base::opts();
@@ -10,7 +10,7 @@ pub fn target() -> TargetResult {
     base.features =
         "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
             .to_string();
-    base.code_model = Some("kernel".to_string());
+    base.code_model = Some(CodeModel::Kernel);
     base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs
index 12edc29330a..849227a574a 100644
--- a/src/librustc_target/spec/x86_64_unknown_uefi.rs
+++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs
@@ -5,7 +5,7 @@
 // The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
 // LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
 
-use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
+use crate::spec::{CodeModel, LinkerFlavor, LldFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::uefi_msvc_base::opts();
@@ -26,7 +26,7 @@ pub fn target() -> TargetResult {
     // UEFI systems run without a host OS, hence we cannot assume any code locality. We must tell
     // LLVM to expect code to reference any address in the address-space. The "large" code-model
     // places no locality-restrictions, so it fits well here.
-    base.code_model = Some("large".to_string());
+    base.code_model = Some(CodeModel::Large);
 
     Ok(Target {
         llvm_target: "x86_64-unknown-windows".to_string(),
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index b17fa57c5c1..6c638c5453a 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -274,7 +274,7 @@ extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
 }
 
 enum class LLVMRustCodeModel {
-  Other,
+  Tiny,
   Small,
   Kernel,
   Medium,
@@ -282,8 +282,10 @@ enum class LLVMRustCodeModel {
   None,
 };
 
-static CodeModel::Model fromRust(LLVMRustCodeModel Model) {
+static Optional<CodeModel::Model> fromRust(LLVMRustCodeModel Model) {
   switch (Model) {
+  case LLVMRustCodeModel::Tiny:
+    return CodeModel::Tiny;
   case LLVMRustCodeModel::Small:
     return CodeModel::Small;
   case LLVMRustCodeModel::Kernel:
@@ -292,6 +294,8 @@ static CodeModel::Model fromRust(LLVMRustCodeModel Model) {
     return CodeModel::Medium;
   case LLVMRustCodeModel::Large:
     return CodeModel::Large;
+  case LLVMRustCodeModel::None:
+    return None;
   default:
     report_fatal_error("Bad CodeModel.");
   }
@@ -452,6 +456,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
 
   auto OptLevel = fromRust(RustOptLevel);
   auto RM = fromRust(RustReloc);
+  auto CM = fromRust(RustCM);
 
   std::string Error;
   Triple Trip(Triple::normalize(TripleStr));
@@ -490,9 +495,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
 
   Options.EmitStackSizeSection = EmitStackSizeSection;
 
-  Optional<CodeModel::Model> CM;
-  if (RustCM != LLVMRustCodeModel::None)
-    CM = fromRust(RustCM);
   TargetMachine *TM = TheTarget->createTargetMachine(
       Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
   return wrap(TM);