Skip to content

Commit d56ad19

Browse files
committed
InstSimplify calls to constructors.
1 parent 2ee3cd2 commit d56ad19

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

compiler/rustc_mir_transform/src/instsimplify.rs

+58
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
//! Performs various peephole optimizations.
22
33
use crate::simplify::simplify_duplicate_switch_targets;
4+
use rustc_hir::def::DefKind;
5+
use rustc_index::IndexVec;
46
use rustc_middle::mir::*;
57
use rustc_middle::ty::layout::ValidityRequirement;
68
use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt};
79
use rustc_span::symbol::Symbol;
810
use rustc_target::abi::FieldIdx;
11+
use rustc_target::abi::FIRST_VARIANT;
912

1013
pub struct InstSimplify;
1114

@@ -38,6 +41,10 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {
3841
block.terminator.as_mut().unwrap(),
3942
&mut block.statements,
4043
);
44+
ctx.simplify_constructor_calls(
45+
&mut block.terminator.as_mut().unwrap(),
46+
&mut block.statements,
47+
);
4148
simplify_duplicate_switch_targets(block.terminator.as_mut().unwrap());
4249
}
4350
}
@@ -287,6 +294,57 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
287294
}
288295
}
289296
}
297+
298+
fn simplify_constructor_calls(
299+
&self,
300+
terminator: &mut Terminator<'tcx>,
301+
statements: &mut Vec<Statement<'tcx>>,
302+
) {
303+
let TerminatorKind::Call { func, target, destination, args, .. } = &mut terminator.kind
304+
else {
305+
return;
306+
};
307+
let Some(target_block) = target else {
308+
return;
309+
};
310+
let func_ty = func.ty(self.local_decls, self.tcx);
311+
let ty::FnDef(ctor_id, generics) = *func_ty.kind() else {
312+
return;
313+
};
314+
let DefKind::Ctor(..) = self.tcx.def_kind(ctor_id) else {
315+
return;
316+
};
317+
318+
let sig = self
319+
.tcx
320+
.fn_sig(ctor_id)
321+
.instantiate(self.tcx, generics)
322+
.no_bound_vars()
323+
.expect("LBR in ADT constructor signature");
324+
let ty::Adt(adt_def, generics) = sig.output().kind() else {
325+
bug!("unexpected type for ADT ctor {:?}", sig.output());
326+
};
327+
let variant_index = if adt_def.is_enum() {
328+
adt_def.variant_index_with_ctor_id(ctor_id)
329+
} else {
330+
FIRST_VARIANT
331+
};
332+
333+
let kind = AggregateKind::Adt(adt_def.did(), variant_index, generics, None, None);
334+
335+
let args = std::mem::take(args);
336+
let fields = IndexVec::from_raw(args);
337+
338+
let statement = Statement {
339+
kind: StatementKind::Assign(Box::new((
340+
*destination,
341+
Rvalue::Aggregate(Box::new(kind), fields),
342+
))),
343+
source_info: terminator.source_info,
344+
};
345+
statements.push(statement);
346+
terminator.kind = TerminatorKind::Goto { target: *target_block };
347+
}
290348
}
291349

292350
fn intrinsic_assert_panics<'tcx>(

0 commit comments

Comments
 (0)