Skip to content

Commit ab58233

Browse files
committed
Move scalar_to_backend to ssa
1 parent 4530eac commit ab58233

14 files changed

Lines changed: 220 additions & 239 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3770,7 +3770,6 @@ dependencies = [
37703770
"rustc_data_structures",
37713771
"rustc_errors",
37723772
"rustc_fs_util",
3773-
"rustc_hashes",
37743773
"rustc_hir",
37753774
"rustc_index",
37763775
"rustc_llvm",

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 26 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use gccjit::{LValue, RValue, ToRValue, Type};
2-
use rustc_abi::Primitive::Pointer;
3-
use rustc_abi::{self as abi, HasDataLayout};
2+
use rustc_abi as abi;
3+
use rustc_abi::HasDataLayout;
44
use rustc_codegen_ssa::traits::{
5-
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
5+
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods as _,
66
};
7-
use rustc_middle::mir::Mutability;
8-
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
7+
use rustc_middle::mir::interpret::ConstAllocation;
98
use rustc_middle::ty::layout::LayoutOf;
109

1110
use crate::consts::const_alloc_to_gcc;
@@ -114,7 +113,7 @@ pub fn type_is_pointer(typ: Type<'_>) -> bool {
114113
typ.get_pointee().is_some()
115114
}
116115

117-
impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
116+
impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
118117
fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> {
119118
if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) }
120119
}
@@ -229,99 +228,32 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
229228
None
230229
}
231230

232-
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) -> RValue<'gcc> {
233-
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
234-
match cv {
235-
Scalar::Int(int) => {
236-
let data = int.to_bits(layout.size(self));
237-
let value = self.const_uint_big(self.type_ix(bitsize), data);
238-
let bytesize = layout.size(self).bytes();
239-
if bitsize > 1 && ty.is_integral() && bytesize as u32 == ty.get_size() {
240-
// NOTE: since the intrinsic _xabort is called with a bitcast, which
241-
// is non-const, but expects a constant, do a normal cast instead of a bitcast.
242-
// FIXME(antoyo): fix bitcast to work in constant contexts.
243-
// FIXME(antoyo): perhaps only use bitcast for pointers?
244-
self.context.new_cast(None, value, ty)
245-
} else {
246-
// FIXME(bjorn3): assert size is correct
247-
self.const_bitcast(value, ty)
248-
}
249-
}
250-
Scalar::Ptr(ptr, _size) => {
251-
let (prov, offset) = ptr.prov_and_relative_offset();
252-
let alloc_id = prov.alloc_id();
253-
let base_addr = match self.tcx.global_alloc(alloc_id) {
254-
GlobalAlloc::Memory(alloc) => {
255-
// For ZSTs directly codegen an aligned pointer.
256-
// This avoids generating a zero-sized constant value and actually needing a
257-
// real address at runtime.
258-
if alloc.inner().len() == 0 {
259-
let val = alloc.inner().align.bytes().wrapping_add(offset.bytes());
260-
let val = self.const_usize(self.tcx.truncate_to_target_usize(val));
261-
return if matches!(layout.primitive(), Pointer(_)) {
262-
self.context.new_cast(None, val, ty)
263-
} else {
264-
self.const_bitcast(val, ty)
265-
};
266-
}
267-
268-
let value = match alloc.inner().mutability {
269-
Mutability::Mut => self.static_addr_of_mut(
270-
const_alloc_to_gcc(self, alloc),
271-
alloc.inner().align,
272-
None,
273-
),
274-
_ => self.static_addr_of(alloc, None),
275-
};
276-
if !self.sess().fewer_names() {
277-
// FIXME(antoyo): set value name.
278-
}
279-
value
280-
}
281-
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance),
282-
GlobalAlloc::VTable(ty, dyn_ty) => {
283-
let alloc = self
284-
.tcx
285-
.global_alloc(self.tcx.vtable_allocation((
286-
ty,
287-
dyn_ty.principal().map(|principal| {
288-
self.tcx.instantiate_bound_regions_with_erased(principal)
289-
}),
290-
)))
291-
.unwrap_memory();
292-
self.static_addr_of(alloc, None)
293-
}
294-
GlobalAlloc::TypeId { .. } => {
295-
let val = self.const_usize(offset.bytes());
296-
// This is still a variable of pointer type, even though we only use the provenance
297-
// of that pointer in CTFE and Miri. But to make LLVM's type system happy,
298-
// we need an int-to-ptr cast here (it doesn't matter at all which provenance that picks).
299-
return self.context.new_cast(None, val, ty);
300-
}
301-
GlobalAlloc::Static(def_id) => {
302-
assert!(self.tcx.is_static(def_id));
303-
self.get_static(def_id).get_address(None)
304-
}
305-
};
306-
let ptr_type = base_addr.get_type();
307-
let base_addr = self.context.new_cast(None, base_addr, self.usize_type);
308-
let offset =
309-
self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
310-
let ptr = self.context.new_cast(None, base_addr + offset, ptr_type);
311-
if !matches!(layout.primitive(), Pointer(_)) {
312-
self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
313-
} else {
314-
self.context.new_cast(None, ptr, ty)
315-
}
316-
}
317-
}
318-
}
319-
320231
fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
321232
self.context
322233
.new_array_access(None, base_addr, self.const_usize(offset.bytes()))
323234
.get_address(None)
324235
}
236+
fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
237+
self.const_bitcast(val, ty)
238+
}
239+
fn const_pointercast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
240+
self.context.new_cast(None, val, ty)
241+
}
242+
fn const_int_to_ptr(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
243+
self.context.new_cast(None, val, ty)
244+
}
245+
fn const_ptr_to_int(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
246+
self.context.new_cast(None, val, ty)
247+
}
248+
249+
fn static_addr_of_const(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
250+
self.static_addr_of(alloc, kind)
251+
}
252+
253+
fn static_addr_of_mut(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
254+
let cv = const_alloc_to_gcc(self, alloc);
255+
self.static_addr_of_mut(cv, alloc.inner().align, kind)
256+
}
325257
}
326258

327259
pub trait SignType<'gcc, 'tcx> {

compiler/rustc_codegen_gcc/src/consts.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,17 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
175175
self.add_used_global(global.to_rvalue());
176176
}
177177
}
178+
179+
fn get_value_name(&self, _val: Self::Value) -> Vec<u8> {
180+
// TODO(antoyo)
181+
vec![]
182+
}
183+
fn set_value_name(&self, _val: Self::Value, _name: &[u8]) {
184+
// TODO(antoyo)
185+
}
186+
fn get_static(&self, def_id: DefId) -> Self::Value {
187+
self.get_static(def_id).get_address(None)
188+
}
178189
}
179190

180191
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {

compiler/rustc_codegen_gcc/src/type_.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,6 @@ use crate::context::{CodegenCx, new_array_type};
1717
use crate::type_of::LayoutGccExt;
1818

1919
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
20-
pub fn type_ix(&self, num_bits: u64) -> Type<'gcc> {
21-
// gcc only supports 1, 2, 4 or 8-byte integers.
22-
// FIXME(antoyo): this is misleading to use the next power of two as rustc_codegen_ssa
23-
// sometimes use 96-bit numbers and the following code will give an integer of a different
24-
// size.
25-
let bytes = (num_bits / 8).next_power_of_two() as i32;
26-
match bytes {
27-
1 => self.i8_type,
28-
2 => self.i16_type,
29-
4 => self.i32_type,
30-
8 => self.i64_type,
31-
16 => self.i128_type,
32-
_ => panic!("unexpected num_bits: {}", num_bits),
33-
}
34-
}
35-
3620
pub fn type_void(&self) -> Type<'gcc> {
3721
self.context.new_type::<()>()
3822
}
@@ -148,6 +132,22 @@ impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> {
148132
self.isize_type
149133
}
150134

135+
fn type_ix(&self, num_bits: u64) -> Type<'gcc> {
136+
// gcc only supports 1, 2, 4 or 8-byte integers.
137+
// FIXME(antoyo): this is misleading to use the next power of two as rustc_codegen_ssa
138+
// sometimes use 96-bit numbers and the following code will give an integer of a different
139+
// size.
140+
let bytes = (num_bits / 8).next_power_of_two() as i32;
141+
match bytes {
142+
1 => self.i8_type,
143+
2 => self.i16_type,
144+
4 => self.i32_type,
145+
8 => self.i64_type,
146+
16 => self.i128_type,
147+
_ => panic!("unexpected num_bits: {}", num_bits),
148+
}
149+
}
150+
151151
fn type_f16(&self) -> Type<'gcc> {
152152
#[cfg(feature = "master")]
153153
if self.supports_f16_type {

compiler/rustc_codegen_llvm/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
2424
rustc_data_structures = { path = "../rustc_data_structures" }
2525
rustc_errors = { path = "../rustc_errors" }
2626
rustc_fs_util = { path = "../rustc_fs_util" }
27-
rustc_hashes = { path = "../rustc_hashes" }
2827
rustc_hir = { path = "../rustc_hir" }
2928
rustc_index = { path = "../rustc_index" }
3029
rustc_llvm = { path = "../rustc_llvm" }

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 27 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@
33
use std::borrow::Borrow;
44

55
use libc::{c_char, c_uint};
6-
use rustc_abi::Primitive::Pointer;
7-
use rustc_abi::{self as abi, HasDataLayout as _};
8-
use rustc_ast::Mutability;
6+
use rustc_abi as abi;
7+
use rustc_abi::HasDataLayout;
98
use rustc_codegen_ssa::common::TypeKind;
109
use rustc_codegen_ssa::traits::*;
11-
use rustc_data_structures::stable_hash::{StableHash, StableHasher};
12-
use rustc_hashes::Hash128;
1310
use rustc_hir::def_id::DefId;
1411
use rustc_middle::bug;
15-
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
12+
use rustc_middle::mir::interpret::ConstAllocation;
1613
use rustc_middle::ty::TyCtxt;
1714
use rustc_session::cstore::DllImport;
1815
use tracing::debug;
@@ -130,7 +127,7 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
130127
}
131128
}
132129

133-
impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
130+
impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
134131
fn const_null(&self, t: &'ll Type) -> &'ll Value {
135132
unsafe { llvm::LLVMConstNull(t) }
136133
}
@@ -268,101 +265,6 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
268265
})
269266
}
270267

271-
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: &'ll Type) -> &'ll Value {
272-
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
273-
match cv {
274-
Scalar::Int(int) => {
275-
let data = int.to_bits(layout.size(self));
276-
let llval = self.const_uint_big(self.type_ix(bitsize), data);
277-
if matches!(layout.primitive(), Pointer(_)) {
278-
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
279-
} else {
280-
self.const_bitcast(llval, llty)
281-
}
282-
}
283-
Scalar::Ptr(ptr, _size) => {
284-
let (prov, offset) = ptr.prov_and_relative_offset();
285-
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
286-
let base_addr = match global_alloc {
287-
GlobalAlloc::Memory(alloc) => {
288-
// For ZSTs directly codegen an aligned pointer.
289-
// This avoids generating a zero-sized constant value and actually needing a
290-
// real address at runtime.
291-
if alloc.inner().len() == 0 {
292-
let val = alloc.inner().align.bytes().wrapping_add(offset.bytes());
293-
let llval = self.const_usize(self.tcx.truncate_to_target_usize(val));
294-
return if matches!(layout.primitive(), Pointer(_)) {
295-
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
296-
} else {
297-
self.const_bitcast(llval, llty)
298-
};
299-
} else {
300-
let init =
301-
const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
302-
let alloc = alloc.inner();
303-
let value = match alloc.mutability {
304-
Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
305-
_ => self.static_addr_of_impl(init, alloc.align, None),
306-
};
307-
if !self.sess().fewer_names() && llvm::get_value_name(value).is_empty()
308-
{
309-
let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
310-
let mut hasher = StableHasher::new();
311-
alloc.stable_hash(&mut hcx, &mut hasher);
312-
hasher.finish::<Hash128>()
313-
});
314-
llvm::set_value_name(
315-
value,
316-
format!("alloc_{hash:032x}").as_bytes(),
317-
);
318-
}
319-
value
320-
}
321-
}
322-
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance),
323-
GlobalAlloc::VTable(ty, dyn_ty) => {
324-
let alloc = self
325-
.tcx
326-
.global_alloc(self.tcx.vtable_allocation((
327-
ty,
328-
dyn_ty.principal().map(|principal| {
329-
self.tcx.instantiate_bound_regions_with_erased(principal)
330-
}),
331-
)))
332-
.unwrap_memory();
333-
let init = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
334-
self.static_addr_of_impl(init, alloc.inner().align, None)
335-
}
336-
GlobalAlloc::Static(def_id) => {
337-
assert!(self.tcx.is_static(def_id));
338-
assert!(!self.tcx.is_thread_local_static(def_id));
339-
self.get_static(def_id)
340-
}
341-
GlobalAlloc::TypeId { .. } => {
342-
// Drop the provenance, the offset contains the bytes of the hash
343-
let llval = self.const_usize(offset.bytes());
344-
return unsafe { llvm::LLVMConstIntToPtr(llval, llty) };
345-
}
346-
};
347-
let base_addr_space = global_alloc.address_space(self);
348-
let llval = unsafe {
349-
llvm::LLVMConstInBoundsGEP2(
350-
self.type_i8(),
351-
// Cast to the required address space if necessary
352-
self.const_pointercast(base_addr, self.type_ptr_ext(base_addr_space)),
353-
&self.const_usize(offset.bytes()),
354-
1,
355-
)
356-
};
357-
if !matches!(layout.primitive(), Pointer(_)) {
358-
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
359-
} else {
360-
self.const_bitcast(llval, llty)
361-
}
362-
}
363-
}
364-
}
365-
366268
fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
367269
unsafe {
368270
llvm::LLVMConstInBoundsGEP2(
@@ -373,6 +275,29 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
373275
)
374276
}
375277
}
278+
279+
fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
280+
unsafe { llvm::LLVMConstBitCast(val, ty) }
281+
}
282+
fn const_pointercast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
283+
unsafe { llvm::LLVMConstPointerCast(val, ty) }
284+
}
285+
fn const_int_to_ptr(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
286+
unsafe { llvm::LLVMConstIntToPtr(val, ty) }
287+
}
288+
fn const_ptr_to_int(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
289+
unsafe { llvm::LLVMConstPtrToInt(val, ty) }
290+
}
291+
292+
fn static_addr_of_const(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
293+
let cv = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
294+
self.static_addr_of_const(cv, alloc.inner().align, kind)
295+
}
296+
297+
fn static_addr_of_mut(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> Self::Value {
298+
let cv = const_alloc_to_llvm(self, alloc.inner(), /*static*/ false);
299+
self.static_addr_of_mut(cv, alloc.inner().align, kind)
300+
}
376301
}
377302

378303
/// Get the [LLVM type][Type] of a [`Value`].

0 commit comments

Comments
 (0)