diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index f35ff57d64..0703b19b96 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -38,26 +38,6 @@ fn define_control_flow( .is_branch(true), ); - ig.push( - Inst::new( - "fallthrough", - r#" - Fall through to the next block. - - This is the same as `jump`, except the destination block must be - the next one in the layout. - - Jumps are turned into fall-through instructions by the branch - relaxation pass. There is no reason to use this instruction outside - that pass. - "#, - &formats.jump, - ) - .operands_in(vec![block, args]) - .is_terminator(true) - .is_branch(true), - ); - let Testable = &TypeVar::new( "Testable", "A scalar boolean or integer type", diff --git a/cranelift/codegen/src/ir/function.rs b/cranelift/codegen/src/ir/function.rs index fe33970d86..0092a33306 100644 --- a/cranelift/codegen/src/ir/function.rs +++ b/cranelift/codegen/src/ir/function.rs @@ -274,12 +274,12 @@ impl Function { let mut inst_iter = inst_iter.skip_while(|&inst| !dfg[inst].opcode().is_branch()); // A conditional branch is permitted in a basic block only when followed - // by a terminal jump or fallthrough instruction. + // by a terminal jump instruction. if let Some(_branch) = inst_iter.next() { if let Some(next) = inst_iter.next() { match dfg[next].opcode() { - Opcode::Fallthrough | Opcode::Jump => (), - _ => return Err((next, "post-branch instruction not fallthrough or jump")), + Opcode::Jump => (), + _ => return Err((next, "post-branch instruction not jump")), } } } diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 9f576fb611..dedc37eda8 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -2158,19 +2158,7 @@ pub(crate) fn lower_insn_to_regs>( ctx.emit(Inst::gen_move(writable_xreg(PINNED_REG), rm, I64)); } - Opcode::Spill - | Opcode::Fill - | Opcode::FillNop - | Opcode::CopyNop - | Opcode::AdjustSpDown - | Opcode::AdjustSpUpImm - | Opcode::AdjustSpDownImm - | Opcode::IfcmpSp => { - panic!("Unused opcode should not be encountered."); - } - Opcode::Jump - | Opcode::Fallthrough | Opcode::Brz | Opcode::Brnz | Opcode::BrIcmp @@ -3789,7 +3777,7 @@ pub(crate) fn lower_branch>( let op0 = ctx.data(branches[0]).opcode(); let op1 = ctx.data(branches[1]).opcode(); - assert!(op1 == Opcode::Jump || op1 == Opcode::Fallthrough); + assert!(op1 == Opcode::Jump); let taken = BranchTarget::Label(targets[0]); // not_taken target is the target of the second branch, even if it is a Fallthrough // instruction: because we reorder blocks while we lower, the fallthrough in the new @@ -3932,11 +3920,8 @@ pub(crate) fn lower_branch>( // Must be an unconditional branch or an indirect branch. let op = ctx.data(branches[0]).opcode(); match op { - Opcode::Jump | Opcode::Fallthrough => { + Opcode::Jump => { assert!(branches.len() == 1); - // In the Fallthrough case, the machine-independent driver - // fills in `targets[0]` with our fallthrough block, so this - // is valid for both Jump and Fallthrough. ctx.emit(Inst::Jump { dest: BranchTarget::Label(targets[0]), }); diff --git a/cranelift/codegen/src/isa/arm32/lower_inst.rs b/cranelift/codegen/src/isa/arm32/lower_inst.rs index ede634f4b8..32937991b9 100644 --- a/cranelift/codegen/src/isa/arm32/lower_inst.rs +++ b/cranelift/codegen/src/isa/arm32/lower_inst.rs @@ -542,10 +542,9 @@ pub(crate) fn lower_branch>( ) -> CodegenResult<()> { // A block should end with at most two branches. The first may be a // conditional branch; a conditional branch can be followed only by an - // unconditional branch or fallthrough. Otherwise, if only one branch, - // it may be an unconditional branch, a fallthrough, a return, or a - // trap. These conditions are verified by `is_ebb_basic()` during the - // verifier pass. + // unconditional branch. Otherwise, if only one branch, it may be an + // unconditional branch, a return, or a trap. These conditions are verified + // by `is_ebb_basic()` during the verifier pass. assert!(branches.len() <= 2); if branches.len() == 2 { @@ -553,7 +552,7 @@ pub(crate) fn lower_branch>( let op0 = ctx.data(branches[0]).opcode(); let op1 = ctx.data(branches[1]).opcode(); - assert!(op1 == Opcode::Jump || op1 == Opcode::Fallthrough); + assert!(op1 == Opcode::Jump); let taken = BranchTarget::Label(targets[0]); let not_taken = BranchTarget::Label(targets[1]); @@ -586,11 +585,8 @@ pub(crate) fn lower_branch>( // Must be an unconditional branch or an indirect branch. let op = ctx.data(branches[0]).opcode(); match op { - Opcode::Jump | Opcode::Fallthrough => { + Opcode::Jump => { assert_eq!(branches.len(), 1); - // In the Fallthrough case, the machine-independent driver - // fills in `targets[0]` with our fallthrough block, so this - // is valid for both Jump and Fallthrough. ctx.emit(Inst::Jump { dest: BranchTarget::Label(targets[0]), }); diff --git a/cranelift/codegen/src/isa/s390x/lower.rs b/cranelift/codegen/src/isa/s390x/lower.rs index 49e6935c85..379b31879d 100644 --- a/cranelift/codegen/src/isa/s390x/lower.rs +++ b/cranelift/codegen/src/isa/s390x/lower.rs @@ -2909,7 +2909,6 @@ fn lower_insn_to_regs>( } Opcode::Jump - | Opcode::Fallthrough | Opcode::Brz | Opcode::Brnz | Opcode::BrIcmp @@ -2980,7 +2979,7 @@ fn lower_branch>( let op0 = ctx.data(branches[0]).opcode(); let op1 = ctx.data(branches[1]).opcode(); - assert!(op1 == Opcode::Jump || op1 == Opcode::Fallthrough); + assert!(op1 == Opcode::Jump); let taken = BranchTarget::Label(targets[0]); let not_taken = BranchTarget::Label(targets[1]); @@ -3029,11 +3028,8 @@ fn lower_branch>( // Must be an unconditional branch or an indirect branch. let op = ctx.data(branches[0]).opcode(); match op { - Opcode::Jump | Opcode::Fallthrough => { + Opcode::Jump => { assert!(branches.len() == 1); - // In the Fallthrough case, the machine-independent driver - // fills in `targets[0]` with our fallthrough block, so this - // is valid for both Jump and Fallthrough. ctx.emit(Inst::Jump { dest: BranchTarget::Label(targets[0]), }); diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index 9eab030d06..458d412899 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -6879,7 +6879,6 @@ fn lower_insn_to_regs>( } Opcode::Jump - | Opcode::Fallthrough | Opcode::Brz | Opcode::Brnz | Opcode::BrIcmp @@ -6931,13 +6930,10 @@ impl LowerBackend for X64Backend { op0, op1 ); - assert!(op1 == Opcode::Jump || op1 == Opcode::Fallthrough); + assert!(op1 == Opcode::Jump); let taken = targets[0]; - // not_taken target is the target of the second branch, even if it is a Fallthrough - // instruction: because we reorder blocks while we lower, the fallthrough in the new - // order is not (necessarily) the same as the fallthrough in CLIF. So we use the - // explicitly-provided target. + // not_taken target is the target of the second branch. let not_taken = targets[1]; match op0 { @@ -7147,7 +7143,7 @@ impl LowerBackend for X64Backend { // Must be an unconditional branch or trap. let op = ctx.data(branches[0]).opcode(); match op { - Opcode::Jump | Opcode::Fallthrough => { + Opcode::Jump => { ctx.emit(Inst::jmp_known(targets[0])); } diff --git a/cranelift/codegen/src/machinst/lower.rs b/cranelift/codegen/src/machinst/lower.rs index 14ff6c6f91..6cd6d970be 100644 --- a/cranelift/codegen/src/machinst/lower.rs +++ b/cranelift/codegen/src/machinst/lower.rs @@ -1295,32 +1295,23 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> { pub(crate) fn visit_block_succs(f: &Function, block: Block, mut visit: F) { for inst in f.layout.block_likely_branches(block) { if f.dfg[inst].opcode().is_branch() { - visit_branch_targets(f, block, inst, &mut visit); + visit_branch_targets(f, inst, &mut visit); } } } -fn visit_branch_targets( - f: &Function, - block: Block, - inst: Inst, - visit: &mut F, -) { - if f.dfg[inst].opcode() == Opcode::Fallthrough { - visit(inst, f.layout.next_block(block).unwrap()); - } else { - match f.dfg[inst].analyze_branch(&f.dfg.value_lists) { - BranchInfo::NotABranch => {} - BranchInfo::SingleDest(dest, _) => { +fn visit_branch_targets(f: &Function, inst: Inst, visit: &mut F) { + match f.dfg[inst].analyze_branch(&f.dfg.value_lists) { + BranchInfo::NotABranch => {} + BranchInfo::SingleDest(dest, _) => { + visit(inst, dest); + } + BranchInfo::Table(table, maybe_dest) => { + if let Some(dest) = maybe_dest { visit(inst, dest); } - BranchInfo::Table(table, maybe_dest) => { - if let Some(dest) = maybe_dest { - visit(inst, dest); - } - for &dest in f.jump_tables[table].as_slice() { - visit(inst, dest); - } + for &dest in f.jump_tables[table].as_slice() { + visit(inst, dest); } } } diff --git a/cranelift/filetests/filetests/runtests/fibonacci.clif b/cranelift/filetests/filetests/runtests/fibonacci.clif index bdce284f36..8730c2ee12 100644 --- a/cranelift/filetests/filetests/runtests/fibonacci.clif +++ b/cranelift/filetests/filetests/runtests/fibonacci.clif @@ -6,12 +6,12 @@ block0(v0: i32): v1 = icmp_imm ule v0, 2 v2 = iconst.i32 1 brnz v1, block3(v2) ; handle base case, n <= 2 - fallthrough block1(v0, v2) + jump block1(v0, v2) block1(v4: i32, v5:i32): v6 = iconst.i32 1 v7 = iadd_imm v4, -2 - fallthrough block2(v7, v5, v6) + jump block2(v7, v5, v6) block2(v10: i32, v11: i32, v12: i32): ; params: n, fib(n-1), fib(n-2) v13 = iadd v11, v12 @@ -40,7 +40,7 @@ function %fibonacci_recursive(i32) -> i32 { block0(v0: i32): v1 = icmp_imm ule v0, 2 brnz v1, block2 - fallthrough block1(v0) + jump block1(v0) block1(v10: i32): v11 = iadd_imm v10, -1 diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index df0eaf8b59..986dca0e50 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -221,7 +221,7 @@ where // Interpret a Cranelift instruction. Ok(match inst.opcode() { - Opcode::Jump | Opcode::Fallthrough => ControlFlow::ContinueAt(branch(), args()?), + Opcode::Jump => ControlFlow::ContinueAt(branch(), args()?), Opcode::Brz => branch_when( !arg(0)? .convert(ValueConversionKind::ToBoolean)?