File tree Expand file tree Collapse file tree 5 files changed +38
-1
lines changed Expand file tree Collapse file tree 5 files changed +38
-1
lines changed Original file line number Diff line number Diff line change @@ -140,7 +140,7 @@ fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
140140 }
141141}
142142
143- fn to_llvm_code_model ( code_model : Option < CodeModel > ) -> llvm:: CodeModel {
143+ pub ( crate ) fn to_llvm_code_model ( code_model : Option < CodeModel > ) -> llvm:: CodeModel {
144144 match code_model {
145145 Some ( CodeModel :: Tiny ) => llvm:: CodeModel :: Tiny ,
146146 Some ( CodeModel :: Small ) => llvm:: CodeModel :: Small ,
Original file line number Diff line number Diff line change 11use crate :: attributes;
2+ use crate :: back:: write:: to_llvm_code_model;
23use crate :: callee:: get_fn;
34use crate :: coverageinfo;
45use crate :: debuginfo;
@@ -181,6 +182,13 @@ pub unsafe fn create_module(
181182 }
182183 }
183184
185+ // Linking object files with different code models is undefined behavior
186+ // because the compiler would have to generate additional code (to span
187+ // longer jumps) if a larger code model is used with a smaller one.
188+ //
189+ // See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323.
190+ llvm:: LLVMRustSetModuleCodeModel ( llmod, to_llvm_code_model ( sess. code_model ( ) ) ) ;
191+
184192 // If skipping the PLT is enabled, we need to add some module metadata
185193 // to ensure intrinsic calls don't use it.
186194 if !sess. needs_plt ( ) {
Original file line number Diff line number Diff line change @@ -2326,6 +2326,7 @@ extern "C" {
23262326 pub fn LLVMRustUnsetComdat ( V : & Value ) ;
23272327 pub fn LLVMRustSetModulePICLevel ( M : & Module ) ;
23282328 pub fn LLVMRustSetModulePIELevel ( M : & Module ) ;
2329+ pub fn LLVMRustSetModuleCodeModel ( M : & Module , Model : CodeModel ) ;
23292330 pub fn LLVMRustModuleBufferCreate ( M : & Module ) -> & ' static mut ModuleBuffer ;
23302331 pub fn LLVMRustModuleBufferPtr ( p : & ModuleBuffer ) -> * const u8 ;
23312332 pub fn LLVMRustModuleBufferLen ( p : & ModuleBuffer ) -> usize ;
Original file line number Diff line number Diff line change @@ -1264,6 +1264,14 @@ extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
12641264 unwrap (M)->setPIELevel (PIELevel::Level::Large);
12651265}
12661266
1267+ extern " C" void LLVMRustSetModuleCodeModel (LLVMModuleRef M,
1268+ LLVMRustCodeModel Model) {
1269+ auto CM = fromRust (Model);
1270+ if (!CM.hasValue ())
1271+ return ;
1272+ unwrap (M)->setCodeModel (*CM);
1273+ }
1274+
12671275// Here you'll find an implementation of ThinLTO as used by the Rust compiler
12681276// right now. This ThinLTO support is only enabled on "recent ish" versions of
12691277// LLVM, and otherwise it's just blanket rejected from other compilers.
Original file line number Diff line number Diff line change 1+ // only-x86_64
2+
3+ // revisions: NOMODEL MODEL-SMALL MODEL-KERNEL MODEL-MEDIUM MODEL-LARGE
4+ //[NOMODEL] compile-flags:
5+ //[MODEL-SMALL] compile-flags: -C code-model=small
6+ //[MODEL-KERNEL] compile-flags: -C code-model=kernel
7+ //[MODEL-MEDIUM] compile-flags: -C code-model=medium
8+ //[MODEL-LARGE] compile-flags: -C code-model=large
9+
10+ #![ crate_type = "lib" ]
11+
12+ // MODEL-SMALL: !llvm.module.flags = !{{{.*}}}
13+ // MODEL-SMALL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 1}
14+ // MODEL-KERNEL: !llvm.module.flags = !{{{.*}}}
15+ // MODEL-KERNEL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 2}
16+ // MODEL-MEDIUM: !llvm.module.flags = !{{{.*}}}
17+ // MODEL-MEDIUM: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 3}
18+ // MODEL-LARGE: !llvm.module.flags = !{{{.*}}}
19+ // MODEL-LARGE: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 4}
20+ // NOMODEL-NOT: Code Model
You can’t perform that action at this time.
0 commit comments