Skip to content

Commit 1a5a224

Browse files
committed
Auto merge of rust-lang#130506 - nnethercote:rustc_codegen_llvm-cleanups, r=jieyouxu
`rustc_codegen_llvm` cleanups Some improvements I found while reading through this crate's code. r? `@michaelwoerister`
2 parents 2b11f26 + 1f35940 commit 1a5a224

File tree

21 files changed

+515
-648
lines changed

21 files changed

+515
-648
lines changed

compiler/rustc_codegen_gcc/src/common.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,14 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
8080
self.const_undef(typ)
8181
}
8282

83-
fn const_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> {
84-
self.gcc_int(typ, int)
85-
}
86-
87-
fn const_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
88-
self.gcc_uint(typ, int)
89-
}
90-
91-
fn const_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
92-
self.gcc_uint_big(typ, num)
93-
}
94-
9583
fn const_bool(&self, val: bool) -> RValue<'gcc> {
9684
self.const_uint(self.type_i1(), val as u64)
9785
}
9886

87+
fn const_i8(&self, i: i8) -> RValue<'gcc> {
88+
self.const_int(self.type_i8(), i as i64)
89+
}
90+
9991
fn const_i16(&self, i: i16) -> RValue<'gcc> {
10092
self.const_int(self.type_i16(), i as i64)
10193
}
@@ -104,8 +96,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
10496
self.const_int(self.type_i32(), i as i64)
10597
}
10698

107-
fn const_i8(&self, i: i8) -> RValue<'gcc> {
108-
self.const_int(self.type_i8(), i as i64)
99+
fn const_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> {
100+
self.gcc_int(typ, int)
101+
}
102+
103+
fn const_u8(&self, i: u8) -> RValue<'gcc> {
104+
self.const_uint(self.type_u8(), i as u64)
109105
}
110106

111107
fn const_u32(&self, i: u32) -> RValue<'gcc> {
@@ -130,8 +126,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
130126
self.const_uint(self.usize_type, i)
131127
}
132128

133-
fn const_u8(&self, i: u8) -> RValue<'gcc> {
134-
self.const_uint(self.type_u8(), i as u64)
129+
fn const_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
130+
self.gcc_uint(typ, int)
131+
}
132+
133+
fn const_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
134+
self.gcc_uint_big(typ, num)
135135
}
136136

137137
fn const_real(&self, typ: Type<'gcc>, val: f64) -> RValue<'gcc> {

compiler/rustc_codegen_llvm/src/asm.rs

+251-292
Large diffs are not rendered by default.

compiler/rustc_codegen_llvm/src/attributes.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
403403
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
404404
to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
405405
// HACK(jubilee): "indirect branch tracking" works by attaching prologues to functions.
406-
// And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules.
407-
// Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768
406+
// And it is a module-level attribute, so the alternative is pulling naked functions into
407+
// new LLVM modules. Otherwise LLVM's "naked" functions come with endbr prefixes per
408+
// https://github.com/rust-lang/rust/issues/98768
408409
to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
409410
if llvm_util::get_version() < (19, 0, 0) {
410411
// Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to
@@ -454,7 +455,8 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
454455
flags |= AllocKindFlags::Zeroed;
455456
}
456457
to_add.push(llvm::CreateAllocKindAttr(cx.llcx, flags));
457-
// apply to return place instead of function (unlike all other attributes applied in this function)
458+
// apply to return place instead of function (unlike all other attributes applied in this
459+
// function)
458460
let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
459461
attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
460462
}

compiler/rustc_codegen_llvm/src/back/lto.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,15 @@ fn get_bitcode_slice_from_object_data<'a>(
156156
obj: &'a [u8],
157157
cgcx: &CodegenContext<LlvmCodegenBackend>,
158158
) -> Result<&'a [u8], LtoBitcodeFromRlib> {
159-
// We're about to assume the data here is an object file with sections, but if it's raw LLVM IR that
160-
// won't work. Fortunately, if that's what we have we can just return the object directly, so we sniff
161-
// the relevant magic strings here and return.
159+
// We're about to assume the data here is an object file with sections, but if it's raw LLVM IR
160+
// that won't work. Fortunately, if that's what we have we can just return the object directly,
161+
// so we sniff the relevant magic strings here and return.
162162
if obj.starts_with(b"\xDE\xC0\x17\x0B") || obj.starts_with(b"BC\xC0\xDE") {
163163
return Ok(obj);
164164
}
165-
// We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment name"
166-
// which in the public API for sections gets treated as part of the section name, but internally
167-
// in MachOObjectFile.cpp gets treated separately.
165+
// We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment
166+
// name" which in the public API for sections gets treated as part of the section name, but
167+
// internally in MachOObjectFile.cpp gets treated separately.
168168
let section_name = bitcode_section_name(cgcx).trim_start_matches("__LLVM,");
169169
let mut len = 0;
170170
let data = unsafe {

compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl OwnedTargetMachine {
3030
data_sections: bool,
3131
unique_section_names: bool,
3232
trap_unreachable: bool,
33-
singletree: bool,
33+
singlethread: bool,
3434
verbose_asm: bool,
3535
emit_stack_size_section: bool,
3636
relax_elf_relocations: bool,
@@ -62,7 +62,7 @@ impl OwnedTargetMachine {
6262
data_sections,
6363
unique_section_names,
6464
trap_unreachable,
65-
singletree,
65+
singlethread,
6666
verbose_asm,
6767
emit_stack_size_section,
6868
relax_elf_relocations,
@@ -86,15 +86,17 @@ impl Deref for OwnedTargetMachine {
8686
type Target = llvm::TargetMachine;
8787

8888
fn deref(&self) -> &Self::Target {
89-
// SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
89+
// SAFETY: constructing ensures we have a valid pointer created by
90+
// llvm::LLVMRustCreateTargetMachine.
9091
unsafe { self.tm_unique.as_ref() }
9192
}
9293
}
9394

9495
impl Drop for OwnedTargetMachine {
9596
fn drop(&mut self) {
96-
// SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
97-
// OwnedTargetMachine is not copyable so there is no double free or use after free
97+
// SAFETY: constructing ensures we have a valid pointer created by
98+
// llvm::LLVMRustCreateTargetMachine OwnedTargetMachine is not copyable so there is no
99+
// double free or use after free.
98100
unsafe {
99101
llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut());
100102
}

compiler/rustc_codegen_llvm/src/back/write.rs

+17-16
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use crate::errors::{
3838
CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, UnknownCompression,
3939
WithLlvmError, WriteBytecode,
4040
};
41-
use crate::llvm::diagnostic::OptimizationDiagnosticKind;
41+
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
4242
use crate::llvm::{self, DiagnosticInfo, PassManager};
4343
use crate::type_::Type;
4444
use crate::{base, common, llvm_util, LlvmCodegenBackend, ModuleLlvm};
@@ -157,7 +157,8 @@ fn to_pass_builder_opt_level(cfg: config::OptLevel) -> llvm::PassBuilderOptLevel
157157
fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
158158
match relocation_model {
159159
RelocModel::Static => llvm::RelocModel::Static,
160-
// LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra attribute.
160+
// LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra
161+
// attribute.
161162
RelocModel::Pic | RelocModel::Pie => llvm::RelocModel::PIC,
162163
RelocModel::DynamicNoPic => llvm::RelocModel::DynamicNoPic,
163164
RelocModel::Ropi => llvm::RelocModel::ROPI,
@@ -188,8 +189,8 @@ pub(crate) fn target_machine_factory(
188189
let use_softfp = if sess.target.arch == "arm" && sess.target.abi == "eabihf" {
189190
sess.opts.cg.soft_float
190191
} else {
191-
// `validate_commandline_args_with_session_available` has already warned about this being ignored.
192-
// Let's make sure LLVM doesn't suddenly start using this flag on more targets.
192+
// `validate_commandline_args_with_session_available` has already warned about this being
193+
// ignored. Let's make sure LLVM doesn't suddenly start using this flag on more targets.
193194
false
194195
};
195196

@@ -446,13 +447,12 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
446447
column: opt.column,
447448
pass_name: &opt.pass_name,
448449
kind: match opt.kind {
449-
OptimizationDiagnosticKind::OptimizationRemark => "success",
450-
OptimizationDiagnosticKind::OptimizationMissed
451-
| OptimizationDiagnosticKind::OptimizationFailure => "missed",
452-
OptimizationDiagnosticKind::OptimizationAnalysis
453-
| OptimizationDiagnosticKind::OptimizationAnalysisFPCommute
454-
| OptimizationDiagnosticKind::OptimizationAnalysisAliasing => "analysis",
455-
OptimizationDiagnosticKind::OptimizationRemarkOther => "other",
450+
OptimizationRemark => "success",
451+
OptimizationMissed | OptimizationFailure => "missed",
452+
OptimizationAnalysis
453+
| OptimizationAnalysisFPCommute
454+
| OptimizationAnalysisAliasing => "analysis",
455+
OptimizationRemarkOther => "other",
456456
},
457457
message: &opt.message,
458458
});
@@ -945,11 +945,12 @@ fn create_section_with_flags_asm(section_name: &str, section_flags: &str, data:
945945
}
946946

947947
fn target_is_apple(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
948-
cgcx.opts.target_triple.triple().contains("-ios")
949-
|| cgcx.opts.target_triple.triple().contains("-darwin")
950-
|| cgcx.opts.target_triple.triple().contains("-tvos")
951-
|| cgcx.opts.target_triple.triple().contains("-watchos")
952-
|| cgcx.opts.target_triple.triple().contains("-visionos")
948+
let triple = cgcx.opts.target_triple.triple();
949+
triple.contains("-ios")
950+
|| triple.contains("-darwin")
951+
|| triple.contains("-tvos")
952+
|| triple.contains("-watchos")
953+
|| triple.contains("-visionos")
953954
}
954955

955956
fn target_is_aix(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {

compiler/rustc_codegen_llvm/src/builder.rs

+32-85
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl<'ll, 'tcx> Deref for Builder<'_, 'll, 'tcx> {
120120
}
121121
}
122122

123-
macro_rules! builder_methods_for_value_instructions {
123+
macro_rules! math_builder_methods {
124124
($($name:ident($($arg:ident),*) => $llvm_capi:ident),+ $(,)?) => {
125125
$(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
126126
unsafe {
@@ -130,6 +130,18 @@ macro_rules! builder_methods_for_value_instructions {
130130
}
131131
}
132132

133+
macro_rules! set_math_builder_methods {
134+
($($name:ident($($arg:ident),*) => ($llvm_capi:ident, $llvm_set_math:ident)),+ $(,)?) => {
135+
$(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
136+
unsafe {
137+
let instr = llvm::$llvm_capi(self.llbuilder, $($arg,)* UNNAMED);
138+
llvm::$llvm_set_math(instr);
139+
instr
140+
}
141+
})+
142+
}
143+
}
144+
133145
impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
134146
type CodegenCx = CodegenCx<'ll, 'tcx>;
135147

@@ -267,7 +279,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
267279
}
268280
}
269281

270-
builder_methods_for_value_instructions! {
282+
math_builder_methods! {
271283
add(a, b) => LLVMBuildAdd,
272284
fadd(a, b) => LLVMBuildFAdd,
273285
sub(a, b) => LLVMBuildSub,
@@ -299,84 +311,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
299311
unchecked_umul(x, y) => LLVMBuildNUWMul,
300312
}
301313

302-
fn fadd_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
303-
unsafe {
304-
let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
305-
llvm::LLVMRustSetFastMath(instr);
306-
instr
307-
}
308-
}
309-
310-
fn fsub_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
311-
unsafe {
312-
let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
313-
llvm::LLVMRustSetFastMath(instr);
314-
instr
315-
}
316-
}
317-
318-
fn fmul_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
319-
unsafe {
320-
let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
321-
llvm::LLVMRustSetFastMath(instr);
322-
instr
323-
}
324-
}
325-
326-
fn fdiv_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
327-
unsafe {
328-
let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
329-
llvm::LLVMRustSetFastMath(instr);
330-
instr
331-
}
332-
}
333-
334-
fn frem_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
335-
unsafe {
336-
let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
337-
llvm::LLVMRustSetFastMath(instr);
338-
instr
339-
}
340-
}
341-
342-
fn fadd_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
343-
unsafe {
344-
let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
345-
llvm::LLVMRustSetAlgebraicMath(instr);
346-
instr
347-
}
348-
}
349-
350-
fn fsub_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
351-
unsafe {
352-
let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
353-
llvm::LLVMRustSetAlgebraicMath(instr);
354-
instr
355-
}
356-
}
357-
358-
fn fmul_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
359-
unsafe {
360-
let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
361-
llvm::LLVMRustSetAlgebraicMath(instr);
362-
instr
363-
}
364-
}
365-
366-
fn fdiv_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
367-
unsafe {
368-
let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
369-
llvm::LLVMRustSetAlgebraicMath(instr);
370-
instr
371-
}
372-
}
373-
374-
fn frem_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
375-
unsafe {
376-
let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
377-
llvm::LLVMRustSetAlgebraicMath(instr);
378-
instr
379-
}
314+
set_math_builder_methods! {
315+
fadd_fast(x, y) => (LLVMBuildFAdd, LLVMRustSetFastMath),
316+
fsub_fast(x, y) => (LLVMBuildFSub, LLVMRustSetFastMath),
317+
fmul_fast(x, y) => (LLVMBuildFMul, LLVMRustSetFastMath),
318+
fdiv_fast(x, y) => (LLVMBuildFDiv, LLVMRustSetFastMath),
319+
frem_fast(x, y) => (LLVMBuildFRem, LLVMRustSetFastMath),
320+
fadd_algebraic(x, y) => (LLVMBuildFAdd, LLVMRustSetAlgebraicMath),
321+
fsub_algebraic(x, y) => (LLVMBuildFSub, LLVMRustSetAlgebraicMath),
322+
fmul_algebraic(x, y) => (LLVMBuildFMul, LLVMRustSetAlgebraicMath),
323+
fdiv_algebraic(x, y) => (LLVMBuildFDiv, LLVMRustSetAlgebraicMath),
324+
frem_algebraic(x, y) => (LLVMBuildFRem, LLVMRustSetAlgebraicMath),
380325
}
381326

382327
fn checked_binop(
@@ -459,6 +404,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
459404
val
460405
}
461406
}
407+
462408
fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value {
463409
if scalar.is_bool() {
464410
return self.trunc(val, self.cx().type_i1());
@@ -727,11 +673,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
727673
// for performance. LLVM doesn't seem to care about this, and will happily treat
728674
// `!nontemporal` stores as-if they were normal stores (for reordering optimizations
729675
// etc) even on x86, despite later lowering them to MOVNT which do *not* behave like
730-
// regular stores but require special fences.
731-
// So we keep a list of architectures where `!nontemporal` is known to be truly just
732-
// a hint, and use regular stores everywhere else.
733-
// (In the future, we could alternatively ensure that an sfence gets emitted after a sequence of movnt
734-
// before any kind of synchronizing operation. But it's not clear how to do that with LLVM.)
676+
// regular stores but require special fences. So we keep a list of architectures
677+
// where `!nontemporal` is known to be truly just a hint, and use regular stores
678+
// everywhere else. (In the future, we could alternatively ensure that an sfence
679+
// gets emitted after a sequence of movnt before any kind of synchronizing
680+
// operation. But it's not clear how to do that with LLVM.)
735681
// For more context, see <https://github.com/rust-lang/rust/issues/114582> and
736682
// <https://github.com/llvm/llvm-project/issues/64521>.
737683
const WELL_BEHAVED_NONTEMPORAL_ARCHS: &[&str] =
@@ -1160,6 +1106,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11601106
(val, success)
11611107
}
11621108
}
1109+
11631110
fn atomic_rmw(
11641111
&mut self,
11651112
op: rustc_codegen_ssa::common::AtomicRmwBinOp,

0 commit comments

Comments
 (0)