Remove LoadSplat opcode, in preparation for pattern-matching Load+Splat.
This was added as an incremental step to improve AArch64 code quality in PR #2278. At the time, we did not have a way to pattern-match the load + splat opcode sequence that the relevant Wasm opcodes lowered to. However, now with PR #2366, we can merge effectful instructions such as loads into other ops, and so we can do this pattern matching directly. The pattern-matching update will come in a subsequent commit.
This commit is contained in:
@@ -396,7 +396,6 @@ fn define_simd(
|
|||||||
let insertlane = insts.by_name("insertlane");
|
let insertlane = insts.by_name("insertlane");
|
||||||
let ishl = insts.by_name("ishl");
|
let ishl = insts.by_name("ishl");
|
||||||
let ishl_imm = insts.by_name("ishl_imm");
|
let ishl_imm = insts.by_name("ishl_imm");
|
||||||
let load_splat = insts.by_name("load_splat");
|
|
||||||
let raw_bitcast = insts.by_name("raw_bitcast");
|
let raw_bitcast = insts.by_name("raw_bitcast");
|
||||||
let scalar_to_vector = insts.by_name("scalar_to_vector");
|
let scalar_to_vector = insts.by_name("scalar_to_vector");
|
||||||
let splat = insts.by_name("splat");
|
let splat = insts.by_name("splat");
|
||||||
@@ -821,7 +820,6 @@ fn define_simd(
|
|||||||
narrow.custom_legalize(fcvt_to_sint_sat, "expand_fcvt_to_sint_sat_vector");
|
narrow.custom_legalize(fcvt_to_sint_sat, "expand_fcvt_to_sint_sat_vector");
|
||||||
narrow.custom_legalize(fmin, "expand_minmax_vector");
|
narrow.custom_legalize(fmin, "expand_minmax_vector");
|
||||||
narrow.custom_legalize(fmax, "expand_minmax_vector");
|
narrow.custom_legalize(fmax, "expand_minmax_vector");
|
||||||
narrow.custom_legalize(load_splat, "expand_load_splat");
|
|
||||||
|
|
||||||
narrow_avx.custom_legalize(imul, "convert_i64x2_imul");
|
narrow_avx.custom_legalize(imul, "convert_i64x2_imul");
|
||||||
narrow_avx.custom_legalize(fcvt_from_uint, "expand_fcvt_from_uint_vector");
|
narrow_avx.custom_legalize(fcvt_from_uint, "expand_fcvt_from_uint_vector");
|
||||||
|
|||||||
@@ -4491,24 +4491,5 @@ pub(crate) fn define(
|
|||||||
.other_side_effects(true),
|
.other_side_effects(true),
|
||||||
);
|
);
|
||||||
|
|
||||||
let Offset = &Operand::new("Offset", &imm.offset32).with_doc("Byte offset from base address");
|
|
||||||
let a = &Operand::new("a", TxN);
|
|
||||||
|
|
||||||
ig.push(
|
|
||||||
Inst::new(
|
|
||||||
"load_splat",
|
|
||||||
r#"
|
|
||||||
Load an element from memory at ``p + Offset`` and return a vector
|
|
||||||
whose lanes are all set to that element.
|
|
||||||
|
|
||||||
This is equivalent to ``load`` followed by ``splat``.
|
|
||||||
"#,
|
|
||||||
&formats.load,
|
|
||||||
)
|
|
||||||
.operands_in(vec![MemFlags, p, Offset])
|
|
||||||
.operands_out(vec![a])
|
|
||||||
.can_load(true),
|
|
||||||
);
|
|
||||||
|
|
||||||
ig.build()
|
ig.build()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1219,6 +1219,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
Opcode::LoadSplat => {
|
Opcode::LoadSplat => {
|
||||||
let off = ctx.data(insn).load_store_offset().unwrap();
|
let off = ctx.data(insn).load_store_offset().unwrap();
|
||||||
let ty = ty.unwrap();
|
let ty = ty.unwrap();
|
||||||
@@ -1234,6 +1235,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
size,
|
size,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
Opcode::Store
|
Opcode::Store
|
||||||
| Opcode::Istore8
|
| Opcode::Istore8
|
||||||
|
|||||||
@@ -1892,31 +1892,3 @@ fn expand_tls_value(
|
|||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_load_splat(
|
|
||||||
inst: ir::Inst,
|
|
||||||
func: &mut ir::Function,
|
|
||||||
_cfg: &mut ControlFlowGraph,
|
|
||||||
_isa: &dyn TargetIsa,
|
|
||||||
) {
|
|
||||||
let mut pos = FuncCursor::new(func).at_inst(inst);
|
|
||||||
|
|
||||||
pos.use_srcloc(inst);
|
|
||||||
|
|
||||||
let (ptr, offset, flags) = match pos.func.dfg[inst] {
|
|
||||||
ir::InstructionData::Load {
|
|
||||||
opcode: ir::Opcode::LoadSplat,
|
|
||||||
arg,
|
|
||||||
offset,
|
|
||||||
flags,
|
|
||||||
} => (arg, offset, flags),
|
|
||||||
_ => panic!(
|
|
||||||
"Expected load_splat: {}",
|
|
||||||
pos.func.dfg.display_inst(inst, None)
|
|
||||||
),
|
|
||||||
};
|
|
||||||
let ty = pos.func.dfg.ctrl_typevar(inst);
|
|
||||||
let load = pos.ins().load(ty.lane_type(), flags, ptr, offset);
|
|
||||||
|
|
||||||
pos.func.dfg.replace(inst).splat(ty, load);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -545,7 +545,6 @@ where
|
|||||||
Opcode::Shuffle => unimplemented!("Shuffle"),
|
Opcode::Shuffle => unimplemented!("Shuffle"),
|
||||||
Opcode::Swizzle => unimplemented!("Swizzle"),
|
Opcode::Swizzle => unimplemented!("Swizzle"),
|
||||||
Opcode::Splat => unimplemented!("Splat"),
|
Opcode::Splat => unimplemented!("Splat"),
|
||||||
Opcode::LoadSplat => unimplemented!("LoadSplat"),
|
|
||||||
Opcode::Insertlane => unimplemented!("Insertlane"),
|
Opcode::Insertlane => unimplemented!("Insertlane"),
|
||||||
Opcode::Extractlane => unimplemented!("Extractlane"),
|
Opcode::Extractlane => unimplemented!("Extractlane"),
|
||||||
Opcode::VhighBits => unimplemented!("VhighBits"),
|
Opcode::VhighBits => unimplemented!("VhighBits"),
|
||||||
|
|||||||
@@ -1414,17 +1414,16 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
| Operator::V128Load16Splat { memarg }
|
| Operator::V128Load16Splat { memarg }
|
||||||
| Operator::V128Load32Splat { memarg }
|
| Operator::V128Load32Splat { memarg }
|
||||||
| Operator::V128Load64Splat { memarg } => {
|
| Operator::V128Load64Splat { memarg } => {
|
||||||
let opcode = ir::Opcode::LoadSplat;
|
translate_load(
|
||||||
let result_ty = type_of(op);
|
|
||||||
let (flags, base, offset) = prepare_load(
|
|
||||||
memarg,
|
memarg,
|
||||||
mem_op_size(opcode, result_ty.lane_type()),
|
ir::Opcode::Load,
|
||||||
|
type_of(op).lane_type(),
|
||||||
builder,
|
builder,
|
||||||
state,
|
state,
|
||||||
environ,
|
environ,
|
||||||
)?;
|
)?;
|
||||||
let (load, dfg) = builder.ins().Load(opcode, result_ty, flags, offset, base);
|
let splatted = builder.ins().splat(type_of(op), state.pop1());
|
||||||
state.push1(dfg.first_result(load))
|
state.push1(splatted)
|
||||||
}
|
}
|
||||||
Operator::V128Load32Zero { memarg } | Operator::V128Load64Zero { memarg } => {
|
Operator::V128Load32Zero { memarg } | Operator::V128Load64Zero { memarg } => {
|
||||||
translate_load(
|
translate_load(
|
||||||
@@ -2103,7 +2102,7 @@ fn mem_op_size(opcode: ir::Opcode, ty: Type) -> u32 {
|
|||||||
ir::Opcode::Istore8 | ir::Opcode::Sload8 | ir::Opcode::Uload8 => 1,
|
ir::Opcode::Istore8 | ir::Opcode::Sload8 | ir::Opcode::Uload8 => 1,
|
||||||
ir::Opcode::Istore16 | ir::Opcode::Sload16 | ir::Opcode::Uload16 => 2,
|
ir::Opcode::Istore16 | ir::Opcode::Sload16 | ir::Opcode::Uload16 => 2,
|
||||||
ir::Opcode::Istore32 | ir::Opcode::Sload32 | ir::Opcode::Uload32 => 4,
|
ir::Opcode::Istore32 | ir::Opcode::Sload32 | ir::Opcode::Uload32 => 4,
|
||||||
ir::Opcode::Store | ir::Opcode::Load | ir::Opcode::LoadSplat => ty.bytes(),
|
ir::Opcode::Store | ir::Opcode::Load => ty.bytes(),
|
||||||
_ => panic!("unknown size of mem op for {:?}", opcode),
|
_ => panic!("unknown size of mem op for {:?}", opcode),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user