Skip to content

Commit 6e75657

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 0d23e5e + 67a5e2b commit 6e75657

File tree

5 files changed

+36
-1
lines changed

5 files changed

+36
-1
lines changed

src/librustc_codegen_llvm/back/write.rs

Lines changed: 1 addition & 1 deletion
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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,6 +2129,7 @@ extern "C" {
21292129
pub fn LLVMRustUnsetComdat(V: &Value);
21302130
pub fn LLVMRustSetModulePICLevel(M: &Module);
21312131
pub fn LLVMRustSetModulePIELevel(M: &Module);
2132+
pub fn LLVMRustSetModuleCodeModel(M: &Module, Model: CodeModel);
21322133
pub fn LLVMRustModuleBufferCreate(M: &Module) -> &'static mut ModuleBuffer;
21332134
pub fn LLVMRustModuleBufferPtr(p: &ModuleBuffer) -> *const u8;
21342135
pub fn LLVMRustModuleBufferLen(p: &ModuleBuffer) -> usize;

src/rustllvm/PassWrapper.cpp

Lines changed: 8 additions & 0 deletions
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

Lines changed: 18 additions & 0 deletions
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: --target=x86_64-unknown-linux-gnu -C code-model=kernel
5+
//[MODEL-MEDIUM] compile-flags: --target=x86_64-unknown-linux-gnu -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)