Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Couple mir building cleanups #138410

Merged
merged 2 commits into from
Mar 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 11 additions & 16 deletions compiler/rustc_mir_build/src/builder/expr/as_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,19 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>
return Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar));
}

let trunc = |n, width: ty::UintTy| {
let width = width
.normalize(tcx.data_layout.pointer_size.bits().try_into().unwrap())
.bit_width()
.unwrap();
let width = Size::from_bits(width);
let lit_ty = match *ty.kind() {
ty::Pat(base, _) => base,
_ => ty,
};

let trunc = |n| {
let width = lit_ty.primitive_size(tcx);
trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
let result = width.truncate(n);
trace!("trunc result: {}", result);
ConstValue::Scalar(Scalar::from_uint(result, width))
};

let lit_ty = match *ty.kind() {
ty::Pat(base, _) => base,
_ => ty,
};

let value = match (lit, lit_ty.kind()) {
(ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
let s = s.as_str();
Expand Down Expand Up @@ -149,11 +145,10 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>
(ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => {
ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1)))
}
(ast::LitKind::Int(n, _), ty::Uint(ui)) if !neg => trunc(n.get(), *ui),
(ast::LitKind::Int(n, _), ty::Int(i)) => trunc(
if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() },
i.to_unsigned(),
),
(ast::LitKind::Int(n, _), ty::Uint(_)) if !neg => trunc(n.get()),
(ast::LitKind::Int(n, _), ty::Int(_)) => {
trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() })
}
(ast::LitKind::Float(n, _), ty::Float(fty)) => {
parse_float_into_constval(*n, *fty, neg).unwrap()
}
Expand Down
37 changes: 17 additions & 20 deletions compiler/rustc_mir_build/src/builder/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,27 +305,25 @@ impl DropTree {
}

/// Builds the MIR for a given drop tree.
///
/// `blocks` should have the same length as `self.drops`, and may have its
/// first value set to some already existing block.
fn build_mir<'tcx, T: DropTreeBuilder<'tcx>>(
&mut self,
cfg: &mut CFG<'tcx>,
blocks: &mut IndexVec<DropIdx, Option<BasicBlock>>,
) {
root_node: Option<BasicBlock>,
) -> IndexVec<DropIdx, Option<BasicBlock>> {
debug!("DropTree::build_mir(drops = {:#?})", self);
assert_eq!(blocks.len(), self.drops.len());

self.assign_blocks::<T>(cfg, blocks);
self.link_blocks(cfg, blocks)
let mut blocks = self.assign_blocks::<T>(cfg, root_node);
self.link_blocks(cfg, &mut blocks);

blocks
}

/// Assign blocks for all of the drops in the drop tree that need them.
fn assign_blocks<'tcx, T: DropTreeBuilder<'tcx>>(
&mut self,
cfg: &mut CFG<'tcx>,
blocks: &mut IndexVec<DropIdx, Option<BasicBlock>>,
) {
root_node: Option<BasicBlock>,
) -> IndexVec<DropIdx, Option<BasicBlock>> {
// StorageDead statements can share blocks with each other and also with
// a Drop terminator. We iterate through the drops to find which drops
// need their own block.
Expand All @@ -342,8 +340,11 @@ impl DropTree {
Own,
}

let mut blocks = IndexVec::from_elem(None, &self.drops);
blocks[ROOT_NODE] = root_node;

let mut needs_block = IndexVec::from_elem(Block::None, &self.drops);
if blocks[ROOT_NODE].is_some() {
if root_node.is_some() {
// In some cases (such as drops for `continue`) the root node
// already has a block. In this case, make sure that we don't
// override it.
Expand Down Expand Up @@ -385,6 +386,8 @@ impl DropTree {

debug!("assign_blocks: blocks = {:#?}", blocks);
assert!(entry_points.is_empty());

blocks
}

fn link_blocks<'tcx>(
Expand Down Expand Up @@ -1574,10 +1577,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
span: Span,
continue_block: Option<BasicBlock>,
) -> Option<BlockAnd<()>> {
let mut blocks = IndexVec::from_elem(None, &drops.drops);
blocks[ROOT_NODE] = continue_block;

drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
let blocks = drops.build_mir::<ExitScopes>(&mut self.cfg, continue_block);
let is_coroutine = self.coroutine.is_some();

// Link the exit drop tree to unwind drop tree.
Expand Down Expand Up @@ -1633,8 +1633,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
let drops = &mut self.scopes.coroutine_drops;
let cfg = &mut self.cfg;
let fn_span = self.fn_span;
let mut blocks = IndexVec::from_elem(None, &drops.drops);
drops.build_mir::<CoroutineDrop>(cfg, &mut blocks);
let blocks = drops.build_mir::<CoroutineDrop>(cfg, None);
if let Some(root_block) = blocks[ROOT_NODE] {
cfg.terminate(
root_block,
Expand Down Expand Up @@ -1670,9 +1669,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
fn_span: Span,
resume_block: &mut Option<BasicBlock>,
) {
let mut blocks = IndexVec::from_elem(None, &drops.drops);
blocks[ROOT_NODE] = *resume_block;
drops.build_mir::<Unwind>(cfg, &mut blocks);
let blocks = drops.build_mir::<Unwind>(cfg, *resume_block);
if let (None, Some(resume)) = (*resume_block, blocks[ROOT_NODE]) {
cfg.terminate(resume, SourceInfo::outermost(fn_span), TerminatorKind::UnwindResume);

Expand Down
Loading