Skip to content

Commit 9df01d8

Browse files
committed
Move scalar_to_backend to ssa
1 parent f191420 commit 9df01d8

File tree

14 files changed

+219
-222
lines changed

14 files changed

+219
-222
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3512,7 +3512,6 @@ dependencies = [
35123512
"rustc_errors",
35133513
"rustc_fluent_macro",
35143514
"rustc_fs_util",
3515-
"rustc_hashes",
35163515
"rustc_hir",
35173516
"rustc_index",
35183517
"rustc_llvm",

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 29 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
use gccjit::{LValue, RValue, ToRValue, Type};
22
use rustc_abi as abi;
3-
use rustc_abi::HasDataLayout;
4-
use rustc_abi::Primitive::Pointer;
3+
use rustc_abi::{Align, HasDataLayout};
54
use rustc_codegen_ssa::traits::{
6-
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
5+
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
76
};
8-
use rustc_middle::mir::Mutability;
9-
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
7+
use rustc_middle::mir::interpret::ConstAllocation;
108
use rustc_middle::ty::layout::LayoutOf;
119

1210
use crate::context::CodegenCx;
@@ -110,7 +108,7 @@ pub fn type_is_pointer(typ: Type<'_>) -> bool {
110108
typ.get_pointee().is_some()
111109
}
112110

113-
impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
111+
impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
114112
fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> {
115113
if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) }
116114
}
@@ -229,86 +227,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
229227
None
230228
}
231229

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-
// TODO(antoyo): perhaps only use bitcast for pointers?
244-
self.context.new_cast(None, value, ty)
245-
} else {
246-
// TODO(bjorn3): assert size is correct
247-
self.const_bitcast(value, ty)
248-
}
249-
}
250-
Scalar::Ptr(ptr, _size) => {
251-
let (prov, offset) = ptr.into_parts(); // we know the `offset` is relative
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-
assert_eq!(offset.bytes(), 0);
260-
let val = self.const_usize(alloc.inner().align.bytes());
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 init = self.const_data_from_alloc(alloc);
269-
let alloc = alloc.inner();
270-
let value = match alloc.mutability {
271-
Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
272-
_ => self.static_addr_of(init, alloc.align, None),
273-
};
274-
if !self.sess().fewer_names() {
275-
// TODO(antoyo): set value name.
276-
}
277-
value
278-
}
279-
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance),
280-
GlobalAlloc::VTable(ty, dyn_ty) => {
281-
let alloc = self
282-
.tcx
283-
.global_alloc(self.tcx.vtable_allocation((
284-
ty,
285-
dyn_ty.principal().map(|principal| {
286-
self.tcx.instantiate_bound_regions_with_erased(principal)
287-
}),
288-
)))
289-
.unwrap_memory();
290-
let init = self.const_data_from_alloc(alloc);
291-
self.static_addr_of(init, alloc.inner().align, None)
292-
}
293-
GlobalAlloc::Static(def_id) => {
294-
assert!(self.tcx.is_static(def_id));
295-
self.get_static(def_id).get_address(None)
296-
}
297-
};
298-
let ptr_type = base_addr.get_type();
299-
let base_addr = self.context.new_cast(None, base_addr, self.usize_type);
300-
let offset =
301-
self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
302-
let ptr = self.context.new_cast(None, base_addr + offset, ptr_type);
303-
if !matches!(layout.primitive(), Pointer(_)) {
304-
self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
305-
} else {
306-
self.context.new_cast(None, ptr, ty)
307-
}
308-
}
309-
}
310-
}
311-
312230
fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value {
313231
// We ignore the alignment for the purpose of deduping RValues
314232
// The alignment is not handled / used in any way by `const_alloc_to_gcc`,
@@ -330,6 +248,31 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
330248
.new_array_access(None, base_addr, self.const_usize(offset.bytes()))
331249
.get_address(None)
332250
}
251+
fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
252+
self.const_bitcast(val, ty)
253+
}
254+
fn const_pointercast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
255+
self.context.new_cast(None, val, ty)
256+
}
257+
fn const_int_to_ptr(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
258+
self.context.new_cast(None, val, ty)
259+
}
260+
fn const_ptr_to_int(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
261+
self.context.new_cast(None, val, ty)
262+
}
263+
264+
fn static_addr_of_impl(
265+
&self,
266+
cv: Self::Value,
267+
align: Align,
268+
kind: Option<&str>,
269+
) -> Self::Value {
270+
self.static_addr_of(cv, align, kind)
271+
}
272+
273+
fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value {
274+
self.static_addr_of_mut(cv, align, kind)
275+
}
333276
}
334277

335278
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
@@ -150,6 +150,17 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
150150
self.add_used_global(global.to_rvalue());
151151
}
152152
}
153+
154+
fn get_value_name(&self, _val: Self::Value) -> &[u8] {
155+
// TODO(antoyo)
156+
&[]
157+
}
158+
fn set_value_name(&self, _val: Self::Value, _name: &[u8]) {
159+
// TODO(antoyo)
160+
}
161+
fn get_static(&self, def_id: DefId) -> Self::Value {
162+
self.get_static(def_id).get_address(None)
163+
}
153164
}
154165

155166
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;
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
@@ -25,7 +25,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
2525
rustc_errors = { path = "../rustc_errors" }
2626
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
2727
rustc_fs_util = { path = "../rustc_fs_util" }
28-
rustc_hashes = { path = "../rustc_hashes" }
2928
rustc_hir = { path = "../rustc_hir" }
3029
rustc_index = { path = "../rustc_index" }
3130
rustc_llvm = { path = "../rustc_llvm" }

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 29 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@ use std::borrow::Borrow;
44

55
use libc::{c_char, c_uint};
66
use rustc_abi as abi;
7-
use rustc_abi::HasDataLayout;
8-
use rustc_abi::Primitive::Pointer;
9-
use rustc_ast::Mutability;
7+
use rustc_abi::{Align, HasDataLayout};
108
use rustc_codegen_ssa::common::TypeKind;
119
use rustc_codegen_ssa::traits::*;
12-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
13-
use rustc_hashes::Hash128;
1410
use rustc_hir::def_id::DefId;
1511
use rustc_middle::bug;
16-
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
12+
use rustc_middle::mir::interpret::ConstAllocation;
1713
use rustc_middle::ty::TyCtxt;
1814
use rustc_session::cstore::DllImport;
1915
use tracing::debug;
@@ -121,7 +117,7 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
121117
}
122118
}
123119

124-
impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
120+
impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
125121
fn const_null(&self, t: &'ll Type) -> &'ll Value {
126122
unsafe { llvm::LLVMConstNull(t) }
127123
}
@@ -255,96 +251,6 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
255251
})
256252
}
257253

258-
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: &'ll Type) -> &'ll Value {
259-
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
260-
match cv {
261-
Scalar::Int(int) => {
262-
let data = int.to_bits(layout.size(self));
263-
let llval = self.const_uint_big(self.type_ix(bitsize), data);
264-
if matches!(layout.primitive(), Pointer(_)) {
265-
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
266-
} else {
267-
self.const_bitcast(llval, llty)
268-
}
269-
}
270-
Scalar::Ptr(ptr, _size) => {
271-
let (prov, offset) = ptr.into_parts();
272-
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
273-
let base_addr = match global_alloc {
274-
GlobalAlloc::Memory(alloc) => {
275-
// For ZSTs directly codegen an aligned pointer.
276-
// This avoids generating a zero-sized constant value and actually needing a
277-
// real address at runtime.
278-
if alloc.inner().len() == 0 {
279-
assert_eq!(offset.bytes(), 0);
280-
let llval = self.const_usize(alloc.inner().align.bytes());
281-
return if matches!(layout.primitive(), Pointer(_)) {
282-
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
283-
} else {
284-
self.const_bitcast(llval, llty)
285-
};
286-
} else {
287-
let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
288-
let alloc = alloc.inner();
289-
let value = match alloc.mutability {
290-
Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
291-
_ => self.static_addr_of_impl(init, alloc.align, None),
292-
};
293-
if !self.sess().fewer_names() && llvm::get_value_name(value).is_empty()
294-
{
295-
let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
296-
let mut hasher = StableHasher::new();
297-
alloc.hash_stable(&mut hcx, &mut hasher);
298-
hasher.finish::<Hash128>()
299-
});
300-
llvm::set_value_name(
301-
value,
302-
format!("alloc_{hash:032x}").as_bytes(),
303-
);
304-
}
305-
value
306-
}
307-
}
308-
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance),
309-
GlobalAlloc::VTable(ty, dyn_ty) => {
310-
let alloc = self
311-
.tcx
312-
.global_alloc(self.tcx.vtable_allocation((
313-
ty,
314-
dyn_ty.principal().map(|principal| {
315-
self.tcx.instantiate_bound_regions_with_erased(principal)
316-
}),
317-
)))
318-
.unwrap_memory();
319-
let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
320-
let value = self.static_addr_of_impl(init, alloc.inner().align, None);
321-
value
322-
}
323-
GlobalAlloc::Static(def_id) => {
324-
assert!(self.tcx.is_static(def_id));
325-
assert!(!self.tcx.is_thread_local_static(def_id));
326-
self.get_static(def_id)
327-
}
328-
};
329-
let base_addr_space = global_alloc.address_space(self);
330-
let llval = unsafe {
331-
llvm::LLVMConstInBoundsGEP2(
332-
self.type_i8(),
333-
// Cast to the required address space if necessary
334-
self.const_pointercast(base_addr, self.type_ptr_ext(base_addr_space)),
335-
&self.const_usize(offset.bytes()),
336-
1,
337-
)
338-
};
339-
if !matches!(layout.primitive(), Pointer(_)) {
340-
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
341-
} else {
342-
self.const_bitcast(llval, llty)
343-
}
344-
}
345-
}
346-
}
347-
348254
fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value {
349255
const_alloc_to_llvm(self, alloc, /*static*/ false)
350256
}
@@ -359,6 +265,32 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
359265
)
360266
}
361267
}
268+
269+
fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
270+
unsafe { llvm::LLVMConstBitCast(val, ty) }
271+
}
272+
fn const_pointercast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
273+
unsafe { llvm::LLVMConstPointerCast(val, ty) }
274+
}
275+
fn const_int_to_ptr(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
276+
unsafe { llvm::LLVMConstIntToPtr(val, ty) }
277+
}
278+
fn const_ptr_to_int(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
279+
unsafe { llvm::LLVMConstPtrToInt(val, ty) }
280+
}
281+
282+
fn static_addr_of_impl(
283+
&self,
284+
cv: Self::Value,
285+
align: Align,
286+
kind: Option<&str>,
287+
) -> Self::Value {
288+
self.static_addr_of_impl(cv, align, kind)
289+
}
290+
291+
fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value {
292+
self.static_addr_of_mut(cv, align, kind)
293+
}
362294
}
363295

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

0 commit comments

Comments
 (0)