Skip to content

Commit c265ceb

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 cdb4236 commit c265ceb

File tree

14 files changed

+585
-11
lines changed

14 files changed

+585
-11
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(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
@@ -57,7 +57,8 @@ use crate::attributes::prototype::CustomMirParser;
5757
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
5858
use crate::attributes::rustc_internal::{
5959
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser,
60-
RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser,
60+
RustcObjectLifetimeDefaultParser, RustcScalableVectorParser,
61+
RustcSimdMonomorphizeLaneLimitParser,
6162
};
6263
use crate::attributes::semantics::MayDangleParser;
6364
use crate::attributes::stability::{
@@ -205,6 +206,7 @@ attribute_parsers!(
205206
Single<RustcLayoutScalarValidRangeEndParser>,
206207
Single<RustcLayoutScalarValidRangeStartParser>,
207208
Single<RustcObjectLifetimeDefaultParser>,
209+
Single<RustcScalableVectorParser>,
208210
Single<RustcSimdMonomorphizeLaneLimitParser>,
209211
Single<SanitizeParser>,
210212
Single<ShouldPanicParser>,

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
14121412
rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes,
14131413
"`#[rustc_force_inline]` forces a free function to be inlined"
14141414
),
1415+
rustc_attr!(
1416+
rustc_scalable_vector, Normal, template!(List: &["count"]), WarnFollowing, EncodeCrossCrate::Yes,
1417+
"`#[rustc_scalable_vector]` defines a scalable vector type"
1418+
),
14151419

14161420
// ==========================================================================
14171421
// 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
@@ -701,6 +701,14 @@ pub enum AttributeKind {
701701
/// Represents `#[rustc_pass_indirectly_in_non_rustic_abis]`
702702
RustcPassIndirectlyInNonRusticAbis(Span),
703703

704+
/// Represents `#[rustc_scalable_vector(N)]`
705+
RustcScalableVector {
706+
/// The base multiple of lanes that are in a scalable vector, if provided. `element_count`
707+
/// is not provided for representing tuple types.
708+
element_count: Option<u128>,
709+
span: Span,
710+
},
711+
704712
/// Represents `#[rustc_should_not_be_called_on_const_items]`
705713
RustcShouldNotBeCalledOnConstItems(Span),
706714

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_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};
@@ -1512,6 +1514,17 @@ impl<'tcx> TyCtxt<'tcx> {
15121514
}
15131515

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

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

15821602
/// 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
@@ -1257,6 +1257,14 @@ impl<'tcx> Ty<'tcx> {
12571257
}
12581258
}
12591259

1260+
#[inline]
1261+
pub fn is_scalable_vector(self) -> bool {
1262+
match self.kind() {
1263+
Adt(def, _) => def.repr().scalable(),
1264+
_ => false,
1265+
}
1266+
}
1267+
12601268
pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
12611269
match self.kind() {
12621270
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
@@ -253,6 +253,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
253253
| AttributeKind::MacroEscape( .. )
254254
| AttributeKind::RustcLayoutScalarValidRangeStart(..)
255255
| AttributeKind::RustcLayoutScalarValidRangeEnd(..)
256+
| AttributeKind::RustcScalableVector { .. }
256257
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
257258
| AttributeKind::RustcShouldNotBeCalledOnConstItems(..)
258259
| AttributeKind::ExportStable

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,6 +1985,7 @@ symbols! {
19851985
rustc_reallocator,
19861986
rustc_regions,
19871987
rustc_reservation_impl,
1988+
rustc_scalable_vector,
19881989
rustc_serialize,
19891990
rustc_should_not_be_called_on_const_items,
19901991
rustc_simd_monomorphize_lane_limit,

0 commit comments

Comments
 (0)