Skip to content

Commit 5c5f0bb

Browse files
attr: parse rustc_scalable_vector(N)
Extend parsing of `ReprOptions` with `rustc_scalable_vector(N)` which optionally accepts a single literal integral value - the base multiple of lanes that are in a scalable vector. Can only be applied to structs. Co-authored-by: Jamie Cunliffe <Jamie.Cunliffe@arm.com>
1 parent d5525a7 commit 5c5f0bb

File tree

14 files changed

+593
-9
lines changed

14 files changed

+593
-9
lines changed

compiler/rustc_abi/src/lib.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ bitflags! {
9696
/// If true, the type is always passed indirectly by non-Rustic ABIs.
9797
/// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details.
9898
const PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS = 1 << 5;
99-
/// Any of these flags being set prevent field reordering optimisation.
100-
const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits()
99+
const IS_SCALABLE = 1 << 6;
100+
// Any of these flags being set prevent field reordering optimisation.
101+
const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits()
101102
| ReprFlags::IS_SIMD.bits()
103+
| ReprFlags::IS_SCALABLE.bits()
102104
| ReprFlags::IS_LINEAR.bits();
103105
const ABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits();
104106
}
@@ -135,6 +137,19 @@ impl IntegerType {
135137
}
136138
}
137139

140+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
141+
#[cfg_attr(
142+
feature = "nightly",
143+
derive(Encodable_NoContext, Decodable_NoContext, HashStable_Generic)
144+
)]
145+
pub enum ScalableElt {
146+
/// `N` in `rustc_scalable_vector(N)` - the element count of the scalable vector
147+
ElementCount(u128),
148+
/// `rustc_scalable_vector` w/out `N`, used for tuple types of scalable vectors that only
149+
/// contain other scalable vectors
150+
Container,
151+
}
152+
138153
/// Represents the repr options provided by the user.
139154
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
140155
#[cfg_attr(
@@ -146,6 +161,8 @@ pub struct ReprOptions {
146161
pub align: Option<Align>,
147162
pub pack: Option<Align>,
148163
pub flags: ReprFlags,
164+
/// `#[rustc_scalable_vector]`
165+
pub scalable: Option<ScalableElt>,
149166
/// The seed to be used for randomizing a type's layout
150167
///
151168
/// Note: This could technically be a `u128` which would
@@ -162,6 +179,11 @@ impl ReprOptions {
162179
self.flags.contains(ReprFlags::IS_SIMD)
163180
}
164181

182+
#[inline]
183+
pub fn scalable(&self) -> bool {
184+
self.flags.contains(ReprFlags::IS_SCALABLE)
185+
}
186+
165187
#[inline]
166188
pub fn c(&self) -> bool {
167189
self.flags.contains(ReprFlags::IS_C)

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,27 @@ impl<S: Stage> SingleAttributeParser<S> for RustcSimdMonomorphizeLaneLimitParser
7676
Some(AttributeKind::RustcSimdMonomorphizeLaneLimit(cx.parse_limit_int(nv)?))
7777
}
7878
}
79+
80+
pub(crate) struct RustcScalableVectorParser;
81+
82+
impl<S: Stage> SingleAttributeParser<S> for RustcScalableVectorParser {
83+
const PATH: &[rustc_span::Symbol] = &[sym::rustc_scalable_vector];
84+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
85+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
86+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
87+
const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]);
88+
89+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
90+
if args.no_args().is_ok() {
91+
return Some(AttributeKind::RustcScalableVector {
92+
element_count: None,
93+
span: cx.attr_span,
94+
});
95+
}
96+
97+
parse_single_integer(cx, args).map(|n| AttributeKind::RustcScalableVector {
98+
element_count: Some(Box::new(n)),
99+
span: cx.attr_span,
100+
})
101+
}
102+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ use crate::attributes::prototype::CustomMirParser;
5959
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
6060
use crate::attributes::rustc_internal::{
6161
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser,
62-
RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser,
62+
RustcObjectLifetimeDefaultParser, RustcScalableVectorParser,
63+
RustcSimdMonomorphizeLaneLimitParser,
6364
};
6465
use crate::attributes::semantics::MayDangleParser;
6566
use crate::attributes::stability::{
@@ -207,6 +208,7 @@ attribute_parsers!(
207208
Single<RustcLayoutScalarValidRangeEndParser>,
208209
Single<RustcLayoutScalarValidRangeStartParser>,
209210
Single<RustcObjectLifetimeDefaultParser>,
211+
Single<RustcScalableVectorParser>,
210212
Single<RustcSimdMonomorphizeLaneLimitParser>,
211213
Single<SanitizeParser>,
212214
Single<ShouldPanicParser>,

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
14171417
rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes,
14181418
"`#[rustc_force_inline]` forces a free function to be inlined"
14191419
),
1420+
rustc_attr!(
1421+
rustc_scalable_vector, Normal, template!(List: &["count"]), WarnFollowing, EncodeCrossCrate::Yes,
1422+
"`#[rustc_scalable_vector]` defines a scalable vector type"
1423+
),
14201424

14211425
// ==========================================================================
14221426
// Internal attributes, Testing:

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,14 @@ pub enum AttributeKind {
717717
/// Represents `#[rustc_pass_indirectly_in_non_rustic_abis]`
718718
RustcPassIndirectlyInNonRusticAbis(Span),
719719

720+
/// Represents `#[rustc_scalable_vector(N)]`
721+
RustcScalableVector {
722+
/// The base multiple of lanes that are in a scalable vector, if provided. `element_count`
723+
/// is not provided for representing tuple types.
724+
element_count: Option<Box<u128>>,
725+
span: Span,
726+
},
727+
720728
/// Represents `#[rustc_should_not_be_called_on_const_items]`
721729
RustcShouldNotBeCalledOnConstItems(Span),
722730

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ impl AttributeKind {
9191
RustcMain => No,
9292
RustcObjectLifetimeDefault => No,
9393
RustcPassIndirectlyInNonRusticAbis(..) => No,
94+
RustcScalableVector { .. } => Yes,
9495
RustcShouldNotBeCalledOnConstItems(..) => Yes,
9596
RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate
9697
Sanitize { .. } => No,

compiler/rustc_hir/src/attrs/pretty_printing.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::num::NonZero;
2+
use std::ops::Deref;
23

34
use rustc_abi::Align;
45
use rustc_ast::token::CommentKind;
@@ -35,6 +36,15 @@ impl<T: PrintAttribute> PrintAttribute for &T {
3536
T::print_attribute(self, p)
3637
}
3738
}
39+
impl<T: PrintAttribute> PrintAttribute for Box<T> {
40+
fn should_render(&self) -> bool {
41+
self.deref().should_render()
42+
}
43+
44+
fn print_attribute(&self, p: &mut Printer) {
45+
T::print_attribute(self.deref(), p)
46+
}
47+
}
3848
impl<T: PrintAttribute> PrintAttribute for Option<T> {
3949
fn should_render(&self) -> bool {
4050
self.as_ref().is_some_and(|x| x.should_render())

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ pub use assoc::*;
2424
pub use generic_args::{GenericArgKind, TermKind, *};
2525
pub use generics::*;
2626
pub use intrinsic::IntrinsicDef;
27-
use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx};
27+
use rustc_abi::{
28+
Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, ScalableElt, VariantIdx,
29+
};
2830
use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree};
2931
use rustc_ast::node_id::NodeMap;
3032
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
@@ -1513,6 +1515,17 @@ impl<'tcx> TyCtxt<'tcx> {
15131515
}
15141516

15151517
let attributes = self.get_all_attrs(did);
1518+
let elt = find_attr!(
1519+
attributes,
1520+
AttributeKind::RustcScalableVector { element_count, .. } => element_count
1521+
)
1522+
.map(|elt| match elt {
1523+
Some(n) => ScalableElt::ElementCount(**n),
1524+
None => ScalableElt::Container,
1525+
});
1526+
if elt.is_some() {
1527+
flags.insert(ReprFlags::IS_SCALABLE);
1528+
}
15161529
if let Some(reprs) = find_attr!(attributes, AttributeKind::Repr { reprs, .. } => reprs) {
15171530
for (r, _) in reprs {
15181531
flags.insert(match *r {
@@ -1577,7 +1590,14 @@ impl<'tcx> TyCtxt<'tcx> {
15771590
flags.insert(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS);
15781591
}
15791592

1580-
ReprOptions { int: size, align: max_align, pack: min_pack, flags, field_shuffle_seed }
1593+
ReprOptions {
1594+
int: size,
1595+
align: max_align,
1596+
pack: min_pack,
1597+
flags,
1598+
field_shuffle_seed,
1599+
scalable: elt,
1600+
}
15811601
}
15821602

15831603
/// Look up the name of a definition across crates. This does not look at HIR.

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,14 @@ impl<'tcx> Ty<'tcx> {
12521252
}
12531253
}
12541254

1255+
#[inline]
1256+
pub fn is_scalable_vector(self) -> bool {
1257+
match self.kind() {
1258+
Adt(def, _) => def.repr().scalable(),
1259+
_ => false,
1260+
}
1261+
}
1262+
12551263
pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
12561264
match self.kind() {
12571265
Array(ty, _) | Slice(ty) => *ty,

compiler/rustc_passes/src/check_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
260260
| AttributeKind::MacroEscape( .. )
261261
| AttributeKind::RustcLayoutScalarValidRangeStart(..)
262262
| AttributeKind::RustcLayoutScalarValidRangeEnd(..)
263+
| AttributeKind::RustcScalableVector { .. }
263264
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
264265
| AttributeKind::RustcShouldNotBeCalledOnConstItems(..)
265266
| AttributeKind::ExportStable

0 commit comments

Comments
 (0)