Skip to content

Commit d8d6fbe

Browse files
authored
Merge pull request bytecodealliance#1718 from cfallin/machinst-codebuffer
Rework of MachInst isel, branch fixups and lowering, and block ordering.
2 parents 28d6df0 + bdd2873 commit d8d6fbe

File tree

32 files changed

+3445
-2333
lines changed

32 files changed

+3445
-2333
lines changed

cranelift/codegen/src/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl Context {
227227
let _tt = timing::binemit();
228228
let mut sink = MemoryCodeSink::new(mem, relocs, traps, stackmaps);
229229
if let Some(ref result) = &self.mach_compile_result {
230-
result.sections.emit(&mut sink);
230+
result.buffer.emit(&mut sink);
231231
} else {
232232
isa.emit_function_to_memory(&self.func, &mut sink);
233233
}

cranelift/codegen/src/inst_predicates.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,24 @@ pub fn has_side_effect(func: &Function, inst: Inst) -> bool {
4040
let opcode = data.opcode();
4141
trivially_has_side_effects(opcode) || is_load_with_defined_trapping(opcode, data)
4242
}
43+
44+
/// Does the given instruction have any side-effect as per [has_side_effect], or else is a load?
45+
pub fn has_side_effect_or_load(func: &Function, inst: Inst) -> bool {
46+
has_side_effect(func, inst) || func.dfg[inst].opcode().can_load()
47+
}
48+
49+
/// Is the given instruction a constant value (`iconst`, `fconst`, `bconst`) that can be
50+
/// represented in 64 bits?
51+
pub fn is_constant_64bit(func: &Function, inst: Inst) -> Option<u64> {
52+
let data = &func.dfg[inst];
53+
if data.opcode() == Opcode::Null {
54+
return Some(0);
55+
}
56+
match data {
57+
&InstructionData::UnaryImm { imm, .. } => Some(imm.bits() as u64),
58+
&InstructionData::UnaryIeee32 { imm, .. } => Some(imm.bits() as u64),
59+
&InstructionData::UnaryIeee64 { imm, .. } => Some(imm.bits()),
60+
&InstructionData::UnaryBool { imm, .. } => Some(if imm { 1 } else { 0 }),
61+
_ => None,
62+
}
63+
}

cranelift/codegen/src/isa/aarch64/abi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ impl AArch64ABIBody {
504504
rn: stack_reg(),
505505
rm: stack_limit,
506506
});
507-
insts.push(Inst::CondBrLowered {
507+
insts.push(Inst::OneWayCondBr {
508508
target: BranchTarget::ResolvedOffset(8),
509509
// Here `Hs` == "higher or same" when interpreting the two
510510
// operands as unsigned integers.

cranelift/codegen/src/isa/aarch64/inst/args.rs

Lines changed: 27 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
// Some variants are never constructed, but we still want them as options in the future.
44
#![allow(dead_code)]
55

6-
use crate::binemit::CodeOffset;
76
use crate::ir::Type;
87
use crate::isa::aarch64::inst::*;
98
use crate::isa::aarch64::lower::ty_bits;
9+
use crate::machinst::MachLabel;
1010

1111
use regalloc::{RealRegUniverse, Reg, Writable};
1212

13-
use core::convert::{Into, TryFrom};
13+
use core::convert::Into;
1414
use std::string::String;
1515

1616
/// A shift operator for a register or immediate.
@@ -303,78 +303,44 @@ impl CondBrKind {
303303

304304
/// A branch target. Either unresolved (basic-block index) or resolved (offset
305305
/// from end of current instruction).
306-
#[derive(Clone, Copy, Debug)]
306+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
307307
pub enum BranchTarget {
308-
/// An unresolved reference to a BlockIndex, as passed into
308+
/// An unresolved reference to a Label, as passed into
309309
/// `lower_branch_group()`.
310-
Block(BlockIndex),
311-
/// A resolved reference to another instruction, after
312-
/// `Inst::with_block_offsets()`.
310+
Label(MachLabel),
311+
/// A fixed PC offset.
313312
ResolvedOffset(isize),
314313
}
315314

316315
impl BranchTarget {
317-
/// Lower the branch target given offsets of each block.
318-
pub fn lower(&mut self, targets: &[CodeOffset], my_offset: CodeOffset) {
319-
match self {
320-
&mut BranchTarget::Block(bix) => {
321-
let bix = usize::try_from(bix).unwrap();
322-
assert!(bix < targets.len());
323-
let block_offset_in_func = targets[bix];
324-
let branch_offset = (block_offset_in_func as isize) - (my_offset as isize);
325-
*self = BranchTarget::ResolvedOffset(branch_offset);
326-
}
327-
&mut BranchTarget::ResolvedOffset(..) => {}
328-
}
329-
}
330-
331-
/// Get the block index.
332-
pub fn as_block_index(&self) -> Option<BlockIndex> {
316+
/// Return the target's label, if it is a label-based target.
317+
pub fn as_label(self) -> Option<MachLabel> {
333318
match self {
334-
&BranchTarget::Block(bix) => Some(bix),
319+
BranchTarget::Label(l) => Some(l),
335320
_ => None,
336321
}
337322
}
338323

339-
/// Get the offset as 4-byte words. Returns `0` if not
340-
/// yet resolved (in that case, we're only computing
341-
/// size and the offset doesn't matter).
342-
pub fn as_offset_words(&self) -> isize {
343-
match self {
344-
&BranchTarget::ResolvedOffset(off) => off >> 2,
324+
/// Return the target's offset, if specified, or zero if label-based.
325+
pub fn as_offset19_or_zero(self) -> u32 {
326+
let off = match self {
327+
BranchTarget::ResolvedOffset(off) => off >> 2,
345328
_ => 0,
346-
}
329+
};
330+
assert!(off <= 0x3ffff);
331+
assert!(off >= -0x40000);
332+
(off as u32) & 0x7ffff
347333
}
348334

349-
/// Get the offset as a 26-bit offset suitable for a 26-bit jump, or `None` if overflow.
350-
pub fn as_off26(&self) -> Option<u32> {
351-
let off = self.as_offset_words();
352-
if (off < (1 << 25)) && (off >= -(1 << 25)) {
353-
Some((off as u32) & ((1 << 26) - 1))
354-
} else {
355-
None
356-
}
357-
}
358-
359-
/// Get the offset as a 19-bit offset, or `None` if overflow.
360-
pub fn as_off19(&self) -> Option<u32> {
361-
let off = self.as_offset_words();
362-
if (off < (1 << 18)) && (off >= -(1 << 18)) {
363-
Some((off as u32) & ((1 << 19) - 1))
364-
} else {
365-
None
366-
}
367-
}
368-
369-
/// Map the block index given a transform map.
370-
pub fn map(&mut self, block_index_map: &[BlockIndex]) {
371-
match self {
372-
&mut BranchTarget::Block(ref mut bix) => {
373-
let n = block_index_map[usize::try_from(*bix).unwrap()];
374-
*bix = n;
375-
}
376-
&mut BranchTarget::ResolvedOffset(_) => {}
377-
}
335+
/// Return the target's offset, if specified, or zero if label-based.
336+
pub fn as_offset26_or_zero(self) -> u32 {
337+
let off = match self {
338+
BranchTarget::ResolvedOffset(off) => off >> 2,
339+
_ => 0,
340+
};
341+
assert!(off <= 0x1ffffff);
342+
assert!(off >= -0x2000000);
343+
(off as u32) & 0x3ffffff
378344
}
379345
}
380346

@@ -507,7 +473,7 @@ impl ShowWithRRU for Cond {
507473
impl ShowWithRRU for BranchTarget {
508474
fn show_rru(&self, _mb_rru: Option<&RealRegUniverse>) -> String {
509475
match self {
510-
&BranchTarget::Block(block) => format!("block{}", block),
476+
&BranchTarget::Label(label) => format!("label{:?}", label.get()),
511477
&BranchTarget::ResolvedOffset(off) => format!("{}", off),
512478
}
513479
}

0 commit comments

Comments
 (0)