Cranelift: Remove the LowerCtx trait (#4697)
The trait had only one implementation: the `Lower` struct. It is easier to just use that directly, and not introduce unnecessary layers of generics and abstractions. Once upon a time, there was hope that we would have other implementations of the `LowerCtx` trait, that did things like lower CLIF to SMTLIB for verification. However, this is not practical these days given the way that the trait has evolved over time, and our verification efforts are focused on ISLE now anyways, and we're actually making some progress on that front (much more than anyone ever did on a second `LowerCtx` trait implementation!)
This commit is contained in:
@@ -81,23 +81,20 @@ impl ResultRSEImm12 {
|
||||
// Lowering: convert instruction inputs to forms that we can use.
|
||||
|
||||
/// Lower an instruction input to a 64-bit constant, if possible.
|
||||
pub(crate) fn input_to_const<C: LowerCtx<I = Inst>>(ctx: &mut C, input: InsnInput) -> Option<u64> {
|
||||
pub(crate) fn input_to_const(ctx: &mut Lower<Inst>, input: InsnInput) -> Option<u64> {
|
||||
let input = ctx.get_input_as_source_or_const(input.insn, input.input);
|
||||
input.constant
|
||||
}
|
||||
|
||||
/// Lower an instruction input to a constant register-shift amount, if possible.
|
||||
pub(crate) fn input_to_shiftimm<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn input_to_shiftimm(
|
||||
ctx: &mut Lower<Inst>,
|
||||
input: InsnInput,
|
||||
) -> Option<ShiftOpShiftImm> {
|
||||
input_to_const(ctx, input).and_then(ShiftOpShiftImm::maybe_from_shift)
|
||||
}
|
||||
|
||||
pub(crate) fn const_param_to_u128<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
inst: IRInst,
|
||||
) -> Option<u128> {
|
||||
pub(crate) fn const_param_to_u128(ctx: &mut Lower<Inst>, inst: IRInst) -> Option<u128> {
|
||||
match ctx.get_immediate(inst) {
|
||||
Some(DataValue::V128(bytes)) => Some(u128::from_le_bytes(bytes)),
|
||||
_ => None,
|
||||
@@ -139,7 +136,7 @@ impl NarrowValueMode {
|
||||
|
||||
/// Emits instruction(s) to generate the given constant value into newly-allocated
|
||||
/// temporary registers, returning these registers.
|
||||
fn generate_constant<C: LowerCtx<I = Inst>>(ctx: &mut C, ty: Type, c: u128) -> ValueRegs<Reg> {
|
||||
fn generate_constant(ctx: &mut Lower<Inst>, ty: Type, c: u128) -> ValueRegs<Reg> {
|
||||
let from_bits = ty_bits(ty);
|
||||
let masked = if from_bits < 128 {
|
||||
c & ((1u128 << from_bits) - 1)
|
||||
@@ -160,8 +157,8 @@ fn generate_constant<C: LowerCtx<I = Inst>>(ctx: &mut C, ty: Type, c: u128) -> V
|
||||
|
||||
/// Extends a register according to `narrow_mode`.
|
||||
/// If extended, the value is always extended to 64 bits, for simplicity.
|
||||
fn extend_reg<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
fn extend_reg(
|
||||
ctx: &mut Lower<Inst>,
|
||||
ty: Type,
|
||||
in_reg: Reg,
|
||||
is_const: bool,
|
||||
@@ -232,10 +229,7 @@ fn extend_reg<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
|
||||
/// Lowers an instruction input to multiple regs
|
||||
fn lower_value_to_regs<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
value: Value,
|
||||
) -> (ValueRegs<Reg>, Type, bool) {
|
||||
fn lower_value_to_regs(ctx: &mut Lower<Inst>, value: Value) -> (ValueRegs<Reg>, Type, bool) {
|
||||
trace!("lower_value_to_regs: value {:?}", value);
|
||||
let ty = ctx.value_ty(value);
|
||||
let inputs = ctx.get_value_as_source_or_const(value);
|
||||
@@ -256,8 +250,8 @@ fn lower_value_to_regs<C: LowerCtx<I = Inst>>(
|
||||
/// The given register will be extended appropriately, according to
|
||||
/// `narrow_mode` and the input's type. If extended, the value is
|
||||
/// always extended to 64 bits, for simplicity.
|
||||
pub(crate) fn put_input_in_reg<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn put_input_in_reg(
|
||||
ctx: &mut Lower<Inst>,
|
||||
input: InsnInput,
|
||||
narrow_mode: NarrowValueMode,
|
||||
) -> Reg {
|
||||
@@ -266,11 +260,7 @@ pub(crate) fn put_input_in_reg<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
|
||||
/// Like above, only for values
|
||||
fn put_value_in_reg<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
value: Value,
|
||||
narrow_mode: NarrowValueMode,
|
||||
) -> Reg {
|
||||
fn put_value_in_reg(ctx: &mut Lower<Inst>, value: Value, narrow_mode: NarrowValueMode) -> Reg {
|
||||
let (in_regs, ty, is_const) = lower_value_to_regs(ctx, value);
|
||||
let reg = in_regs
|
||||
.only_reg()
|
||||
@@ -280,10 +270,7 @@ fn put_value_in_reg<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
|
||||
/// Lower an instruction input to multiple regs
|
||||
pub(crate) fn put_input_in_regs<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
input: InsnInput,
|
||||
) -> ValueRegs<Reg> {
|
||||
pub(crate) fn put_input_in_regs(ctx: &mut Lower<Inst>, input: InsnInput) -> ValueRegs<Reg> {
|
||||
let value = ctx.input_as_value(input.insn, input.input);
|
||||
let (in_regs, _, _) = lower_value_to_regs(ctx, value);
|
||||
in_regs
|
||||
@@ -300,8 +287,8 @@ pub(crate) fn put_input_in_regs<C: LowerCtx<I = Inst>>(
|
||||
/// divide or a right-shift or a compare-to-zero), `narrow_mode` should be
|
||||
/// set to `ZeroExtend` or `SignExtend` as appropriate, and the resulting
|
||||
/// register will be provided the extended value.
|
||||
fn put_input_in_rs<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
fn put_input_in_rs(
|
||||
ctx: &mut Lower<Inst>,
|
||||
input: InsnInput,
|
||||
narrow_mode: NarrowValueMode,
|
||||
) -> ResultRS {
|
||||
@@ -334,8 +321,8 @@ fn put_input_in_rs<C: LowerCtx<I = Inst>>(
|
||||
/// vreg into which the source instruction will generate its value.
|
||||
///
|
||||
/// See note on `put_input_in_rs` for a description of `narrow_mode`.
|
||||
fn put_input_in_rse<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
fn put_input_in_rse(
|
||||
ctx: &mut Lower<Inst>,
|
||||
input: InsnInput,
|
||||
narrow_mode: NarrowValueMode,
|
||||
) -> ResultRSE {
|
||||
@@ -348,8 +335,8 @@ fn put_input_in_rse<C: LowerCtx<I = Inst>>(
|
||||
ResultRSE::from_rs(put_input_in_rs(ctx, input, narrow_mode))
|
||||
}
|
||||
|
||||
fn get_as_extended_value<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
fn get_as_extended_value(
|
||||
ctx: &mut Lower<Inst>,
|
||||
val: Value,
|
||||
narrow_mode: NarrowValueMode,
|
||||
) -> Option<(Value, ExtendOp)> {
|
||||
@@ -427,8 +414,8 @@ fn get_as_extended_value<C: LowerCtx<I = Inst>>(
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn put_input_in_rse_imm12<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn put_input_in_rse_imm12(
|
||||
ctx: &mut Lower<Inst>,
|
||||
input: InsnInput,
|
||||
narrow_mode: NarrowValueMode,
|
||||
) -> ResultRSEImm12 {
|
||||
@@ -526,8 +513,8 @@ type AddressAddend64List = SmallVec<[Reg; 4]>;
|
||||
/// additional masking of high-order bits, which is too complex. So, in essence, we
|
||||
/// descend any number of adds from the roots, collecting all 64-bit address addends;
|
||||
/// then possibly support extensions at these leaves.
|
||||
fn collect_address_addends<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
fn collect_address_addends(
|
||||
ctx: &mut Lower<Inst>,
|
||||
roots: &[InsnInput],
|
||||
) -> (AddressAddend64List, AddressAddend32List, i64) {
|
||||
let mut result32: AddressAddend32List = SmallVec::new();
|
||||
@@ -597,8 +584,8 @@ fn collect_address_addends<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
|
||||
/// Lower the address of a pair load or store.
|
||||
pub(crate) fn lower_pair_address<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn lower_pair_address(
|
||||
ctx: &mut Lower<Inst>,
|
||||
roots: &[InsnInput],
|
||||
offset: i32,
|
||||
) -> PairAMode {
|
||||
@@ -654,8 +641,8 @@ pub(crate) fn lower_pair_address<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
|
||||
/// Lower the address of a load or store.
|
||||
pub(crate) fn lower_address<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn lower_address(
|
||||
ctx: &mut Lower<Inst>,
|
||||
elem_ty: Type,
|
||||
roots: &[InsnInput],
|
||||
offset: i32,
|
||||
@@ -764,8 +751,8 @@ pub(crate) fn lower_address<C: LowerCtx<I = Inst>>(
|
||||
memarg
|
||||
}
|
||||
|
||||
fn lower_add_addends<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
fn lower_add_addends(
|
||||
ctx: &mut Lower<Inst>,
|
||||
rd: Writable<Reg>,
|
||||
addends64: AddressAddend64List,
|
||||
addends32: AddressAddend32List,
|
||||
@@ -803,7 +790,7 @@ fn lower_add_addends<C: LowerCtx<I = Inst>>(
|
||||
|
||||
/// Adds into `rd` a signed imm pattern matching the best instruction for it.
|
||||
// TODO: This function is duplicated in ctx.gen_add_imm
|
||||
fn lower_add_immediate<C: LowerCtx<I = Inst>>(ctx: &mut C, dst: Writable<Reg>, src: Reg, imm: i64) {
|
||||
fn lower_add_immediate(ctx: &mut Lower<Inst>, dst: Writable<Reg>, src: Reg, imm: i64) {
|
||||
// If we can fit offset or -offset in an imm12, use an add-imm
|
||||
// Otherwise, lower the constant first then add.
|
||||
if let Some(imm12) = Imm12::maybe_from_u64(imm as u64) {
|
||||
@@ -834,21 +821,13 @@ fn lower_add_immediate<C: LowerCtx<I = Inst>>(ctx: &mut C, dst: Writable<Reg>, s
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lower_constant_u64<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
rd: Writable<Reg>,
|
||||
value: u64,
|
||||
) {
|
||||
pub(crate) fn lower_constant_u64(ctx: &mut Lower<Inst>, rd: Writable<Reg>, value: u64) {
|
||||
for inst in Inst::load_constant(rd, value) {
|
||||
ctx.emit(inst);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lower_constant_f32<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
rd: Writable<Reg>,
|
||||
value: f32,
|
||||
) {
|
||||
pub(crate) fn lower_constant_f32(ctx: &mut Lower<Inst>, rd: Writable<Reg>, value: f32) {
|
||||
let alloc_tmp = |ty| ctx.alloc_tmp(ty).only_reg().unwrap();
|
||||
|
||||
for inst in Inst::load_fp_constant32(rd, value.to_bits(), alloc_tmp) {
|
||||
@@ -856,11 +835,7 @@ pub(crate) fn lower_constant_f32<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lower_constant_f64<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
rd: Writable<Reg>,
|
||||
value: f64,
|
||||
) {
|
||||
pub(crate) fn lower_constant_f64(ctx: &mut Lower<Inst>, rd: Writable<Reg>, value: f64) {
|
||||
let alloc_tmp = |ty| ctx.alloc_tmp(ty).only_reg().unwrap();
|
||||
|
||||
for inst in Inst::load_fp_constant64(rd, value.to_bits(), alloc_tmp) {
|
||||
@@ -868,11 +843,7 @@ pub(crate) fn lower_constant_f64<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lower_constant_f128<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
rd: Writable<Reg>,
|
||||
value: u128,
|
||||
) {
|
||||
pub(crate) fn lower_constant_f128(ctx: &mut Lower<Inst>, rd: Writable<Reg>, value: u128) {
|
||||
if value == 0 {
|
||||
// Fast-track a common case. The general case, viz, calling `Inst::load_fp_constant128`,
|
||||
// is potentially expensive.
|
||||
@@ -890,8 +861,8 @@ pub(crate) fn lower_constant_f128<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lower_splat_const<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn lower_splat_const(
|
||||
ctx: &mut Lower<Inst>,
|
||||
rd: Writable<Reg>,
|
||||
value: u64,
|
||||
size: VectorSize,
|
||||
@@ -974,8 +945,8 @@ pub(crate) fn lower_fp_condcode(cc: FloatCC) -> Cond {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lower_vector_compare<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn lower_vector_compare(
|
||||
ctx: &mut Lower<Inst>,
|
||||
rd: Writable<Reg>,
|
||||
mut rn: Reg,
|
||||
mut rm: Reg,
|
||||
@@ -1114,8 +1085,8 @@ pub(crate) fn choose_32_64<T: Copy>(ty: Type, op32: T, op64: T) -> T {
|
||||
}
|
||||
|
||||
/// Checks for an instance of `op` feeding the given input.
|
||||
pub(crate) fn maybe_input_insn<C: LowerCtx<I = Inst>>(
|
||||
c: &mut C,
|
||||
pub(crate) fn maybe_input_insn(
|
||||
c: &mut Lower<Inst>,
|
||||
input: InsnInput,
|
||||
op: Opcode,
|
||||
) -> Option<IRInst> {
|
||||
@@ -1137,8 +1108,8 @@ pub(crate) fn maybe_input_insn<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
|
||||
/// Checks for an instance of any one of `ops` feeding the given input.
|
||||
pub(crate) fn maybe_input_insn_multi<C: LowerCtx<I = Inst>>(
|
||||
c: &mut C,
|
||||
pub(crate) fn maybe_input_insn_multi(
|
||||
c: &mut Lower<Inst>,
|
||||
input: InsnInput,
|
||||
ops: &[Opcode],
|
||||
) -> Option<(Opcode, IRInst)> {
|
||||
@@ -1155,8 +1126,8 @@ pub(crate) fn maybe_input_insn_multi<C: LowerCtx<I = Inst>>(
|
||||
///
|
||||
/// FIXME cfallin 2020-03-30: this is really ugly. Factor out tree-matching stuff and make it
|
||||
/// a bit more generic.
|
||||
pub(crate) fn maybe_input_insn_via_conv<C: LowerCtx<I = Inst>>(
|
||||
c: &mut C,
|
||||
pub(crate) fn maybe_input_insn_via_conv(
|
||||
c: &mut Lower<Inst>,
|
||||
input: InsnInput,
|
||||
op: Opcode,
|
||||
conv: Opcode,
|
||||
@@ -1222,8 +1193,8 @@ impl IcmpResult {
|
||||
///
|
||||
/// We can lower into the status flags, or materialize the result into a register
|
||||
/// This is controlled by the `output` parameter.
|
||||
pub(crate) fn lower_icmp<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn lower_icmp(
|
||||
ctx: &mut Lower<Inst>,
|
||||
insn: IRInst,
|
||||
condcode: IntCC,
|
||||
output: IcmpOutput,
|
||||
@@ -1478,7 +1449,7 @@ pub(crate) fn lower_icmp<C: LowerCtx<I = Inst>>(
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn lower_fcmp_or_ffcmp_to_flags<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRInst) {
|
||||
pub(crate) fn lower_fcmp_or_ffcmp_to_flags(ctx: &mut Lower<Inst>, insn: IRInst) {
|
||||
let ty = ctx.input_ty(insn, 0);
|
||||
let inputs = [InsnInput { insn, input: 0 }, InsnInput { insn, input: 1 }];
|
||||
let rn = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
@@ -1493,8 +1464,8 @@ pub(crate) fn lower_fcmp_or_ffcmp_to_flags<C: LowerCtx<I = Inst>>(ctx: &mut C, i
|
||||
/// Materialize a boolean value into a register from the flags
|
||||
/// (e.g set by a comparison).
|
||||
/// A 0 / -1 (all-ones) result as expected for bool operations.
|
||||
pub(crate) fn materialize_bool_result<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn materialize_bool_result(
|
||||
ctx: &mut Lower<Inst>,
|
||||
insn: IRInst,
|
||||
rd: Writable<Reg>,
|
||||
cond: Cond,
|
||||
@@ -1524,10 +1495,9 @@ fn load_op_to_ty(op: Opcode) -> Option<Type> {
|
||||
/// Helper to lower a load instruction; this is used in several places, because
|
||||
/// a load can sometimes be merged into another operation.
|
||||
pub(crate) fn lower_load<
|
||||
C: LowerCtx<I = Inst>,
|
||||
F: FnMut(&mut C, ValueRegs<Writable<Reg>>, Type, AMode) -> CodegenResult<()>,
|
||||
F: FnMut(&mut Lower<Inst>, ValueRegs<Writable<Reg>>, Type, AMode) -> CodegenResult<()>,
|
||||
>(
|
||||
ctx: &mut C,
|
||||
ctx: &mut Lower<Inst>,
|
||||
ir_inst: IRInst,
|
||||
inputs: &[InsnInput],
|
||||
output: InsnOutput,
|
||||
@@ -1550,13 +1520,13 @@ pub(crate) fn lower_load<
|
||||
impl LowerBackend for AArch64Backend {
|
||||
type MInst = Inst;
|
||||
|
||||
fn lower<C: LowerCtx<I = Inst>>(&self, ctx: &mut C, ir_inst: IRInst) -> CodegenResult<()> {
|
||||
fn lower(&self, ctx: &mut Lower<Inst>, ir_inst: IRInst) -> CodegenResult<()> {
|
||||
lower_inst::lower_insn_to_regs(ctx, ir_inst, &self.triple, &self.flags, &self.isa_flags)
|
||||
}
|
||||
|
||||
fn lower_branch_group<C: LowerCtx<I = Inst>>(
|
||||
fn lower_branch_group(
|
||||
&self,
|
||||
ctx: &mut C,
|
||||
ctx: &mut Lower<Inst>,
|
||||
branches: &[IRInst],
|
||||
targets: &[MachLabel],
|
||||
) -> CodegenResult<()> {
|
||||
|
||||
@@ -24,7 +24,7 @@ use crate::{
|
||||
isa::aarch64::inst::args::{ShiftOp, ShiftOpShiftImm},
|
||||
isa::aarch64::lower::{writable_vreg, writable_xreg, xreg},
|
||||
isa::unwind::UnwindInst,
|
||||
machinst::{ty_bits, InsnOutput, LowerCtx, VCodeConstant, VCodeConstantData},
|
||||
machinst::{ty_bits, InsnOutput, Lower, VCodeConstant, VCodeConstantData},
|
||||
};
|
||||
use regalloc2::PReg;
|
||||
use std::boxed::Box;
|
||||
@@ -39,17 +39,14 @@ type BoxJTSequenceInfo = Box<JTSequenceInfo>;
|
||||
type BoxExternalName = Box<ExternalName>;
|
||||
|
||||
/// The main entry point for lowering with ISLE.
|
||||
pub(crate) fn lower<C>(
|
||||
lower_ctx: &mut C,
|
||||
pub(crate) fn lower(
|
||||
lower_ctx: &mut Lower<MInst>,
|
||||
triple: &Triple,
|
||||
flags: &Flags,
|
||||
isa_flags: &IsaFlags,
|
||||
outputs: &[InsnOutput],
|
||||
inst: Inst,
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
) -> Result<(), ()> {
|
||||
lower_common(
|
||||
lower_ctx,
|
||||
triple,
|
||||
@@ -71,10 +68,7 @@ pub struct SinkableAtomicLoad {
|
||||
atomic_addr: Value,
|
||||
}
|
||||
|
||||
impl<C> generated_code::Context for IsleContext<'_, C, Flags, IsaFlags, 6>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
|
||||
isle_prelude_methods!();
|
||||
|
||||
fn use_lse(&mut self, _: Inst) -> Option<()> {
|
||||
|
||||
@@ -19,8 +19,8 @@ use core::convert::TryFrom;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
/// Actually codegen an instruction's results into registers.
|
||||
pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn lower_insn_to_regs(
|
||||
ctx: &mut Lower<Inst>,
|
||||
insn: IRInst,
|
||||
triple: &Triple,
|
||||
flags: &Flags,
|
||||
@@ -39,7 +39,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let implemented_in_isle = |ctx: &mut C| -> ! {
|
||||
let implemented_in_isle = |ctx: &mut Lower<Inst>| -> ! {
|
||||
unreachable!(
|
||||
"implemented in ISLE: inst = `{}`, type = `{:?}`",
|
||||
ctx.dfg().display_inst(insn),
|
||||
@@ -1621,8 +1621,8 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn lower_branch<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
pub(crate) fn lower_branch(
|
||||
ctx: &mut Lower<Inst>,
|
||||
branches: &[IRInst],
|
||||
targets: &[MachLabel],
|
||||
) -> CodegenResult<()> {
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::ir::Inst as IRInst;
|
||||
use crate::ir::Opcode;
|
||||
use crate::isa::s390x::inst::Inst;
|
||||
use crate::isa::s390x::S390xBackend;
|
||||
use crate::machinst::{InsnOutput, LowerBackend, LowerCtx, MachLabel};
|
||||
use crate::machinst::{InsnOutput, Lower, LowerBackend, MachLabel};
|
||||
use crate::CodegenResult;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
@@ -16,7 +16,7 @@ pub mod isle;
|
||||
impl LowerBackend for S390xBackend {
|
||||
type MInst = Inst;
|
||||
|
||||
fn lower<C: LowerCtx<I = Inst>>(&self, ctx: &mut C, ir_inst: IRInst) -> CodegenResult<()> {
|
||||
fn lower(&self, ctx: &mut Lower<Inst>, ir_inst: IRInst) -> CodegenResult<()> {
|
||||
let op = ctx.data(ir_inst).opcode();
|
||||
let outputs: SmallVec<[InsnOutput; 2]> = (0..ctx.num_outputs(ir_inst))
|
||||
.map(|i| InsnOutput {
|
||||
@@ -278,9 +278,9 @@ impl LowerBackend for S390xBackend {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_branch_group<C: LowerCtx<I = Inst>>(
|
||||
fn lower_branch_group(
|
||||
&self,
|
||||
ctx: &mut C,
|
||||
ctx: &mut Lower<Inst>,
|
||||
branches: &[IRInst],
|
||||
targets: &[MachLabel],
|
||||
) -> CodegenResult<()> {
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::{
|
||||
isa::unwind::UnwindInst,
|
||||
isa::CallConv,
|
||||
machinst::abi_impl::ABIMachineSpec,
|
||||
machinst::{InsnOutput, LowerCtx, VCodeConstant, VCodeConstantData},
|
||||
machinst::{InsnOutput, Lower, VCodeConstant, VCodeConstantData},
|
||||
};
|
||||
use regalloc2::PReg;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@@ -46,17 +46,14 @@ type VecMInst = Vec<MInst>;
|
||||
type VecMInstBuilder = Cell<Vec<MInst>>;
|
||||
|
||||
/// The main entry point for lowering with ISLE.
|
||||
pub(crate) fn lower<C>(
|
||||
lower_ctx: &mut C,
|
||||
pub(crate) fn lower(
|
||||
lower_ctx: &mut Lower<MInst>,
|
||||
triple: &Triple,
|
||||
flags: &Flags,
|
||||
isa_flags: &IsaFlags,
|
||||
outputs: &[InsnOutput],
|
||||
inst: Inst,
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
) -> Result<(), ()> {
|
||||
lower_common(
|
||||
lower_ctx,
|
||||
triple,
|
||||
@@ -69,17 +66,14 @@ where
|
||||
}
|
||||
|
||||
/// The main entry point for branch lowering with ISLE.
|
||||
pub(crate) fn lower_branch<C>(
|
||||
lower_ctx: &mut C,
|
||||
pub(crate) fn lower_branch(
|
||||
lower_ctx: &mut Lower<MInst>,
|
||||
triple: &Triple,
|
||||
flags: &Flags,
|
||||
isa_flags: &IsaFlags,
|
||||
branch: Inst,
|
||||
targets: &[MachLabel],
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
) -> Result<(), ()> {
|
||||
lower_common(
|
||||
lower_ctx,
|
||||
triple,
|
||||
@@ -91,10 +85,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
impl<C> generated_code::Context for IsleContext<'_, C, Flags, IsaFlags, 6>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
|
||||
isle_prelude_methods!();
|
||||
|
||||
fn abi_sig(&mut self, sig_ref: SigRef) -> ABISig {
|
||||
|
||||
@@ -34,11 +34,7 @@ fn is_int_or_ref_ty(ty: Type) -> bool {
|
||||
/// Returns whether the given specified `input` is a result produced by an instruction with Opcode
|
||||
/// `op`.
|
||||
// TODO investigate failures with checking against the result index.
|
||||
fn matches_input<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
input: InsnInput,
|
||||
op: Opcode,
|
||||
) -> Option<IRInst> {
|
||||
fn matches_input(ctx: &mut Lower<Inst>, input: InsnInput, op: Opcode) -> Option<IRInst> {
|
||||
let inputs = ctx.get_input_as_source_or_const(input.insn, input.input);
|
||||
inputs.inst.as_inst().and_then(|(src_inst, _)| {
|
||||
let data = ctx.data(src_inst);
|
||||
@@ -51,7 +47,7 @@ fn matches_input<C: LowerCtx<I = Inst>>(
|
||||
|
||||
/// Emits instruction(s) to generate the given 64-bit constant value into a newly-allocated
|
||||
/// temporary register, returning that register.
|
||||
fn generate_constant<C: LowerCtx<I = Inst>>(ctx: &mut C, ty: Type, c: u64) -> ValueRegs<Reg> {
|
||||
fn generate_constant(ctx: &mut Lower<Inst>, ty: Type, c: u64) -> ValueRegs<Reg> {
|
||||
let from_bits = ty_bits(ty);
|
||||
let masked = if from_bits < 64 {
|
||||
c & ((1u64 << from_bits) - 1)
|
||||
@@ -71,7 +67,7 @@ fn generate_constant<C: LowerCtx<I = Inst>>(ctx: &mut C, ty: Type, c: u64) -> Va
|
||||
}
|
||||
|
||||
/// Put the given input into possibly multiple registers, and mark it as used (side-effect).
|
||||
fn put_input_in_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput) -> ValueRegs<Reg> {
|
||||
fn put_input_in_regs(ctx: &mut Lower<Inst>, spec: InsnInput) -> ValueRegs<Reg> {
|
||||
let ty = ctx.input_ty(spec.insn, spec.input);
|
||||
let input = ctx.get_input_as_source_or_const(spec.insn, spec.input);
|
||||
|
||||
@@ -84,7 +80,7 @@ fn put_input_in_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput) -> Val
|
||||
}
|
||||
|
||||
/// Put the given input into a register, and mark it as used (side-effect).
|
||||
fn put_input_in_reg<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput) -> Reg {
|
||||
fn put_input_in_reg(ctx: &mut Lower<Inst>, spec: InsnInput) -> Reg {
|
||||
put_input_in_regs(ctx, spec)
|
||||
.only_reg()
|
||||
.expect("Multi-register value not expected")
|
||||
@@ -94,10 +90,7 @@ fn put_input_in_reg<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput) -> Reg
|
||||
/// into the current lowering point. If so, returns the address-base source (as
|
||||
/// an `InsnInput`) and an offset from that address from which to perform the
|
||||
/// load.
|
||||
fn is_mergeable_load<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
src_insn: IRInst,
|
||||
) -> Option<(InsnInput, i32)> {
|
||||
fn is_mergeable_load(ctx: &mut Lower<Inst>, src_insn: IRInst) -> Option<(InsnInput, i32)> {
|
||||
let insn_data = ctx.data(src_insn);
|
||||
let inputs = ctx.num_inputs(src_insn);
|
||||
if inputs != 1 {
|
||||
@@ -142,7 +135,7 @@ fn is_mergeable_load<C: LowerCtx<I = Inst>>(
|
||||
|
||||
/// Put the given input into a register or a memory operand.
|
||||
/// Effectful: may mark the given input as used, when returning the register form.
|
||||
fn input_to_reg_mem<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput) -> RegMem {
|
||||
fn input_to_reg_mem(ctx: &mut Lower<Inst>, spec: InsnInput) -> RegMem {
|
||||
let inputs = ctx.get_input_as_source_or_const(spec.insn, spec.input);
|
||||
|
||||
if let Some(c) = inputs.constant {
|
||||
@@ -166,19 +159,13 @@ fn input_to_reg_mem<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput) -> RegM
|
||||
)
|
||||
}
|
||||
|
||||
fn input_to_imm<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput) -> Option<u64> {
|
||||
fn input_to_imm(ctx: &mut Lower<Inst>, spec: InsnInput) -> Option<u64> {
|
||||
ctx.get_input_as_source_or_const(spec.insn, spec.input)
|
||||
.constant
|
||||
}
|
||||
|
||||
/// Emit an instruction to insert a value `src` into a lane of `dst`.
|
||||
fn emit_insert_lane<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
src: RegMem,
|
||||
dst: Writable<Reg>,
|
||||
lane: u8,
|
||||
ty: Type,
|
||||
) {
|
||||
fn emit_insert_lane(ctx: &mut Lower<Inst>, src: RegMem, dst: Writable<Reg>, lane: u8, ty: Type) {
|
||||
if !ty.is_float() {
|
||||
let (sse_op, size) = match ty.lane_bits() {
|
||||
8 => (SseOpcode::Pinsrb, OperandSize::Size32),
|
||||
@@ -220,13 +207,7 @@ fn emit_insert_lane<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
|
||||
/// Emit an instruction to extract a lane of `src` into `dst`.
|
||||
fn emit_extract_lane<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
src: Reg,
|
||||
dst: Writable<Reg>,
|
||||
lane: u8,
|
||||
ty: Type,
|
||||
) {
|
||||
fn emit_extract_lane(ctx: &mut Lower<Inst>, src: Reg, dst: Writable<Reg>, lane: u8, ty: Type) {
|
||||
if !ty.is_float() {
|
||||
let (sse_op, size) = match ty.lane_bits() {
|
||||
8 => (SseOpcode::Pextrb, OperandSize::Size32),
|
||||
@@ -277,8 +258,8 @@ fn emit_extract_lane<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_vm_call<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
fn emit_vm_call(
|
||||
ctx: &mut Lower<Inst>,
|
||||
flags: &Flags,
|
||||
triple: &Triple,
|
||||
libcall: LibCall,
|
||||
@@ -319,10 +300,7 @@ fn emit_vm_call<C: LowerCtx<I = Inst>>(
|
||||
|
||||
/// Returns whether the given input is a shift by a constant value less or equal than 3.
|
||||
/// The goal is to embed it within an address mode.
|
||||
fn matches_small_constant_shift<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
spec: InsnInput,
|
||||
) -> Option<(InsnInput, u8)> {
|
||||
fn matches_small_constant_shift(ctx: &mut Lower<Inst>, spec: InsnInput) -> Option<(InsnInput, u8)> {
|
||||
matches_input(ctx, spec, Opcode::Ishl).and_then(|shift| {
|
||||
match input_to_imm(
|
||||
ctx,
|
||||
@@ -346,7 +324,7 @@ fn matches_small_constant_shift<C: LowerCtx<I = Inst>>(
|
||||
/// Lowers an instruction to one of the x86 addressing modes.
|
||||
///
|
||||
/// Note: the 32-bit offset in Cranelift has to be sign-extended, which maps x86's behavior.
|
||||
fn lower_to_amode<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput, offset: i32) -> Amode {
|
||||
fn lower_to_amode(ctx: &mut Lower<Inst>, spec: InsnInput, offset: i32) -> Amode {
|
||||
let flags = ctx
|
||||
.memflags(spec.insn)
|
||||
.expect("Instruction with amode should have memflags");
|
||||
@@ -443,8 +421,8 @@ fn lower_to_amode<C: LowerCtx<I = Inst>>(ctx: &mut C, spec: InsnInput, offset: i
|
||||
// Top-level instruction lowering entry point, for one instruction.
|
||||
|
||||
/// Actually codegen an instruction's results into registers.
|
||||
fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
fn lower_insn_to_regs(
|
||||
ctx: &mut Lower<Inst>,
|
||||
insn: IRInst,
|
||||
flags: &Flags,
|
||||
isa_flags: &x64_settings::Flags,
|
||||
@@ -469,7 +447,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let implemented_in_isle = |ctx: &mut C| {
|
||||
let implemented_in_isle = |ctx: &mut Lower<Inst>| {
|
||||
unreachable!(
|
||||
"implemented in ISLE: inst = `{}`, type = `{:?}`",
|
||||
ctx.dfg().display_inst(insn),
|
||||
@@ -2227,13 +2205,13 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
impl LowerBackend for X64Backend {
|
||||
type MInst = Inst;
|
||||
|
||||
fn lower<C: LowerCtx<I = Inst>>(&self, ctx: &mut C, ir_inst: IRInst) -> CodegenResult<()> {
|
||||
fn lower(&self, ctx: &mut Lower<Inst>, ir_inst: IRInst) -> CodegenResult<()> {
|
||||
lower_insn_to_regs(ctx, ir_inst, &self.flags, &self.x64_flags, &self.triple)
|
||||
}
|
||||
|
||||
fn lower_branch_group<C: LowerCtx<I = Inst>>(
|
||||
fn lower_branch_group(
|
||||
&self,
|
||||
ctx: &mut C,
|
||||
ctx: &mut Lower<Inst>,
|
||||
branches: &[IRInst],
|
||||
targets: &[MachLabel],
|
||||
) -> CodegenResult<()> {
|
||||
|
||||
@@ -30,7 +30,7 @@ use crate::{
|
||||
},
|
||||
},
|
||||
machinst::{
|
||||
isle::*, valueregs, ABICaller, InsnInput, InsnOutput, LowerCtx, MachAtomicRmwOp, MachInst,
|
||||
isle::*, valueregs, ABICaller, InsnInput, InsnOutput, Lower, MachAtomicRmwOp, MachInst,
|
||||
VCodeConstant, VCodeConstantData,
|
||||
},
|
||||
};
|
||||
@@ -51,17 +51,14 @@ pub struct SinkableLoad {
|
||||
}
|
||||
|
||||
/// The main entry point for lowering with ISLE.
|
||||
pub(crate) fn lower<C>(
|
||||
lower_ctx: &mut C,
|
||||
pub(crate) fn lower(
|
||||
lower_ctx: &mut Lower<MInst>,
|
||||
triple: &Triple,
|
||||
flags: &Flags,
|
||||
isa_flags: &IsaFlags,
|
||||
outputs: &[InsnOutput],
|
||||
inst: Inst,
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
) -> Result<(), ()> {
|
||||
lower_common(
|
||||
lower_ctx,
|
||||
triple,
|
||||
@@ -73,17 +70,14 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn lower_branch<C>(
|
||||
lower_ctx: &mut C,
|
||||
pub(crate) fn lower_branch(
|
||||
lower_ctx: &mut Lower<MInst>,
|
||||
triple: &Triple,
|
||||
flags: &Flags,
|
||||
isa_flags: &IsaFlags,
|
||||
branch: Inst,
|
||||
targets: &[MachLabel],
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
) -> Result<(), ()> {
|
||||
lower_common(
|
||||
lower_ctx,
|
||||
triple,
|
||||
@@ -95,10 +89,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
impl<C> Context for IsleContext<'_, C, Flags, IsaFlags, 6>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
impl Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
|
||||
isle_prelude_methods!();
|
||||
|
||||
#[inline]
|
||||
@@ -793,10 +784,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> IsleContext<'_, C, Flags, IsaFlags, 6>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
impl IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
|
||||
fn abi_arg_slot_regs(&mut self, arg: &ABIArg) -> Option<WritableValueRegs> {
|
||||
match arg {
|
||||
&ABIArg::Slots { ref slots, .. } => match slots.len() {
|
||||
|
||||
Reference in New Issue
Block a user