Skip to content

Commit a300087

Browse files
committed
refactor: replace LLVMRustBuildMem{Cpy,Move,Set} with plain LLVM functions
The only difference between our wrappers and the plain LLVM functions is that our wrappers take an extra `volatile` argument. But we can easily just set the `volatile` flag on the LLVM IR instructions after creating them using `LLVMSetVolatile`.
1 parent 5767910 commit a300087

File tree

3 files changed

+50
-77
lines changed

3 files changed

+50
-77
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,7 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
177177

178178
fn memset(&mut self, ptr: &'ll Value, fill_byte: &'ll Value, size: &'ll Value, align: Align) {
179179
unsafe {
180-
llvm::LLVMRustBuildMemSet(
181-
self.llbuilder,
182-
ptr,
183-
align.bytes() as c_uint,
184-
fill_byte,
185-
size,
186-
false,
187-
);
180+
llvm::LLVMBuildMemSet(self.llbuilder, ptr, align.bytes() as c_uint, fill_byte, size);
188181
}
189182
}
190183
}
@@ -1103,17 +1096,22 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11031096
let size = self.intcast(size, self.type_isize(), false);
11041097
let is_volatile = flags.contains(MemFlags::VOLATILE);
11051098
let memcpy = unsafe {
1106-
llvm::LLVMRustBuildMemCpy(
1099+
llvm::LLVMBuildMemCpy(
11071100
self.llbuilder,
11081101
dst,
11091102
dst_align.bytes() as c_uint,
11101103
src,
11111104
src_align.bytes() as c_uint,
11121105
size,
1113-
is_volatile,
11141106
)
11151107
};
11161108

1109+
if is_volatile {
1110+
unsafe {
1111+
llvm::LLVMSetVolatile(memcpy, llvm::TRUE);
1112+
}
1113+
}
1114+
11171115
// TypeTree metadata for memcpy is especially important: when Enzyme encounters
11181116
// a memcpy during autodiff, it needs to know the structure of the data being
11191117
// copied to properly track derivatives. For example, copying an array of floats
@@ -1136,16 +1134,21 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11361134
assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memmove not supported");
11371135
let size = self.intcast(size, self.type_isize(), false);
11381136
let is_volatile = flags.contains(MemFlags::VOLATILE);
1139-
unsafe {
1140-
llvm::LLVMRustBuildMemMove(
1137+
let memmove = unsafe {
1138+
llvm::LLVMBuildMemMove(
11411139
self.llbuilder,
11421140
dst,
11431141
dst_align.bytes() as c_uint,
11441142
src,
11451143
src_align.bytes() as c_uint,
11461144
size,
1147-
is_volatile,
1148-
);
1145+
)
1146+
};
1147+
1148+
if is_volatile {
1149+
unsafe {
1150+
llvm::LLVMSetVolatile(memmove, llvm::TRUE);
1151+
}
11491152
}
11501153
}
11511154

@@ -1159,15 +1162,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11591162
) {
11601163
assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memset not supported");
11611164
let is_volatile = flags.contains(MemFlags::VOLATILE);
1162-
unsafe {
1163-
llvm::LLVMRustBuildMemSet(
1164-
self.llbuilder,
1165-
ptr,
1166-
align.bytes() as c_uint,
1167-
fill_byte,
1168-
size,
1169-
is_volatile,
1170-
);
1165+
let memset = unsafe {
1166+
llvm::LLVMBuildMemSet(self.llbuilder, ptr, align.bytes() as c_uint, fill_byte, size)
1167+
};
1168+
1169+
if is_volatile {
1170+
unsafe {
1171+
llvm::LLVMSetVolatile(memset, llvm::TRUE);
1172+
}
11711173
}
11721174
}
11731175

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,6 +1693,31 @@ unsafe extern "C" {
16931693
NumBundles: c_uint,
16941694
Name: *const c_char,
16951695
) -> &'a Value;
1696+
1697+
// Memory operations
1698+
pub(crate) fn LLVMBuildMemCpy<'a>(
1699+
B: &Builder<'a>,
1700+
Dst: &'a Value,
1701+
DstAlign: c_uint,
1702+
Src: &'a Value,
1703+
SrcAlign: c_uint,
1704+
Size: &'a Value,
1705+
) -> &'a Value;
1706+
pub(crate) fn LLVMBuildMemMove<'a>(
1707+
B: &Builder<'a>,
1708+
Dst: &'a Value,
1709+
DstAlign: c_uint,
1710+
Src: &'a Value,
1711+
SrcAlign: c_uint,
1712+
Size: &'a Value,
1713+
) -> &'a Value;
1714+
pub(crate) fn LLVMBuildMemSet<'a>(
1715+
B: &Builder<'a>,
1716+
Dst: &'a Value,
1717+
DstAlign: c_uint,
1718+
Val: &'a Value,
1719+
Size: &'a Value,
1720+
) -> &'a Value;
16961721
}
16971722

16981723
// FFI bindings for `DIBuilder` functions in the LLVM-C API.
@@ -2016,33 +2041,6 @@ unsafe extern "C" {
20162041
pub(crate) fn LLVMRustSetAllowReassoc(Instr: &Value);
20172042

20182043
// Miscellaneous instructions
2019-
pub(crate) fn LLVMRustBuildMemCpy<'a>(
2020-
B: &Builder<'a>,
2021-
Dst: &'a Value,
2022-
DstAlign: c_uint,
2023-
Src: &'a Value,
2024-
SrcAlign: c_uint,
2025-
Size: &'a Value,
2026-
IsVolatile: bool,
2027-
) -> &'a Value;
2028-
pub(crate) fn LLVMRustBuildMemMove<'a>(
2029-
B: &Builder<'a>,
2030-
Dst: &'a Value,
2031-
DstAlign: c_uint,
2032-
Src: &'a Value,
2033-
SrcAlign: c_uint,
2034-
Size: &'a Value,
2035-
IsVolatile: bool,
2036-
) -> &'a Value;
2037-
pub(crate) fn LLVMRustBuildMemSet<'a>(
2038-
B: &Builder<'a>,
2039-
Dst: &'a Value,
2040-
DstAlign: c_uint,
2041-
Val: &'a Value,
2042-
Size: &'a Value,
2043-
IsVolatile: bool,
2044-
) -> &'a Value;
2045-
20462044
pub(crate) fn LLVMRustBuildVectorReduceFAdd<'a>(
20472045
B: &Builder<'a>,
20482046
Acc: &'a Value,

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,33 +1378,6 @@ LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef, RustStringRef MessageOut,
13781378
return true;
13791379
}
13801380

1381-
extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst,
1382-
unsigned DstAlign, LLVMValueRef Src,
1383-
unsigned SrcAlign,
1384-
LLVMValueRef Size,
1385-
bool IsVolatile) {
1386-
return wrap(unwrap(B)->CreateMemCpy(unwrap(Dst), MaybeAlign(DstAlign),
1387-
unwrap(Src), MaybeAlign(SrcAlign),
1388-
unwrap(Size), IsVolatile));
1389-
}
1390-
1391-
extern "C" LLVMValueRef
1392-
LLVMRustBuildMemMove(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
1393-
LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size,
1394-
bool IsVolatile) {
1395-
return wrap(unwrap(B)->CreateMemMove(unwrap(Dst), MaybeAlign(DstAlign),
1396-
unwrap(Src), MaybeAlign(SrcAlign),
1397-
unwrap(Size), IsVolatile));
1398-
}
1399-
1400-
extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B, LLVMValueRef Dst,
1401-
unsigned DstAlign, LLVMValueRef Val,
1402-
LLVMValueRef Size,
1403-
bool IsVolatile) {
1404-
return wrap(unwrap(B)->CreateMemSet(unwrap(Dst), unwrap(Val), unwrap(Size),
1405-
MaybeAlign(DstAlign), IsVolatile));
1406-
}
1407-
14081381
extern "C" void LLVMRustPositionBuilderPastAllocas(LLVMBuilderRef B,
14091382
LLVMValueRef Fn) {
14101383
Function *F = unwrap<Function>(Fn);

0 commit comments

Comments
 (0)