Rollup merge of #123775 - scottmcm:place-val, r=cjgillot
Make `PlaceRef` and `OperandValue::Ref` share a common `PlaceValue` type Both `PlaceRef` and `OperandValue::Ref` need the triple of the backend pointer immediate, the optional backend metadata for DSTs, and the actual alignment of the place (since it can differ from the ABI alignment). This PR introduces a new `PlaceValue` type for those three values, leaving [`PlaceRef`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/place/struct.PlaceRef.html) with the `TyAndLayout` and a `PlaceValue`, just like how [`OperandRef`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/mir/operand/struct.OperandRef.html) is a `TyAndLayout` and an `OperandValue`. This means that various places that use `Ref`s as places can just pass the `PlaceValue` along, like in the below excerpt from the diff: ```diff match operand.val { - OperandValue::Ref(ptr, meta, align) => { - debug_assert_eq!(meta, None); + OperandValue::Ref(source_place_val) => { + debug_assert_eq!(source_place_val.llextra, None); debug_assert!(matches!(operand_kind, OperandValueKind::Ref)); - let fake_place = PlaceRef::new_sized_aligned(ptr, cast, align); + let fake_place = PlaceRef { val: source_place_val, layout: cast }; Some(bx.load_operand(fake_place).val) } ``` There's more refactoring that I'd like to do after this, but I wanted to stop the PR here where it's hopefully easy (albeit probably not quick) to review since I tried to keep every change line-by-line clear. (Most are just adding `.val` to get to a field.) You can also go commit-at-a-time if you'd like. Each passed tidy and the codegen tests on my machine (though I didn't run the cg_gcc ones).
This commit is contained in:
commit
f4f644182b
14 changed files with 239 additions and 169 deletions
|
@ -7,7 +7,7 @@ use crate::type_of::LayoutLlvmExt;
|
|||
use crate::value::Value;
|
||||
|
||||
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
use rustc_middle::bug;
|
||||
|
@ -207,7 +207,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
|||
// Sized indirect arguments
|
||||
PassMode::Indirect { attrs, meta_attrs: None, on_stack: _ } => {
|
||||
let align = attrs.pointee_align.unwrap_or(self.layout.align.abi);
|
||||
OperandValue::Ref(val, None, align).store(bx, dst);
|
||||
OperandValue::Ref(PlaceValue::new_sized(val, align)).store(bx, dst);
|
||||
}
|
||||
// Unsized indirect qrguments
|
||||
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
|
||||
|
@ -233,7 +233,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
|||
bx.store(val, llscratch, scratch_align);
|
||||
// ... and then memcpy it to the intended destination.
|
||||
bx.memcpy(
|
||||
dst.llval,
|
||||
dst.val.llval,
|
||||
self.layout.align.abi,
|
||||
llscratch,
|
||||
scratch_align,
|
||||
|
@ -265,7 +265,12 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
|
|||
OperandValue::Pair(next(), next()).store(bx, dst);
|
||||
}
|
||||
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
|
||||
OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst);
|
||||
let place_val = PlaceValue {
|
||||
llval: next(),
|
||||
llextra: Some(next()),
|
||||
align: self.layout.align.abi,
|
||||
};
|
||||
OperandValue::Ref(place_val).store(bx, dst);
|
||||
}
|
||||
PassMode::Direct(_)
|
||||
| PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ }
|
||||
|
|
|
@ -535,7 +535,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
panic!("unsized locals must not be `extern` types");
|
||||
}
|
||||
}
|
||||
assert_eq!(place.llextra.is_some(), place.layout.is_unsized());
|
||||
assert_eq!(place.val.llextra.is_some(), place.layout.is_unsized());
|
||||
|
||||
if place.layout.is_zst() {
|
||||
return OperandRef::zero_sized(place.layout);
|
||||
|
@ -579,13 +579,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let val = if let Some(llextra) = place.llextra {
|
||||
OperandValue::Ref(place.llval, Some(llextra), place.align)
|
||||
let val = if let Some(_) = place.val.llextra {
|
||||
// FIXME: Merge with the `else` below?
|
||||
OperandValue::Ref(place.val)
|
||||
} else if place.layout.is_llvm_immediate() {
|
||||
let mut const_llval = None;
|
||||
let llty = place.layout.llvm_type(self);
|
||||
unsafe {
|
||||
if let Some(global) = llvm::LLVMIsAGlobalVariable(place.llval) {
|
||||
if let Some(global) = llvm::LLVMIsAGlobalVariable(place.val.llval) {
|
||||
if llvm::LLVMIsGlobalConstant(global) == llvm::True {
|
||||
if let Some(init) = llvm::LLVMGetInitializer(global) {
|
||||
if self.val_ty(init) == llty {
|
||||
|
@ -596,7 +597,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
}
|
||||
}
|
||||
let llval = const_llval.unwrap_or_else(|| {
|
||||
let load = self.load(llty, place.llval, place.align);
|
||||
let load = self.load(llty, place.val.llval, place.val.align);
|
||||
if let abi::Abi::Scalar(scalar) = place.layout.abi {
|
||||
scalar_load_metadata(self, load, scalar, place.layout, Size::ZERO);
|
||||
}
|
||||
|
@ -608,9 +609,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
|
||||
let mut load = |i, scalar: abi::Scalar, layout, align, offset| {
|
||||
let llptr = if i == 0 {
|
||||
place.llval
|
||||
place.val.llval
|
||||
} else {
|
||||
self.inbounds_ptradd(place.llval, self.const_usize(b_offset.bytes()))
|
||||
self.inbounds_ptradd(place.val.llval, self.const_usize(b_offset.bytes()))
|
||||
};
|
||||
let llty = place.layout.scalar_pair_element_llvm_type(self, i, false);
|
||||
let load = self.load(llty, llptr, align);
|
||||
|
@ -619,11 +620,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
};
|
||||
|
||||
OperandValue::Pair(
|
||||
load(0, a, place.layout, place.align, Size::ZERO),
|
||||
load(1, b, place.layout, place.align.restrict_for_offset(b_offset), b_offset),
|
||||
load(0, a, place.layout, place.val.align, Size::ZERO),
|
||||
load(1, b, place.layout, place.val.align.restrict_for_offset(b_offset), b_offset),
|
||||
)
|
||||
} else {
|
||||
OperandValue::Ref(place.llval, None, place.align)
|
||||
OperandValue::Ref(place.val)
|
||||
};
|
||||
|
||||
OperandRef { val, layout: place.layout }
|
||||
|
|
|
@ -264,7 +264,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
llvm::LLVMSetAlignment(load, align);
|
||||
}
|
||||
if !result.layout.is_zst() {
|
||||
self.store(load, result.llval, result.align);
|
||||
self.store_to_place(load, result.val);
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
|
||||
sym::black_box => {
|
||||
args[0].val.store(self, result);
|
||||
let result_val_span = [result.llval];
|
||||
let result_val_span = [result.val.llval];
|
||||
// We need to "use" the argument in some way LLVM can't introspect, and on
|
||||
// targets that support it we can typically leverage inline assembly to do
|
||||
// this. LLVM's interpretation of inline assembly is that it's, well, a black
|
||||
|
@ -482,7 +482,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
if let PassMode::Cast { .. } = &fn_abi.ret.mode {
|
||||
self.store(llval, result.llval, result.align);
|
||||
self.store(llval, result.val.llval, result.val.align);
|
||||
} else {
|
||||
OperandRef::from_immediate_or_packed_pair(self, llval, result.layout)
|
||||
.val
|
||||
|
@ -1065,7 +1065,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
|||
let place = PlaceRef::alloca(bx, args[0].layout);
|
||||
args[0].val.store(bx, place);
|
||||
let int_ty = bx.type_ix(expected_bytes * 8);
|
||||
bx.load(int_ty, place.llval, Align::ONE)
|
||||
bx.load(int_ty, place.val.llval, Align::ONE)
|
||||
}
|
||||
_ => return_error!(InvalidMonomorphization::InvalidBitmask {
|
||||
span,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue