File tree Expand file tree Collapse file tree 5 files changed +36
-1
lines changed Expand file tree Collapse file tree 5 files changed +36
-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 @@ -1260,6 +1260,14 @@ extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
12601260 unwrap (M)->setPIELevel (PIELevel::Level::Large);
12611261}
12621262
1263+ extern " C" void LLVMRustSetModuleCodeModel (LLVMModuleRef M,
1264+ LLVMRustCodeModel Model) {
1265+ auto CM = fromRust (Model);
1266+ if (!CM.hasValue ())
1267+ return ;
1268+ unwrap (M)->setCodeModel (*CM);
1269+ }
1270+
12631271// Here you'll find an implementation of ThinLTO as used by the Rust compiler
12641272// right now. This ThinLTO support is only enabled on "recent ish" versions of
12651273// LLVM, and otherwise it's just blanket rejected from other compilers.
Original file line number Diff line number Diff line change 1+ // revisions: NOMODEL MODEL-SMALL MODEL-KERNEL MODEL-MEDIUM MODEL-LARGE
2+ //[NOMODEL] compile-flags:
3+ //[MODEL-SMALL] compile-flags: -C code-model=small
4+ //[MODEL-KERNEL] compile-flags: --target x86_64-unknown-linux-gnu -C code-model=kernel
5+ //[MODEL-MEDIUM] compile-flags: -C code-model=medium
6+ //[MODEL-LARGE] compile-flags: -C code-model=large
7+
8+ #![ crate_type = "lib" ]
9+
10+ // MODEL-SMALL: !llvm.module.flags = !{{{.*}}}
11+ // MODEL-SMALL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 1}
12+ // MODEL-KERNEL: !llvm.module.flags = !{{{.*}}}
13+ // MODEL-KERNEL: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 2}
14+ // MODEL-MEDIUM: !llvm.module.flags = !{{{.*}}}
15+ // MODEL-MEDIUM: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 3}
16+ // MODEL-LARGE: !llvm.module.flags = !{{{.*}}}
17+ // MODEL-LARGE: !{{[0-9]+}} = !{i32 1, !"Code Model", i32 4}
18+ // NOMODEL-NOT: Code Model
You can’t perform that action at this time.
0 commit comments