From a225f0a66b83b79e62d679568675adea284bfe21 Mon Sep 17 00:00:00 2001 From: yvt Date: Tue, 3 May 2022 13:53:10 +0900 Subject: [PATCH 1/2] Pass a pointee type to `::load` when calling it ourselves The parameter name isn't very descriptive, but it actually supposed to take a pointee type. When calling it ourselves, we've been passing a *pointer* type, which made it impossible to make any meaningful uses of this parameter in the method implementation. This commit intends to rectify that. --- src/builder.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 6f24abaea8ae..4cc5eef9dad4 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -652,7 +652,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { unimplemented!(); } - fn load(&mut self, _ty: Type<'gcc>, ptr: RValue<'gcc>, _align: Align) -> RValue<'gcc> { + fn load(&mut self, _pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, _align: Align) -> RValue<'gcc> { // TODO(antoyo): use ty. let block = self.llbb(); let function = block.get_function(); @@ -715,7 +715,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { OperandValue::Ref(place.llval, Some(llextra), place.align) } else if place.layout.is_gcc_immediate() { - let load = self.load(place.llval.get_type(), place.llval, place.align); + let load = self.load( + place.layout.gcc_type(self, false), + place.llval, + place.align, + ); if let abi::Abi::Scalar(ref scalar) = place.layout.abi { scalar_load_metadata(self, load, scalar); } @@ -727,7 +731,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let mut load = |i, scalar: &abi::Scalar, align| { let llptr = self.struct_gep(pair_type, place.llval, i as u64); - let load = self.load(llptr.get_type(), llptr, align); + let llty = place.layout.scalar_pair_element_gcc_type(self, i, false); + let load = self.load(llty, llptr, align); scalar_load_metadata(self, load, scalar); if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load } }; @@ -980,7 +985,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn memmove(&mut self, dst: RValue<'gcc>, dst_align: Align, src: RValue<'gcc>, src_align: Align, size: RValue<'gcc>, flags: MemFlags) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memmove. - let val = self.load(src.get_type(), src, src_align); + let val = self.load(src.get_type().get_pointee().expect("get_pointee"), src, src_align); let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val))); self.store_with_flags(val, ptr, dst_align, flags); return; From 351c68367425c4e292394ae5c7137b6e45de0916 Mon Sep 17 00:00:00 2001 From: yvt Date: Mon, 2 May 2022 11:00:07 +0900 Subject: [PATCH 2/2] Use the given pointee type in `::load` This commit updates this method implementation to return an `RValue` of the given pointee type. While this parameter does not seem to have much significance at the moment, it will likely become important as cg_llvm and cg_ssa migrate to LLVM opaque pointers and get rid of pointercasts. --- src/builder.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 4cc5eef9dad4..9a5cf785a1f5 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -652,18 +652,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { unimplemented!(); } - fn load(&mut self, _pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, _align: Align) -> RValue<'gcc> { - // TODO(antoyo): use ty. + fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, _align: Align) -> RValue<'gcc> { let block = self.llbb(); let function = block.get_function(); // NOTE: instead of returning the dereference here, we have to assign it to a variable in // the current basic block. Otherwise, it could be used in another basic block, causing a // dereference after a drop, for instance. // TODO(antoyo): handle align of the load instruction. + let ptr = self.context.new_cast(None, ptr, pointee_ty.make_pointer()); let deref = ptr.dereference(None).to_rvalue(); - let value_type = deref.get_type(); unsafe { RETURN_VALUE_COUNT += 1 }; - let loaded_value = function.new_local(None, value_type, &format!("loadedValue{}", unsafe { RETURN_VALUE_COUNT })); + let loaded_value = function.new_local(None, pointee_ty, &format!("loadedValue{}", unsafe { RETURN_VALUE_COUNT })); block.add_assignment(None, loaded_value, deref); loaded_value.to_rvalue() }