diff options
| author | clubby789 <jamie@hill-daniel.co.uk> | 2024-02-05 16:15:47 +0000 |
|---|---|---|
| committer | clubby789 <jamie@hill-daniel.co.uk> | 2024-02-23 10:52:55 +0000 |
| commit | 7159aed51e7ef4d8459a10e449bf8e9cc09c9b98 (patch) | |
| tree | a706c7710ac7008fdc08184cd923e419ac4a3fad /compiler/rustc_codegen_ssa | |
| parent | 397937d812852f9bbeb671005cb399dbcb357cde (diff) | |
| download | rust-7159aed51e7ef4d8459a10e449bf8e9cc09c9b98.tar.gz rust-7159aed51e7ef4d8459a10e449bf8e9cc09c9b98.zip | |
Use `br` instead of conditional when branching on constant
Diffstat (limited to 'compiler/rustc_codegen_ssa')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 00007110938..9c7aadb81f8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -319,7 +319,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { targets: &SwitchTargets, ) { let discr = self.codegen_operand(bx, discr); + let discr_value = discr.immediate(); let switch_ty = discr.layout.ty; + // If our discriminant is a constant we can branch directly + if let Some(const_discr) = bx.const_to_opt_u128(discr_value, false) { + let target = targets.target_for_value(const_discr); + bx.br(helper.llbb_with_cleanup(self, target)); + return; + }; + let mut target_iter = targets.iter(); if target_iter.len() == 1 { // If there are two targets (one conditional, one fallback), emit `br` instead of @@ -330,14 +338,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if switch_ty == bx.tcx().types.bool { // Don't generate trivial icmps when switching on bool. match test_value { - 0 => bx.cond_br(discr.immediate(), llfalse, lltrue), - 1 => bx.cond_br(discr.immediate(), lltrue, llfalse), + 0 => bx.cond_br(discr_value, llfalse, lltrue), + 1 => bx.cond_br(discr_value, lltrue, llfalse), _ => bug!(), } } else { let switch_llty = bx.immediate_backend_type(bx.layout_of(switch_ty)); let llval = bx.const_uint_big(switch_llty, test_value); - let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval); + let cmp = bx.icmp(IntPredicate::IntEQ, discr_value, llval); bx.cond_br(cmp, lltrue, llfalse); } } else if self.cx.sess().opts.optimize == OptLevel::No @@ -362,11 +370,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ll2 = helper.llbb_with_cleanup(self, target2); let switch_llty = bx.immediate_backend_type(bx.layout_of(switch_ty)); let llval = bx.const_uint_big(switch_llty, test_value1); - let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval); + let cmp = bx.icmp(IntPredicate::IntEQ, discr_value, llval); bx.cond_br(cmp, ll1, ll2); } else { bx.switch( - discr.immediate(), + discr_value, helper.llbb_with_cleanup(self, targets.otherwise()), target_iter.map(|(value, target)| (value, helper.llbb_with_cleanup(self, target))), ); |
