Add a distinct OperandValue::ZeroSized variant for ZSTs

These tend to have special handling in a bunch of places anyway, so the variant helps remember that.  And I think it's easier to grok than non-Scalar Aggregates sometimes being `Immediates` (like I got wrong and caused 109992).  As a minor bonus, it means we don't need to generate poison LLVM values for them to pass around in `OperandValue::Immediate`s.
This commit is contained in:
Scott McMurray
2023-05-07 03:00:41 -07:00
parent 9af3865dec
commit bf36193ef6
11 changed files with 157 additions and 76 deletions

View File

@@ -129,16 +129,13 @@ enum LocalRef<'tcx, V> {
PendingOperand,
}
impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
fn new_operand<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
layout: TyAndLayout<'tcx>,
) -> LocalRef<'tcx, V> {
impl<'tcx, V: CodegenObject> LocalRef<'tcx, V> {
fn new_operand(layout: TyAndLayout<'tcx>) -> LocalRef<'tcx, V> {
if layout.is_zst() {
// 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(OperandRef::new_zst(bx, layout))
LocalRef::Operand(OperandRef::zero_sized(layout))
} else {
LocalRef::PendingOperand
}
@@ -249,7 +246,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
} else {
debug!("alloc: {:?} -> operand", local);
LocalRef::new_operand(&mut start_bx, layout)
LocalRef::new_operand(layout)
}
};
@@ -355,7 +352,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let local = |op| LocalRef::Operand(op);
match arg.mode {
PassMode::Ignore => {
return local(OperandRef::new_zst(bx, arg.layout));
return local(OperandRef::zero_sized(arg.layout));
}
PassMode::Direct(_) => {
let llarg = bx.get_param(llarg_idx);