File tree 5 files changed +36
-1
lines changed
5 files changed +36
-1
lines changed Original file line number Diff line number Diff line change @@ -108,7 +108,7 @@ fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
108
108
}
109
109
}
110
110
111
- fn to_llvm_code_model ( code_model : Option < CodeModel > ) -> llvm:: CodeModel {
111
+ pub ( crate ) fn to_llvm_code_model ( code_model : Option < CodeModel > ) -> llvm:: CodeModel {
112
112
match code_model {
113
113
Some ( CodeModel :: Tiny ) => llvm:: CodeModel :: Tiny ,
114
114
Some ( CodeModel :: Small ) => llvm:: CodeModel :: Small ,
Original file line number Diff line number Diff line change 1
1
use crate :: attributes;
2
+ use crate :: back:: write:: to_llvm_code_model;
2
3
use crate :: callee:: get_fn;
3
4
use crate :: coverageinfo;
4
5
use crate :: debuginfo;
@@ -181,6 +182,13 @@ pub unsafe fn create_module(
181
182
}
182
183
}
183
184
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
+
184
192
// If skipping the PLT is enabled, we need to add some module metadata
185
193
// to ensure intrinsic calls don't use it.
186
194
if !sess. needs_plt ( ) {
Original file line number Diff line number Diff line change @@ -2139,6 +2139,7 @@ extern "C" {
2139
2139
pub fn LLVMRustUnsetComdat ( V : & Value ) ;
2140
2140
pub fn LLVMRustSetModulePICLevel ( M : & Module ) ;
2141
2141
pub fn LLVMRustSetModulePIELevel ( M : & Module ) ;
2142
+ pub fn LLVMRustSetModuleCodeModel ( M : & Module , Model : CodeModel ) ;
2142
2143
pub fn LLVMRustModuleBufferCreate ( M : & Module ) -> & ' static mut ModuleBuffer ;
2143
2144
pub fn LLVMRustModuleBufferPtr ( p : & ModuleBuffer ) -> * const u8 ;
2144
2145
pub fn LLVMRustModuleBufferLen ( p : & ModuleBuffer ) -> usize ;
Original file line number Diff line number Diff line change @@ -1163,6 +1163,14 @@ extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
1163
1163
unwrap (M)->setPIELevel (PIELevel::Level::Large);
1164
1164
}
1165
1165
1166
+ extern " C" void LLVMRustSetModuleCodeModel (LLVMModuleRef M,
1167
+ LLVMRustCodeModel Model) {
1168
+ auto CM = fromRust (Model);
1169
+ if (!CM.hasValue ())
1170
+ return ;
1171
+ unwrap (M)->setCodeModel (*CM);
1172
+ }
1173
+
1166
1174
// Here you'll find an implementation of ThinLTO as used by the Rust compiler
1167
1175
// right now. This ThinLTO support is only enabled on "recent ish" versions of
1168
1176
// 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: -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