Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Build StKind::CopyOverlapping
This replaces where it was previously being constructed in intrinsics, with direct construction
of the Statement.
  • Loading branch information
JulianKnodt committed Mar 9, 2021
commit d4ae9ff82664a1d7473e32d59819c208efce48c7
15 changes: 13 additions & 2 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,10 +837,21 @@ fn codegen_stmt<'tcx>(
dst,
count,
}) => {
let dst = codegen_operand(fx, dst).load_scalar(fx);
let dst = codegen_operand(fx, dst);
let pointee = dst
.layout()
.pointee_info_at(fx, rustc_target::abi::Size::ZERO)
.expect("Expected pointer");
let dst = dst.load_scalar(fx);
let src = codegen_operand(fx, src).load_scalar(fx);
let count = codegen_operand(fx, count).load_scalar(fx);
fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, count);
let elem_size: u64 = pointee.size.bytes();
let bytes = if elem_size != 1 {
fx.bcx.ins().imul_imm(count, elem_size as i64)
} else {
count
};
fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, bytes);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![feature(or_patterns)]
#![feature(associated_type_bounds)]
#![recursion_limit = "256"]
#![feature(box_syntax)]

//! This crate contains codegen code that is used by all codegen backends (LLVM and others).
//! The backend-agnostic functions of this crate use functions defined in various traits that
Expand Down
130 changes: 76 additions & 54 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,67 +641,89 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return;
}

if intrinsic.is_some() && intrinsic != Some(sym::drop_in_place) {
let intrinsic = intrinsic.unwrap();
let dest = match ret_dest {
_ if fn_abi.ret.is_indirect() => llargs[0],
ReturnDest::Nothing => {
bx.const_undef(bx.type_ptr_to(bx.arg_memory_ty(&fn_abi.ret)))
}
ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.llval,
ReturnDest::DirectOperand(_) => {
bug!("Cannot use direct operand with an intrinsic call")
}
};
match intrinsic {
None | Some(sym::drop_in_place) => {}
Some(sym::copy_nonoverlapping) => {
bx = self.codegen_statement(
bx,
&rustc_middle::mir::Statement {
source_info: rustc_middle::mir::SourceInfo::outermost(span),
kind: rustc_middle::mir::StatementKind::CopyNonOverlapping(
box rustc_middle::mir::CopyNonOverlapping {
src: args[0].clone(),
dst: args[1].clone(),
count: args[2].clone(),
},
),
},
);
helper.funclet_br(self, &mut bx, destination.unwrap().1);
return;
}
Some(intrinsic) => {
let dest = match ret_dest {
_ if fn_abi.ret.is_indirect() => llargs[0],
ReturnDest::Nothing => {
bx.const_undef(bx.type_ptr_to(bx.arg_memory_ty(&fn_abi.ret)))
}
ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.llval,
ReturnDest::DirectOperand(_) => {
bug!("Cannot use direct operand with an intrinsic call")
}
};

let args: Vec<_> = args
.iter()
.enumerate()
.map(|(i, arg)| {
// The indices passed to simd_shuffle* in the
// third argument must be constant. This is
// checked by const-qualification, which also
// promotes any complex rvalues to constants.
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
if let mir::Operand::Constant(constant) = arg {
let c = self.eval_mir_constant(constant);
let (llval, ty) = self.simd_shuffle_indices(
&bx,
constant.span,
constant.literal.ty,
c,
);
return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty) };
} else {
span_bug!(span, "shuffle indices must be constant");
let args: Vec<_> = args
.iter()
.enumerate()
.map(|(i, arg)| {
// The indices passed to simd_shuffle* in the
// third argument must be constant. This is
// checked by const-qualification, which also
// promotes any complex rvalues to constants.
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
if let mir::Operand::Constant(constant) = arg {
let c = self.eval_mir_constant(constant);
let (llval, ty) = self.simd_shuffle_indices(
&bx,
constant.span,
constant.literal.ty,
c,
);
return OperandRef {
val: Immediate(llval),
layout: bx.layout_of(ty),
};
} else {
span_bug!(span, "shuffle indices must be constant");
}
}
}

self.codegen_operand(&mut bx, arg)
})
.collect();
self.codegen_operand(&mut bx, arg)
})
.collect();

self.codegen_intrinsic_call(
&mut bx,
*instance.as_ref().unwrap(),
&fn_abi,
&args,
dest,
span,
);

Self::codegen_intrinsic_call(
&mut bx,
*instance.as_ref().unwrap(),
&fn_abi,
&args,
dest,
span,
);
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
self.store_return(&mut bx, ret_dest, &fn_abi.ret, dst.llval);
}

if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
self.store_return(&mut bx, ret_dest, &fn_abi.ret, dst.llval);
}
if let Some((_, target)) = *destination {
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
helper.funclet_br(self, &mut bx, target);
} else {
bx.unreachable();
}

if let Some((_, target)) = *destination {
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
helper.funclet_br(self, &mut bx, target);
} else {
bx.unreachable();
return;
}

return;
}

// Split the rust-call tupled arguments off.
Expand Down
13 changes: 3 additions & 10 deletions compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ fn memset_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn codegen_intrinsic_call(
&self,
bx: &mut Bx,
instance: ty::Instance<'tcx>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
Expand Down Expand Up @@ -127,16 +128,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}

sym::copy_nonoverlapping => {
copy_intrinsic(
bx,
false,
false,
substs.type_at(0),
args[1].immediate(),
args[0].immediate(),
args[2].immediate(),
);
return;
// handled explicitly in compiler/rustc_codegen_ssa/src/mir/block.rs
unreachable!();
}
sym::copy => {
copy_intrinsic(
Expand Down
14 changes: 5 additions & 9 deletions compiler/rustc_codegen_ssa/src/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,20 +123,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let dst_val = self.codegen_operand(&mut bx, dst);
let src_val = self.codegen_operand(&mut bx, src);
let count = self.codegen_operand(&mut bx, count).immediate();
let get_val_align = |oper_ref: crate::mir::OperandRef<'_, _>| match oper_ref.val {
OperandValue::Ref(val, _, align) => (val, align),
_ => unreachable!(),
};
let pointee_layout = dst_val
.layout
.pointee_info_at(&mut bx, rustc_target::abi::Size::ZERO)
.expect("Expected pointer");
let elem_size = bx.const_u64(pointee_layout.size.bytes());
let byte_count = bx.mul(count, elem_size);
let bytes = bx.mul(count, bx.const_usize(pointee_layout.size.bytes()));

let (dst, dst_align) = get_val_align(dst_val);
let (src, src_align) = get_val_align(src_val);
bx.memcpy(dst, dst_align, src, src_align, byte_count, crate::MemFlags::empty());
let align = pointee_layout.align;
let dst = dst_val.immediate();
let src = src_val.immediate();
bx.memcpy(dst, align, src, align, bytes, crate::MemFlags::empty());
bx
}
mir::StatementKind::FakeRead(..)
Expand Down