Browse Source

ISLE: Re-implement ValueSlice (#3784)

The current definition of `ValueSlice` is not usable, since any call to
a constructor returning a `ValueSlice` will extend the mutable borrow
on the context taken by the constructor call, with the result that it
cannot be passed to any other constructor ever.

Re-implement `ValueSlice` as a pair of a `ValueList` identifer plus an
offset into the list.  This type can simply be copied without requiring
a borrow on the context.
pull/3852/head
Ulrich Weigand 3 years ago
committed by GitHub
parent
commit
b064e60087
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      cranelift/codegen/src/ir/dfg.rs
  2. 2
      cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest
  3. 26
      cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs
  4. 2
      cranelift/codegen/src/isa/s390x/lower/isle/generated_code.manifest
  5. 131
      cranelift/codegen/src/isa/s390x/lower/isle/generated_code.rs
  6. 2
      cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest
  7. 26
      cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs
  8. 51
      cranelift/codegen/src/machinst/isle.rs
  9. 22
      cranelift/codegen/src/prelude.isle

5
cranelift/codegen/src/ir/dfg.rs

@ -699,6 +699,11 @@ impl DataFlowGraph {
self.results[inst].as_slice(&self.value_lists)
}
/// Return all the results of an instruction as ValueList.
pub fn inst_results_list(&self, inst: Inst) -> ValueList {
self.results[inst]
}
/// Get the call signature of a direct or indirect call instruction.
/// Returns `None` if `inst` is not a call instruction.
pub fn call_signature(&self, inst: Inst) -> Option<SigRef> {

2
cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest

@ -1,4 +1,4 @@
src/clif.isle 9ea75a6f790b5c03
src/prelude.isle 957023853b23dacb
src/prelude.isle 9830498351ddf6a3
src/isa/aarch64/inst.isle 3678d0a37bdb4cff
src/isa/aarch64/lower.isle 90accbfcadaea46d

26
cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs

@ -51,8 +51,10 @@ pub trait Context {
fn vec128(&mut self, arg0: Type) -> Option<Type>;
fn not_i64x2(&mut self, arg0: Type) -> Option<()>;
fn value_list_slice(&mut self, arg0: ValueList) -> ValueSlice;
fn unwrap_head_value_list_1(&mut self, arg0: ValueList) -> (Value, ValueSlice);
fn unwrap_head_value_list_2(&mut self, arg0: ValueList) -> (Value, Value, ValueSlice);
fn value_slice_empty(&mut self, arg0: ValueSlice) -> Option<()>;
fn value_slice_unwrap(&mut self, arg0: ValueSlice) -> Option<(Value, ValueSlice)>;
fn value_slice_len(&mut self, arg0: ValueSlice) -> usize;
fn value_slice_get(&mut self, arg0: ValueSlice, arg1: usize) -> Value;
fn writable_reg_to_reg(&mut self, arg0: WritableReg) -> Reg;
fn u8_from_uimm8(&mut self, arg0: Uimm8) -> u8;
fn u64_from_imm64(&mut self, arg0: Imm64) -> u64;
@ -108,13 +110,13 @@ pub trait Context {
fn rotr_opposite_amount(&mut self, arg0: Type, arg1: ImmShift) -> ImmShift;
}
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 345.
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 363.
#[derive(Clone, Debug)]
pub enum SideEffectNoResult {
Inst { inst: MInst },
}
/// Internal type ProducesFlags: defined at src/prelude.isle line 367.
/// Internal type ProducesFlags: defined at src/prelude.isle line 385.
#[derive(Clone, Debug)]
pub enum ProducesFlags {
ProducesFlagsSideEffect { inst: MInst },
@ -122,7 +124,7 @@ pub enum ProducesFlags {
ProducesFlagsReturnsResultWithConsumer { inst: MInst, result: Reg },
}
/// Internal type ConsumesFlags: defined at src/prelude.isle line 378.
/// Internal type ConsumesFlags: defined at src/prelude.isle line 396.
#[derive(Clone, Debug)]
pub enum ConsumesFlags {
ConsumesFlagsReturnsResultWithProducer {
@ -1048,7 +1050,7 @@ pub fn constructor_side_effect<C: Context>(
inst: ref pattern1_0,
} = pattern0_0
{
// Rule at src/prelude.isle line 350.
// Rule at src/prelude.isle line 368.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::output_none(ctx);
return Some(expr1_0);
@ -1066,7 +1068,7 @@ pub fn constructor_safepoint<C: Context>(
inst: ref pattern1_0,
} = pattern0_0
{
// Rule at src/prelude.isle line 356.
// Rule at src/prelude.isle line 374.
let expr0_0 = C::emit_safepoint(ctx, pattern1_0);
let expr1_0 = C::output_none(ctx);
return Some(expr1_0);
@ -1092,7 +1094,7 @@ pub fn constructor_consumes_flags_concat<C: Context>(
result: pattern3_1,
} = pattern2_0
{
// Rule at src/prelude.isle line 390.
// Rule at src/prelude.isle line 408.
let expr0_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
let expr1_0 = ConsumesFlags::ConsumesFlagsTwiceReturnsValueRegs {
inst1: pattern1_0.clone(),
@ -1122,7 +1124,7 @@ pub fn constructor_with_flags<C: Context>(
inst: ref pattern3_0,
result: pattern3_1,
} => {
// Rule at src/prelude.isle line 415.
// Rule at src/prelude.isle line 433.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_0);
let expr2_0 = C::value_reg(ctx, pattern3_1);
@ -1133,7 +1135,7 @@ pub fn constructor_with_flags<C: Context>(
inst2: ref pattern3_1,
result: pattern3_2,
} => {
// Rule at src/prelude.isle line 421.
// Rule at src/prelude.isle line 439.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_1);
let expr2_0 = C::emit(ctx, pattern3_0);
@ -1152,7 +1154,7 @@ pub fn constructor_with_flags<C: Context>(
result: pattern3_1,
} = pattern2_0
{
// Rule at src/prelude.isle line 409.
// Rule at src/prelude.isle line 427.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_0);
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
@ -1172,7 +1174,7 @@ pub fn constructor_with_flags_reg<C: Context>(
) -> Option<Reg> {
let pattern0_0 = arg0;
let pattern1_0 = arg1;
// Rule at src/prelude.isle line 434.
// Rule at src/prelude.isle line 452.
let expr0_0 = constructor_with_flags(ctx, pattern0_0, pattern1_0)?;
let expr1_0: usize = 0;
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);

2
cranelift/codegen/src/isa/s390x/lower/isle/generated_code.manifest

@ -1,4 +1,4 @@
src/clif.isle 9ea75a6f790b5c03
src/prelude.isle 957023853b23dacb
src/prelude.isle 9830498351ddf6a3
src/isa/s390x/inst.isle d91a16074ab186a8
src/isa/s390x/lower.isle 1cc5a12adc8c75f9

131
cranelift/codegen/src/isa/s390x/lower/isle/generated_code.rs

@ -51,8 +51,10 @@ pub trait Context {
fn vec128(&mut self, arg0: Type) -> Option<Type>;
fn not_i64x2(&mut self, arg0: Type) -> Option<()>;
fn value_list_slice(&mut self, arg0: ValueList) -> ValueSlice;
fn unwrap_head_value_list_1(&mut self, arg0: ValueList) -> (Value, ValueSlice);
fn unwrap_head_value_list_2(&mut self, arg0: ValueList) -> (Value, Value, ValueSlice);
fn value_slice_empty(&mut self, arg0: ValueSlice) -> Option<()>;
fn value_slice_unwrap(&mut self, arg0: ValueSlice) -> Option<(Value, ValueSlice)>;
fn value_slice_len(&mut self, arg0: ValueSlice) -> usize;
fn value_slice_get(&mut self, arg0: ValueSlice, arg1: usize) -> Value;
fn writable_reg_to_reg(&mut self, arg0: WritableReg) -> Reg;
fn u8_from_uimm8(&mut self, arg0: Uimm8) -> u8;
fn u64_from_imm64(&mut self, arg0: Imm64) -> u64;
@ -142,13 +144,13 @@ pub trait Context {
fn same_reg(&mut self, arg0: Reg, arg1: WritableReg) -> Option<()>;
}
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 345.
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 363.
#[derive(Clone, Debug)]
pub enum SideEffectNoResult {
Inst { inst: MInst },
}
/// Internal type ProducesFlags: defined at src/prelude.isle line 367.
/// Internal type ProducesFlags: defined at src/prelude.isle line 385.
#[derive(Clone, Debug)]
pub enum ProducesFlags {
ProducesFlagsSideEffect { inst: MInst },
@ -156,7 +158,7 @@ pub enum ProducesFlags {
ProducesFlagsReturnsResultWithConsumer { inst: MInst, result: Reg },
}
/// Internal type ConsumesFlags: defined at src/prelude.isle line 378.
/// Internal type ConsumesFlags: defined at src/prelude.isle line 396.
#[derive(Clone, Debug)]
pub enum ConsumesFlags {
ConsumesFlagsReturnsResultWithProducer {
@ -939,7 +941,7 @@ pub fn constructor_side_effect<C: Context>(
inst: ref pattern1_0,
} = pattern0_0
{
// Rule at src/prelude.isle line 350.
// Rule at src/prelude.isle line 368.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::output_none(ctx);
return Some(expr1_0);
@ -957,7 +959,7 @@ pub fn constructor_safepoint<C: Context>(
inst: ref pattern1_0,
} = pattern0_0
{
// Rule at src/prelude.isle line 356.
// Rule at src/prelude.isle line 374.
let expr0_0 = C::emit_safepoint(ctx, pattern1_0);
let expr1_0 = C::output_none(ctx);
return Some(expr1_0);
@ -983,7 +985,7 @@ pub fn constructor_consumes_flags_concat<C: Context>(
result: pattern3_1,
} = pattern2_0
{
// Rule at src/prelude.isle line 390.
// Rule at src/prelude.isle line 408.
let expr0_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
let expr1_0 = ConsumesFlags::ConsumesFlagsTwiceReturnsValueRegs {
inst1: pattern1_0.clone(),
@ -1013,7 +1015,7 @@ pub fn constructor_with_flags<C: Context>(
inst: ref pattern3_0,
result: pattern3_1,
} => {
// Rule at src/prelude.isle line 415.
// Rule at src/prelude.isle line 433.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_0);
let expr2_0 = C::value_reg(ctx, pattern3_1);
@ -1024,7 +1026,7 @@ pub fn constructor_with_flags<C: Context>(
inst2: ref pattern3_1,
result: pattern3_2,
} => {
// Rule at src/prelude.isle line 421.
// Rule at src/prelude.isle line 439.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_1);
let expr2_0 = C::emit(ctx, pattern3_0);
@ -1043,7 +1045,7 @@ pub fn constructor_with_flags<C: Context>(
result: pattern3_1,
} = pattern2_0
{
// Rule at src/prelude.isle line 409.
// Rule at src/prelude.isle line 427.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_0);
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
@ -1063,7 +1065,7 @@ pub fn constructor_with_flags_reg<C: Context>(
) -> Option<Reg> {
let pattern0_0 = arg0;
let pattern1_0 = arg1;
// Rule at src/prelude.isle line 434.
// Rule at src/prelude.isle line 452.
let expr0_0 = constructor_with_flags(ctx, pattern0_0, pattern1_0)?;
let expr1_0: usize = 0;
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
@ -11767,31 +11769,35 @@ pub fn constructor_lower_branch<C: Context>(
} => {
match pattern2_0 {
&Opcode::Brz => {
let (pattern4_0, pattern4_1) = C::unwrap_head_value_list_1(ctx, pattern2_1);
let pattern5_0 = arg1;
// Rule at src/isa/s390x/lower.isle line 2109.
let expr0_0 = constructor_value_nonzero(ctx, pattern4_0)?;
let expr1_0 = constructor_invert_bool(ctx, &expr0_0)?;
let expr2_0: u8 = 0;
let expr3_0 = C::vec_element(ctx, pattern5_0, expr2_0);
let expr4_0: u8 = 1;
let expr5_0 = C::vec_element(ctx, pattern5_0, expr4_0);
let expr6_0 = constructor_cond_br_bool(ctx, &expr1_0, expr3_0, expr5_0)?;
let expr7_0 = constructor_side_effect(ctx, &expr6_0)?;
return Some(expr7_0);
let pattern4_0 = C::value_list_slice(ctx, pattern2_1);
if let Some((pattern5_0, pattern5_1)) = C::value_slice_unwrap(ctx, pattern4_0) {
let pattern6_0 = arg1;
// Rule at src/isa/s390x/lower.isle line 2109.
let expr0_0 = constructor_value_nonzero(ctx, pattern5_0)?;
let expr1_0 = constructor_invert_bool(ctx, &expr0_0)?;
let expr2_0: u8 = 0;
let expr3_0 = C::vec_element(ctx, pattern6_0, expr2_0);
let expr4_0: u8 = 1;
let expr5_0 = C::vec_element(ctx, pattern6_0, expr4_0);
let expr6_0 = constructor_cond_br_bool(ctx, &expr1_0, expr3_0, expr5_0)?;
let expr7_0 = constructor_side_effect(ctx, &expr6_0)?;
return Some(expr7_0);
}
}
&Opcode::Brnz => {
let (pattern4_0, pattern4_1) = C::unwrap_head_value_list_1(ctx, pattern2_1);
let pattern5_0 = arg1;
// Rule at src/isa/s390x/lower.isle line 2120.
let expr0_0 = constructor_value_nonzero(ctx, pattern4_0)?;
let expr1_0: u8 = 0;
let expr2_0 = C::vec_element(ctx, pattern5_0, expr1_0);
let expr3_0: u8 = 1;
let expr4_0 = C::vec_element(ctx, pattern5_0, expr3_0);
let expr5_0 = constructor_cond_br_bool(ctx, &expr0_0, expr2_0, expr4_0)?;
let expr6_0 = constructor_side_effect(ctx, &expr5_0)?;
return Some(expr6_0);
let pattern4_0 = C::value_list_slice(ctx, pattern2_1);
if let Some((pattern5_0, pattern5_1)) = C::value_slice_unwrap(ctx, pattern4_0) {
let pattern6_0 = arg1;
// Rule at src/isa/s390x/lower.isle line 2120.
let expr0_0 = constructor_value_nonzero(ctx, pattern5_0)?;
let expr1_0: u8 = 0;
let expr2_0 = C::vec_element(ctx, pattern6_0, expr1_0);
let expr3_0: u8 = 1;
let expr4_0 = C::vec_element(ctx, pattern6_0, expr3_0);
let expr5_0 = constructor_cond_br_bool(ctx, &expr0_0, expr2_0, expr4_0)?;
let expr6_0 = constructor_side_effect(ctx, &expr5_0)?;
return Some(expr6_0);
}
}
_ => {}
}
@ -11819,30 +11825,37 @@ pub fn constructor_lower_branch<C: Context>(
destination: pattern2_3,
} => {
if let &Opcode::Brif = pattern2_0 {
let (pattern4_0, pattern4_1) = C::unwrap_head_value_list_1(ctx, pattern2_1);
if let Some(pattern5_0) = C::def_inst(ctx, pattern4_0) {
let pattern6_0 = C::inst_data(ctx, pattern5_0);
if let &InstructionData::Binary {
opcode: ref pattern7_0,
args: ref pattern7_1,
} = &pattern6_0
{
if let &Opcode::Ifcmp = pattern7_0 {
let (pattern9_0, pattern9_1) = C::unpack_value_array_2(ctx, pattern7_1);
let pattern10_0 = arg1;
// Rule at src/isa/s390x/lower.isle line 2131.
let expr0_0: bool = false;
let expr1_0 = constructor_icmp_val(
ctx, expr0_0, pattern2_2, pattern9_0, pattern9_1,
)?;
let expr2_0: u8 = 0;
let expr3_0 = C::vec_element(ctx, pattern10_0, expr2_0);
let expr4_0: u8 = 1;
let expr5_0 = C::vec_element(ctx, pattern10_0, expr4_0);
let expr6_0 =
constructor_cond_br_bool(ctx, &expr1_0, expr3_0, expr5_0)?;
let expr7_0 = constructor_side_effect(ctx, &expr6_0)?;
return Some(expr7_0);
let pattern4_0 = C::value_list_slice(ctx, pattern2_1);
if let Some((pattern5_0, pattern5_1)) = C::value_slice_unwrap(ctx, pattern4_0) {
if let Some(pattern6_0) = C::def_inst(ctx, pattern5_0) {
let pattern7_0 = C::inst_data(ctx, pattern6_0);
if let &InstructionData::Binary {
opcode: ref pattern8_0,
args: ref pattern8_1,
} = &pattern7_0
{
if let &Opcode::Ifcmp = pattern8_0 {
let (pattern10_0, pattern10_1) =
C::unpack_value_array_2(ctx, pattern8_1);
let pattern11_0 = arg1;
// Rule at src/isa/s390x/lower.isle line 2131.
let expr0_0: bool = false;
let expr1_0 = constructor_icmp_val(
ctx,
expr0_0,
pattern2_2,
pattern10_0,
pattern10_1,
)?;
let expr2_0: u8 = 0;
let expr3_0 = C::vec_element(ctx, pattern11_0, expr2_0);
let expr4_0: u8 = 1;
let expr5_0 = C::vec_element(ctx, pattern11_0, expr4_0);
let expr6_0 =
constructor_cond_br_bool(ctx, &expr1_0, expr3_0, expr5_0)?;
let expr7_0 = constructor_side_effect(ctx, &expr6_0)?;
return Some(expr7_0);
}
}
}
}

2
cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest

@ -1,4 +1,4 @@
src/clif.isle 9ea75a6f790b5c03
src/prelude.isle 957023853b23dacb
src/prelude.isle 9830498351ddf6a3
src/isa/x64/inst.isle 5ee89205e6e9a46b
src/isa/x64/lower.isle 348a808ea5de4cdb

26
cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs

@ -51,8 +51,10 @@ pub trait Context {
fn vec128(&mut self, arg0: Type) -> Option<Type>;
fn not_i64x2(&mut self, arg0: Type) -> Option<()>;
fn value_list_slice(&mut self, arg0: ValueList) -> ValueSlice;
fn unwrap_head_value_list_1(&mut self, arg0: ValueList) -> (Value, ValueSlice);
fn unwrap_head_value_list_2(&mut self, arg0: ValueList) -> (Value, Value, ValueSlice);
fn value_slice_empty(&mut self, arg0: ValueSlice) -> Option<()>;
fn value_slice_unwrap(&mut self, arg0: ValueSlice) -> Option<(Value, ValueSlice)>;
fn value_slice_len(&mut self, arg0: ValueSlice) -> usize;
fn value_slice_get(&mut self, arg0: ValueSlice, arg1: usize) -> Value;
fn writable_reg_to_reg(&mut self, arg0: WritableReg) -> Reg;
fn u8_from_uimm8(&mut self, arg0: Uimm8) -> u8;
fn u64_from_imm64(&mut self, arg0: Imm64) -> u64;
@ -133,13 +135,13 @@ pub trait Context {
fn sse_insertps_lane_imm(&mut self, arg0: u8) -> u8;
}
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 345.
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 363.
#[derive(Clone, Debug)]
pub enum SideEffectNoResult {
Inst { inst: MInst },
}
/// Internal type ProducesFlags: defined at src/prelude.isle line 367.
/// Internal type ProducesFlags: defined at src/prelude.isle line 385.
#[derive(Clone, Debug)]
pub enum ProducesFlags {
ProducesFlagsSideEffect { inst: MInst },
@ -147,7 +149,7 @@ pub enum ProducesFlags {
ProducesFlagsReturnsResultWithConsumer { inst: MInst, result: Reg },
}
/// Internal type ConsumesFlags: defined at src/prelude.isle line 378.
/// Internal type ConsumesFlags: defined at src/prelude.isle line 396.
#[derive(Clone, Debug)]
pub enum ConsumesFlags {
ConsumesFlagsReturnsResultWithProducer {
@ -547,7 +549,7 @@ pub fn constructor_side_effect<C: Context>(
inst: ref pattern1_0,
} = pattern0_0
{
// Rule at src/prelude.isle line 350.
// Rule at src/prelude.isle line 368.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::output_none(ctx);
return Some(expr1_0);
@ -565,7 +567,7 @@ pub fn constructor_safepoint<C: Context>(
inst: ref pattern1_0,
} = pattern0_0
{
// Rule at src/prelude.isle line 356.
// Rule at src/prelude.isle line 374.
let expr0_0 = C::emit_safepoint(ctx, pattern1_0);
let expr1_0 = C::output_none(ctx);
return Some(expr1_0);
@ -591,7 +593,7 @@ pub fn constructor_consumes_flags_concat<C: Context>(
result: pattern3_1,
} = pattern2_0
{
// Rule at src/prelude.isle line 390.
// Rule at src/prelude.isle line 408.
let expr0_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
let expr1_0 = ConsumesFlags::ConsumesFlagsTwiceReturnsValueRegs {
inst1: pattern1_0.clone(),
@ -621,7 +623,7 @@ pub fn constructor_with_flags<C: Context>(
inst: ref pattern3_0,
result: pattern3_1,
} => {
// Rule at src/prelude.isle line 415.
// Rule at src/prelude.isle line 433.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_0);
let expr2_0 = C::value_reg(ctx, pattern3_1);
@ -632,7 +634,7 @@ pub fn constructor_with_flags<C: Context>(
inst2: ref pattern3_1,
result: pattern3_2,
} => {
// Rule at src/prelude.isle line 421.
// Rule at src/prelude.isle line 439.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_1);
let expr2_0 = C::emit(ctx, pattern3_0);
@ -651,7 +653,7 @@ pub fn constructor_with_flags<C: Context>(
result: pattern3_1,
} = pattern2_0
{
// Rule at src/prelude.isle line 409.
// Rule at src/prelude.isle line 427.
let expr0_0 = C::emit(ctx, pattern1_0);
let expr1_0 = C::emit(ctx, pattern3_0);
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
@ -671,7 +673,7 @@ pub fn constructor_with_flags_reg<C: Context>(
) -> Option<Reg> {
let pattern0_0 = arg0;
let pattern1_0 = arg1;
// Rule at src/prelude.isle line 434.
// Rule at src/prelude.isle line 452.
let expr0_0 = constructor_with_flags(ctx, pattern0_0, pattern1_0)?;
let expr1_0: usize = 0;
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);

51
cranelift/codegen/src/machinst/isle.rs

@ -1,4 +1,4 @@
use crate::ir::{types, Inst, Value};
use crate::ir::{types, Inst, Value, ValueList};
use crate::machinst::{get_output_reg, InsnOutput, LowerCtx, MachInst, RegRenamer};
use alloc::boxed::Box;
use alloc::vec::Vec;
@ -12,7 +12,7 @@ pub use crate::isa::unwind::UnwindInst;
pub use crate::machinst::RelocDistance;
pub type Unit = ();
pub type ValueSlice<'a> = &'a [Value];
pub type ValueSlice = (ValueList, usize);
pub type ValueArray2 = [Value; 2];
pub type ValueArray3 = [Value; 3];
pub type WritableReg = Writable<Reg>;
@ -210,29 +210,42 @@ macro_rules! isle_prelude_methods {
#[inline]
fn value_list_slice(&mut self, list: ValueList) -> ValueSlice {
list.as_slice(&self.lower_ctx.dfg().value_lists)
(list, 0)
}
#[inline]
fn unwrap_head_value_list_1(&mut self, list: ValueList) -> (Value, ValueSlice) {
match self.value_list_slice(list) {
[head, tail @ ..] => (*head, tail),
_ => crate::machinst::isle::out_of_line_panic(
"`unwrap_head_value_list_1` on empty `ValueList`",
),
fn value_slice_empty(&mut self, slice: ValueSlice) -> Option<()> {
let (list, off) = slice;
if off >= list.len(&self.lower_ctx.dfg().value_lists) {
Some(())
} else {
None
}
}
#[inline]
fn unwrap_head_value_list_2(&mut self, list: ValueList) -> (Value, Value, ValueSlice) {
match self.value_list_slice(list) {
[head1, head2, tail @ ..] => (*head1, *head2, tail),
_ => crate::machinst::isle::out_of_line_panic(
"`unwrap_head_value_list_2` on list without at least two elements",
),
fn value_slice_unwrap(&mut self, slice: ValueSlice) -> Option<(Value, ValueSlice)> {
let (list, off) = slice;
if let Some(val) = list.get(off, &self.lower_ctx.dfg().value_lists) {
Some((val, (list, off + 1)))
} else {
None
}
}
#[inline]
fn value_slice_len(&mut self, slice: ValueSlice) -> usize {
let (list, off) = slice;
list.len(&self.lower_ctx.dfg().value_lists) - off
}
#[inline]
fn value_slice_get(&mut self, slice: ValueSlice, idx: usize) -> Value {
let (list, off) = slice;
list.get(off + idx, &self.lower_ctx.dfg().value_lists)
.unwrap()
}
#[inline]
fn writable_reg_to_reg(&mut self, r: WritableReg) -> Reg {
r.to_reg()
@ -245,7 +258,7 @@ macro_rules! isle_prelude_methods {
#[inline]
fn inst_results(&mut self, inst: Inst) -> ValueSlice {
self.lower_ctx.dfg().inst_results(inst)
(self.lower_ctx.dfg().inst_results_list(inst), 0)
}
#[inline]
@ -477,9 +490,3 @@ where
Ok(())
}
#[inline(never)]
#[cold]
pub fn out_of_line_panic(msg: &str) -> ! {
panic!("{}", msg);
}

22
cranelift/codegen/src/prelude.isle

@ -251,15 +251,33 @@
(decl value_list_slice (ValueSlice) ValueList)
(extern extractor infallible value_list_slice value_list_slice)
;; Extractor to test whether a `ValueSlice` is empty.
(decl value_slice_empty () ValueSlice)
(extern extractor value_slice_empty value_slice_empty)
;; Extractor to split a `ValueSlice` into its first element plus a tail.
(decl value_slice_unwrap (Value ValueSlice) ValueSlice)
(extern extractor value_slice_unwrap value_slice_unwrap)
;; Return the length of a `ValueSlice`.
(decl value_slice_len (ValueSlice) usize)
(extern constructor value_slice_len value_slice_len)
;; Return any element of a `ValueSlice`.
(decl value_slice_get (ValueSlice usize) Value)
(extern constructor value_slice_get value_slice_get)
;; Extractor to get the first element from a value list, along with its tail as
;; a `ValueSlice`.
(decl unwrap_head_value_list_1 (Value ValueSlice) ValueList)
(extern extractor infallible unwrap_head_value_list_1 unwrap_head_value_list_1)
(extractor (unwrap_head_value_list_1 head tail)
(value_list_slice (value_slice_unwrap head tail)))
;; Extractor to get the first two elements from a value list, along with its
;; tail as a `ValueSlice`.
(decl unwrap_head_value_list_2 (Value Value ValueSlice) ValueList)
(extern extractor infallible unwrap_head_value_list_2 unwrap_head_value_list_2)
(extractor (unwrap_head_value_list_2 head1 head2 tail)
(value_list_slice (value_slice_unwrap head1 (value_slice_unwrap head2 tail))))
;; Turn a `Writable<Reg>` into a `Reg` via `Writable::to_reg`.
(decl writable_reg_to_reg (WritableReg) Reg)

Loading…
Cancel
Save