machinst: allow passing constant information to the instruction emitter;
A new associated type Info is added to MachInstEmit, which is the immutable counterpart to State. It can't easily be constructed from an ABICallee, since it would require adding an associated type to the latter, and making so leaks the associated type in a lot of places in the code base and makes the code harder to read. Instead, the EmitInfo state can simply be passed to the `Vcode::emit` function directly.
This commit is contained in:
@@ -88,6 +88,10 @@ pub struct VCode<I: VCodeInst> {
|
||||
/// ABI object.
|
||||
abi: Box<dyn ABICallee<I = I>>,
|
||||
|
||||
/// Constant information used during code emission. This should be
|
||||
/// immutable across function compilations within the same module.
|
||||
emit_info: I::Info,
|
||||
|
||||
/// Safepoint instruction indices. Filled in post-regalloc. (Prior to
|
||||
/// regalloc, the safepoint instructions are listed in the separate
|
||||
/// `StackmapRequestInfo` held separate from the `VCode`.)
|
||||
@@ -132,9 +136,13 @@ pub struct VCodeBuilder<I: VCodeInst> {
|
||||
|
||||
impl<I: VCodeInst> VCodeBuilder<I> {
|
||||
/// Create a new VCodeBuilder.
|
||||
pub fn new(abi: Box<dyn ABICallee<I = I>>, block_order: BlockLoweringOrder) -> VCodeBuilder<I> {
|
||||
pub fn new(
|
||||
abi: Box<dyn ABICallee<I = I>>,
|
||||
emit_info: I::Info,
|
||||
block_order: BlockLoweringOrder,
|
||||
) -> VCodeBuilder<I> {
|
||||
let reftype_class = I::ref_type_regclass(abi.flags());
|
||||
let vcode = VCode::new(abi, block_order);
|
||||
let vcode = VCode::new(abi, emit_info, block_order);
|
||||
let stack_map_info = StackmapRequestInfo {
|
||||
reftype_class,
|
||||
reftyped_vregs: vec![],
|
||||
@@ -263,7 +271,11 @@ fn is_reftype(ty: Type) -> bool {
|
||||
|
||||
impl<I: VCodeInst> VCode<I> {
|
||||
/// New empty VCode.
|
||||
fn new(abi: Box<dyn ABICallee<I = I>>, block_order: BlockLoweringOrder) -> VCode<I> {
|
||||
fn new(
|
||||
abi: Box<dyn ABICallee<I = I>>,
|
||||
emit_info: I::Info,
|
||||
block_order: BlockLoweringOrder,
|
||||
) -> VCode<I> {
|
||||
VCode {
|
||||
liveins: abi.liveins(),
|
||||
liveouts: abi.liveouts(),
|
||||
@@ -277,6 +289,7 @@ impl<I: VCodeInst> VCode<I> {
|
||||
block_succs: vec![],
|
||||
block_order,
|
||||
abi,
|
||||
emit_info,
|
||||
safepoint_insns: vec![],
|
||||
safepoint_slots: vec![],
|
||||
}
|
||||
@@ -431,7 +444,6 @@ impl<I: VCodeInst> VCode<I> {
|
||||
|
||||
buffer.reserve_labels_for_blocks(self.num_blocks() as BlockIndex); // first N MachLabels are simply block indices.
|
||||
|
||||
let flags = self.abi.flags();
|
||||
let mut safepoint_idx = 0;
|
||||
let mut cur_srcloc = None;
|
||||
for block in 0..self.num_blocks() {
|
||||
@@ -440,7 +452,7 @@ impl<I: VCodeInst> VCode<I> {
|
||||
while new_offset > buffer.cur_offset() {
|
||||
// Pad with NOPs up to the aligned block offset.
|
||||
let nop = I::gen_nop((new_offset - buffer.cur_offset()) as usize);
|
||||
nop.emit(&mut buffer, flags, &mut Default::default());
|
||||
nop.emit(&mut buffer, &self.emit_info, &mut Default::default());
|
||||
}
|
||||
assert_eq!(buffer.cur_offset(), new_offset);
|
||||
|
||||
@@ -469,7 +481,7 @@ impl<I: VCodeInst> VCode<I> {
|
||||
safepoint_idx += 1;
|
||||
}
|
||||
|
||||
self.insts[iix as usize].emit(&mut buffer, flags, &mut state);
|
||||
self.insts[iix as usize].emit(&mut buffer, &self.emit_info, &mut state);
|
||||
}
|
||||
|
||||
if cur_srcloc.is_some() {
|
||||
|
||||
Reference in New Issue
Block a user