diff --git a/cranelift/codegen/meta/src/cdsl/instructions.rs b/cranelift/codegen/meta/src/cdsl/instructions.rs index 9db2bfba81..38aab6e3f4 100644 --- a/cranelift/codegen/meta/src/cdsl/instructions.rs +++ b/cranelift/codegen/meta/src/cdsl/instructions.rs @@ -70,8 +70,6 @@ pub(crate) struct InstructionContent { pub is_terminator: bool, /// True for all branch or jump instructions. pub is_branch: bool, - /// True for all indirect branch or jump instructions.', - pub is_indirect_branch: bool, /// Is this a call instruction? pub is_call: bool, /// Is this a return instruction? @@ -145,7 +143,6 @@ pub(crate) struct InstructionBuilder { // See Instruction comments for the meaning of these fields. is_terminator: bool, is_branch: bool, - is_indirect_branch: bool, is_call: bool, is_return: bool, is_ghost: bool, @@ -168,7 +165,6 @@ impl InstructionBuilder { is_terminator: false, is_branch: false, - is_indirect_branch: false, is_call: false, is_return: false, is_ghost: false, @@ -210,12 +206,6 @@ impl InstructionBuilder { self } - #[allow(clippy::wrong_self_convention)] - pub fn is_indirect_branch(mut self, val: bool) -> Self { - self.is_indirect_branch = val; - self - } - #[allow(clippy::wrong_self_convention)] pub fn is_call(mut self, val: bool) -> Self { self.is_call = val; @@ -300,7 +290,6 @@ impl InstructionBuilder { imm_opnums, is_terminator: self.is_terminator, is_branch: self.is_branch, - is_indirect_branch: self.is_indirect_branch, is_call: self.is_call, is_return: self.is_return, is_ghost: self.is_ghost, diff --git a/cranelift/codegen/meta/src/gen_inst.rs b/cranelift/codegen/meta/src/gen_inst.rs index 13f4776d3b..13c1d96755 100644 --- a/cranelift/codegen/meta/src/gen_inst.rs +++ b/cranelift/codegen/meta/src/gen_inst.rs @@ -468,13 +468,6 @@ fn gen_opcodes(all_inst: &AllInstructions, fmt: &mut Formatter) { "True for all branch or jump instructions.", fmt, ); - gen_bool_accessor( - all_inst, - |inst| inst.is_indirect_branch, - "is_indirect_branch", - "True for all indirect branch or jump instructions.", - fmt, - ); gen_bool_accessor( all_inst, |inst| inst.is_call, diff --git a/cranelift/codegen/meta/src/shared/formats.rs b/cranelift/codegen/meta/src/shared/formats.rs index f1d0a1826d..d1fe6adaac 100644 --- a/cranelift/codegen/meta/src/shared/formats.rs +++ b/cranelift/codegen/meta/src/shared/formats.rs @@ -13,8 +13,6 @@ pub(crate) struct Formats { pub(crate) branch_icmp: Rc, pub(crate) branch_int: Rc, pub(crate) branch_table: Rc, - pub(crate) branch_table_base: Rc, - pub(crate) branch_table_entry: Rc, pub(crate) call: Rc, pub(crate) call_indirect: Rc, pub(crate) cond_trap: Rc, @@ -23,7 +21,6 @@ pub(crate) struct Formats { pub(crate) float_cond_trap: Rc, pub(crate) func_addr: Rc, pub(crate) heap_addr: Rc, - pub(crate) indirect_jump: Rc, pub(crate) int_compare: Rc, pub(crate) int_compare_imm: Rc, pub(crate) int_cond: Rc, @@ -172,22 +169,6 @@ impl Formats { .imm(&entities.jump_table) .build(), - branch_table_entry: Builder::new("BranchTableEntry") - .value() - .value() - .imm(&imm.uimm8) - .imm(&entities.jump_table) - .build(), - - branch_table_base: Builder::new("BranchTableBase") - .imm(&entities.jump_table) - .build(), - - indirect_jump: Builder::new("IndirectJump") - .value() - .imm(&entities.jump_table) - .build(), - call: Builder::new("Call") .imm(&entities.func_ref) .varargs() diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index 01865ccba1..23dbbaea0a 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", @@ -214,68 +194,6 @@ fn define_control_flow( TypeSetBuilder::new().ints(32..64).refs(32..64).build(), ); - { - let x = &Operand::new("x", iAddr).with_doc("index into jump table"); - let addr = &Operand::new("addr", iAddr); - let Size = &Operand::new("Size", &imm.uimm8).with_doc("Size in bytes"); - let JT = &Operand::new("JT", &entities.jump_table); - let entry = &Operand::new("entry", iAddr).with_doc("entry of jump table"); - - ig.push( - Inst::new( - "jump_table_entry", - r#" - Get an entry from a jump table. - - Load a serialized ``entry`` from a jump table ``JT`` at a given index - ``addr`` with a specific ``Size``. The retrieved entry may need to be - decoded after loading, depending upon the jump table type used. - - Currently, the only type supported is entries which are relative to the - base of the jump table. - "#, - &formats.branch_table_entry, - ) - .operands_in(vec![x, addr, Size, JT]) - .operands_out(vec![entry]) - .can_load(true), - ); - - ig.push( - Inst::new( - "jump_table_base", - r#" - Get the absolute base address of a jump table. - - This is used for jump tables wherein the entries are stored relative to - the base of jump table. In order to use these, generated code should first - load an entry using ``jump_table_entry``, then use this instruction to add - the relative base back to it. - "#, - &formats.branch_table_base, - ) - .operands_in(vec![JT]) - .operands_out(vec![addr]), - ); - - ig.push( - Inst::new( - "indirect_jump_table_br", - r#" - Branch indirectly via a jump table entry. - - Unconditionally jump via a jump table entry that was previously loaded - with the ``jump_table_entry`` instruction. - "#, - &formats.indirect_jump, - ) - .operands_in(vec![addr, JT]) - .is_indirect_branch(true) - .is_terminator(true) - .is_branch(true), - ); - } - ig.push( Inst::new( "debugtrap", @@ -1880,156 +1798,6 @@ pub(crate) fn define( .operands_out(vec![a]), ); - ig.push( - Inst::new( - "spill", - r#" - Spill a register value to a stack slot. - - This instruction behaves exactly like `copy`, but the result - value is assigned to a spill slot. - "#, - &formats.unary, - ) - .operands_in(vec![x]) - .operands_out(vec![a]) - .can_store(true), - ); - - ig.push( - Inst::new( - "fill", - r#" - Load a register value from a stack slot. - - This instruction behaves exactly like `copy`, but creates a new - SSA value for the spilled input value. - "#, - &formats.unary, - ) - .operands_in(vec![x]) - .operands_out(vec![a]) - .can_load(true), - ); - - ig.push( - Inst::new( - "fill_nop", - r#" - This is identical to `fill`, except it has no encoding, since it is a no-op. - - This instruction is created only during late-stage redundant-reload removal, after all - registers and stack slots have been assigned. It is used to replace `fill`s that have - been identified as redundant. - "#, - &formats.unary, - ) - .operands_in(vec![x]) - .operands_out(vec![a]) - .can_load(true), - ); - - ig.push( - Inst::new( - "copy_nop", - r#" - Stack-slot-to-the-same-stack-slot copy, which is guaranteed to turn - into a no-op. This instruction is for use only within Cranelift itself. - - This instruction copies its input, preserving the value type. - "#, - &formats.unary, - ) - .operands_in(vec![x]) - .operands_out(vec![a]), - ); - - let delta = &Operand::new("delta", Int); - - ig.push( - Inst::new( - "adjust_sp_down", - r#" - Subtracts ``delta`` offset value from the stack pointer register. - - This instruction is used to adjust the stack pointer by a dynamic amount. - "#, - &formats.unary, - ) - .operands_in(vec![delta]) - .other_side_effects(true), - ); - - let Offset = &Operand::new("Offset", &imm.imm64).with_doc("Offset from current stack pointer"); - - ig.push( - Inst::new( - "adjust_sp_up_imm", - r#" - Adds ``Offset`` immediate offset value to the stack pointer register. - - This instruction is used to adjust the stack pointer, primarily in function - prologues and epilogues. ``Offset`` is constrained to the size of a signed - 32-bit integer. - "#, - &formats.unary_imm, - ) - .operands_in(vec![Offset]) - .other_side_effects(true), - ); - - let Offset = &Operand::new("Offset", &imm.imm64).with_doc("Offset from current stack pointer"); - - ig.push( - Inst::new( - "adjust_sp_down_imm", - r#" - Subtracts ``Offset`` immediate offset value from the stack pointer - register. - - This instruction is used to adjust the stack pointer, primarily in function - prologues and epilogues. ``Offset`` is constrained to the size of a signed - 32-bit integer. - "#, - &formats.unary_imm, - ) - .operands_in(vec![Offset]) - .other_side_effects(true), - ); - - let f = &Operand::new("f", iflags); - - ig.push( - Inst::new( - "ifcmp_sp", - r#" - Compare ``addr`` with the stack pointer and set the CPU flags. - - This is like `ifcmp` where ``addr`` is the LHS operand and the stack - pointer is the RHS. - "#, - &formats.unary, - ) - .operands_in(vec![addr]) - .operands_out(vec![f]), - ); - - let N = - &Operand::new("args", &entities.varargs).with_doc("Variable number of args for StackMap"); - - ig.push( - Inst::new( - "safepoint", - r#" - This instruction will provide live reference values at a point in - the function. It can only be used by the compiler. - "#, - &formats.multiary, - ) - .operands_in(vec![N]) - .other_side_effects(true), - ); - let x = &Operand::new("x", TxN).with_doc("Vector to split"); let lo = &Operand::new("lo", &TxN.half_vector()).with_doc("Low-numbered lanes of `x`"); let hi = &Operand::new("hi", &TxN.half_vector()).with_doc("High-numbered lanes of `x`"); 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/ir/instructions.rs b/cranelift/codegen/src/ir/instructions.rs index 3580f27376..92f7c34bec 100644 --- a/cranelift/codegen/src/ir/instructions.rs +++ b/cranelift/codegen/src/ir/instructions.rs @@ -229,7 +229,6 @@ impl InstructionData { Self::BranchTable { table, destination, .. } => BranchInfo::Table(table, Some(destination)), - Self::IndirectJump { table, .. } => BranchInfo::Table(table, None), _ => { debug_assert!(!self.opcode().is_branch()); BranchInfo::NotABranch @@ -248,7 +247,7 @@ impl InstructionData { | Self::BranchInt { destination, .. } | Self::BranchFloat { destination, .. } | Self::BranchIcmp { destination, .. } => Some(destination), - Self::BranchTable { .. } | Self::IndirectJump { .. } => None, + Self::BranchTable { .. } => None, _ => { debug_assert!(!self.opcode().is_branch()); None @@ -282,7 +281,7 @@ impl InstructionData { ref mut destination, .. } => Some(destination), - Self::BranchTable { .. } | Self::IndirectJump { .. } => None, + Self::BranchTable { .. } => None, _ => { debug_assert!(!self.opcode().is_branch()); None @@ -297,8 +296,7 @@ impl InstructionData { &InstructionData::UnaryBool { imm, .. } => Some(DataValue::from(imm)), // 8-bit. &InstructionData::BinaryImm8 { imm, .. } - | &InstructionData::TernaryImm8 { imm, .. } - | &InstructionData::BranchTableEntry { imm, .. } => Some(DataValue::from(imm as i8)), // Note the switch from unsigned to signed. + | &InstructionData::TernaryImm8 { imm, .. } => Some(DataValue::from(imm as i8)), // Note the switch from unsigned to signed. // 32-bit &InstructionData::UnaryIeee32 { imm, .. } => Some(DataValue::from(imm)), &InstructionData::HeapAddr { imm, .. } => { diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 1015e054c4..8fa9115d79 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -2029,10 +2029,6 @@ pub(crate) fn lower_insn_to_regs>( } } - Opcode::JumpTableEntry | Opcode::JumpTableBase => { - panic!("Should not appear: we handle BrTable directly"); - } - Opcode::Debugtrap => { ctx.emit(Inst::Brk); } @@ -2076,10 +2072,6 @@ pub(crate) fn lower_insn_to_regs>( }); } - Opcode::Safepoint => { - panic!("safepoint instructions not used by new backend's safepoints!"); - } - Opcode::Trapz | Opcode::Trapnz | Opcode::ResumableTrapnz => { panic!("trapz / trapnz / resumable_trapnz should have been removed by legalization!"); } @@ -2162,25 +2154,12 @@ 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 | Opcode::Brif | Opcode::Brff - | Opcode::IndirectJumpTableBr | Opcode::BrTable => { panic!("Branch opcode reached non-branch lowering logic!"); } @@ -3794,7 +3773,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 @@ -3937,11 +3916,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 e1cff43b93..fe96631ccb 100644 --- a/cranelift/codegen/src/isa/s390x/lower.rs +++ b/cranelift/codegen/src/isa/s390x/lower.rs @@ -2888,17 +2888,6 @@ fn lower_insn_to_regs>( Opcode::Isplit | Opcode::Iconcat => unimplemented!("Wide integer ops not implemented."), - Opcode::Spill - | Opcode::Fill - | Opcode::FillNop - | Opcode::CopyNop - | Opcode::AdjustSpDown - | Opcode::AdjustSpUpImm - | Opcode::AdjustSpDownImm - | Opcode::IfcmpSp => { - panic!("Unused opcode should not be encountered."); - } - Opcode::Ifcmp | Opcode::Ffcmp | Opcode::Trapff @@ -2909,25 +2898,15 @@ fn lower_insn_to_regs>( } Opcode::Jump - | Opcode::Fallthrough | Opcode::Brz | Opcode::Brnz | Opcode::BrIcmp | Opcode::Brif | Opcode::Brff - | Opcode::IndirectJumpTableBr | Opcode::BrTable => { panic!("Branch opcode reached non-branch lowering logic!"); } - Opcode::JumpTableEntry | Opcode::JumpTableBase => { - panic!("Should not appear: we handle BrTable directly"); - } - - Opcode::Safepoint => { - panic!("safepoint instructions not used by new backend's safepoints!"); - } - Opcode::IaddImm | Opcode::ImulImm | Opcode::UdivImm @@ -2984,7 +2963,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]); @@ -3033,11 +3012,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 1a635108d0..78cbeb6272 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -6858,38 +6858,20 @@ fn lower_insn_to_regs>( panic!("table_addr should have been removed by legalization!"); } - Opcode::Safepoint => { - panic!("safepoint instructions not used by new backend's safepoints!"); - } - - Opcode::Spill - | Opcode::Fill - | Opcode::FillNop - | Opcode::CopyNop - | Opcode::AdjustSpDown - | Opcode::AdjustSpUpImm - | Opcode::AdjustSpDownImm - | Opcode::IfcmpSp - | Opcode::Copy => { + Opcode::Copy => { panic!("Unused opcode should not be encountered."); } - Opcode::JumpTableEntry | Opcode::JumpTableBase => { - panic!("Should not appear: we handle BrTable directly"); - } - Opcode::Trapz | Opcode::Trapnz | Opcode::ResumableTrapnz => { panic!("trapz / trapnz / resumable_trapnz should have been removed by legalization!"); } Opcode::Jump - | Opcode::Fallthrough | Opcode::Brz | Opcode::Brnz | Opcode::BrIcmp | Opcode::Brif | Opcode::Brff - | Opcode::IndirectJumpTableBr | Opcode::BrTable => { panic!("Branch opcode reached non-branch lowering logic!"); } @@ -6936,13 +6918,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 { @@ -7094,23 +7073,6 @@ impl LowerBackend for X64Backend { let cond_code = emit_cmp(ctx, ifcmp, cond_code); let cc = CC::from_intcc(cond_code); ctx.emit(Inst::jmp_cond(cc, taken, not_taken)); - } else if let Some(ifcmp_sp) = matches_input(ctx, flag_input, Opcode::IfcmpSp) { - let operand = put_input_in_reg( - ctx, - InsnInput { - insn: ifcmp_sp, - input: 0, - }, - ); - let ty = ctx.input_ty(ifcmp_sp, 0); - ctx.emit(Inst::cmp_rmi_r( - OperandSize::from_ty(ty), - RegMemImm::reg(regs::rsp()), - operand, - )); - let cond_code = ctx.data(branches[0]).cond_code().unwrap(); - let cc = CC::from_intcc(cond_code); - ctx.emit(Inst::jmp_cond(cc, taken, not_taken)); } else { // Should be disallowed by flags checks in verifier. unimplemented!("Brif with non-ifcmp input"); @@ -7152,7 +7114,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/codegen/src/peepmatic.rs b/cranelift/codegen/src/peepmatic.rs index a7e37c9ba0..7281596eaf 100644 --- a/cranelift/codegen/src/peepmatic.rs +++ b/cranelift/codegen/src/peepmatic.rs @@ -26,14 +26,6 @@ use std::sync::atomic::{AtomicPtr, Ordering}; peepmatic_traits::define_parse_and_typing_rules_for_operator! { Opcode { - adjust_sp_down => AdjustSpDown { - parameters(iNN); - result(void); - } - adjust_sp_down_imm => AdjustSpDownImm { - immediates(iNN); - result(void); - } band => Band { parameters(iNN, iNN); result(iNN); @@ -888,10 +880,6 @@ unsafe impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa { } InstructionData::Unary { - opcode: opcode @ Opcode::AdjustSpDown, - arg, - } - | InstructionData::Unary { opcode: opcode @ Opcode::Bint, arg, } @@ -920,10 +908,6 @@ unsafe impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa { } InstructionData::UnaryImm { - opcode: opcode @ Opcode::AdjustSpDownImm, - imm, - } - | InstructionData::UnaryImm { opcode: opcode @ Opcode::Iconst, imm, } => { @@ -949,15 +933,6 @@ unsafe impl<'a, 'b> InstructionSet<'b> for &'a dyn TargetIsa { let root = root.resolve_inst(&pos.func.dfg).unwrap(); match operator { - Opcode::AdjustSpDown => { - let a = part_to_value(pos, root, a).unwrap(); - pos.ins().adjust_sp_down(a).into() - } - Opcode::AdjustSpDownImm => { - let c = a.unwrap_constant(); - let imm = Imm64::try_from(c).unwrap(); - pos.ins().adjust_sp_down_imm(imm).into() - } Opcode::Bconst => { let c = a.unwrap_constant(); let val = const_to_value(pos.ins(), c, root); diff --git a/cranelift/codegen/src/preopt.peepmatic b/cranelift/codegen/src/preopt.peepmatic index cd988ff7d9..b032089492 100644 --- a/cranelift/codegen/src/preopt.peepmatic +++ b/cranelift/codegen/src/preopt.peepmatic @@ -82,9 +82,6 @@ (fits-in-native-word $C)) (irsub_imm $C $x)) -;; Unary instructions whose operand is constant. -(=> (adjust_sp_down $C) (adjust_sp_down_imm $C)) - ;; Fold `(binop_imm $C1 (binop_imm $C2 $x))` into `(binop_imm $(binop $C2 $C1) $x)`. (=> (iadd_imm $C1 (iadd_imm $C2 $x)) (iadd_imm $(iadd $C1 $C2) $x)) (=> (imul_imm $C1 (imul_imm $C2 $x)) (imul_imm $(imul $C1 $C2) $x)) diff --git a/cranelift/codegen/src/simple_preopt.rs b/cranelift/codegen/src/simple_preopt.rs index 6903d18f6c..0beda58c1a 100644 --- a/cranelift/codegen/src/simple_preopt.rs +++ b/cranelift/codegen/src/simple_preopt.rs @@ -809,15 +809,6 @@ mod simplify { } } - InstructionData::Unary { opcode, arg } => { - if let Opcode::AdjustSpDown = opcode { - if let Some(imm) = resolve_imm64_value(&pos.func.dfg, arg) { - // Note this works for both positive and negative immediate values. - pos.func.dfg.replace(inst).adjust_sp_down_imm(imm); - } - } - } - InstructionData::BinaryImm64 { opcode, arg, imm } => { let ty = pos.func.dfg.ctrl_typevar(inst); diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index 36e7286348..f63c45b924 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -65,8 +65,8 @@ use crate::ir; use crate::ir::entities::AnyEntity; use crate::ir::instructions::{BranchInfo, CallInfo, InstructionFormat, ResolvedConstraint}; use crate::ir::{ - types, ArgumentPurpose, Block, Constant, FuncRef, Function, GlobalValue, Inst, InstructionData, - JumpTable, Opcode, SigRef, StackSlot, Type, Value, ValueDef, ValueList, + types, ArgumentPurpose, Block, Constant, FuncRef, Function, GlobalValue, Inst, JumpTable, + Opcode, SigRef, StackSlot, Type, Value, ValueDef, ValueList, }; use crate::isa::TargetIsa; use crate::iterators::IteratorExtras; @@ -663,11 +663,6 @@ impl<'a> Verifier<'a> { self.verify_block(inst, destination, errors)?; self.verify_jump_table(inst, table, errors)?; } - BranchTableBase { table, .. } - | BranchTableEntry { table, .. } - | IndirectJump { table, .. } => { - self.verify_jump_table(inst, table, errors)?; - } Call { func_ref, ref args, .. } => { @@ -1221,9 +1216,6 @@ impl<'a> Verifier<'a> { let _ = self.typecheck_return(inst, errors); let _ = self.typecheck_special(inst, ctrl_type, errors); - // Misuses of copy_nop instructions are fatal - self.typecheck_copy_nop(inst, errors)?; - Ok(()) } @@ -1555,36 +1547,6 @@ impl<'a> Verifier<'a> { Ok(()) } - fn typecheck_copy_nop( - &self, - inst: Inst, - errors: &mut VerifierErrors, - ) -> VerifierStepResult<()> { - if let InstructionData::Unary { - opcode: Opcode::CopyNop, - arg, - } = self.func.dfg[inst] - { - let dst_vals = self.func.dfg.inst_results(inst); - if dst_vals.len() != 1 { - return errors.fatal(( - inst, - self.context(inst), - "copy_nop must produce exactly one result", - )); - } - let dst_val = dst_vals[0]; - if self.func.dfg.value_type(dst_val) != self.func.dfg.value_type(arg) { - return errors.fatal(( - inst, - self.context(inst), - "copy_nop src and dst types must be the same", - )); - } - } - Ok(()) - } - fn cfg_integrity( &self, cfg: &ControlFlowGraph, @@ -1706,24 +1668,6 @@ impl<'a> Verifier<'a> { } } - fn verify_safepoint_unused( - &self, - inst: Inst, - errors: &mut VerifierErrors, - ) -> VerifierStepResult<()> { - if let Some(isa) = self.isa { - if !isa.flags().enable_safepoints() && self.func.dfg[inst].opcode() == Opcode::Safepoint - { - return errors.fatal(( - inst, - self.context(inst), - "safepoint instruction cannot be used when it is not enabled.", - )); - } - } - Ok(()) - } - fn typecheck_function_signature(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> { self.func .signature @@ -1787,7 +1731,6 @@ impl<'a> Verifier<'a> { for inst in self.func.layout.block_insts(block) { self.block_integrity(block, inst, errors)?; self.instruction_integrity(inst, errors)?; - self.verify_safepoint_unused(inst, errors)?; self.typecheck(inst, errors)?; self.immediate_constraints(inst, errors)?; } diff --git a/cranelift/codegen/src/write.rs b/cranelift/codegen/src/write.rs index 3c262a5f6d..1883251b90 100644 --- a/cranelift/codegen/src/write.rs +++ b/cranelift/codegen/src/write.rs @@ -462,11 +462,6 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt table, .. } => write!(w, " {}, {}, {}", arg, destination, table), - BranchTableBase { table, .. } => write!(w, " {}", table), - BranchTableEntry { - args, imm, table, .. - } => write!(w, " {}, {}, {}, {}", args[0], args[1], imm, table), - IndirectJump { arg, table, .. } => write!(w, " {}, {}", arg, table), Call { func_ref, ref args, .. } => write!(w, " {}({})", func_ref, DisplayValues(args.as_slice(pool))), diff --git a/cranelift/filetests/filetests/licm/jump-table-entry.clif b/cranelift/filetests/filetests/licm/jump-table-entry.clif deleted file mode 100644 index 66b8f9817c..0000000000 --- a/cranelift/filetests/filetests/licm/jump-table-entry.clif +++ /dev/null @@ -1,34 +0,0 @@ -test licm -target aarch64 -target x86_64 - -function %dont_hoist_jump_table_entry_during_licm() { - jt0 = jump_table [block1, block1] - -block0: - fallthrough block1 - -block1: ; the loop! - v2 = iconst.i32 42 - v3 = ifcmp_imm v2, 0 - brif uge v3, block1 - fallthrough block2 - -block2: - v1 = iconst.i64 -14 - v8 = ifcmp_imm v1, 2 - brif uge v8, block1 - jump block3 - -block3: - v5 = jump_table_base.i64 jt0 - v6 = jump_table_entry.i64 v1, v5, 4, jt0 - v7 = iadd v5, v6 - indirect_jump_table_br v7, jt0 -; check: block2: -; nextln: v8 = ifcmp_imm.i64 v1, 2 -; nextln: brif uge v8, block1 -; nextln: jump block3 -; check: block3: -; nextln: jump_table_entry.i64 -} diff --git a/cranelift/filetests/filetests/licm/rewrite-jump-table.clif b/cranelift/filetests/filetests/licm/rewrite-jump-table.clif index 860ff53f21..146628781c 100644 --- a/cranelift/filetests/filetests/licm/rewrite-jump-table.clif +++ b/cranelift/filetests/filetests/licm/rewrite-jump-table.clif @@ -6,10 +6,7 @@ function %rewrite_jump_table() { block0: v0 = iconst.i64 1 - v1 = jump_table_base.i64 jt0 - v2 = jump_table_entry.i64 v0, v1, 4, jt0 - v3 = iadd v1, v2 - indirect_jump_table_br v3, jt0 + br_table v0, block1, jt0 block1: return 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/filetests/filetests/simple_gvn/reject.clif b/cranelift/filetests/filetests/simple_gvn/reject.clif index bb01fe5839..3a5c1e0ee3 100644 --- a/cranelift/filetests/filetests/simple_gvn/reject.clif +++ b/cranelift/filetests/filetests/simple_gvn/reject.clif @@ -29,18 +29,3 @@ block0: ; check: v5 = trueif eq v4 return v6 } - -function %spill() -> i32 { -block0: - v0 = iconst.i32 7 - v1 = spill v0 - v2 = fill v1 - v3 = spill v0 - v4 = fill v1 - v5 = bor v2, v4 -; check: v1 = spill v0 -; check: v2 = fill v1 -; check: v3 = spill v0 -; check: v4 = fill v1 - return v5 -} diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index eb6adc770f..60ab37dc67 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)? @@ -448,15 +448,6 @@ where assign(Value::or(mask_a, mask_b)?) } Opcode::Copy => assign(arg(0)?), - Opcode::Spill => unimplemented!("Spill"), - Opcode::Fill => unimplemented!("Fill"), - Opcode::FillNop => assign(arg(0)?), - Opcode::CopyNop => unimplemented!("CopyNop"), - Opcode::AdjustSpDown => unimplemented!("AdjustSpDown"), - Opcode::AdjustSpUpImm => unimplemented!("AdjustSpUpImm"), - Opcode::AdjustSpDownImm => unimplemented!("AdjustSpDownImm"), - Opcode::IfcmpSp => unimplemented!("IfcmpSp"), - Opcode::Safepoint => unimplemented!("Safepoint"), Opcode::Icmp => assign(icmp( ctrl_ty, inst.cond_code().unwrap(), @@ -1026,10 +1017,6 @@ where assign(vectorizelanes(&new_vec, ctrl_ty)?) } Opcode::IaddPairwise => assign(binary_pairwise(arg(0)?, arg(1)?, ctrl_ty, Value::add)?), - - Opcode::JumpTableBase | Opcode::JumpTableEntry | Opcode::IndirectJumpTableBr => { - unimplemented!("Legacy instruction: {}", inst.opcode()) - } }) } diff --git a/cranelift/peepmatic/crates/fuzzing/src/interp.rs b/cranelift/peepmatic/crates/fuzzing/src/interp.rs index 3cd7aa9280..b2d5355fc4 100644 --- a/cranelift/peepmatic/crates/fuzzing/src/interp.rs +++ b/cranelift/peepmatic/crates/fuzzing/src/interp.rs @@ -324,15 +324,6 @@ mod tests { ); } - #[test] - fn regression_8() { - interp( - b" - (=> (adjust_sp_down $C) (adjust_sp_down_imm $C)) - ", - ); - } - #[test] fn regression_9() { interp( diff --git a/cranelift/peepmatic/crates/test-operator/src/lib.rs b/cranelift/peepmatic/crates/test-operator/src/lib.rs index cff0ad5876..b3dff3c9eb 100644 --- a/cranelift/peepmatic/crates/test-operator/src/lib.rs +++ b/cranelift/peepmatic/crates/test-operator/src/lib.rs @@ -6,14 +6,6 @@ peepmatic_traits::define_operator! { /// A `TOperator` type for use inside tests. TestOperator { - adjust_sp_down => AdjustSpDown { - parameters(iNN); - result(void); - } - adjust_sp_down_imm => AdjustSpDownImm { - immediates(iNN); - result(void); - } band => Band { parameters(iNN, iNN); result(iNN); diff --git a/cranelift/reader/src/parser.rs b/cranelift/reader/src/parser.rs index 46ac424957..d403d3534a 100644 --- a/cranelift/reader/src/parser.rs +++ b/cranelift/reader/src/parser.rs @@ -2676,34 +2676,6 @@ impl<'a> Parser<'a> { table, } } - InstructionFormat::BranchTableBase => { - let table = self.match_jt()?; - ctx.check_jt(table, self.loc)?; - InstructionData::BranchTableBase { opcode, table } - } - InstructionFormat::BranchTableEntry => { - let index = self.match_value("expected SSA value operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let base = self.match_value("expected SSA value operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let imm = self.match_uimm8("expected width")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let table = self.match_jt()?; - ctx.check_jt(table, self.loc)?; - InstructionData::BranchTableEntry { - opcode, - args: [index, base], - imm, - table, - } - } - InstructionFormat::IndirectJump => { - let arg = self.match_value("expected SSA value operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let table = self.match_jt()?; - ctx.check_jt(table, self.loc)?; - InstructionData::IndirectJump { opcode, arg, table } - } InstructionFormat::TernaryImm8 => { let lhs = self.match_value("expected SSA value first operand")?; self.match_token(Token::Comma, "expected ',' between operands")?;