diff --git a/cranelift/codegen/src/isa/aarch64/abi.rs b/cranelift/codegen/src/isa/aarch64/abi.rs index 1d7cb9e2f2..bb8d2de30c 100644 --- a/cranelift/codegen/src/isa/aarch64/abi.rs +++ b/cranelift/codegen/src/isa/aarch64/abi.rs @@ -1276,33 +1276,39 @@ impl ABICall for AArch64ABICall { ); match &self.dest { &CallDest::ExtName(ref name, RelocDistance::Near) => ctx.emit(Inst::Call { - dest: Box::new(name.clone()), - uses: uses.into_boxed_slice(), - defs: defs.into_boxed_slice(), - loc: self.loc, - opcode: self.opcode, + info: Box::new(CallInfo { + dest: name.clone(), + uses, + defs, + loc: self.loc, + opcode: self.opcode, + }), }), &CallDest::ExtName(ref name, RelocDistance::Far) => { ctx.emit(Inst::LoadExtName { rd: writable_spilltmp_reg(), - name: name.clone(), + name: Box::new(name.clone()), offset: 0, srcloc: self.loc, }); ctx.emit(Inst::CallInd { - rn: spilltmp_reg(), - uses: uses.into_boxed_slice(), - defs: defs.into_boxed_slice(), - loc: self.loc, - opcode: self.opcode, + info: Box::new(CallIndInfo { + rn: spilltmp_reg(), + uses, + defs, + loc: self.loc, + opcode: self.opcode, + }), }); } &CallDest::Reg(reg) => ctx.emit(Inst::CallInd { - rn: reg, - uses: uses.into_boxed_slice(), - defs: defs.into_boxed_slice(), - loc: self.loc, - opcode: self.opcode, + info: Box::new(CallIndInfo { + rn: reg, + uses, + defs, + loc: self.loc, + opcode: self.opcode, + }), }), } } diff --git a/cranelift/codegen/src/isa/aarch64/inst/args.rs b/cranelift/codegen/src/isa/aarch64/inst/args.rs index 3648eba2d0..0ea61a0404 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/args.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/args.rs @@ -309,7 +309,7 @@ pub enum BranchTarget { /// `lower_branch_group()`. Label(MachLabel), /// A fixed PC offset. - ResolvedOffset(isize), + ResolvedOffset(i32), } impl BranchTarget { diff --git a/cranelift/codegen/src/isa/aarch64/inst/emit.rs b/cranelift/codegen/src/isa/aarch64/inst/emit.rs index 913c9da0a1..0639215a2c 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/emit.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/emit.rs @@ -1239,24 +1239,17 @@ impl MachInstEmit for Inst { &Inst::EpiloguePlaceholder => { // Noop; this is just a placeholder for epilogues. } - &Inst::Call { - ref dest, - loc, - opcode, - .. - } => { - sink.add_reloc(loc, Reloc::Arm64Call, dest, 0); + &Inst::Call { ref info } => { + sink.add_reloc(info.loc, Reloc::Arm64Call, &info.dest, 0); sink.put4(enc_jump26(0b100101, 0)); - if opcode.is_call() { - sink.add_call_site(loc, opcode); + if info.opcode.is_call() { + sink.add_call_site(info.loc, info.opcode); } } - &Inst::CallInd { - rn, loc, opcode, .. - } => { - sink.put4(0b1101011_0001_11111_000000_00000_00000 | (machreg_to_gpr(rn) << 5)); - if opcode.is_call() { - sink.add_call_site(loc, opcode); + &Inst::CallInd { ref info } => { + sink.put4(0b1101011_0001_11111_000000_00000_00000 | (machreg_to_gpr(info.rn) << 5)); + if info.opcode.is_call() { + sink.add_call_site(info.loc, info.opcode); } } &Inst::CondBr { @@ -1318,7 +1311,7 @@ impl MachInstEmit for Inst { ridx, rtmp1, rtmp2, - ref targets, + ref info, .. } => { // This sequence is *one* instruction in the vcode, and is expanded only here at @@ -1361,7 +1354,7 @@ impl MachInstEmit for Inst { inst.emit(sink, flags, state); // Emit jump table (table of 32-bit offsets). let jt_off = sink.cur_offset(); - for &target in targets.iter() { + for &target in info.targets.iter() { let word_off = sink.cur_offset(); let off_into_table = word_off - jt_off; sink.use_label_at_offset( diff --git a/cranelift/codegen/src/isa/aarch64/inst/emit_tests.rs b/cranelift/codegen/src/isa/aarch64/inst/emit_tests.rs index b1ef3a4cfa..612e10ce81 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/emit_tests.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/emit_tests.rs @@ -2113,11 +2113,13 @@ fn test_aarch64_binemit() { insns.push(( Inst::Call { - dest: Box::new(ExternalName::testcase("test0")), - uses: Vec::new().into_boxed_slice(), - defs: Vec::new().into_boxed_slice(), - loc: SourceLoc::default(), - opcode: Opcode::Call, + info: Box::new(CallInfo { + dest: ExternalName::testcase("test0"), + uses: Vec::new(), + defs: Vec::new(), + loc: SourceLoc::default(), + opcode: Opcode::Call, + }), }, "00000094", "bl 0", @@ -2125,11 +2127,13 @@ fn test_aarch64_binemit() { insns.push(( Inst::CallInd { - rn: xreg(10), - uses: Vec::new().into_boxed_slice(), - defs: Vec::new().into_boxed_slice(), - loc: SourceLoc::default(), - opcode: Opcode::CallIndirect, + info: Box::new(CallIndInfo { + rn: xreg(10), + uses: Vec::new(), + defs: Vec::new(), + loc: SourceLoc::default(), + opcode: Opcode::CallIndirect, + }), }, "40013FD6", "blr x10", diff --git a/cranelift/codegen/src/isa/aarch64/inst/mod.rs b/cranelift/codegen/src/isa/aarch64/inst/mod.rs index 85d646d49e..e73027ba3e 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/mod.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/mod.rs @@ -247,6 +247,36 @@ impl From<(Opcode, Type)> for BitOp { } } +/// Additional information for (direct) Call instructions, left out of line to lower the size of +/// the Inst enum. +#[derive(Clone, Debug)] +pub struct CallInfo { + pub dest: ExternalName, + pub uses: Vec, + pub defs: Vec>, + pub loc: SourceLoc, + pub opcode: Opcode, +} + +/// Additional information for CallInd instructions, left out of line to lower the size of the Inst +/// enum. +#[derive(Clone, Debug)] +pub struct CallIndInfo { + pub rn: Reg, + pub uses: Vec, + pub defs: Vec>, + pub loc: SourceLoc, + pub opcode: Opcode, +} + +/// Additional information for JTSequence instructions, left out of line to lower the size of the Inst +/// enum. +#[derive(Clone, Debug)] +pub struct JTSequenceInfo { + pub targets: Vec, + pub targets_for_term: Vec, // needed for MachTerminator. +} + /// Instruction formats. #[derive(Clone, Debug)] pub enum Inst { @@ -649,19 +679,11 @@ pub enum Inst { /// code should use a `LoadExtName` / `CallInd` sequence instead, allowing an arbitrary 64-bit /// target. Call { - dest: Box, - uses: Box<[Reg]>, - defs: Box<[Writable]>, - loc: SourceLoc, - opcode: Opcode, + info: Box, }, /// A machine indirect-call instruction. CallInd { - rn: Reg, - uses: Box<[Reg]>, - defs: Box<[Writable]>, - loc: SourceLoc, - opcode: Opcode, + info: Box, }, // ---- branches (exactly one must appear at end of BB) ---- @@ -742,8 +764,7 @@ pub enum Inst { /// Jump-table sequence, as one compound instruction (see note in lower.rs /// for rationale). JTSequence { - targets: Box<[BranchTarget]>, - targets_for_term: Box<[MachLabel]>, // needed for MachTerminator. + info: Box, ridx: Reg, rtmp1: Writable, rtmp2: Writable, @@ -758,7 +779,7 @@ pub enum Inst { /// Load an inline symbol reference. LoadExtName { rd: Writable, - name: ExternalName, + name: Box, srcloc: SourceLoc, offset: i64, }, @@ -817,7 +838,7 @@ fn count_zero_half_words(mut value: u64) -> usize { fn inst_size_test() { // This test will help with unintentionally growing the size // of the Inst enum. - assert_eq!(48, std::mem::size_of::()); + assert_eq!(32, std::mem::size_of::()); } impl Inst { @@ -1173,21 +1194,14 @@ fn aarch64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) { collector.add_use(rn); } &Inst::Jump { .. } | &Inst::Ret | &Inst::EpiloguePlaceholder => {} - &Inst::Call { - ref uses, ref defs, .. - } => { - collector.add_uses(&*uses); - collector.add_defs(&*defs); + &Inst::Call { ref info } => { + collector.add_uses(&*info.uses); + collector.add_defs(&*info.defs); } - &Inst::CallInd { - ref uses, - ref defs, - rn, - .. - } => { - collector.add_uses(&*uses); - collector.add_defs(&*defs); - collector.add_use(rn); + &Inst::CallInd { ref info } => { + collector.add_uses(&*info.uses); + collector.add_defs(&*info.defs); + collector.add_use(info.rn); } &Inst::CondBr { ref kind, .. } | &Inst::OneWayCondBr { ref kind, .. } => match kind { CondBrKind::Zero(rt) | CondBrKind::NotZero(rt) => { @@ -1724,32 +1738,23 @@ fn aarch64_map_regs(inst: &mut Inst, mapper: &RUM) { map_use(mapper, rn); } &mut Inst::Jump { .. } => {} - &mut Inst::Call { - ref mut uses, - ref mut defs, - .. - } => { - for r in uses.iter_mut() { + &mut Inst::Call { ref mut info } => { + for r in info.uses.iter_mut() { map_use(mapper, r); } - for r in defs.iter_mut() { + for r in info.defs.iter_mut() { map_def(mapper, r); } } &mut Inst::Ret | &mut Inst::EpiloguePlaceholder => {} - &mut Inst::CallInd { - ref mut uses, - ref mut defs, - ref mut rn, - .. - } => { - for r in uses.iter_mut() { + &mut Inst::CallInd { ref mut info, .. } => { + for r in info.uses.iter_mut() { map_use(mapper, r); } - for r in defs.iter_mut() { + for r in info.defs.iter_mut() { map_def(mapper, r); } - map_use(mapper, rn); + map_use(mapper, &mut info.rn); } &mut Inst::CondBr { ref mut kind, .. } | &mut Inst::OneWayCondBr { ref mut kind, .. } => { map_br(mapper, kind); @@ -1833,10 +1838,9 @@ impl MachInst for Inst { MachTerminator::None } &Inst::IndirectBr { ref targets, .. } => MachTerminator::Indirect(&targets[..]), - &Inst::JTSequence { - ref targets_for_term, - .. - } => MachTerminator::Indirect(&targets_for_term[..]), + &Inst::JTSequence { ref info, .. } => { + MachTerminator::Indirect(&info.targets_for_term[..]) + } _ => MachTerminator::None, } } @@ -2554,9 +2558,9 @@ impl ShowWithRRU for Inst { &Inst::Extend { .. } => { panic!("Unsupported Extend case"); } - &Inst::Call { dest: _, .. } => format!("bl 0"), - &Inst::CallInd { rn, .. } => { - let rn = rn.show_rru(mb_rru); + &Inst::Call { .. } => format!("bl 0"), + &Inst::CallInd { ref info, .. } => { + let rn = info.rn.show_rru(mb_rru); format!("blr {}", rn) } &Inst::Ret => "ret".to_string(), @@ -2620,7 +2624,7 @@ impl ShowWithRRU for Inst { &Inst::Word4 { data } => format!("data.i32 {}", data), &Inst::Word8 { data } => format!("data.i64 {}", data), &Inst::JTSequence { - ref targets, + ref info, ridx, rtmp1, rtmp2, @@ -2637,7 +2641,7 @@ impl ShowWithRRU for Inst { "br {} ; ", "jt_entries {:?}" ), - rtmp1, rtmp2, rtmp1, ridx, rtmp1, rtmp1, rtmp2, rtmp1, targets + rtmp1, rtmp2, rtmp1, ridx, rtmp1, rtmp1, rtmp2, rtmp1, info.targets ) } &Inst::LoadConst64 { rd, const_data } => { diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 2faa66941f..4f7250bd64 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -14,6 +14,7 @@ use crate::isa::aarch64::inst::*; use regalloc::RegClass; +use alloc::boxed::Box; use alloc::vec::Vec; use core::convert::TryFrom; use smallvec::SmallVec; @@ -1245,7 +1246,7 @@ pub(crate) fn lower_insn_to_regs>( let loc = ctx.srcloc(insn); ctx.emit(Inst::LoadExtName { rd, - name: extname, + name: Box::new(extname), srcloc: loc, offset: 0, }); @@ -1262,7 +1263,7 @@ pub(crate) fn lower_insn_to_regs>( let loc = ctx.srcloc(insn); ctx.emit(Inst::LoadExtName { rd, - name: extname, + name: Box::new(extname), srcloc: loc, offset, }); @@ -2140,8 +2141,10 @@ pub(crate) fn lower_branch>( ridx, rtmp1, rtmp2, - targets: jt_targets.into_boxed_slice(), - targets_for_term: targets_for_term.into_boxed_slice(), + info: Box::new(JTSequenceInfo { + targets: jt_targets, + targets_for_term: targets_for_term, + }), }); }