From 96b14ed8eb516efa7f165ec8f281dc55a3b74f03 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 31 Oct 2021 17:52:43 +0100 Subject: [PATCH] Match on InstructionData instead of Opcode This should be faster by avoiding matching on InstructionData to get the Opcode, then on Opcode and then finally on the InstructionData again to get the arguments --- cranelift/codegen/src/legalizer/mod.rs | 259 +++++++++++++++++-------- 1 file changed, 177 insertions(+), 82 deletions(-) diff --git a/cranelift/codegen/src/legalizer/mod.rs b/cranelift/codegen/src/legalizer/mod.rs index b09d1c601c..a9a8022d49 100644 --- a/cranelift/codegen/src/legalizer/mod.rs +++ b/cranelift/codegen/src/legalizer/mod.rs @@ -16,7 +16,7 @@ use crate::cursor::{Cursor, FuncCursor}; use crate::flowgraph::ControlFlowGraph; use crate::ir::types::I32; -use crate::ir::{self, InstBuilder, MemFlags}; +use crate::ir::{self, InstBuilder, InstructionData, MemFlags}; use crate::isa::TargetIsa; mod globalvalue; @@ -30,116 +30,211 @@ use self::table::expand_table_addr; /// Perform a simple legalization by expansion of the function, without /// platform-specific transforms. pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: &dyn TargetIsa) { - macro_rules! expand_imm_op { - ($pos:ident, $inst:ident: $from:ident => $to:ident) => {{ - let (arg, imm) = match $pos.func.dfg[$inst] { - ir::InstructionData::BinaryImm64 { - opcode: _, - arg, - imm, - } => (arg, imm), - _ => panic!( - concat!("Expected ", stringify!($from), ": {}"), - $pos.func.dfg.display_inst($inst) - ), - }; - let ty = $pos.func.dfg.value_type(arg); - let imm = $pos.ins().iconst(ty, imm); - $pos.func.dfg.replace($inst).$to(arg, imm); - }}; - - ($pos:ident, $inst:ident<$ty:ident>: $from:ident => $to:ident) => {{ - let (arg, imm) = match $pos.func.dfg[$inst] { - ir::InstructionData::BinaryImm64 { - opcode: _, - arg, - imm, - } => (arg, imm), - _ => panic!( - concat!("Expected ", stringify!($from), ": {}"), - $pos.func.dfg.display_inst($inst) - ), - }; - let imm = $pos.ins().iconst($ty, imm); - $pos.func.dfg.replace($inst).$to(arg, imm); - }}; - } - let mut pos = FuncCursor::new(func); let func_begin = pos.position(); pos.set_position(func_begin); while let Some(_block) = pos.next_block() { let mut prev_pos = pos.position(); while let Some(inst) = pos.next_inst() { - match pos.func.dfg[inst].opcode() { + match pos.func.dfg[inst] { // control flow - ir::Opcode::BrIcmp => expand_br_icmp(inst, &mut pos.func, cfg, isa), - ir::Opcode::Trapnz | ir::Opcode::Trapz | ir::Opcode::ResumableTrapnz => { + InstructionData::BranchIcmp { + opcode: ir::Opcode::BrIcmp, + .. + } => { + expand_br_icmp(inst, &mut pos.func, cfg, isa); + } + InstructionData::CondTrap { + opcode: ir::Opcode::Trapnz | ir::Opcode::Trapz | ir::Opcode::ResumableTrapnz, + .. + } => { expand_cond_trap(inst, &mut pos.func, cfg, isa); } // memory and constants - ir::Opcode::GlobalValue => expand_global_value(inst, &mut pos.func, cfg, isa), - ir::Opcode::HeapAddr => expand_heap_addr(inst, &mut pos.func, cfg, isa), - ir::Opcode::StackLoad => expand_stack_load(inst, &mut pos.func, cfg, isa), - ir::Opcode::StackStore => expand_stack_store(inst, &mut pos.func, cfg, isa), - ir::Opcode::TableAddr => expand_table_addr(inst, &mut pos.func, cfg, isa), + InstructionData::UnaryGlobalValue { + opcode: ir::Opcode::GlobalValue, + .. + } => expand_global_value(inst, &mut pos.func, cfg, isa), + InstructionData::HeapAddr { + opcode: ir::Opcode::HeapAddr, + .. + } => expand_heap_addr(inst, &mut pos.func, cfg, isa), + InstructionData::StackLoad { + opcode: ir::Opcode::StackLoad, + .. + } => expand_stack_load(inst, &mut pos.func, cfg, isa), + InstructionData::StackStore { + opcode: ir::Opcode::StackStore, + .. + } => expand_stack_store(inst, &mut pos.func, cfg, isa), + InstructionData::TableAddr { + opcode: ir::Opcode::TableAddr, + .. + } => expand_table_addr(inst, &mut pos.func, cfg, isa), // bitops - ir::Opcode::BandImm => expand_imm_op!(pos, inst: band_imm => band), - ir::Opcode::BorImm => expand_imm_op!(pos, inst: bor_imm => bor), - ir::Opcode::BxorImm => expand_imm_op!(pos, inst: bxor_imm => bxor), - ir::Opcode::IaddImm => expand_imm_op!(pos, inst: iadd_imm => iadd), + InstructionData::BinaryImm64 { + opcode: ir::Opcode::BandImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).band(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::BorImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).bor(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::BxorImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).bxor(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::IaddImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).iadd(arg, imm); + } // bitshifting - ir::Opcode::IshlImm => expand_imm_op!(pos, inst: ishl_imm => ishl), - ir::Opcode::RotlImm => expand_imm_op!(pos, inst: rotl_imm => rotl), - ir::Opcode::RotrImm => expand_imm_op!(pos, inst: rotr_imm => rotr), - ir::Opcode::SshrImm => expand_imm_op!(pos, inst: sshr_imm => sshr), - ir::Opcode::UshrImm => expand_imm_op!(pos, inst: ushr_imm => ushr), + InstructionData::BinaryImm64 { + opcode: ir::Opcode::IshlImm, + arg, + imm, + } => { + let imm = pos.ins().iconst(I32, imm); + pos.func.dfg.replace(inst).ishl(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::RotlImm, + arg, + imm, + } => { + let imm = pos.ins().iconst(I32, imm); + pos.func.dfg.replace(inst).rotl(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::RotrImm, + arg, + imm, + } => { + let imm = pos.ins().iconst(I32, imm); + pos.func.dfg.replace(inst).rotr(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::SshrImm, + arg, + imm, + } => { + let imm = pos.ins().iconst(I32, imm); + pos.func.dfg.replace(inst).sshr(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::UshrImm, + arg, + imm, + } => { + let imm = pos.ins().iconst(I32, imm); + pos.func.dfg.replace(inst).ushr(arg, imm); + } // math - ir::Opcode::IrsubImm => { - let (arg, imm) = match pos.func.dfg[inst] { - ir::InstructionData::BinaryImm64 { - opcode: _, - arg, - imm, - } => (arg, imm), - _ => panic!("Expected irsub_imm: {}", pos.func.dfg.display_inst(inst)), - }; + InstructionData::BinaryImm64 { + opcode: ir::Opcode::IrsubImm, + arg, + imm, + } => { let ty = pos.func.dfg.value_type(arg); let imm = pos.ins().iconst(ty, imm); pos.func.dfg.replace(inst).isub(imm, arg); // note: arg order reversed } - ir::Opcode::ImulImm => expand_imm_op!(pos, inst: imul_imm => imul), - ir::Opcode::SdivImm => expand_imm_op!(pos, inst: sdiv_imm => sdiv), - ir::Opcode::SremImm => expand_imm_op!(pos, inst: srem_imm => srem), - ir::Opcode::UdivImm => expand_imm_op!(pos, inst: udiv_imm => udiv), - ir::Opcode::UremImm => expand_imm_op!(pos, inst: urem_imm => urem), + InstructionData::BinaryImm64 { + opcode: ir::Opcode::ImulImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).imul(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::SdivImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).sdiv(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::SremImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).srem(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::UdivImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).udiv(arg, imm); + } + InstructionData::BinaryImm64 { + opcode: ir::Opcode::UremImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).urem(arg, imm); + } // comparisons - ir::Opcode::IfcmpImm => expand_imm_op!(pos, inst: ifcmp_imm => ifcmp), - ir::Opcode::IcmpImm => { - let (cc, x, y) = match pos.func.dfg[inst] { - ir::InstructionData::IntCompareImm { - opcode: _, - cond, - arg, - imm, - } => (cond, arg, imm), - _ => panic!("Expected ircmp_imm: {}", pos.func.dfg.display_inst(inst)), - }; - let ty = pos.func.dfg.value_type(x); - let y = pos.ins().iconst(ty, y); - pos.func.dfg.replace(inst).icmp(cc, x, y); + InstructionData::BinaryImm64 { + opcode: ir::Opcode::IfcmpImm, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).ifcmp(arg, imm); + } + InstructionData::IntCompareImm { + opcode: ir::Opcode::IcmpImm, + cond, + arg, + imm, + } => { + let ty = pos.func.dfg.value_type(arg); + let imm = pos.ins().iconst(ty, imm); + pos.func.dfg.replace(inst).icmp(cond, arg, imm); } _ => { prev_pos = pos.position(); continue; } - }; + } // Legalization implementations require fixpoint loop here. // TODO: fix this.