Skip to content

Commit 84c08f8

Browse files
committed
Auto merge of #83044 - kubo39:set-llvm-code-model, r=nikic
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. This patch is based on #74002
2 parents f293f70 + 7141838 commit 84c08f8

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed

compiler/rustc_codegen_llvm/src/back/write.rs

+1-1
Original file line numberDiff line numberDiff 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,

compiler/rustc_codegen_llvm/src/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() {

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+1
Original file line numberDiff line numberDiff 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;

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+8
Original file line numberDiff line numberDiff 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.

src/test/codegen/codemodels.rs

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

0 commit comments

Comments
 (0)