提交 4f4f7dfc 编写于 作者: N Nikita Popov

Generate br for all two target SwitchInts

Instead of only for booleans. This means that if let also becomes
a br.

Apart from making the IR slightly simpler, this is supported by
FastISel.
上级 6de4ec67
...@@ -191,14 +191,23 @@ fn codegen_terminator(&mut self, ...@@ -191,14 +191,23 @@ fn codegen_terminator(&mut self,
mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => { mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
let discr = self.codegen_operand(&bx, discr); let discr = self.codegen_operand(&bx, discr);
if switch_ty == bx.tcx().types.bool { if targets.len() == 2 {
// If there are two targets, emit br instead of switch
let lltrue = llblock(self, targets[0]); let lltrue = llblock(self, targets[0]);
let llfalse = llblock(self, targets[1]); let llfalse = llblock(self, targets[1]);
if let [0] = values[..] { if switch_ty == bx.tcx().types.bool {
bx.cond_br(discr.immediate(), llfalse, lltrue); // Don't generate trivial icmps when switching on bool
if let [0] = values[..] {
bx.cond_br(discr.immediate(), llfalse, lltrue);
} else {
assert_eq!(&values[..], &[1]);
bx.cond_br(discr.immediate(), lltrue, llfalse);
}
} else { } else {
assert_eq!(&values[..], &[1]); let switch_llty = bx.cx.layout_of(switch_ty).immediate_llvm_type(bx.cx);
bx.cond_br(discr.immediate(), lltrue, llfalse); let llval = C_uint_big(switch_llty, values[0]);
let cmp = bx.icmp(llvm::IntEQ, discr.immediate(), llval);
bx.cond_br(cmp, lltrue, llfalse);
} }
} else { } else {
let (otherwise, targets) = targets.split_last().unwrap(); let (otherwise, targets) = targets.split_last().unwrap();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册