Skip to content

Commit b067154

Browse files
committed
Move scalar_to_backend to ssa
1 parent f51c987 commit b067154

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
@@ -3525,7 +3525,6 @@ dependencies = [
35253525
"rustc_errors",
35263526
"rustc_fluent_macro",
35273527
"rustc_fs_util",
3528-
"rustc_hashes",
35293528
"rustc_hir",
35303529
"rustc_index",
35313530
"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
}
@@ -221,86 +219,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
221219
None
222220
}
223221

224-
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) -> RValue<'gcc> {
225-
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
226-
match cv {
227-
Scalar::Int(int) => {
228-
let data = int.to_bits(layout.size(self));
229-
let value = self.const_uint_big(self.type_ix(bitsize), data);
230-
let bytesize = layout.size(self).bytes();
231-
if bitsize > 1 && ty.is_integral() && bytesize as u32 == ty.get_size() {
232-
// NOTE: since the intrinsic _xabort is called with a bitcast, which
233-
// is non-const, but expects a constant, do a normal cast instead of a bitcast.
234-
// FIXME(antoyo): fix bitcast to work in constant contexts.
235-
// TODO(antoyo): perhaps only use bitcast for pointers?
236-
self.context.new_cast(None, value, ty)
237-
} else {
238-
// TODO(bjorn3): assert size is correct
239-
self.const_bitcast(value, ty)
240-
}
241-
}
242-
Scalar::Ptr(ptr, _size) => {
243-
let (prov, offset) = ptr.prov_and_relative_offset();
244-
let alloc_id = prov.alloc_id();
245-
let base_addr = match self.tcx.global_alloc(alloc_id) {
246-
GlobalAlloc::Memory(alloc) => {
247-
// For ZSTs directly codegen an aligned pointer.
248-
// This avoids generating a zero-sized constant value and actually needing a
249-
// real address at runtime.
250-
if alloc.inner().len() == 0 {
251-
assert_eq!(offset.bytes(), 0);
252-
let val = self.const_usize(alloc.inner().align.bytes());
253-
return if matches!(layout.primitive(), Pointer(_)) {
254-
self.context.new_cast(None, val, ty)
255-
} else {
256-
self.const_bitcast(val, ty)
257-
};
258-
}
259-
260-
let init = self.const_data_from_alloc(alloc);
261-
let alloc = alloc.inner();
262-
let value = match alloc.mutability {
263-
Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
264-
_ => self.static_addr_of(init, alloc.align, None),
265-
};
266-
if !self.sess().fewer_names() {
267-
// TODO(antoyo): set value name.
268-
}
269-
value
270-
}
271-
GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance),
272-
GlobalAlloc::VTable(ty, dyn_ty) => {
273-
let alloc = self
274-
.tcx
275-
.global_alloc(self.tcx.vtable_allocation((
276-
ty,
277-
dyn_ty.principal().map(|principal| {
278-
self.tcx.instantiate_bound_regions_with_erased(principal)
279-
}),
280-
)))
281-
.unwrap_memory();
282-
let init = self.const_data_from_alloc(alloc);
283-
self.static_addr_of(init, alloc.inner().align, None)
284-
}
285-
GlobalAlloc::Static(def_id) => {
286-
assert!(self.tcx.is_static(def_id));
287-
self.get_static(def_id).get_address(None)
288-
}
289-
};
290-
let ptr_type = base_addr.get_type();
291-
let base_addr = self.context.new_cast(None, base_addr, self.usize_type);
292-
let offset =
293-
self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
294-
let ptr = self.context.new_cast(None, base_addr + offset, ptr_type);
295-
if !matches!(layout.primitive(), Pointer(_)) {
296-
self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
297-
} else {
298-
self.context.new_cast(None, ptr, ty)
299-
}
300-
}
301-
}
302-
}
303-
304222
fn const_data_from_alloc(&self, alloc: ConstAllocation<'_>) -> Self::Value {
305223
// We ignore the alignment for the purpose of deduping RValues
306224
// The alignment is not handled / used in any way by `const_alloc_to_gcc`,
@@ -322,6 +240,31 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
322240
.new_array_access(None, base_addr, self.const_usize(offset.bytes()))
323241
.get_address(None)
324242
}
243+
fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
244+
self.const_bitcast(val, ty)
245+
}
246+
fn const_pointercast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
247+
self.context.new_cast(None, val, ty)
248+
}
249+
fn const_int_to_ptr(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
250+
self.context.new_cast(None, val, ty)
251+
}
252+
fn const_ptr_to_int(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
253+
self.context.new_cast(None, val, ty)
254+
}
255+
256+
fn static_addr_of_impl(
257+
&self,
258+
cv: Self::Value,
259+
align: Align,
260+
kind: Option<&str>,
261+
) -> Self::Value {
262+
self.static_addr_of(cv, align, kind)
263+
}
264+
265+
fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value {
266+
self.static_addr_of_mut(cv, align, kind)
267+
}
325268
}
326269

327270
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.prov_and_relative_offset();
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)