Remove instructions used by old br_table legalization
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -13,8 +13,6 @@ pub(crate) struct Formats {
|
||||
pub(crate) branch_icmp: Rc<InstructionFormat>,
|
||||
pub(crate) branch_int: Rc<InstructionFormat>,
|
||||
pub(crate) branch_table: Rc<InstructionFormat>,
|
||||
pub(crate) branch_table_base: Rc<InstructionFormat>,
|
||||
pub(crate) branch_table_entry: Rc<InstructionFormat>,
|
||||
pub(crate) call: Rc<InstructionFormat>,
|
||||
pub(crate) call_indirect: Rc<InstructionFormat>,
|
||||
pub(crate) cond_trap: Rc<InstructionFormat>,
|
||||
@@ -23,7 +21,6 @@ pub(crate) struct Formats {
|
||||
pub(crate) float_cond_trap: Rc<InstructionFormat>,
|
||||
pub(crate) func_addr: Rc<InstructionFormat>,
|
||||
pub(crate) heap_addr: Rc<InstructionFormat>,
|
||||
pub(crate) indirect_jump: Rc<InstructionFormat>,
|
||||
pub(crate) int_compare: Rc<InstructionFormat>,
|
||||
pub(crate) int_compare_imm: Rc<InstructionFormat>,
|
||||
pub(crate) int_cond: Rc<InstructionFormat>,
|
||||
@@ -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()
|
||||
|
||||
@@ -214,68 +214,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",
|
||||
|
||||
@@ -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, .. } => {
|
||||
|
||||
@@ -2029,10 +2029,6 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
|
||||
Opcode::JumpTableEntry | Opcode::JumpTableBase => {
|
||||
panic!("Should not appear: we handle BrTable directly");
|
||||
}
|
||||
|
||||
Opcode::Debugtrap => {
|
||||
ctx.emit(Inst::Brk);
|
||||
}
|
||||
@@ -2180,7 +2176,6 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
| Opcode::BrIcmp
|
||||
| Opcode::Brif
|
||||
| Opcode::Brff
|
||||
| Opcode::IndirectJumpTableBr
|
||||
| Opcode::BrTable => {
|
||||
panic!("Branch opcode reached non-branch lowering logic!");
|
||||
}
|
||||
|
||||
@@ -2915,14 +2915,10 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
| 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!");
|
||||
|
||||
@@ -6874,10 +6874,6 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
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!");
|
||||
}
|
||||
@@ -6889,7 +6885,6 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
| Opcode::BrIcmp
|
||||
| Opcode::Brif
|
||||
| Opcode::Brff
|
||||
| Opcode::IndirectJumpTableBr
|
||||
| Opcode::BrTable => {
|
||||
panic!("Branch opcode reached non-branch lowering logic!");
|
||||
}
|
||||
|
||||
@@ -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, ..
|
||||
} => {
|
||||
|
||||
@@ -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))),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -1026,10 +1026,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())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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")?;
|
||||
|
||||
Reference in New Issue
Block a user