Skip to content

Commit 03032e8

Browse files
authored
Rollup merge of rust-lang#74002 - kubo39:set-code-model, r=nagisa
Add support for storing code model to LLVM module IR This patch avoids undefined behavior by linking different object files. Also this would it could be propagated properly to LTO. See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323.
2 parents 7457f48 + 5c24a94 commit 03032e8

File tree

5 files changed

+36
-1
lines changed

5 files changed

+36
-1
lines changed

src/librustc_codegen_llvm/back/write.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
108108
}
109109
}
110110

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 {
112112
match code_model {
113113
Some(CodeModel::Tiny) => llvm::CodeModel::Tiny,
114114
Some(CodeModel::Small) => llvm::CodeModel::Small,

src/librustc_codegen_llvm/context.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::attributes;
2+
use crate::back::write::to_llvm_code_model;
23
use crate::callee::get_fn;
34
use crate::coverageinfo;
45
use 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() {

src/librustc_codegen_llvm/llvm/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2139,6 +2139,7 @@ extern "C" {
21392139
pub fn LLVMRustUnsetComdat(V: &Value);
21402140
pub fn LLVMRustSetModulePICLevel(M: &Module);
21412141
pub fn LLVMRustSetModulePIELevel(M: &Module);
2142+
pub fn LLVMRustSetModuleCodeModel(M: &Module, Model: CodeModel);
21422143
pub fn LLVMRustModuleBufferCreate(M: &Module) -> &'static mut ModuleBuffer;
21432144
pub fn LLVMRustModuleBufferPtr(p: &ModuleBuffer) -> *const u8;
21442145
pub fn LLVMRustModuleBufferLen(p: &ModuleBuffer) -> usize;

src/rustllvm/PassWrapper.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,14 @@ extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
11631163
unwrap(M)->setPIELevel(PIELevel::Level::Large);
11641164
}
11651165

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+
11661174
// Here you'll find an implementation of ThinLTO as used by the Rust compiler
11671175
// right now. This ThinLTO support is only enabled on "recent ish" versions of
11681176
// LLVM, and otherwise it's just blanket rejected from other compilers.

src/test/codegen/codemodels.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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

0 commit comments

Comments
 (0)