Skip to content

Commit f0ed021

Browse files
Use helper method for what types need allocas
1 parent 527a685 commit f0ed021

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

src/librustc_codegen_ssa/mir/analyze.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_middle::mir::visit::{
1212
};
1313
use rustc_middle::mir::{self, Location, TerminatorKind};
1414
use rustc_middle::ty;
15-
use rustc_middle::ty::layout::HasTyCtxt;
15+
use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
1616
use rustc_target::abi::LayoutOf;
1717

1818
pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
@@ -27,18 +27,8 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
2727
let ty = fx.monomorphize(&decl.ty);
2828
debug!("local {:?} has type `{}`", local, ty);
2929
let layout = fx.cx.spanned_layout_of(ty, decl.source_info.span);
30-
if fx.cx.is_backend_immediate(layout) {
31-
// These sorts of types are immediates that we can store
32-
// in an Value without an alloca.
33-
} else if fx.cx.is_backend_scalar_pair(layout) {
34-
// We allow pairs and uses of any of their 2 fields.
35-
} else {
36-
// These sorts of types require an alloca. Note that
37-
// is_llvm_immediate() may *still* be true, particularly
38-
// for newtypes, but we currently force some types
39-
// (e.g., structs) into an alloca unconditionally, just so
40-
// that we don't have to deal with having two pathways
41-
// (gep vs extractvalue etc).
30+
31+
if ty_requires_alloca(&analyzer.fx, layout) {
4232
analyzer.not_ssa(local);
4333
}
4434
}
@@ -132,7 +122,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
132122

133123
if let mir::ProjectionElem::Field(..) = elem {
134124
let layout = cx.spanned_layout_of(base_ty.ty, span);
135-
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
125+
if self.ty_requires_alloca(layout) {
136126
// Recurse with the same context, instead of `Projection`,
137127
// potentially stopping at non-operand projections,
138128
// which would trigger `not_ssa` on locals.
@@ -446,3 +436,14 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
446436
debug!("cleanup_kinds: result={:?}", result);
447437
result
448438
}
439+
440+
/// Returns `true` if locals of this type need to be allocated on the stack.
441+
fn ty_requires_alloca<'a, 'tcx>(
442+
fx: &FunctionCx<'a, 'tcx, impl BuilderMethods<'a, 'tcx>>,
443+
ty: TyAndLayout<'tcx>,
444+
) -> bool {
445+
// Currently, this returns `true` for ADTs that are otherwise small enough to qualify. For
446+
// example, `struct Newtype(i32)`. This way, every type has a single way to extract data
447+
// (gep, extractvalue, etc.).
448+
!fx.cx.is_backend_immediate(ty) && !fx.cx.is_backend_scalar_pair(ty)
449+
}

0 commit comments

Comments
 (0)