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.
This commit is contained in:
@@ -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> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,32 +11769,36 @@ 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;
|
||||
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, pattern4_0)?;
|
||||
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, pattern5_0, expr2_0);
|
||||
let expr3_0 = C::vec_element(ctx, pattern6_0, expr2_0);
|
||||
let expr4_0: u8 = 1;
|
||||
let expr5_0 = C::vec_element(ctx, pattern5_0, expr4_0);
|
||||
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;
|
||||
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, pattern4_0)?;
|
||||
let expr0_0 = constructor_value_nonzero(ctx, pattern5_0)?;
|
||||
let expr1_0: u8 = 0;
|
||||
let expr2_0 = C::vec_element(ctx, pattern5_0, expr1_0);
|
||||
let expr2_0 = C::vec_element(ctx, pattern6_0, expr1_0);
|
||||
let expr3_0: u8 = 1;
|
||||
let expr4_0 = C::vec_element(ctx, pattern5_0, expr3_0);
|
||||
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,26 +11825,32 @@ 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);
|
||||
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 pattern7_0,
|
||||
args: ref pattern7_1,
|
||||
} = &pattern6_0
|
||||
opcode: ref pattern8_0,
|
||||
args: ref pattern8_1,
|
||||
} = &pattern7_0
|
||||
{
|
||||
if let &Opcode::Ifcmp = pattern7_0 {
|
||||
let (pattern9_0, pattern9_1) = C::unpack_value_array_2(ctx, pattern7_1);
|
||||
let pattern10_0 = arg1;
|
||||
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, pattern9_0, pattern9_1,
|
||||
ctx,
|
||||
expr0_0,
|
||||
pattern2_2,
|
||||
pattern10_0,
|
||||
pattern10_1,
|
||||
)?;
|
||||
let expr2_0: u8 = 0;
|
||||
let expr3_0 = C::vec_element(ctx, pattern10_0, expr2_0);
|
||||
let expr3_0 = C::vec_element(ctx, pattern11_0, expr2_0);
|
||||
let expr4_0: u8 = 1;
|
||||
let expr5_0 = C::vec_element(ctx, pattern10_0, expr4_0);
|
||||
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)?;
|
||||
@@ -11848,6 +11860,7 @@ pub fn constructor_lower_branch<C: Context>(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
return None;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user