Skip to content

Pass in the layout to codegen_rvalue_operand/rvalue_creates_operand #109556

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

Closed
wants to merge 1 commit into from
Closed
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
33 changes: 16 additions & 17 deletions compiler/rustc_codegen_ssa/src/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_index::vec::IndexVec;
use rustc_middle::mir::traversal;
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{self, Location, TerminatorKind};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};

pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx: &FunctionCx<'a, 'tcx, Bx>,
Expand All @@ -22,13 +22,14 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
.map(|decl| {
let ty = fx.monomorphize(decl.ty);
let layout = fx.cx.spanned_layout_of(ty, decl.source_info.span);
if layout.is_zst() {
let kind = if layout.is_zst() {
LocalKind::ZST
} else if fx.cx.is_backend_immediate(layout) || fx.cx.is_backend_scalar_pair(layout) {
LocalKind::Unused
} else {
LocalKind::Memory
}
};
(kind, layout)
})
.collect();

Expand All @@ -48,7 +49,7 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(

let mut non_ssa_locals = BitSet::new_empty(analyzer.locals.len());
for (local, kind) in analyzer.locals.iter_enumerated() {
if matches!(kind, LocalKind::Memory) {
if matches!(kind.0, LocalKind::Memory) {
non_ssa_locals.insert(local);
}
}
Expand Down Expand Up @@ -85,12 +86,12 @@ impl DefLocation {
struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
fx: &'mir FunctionCx<'a, 'tcx, Bx>,
dominators: Dominators<mir::BasicBlock>,
locals: IndexVec<mir::Local, LocalKind>,
locals: IndexVec<mir::Local, (LocalKind, TyAndLayout<'tcx>)>,
}

impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
fn assign(&mut self, local: mir::Local, location: DefLocation) {
let kind = &mut self.locals[local];
let kind = &mut self.locals[local].0;
match *kind {
LocalKind::ZST => {}
LocalKind::Memory => {}
Expand Down Expand Up @@ -178,10 +179,9 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>

if let Some(local) = place.as_local() {
self.assign(local, DefLocation::Body(location));
if self.locals[local] != LocalKind::Memory {
let decl_span = self.fx.mir.local_decls[local].source_info.span;
if !self.fx.rvalue_creates_operand(rvalue, decl_span) {
self.locals[local] = LocalKind::Memory;
if self.locals[local].0 != LocalKind::Memory {
if !self.fx.rvalue_creates_operand(rvalue, self.locals[local].1) {
self.locals[local].0 = LocalKind::Memory;
}
}
} else {
Expand All @@ -207,7 +207,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>

PlaceContext::NonMutatingUse(
NonMutatingUseContext::Copy | NonMutatingUseContext::Move,
) => match &mut self.locals[local] {
) => match &mut self.locals[local].0 {
LocalKind::ZST => {}
LocalKind::Memory => {}
LocalKind::SSA(def) if def.dominates(location, &self.dominators) => {}
Expand Down Expand Up @@ -237,17 +237,16 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
| NonMutatingUseContext::AddressOf
| NonMutatingUseContext::Projection,
) => {
self.locals[local] = LocalKind::Memory;
self.locals[local].0 = LocalKind::Memory;
}

PlaceContext::MutatingUse(MutatingUseContext::Drop) => {
let kind = &mut self.locals[local];
if *kind != LocalKind::Memory {
let ty = self.fx.mir.local_decls[local].ty;
let ty = self.fx.monomorphize(ty);
let kind_and_ty = &mut self.locals[local];
if kind_and_ty.0 != LocalKind::Memory {
let ty = kind_and_ty.1.ty;
if self.fx.cx.type_needs_drop(ty) {
// Only need the place if we're actually dropping it.
*kind = LocalKind::Memory;
kind_and_ty.0 = LocalKind::Memory;
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

PassMode::Cast(cast_ty, _) => {
let op = match self.locals[mir::RETURN_PLACE] {
LocalRef::Operand(Some(op)) => op,
LocalRef::Operand(None) => bug!("use of return before def"),
LocalRef::Operand(op) => op,
LocalRef::PendingOperand(_) => bug!("use of return before def"),
LocalRef::Place(cg_place) => OperandRef {
val: Ref(cg_place.llval, None, cg_place.align),
layout: cg_place.layout,
Expand Down Expand Up @@ -1673,7 +1673,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
match self.locals[index] {
LocalRef::Place(dest) => dest,
LocalRef::UnsizedPlace(_) => bug!("return type must be sized"),
LocalRef::Operand(None) => {
LocalRef::PendingOperand(op_layout) => {
debug_assert_eq!(op_layout, fn_ret.layout);
// Handle temporary places, specifically `Operand` ones, as
// they don't have `alloca`s.
return if fn_ret.is_indirect() {
Expand All @@ -1694,7 +1695,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
ReturnDest::DirectOperand(index)
};
}
LocalRef::Operand(Some(_)) => {
LocalRef::Operand(_) => {
bug!("place local already assigned to");
}
}
Expand Down Expand Up @@ -1737,7 +1738,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
IndirectOperand(tmp, index) => {
let op = bx.load_operand(tmp);
tmp.storage_dead(bx);
self.locals[index] = LocalRef::Operand(Some(op));
self.locals[index] = LocalRef::Operand(op);
self.debug_introduce_local(bx, index);
}
DirectOperand(index) => {
Expand All @@ -1752,7 +1753,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} else {
OperandRef::from_immediate_or_packed_pair(bx, llval, ret_abi.layout)
};
self.locals[index] = LocalRef::Operand(Some(op));
self.locals[index] = LocalRef::Operand(op);
self.debug_introduce_local(bx, index);
}
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
LocalRef::Place(place) | LocalRef::UnsizedPlace(place) => {
bx.set_var_name(place.llval, name);
}
LocalRef::Operand(Some(operand)) => match operand.val {
LocalRef::Operand(operand) => match operand.val {
OperandValue::Ref(x, ..) | OperandValue::Immediate(x) => {
bx.set_var_name(x, name);
}
Expand All @@ -323,7 +323,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.set_var_name(b, &(name.clone() + ".1"));
}
},
LocalRef::Operand(None) => {}
LocalRef::PendingOperand(_) => {}
}
}

Expand All @@ -332,9 +332,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}

let base = match local_ref {
LocalRef::Operand(None) => return,
LocalRef::PendingOperand(_) => return,

LocalRef::Operand(Some(operand)) => {
LocalRef::Operand(operand) => {
// Don't spill operands onto the stack in naked functions.
// See: https://github.com/rust-lang/rust/issues/42779
let attrs = bx.tcx().codegen_fn_attrs(self.instance.def_id());
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_codegen_ssa/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,11 @@ enum LocalRef<'tcx, V> {
/// Every time it is initialized, we have to reallocate the place
/// and update the fat pointer. That's the reason why it is indirect.
UnsizedPlace(PlaceRef<'tcx, V>),
Operand(Option<OperandRef<'tcx, V>>),
/// `Operand(o)`: `o` has the backend [`OperandValue`] already generated.
Operand(OperandRef<'tcx, V>),
/// `PendingOperand(l)`: codegen has not yet run for this local.
/// `l` is the expected layout, to save recomputing it later.
PendingOperand(TyAndLayout<'tcx>),
}

impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
Expand All @@ -135,9 +139,9 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
// Zero-size temporaries aren't always initialized, which
// doesn't matter because they don't contain data, but
// we need something in the operand.
LocalRef::Operand(Some(OperandRef::new_zst(bx, layout)))
LocalRef::Operand(OperandRef::new_zst(bx, layout))
} else {
LocalRef::Operand(None)
LocalRef::PendingOperand(layout)
}
}
}
Expand Down Expand Up @@ -337,7 +341,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// We don't have to cast or keep the argument in the alloca.
// FIXME(eddyb): We should figure out how to use llvm.dbg.value instead
// of putting everything in allocas just so we can use llvm.dbg.declare.
let local = |op| LocalRef::Operand(Some(op));
let local = |op| LocalRef::Operand(op);
match arg.mode {
PassMode::Ignore => {
return local(OperandRef::new_zst(bx, arg.layout));
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref);

match self.locals[place_ref.local] {
LocalRef::Operand(Some(mut o)) => {
LocalRef::Operand(mut o) => {
// Moves out of scalar and scalar pair fields are trivial.
for elem in place_ref.projection.iter() {
match elem {
Expand All @@ -395,7 +395,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

Some(o)
}
LocalRef::Operand(None) => {
LocalRef::PendingOperand(_) => {
bug!("use of {:?} before def", place_ref);
}
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let mut cg_base = match self.locals[place_ref.local] {
LocalRef::Place(place) => place,
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
LocalRef::Operand(..) => {
LocalRef::Operand(..) | LocalRef::PendingOperand(..) => {
if place_ref.has_deref() {
base = 1;
let cg_base = self.codegen_consume(
Expand Down
Loading