Skip to content

Commit d4ae9ff

Browse files
committed
Build StKind::CopyOverlapping
This replaces where it was previously being constructed in intrinsics, with direct construction of the Statement.
1 parent 845e4b5 commit d4ae9ff

File tree

5 files changed

+98
-75
lines changed

5 files changed

+98
-75
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -837,10 +837,21 @@ fn codegen_stmt<'tcx>(
837837
dst,
838838
count,
839839
}) => {
840-
let dst = codegen_operand(fx, dst).load_scalar(fx);
840+
let dst = codegen_operand(fx, dst);
841+
let pointee = dst
842+
.layout()
843+
.pointee_info_at(fx, rustc_target::abi::Size::ZERO)
844+
.expect("Expected pointer");
845+
let dst = dst.load_scalar(fx);
841846
let src = codegen_operand(fx, src).load_scalar(fx);
842847
let count = codegen_operand(fx, count).load_scalar(fx);
843-
fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, count);
848+
let elem_size: u64 = pointee.size.bytes();
849+
let bytes = if elem_size != 1 {
850+
fx.bcx.ins().imul_imm(count, elem_size as i64)
851+
} else {
852+
count
853+
};
854+
fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, bytes);
844855
}
845856
}
846857
}

compiler/rustc_codegen_ssa/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#![feature(or_patterns)]
1010
#![feature(associated_type_bounds)]
1111
#![recursion_limit = "256"]
12+
#![feature(box_syntax)]
1213

1314
//! This crate contains codegen code that is used by all codegen backends (LLVM and others).
1415
//! The backend-agnostic functions of this crate use functions defined in various traits that

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 76 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -641,67 +641,89 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
641641
return;
642642
}
643643

644-
if intrinsic.is_some() && intrinsic != Some(sym::drop_in_place) {
645-
let intrinsic = intrinsic.unwrap();
646-
let dest = match ret_dest {
647-
_ if fn_abi.ret.is_indirect() => llargs[0],
648-
ReturnDest::Nothing => {
649-
bx.const_undef(bx.type_ptr_to(bx.arg_memory_ty(&fn_abi.ret)))
650-
}
651-
ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.llval,
652-
ReturnDest::DirectOperand(_) => {
653-
bug!("Cannot use direct operand with an intrinsic call")
654-
}
655-
};
644+
match intrinsic {
645+
None | Some(sym::drop_in_place) => {}
646+
Some(sym::copy_nonoverlapping) => {
647+
bx = self.codegen_statement(
648+
bx,
649+
&rustc_middle::mir::Statement {
650+
source_info: rustc_middle::mir::SourceInfo::outermost(span),
651+
kind: rustc_middle::mir::StatementKind::CopyNonOverlapping(
652+
box rustc_middle::mir::CopyNonOverlapping {
653+
src: args[0].clone(),
654+
dst: args[1].clone(),
655+
count: args[2].clone(),
656+
},
657+
),
658+
},
659+
);
660+
helper.funclet_br(self, &mut bx, destination.unwrap().1);
661+
return;
662+
}
663+
Some(intrinsic) => {
664+
let dest = match ret_dest {
665+
_ if fn_abi.ret.is_indirect() => llargs[0],
666+
ReturnDest::Nothing => {
667+
bx.const_undef(bx.type_ptr_to(bx.arg_memory_ty(&fn_abi.ret)))
668+
}
669+
ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.llval,
670+
ReturnDest::DirectOperand(_) => {
671+
bug!("Cannot use direct operand with an intrinsic call")
672+
}
673+
};
656674

657-
let args: Vec<_> = args
658-
.iter()
659-
.enumerate()
660-
.map(|(i, arg)| {
661-
// The indices passed to simd_shuffle* in the
662-
// third argument must be constant. This is
663-
// checked by const-qualification, which also
664-
// promotes any complex rvalues to constants.
665-
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
666-
if let mir::Operand::Constant(constant) = arg {
667-
let c = self.eval_mir_constant(constant);
668-
let (llval, ty) = self.simd_shuffle_indices(
669-
&bx,
670-
constant.span,
671-
constant.literal.ty,
672-
c,
673-
);
674-
return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty) };
675-
} else {
676-
span_bug!(span, "shuffle indices must be constant");
675+
let args: Vec<_> = args
676+
.iter()
677+
.enumerate()
678+
.map(|(i, arg)| {
679+
// The indices passed to simd_shuffle* in the
680+
// third argument must be constant. This is
681+
// checked by const-qualification, which also
682+
// promotes any complex rvalues to constants.
683+
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
684+
if let mir::Operand::Constant(constant) = arg {
685+
let c = self.eval_mir_constant(constant);
686+
let (llval, ty) = self.simd_shuffle_indices(
687+
&bx,
688+
constant.span,
689+
constant.literal.ty,
690+
c,
691+
);
692+
return OperandRef {
693+
val: Immediate(llval),
694+
layout: bx.layout_of(ty),
695+
};
696+
} else {
697+
span_bug!(span, "shuffle indices must be constant");
698+
}
677699
}
678-
}
679700

680-
self.codegen_operand(&mut bx, arg)
681-
})
682-
.collect();
701+
self.codegen_operand(&mut bx, arg)
702+
})
703+
.collect();
704+
705+
self.codegen_intrinsic_call(
706+
&mut bx,
707+
*instance.as_ref().unwrap(),
708+
&fn_abi,
709+
&args,
710+
dest,
711+
span,
712+
);
683713

684-
Self::codegen_intrinsic_call(
685-
&mut bx,
686-
*instance.as_ref().unwrap(),
687-
&fn_abi,
688-
&args,
689-
dest,
690-
span,
691-
);
714+
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
715+
self.store_return(&mut bx, ret_dest, &fn_abi.ret, dst.llval);
716+
}
692717

693-
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
694-
self.store_return(&mut bx, ret_dest, &fn_abi.ret, dst.llval);
695-
}
718+
if let Some((_, target)) = *destination {
719+
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
720+
helper.funclet_br(self, &mut bx, target);
721+
} else {
722+
bx.unreachable();
723+
}
696724

697-
if let Some((_, target)) = *destination {
698-
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
699-
helper.funclet_br(self, &mut bx, target);
700-
} else {
701-
bx.unreachable();
725+
return;
702726
}
703-
704-
return;
705727
}
706728

707729
// Split the rust-call tupled arguments off.

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ fn memset_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
4949

5050
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
5151
pub fn codegen_intrinsic_call(
52+
&self,
5253
bx: &mut Bx,
5354
instance: ty::Instance<'tcx>,
5455
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
@@ -127,16 +128,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
127128
}
128129

129130
sym::copy_nonoverlapping => {
130-
copy_intrinsic(
131-
bx,
132-
false,
133-
false,
134-
substs.type_at(0),
135-
args[1].immediate(),
136-
args[0].immediate(),
137-
args[2].immediate(),
138-
);
139-
return;
131+
// handled explicitly in compiler/rustc_codegen_ssa/src/mir/block.rs
132+
unreachable!();
140133
}
141134
sym::copy => {
142135
copy_intrinsic(

compiler/rustc_codegen_ssa/src/mir/statement.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,20 +123,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
123123
let dst_val = self.codegen_operand(&mut bx, dst);
124124
let src_val = self.codegen_operand(&mut bx, src);
125125
let count = self.codegen_operand(&mut bx, count).immediate();
126-
let get_val_align = |oper_ref: crate::mir::OperandRef<'_, _>| match oper_ref.val {
127-
OperandValue::Ref(val, _, align) => (val, align),
128-
_ => unreachable!(),
129-
};
130126
let pointee_layout = dst_val
131127
.layout
132128
.pointee_info_at(&mut bx, rustc_target::abi::Size::ZERO)
133129
.expect("Expected pointer");
134-
let elem_size = bx.const_u64(pointee_layout.size.bytes());
135-
let byte_count = bx.mul(count, elem_size);
130+
let bytes = bx.mul(count, bx.const_usize(pointee_layout.size.bytes()));
136131

137-
let (dst, dst_align) = get_val_align(dst_val);
138-
let (src, src_align) = get_val_align(src_val);
139-
bx.memcpy(dst, dst_align, src, src_align, byte_count, crate::MemFlags::empty());
132+
let align = pointee_layout.align;
133+
let dst = dst_val.immediate();
134+
let src = src_val.immediate();
135+
bx.memcpy(dst, align, src, align, bytes, crate::MemFlags::empty());
140136
bx
141137
}
142138
mir::StatementKind::FakeRead(..)

0 commit comments

Comments
 (0)