Skip to content

Commit 96dee28

Browse files
committed
Auto merge of #88839 - nbdd0121:alignof, r=nagisa
Introduce NullOp::AlignOf This PR introduces `Rvalue::NullaryOp(NullOp::AlignOf, ty)`, which will be lowered from `align_of`, similar to `size_of` lowering to `Rvalue::NullaryOp(NullOp::SizeOf, ty)`. The changes are originally part of #88700 but since it's not dependent on other changes and could have performance impact on its own, it's separated into its own PR.
2 parents 51e514c + cdec87c commit 96dee28

21 files changed

+234
-184
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -726,15 +726,20 @@ fn codegen_stmt<'tcx>(
726726
let ptr = fx.bcx.inst_results(call)[0];
727727
lval.write_cvalue(fx, CValue::by_val(ptr, box_layout));
728728
}
729-
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
729+
Rvalue::NullaryOp(null_op, ty) => {
730730
assert!(
731731
lval.layout()
732732
.ty
733733
.is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all())
734734
);
735-
let ty_size = fx.layout_of(fx.monomorphize(ty)).size.bytes();
735+
let layout = fx.layout_of(fx.monomorphize(ty));
736+
let val = match null_op {
737+
NullOp::SizeOf => layout.size.bytes(),
738+
NullOp::AlignOf => layout.align.abi.bytes(),
739+
NullOp::Box => unreachable!(),
740+
};
736741
let val =
737-
CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), ty_size.into());
742+
CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
738743
lval.write_cvalue(fx, val);
739744
}
740745
Rvalue::Aggregate(ref kind, ref operands) => match kind.as_ref() {

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
823823
dest.write_cvalue(fx, val);
824824
};
825825

826-
pref_align_of | min_align_of | needs_drop | type_id | type_name | variant_count, () {
826+
pref_align_of | needs_drop | type_id | type_name | variant_count, () {
827827
let const_val =
828828
fx.tcx.const_eval_instance(ParamEnv::reveal_all(), instance, None).unwrap();
829829
let val = crate::constant::codegen_const_value(

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
104104
}
105105
}
106106
sym::pref_align_of
107-
| sym::min_align_of
108107
| sym::needs_drop
109108
| sym::type_id
110109
| sym::type_name

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -486,20 +486,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
486486
)
487487
}
488488

489-
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
490-
let ty = self.monomorphize(ty);
491-
assert!(bx.cx().type_is_sized(ty));
492-
let val = bx.cx().const_usize(bx.cx().layout_of(ty).size.bytes());
493-
let tcx = self.cx.tcx();
494-
(
495-
bx,
496-
OperandRef {
497-
val: OperandValue::Immediate(val),
498-
layout: self.cx.layout_of(tcx.types.usize),
499-
},
500-
)
501-
}
502-
503489
mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => {
504490
let content_ty = self.monomorphize(content_ty);
505491
let content_layout = bx.cx().layout_of(content_ty);
@@ -524,6 +510,27 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
524510
let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout };
525511
(bx, operand)
526512
}
513+
514+
mir::Rvalue::NullaryOp(null_op, ty) => {
515+
let ty = self.monomorphize(ty);
516+
assert!(bx.cx().type_is_sized(ty));
517+
let layout = bx.cx().layout_of(ty);
518+
let val = match null_op {
519+
mir::NullOp::SizeOf => layout.size.bytes(),
520+
mir::NullOp::AlignOf => layout.align.abi.bytes(),
521+
mir::NullOp::Box => unreachable!(),
522+
};
523+
let val = bx.cx().const_usize(val);
524+
let tcx = self.cx.tcx();
525+
(
526+
bx,
527+
OperandRef {
528+
val: OperandValue::Immediate(val),
529+
layout: self.cx.layout_of(tcx.types.usize),
530+
},
531+
)
532+
}
533+
527534
mir::Rvalue::ThreadLocalRef(def_id) => {
528535
assert!(bx.cx().tcx().is_static(def_id));
529536
let static_ = bx.get_static(def_id);

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
160160
self.write_scalar(Scalar::from_machine_usize(result, self), dest)?;
161161
}
162162

163-
sym::min_align_of
164-
| sym::pref_align_of
163+
sym::pref_align_of
165164
| sym::needs_drop
166165
| sym::type_id
167166
| sym::type_name
168167
| sym::variant_count => {
169168
let gid = GlobalId { instance, promoted: None };
170169
let ty = match intrinsic_name {
171-
sym::min_align_of | sym::pref_align_of | sym::variant_count => {
172-
self.tcx.types.usize
173-
}
170+
sym::pref_align_of | sym::variant_count => self.tcx.types.usize,
174171
sym::needs_drop => self.tcx.types.bool,
175172
sym::type_id => self.tcx.types.u64,
176173
sym::type_name => self.tcx.mk_static_str(),

compiler/rustc_const_eval/src/interpret/step.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -270,18 +270,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
270270
M::box_alloc(self, &dest)?;
271271
}
272272

273-
NullaryOp(mir::NullOp::SizeOf, ty) => {
273+
NullaryOp(null_op, ty) => {
274274
let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty);
275275
let layout = self.layout_of(ty)?;
276276
if layout.is_unsized() {
277277
// FIXME: This should be a span_bug (#80742)
278278
self.tcx.sess.delay_span_bug(
279279
self.frame().current_span(),
280-
&format!("SizeOf nullary MIR operator called for unsized type {}", ty),
280+
&format!("Nullary MIR operator called for unsized type {}", ty),
281281
);
282282
throw_inval!(SizeOfUnsizedType(ty));
283283
}
284-
self.write_scalar(Scalar::from_machine_usize(layout.size.bytes(), self), &dest)?;
284+
let val = match null_op {
285+
mir::NullOp::SizeOf => layout.size.bytes(),
286+
mir::NullOp::AlignOf => layout.align.abi.bytes(),
287+
mir::NullOp::Box => unreachable!(),
288+
};
289+
self.write_scalar(Scalar::from_machine_usize(val, self), &dest)?;
285290
}
286291

287292
Cast(cast_kind, ref operand, cast_ty) => {

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
648648
}
649649
}
650650

651-
Rvalue::NullaryOp(NullOp::SizeOf, _) => {}
651+
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
652652
Rvalue::NullaryOp(NullOp::Box, _) => self.check_op(ops::HeapAllocation),
653653

654654
Rvalue::UnaryOp(_, ref operand) => {

compiler/rustc_const_eval/src/transform/promote_consts.rs

+1
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ impl<'tcx> Validator<'_, 'tcx> {
520520
Rvalue::NullaryOp(op, _) => match op {
521521
NullOp::Box => return Err(Unpromotable),
522522
NullOp::SizeOf => {}
523+
NullOp::AlignOf => {}
523524
},
524525

525526
Rvalue::UnaryOp(op, operand) => {

compiler/rustc_middle/src/mir/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2277,6 +2277,8 @@ impl BinOp {
22772277
pub enum NullOp {
22782278
/// Returns the size of a value of that type
22792279
SizeOf,
2280+
/// Returns the minimum alignment of a type
2281+
AlignOf,
22802282
/// Creates a new uninitialized box for a value of that type
22812283
Box,
22822284
}

compiler/rustc_middle/src/mir/tcx.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ impl<'tcx> Rvalue<'tcx> {
196196
Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
197197
Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
198198
Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
199-
Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize,
199+
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize,
200200
Rvalue::Aggregate(ref ak, ref ops) => match **ak {
201201
AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64),
202202
AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))),

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
342342
| Rvalue::AddressOf(..)
343343
| Rvalue::Discriminant(..)
344344
| Rvalue::Len(..)
345-
| Rvalue::NullaryOp(NullOp::SizeOf, _)
345+
| Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _)
346346
| Rvalue::NullaryOp(NullOp::Box, _) => {
347347
// This returns an rvalue with uninitialized contents. We can't
348348
// move out of it here because it is an rvalue - assignments always

compiler/rustc_mir_transform/src/lower_intrinsics.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,19 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
9292
// since their semantics depend on the value of overflow-checks flag used
9393
// during codegen. Issue #35310.
9494
}
95-
sym::size_of => {
95+
sym::size_of | sym::min_align_of => {
9696
if let Some((destination, target)) = *destination {
9797
let tp_ty = substs.type_at(0);
98+
let null_op = match intrinsic_name {
99+
sym::size_of => NullOp::SizeOf,
100+
sym::min_align_of => NullOp::AlignOf,
101+
_ => bug!("unexpected intrinsic"),
102+
};
98103
block.statements.push(Statement {
99104
source_info: terminator.source_info,
100105
kind: StatementKind::Assign(Box::new((
101106
destination,
102-
Rvalue::NullaryOp(NullOp::SizeOf, tp_ty),
107+
Rvalue::NullaryOp(null_op, tp_ty),
103108
))),
104109
});
105110
terminator.kind = TerminatorKind::Goto { target };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
- // MIR for `align_of` before LowerIntrinsics
2+
+ // MIR for `align_of` after LowerIntrinsics
3+
4+
fn align_of() -> usize {
5+
let mut _0: usize; // return place in scope 0 at $DIR/lower_intrinsics.rs:18:25: 18:30
6+
7+
bb0: {
8+
- _0 = std::intrinsics::min_align_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:42
9+
- // mir::Constant
10+
- // + span: $DIR/lower_intrinsics.rs:19:5: 19:40
11+
- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::<T>}, val: Value(Scalar(<ZST>)) }
12+
+ _0 = AlignOf(T); // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:42
13+
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:42
14+
}
15+
16+
bb1: {
17+
return; // scope 0 at $DIR/lower_intrinsics.rs:20:2: 20:2
18+
}
19+
20+
bb2 (cleanup): {
21+
resume; // scope 0 at $DIR/lower_intrinsics.rs:18:1: 20:2
22+
}
23+
}
24+

0 commit comments

Comments
 (0)