Skip to content

Commit a5aeb8e

Browse files
denismerigouxeddyb
authored andcommitted
Transfered memcpy and memset to BuilderMethods
1 parent 3c082a2 commit a5aeb8e

File tree

8 files changed

+110
-99
lines changed

8 files changed

+110
-99
lines changed

src/librustc_codegen_llvm/abi.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// except according to those terms.
1010

1111
use llvm::{self, AttributePlace};
12-
use base;
1312
use builder::{Builder, MemFlags};
1413
use context::CodegenCx;
1514
use mir::place::PlaceRef;
@@ -239,13 +238,14 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
239238
bx.store(val, llscratch, scratch_align);
240239

241240
// ...and then memcpy it to the intended destination.
242-
base::call_memcpy(bx,
243-
bx.pointercast(dst.llval, cx.type_i8p()),
244-
self.layout.align,
245-
bx.pointercast(llscratch, cx.type_i8p()),
246-
scratch_align,
247-
cx.const_usize(self.layout.size.bytes()),
248-
MemFlags::empty());
241+
bx.memcpy(
242+
bx.pointercast(dst.llval, cx.type_i8p()),
243+
self.layout.align,
244+
bx.pointercast(llscratch, cx.type_i8p()),
245+
scratch_align,
246+
cx.const_usize(self.layout.size.bytes()),
247+
MemFlags::empty()
248+
);
249249

250250
bx.lifetime_end(llscratch, scratch_size);
251251
}

src/librustc_codegen_llvm/base.rs

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -433,30 +433,6 @@ pub fn to_immediate_scalar<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
433433
val
434434
}
435435

436-
pub fn call_memcpy<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
437-
bx: &Builder,
438-
dst: Builder::Value,
439-
dst_align: Align,
440-
src: Builder::Value,
441-
src_align: Align,
442-
n_bytes: Builder::Value,
443-
flags: MemFlags,
444-
) {
445-
if flags.contains(MemFlags::NONTEMPORAL) {
446-
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
447-
let val = bx.load(src, src_align);
448-
let ptr = bx.pointercast(dst, bx.cx().type_ptr_to(bx.cx().val_ty(val)));
449-
bx.store_with_flags(val, ptr, dst_align, flags);
450-
return;
451-
}
452-
let cx = bx.cx();
453-
let src_ptr = bx.pointercast(src, cx.type_i8p());
454-
let dst_ptr = bx.pointercast(dst, cx.type_i8p());
455-
let size = bx.intcast(n_bytes, cx.type_isize(), false);
456-
let volatile = flags.contains(MemFlags::VOLATILE);
457-
bx.memcpy(dst_ptr, dst_align.abi(), src_ptr, src_align.abi(), size, volatile);
458-
}
459-
460436
pub fn memcpy_ty<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
461437
bx: &Builder,
462438
dst: Builder::Value,
@@ -471,22 +447,7 @@ pub fn memcpy_ty<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
471447
return;
472448
}
473449

474-
call_memcpy(bx, dst, dst_align, src, src_align, bx.cx().const_usize(size), flags);
475-
}
476-
477-
pub fn call_memset<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
478-
bx: &Builder,
479-
ptr: Builder::Value,
480-
fill_byte: Builder::Value,
481-
size: Builder::Value,
482-
align: Builder::Value,
483-
volatile: bool,
484-
) -> Builder::Value {
485-
let ptr_width = &bx.sess().target.target.target_pointer_width;
486-
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
487-
let llintrinsicfn = bx.cx().get_intrinsic(&intrinsic_key);
488-
let volatile = bx.cx().const_bool(volatile);
489-
bx.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None)
450+
bx.memcpy(dst, dst_align, src, src_align, bx.cx().const_usize(size), flags);
490451
}
491452

492453
pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tcx>) {

src/librustc_codegen_llvm/builder.rs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -785,24 +785,63 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
785785
}
786786
}
787787

788-
fn memcpy(&self, dst: &'ll Value, dst_align: u64,
789-
src: &'ll Value, src_align: u64,
790-
size: &'ll Value, is_volatile: bool) -> &'ll Value {
788+
fn memcpy(&self, dst: &'ll Value, dst_align: Align,
789+
src: &'ll Value, src_align: Align,
790+
size: &'ll Value, flags: MemFlags) {
791+
if flags.contains(MemFlags::NONTEMPORAL) {
792+
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
793+
let val = self.load(src, src_align);
794+
let ptr = self.pointercast(dst, self.cx().type_ptr_to(self.cx().val_ty(val)));
795+
self.store_with_flags(val, ptr, dst_align, flags);
796+
return;
797+
}
798+
let size = self.intcast(size, self.cx().type_isize(), false);
799+
let is_volatile = flags.contains(MemFlags::VOLATILE);
800+
let dst = self.pointercast(dst, self.cx().type_i8p());
801+
let src = self.pointercast(src, self.cx().type_i8p());
791802
unsafe {
792-
llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align as c_uint,
793-
src, src_align as c_uint, size, is_volatile)
803+
llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.abi() as c_uint,
804+
src, src_align.abi() as c_uint, size, is_volatile);
794805
}
795806
}
796807

797-
fn memmove(&self, dst: &'ll Value, dst_align: u64,
798-
src: &'ll Value, src_align: u64,
799-
size: &'ll Value, is_volatile: bool) -> &'ll Value {
808+
fn memmove(&self, dst: &'ll Value, dst_align: Align,
809+
src: &'ll Value, src_align: Align,
810+
size: &'ll Value, flags: MemFlags) {
811+
if flags.contains(MemFlags::NONTEMPORAL) {
812+
// HACK(nox): This is inefficient but there is no nontemporal memmove.
813+
let val = self.load(src, src_align);
814+
let ptr = self.pointercast(dst, self.cx().type_ptr_to(self.cx().val_ty(val)));
815+
self.store_with_flags(val, ptr, dst_align, flags);
816+
return;
817+
}
818+
let size = self.intcast(size, self.cx().type_isize(), false);
819+
let is_volatile = flags.contains(MemFlags::VOLATILE);
820+
let dst = self.pointercast(dst, self.cx().type_i8p());
821+
let src = self.pointercast(src, self.cx().type_i8p());
800822
unsafe {
801-
llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align as c_uint,
802-
src, src_align as c_uint, size, is_volatile)
823+
llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.abi() as c_uint,
824+
src, src_align.abi() as c_uint, size, is_volatile);
803825
}
804826
}
805827

828+
fn memset(
829+
&self,
830+
ptr: &'ll Value,
831+
fill_byte: &'ll Value,
832+
size: &'ll Value,
833+
align: Align,
834+
flags: MemFlags,
835+
) {
836+
let ptr_width = &self.sess().target.target.target_pointer_width;
837+
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
838+
let llintrinsicfn = self.cx().get_intrinsic(&intrinsic_key);
839+
let ptr = self.pointercast(ptr, self.cx().type_i8p());
840+
let align = self.cx().const_u32(align.abi() as u32);
841+
let volatile = self.cx().const_bool(flags.contains(MemFlags::VOLATILE));
842+
self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None);
843+
}
844+
806845
fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
807846
self.count_insn("minnum");
808847
unsafe {

src/librustc_codegen_llvm/interfaces/builder.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,20 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: Backend {
170170
) -> Option<Self::Value>;
171171

172172

173-
fn memcpy(&self, dst: Self::Value, dst_align: u64,
174-
src: Self::Value, src_align: u64,
175-
size: Self::Value, is_volatile: bool) -> Self::Value;
176-
fn memmove(&self, dst: Self::Value, dst_align: u64,
177-
src: Self::Value, src_align: u64,
178-
size: Self::Value, is_volatile: bool) -> Self::Value;
173+
fn memcpy(&self, dst: Self::Value, dst_align: Align,
174+
src: Self::Value, src_align: Align,
175+
size: Self::Value, flags: MemFlags);
176+
fn memmove(&self, dst: Self::Value, dst_align: Align,
177+
src: Self::Value, src_align: Align,
178+
size: Self::Value, flags: MemFlags);
179+
fn memset(
180+
&self,
181+
ptr: Self::Value,
182+
fill_byte: Self::Value,
183+
size: Self::Value,
184+
align: Align,
185+
flags: MemFlags,
186+
);
179187

180188
fn minnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
181189
fn maxnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;

src/librustc_codegen_llvm/intrinsic.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc::ty::layout::LayoutOf;
2929
use rustc::hir;
3030
use syntax::ast;
3131
use syntax::symbol::Symbol;
32-
use builder::Builder;
32+
use builder::{Builder, MemFlags};
3333
use value::Value;
3434

3535
use interfaces::{
@@ -228,28 +228,34 @@ pub fn codegen_intrinsic_call(
228228

229229
"copy_nonoverlapping" => {
230230
copy_intrinsic(bx, false, false, substs.type_at(0),
231-
args[1].immediate(), args[0].immediate(), args[2].immediate())
231+
args[1].immediate(), args[0].immediate(), args[2].immediate());
232+
return;
232233
}
233234
"copy" => {
234235
copy_intrinsic(bx, true, false, substs.type_at(0),
235-
args[1].immediate(), args[0].immediate(), args[2].immediate())
236+
args[1].immediate(), args[0].immediate(), args[2].immediate());
237+
return;
236238
}
237239
"write_bytes" => {
238240
memset_intrinsic(bx, false, substs.type_at(0),
239-
args[0].immediate(), args[1].immediate(), args[2].immediate())
241+
args[0].immediate(), args[1].immediate(), args[2].immediate());
242+
return;
240243
}
241244

242245
"volatile_copy_nonoverlapping_memory" => {
243246
copy_intrinsic(bx, false, true, substs.type_at(0),
244-
args[0].immediate(), args[1].immediate(), args[2].immediate())
247+
args[0].immediate(), args[1].immediate(), args[2].immediate());
248+
return;
245249
}
246250
"volatile_copy_memory" => {
247251
copy_intrinsic(bx, true, true, substs.type_at(0),
248-
args[0].immediate(), args[1].immediate(), args[2].immediate())
252+
args[0].immediate(), args[1].immediate(), args[2].immediate());
253+
return;
249254
}
250255
"volatile_set_memory" => {
251256
memset_intrinsic(bx, true, substs.type_at(0),
252-
args[0].immediate(), args[1].immediate(), args[2].immediate())
257+
args[0].immediate(), args[1].immediate(), args[2].immediate());
258+
return;
253259
}
254260
"volatile_load" | "unaligned_volatile_load" => {
255261
let tp_ty = substs.type_at(0);
@@ -725,17 +731,18 @@ fn copy_intrinsic(
725731
dst: &'ll Value,
726732
src: &'ll Value,
727733
count: &'ll Value,
728-
) -> &'ll Value {
729-
let cx = bx.cx();
730-
let (size, align) = cx.size_and_align_of(ty);
731-
let size = cx.const_usize(size.bytes());
732-
let align = align.abi();
733-
let dst_ptr = bx.pointercast(dst, cx.type_i8p());
734-
let src_ptr = bx.pointercast(src, cx.type_i8p());
734+
) {
735+
let (size, align) = bx.cx().size_and_align_of(ty);
736+
let size = bx.mul(bx.cx().const_usize(size.bytes()), count);
737+
let flags = if volatile {
738+
MemFlags::VOLATILE
739+
} else {
740+
MemFlags::empty()
741+
};
735742
if allow_overlap {
736-
bx.memmove(dst_ptr, align, src_ptr, align, bx.mul(size, count), volatile)
743+
bx.memmove(dst, align, src, align, size, flags);
737744
} else {
738-
bx.memcpy(dst_ptr, align, src_ptr, align, bx.mul(size, count), volatile)
745+
bx.memcpy(dst, align, src, align, size, flags);
739746
}
740747
}
741748

@@ -746,13 +753,15 @@ fn memset_intrinsic(
746753
dst: &'ll Value,
747754
val: &'ll Value,
748755
count: &'ll Value
749-
) -> &'ll Value {
750-
let cx = bx.cx();
751-
let (size, align) = cx.size_and_align_of(ty);
752-
let size = cx.const_usize(size.bytes());
753-
let align = cx.const_i32(align.abi() as i32);
754-
let dst = bx.pointercast(dst, cx.type_i8p());
755-
call_memset(bx, dst, val, bx.mul(size, count), align, volatile)
756+
) {
757+
let (size, align) = bx.cx().size_and_align_of(ty);
758+
let size = bx.cx().const_usize(size.bytes());
759+
let flags = if volatile {
760+
MemFlags::VOLATILE
761+
} else {
762+
MemFlags::empty()
763+
};
764+
bx.memset(dst, val, bx.mul(size, count), align, flags);
756765
}
757766

758767
fn try_intrinsic(

src/librustc_codegen_llvm/mir/operand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ impl OperandValue<&'ll Value> {
349349
// Allocate an appropriate region on the stack, and copy the value into it
350350
let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
351351
let lldst = bx.array_alloca(bx.cx().type_i8(), llsize, "unsized_tmp", max_align);
352-
base::call_memcpy(bx, lldst, max_align, llptr, min_align, llsize, flags);
352+
bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags);
353353

354354
// Store the allocated region and the extra to the indirect place.
355355
let indirect_operand = OperandValue::Pair(lldst, llextra);

src/librustc_codegen_llvm/mir/place.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size, VariantIdx};
1414
use rustc::mir;
1515
use rustc::mir::tcx::PlaceTy;
1616
use base;
17-
use builder::Builder;
17+
use builder::{Builder, MemFlags};
1818
use common::{CodegenCx, IntPredicate};
1919
use type_of::LayoutLlvmExt;
2020
use value::Value;
@@ -381,15 +381,10 @@ impl PlaceRef<'tcx, &'ll Value> {
381381
bx.sess().target.target.arch == "aarch64" {
382382
// Issue #34427: As workaround for LLVM bug on ARM,
383383
// use memset of 0 before assigning niche value.
384-
let llptr = bx.pointercast(
385-
self.llval,
386-
bx.cx().type_ptr_to(bx.cx().type_i8())
387-
);
388384
let fill_byte = bx.cx().const_u8(0);
389385
let (size, align) = self.layout.size_and_align();
390386
let size = bx.cx().const_usize(size.bytes());
391-
let align = bx.cx().const_u32(align.abi() as u32);
392-
base::call_memset(bx, llptr, fill_byte, size, align, false);
387+
bx.memset(self.llval, fill_byte, size, align, MemFlags::empty());
393388
}
394389

395390
let niche = self.project_field(bx, 0);

src/librustc_codegen_llvm/mir/rvalue.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_apfloat::{ieee, Float, Status, Round};
1717
use std::{u128, i128};
1818

1919
use base;
20-
use builder::Builder;
20+
use builder::{Builder, MemFlags};
2121
use callee;
2222
use common::{self, IntPredicate, RealPredicate};
2323
use monomorphize;
@@ -104,20 +104,19 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
104104
let start = dest.project_index(&bx, bx.cx().const_usize(0)).llval;
105105

106106
if let OperandValue::Immediate(v) = cg_elem.val {
107-
let align = bx.cx().const_i32(dest.align.abi() as i32);
108107
let size = bx.cx().const_usize(dest.layout.size.bytes());
109108

110109
// Use llvm.memset.p0i8.* to initialize all zero arrays
111110
if bx.cx().is_const_integral(v) && bx.cx().const_to_uint(v) == 0 {
112111
let fill = bx.cx().const_u8(0);
113-
base::call_memset(&bx, start, fill, size, align, false);
112+
bx.memset(start, fill, size, dest.align, MemFlags::empty());
114113
return bx;
115114
}
116115

117116
// Use llvm.memset.p0i8.* to initialize byte arrays
118117
let v = base::from_immediate(&bx, v);
119118
if bx.cx().val_ty(v) == bx.cx().type_i8() {
120-
base::call_memset(&bx, start, v, size, align, false);
119+
bx.memset(start, v, size, dest.align, MemFlags::empty());
121120
return bx;
122121
}
123122
}

0 commit comments

Comments
 (0)