Skip to content

Commit adb3f2e

Browse files
Avoid per-register closure expansions
1 parent 1bcbb7c commit adb3f2e

File tree

1 file changed

+54
-49
lines changed
  • compiler/rustc_ast_lowering/src

1 file changed

+54
-49
lines changed

compiler/rustc_ast_lowering/src/asm.rs

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -341,61 +341,66 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
341341

342342
// Flag to output the error only once per operand
343343
let mut skip = false;
344-
reg.overlapping_regs(|r| {
345-
let mut check = |used_regs: &mut FxHashMap<asm::InlineAsmReg, usize>,
346-
input| {
347-
match used_regs.entry(r) {
348-
Entry::Occupied(o) => {
349-
if skip {
350-
return;
351-
}
352-
skip = true;
353344

354-
let idx2 = *o.get();
355-
let (ref op2, op_sp2) = operands[idx2];
356-
let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg()
357-
else {
358-
unreachable!();
359-
};
345+
let mut check = |used_regs: &mut FxHashMap<asm::InlineAsmReg, usize>,
346+
input,
347+
r: asm::InlineAsmReg| {
348+
match used_regs.entry(r) {
349+
Entry::Occupied(o) => {
350+
if skip {
351+
return;
352+
}
353+
skip = true;
360354

361-
let in_out = match (op, op2) {
362-
(
363-
hir::InlineAsmOperand::In { .. },
364-
hir::InlineAsmOperand::Out { late, .. },
365-
)
366-
| (
367-
hir::InlineAsmOperand::Out { late, .. },
368-
hir::InlineAsmOperand::In { .. },
369-
) => {
370-
assert!(!*late);
371-
let out_op_sp = if input { op_sp2 } else { op_sp };
372-
Some(out_op_sp)
373-
}
374-
_ => None,
375-
};
355+
let idx2 = *o.get();
356+
let (ref op2, op_sp2) = operands[idx2];
357+
let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg() else {
358+
unreachable!();
359+
};
376360

377-
sess.emit_err(RegisterConflict {
378-
op_span1: op_sp,
379-
op_span2: op_sp2,
380-
reg1_name: reg.name(),
381-
reg2_name: reg2.name(),
382-
in_out,
383-
});
384-
}
385-
Entry::Vacant(v) => {
386-
if r == reg {
387-
v.insert(idx);
361+
let in_out = match (op, op2) {
362+
(
363+
hir::InlineAsmOperand::In { .. },
364+
hir::InlineAsmOperand::Out { late, .. },
365+
)
366+
| (
367+
hir::InlineAsmOperand::Out { late, .. },
368+
hir::InlineAsmOperand::In { .. },
369+
) => {
370+
assert!(!*late);
371+
let out_op_sp = if input { op_sp2 } else { op_sp };
372+
Some(out_op_sp)
388373
}
374+
_ => None,
375+
};
376+
377+
sess.emit_err(RegisterConflict {
378+
op_span1: op_sp,
379+
op_span2: op_sp2,
380+
reg1_name: reg.name(),
381+
reg2_name: reg2.name(),
382+
in_out,
383+
});
384+
}
385+
Entry::Vacant(v) => {
386+
if r == reg {
387+
v.insert(idx);
389388
}
390389
}
391-
};
390+
}
391+
};
392+
let mut overlapping_with = vec![];
393+
reg.overlapping_regs(|r| {
394+
overlapping_with.push(r);
395+
});
396+
for r in overlapping_with {
392397
if input {
393-
check(&mut used_input_regs, true);
398+
check(&mut used_input_regs, true, r);
394399
}
395400
if output {
396-
check(&mut used_output_regs, false);
401+
check(&mut used_output_regs, false, r);
397402
}
398-
});
403+
}
399404
}
400405
}
401406
}
@@ -410,12 +415,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
410415
continue;
411416
}
412417

413-
let mut output_used = false;
418+
let mut overlapping_with = vec![];
414419
clobber.overlapping_regs(|reg| {
415-
if used_output_regs.contains_key(&reg) {
416-
output_used = true;
417-
}
420+
overlapping_with.push(reg);
418421
});
422+
let output_used =
423+
overlapping_with.iter().any(|reg| used_output_regs.contains_key(&reg));
419424

420425
if !output_used {
421426
operands.push((

0 commit comments

Comments
 (0)