Skip to content

Commit 22867ea

Browse files
committed
Implement representation options to smir
1 parent 2fc3dee commit 22867ea

File tree

6 files changed

+147
-6
lines changed

6 files changed

+147
-6
lines changed

compiler/rustc_smir/src/rustc_smir/context.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_middle::ty::{
1616
};
1717
use rustc_middle::{mir, ty};
1818
use rustc_span::def_id::LOCAL_CRATE;
19-
use stable_mir::abi::{FnAbi, Layout, LayoutShape};
19+
use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions};
2020
use stable_mir::mir::alloc::GlobalAlloc;
2121
use stable_mir::mir::mono::{InstanceDef, StaticDef};
2222
use stable_mir::mir::{BinOp, Body, Place, UnOp};
@@ -397,6 +397,13 @@ impl<'tcx> SmirCtxt<'tcx> {
397397
tables.tcx.is_lang_item(def_id, LangItem::CStr)
398398
}
399399

400+
/// Returns the representation options for this ADT
401+
pub fn adt_repr(&self, def: AdtDef) -> ReprOptions {
402+
let mut tables = self.0.borrow_mut();
403+
let tcx = tables.tcx;
404+
def.internal(&mut *tables, tcx).repr().stable(&mut *tables)
405+
}
406+
400407
/// Retrieve the function signature for the given generic arguments.
401408
pub fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {
402409
let mut tables = self.0.borrow_mut();

compiler/rustc_smir/src/rustc_smir/convert/abi.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
use rustc_middle::ty;
66
use rustc_target::callconv::{self, Conv};
77
use stable_mir::abi::{
8-
AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, Layout,
9-
LayoutShape, PassMode, Primitive, Scalar, TagEncoding, TyAndLayout, ValueAbi, VariantsShape,
10-
WrappingRange,
8+
AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength,
9+
IntegerType, Layout, LayoutShape, PassMode, Primitive, ReprFlags, ReprOptions, Scalar,
10+
TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange,
1111
};
1212
use stable_mir::opaque;
1313
use stable_mir::target::MachineSize as Size;
@@ -303,3 +303,42 @@ impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
303303
WrappingRange { start: self.start, end: self.end }
304304
}
305305
}
306+
307+
impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
308+
type T = ReprFlags;
309+
310+
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
311+
ReprFlags {
312+
is_simd: self.intersects(Self::IS_SIMD),
313+
is_c: self.intersects(Self::IS_C),
314+
is_transparent: self.intersects(Self::IS_TRANSPARENT),
315+
is_linear: self.intersects(Self::IS_LINEAR),
316+
}
317+
}
318+
}
319+
320+
impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
321+
type T = IntegerType;
322+
323+
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
324+
match self {
325+
rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
326+
rustc_abi::IntegerType::Fixed(integer, signed) => {
327+
IntegerType::Fixed { length: integer.stable(tables), is_signed: *signed }
328+
}
329+
}
330+
}
331+
}
332+
333+
impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
334+
type T = ReprOptions;
335+
336+
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
337+
ReprOptions {
338+
int: self.int.map(|int| int.stable(tables)),
339+
align: self.align.map(|align| align.stable(tables)),
340+
pack: self.pack.map(|pack| pack.stable(tables)),
341+
flags: self.flags.stable(tables),
342+
}
343+
}
344+
}

compiler/rustc_smir/src/stable_mir/abi.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,3 +455,53 @@ pub enum CallConvention {
455455

456456
RiscvInterrupt,
457457
}
458+
459+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
460+
pub struct ReprFlags {
461+
pub(crate) is_simd: bool,
462+
pub(crate) is_c: bool,
463+
pub(crate) is_transparent: bool,
464+
pub(crate) is_linear: bool,
465+
}
466+
467+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
468+
pub enum IntegerType {
469+
/// Pointer-sized integer type, i.e. `isize` and `usize`.
470+
Pointer {
471+
/// Signedness. e.g. `true` for `isize`
472+
is_signed: bool,
473+
},
474+
/// Fixed-sized integer type, e.g. `i8`, `u32`, `i128`.
475+
Fixed {
476+
/// Length of this integer type. e.g. `IntegerLength::I8` for `u8`.
477+
length: IntegerLength,
478+
/// Signedness. e.g. `false` for `u8`
479+
is_signed: bool,
480+
},
481+
}
482+
483+
/// Represntation options provided by the user
484+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
485+
pub struct ReprOptions {
486+
pub(crate) int: Option<IntegerType>,
487+
pub(crate) align: Option<Align>,
488+
pub(crate) pack: Option<Align>,
489+
pub(crate) flags: ReprFlags,
490+
}
491+
492+
impl ReprOptions {
493+
#[inline]
494+
pub fn is_c(&self) -> bool {
495+
self.flags.is_c
496+
}
497+
498+
#[inline]
499+
pub fn is_simd(&self) -> bool {
500+
self.flags.is_simd
501+
}
502+
503+
#[inline]
504+
pub fn is_transparent(&self) -> bool {
505+
self.flags.is_transparent
506+
}
507+
}

compiler/rustc_smir/src/stable_mir/compiler_interface.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use std::cell::Cell;
77

88
use rustc_smir::context::SmirCtxt;
9-
use stable_mir::abi::{FnAbi, Layout, LayoutShape};
9+
use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions};
1010
use stable_mir::crate_def::Attribute;
1111
use stable_mir::mir::alloc::{AllocId, GlobalAlloc};
1212
use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef};
@@ -200,6 +200,11 @@ impl<'tcx> SmirInterface<'tcx> {
200200
self.cx.adt_is_cstr(def)
201201
}
202202

203+
/// Returns the representation options for this ADT
204+
pub(crate) fn adt_repr(&self, def: AdtDef) -> ReprOptions {
205+
self.cx.adt_repr(def)
206+
}
207+
203208
/// Retrieve the function signature for the given generic arguments.
204209
pub(crate) fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {
205210
self.cx.fn_sig(def, args)

compiler/rustc_smir/src/stable_mir/ty.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use stable_mir::mir::mono::StaticDef;
99
use stable_mir::target::MachineInfo;
1010
use stable_mir::{Filename, Opaque};
1111

12+
use super::abi::ReprOptions;
1213
use super::mir::{Body, Mutability, Safety};
1314
use super::{DefId, Error, Symbol, with};
1415
use crate::stable_mir;
@@ -818,6 +819,10 @@ impl AdtDef {
818819
pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
819820
(idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self })
820821
}
822+
823+
pub fn repr(&self) -> ReprOptions {
824+
with(|cx| cx.adt_repr(*self))
825+
}
821826
}
822827

823828
/// Definition of a variant, which can be either a struct / union field or an enum variant.

tests/ui-fulldeps/stable-mir/check_abi.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ use stable_mir::abi::{
2121
ArgAbi, CallConvention, FieldsShape, IntegerLength, PassMode, Primitive, Scalar, ValueAbi,
2222
VariantsShape,
2323
};
24+
use stable_mir::mir::MirVisitor;
2425
use stable_mir::mir::mono::Instance;
2526
use stable_mir::target::MachineInfo;
27+
use stable_mir::ty::{AdtDef, RigidTy, Ty, TyKind};
2628
use stable_mir::{CrateDef, CrateItem, CrateItems, ItemKind};
2729
use std::assert_matches::assert_matches;
30+
use std::collections::HashSet;
2831
use std::convert::TryFrom;
2932
use std::io::Write;
3033
use std::ops::ControlFlow;
@@ -67,6 +70,17 @@ fn test_stable_mir() -> ControlFlow<()> {
6770
assert!(ptr_variadic_fn_abi.c_variadic);
6871
assert_eq!(ptr_variadic_fn_abi.args.len(), 1);
6972

73+
let entry = stable_mir::entry_fn().unwrap();
74+
let main_fn = Instance::try_from(entry).unwrap();
75+
let mut visitor = AdtDefVisitor::default();
76+
visitor.visit_body(&main_fn.body().unwrap());
77+
let AdtDefVisitor { adt_defs } = visitor;
78+
assert_eq!(adt_defs.len(), 1);
79+
80+
// Test ADT representation options
81+
let repr_c_struct = adt_defs.iter().find(|def| def.trimmed_name() == "ReprCStruct").unwrap();
82+
assert!(repr_c_struct.repr().is_c());
83+
7084
ControlFlow::Continue(())
7185
}
7286

@@ -138,6 +152,20 @@ fn get_item<'a>(
138152
items.iter().find(|crate_item| (item.0 == crate_item.kind()) && crate_item.name() == item.1)
139153
}
140154

155+
#[derive(Default)]
156+
struct AdtDefVisitor {
157+
adt_defs: HashSet<AdtDef>,
158+
}
159+
160+
impl MirVisitor for AdtDefVisitor {
161+
fn visit_ty(&mut self, ty: &Ty, _location: stable_mir::mir::visit::Location) {
162+
if let TyKind::RigidTy(RigidTy::Adt(adt, _)) = ty.kind() {
163+
self.adt_defs.insert(adt);
164+
}
165+
self.super_ty(ty)
166+
}
167+
}
168+
141169
/// This test will generate and analyze a dummy crate using the stable mir.
142170
/// For that, it will first write the dummy crate into a file.
143171
/// Then it will create a `StableMir` using custom arguments and then
@@ -147,7 +175,7 @@ fn main() {
147175
generate_input(&path).unwrap();
148176
let args = &[
149177
"rustc".to_string(),
150-
"--crate-type=lib".to_string(),
178+
"-Cpanic=abort".to_string(),
151179
"--crate-name".to_string(),
152180
CRATE_NAME.to_string(),
153181
path.to_string(),
@@ -185,6 +213,13 @@ fn generate_input(path: &str) -> std::io::Result<()> {
185213
// We only care about the signature.
186214
todo!()
187215
}}
216+
217+
fn main() {{
218+
#[repr(C)]
219+
struct ReprCStruct;
220+
221+
let _s = ReprCStruct;
222+
}}
188223
"#
189224
)?;
190225
Ok(())

0 commit comments

Comments
 (0)