Remove instructions used by old br_table legalization

This commit is contained in:
bjorn3
2021-10-12 14:18:52 +02:00
parent 783bb1f759
commit 5b24e117ee
14 changed files with 4 additions and 198 deletions

View File

@@ -70,8 +70,6 @@ pub(crate) struct InstructionContent {
pub is_terminator: bool, pub is_terminator: bool,
/// True for all branch or jump instructions. /// True for all branch or jump instructions.
pub is_branch: bool, pub is_branch: bool,
/// True for all indirect branch or jump instructions.',
pub is_indirect_branch: bool,
/// Is this a call instruction? /// Is this a call instruction?
pub is_call: bool, pub is_call: bool,
/// Is this a return instruction? /// Is this a return instruction?
@@ -145,7 +143,6 @@ pub(crate) struct InstructionBuilder {
// See Instruction comments for the meaning of these fields. // See Instruction comments for the meaning of these fields.
is_terminator: bool, is_terminator: bool,
is_branch: bool, is_branch: bool,
is_indirect_branch: bool,
is_call: bool, is_call: bool,
is_return: bool, is_return: bool,
is_ghost: bool, is_ghost: bool,
@@ -168,7 +165,6 @@ impl InstructionBuilder {
is_terminator: false, is_terminator: false,
is_branch: false, is_branch: false,
is_indirect_branch: false,
is_call: false, is_call: false,
is_return: false, is_return: false,
is_ghost: false, is_ghost: false,
@@ -210,12 +206,6 @@ impl InstructionBuilder {
self 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)] #[allow(clippy::wrong_self_convention)]
pub fn is_call(mut self, val: bool) -> Self { pub fn is_call(mut self, val: bool) -> Self {
self.is_call = val; self.is_call = val;
@@ -300,7 +290,6 @@ impl InstructionBuilder {
imm_opnums, imm_opnums,
is_terminator: self.is_terminator, is_terminator: self.is_terminator,
is_branch: self.is_branch, is_branch: self.is_branch,
is_indirect_branch: self.is_indirect_branch,
is_call: self.is_call, is_call: self.is_call,
is_return: self.is_return, is_return: self.is_return,
is_ghost: self.is_ghost, is_ghost: self.is_ghost,

View File

@@ -468,13 +468,6 @@ fn gen_opcodes(all_inst: &AllInstructions, fmt: &mut Formatter) {
"True for all branch or jump instructions.", "True for all branch or jump instructions.",
fmt, 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( gen_bool_accessor(
all_inst, all_inst,
|inst| inst.is_call, |inst| inst.is_call,

View File

@@ -13,8 +13,6 @@ pub(crate) struct Formats {
pub(crate) branch_icmp: Rc<InstructionFormat>, pub(crate) branch_icmp: Rc<InstructionFormat>,
pub(crate) branch_int: Rc<InstructionFormat>, pub(crate) branch_int: Rc<InstructionFormat>,
pub(crate) branch_table: 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: Rc<InstructionFormat>,
pub(crate) call_indirect: Rc<InstructionFormat>, pub(crate) call_indirect: Rc<InstructionFormat>,
pub(crate) cond_trap: 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) float_cond_trap: Rc<InstructionFormat>,
pub(crate) func_addr: Rc<InstructionFormat>, pub(crate) func_addr: Rc<InstructionFormat>,
pub(crate) heap_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: Rc<InstructionFormat>,
pub(crate) int_compare_imm: Rc<InstructionFormat>, pub(crate) int_compare_imm: Rc<InstructionFormat>,
pub(crate) int_cond: Rc<InstructionFormat>, pub(crate) int_cond: Rc<InstructionFormat>,
@@ -172,22 +169,6 @@ impl Formats {
.imm(&entities.jump_table) .imm(&entities.jump_table)
.build(), .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") call: Builder::new("Call")
.imm(&entities.func_ref) .imm(&entities.func_ref)
.varargs() .varargs()

View File

@@ -214,68 +214,6 @@ fn define_control_flow(
TypeSetBuilder::new().ints(32..64).refs(32..64).build(), 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( ig.push(
Inst::new( Inst::new(
"debugtrap", "debugtrap",

View File

@@ -229,7 +229,6 @@ impl InstructionData {
Self::BranchTable { Self::BranchTable {
table, destination, .. table, destination, ..
} => BranchInfo::Table(table, Some(destination)), } => BranchInfo::Table(table, Some(destination)),
Self::IndirectJump { table, .. } => BranchInfo::Table(table, None),
_ => { _ => {
debug_assert!(!self.opcode().is_branch()); debug_assert!(!self.opcode().is_branch());
BranchInfo::NotABranch BranchInfo::NotABranch
@@ -248,7 +247,7 @@ impl InstructionData {
| Self::BranchInt { destination, .. } | Self::BranchInt { destination, .. }
| Self::BranchFloat { destination, .. } | Self::BranchFloat { destination, .. }
| Self::BranchIcmp { destination, .. } => Some(destination), | Self::BranchIcmp { destination, .. } => Some(destination),
Self::BranchTable { .. } | Self::IndirectJump { .. } => None, Self::BranchTable { .. } => None,
_ => { _ => {
debug_assert!(!self.opcode().is_branch()); debug_assert!(!self.opcode().is_branch());
None None
@@ -282,7 +281,7 @@ impl InstructionData {
ref mut destination, ref mut destination,
.. ..
} => Some(destination), } => Some(destination),
Self::BranchTable { .. } | Self::IndirectJump { .. } => None, Self::BranchTable { .. } => None,
_ => { _ => {
debug_assert!(!self.opcode().is_branch()); debug_assert!(!self.opcode().is_branch());
None None
@@ -297,8 +296,7 @@ impl InstructionData {
&InstructionData::UnaryBool { imm, .. } => Some(DataValue::from(imm)), &InstructionData::UnaryBool { imm, .. } => Some(DataValue::from(imm)),
// 8-bit. // 8-bit.
&InstructionData::BinaryImm8 { imm, .. } &InstructionData::BinaryImm8 { imm, .. }
| &InstructionData::TernaryImm8 { imm, .. } | &InstructionData::TernaryImm8 { imm, .. } => Some(DataValue::from(imm as i8)), // Note the switch from unsigned to signed.
| &InstructionData::BranchTableEntry { imm, .. } => Some(DataValue::from(imm as i8)), // Note the switch from unsigned to signed.
// 32-bit // 32-bit
&InstructionData::UnaryIeee32 { imm, .. } => Some(DataValue::from(imm)), &InstructionData::UnaryIeee32 { imm, .. } => Some(DataValue::from(imm)),
&InstructionData::HeapAddr { imm, .. } => { &InstructionData::HeapAddr { imm, .. } => {

View File

@@ -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 => { Opcode::Debugtrap => {
ctx.emit(Inst::Brk); ctx.emit(Inst::Brk);
} }
@@ -2180,7 +2176,6 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
| Opcode::BrIcmp | Opcode::BrIcmp
| Opcode::Brif | Opcode::Brif
| Opcode::Brff | Opcode::Brff
| Opcode::IndirectJumpTableBr
| Opcode::BrTable => { | Opcode::BrTable => {
panic!("Branch opcode reached non-branch lowering logic!"); panic!("Branch opcode reached non-branch lowering logic!");
} }

View File

@@ -2915,14 +2915,10 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
| Opcode::BrIcmp | Opcode::BrIcmp
| Opcode::Brif | Opcode::Brif
| Opcode::Brff | Opcode::Brff
| Opcode::IndirectJumpTableBr
| Opcode::BrTable => { | Opcode::BrTable => {
panic!("Branch opcode reached non-branch lowering logic!"); panic!("Branch opcode reached non-branch lowering logic!");
} }
Opcode::JumpTableEntry | Opcode::JumpTableBase => {
panic!("Should not appear: we handle BrTable directly");
}
Opcode::Safepoint => { Opcode::Safepoint => {
panic!("safepoint instructions not used by new backend's safepoints!"); panic!("safepoint instructions not used by new backend's safepoints!");

View File

@@ -6874,10 +6874,6 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
panic!("Unused opcode should not be encountered."); 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 => { Opcode::Trapz | Opcode::Trapnz | Opcode::ResumableTrapnz => {
panic!("trapz / trapnz / resumable_trapnz should have been removed by legalization!"); 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::BrIcmp
| Opcode::Brif | Opcode::Brif
| Opcode::Brff | Opcode::Brff
| Opcode::IndirectJumpTableBr
| Opcode::BrTable => { | Opcode::BrTable => {
panic!("Branch opcode reached non-branch lowering logic!"); panic!("Branch opcode reached non-branch lowering logic!");
} }

View File

@@ -663,11 +663,6 @@ impl<'a> Verifier<'a> {
self.verify_block(inst, destination, errors)?; self.verify_block(inst, destination, errors)?;
self.verify_jump_table(inst, table, errors)?; self.verify_jump_table(inst, table, errors)?;
} }
BranchTableBase { table, .. }
| BranchTableEntry { table, .. }
| IndirectJump { table, .. } => {
self.verify_jump_table(inst, table, errors)?;
}
Call { Call {
func_ref, ref args, .. func_ref, ref args, ..
} => { } => {

View File

@@ -462,11 +462,6 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt
table, table,
.. ..
} => write!(w, " {}, {}, {}", arg, destination, 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 { Call {
func_ref, ref args, .. func_ref, ref args, ..
} => write!(w, " {}({})", func_ref, DisplayValues(args.as_slice(pool))), } => write!(w, " {}({})", func_ref, DisplayValues(args.as_slice(pool))),

View File

@@ -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
}

View File

@@ -6,10 +6,7 @@ function %rewrite_jump_table() {
block0: block0:
v0 = iconst.i64 1 v0 = iconst.i64 1
v1 = jump_table_base.i64 jt0 br_table v0, block1, jt0
v2 = jump_table_entry.i64 v0, v1, 4, jt0
v3 = iadd v1, v2
indirect_jump_table_br v3, jt0
block1: block1:
return return

View File

@@ -1026,10 +1026,6 @@ where
assign(vectorizelanes(&new_vec, ctrl_ty)?) assign(vectorizelanes(&new_vec, ctrl_ty)?)
} }
Opcode::IaddPairwise => assign(binary_pairwise(arg(0)?, arg(1)?, ctrl_ty, Value::add)?), Opcode::IaddPairwise => assign(binary_pairwise(arg(0)?, arg(1)?, ctrl_ty, Value::add)?),
Opcode::JumpTableBase | Opcode::JumpTableEntry | Opcode::IndirectJumpTableBr => {
unimplemented!("Legacy instruction: {}", inst.opcode())
}
}) })
} }

View File

@@ -2676,34 +2676,6 @@ impl<'a> Parser<'a> {
table, 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 => { InstructionFormat::TernaryImm8 => {
let lhs = self.match_value("expected SSA value first operand")?; let lhs = self.match_value("expected SSA value first operand")?;
self.match_token(Token::Comma, "expected ',' between operands")?; self.match_token(Token::Comma, "expected ',' between operands")?;