bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly
https://wasmtime.dev/
Apache License 2.0
15.4k stars 1.3k forks source link

riscv64: Suboptimal register allocation for short function #7147

Open afonso360 opened 1 year ago

afonso360 commented 1 year ago

👋 Hey,

This is something that I noticed while working on #7123.

.clif Test Case

test compile precise-output
set unwind_info=false
target riscv64

function %c_lh(i64) -> i16, i16 {
block0(v0: i64):
  v1 = load.i16 v0+0
  v2 = load.i16 v0+2
  return v1, v2
}

; VCode:
; block0:
;   lh a3,0(a0)
;   mv a4,a3
;   lh a1,2(a0)
;   mv a0,a4
;   ret
;
; Disassembled:
; block0: ; offset 0x0
;   lh a3, 0(a0)
;   mv a4, a3
;   lh a1, 2(a0)
;   mv a0, a4
;   ret

Steps to Reproduce

Expected Results

We could eliminate the first move by generating something along these lines:

; VCode:
; block0:
;   lh a3,0(a0)
;   lh a1,2(a0)
;   mv a0,a3
;   ret

Actual Results

We get an extra move between loads.

Versions and Environment

Cranelift version or commit: main

Operating system: Linux

Architecture: RISC-V

Extra Info

VCode:

VCode {
  Entry block: 0
  v193 := v196
  v194 := v195
Block 0:
    (original IR block: block0)
    (instruction range: 0 .. 4)
  Inst 0: args v192=a0
  Inst 1: lh v196,0(v192)
  Inst 2: lh v195,2(v192)
  Inst 3: rets v193=a0 v194=a1
}
afonso360 commented 1 year ago

I couldn't fit this in the initial issue due to a character limit.

Here's the full trace log during compliation: ``` afonso@DESKTOP-1AHKMV2:~/git/wasmtime/cranelift$ RUST_LOG=trace cargo run -- test ./lmao.clif Blocking waiting for file lock on build directory Finished dev [unoptimized + debuginfo] target(s) in 45.38s Running `/home/afonso/git/wasmtime/target/debug/clif-util test ./lmao.clif` INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. DEBUG cranelift_codegen::timing > timing: Starting Processing test file, (during ) INFO cranelift_filetests::runone > --- File: ./lmao.clif DEBUG cranelift_codegen::timing > timing: Starting Parsing textual Cranelift IR, (during Processing test file) DEBUG cranelift_codegen::timing > timing: Ending Parsing textual Cranelift IR: 0ms DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Processing test file) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms INFO cranelift_filetests::subtest > Test: compile(%c_lh) riscv64 DEBUG cranelift_codegen::timing > timing: Starting Compilation passes, (during Processing test file) DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms DEBUG cranelift_codegen::context > Number of CLIF instructions to optimize: 3 DEBUG cranelift_codegen::context > Number of CLIF blocks to optimize: 1 TRACE cranelift_codegen::context > Optimizing (opt level None): function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms TRACE cranelift_codegen::legalizer > Pre-legalization function: function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } TRACE cranelift_codegen::legalizer > Post-legalization function: function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Starting Remove unreachable blocks, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Ending Remove unreachable blocks: 0ms DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms DEBUG cranelift_codegen::timing > timing: Starting Remove constant phi-nodes, (during Compilation passes) DEBUG cranelift_codegen::remove_constant_phis > do_remove_constant_phis: done, 1 iters. 0 formals, of which 0 const. DEBUG cranelift_codegen::timing > timing: Ending Remove constant phi-nodes: 0ms DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms TRACE cranelift_codegen::machinst::abi > ABISig: sig Signature { params: [AbiParam { value_type: types::I64, purpose: Normal, extension: None }], returns: [AbiParam { value_type: types::I16, purpose: Normal, extension: None }, AbiParam { value_type: types::I16, purpose: Normal, extension: None }], call_conv: Fast } => args end = 3 rets end = 2 arg stack = 0 ret stack = 0 stack_ret_arg = false TRACE cranelift_codegen::machinst::abi > ABI: func signature Signature { params: [AbiParam { value_type: types::I64, purpose: Normal, extension: None }], returns: [AbiParam { value_type: types::I16, purpose: Normal, extension: None }, AbiParam { value_type: types::I16, purpose: Normal, extension: None }], call_conv: Fast } TRACE cranelift_codegen::machinst::blockorder > BlockLoweringOrder: function body function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } TRACE cranelift_codegen::machinst::blockorder > BlockLoweringOrder: BlockLoweringOrder { lowered_order: [ Orig { block: block0, }, ], lowered_succ_indices: [], lowered_succ_ranges: [ ( None, 0..0, ), ], cold_blocks: {}, indirect_branch_targets: {}, } TRACE cranelift_codegen::machinst::lower > bb block0 param v0: regs ValueRegs { parts: [v192, v2097151] } TRACE cranelift_codegen::machinst::lower > bb block0 inst inst0 (Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(0) }): result v1 regs ValueRegs { parts: [v193, v2097151] } TRACE cranelift_codegen::machinst::lower > bb block0 inst inst1 (Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(2) }): result v2 regs ValueRegs { parts: [v194, v2097151] } TRACE cranelift_codegen::machinst::lower > bb block0 inst inst0 has color 1 TRACE cranelift_codegen::machinst::lower > -> side-effecting; incrementing color for next inst TRACE cranelift_codegen::machinst::lower > bb block0 inst inst1 has color 2 TRACE cranelift_codegen::machinst::lower > -> side-effecting; incrementing color for next inst TRACE cranelift_codegen::machinst::lower > bb block0 inst inst2 has color 3 TRACE cranelift_codegen::machinst::lower > -> side-effecting; incrementing color for next inst TRACE cranelift_codegen::machinst::lower > arg v0 used, old state Unused, new Once TRACE cranelift_codegen::machinst::lower > arg v0 used, old state Once, new Multiple TRACE cranelift_codegen::machinst::lower > -> pushing args for v0 onto stack TRACE cranelift_codegen::machinst::lower > arg v1 used, old state Unused, new Once TRACE cranelift_codegen::machinst::lower > arg v2 used, old state Unused, new Once DEBUG cranelift_codegen::machinst::compile > Number of CLIF instructions to lower: 3 DEBUG cranelift_codegen::machinst::compile > Number of CLIF blocks to lower: 1 DEBUG cranelift_codegen::timing > timing: Starting VCode lowering, (during Compilation passes) TRACE cranelift_codegen::machinst::lower > about to lower function: function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } TRACE cranelift_codegen::machinst::lower > lower_clif_block: block block0 inst inst2 (MultiAry { opcode: Return, args: EntityList { index: 13, unused: PhantomData } }) is_branch false side_effect true value_needed false TRACE cranelift_codegen::machinst::lower > lowering: inst inst2: MultiAry { opcode: Return, args: EntityList { index: 13, unused: PhantomData } } TRACE cranelift_codegen::machinst::lower > put_value_in_regs: val v1 TRACE cranelift_codegen::machinst::lower > -> regs ValueRegs { parts: [v193, v2097151] } TRACE cranelift_codegen::machinst::lower > put_value_in_regs: val v2 TRACE cranelift_codegen::machinst::lower > -> regs ValueRegs { parts: [v194, v2097151] } TRACE cranelift_codegen::machinst::lower > emit: Rets { rets: [RetPair { vreg: v193, preg: p10i }, RetPair { vreg: v194, preg: p11i }] } TRACE cranelift_codegen::machinst::lower > lower_clif_block: block block0 inst inst1 (Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(2) }) is_branch false side_effect true value_needed true TRACE cranelift_codegen::machinst::lower > lowering: inst inst1: Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(2) } TRACE cranelift_codegen::machinst::lower > put_value_in_regs: val v0 TRACE cranelift_codegen::machinst::lower > -> regs ValueRegs { parts: [v192, v2097151] } TRACE cranelift_codegen::machinst::lower > emit: Load { rd: Writable { reg: v195 }, op: Lh, flags: MemFlags { bits: 0 }, from: RegOffset(v192, 2, types::I16) } TRACE cranelift_codegen::machinst::lower > set vreg alias: from v194 to v195 TRACE cranelift_codegen::machinst::lower > lower_clif_block: block block0 inst inst0 (Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(0) }) is_branch false side_effect true value_needed true TRACE cranelift_codegen::machinst::lower > lowering: inst inst0: Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(0) } TRACE cranelift_codegen::machinst::lower > put_value_in_regs: val v0 TRACE cranelift_codegen::machinst::lower > -> regs ValueRegs { parts: [v192, v2097151] } TRACE cranelift_codegen::machinst::lower > emit: Load { rd: Writable { reg: v196 }, op: Lh, flags: MemFlags { bits: 0 }, from: RegOffset(v192, 0, types::I16) } TRACE cranelift_codegen::machinst::lower > set vreg alias: from v193 to v196 TRACE cranelift_codegen::machinst::lower > gen_arg_setup: entry BB block0 args are: [v0] TRACE cranelift_codegen::machinst::abi > gen_retval_area_setup: not needed TRACE cranelift_codegen::machinst::lower > emit: Args { args: [ArgPair { vreg: Writable { reg: v192 }, preg: p10i }] } TRACE cranelift_codegen::machinst::lower > built vcode: VCode { Entry block: 0 v193 := v196 v194 := v195 Block 0: (original IR block: block0) (instruction range: 0 .. 4) Inst 0: args v192=a0 Inst 1: lh v196,0(v192) Inst 2: lh v195,2(v192) Inst 3: rets v193=a0 v194=a1 } DEBUG cranelift_codegen::timing > timing: Ending VCode lowering: 1ms DEBUG cranelift_codegen::machinst::compile > Number of lowered vcode instructions: 4 DEBUG cranelift_codegen::machinst::compile > Number of lowered vcode blocks: 1 TRACE cranelift_codegen::machinst::compile > vcode from lowering: VCode { Entry block: 0 v193 := v196 v194 := v195 Block 0: (original IR block: block0) (instruction range: 0 .. 4) Inst 0: args v192=a0 Inst 1: lh v196,0(v192) Inst 2: lh v195,2(v192) Inst 3: rets v193=a0 v194=a1 } DEBUG cranelift_codegen::timing > timing: Starting Register allocation, (during Compilation passes) TRACE regalloc2::ion::liveranges > computing liveins for block0 TRACE regalloc2::ion::liveranges > -> initial liveout set: [] TRACE regalloc2::ion::liveranges > op Use: v196i fixed(p10i) was_live = false TRACE regalloc2::ion::liveranges > op Use: v195i fixed(p11i) was_live = false TRACE regalloc2::ion::liveranges > op Def: v195i reg was_live = true TRACE regalloc2::ion::liveranges > op Use: v192i reg was_live = false TRACE regalloc2::ion::liveranges > op Def: v196i reg was_live = true TRACE regalloc2::ion::liveranges > op Use: v192i reg was_live = true TRACE regalloc2::ion::liveranges > op Def: v192i fixed(p10i) was_live = true TRACE regalloc2::ion::liveranges > computed liveins at block0: [] TRACE regalloc2::ion::liveranges > processing inst3 operand at progpoint3-pre: Use: v196i fixed(p10i) TRACE regalloc2::ion::liveranges > add_liverange_to_vreg: vreg VRegIndex(196) range CodeRange { from: progpoint0-pre, to: progpoint3-post } TRACE regalloc2::ion::liveranges > Use of Use: v196i fixed(p10i) at progpoint3-pre -> LiveRangeIndex(0) TRACE regalloc2::ion::liveranges > insert use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } into lr LiveRangeIndex(0) with weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > processing inst3 operand at progpoint3-pre: Use: v195i fixed(p11i) TRACE regalloc2::ion::liveranges > add_liverange_to_vreg: vreg VRegIndex(195) range CodeRange { from: progpoint0-pre, to: progpoint3-post } TRACE regalloc2::ion::liveranges > Use of Use: v195i fixed(p11i) at progpoint3-pre -> LiveRangeIndex(1) TRACE regalloc2::ion::liveranges > insert use Use { operand: Use: v195i fixed(p11i), pos: progpoint3-pre, slot: 1, weight: 35447 } into lr LiveRangeIndex(1) with weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > processing inst2 operand at progpoint2-post: Def: v195i reg TRACE regalloc2::ion::liveranges > Def of v195 at progpoint2-post TRACE regalloc2::ion::liveranges > -> has existing LR LiveRangeIndex(1) TRACE regalloc2::ion::liveranges > insert use Use { operand: Def: v195i reg, pos: progpoint2-post, slot: 1, weight: 35640 } into lr LiveRangeIndex(1) with weight SpillWeight(5000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(8000.0) TRACE regalloc2::ion::liveranges > -> started at block start; trimming to progpoint2-post TRACE regalloc2::ion::liveranges > processing inst2 operand at progpoint2-pre: Use: v192i reg TRACE regalloc2::ion::liveranges > add_liverange_to_vreg: vreg VRegIndex(192) range CodeRange { from: progpoint0-pre, to: progpoint2-post } TRACE regalloc2::ion::liveranges > Use of Use: v192i reg at progpoint2-pre -> LiveRangeIndex(2) TRACE regalloc2::ion::liveranges > insert use Use { operand: Use: v192i reg, pos: progpoint2-pre, slot: 0, weight: 35447 } into lr LiveRangeIndex(2) with weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > processing inst1 operand at progpoint1-post: Def: v196i reg TRACE regalloc2::ion::liveranges > Def of v196 at progpoint1-post TRACE regalloc2::ion::liveranges > -> has existing LR LiveRangeIndex(0) TRACE regalloc2::ion::liveranges > insert use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } into lr LiveRangeIndex(0) with weight SpillWeight(5000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(8000.0) TRACE regalloc2::ion::liveranges > -> started at block start; trimming to progpoint1-post TRACE regalloc2::ion::liveranges > processing inst1 operand at progpoint1-pre: Use: v192i reg TRACE regalloc2::ion::liveranges > Use of Use: v192i reg at progpoint1-pre -> LiveRangeIndex(2) TRACE regalloc2::ion::liveranges > insert use Use { operand: Use: v192i reg, pos: progpoint1-pre, slot: 0, weight: 35447 } into lr LiveRangeIndex(2) with weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(6000.0) TRACE regalloc2::ion::liveranges > processing inst0 operand at progpoint0-post: Def: v192i fixed(p10i) TRACE regalloc2::ion::liveranges > Def of v192 at progpoint0-post TRACE regalloc2::ion::liveranges > -> has existing LR LiveRangeIndex(2) TRACE regalloc2::ion::liveranges > insert use Use { operand: Def: v192i fixed(p10i), pos: progpoint0-post, slot: 0, weight: 35640 } into lr LiveRangeIndex(2) with weight SpillWeight(5000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(11000.0) TRACE regalloc2::ion::liveranges > -> started at block start; trimming to progpoint0-post TRACE regalloc2::ion::liveranges > multi-fixed-reg cleanup: vreg VRegIndex(192) range LiveRangeIndex(2) TRACE regalloc2::ion::liveranges > multi-fixed-reg cleanup: vreg VRegIndex(195) range LiveRangeIndex(1) TRACE regalloc2::ion::liveranges > multi-fixed-reg cleanup: vreg VRegIndex(196) range LiveRangeIndex(0) TRACE regalloc2::ion::merge > merge_vreg_bundles: creating vreg bundles TRACE regalloc2::ion::merge > vreg v192 gets bundle0 TRACE regalloc2::ion::merge > -> with LR range2: CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::merge > vreg v195 gets bundle1 TRACE regalloc2::ion::merge > -> with LR range1: CodeRange { from: progpoint2-post, to: progpoint3-post } TRACE regalloc2::ion::merge > vreg v196 gets bundle2 TRACE regalloc2::ion::merge > -> with LR range0: CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::merge > done merging bundles TRACE regalloc2::ion::merge > enqueueing bundle0 TRACE regalloc2::ion::merge > -> prio 2 TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(0) TRACE regalloc2::ion::process > -> use: Use { operand: Def: v192i fixed(p10i), pos: progpoint0-post, slot: 0, weight: 35640 } TRACE regalloc2::ion::process > -> fixed operand at progpoint0-post: Def: v192i fixed(p10i) TRACE regalloc2::ion::process > -> is fixed def TRACE regalloc2::ion::process > -> use: Use { operand: Use: v192i reg, pos: progpoint1-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> use: Use { operand: Use: v192i reg, pos: progpoint2-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::process > -> minimal: false TRACE regalloc2::ion::process > -> uses spill weight: +SpillWeight(11000.0) TRACE regalloc2::ion::process > -> dividing by prio 2; final weight 5500 TRACE regalloc2::ion::merge > enqueueing bundle1 TRACE regalloc2::ion::merge > -> prio 1 TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(1) TRACE regalloc2::ion::process > -> use: Use { operand: Def: v195i reg, pos: progpoint2-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::process > -> use: Use { operand: Use: v195i fixed(p11i), pos: progpoint3-pre, slot: 1, weight: 35447 } TRACE regalloc2::ion::process > -> fixed operand at progpoint3-pre: Use: v195i fixed(p11i) TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint2-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> minimal: false TRACE regalloc2::ion::process > -> uses spill weight: +SpillWeight(8000.0) TRACE regalloc2::ion::process > -> dividing by prio 1; final weight 8000 TRACE regalloc2::ion::merge > enqueueing bundle2 TRACE regalloc2::ion::merge > -> prio 2 TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(2) TRACE regalloc2::ion::process > -> use: Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::process > -> use: Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> fixed operand at progpoint3-pre: Use: v196i fixed(p10i) TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> minimal: false TRACE regalloc2::ion::process > -> uses spill weight: +SpillWeight(8000.0) TRACE regalloc2::ion::process > -> dividing by prio 2; final weight 4000 TRACE regalloc2::ion::dump > Bundles: TRACE regalloc2::ion::dump > bundle0: spillset=SpillSetIndex(0) alloc=none TRACE regalloc2::ion::dump > * range progpoint0-post -- progpoint2-post: range2 TRACE regalloc2::ion::dump > bundle1: spillset=SpillSetIndex(1) alloc=none TRACE regalloc2::ion::dump > * range progpoint2-post -- progpoint3-post: range1 TRACE regalloc2::ion::dump > bundle2: spillset=SpillSetIndex(2) alloc=none TRACE regalloc2::ion::dump > * range progpoint1-post -- progpoint3-post: range0 TRACE regalloc2::ion::dump > VRegs: TRACE regalloc2::ion::dump > vreg0: TRACE regalloc2::ion::dump > vreg1: TRACE regalloc2::ion::dump > vreg2: TRACE regalloc2::ion::dump > vreg3: TRACE regalloc2::ion::dump > vreg4: TRACE regalloc2::ion::dump > vreg5: TRACE regalloc2::ion::dump > vreg6: TRACE regalloc2::ion::dump > vreg7: TRACE regalloc2::ion::dump > vreg8: TRACE regalloc2::ion::dump > vreg9: TRACE regalloc2::ion::dump > vreg10: TRACE regalloc2::ion::dump > vreg11: TRACE regalloc2::ion::dump > vreg12: TRACE regalloc2::ion::dump > vreg13: TRACE regalloc2::ion::dump > vreg14: TRACE regalloc2::ion::dump > vreg15: TRACE regalloc2::ion::dump > vreg16: TRACE regalloc2::ion::dump > vreg17: TRACE regalloc2::ion::dump > vreg18: TRACE regalloc2::ion::dump > vreg19: TRACE regalloc2::ion::dump > vreg20: TRACE regalloc2::ion::dump > vreg21: TRACE regalloc2::ion::dump > vreg22: TRACE regalloc2::ion::dump > vreg23: TRACE regalloc2::ion::dump > vreg24: TRACE regalloc2::ion::dump > vreg25: TRACE regalloc2::ion::dump > vreg26: TRACE regalloc2::ion::dump > vreg27: TRACE regalloc2::ion::dump > vreg28: TRACE regalloc2::ion::dump > vreg29: TRACE regalloc2::ion::dump > vreg30: TRACE regalloc2::ion::dump > vreg31: TRACE regalloc2::ion::dump > vreg32: TRACE regalloc2::ion::dump > vreg33: TRACE regalloc2::ion::dump > vreg34: TRACE regalloc2::ion::dump > vreg35: TRACE regalloc2::ion::dump > vreg36: TRACE regalloc2::ion::dump > vreg37: TRACE regalloc2::ion::dump > vreg38: TRACE regalloc2::ion::dump > vreg39: TRACE regalloc2::ion::dump > vreg40: TRACE regalloc2::ion::dump > vreg41: TRACE regalloc2::ion::dump > vreg42: TRACE regalloc2::ion::dump > vreg43: TRACE regalloc2::ion::dump > vreg44: TRACE regalloc2::ion::dump > vreg45: TRACE regalloc2::ion::dump > vreg46: TRACE regalloc2::ion::dump > vreg47: TRACE regalloc2::ion::dump > vreg48: TRACE regalloc2::ion::dump > vreg49: TRACE regalloc2::ion::dump > vreg50: TRACE regalloc2::ion::dump > vreg51: TRACE regalloc2::ion::dump > vreg52: TRACE regalloc2::ion::dump > vreg53: TRACE regalloc2::ion::dump > vreg54: TRACE regalloc2::ion::dump > vreg55: TRACE regalloc2::ion::dump > vreg56: TRACE regalloc2::ion::dump > vreg57: TRACE regalloc2::ion::dump > vreg58: TRACE regalloc2::ion::dump > vreg59: TRACE regalloc2::ion::dump > vreg60: TRACE regalloc2::ion::dump > vreg61: TRACE regalloc2::ion::dump > vreg62: TRACE regalloc2::ion::dump > vreg63: TRACE regalloc2::ion::dump > vreg64: TRACE regalloc2::ion::dump > vreg65: TRACE regalloc2::ion::dump > vreg66: TRACE regalloc2::ion::dump > vreg67: TRACE regalloc2::ion::dump > vreg68: TRACE regalloc2::ion::dump > vreg69: TRACE regalloc2::ion::dump > vreg70: TRACE regalloc2::ion::dump > vreg71: TRACE regalloc2::ion::dump > vreg72: TRACE regalloc2::ion::dump > vreg73: TRACE regalloc2::ion::dump > vreg74: TRACE regalloc2::ion::dump > vreg75: TRACE regalloc2::ion::dump > vreg76: TRACE regalloc2::ion::dump > vreg77: TRACE regalloc2::ion::dump > vreg78: TRACE regalloc2::ion::dump > vreg79: TRACE regalloc2::ion::dump > vreg80: TRACE regalloc2::ion::dump > vreg81: TRACE regalloc2::ion::dump > vreg82: TRACE regalloc2::ion::dump > vreg83: TRACE regalloc2::ion::dump > vreg84: TRACE regalloc2::ion::dump > vreg85: TRACE regalloc2::ion::dump > vreg86: TRACE regalloc2::ion::dump > vreg87: TRACE regalloc2::ion::dump > vreg88: TRACE regalloc2::ion::dump > vreg89: TRACE regalloc2::ion::dump > vreg90: TRACE regalloc2::ion::dump > vreg91: TRACE regalloc2::ion::dump > vreg92: TRACE regalloc2::ion::dump > vreg93: TRACE regalloc2::ion::dump > vreg94: TRACE regalloc2::ion::dump > vreg95: TRACE regalloc2::ion::dump > vreg96: TRACE regalloc2::ion::dump > vreg97: TRACE regalloc2::ion::dump > vreg98: TRACE regalloc2::ion::dump > vreg99: TRACE regalloc2::ion::dump > vreg100: TRACE regalloc2::ion::dump > vreg101: TRACE regalloc2::ion::dump > vreg102: TRACE regalloc2::ion::dump > vreg103: TRACE regalloc2::ion::dump > vreg104: TRACE regalloc2::ion::dump > vreg105: TRACE regalloc2::ion::dump > vreg106: TRACE regalloc2::ion::dump > vreg107: TRACE regalloc2::ion::dump > vreg108: TRACE regalloc2::ion::dump > vreg109: TRACE regalloc2::ion::dump > vreg110: TRACE regalloc2::ion::dump > vreg111: TRACE regalloc2::ion::dump > vreg112: TRACE regalloc2::ion::dump > vreg113: TRACE regalloc2::ion::dump > vreg114: TRACE regalloc2::ion::dump > vreg115: TRACE regalloc2::ion::dump > vreg116: TRACE regalloc2::ion::dump > vreg117: TRACE regalloc2::ion::dump > vreg118: TRACE regalloc2::ion::dump > vreg119: TRACE regalloc2::ion::dump > vreg120: TRACE regalloc2::ion::dump > vreg121: TRACE regalloc2::ion::dump > vreg122: TRACE regalloc2::ion::dump > vreg123: TRACE regalloc2::ion::dump > vreg124: TRACE regalloc2::ion::dump > vreg125: TRACE regalloc2::ion::dump > vreg126: TRACE regalloc2::ion::dump > vreg127: TRACE regalloc2::ion::dump > vreg128: TRACE regalloc2::ion::dump > vreg129: TRACE regalloc2::ion::dump > vreg130: TRACE regalloc2::ion::dump > vreg131: TRACE regalloc2::ion::dump > vreg132: TRACE regalloc2::ion::dump > vreg133: TRACE regalloc2::ion::dump > vreg134: TRACE regalloc2::ion::dump > vreg135: TRACE regalloc2::ion::dump > vreg136: TRACE regalloc2::ion::dump > vreg137: TRACE regalloc2::ion::dump > vreg138: TRACE regalloc2::ion::dump > vreg139: TRACE regalloc2::ion::dump > vreg140: TRACE regalloc2::ion::dump > vreg141: TRACE regalloc2::ion::dump > vreg142: TRACE regalloc2::ion::dump > vreg143: TRACE regalloc2::ion::dump > vreg144: TRACE regalloc2::ion::dump > vreg145: TRACE regalloc2::ion::dump > vreg146: TRACE regalloc2::ion::dump > vreg147: TRACE regalloc2::ion::dump > vreg148: TRACE regalloc2::ion::dump > vreg149: TRACE regalloc2::ion::dump > vreg150: TRACE regalloc2::ion::dump > vreg151: TRACE regalloc2::ion::dump > vreg152: TRACE regalloc2::ion::dump > vreg153: TRACE regalloc2::ion::dump > vreg154: TRACE regalloc2::ion::dump > vreg155: TRACE regalloc2::ion::dump > vreg156: TRACE regalloc2::ion::dump > vreg157: TRACE regalloc2::ion::dump > vreg158: TRACE regalloc2::ion::dump > vreg159: TRACE regalloc2::ion::dump > vreg160: TRACE regalloc2::ion::dump > vreg161: TRACE regalloc2::ion::dump > vreg162: TRACE regalloc2::ion::dump > vreg163: TRACE regalloc2::ion::dump > vreg164: TRACE regalloc2::ion::dump > vreg165: TRACE regalloc2::ion::dump > vreg166: TRACE regalloc2::ion::dump > vreg167: TRACE regalloc2::ion::dump > vreg168: TRACE regalloc2::ion::dump > vreg169: TRACE regalloc2::ion::dump > vreg170: TRACE regalloc2::ion::dump > vreg171: TRACE regalloc2::ion::dump > vreg172: TRACE regalloc2::ion::dump > vreg173: TRACE regalloc2::ion::dump > vreg174: TRACE regalloc2::ion::dump > vreg175: TRACE regalloc2::ion::dump > vreg176: TRACE regalloc2::ion::dump > vreg177: TRACE regalloc2::ion::dump > vreg178: TRACE regalloc2::ion::dump > vreg179: TRACE regalloc2::ion::dump > vreg180: TRACE regalloc2::ion::dump > vreg181: TRACE regalloc2::ion::dump > vreg182: TRACE regalloc2::ion::dump > vreg183: TRACE regalloc2::ion::dump > vreg184: TRACE regalloc2::ion::dump > vreg185: TRACE regalloc2::ion::dump > vreg186: TRACE regalloc2::ion::dump > vreg187: TRACE regalloc2::ion::dump > vreg188: TRACE regalloc2::ion::dump > vreg189: TRACE regalloc2::ion::dump > vreg190: TRACE regalloc2::ion::dump > vreg191: TRACE regalloc2::ion::dump > vreg192: TRACE regalloc2::ion::dump > * range progpoint0-post -- progpoint2-post: range2 TRACE regalloc2::ion::dump > vreg193: TRACE regalloc2::ion::dump > vreg194: TRACE regalloc2::ion::dump > vreg195: TRACE regalloc2::ion::dump > * range progpoint2-post -- progpoint3-post: range1 TRACE regalloc2::ion::dump > vreg196: TRACE regalloc2::ion::dump > * range progpoint1-post -- progpoint3-post: range0 TRACE regalloc2::ion::dump > Ranges: TRACE regalloc2::ion::dump > range0: range=CodeRange { from: progpoint1-post, to: progpoint3-post } vreg=VRegIndex(196) bundle=LiveBundleIndex(2) weight=SpillWeight(8000.0) TRACE regalloc2::ion::dump > * use at progpoint1-post (slot 1): Def: v196i reg TRACE regalloc2::ion::dump > * use at progpoint3-pre (slot 0): Use: v196i fixed(p10i) TRACE regalloc2::ion::dump > range1: range=CodeRange { from: progpoint2-post, to: progpoint3-post } vreg=VRegIndex(195) bundle=LiveBundleIndex(1) weight=SpillWeight(8000.0) TRACE regalloc2::ion::dump > * use at progpoint2-post (slot 1): Def: v195i reg TRACE regalloc2::ion::dump > * use at progpoint3-pre (slot 1): Use: v195i fixed(p11i) TRACE regalloc2::ion::dump > range2: range=CodeRange { from: progpoint0-post, to: progpoint2-post } vreg=VRegIndex(192) bundle=LiveBundleIndex(0) weight=SpillWeight(11000.0) TRACE regalloc2::ion::dump > * use at progpoint0-post (slot 0): Def: v192i fixed(p10i) TRACE regalloc2::ion::dump > * use at progpoint1-pre (slot 0): Use: v192i reg TRACE regalloc2::ion::dump > * use at progpoint2-pre (slot 0): Use: v192i reg TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(2) hint PReg(hw = 63, class = Int, index = 63) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(2) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::requirement > -> req Register TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(2) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 3, to: 3 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(2) assigned to preg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(10) TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(0) hint PReg(hw = 63, class = Int, index = 63) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(0) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(2): CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v192i fixed(p10i), pos: progpoint0-post, slot: 0, weight: 35640 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v192i reg, pos: progpoint1-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v192i reg, pos: progpoint2-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(0) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 1, to: 1 }..: {LiveRangeKey { from: 3, to: 7 }: LiveRangeIndex(0)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(2): CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 3, to: 7 }, LiveRangeIndex(0))) TRACE regalloc2::ion::process > -> btree contains range LiveRangeIndex(0) that overlaps TRACE regalloc2::ion::process > -> from vreg VRegIndex(196) TRACE regalloc2::ion::process > -> conflict bundle LiveBundleIndex(2) TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> conflict with bundles [LiveBundleIndex(2)], first conflict at progpoint1-post TRACE regalloc2::ion::process > maximum_spill_weight_in_bundle_set: [LiveBundleIndex(2)] TRACE regalloc2::ion::process > bundle2: 4000 TRACE regalloc2::ion::process > -> max: 4000 TRACE regalloc2::ion::process > -> lowest cost evict: set Some([LiveBundleIndex(2)]), cost Some(4000) TRACE regalloc2::ion::process > -> lowest cost split: cost Some(9000), point progpoint1-post, reg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> our spill weight: 5500 TRACE regalloc2::ion::process > -> evicting LiveBundleIndex(2) TRACE regalloc2::ion::process > evicting bundle LiveBundleIndex(2): alloc p10i TRACE regalloc2::ion::process > -> removing LR LiveRangeIndex(0) from reg PRegIndex(10) TRACE regalloc2::ion::process > -> prio 2; back into queue TRACE regalloc2::ion::process > attempt 2, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(0) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 1, to: 1 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(2): CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(0) assigned to preg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(10) TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(2) hint PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(2) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::requirement > -> req Register TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(2) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 3, to: 3 }..: {LiveRangeKey { from: 1, to: 5 }: LiveRangeIndex(2)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 1, to: 5 }, LiveRangeIndex(2))) TRACE regalloc2::ion::process > -> btree contains range LiveRangeIndex(2) that overlaps TRACE regalloc2::ion::process > -> from vreg VRegIndex(192) TRACE regalloc2::ion::process > -> conflict bundle LiveBundleIndex(0) TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> conflict with bundles [LiveBundleIndex(0)], first conflict at progpoint1-post TRACE regalloc2::ion::process > maximum_spill_weight_in_bundle_set: [LiveBundleIndex(0)] TRACE regalloc2::ion::process > bundle0: 5500 TRACE regalloc2::ion::process > -> max: 5500 TRACE regalloc2::ion::process > -> lowest cost evict: set Some([LiveBundleIndex(0)]), cost Some(5500) TRACE regalloc2::ion::process > -> lowest cost split: cost Some(10500), point progpoint1-post, reg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> our spill weight: 4000 TRACE regalloc2::ion::process > -> deciding to split: our spill weight is 4000 TRACE regalloc2::ion::process > split bundle LiveBundleIndex(2) at progpoint1-post and requeue with reg hint (for first part) PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> first use loc is Some(progpoint1-post) TRACE regalloc2::ion::process > split point is at bundle start; advancing to progpoint2-pre TRACE regalloc2::ion::process > -> LRs: [LiveRangeListEntry { range: CodeRange { from: progpoint1-post, to: progpoint3-post }, index: LiveRangeIndex(0) }] TRACE regalloc2::ion::process > -> last LR in old bundle: LR LiveRangeListEntry { range: CodeRange { from: progpoint1-post, to: progpoint3-post }, index: LiveRangeIndex(0) } TRACE regalloc2::ion::process > -> first LR in new bundle: LR LiveRangeListEntry { range: CodeRange { from: progpoint1-post, to: progpoint3-post }, index: LiveRangeIndex(0) } TRACE regalloc2::ion::process > -> splitting LR LiveRangeIndex(0) into LiveRangeIndex(3) TRACE regalloc2::ion::process > range0: use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::process > range3: use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> creating new bundle LiveBundleIndex(3) TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(2) range LiveRangeIndex(3): first use implies split point progpoint3-pre TRACE regalloc2::ion::process > -> moving leading empty region to new spill bundle LiveBundleIndex(4) with new LR LiveRangeIndex(4) TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(2) TRACE regalloc2::ion::process > -> use: Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint1-post, to: progpoint2-pre } TRACE regalloc2::ion::process > -> minimal: true TRACE regalloc2::ion::process > -> non-fixed and minimal TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(3) TRACE regalloc2::ion::process > -> use: Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> fixed operand at progpoint3-pre: Use: v196i fixed(p10i) TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint3-pre, to: progpoint3-post } TRACE regalloc2::ion::process > -> minimal: true TRACE regalloc2::ion::process > -> fixed and minimal TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(2) hint PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(2) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint2-pre } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::requirement > -> req Register TRACE regalloc2::ion::requirement > -> final: Register TRACE regalloc2::ion::process > attempt 1, req Register TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(2) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 3, to: 3 }..: {LiveRangeKey { from: 1, to: 5 }: LiveRangeIndex(2)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint2-pre } TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 1, to: 5 }, LiveRangeIndex(2))) TRACE regalloc2::ion::process > -> btree contains range LiveRangeIndex(2) that overlaps TRACE regalloc2::ion::process > -> from vreg VRegIndex(192) TRACE regalloc2::ion::process > -> conflict bundle LiveBundleIndex(0) TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> conflict with bundles [LiveBundleIndex(0)], first conflict at progpoint1-post TRACE regalloc2::ion::process > maximum_spill_weight_in_bundle_set: [LiveBundleIndex(0)] TRACE regalloc2::ion::process > bundle0: 5500 TRACE regalloc2::ion::process > -> max: 5500 TRACE regalloc2::ion::process > trying preg PRegIndex(13) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(2) -> PRegIndex(13) TRACE regalloc2::ion::process > alloc map for PRegIndex(13) in range LiveRangeKey { from: 3, to: 3 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint2-pre } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(2) assigned to preg PReg(hw = 13, class = Int, index = 13) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(13) TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(1) hint PReg(hw = 63, class = Int, index = 63) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(1) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(1): CodeRange { from: progpoint2-post, to: progpoint3-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v195i reg, pos: progpoint2-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::requirement > -> req Register TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v195i fixed(p11i), pos: progpoint3-pre, slot: 1, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 11, class = Int, index = 11)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 11, class = Int, index = 11)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 11, class = Int, index = 11)) TRACE regalloc2::ion::process > trying preg PRegIndex(11) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(1) -> PRegIndex(11) TRACE regalloc2::ion::process > alloc map for PRegIndex(11) in range LiveRangeKey { from: 5, to: 5 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(1): CodeRange { from: progpoint2-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(1) assigned to preg PReg(hw = 11, class = Int, index = 11) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(11) TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(3) hint PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(3) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(3): CodeRange { from: progpoint3-pre, to: progpoint3-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(3) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 6, to: 6 }..: {LiveRangeKey { from: 1, to: 5 }: LiveRangeIndex(2)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(3): CodeRange { from: progpoint3-pre, to: progpoint3-post } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(3) assigned to preg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(10) TRACE regalloc2::ion::spill > allocating regs for spilled bundles TRACE regalloc2::ion::spill > trying bundle LiveBundleIndex(4) to preg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(4) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 4, to: 4 }..: {LiveRangeKey { from: 1, to: 5 }: LiveRangeIndex(2), LiveRangeKey { from: 6, to: 7 }: LiveRangeIndex(3)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(4): CodeRange { from: progpoint2-pre, to: progpoint3-pre } TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 1, to: 5 }, LiveRangeIndex(2))) TRACE regalloc2::ion::process > -> btree contains range LiveRangeIndex(2) that overlaps TRACE regalloc2::ion::process > -> from vreg VRegIndex(192) TRACE regalloc2::ion::process > -> conflict bundle LiveBundleIndex(0) TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 6, to: 7 }, LiveRangeIndex(3))) TRACE regalloc2::ion::process > -> next PReg allocation is at LiveRangeKey { from: 6, to: 7 }; moving to next VReg range TRACE regalloc2::ion::spill > trying bundle LiveBundleIndex(4) to preg PReg(hw = 14, class = Int, index = 14) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(4) -> PRegIndex(14) TRACE regalloc2::ion::process > alloc map for PRegIndex(14) in range LiveRangeKey { from: 4, to: 4 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(4): CodeRange { from: progpoint2-pre, to: progpoint3-pre } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(4) assigned to preg PReg(hw = 14, class = Int, index = 14) TRACE regalloc2::ion::spill > allocate spillslot: 0 TRACE regalloc2::ion::spill > allocate spillslot: 1 TRACE regalloc2::ion::spill > allocate spillslot: 2 TRACE regalloc2::ion::spill > spillslot allocator done TRACE regalloc2::ion::moves > apply_allocations_and_insert_moves TRACE regalloc2::ion::moves > blockparam_ins: [] TRACE regalloc2::ion::moves > blockparam_outs: [] TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(2) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(0) TRACE regalloc2::ion::moves > -> allocation p10i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(192) LR LiveRangeIndex(2) with range CodeRange { from: progpoint0-post, to: progpoint2-post } has alloc p10i TRACE regalloc2::ion::moves > applying to use: Use { operand: Def: v192i fixed(p10i), pos: progpoint0-post, slot: 0, weight: 35640 } TRACE regalloc2::ion::moves > applying to use: Use { operand: Use: v192i reg, pos: progpoint1-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::moves > applying to use: Use { operand: Use: v192i reg, pos: progpoint2-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(1) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(1) TRACE regalloc2::ion::moves > -> allocation p11i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(195) LR LiveRangeIndex(1) with range CodeRange { from: progpoint2-post, to: progpoint3-post } has alloc p11i TRACE regalloc2::ion::moves > applying to use: Use { operand: Def: v195i reg, pos: progpoint2-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::moves > applying to use: Use { operand: Use: v195i fixed(p11i), pos: progpoint3-pre, slot: 1, weight: 35447 } TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(0) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(2) TRACE regalloc2::ion::moves > -> allocation p13i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(196) LR LiveRangeIndex(0) with range CodeRange { from: progpoint1-post, to: progpoint2-pre } has alloc p13i TRACE regalloc2::ion::moves > applying to use: Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(4) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(4) TRACE regalloc2::ion::moves > -> allocation p14i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(196) LR LiveRangeIndex(4) with range CodeRange { from: progpoint2-pre, to: progpoint3-pre } has alloc p14i TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(0) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(2) TRACE regalloc2::ion::moves > -> allocation p13i TRACE regalloc2::ion::moves > prev LR 0 abuts LR 4 in same block; moving p13i -> p14i for v196 TRACE regalloc2::ion::data_structures > insert_move: pos progpoint2-pre prio Regular from_alloc p13i to_alloc p14i to_vreg VReg(vreg = 196, class = Int) TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(3) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(3) TRACE regalloc2::ion::moves > -> allocation p10i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(196) LR LiveRangeIndex(3) with range CodeRange { from: progpoint3-pre, to: progpoint3-post } has alloc p10i TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(4) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(4) TRACE regalloc2::ion::moves > -> allocation p14i TRACE regalloc2::ion::moves > prev LR 4 abuts LR 3 in same block; moving p14i -> p10i for v196 TRACE regalloc2::ion::data_structures > insert_move: pos progpoint3-pre prio Regular from_alloc p14i to_alloc p10i to_vreg VReg(vreg = 196, class = Int) TRACE regalloc2::ion::moves > applying to use: Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p10i TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p13i TRACE regalloc2::ion::moves > parallel moves at pos progpoint2-pre prio 1 TRACE regalloc2::ion::moves > p13i -> p14i TRACE regalloc2::ion::moves > resolved: p13i -> p14i (Some(VReg(vreg = 196, class = Int))) TRACE regalloc2::ion::redundant_moves > -> redundant move tracker: from p13i to p14i to_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> from_state None to_state None TRACE regalloc2::ion::redundant_moves > -> src_vreg None TRACE regalloc2::ion::redundant_moves > -> dst_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> existing_dst_vreg None TRACE regalloc2::ion::redundant_moves > -> elide false TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p14i TRACE regalloc2::ion::redundant_moves > -> create mapping p14i -> Copy(p13i, Some(VReg(vreg = 196, class = Int))) TRACE regalloc2::ion::moves > parallel moves at pos progpoint2-pre prio 1 TRACE regalloc2::ion::moves > parallel moves at pos progpoint2-pre prio 1 TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p11i TRACE regalloc2::ion::moves > parallel moves at pos progpoint3-pre prio 1 TRACE regalloc2::ion::moves > p14i -> p10i TRACE regalloc2::ion::moves > resolved: p14i -> p10i (Some(VReg(vreg = 196, class = Int))) TRACE regalloc2::ion::redundant_moves > -> redundant move tracker: from p14i to p10i to_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> from_state Copy(p13i, Some(VReg(vreg = 196, class = Int))) to_state None TRACE regalloc2::ion::redundant_moves > -> src_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> dst_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> existing_dst_vreg None TRACE regalloc2::ion::redundant_moves > -> elide false TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p10i TRACE regalloc2::ion::redundant_moves > -> create mapping p10i -> Copy(p14i, Some(VReg(vreg = 196, class = Int))) TRACE regalloc2::ion::moves > parallel moves at pos progpoint3-pre prio 1 TRACE regalloc2::ion::moves > parallel moves at pos progpoint3-pre prio 1 DEBUG cranelift_codegen::timing > timing: Ending Register allocation: 21ms DEBUG cranelift_codegen::timing > timing: Starting VCode emission, (during Compilation passes) TRACE cranelift_codegen::machinst::buffer > MachBuffer: first 1 labels are for blocks TRACE cranelift_codegen::machinst::vcode > emitting block Block(0) TRACE cranelift_codegen::machinst::vcode > -> entry block TRACE cranelift_codegen::machinst::buffer > MachBuffer: bind label MachLabel(0) at offset 0 TRACE cranelift_codegen::machinst::buffer > enter optimize_branches: b = [] l = [MachLabel(0)] f = [] TRACE cranelift_codegen::machinst::buffer > leave optimize_branches: b = [] l = [MachLabel(0)] f = [] TRACE cranelift_codegen::machinst::abi > Epilogue: [Ret] TRACE cranelift_codegen::machinst::buffer > enter optimize_branches: b = [] l = [] f = [] TRACE cranelift_codegen::machinst::buffer > leave optimize_branches: b = [] l = [] f = [] DEBUG cranelift_codegen::timing > timing: Starting VCode emission finalization, (during VCode emission) DEBUG cranelift_codegen::timing > timing: Ending VCode emission finalization: 0ms DEBUG cranelift_codegen::timing > timing: Ending VCode emission: 5ms DEBUG cranelift_codegen::isa::riscv64 > disassembly: block0: lh a3,0(a0) mv a4,a3 lh a1,2(a0) mv a0,a4 ret DEBUG cranelift_codegen::timing > timing: Ending Compilation passes: 32ms INFO cranelift_filetests::test_compile > Generated 20 bytes of code: block0: lh a3,0(a0) mv a4,a3 lh a1,2(a0) mv a0,a4 ret DEBUG cranelift_codegen::timing > timing: Ending Processing test file: 34ms 1 tests ```
afonso360 commented 1 year ago

Tested locally with the latest regalloc2 (7d90ca9) and it still produces the same output.

Trace log ``` Running `/home/afonso/git/wasmtime/target/debug/clif-util test ./lmao.clif` INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. DEBUG cranelift_codegen::timing > timing: Starting Processing test file, (during ) INFO cranelift_filetests::runone > --- File: ./lmao.clif DEBUG cranelift_codegen::timing > timing: Starting Parsing textual Cranelift IR, (during Processing test file) INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. INFO file_per_thread_logger > Set up logging; filename prefix is cranelift.dbg. DEBUG cranelift_codegen::timing > timing: Ending Parsing textual Cranelift IR: 2ms DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Processing test file) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms INFO cranelift_filetests::subtest > Test: compile(%c_lh) riscv64 DEBUG cranelift_codegen::timing > timing: Starting Compilation passes, (during Processing test file) DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms DEBUG cranelift_codegen::context > Number of CLIF instructions to optimize: 3 DEBUG cranelift_codegen::context > Number of CLIF blocks to optimize: 1 TRACE cranelift_codegen::context > Optimizing (opt level None): function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms TRACE cranelift_codegen::legalizer > Pre-legalization function: function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } TRACE cranelift_codegen::legalizer > Post-legalization function: function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Starting Remove unreachable blocks, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Ending Remove unreachable blocks: 0ms DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms DEBUG cranelift_codegen::timing > timing: Starting Remove constant phi-nodes, (during Compilation passes) DEBUG cranelift_codegen::remove_constant_phis > do_remove_constant_phis: done, 1 iters. 0 formals, of which 0 const. DEBUG cranelift_codegen::timing > timing: Ending Remove constant phi-nodes: 0ms DEBUG cranelift_codegen::timing > timing: Starting Verify Cranelift IR, (during Compilation passes) DEBUG cranelift_codegen::timing > timing: Starting Control flow graph, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Control flow graph: 0ms DEBUG cranelift_codegen::timing > timing: Starting Dominator tree, (during Verify Cranelift IR) DEBUG cranelift_codegen::timing > timing: Ending Dominator tree: 0ms DEBUG cranelift_codegen::timing > timing: Ending Verify Cranelift IR: 0ms TRACE cranelift_codegen::machinst::abi > ABISig: sig Signature { params: [AbiParam { value_type: types::I64, purpose: Normal, extension: None }], returns: [AbiParam { value_type: types::I16, purpose: Normal, extension: None }, AbiParam { value_type: types::I16, purpose: Normal, extension: None }], call_conv: Fast } => args end = 3 rets end = 2 arg stack = 0 ret stack = 0 stack_ret_arg = false TRACE cranelift_codegen::machinst::abi > ABI: func signature Signature { params: [AbiParam { value_type: types::I64, purpose: Normal, extension: None }], returns: [AbiParam { value_type: types::I16, purpose: Normal, extension: None }, AbiParam { value_type: types::I16, purpose: Normal, extension: None }], call_conv: Fast } TRACE cranelift_codegen::machinst::blockorder > BlockLoweringOrder: function body function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } TRACE cranelift_codegen::machinst::blockorder > BlockLoweringOrder: BlockLoweringOrder { lowered_order: [ Orig { block: block0, }, ], lowered_succ_indices: [], lowered_succ_ranges: [ ( None, 0..0, ), ], cold_blocks: {}, indirect_branch_targets: {}, } TRACE cranelift_codegen::machinst::lower > bb block0 param v0: regs ValueRegs { parts: [v192, v2097151] } TRACE cranelift_codegen::machinst::lower > bb block0 inst inst0 (Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(0) }): result v1 regs ValueRegs { parts: [v193, v2097151] } TRACE cranelift_codegen::machinst::lower > bb block0 inst inst1 (Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(2) }): result v2 regs ValueRegs { parts: [v194, v2097151] } TRACE cranelift_codegen::machinst::lower > bb block0 inst inst0 has color 1 TRACE cranelift_codegen::machinst::lower > -> side-effecting; incrementing color for next inst TRACE cranelift_codegen::machinst::lower > bb block0 inst inst1 has color 2 TRACE cranelift_codegen::machinst::lower > -> side-effecting; incrementing color for next inst TRACE cranelift_codegen::machinst::lower > bb block0 inst inst2 has color 3 TRACE cranelift_codegen::machinst::lower > -> side-effecting; incrementing color for next inst TRACE cranelift_codegen::machinst::lower > arg v0 used, old state Unused, new Once TRACE cranelift_codegen::machinst::lower > arg v0 used, old state Once, new Multiple TRACE cranelift_codegen::machinst::lower > -> pushing args for v0 onto stack TRACE cranelift_codegen::machinst::lower > arg v1 used, old state Unused, new Once TRACE cranelift_codegen::machinst::lower > arg v2 used, old state Unused, new Once DEBUG cranelift_codegen::machinst::compile > Number of CLIF instructions to lower: 3 DEBUG cranelift_codegen::machinst::compile > Number of CLIF blocks to lower: 1 DEBUG cranelift_codegen::timing > timing: Starting VCode lowering, (during Compilation passes) TRACE cranelift_codegen::machinst::lower > about to lower function: function %c_lh(i64) -> i16, i16 fast { block0(v0: i64): v1 = load.i16 v0 v2 = load.i16 v0+2 return v1, v2 } TRACE cranelift_codegen::machinst::lower > lower_clif_block: block block0 inst inst2 (MultiAry { opcode: Return, args: EntityList { index: 13, unused: PhantomData } }) is_branch false side_effect true value_needed false TRACE cranelift_codegen::machinst::lower > lowering: inst inst2: MultiAry { opcode: Return, args: EntityList { index: 13, unused: PhantomData } } TRACE cranelift_codegen::machinst::lower > put_value_in_regs: val v1 TRACE cranelift_codegen::machinst::lower > -> regs ValueRegs { parts: [v193, v2097151] } TRACE cranelift_codegen::machinst::lower > put_value_in_regs: val v2 TRACE cranelift_codegen::machinst::lower > -> regs ValueRegs { parts: [v194, v2097151] } TRACE cranelift_codegen::machinst::lower > emit: Rets { rets: [RetPair { vreg: v193, preg: p10i }, RetPair { vreg: v194, preg: p11i }] } TRACE cranelift_codegen::machinst::lower > lower_clif_block: block block0 inst inst1 (Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(2) }) is_branch false side_effect true value_needed true TRACE cranelift_codegen::machinst::lower > lowering: inst inst1: Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(2) } TRACE cranelift_codegen::machinst::lower > put_value_in_regs: val v0 TRACE cranelift_codegen::machinst::lower > -> regs ValueRegs { parts: [v192, v2097151] } TRACE cranelift_codegen::machinst::lower > emit: Load { rd: Writable { reg: v195 }, op: Lh, flags: MemFlags { bits: 0 }, from: RegOffset(v192, 2, types::I16) } TRACE cranelift_codegen::machinst::lower > set vreg alias: from v194 to v195 TRACE cranelift_codegen::machinst::lower > lower_clif_block: block block0 inst inst0 (Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(0) }) is_branch false side_effect true value_needed true TRACE cranelift_codegen::machinst::lower > lowering: inst inst0: Load { opcode: Load, arg: v0, flags: MemFlags { bits: 0 }, offset: Offset32(0) } TRACE cranelift_codegen::machinst::lower > put_value_in_regs: val v0 TRACE cranelift_codegen::machinst::lower > -> regs ValueRegs { parts: [v192, v2097151] } TRACE cranelift_codegen::machinst::lower > emit: Load { rd: Writable { reg: v196 }, op: Lh, flags: MemFlags { bits: 0 }, from: RegOffset(v192, 0, types::I16) } TRACE cranelift_codegen::machinst::lower > set vreg alias: from v193 to v196 TRACE cranelift_codegen::machinst::lower > gen_arg_setup: entry BB block0 args are: [v0] TRACE cranelift_codegen::machinst::abi > gen_retval_area_setup: not needed TRACE cranelift_codegen::machinst::lower > emit: Args { args: [ArgPair { vreg: Writable { reg: v192 }, preg: p10i }] } TRACE cranelift_codegen::machinst::lower > built vcode: VCode { Entry block: 0 v193 := v196 v194 := v195 Block 0: (original IR block: block0) (instruction range: 0 .. 4) Inst 0: args v192=a0 Inst 1: lh v196,0(v192) Inst 2: lh v195,2(v192) Inst 3: rets v193=a0 v194=a1 } DEBUG cranelift_codegen::timing > timing: Ending VCode lowering: 3ms DEBUG cranelift_codegen::machinst::compile > Number of lowered vcode instructions: 4 DEBUG cranelift_codegen::machinst::compile > Number of lowered vcode blocks: 1 TRACE cranelift_codegen::machinst::compile > vcode from lowering: VCode { Entry block: 0 v193 := v196 v194 := v195 Block 0: (original IR block: block0) (instruction range: 0 .. 4) Inst 0: args v192=a0 Inst 1: lh v196,0(v192) Inst 2: lh v195,2(v192) Inst 3: rets v193=a0 v194=a1 } DEBUG cranelift_codegen::timing > timing: Starting Register allocation, (during Compilation passes) TRACE regalloc2::ion::liveranges > computing liveins for block0 TRACE regalloc2::ion::liveranges > -> initial liveout set: [] TRACE regalloc2::ion::liveranges > op Use: v196i fixed(p10i) was_live = false TRACE regalloc2::ion::liveranges > op Use: v195i fixed(p11i) was_live = false TRACE regalloc2::ion::liveranges > op Def: v195i reg was_live = true TRACE regalloc2::ion::liveranges > op Use: v192i reg was_live = false TRACE regalloc2::ion::liveranges > op Def: v196i reg was_live = true TRACE regalloc2::ion::liveranges > op Use: v192i reg was_live = true TRACE regalloc2::ion::liveranges > op Def: v192i fixed(p10i) was_live = true TRACE regalloc2::ion::liveranges > computed liveins at block0: [] TRACE regalloc2::ion::liveranges > processing inst3 operand at progpoint3-pre: Use: v196i fixed(p10i) TRACE regalloc2::ion::liveranges > add_liverange_to_vreg: vreg VRegIndex(196) range CodeRange { from: progpoint0-pre, to: progpoint3-post } TRACE regalloc2::ion::liveranges > Use of Use: v196i fixed(p10i) at progpoint3-pre -> LiveRangeIndex(0) TRACE regalloc2::ion::liveranges > insert use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } into lr LiveRangeIndex(0) with weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > processing inst3 operand at progpoint3-pre: Use: v195i fixed(p11i) TRACE regalloc2::ion::liveranges > add_liverange_to_vreg: vreg VRegIndex(195) range CodeRange { from: progpoint0-pre, to: progpoint3-post } TRACE regalloc2::ion::liveranges > Use of Use: v195i fixed(p11i) at progpoint3-pre -> LiveRangeIndex(1) TRACE regalloc2::ion::liveranges > insert use Use { operand: Use: v195i fixed(p11i), pos: progpoint3-pre, slot: 1, weight: 35447 } into lr LiveRangeIndex(1) with weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > processing inst2 operand at progpoint2-post: Def: v195i reg TRACE regalloc2::ion::liveranges > Def of v195 at progpoint2-post TRACE regalloc2::ion::liveranges > -> has existing LR LiveRangeIndex(1) TRACE regalloc2::ion::liveranges > insert use Use { operand: Def: v195i reg, pos: progpoint2-post, slot: 1, weight: 35640 } into lr LiveRangeIndex(1) with weight SpillWeight(5000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(8000.0) TRACE regalloc2::ion::liveranges > -> started at block start; trimming to progpoint2-post TRACE regalloc2::ion::liveranges > processing inst2 operand at progpoint2-pre: Use: v192i reg TRACE regalloc2::ion::liveranges > add_liverange_to_vreg: vreg VRegIndex(192) range CodeRange { from: progpoint0-pre, to: progpoint2-post } TRACE regalloc2::ion::liveranges > Use of Use: v192i reg at progpoint2-pre -> LiveRangeIndex(2) TRACE regalloc2::ion::liveranges > insert use Use { operand: Use: v192i reg, pos: progpoint2-pre, slot: 0, weight: 35447 } into lr LiveRangeIndex(2) with weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > processing inst1 operand at progpoint1-post: Def: v196i reg TRACE regalloc2::ion::liveranges > Def of v196 at progpoint1-post TRACE regalloc2::ion::liveranges > -> has existing LR LiveRangeIndex(0) TRACE regalloc2::ion::liveranges > insert use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } into lr LiveRangeIndex(0) with weight SpillWeight(5000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(8000.0) TRACE regalloc2::ion::liveranges > -> started at block start; trimming to progpoint1-post TRACE regalloc2::ion::liveranges > processing inst1 operand at progpoint1-pre: Use: v192i reg TRACE regalloc2::ion::liveranges > Use of Use: v192i reg at progpoint1-pre -> LiveRangeIndex(2) TRACE regalloc2::ion::liveranges > insert use Use { operand: Use: v192i reg, pos: progpoint1-pre, slot: 0, weight: 35447 } into lr LiveRangeIndex(2) with weight SpillWeight(3000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(6000.0) TRACE regalloc2::ion::liveranges > processing inst0 operand at progpoint0-post: Def: v192i fixed(p10i) TRACE regalloc2::ion::liveranges > Def of v192 at progpoint0-post TRACE regalloc2::ion::liveranges > -> has existing LR LiveRangeIndex(2) TRACE regalloc2::ion::liveranges > insert use Use { operand: Def: v192i fixed(p10i), pos: progpoint0-post, slot: 0, weight: 35640 } into lr LiveRangeIndex(2) with weight SpillWeight(5000.0) TRACE regalloc2::ion::liveranges > -> now range has weight SpillWeight(11000.0) TRACE regalloc2::ion::liveranges > -> started at block start; trimming to progpoint0-post TRACE regalloc2::ion::liveranges > multi-fixed-reg cleanup: vreg VRegIndex(192) range LiveRangeIndex(2) TRACE regalloc2::ion::liveranges > multi-fixed-reg cleanup: vreg VRegIndex(195) range LiveRangeIndex(1) TRACE regalloc2::ion::liveranges > multi-fixed-reg cleanup: vreg VRegIndex(196) range LiveRangeIndex(0) TRACE regalloc2::ion::merge > merge_vreg_bundles: creating vreg bundles TRACE regalloc2::ion::merge > vreg v192 gets bundle0 TRACE regalloc2::ion::merge > -> with LR range2: CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::merge > vreg v195 gets bundle1 TRACE regalloc2::ion::merge > -> with LR range1: CodeRange { from: progpoint2-post, to: progpoint3-post } TRACE regalloc2::ion::merge > vreg v196 gets bundle2 TRACE regalloc2::ion::merge > -> with LR range0: CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::merge > done merging bundles TRACE regalloc2::ion::merge > enqueueing bundle0 TRACE regalloc2::ion::merge > -> prio 2 TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(0) TRACE regalloc2::ion::process > -> use: Use { operand: Def: v192i fixed(p10i), pos: progpoint0-post, slot: 0, weight: 35640 } TRACE regalloc2::ion::process > -> fixed operand at progpoint0-post: Def: v192i fixed(p10i) TRACE regalloc2::ion::process > -> is fixed def TRACE regalloc2::ion::process > -> use: Use { operand: Use: v192i reg, pos: progpoint1-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> use: Use { operand: Use: v192i reg, pos: progpoint2-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::process > -> minimal: false TRACE regalloc2::ion::process > -> uses spill weight: +SpillWeight(11000.0) TRACE regalloc2::ion::process > -> dividing by prio 2; final weight 5500 TRACE regalloc2::ion::merge > enqueueing bundle1 TRACE regalloc2::ion::merge > -> prio 1 TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(1) TRACE regalloc2::ion::process > -> use: Use { operand: Def: v195i reg, pos: progpoint2-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::process > -> use: Use { operand: Use: v195i fixed(p11i), pos: progpoint3-pre, slot: 1, weight: 35447 } TRACE regalloc2::ion::process > -> fixed operand at progpoint3-pre: Use: v195i fixed(p11i) TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint2-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> minimal: false TRACE regalloc2::ion::process > -> uses spill weight: +SpillWeight(8000.0) TRACE regalloc2::ion::process > -> dividing by prio 1; final weight 8000 TRACE regalloc2::ion::merge > enqueueing bundle2 TRACE regalloc2::ion::merge > -> prio 2 TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(2) TRACE regalloc2::ion::process > -> use: Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::process > -> use: Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> fixed operand at progpoint3-pre: Use: v196i fixed(p10i) TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> minimal: false TRACE regalloc2::ion::process > -> uses spill weight: +SpillWeight(8000.0) TRACE regalloc2::ion::process > -> dividing by prio 2; final weight 4000 TRACE regalloc2::ion::dump > Bundles: TRACE regalloc2::ion::dump > bundle0: spillset=SpillSetIndex(0) alloc=none TRACE regalloc2::ion::dump > * range progpoint0-post -- progpoint2-post: range2 TRACE regalloc2::ion::dump > bundle1: spillset=SpillSetIndex(1) alloc=none TRACE regalloc2::ion::dump > * range progpoint2-post -- progpoint3-post: range1 TRACE regalloc2::ion::dump > bundle2: spillset=SpillSetIndex(2) alloc=none TRACE regalloc2::ion::dump > * range progpoint1-post -- progpoint3-post: range0 TRACE regalloc2::ion::dump > VRegs: TRACE regalloc2::ion::dump > vreg0: TRACE regalloc2::ion::dump > vreg1: TRACE regalloc2::ion::dump > vreg2: TRACE regalloc2::ion::dump > vreg3: TRACE regalloc2::ion::dump > vreg4: TRACE regalloc2::ion::dump > vreg5: TRACE regalloc2::ion::dump > vreg6: TRACE regalloc2::ion::dump > vreg7: TRACE regalloc2::ion::dump > vreg8: TRACE regalloc2::ion::dump > vreg9: TRACE regalloc2::ion::dump > vreg10: TRACE regalloc2::ion::dump > vreg11: TRACE regalloc2::ion::dump > vreg12: TRACE regalloc2::ion::dump > vreg13: TRACE regalloc2::ion::dump > vreg14: TRACE regalloc2::ion::dump > vreg15: TRACE regalloc2::ion::dump > vreg16: TRACE regalloc2::ion::dump > vreg17: TRACE regalloc2::ion::dump > vreg18: TRACE regalloc2::ion::dump > vreg19: TRACE regalloc2::ion::dump > vreg20: TRACE regalloc2::ion::dump > vreg21: TRACE regalloc2::ion::dump > vreg22: TRACE regalloc2::ion::dump > vreg23: TRACE regalloc2::ion::dump > vreg24: TRACE regalloc2::ion::dump > vreg25: TRACE regalloc2::ion::dump > vreg26: TRACE regalloc2::ion::dump > vreg27: TRACE regalloc2::ion::dump > vreg28: TRACE regalloc2::ion::dump > vreg29: TRACE regalloc2::ion::dump > vreg30: TRACE regalloc2::ion::dump > vreg31: TRACE regalloc2::ion::dump > vreg32: TRACE regalloc2::ion::dump > vreg33: TRACE regalloc2::ion::dump > vreg34: TRACE regalloc2::ion::dump > vreg35: TRACE regalloc2::ion::dump > vreg36: TRACE regalloc2::ion::dump > vreg37: TRACE regalloc2::ion::dump > vreg38: TRACE regalloc2::ion::dump > vreg39: TRACE regalloc2::ion::dump > vreg40: TRACE regalloc2::ion::dump > vreg41: TRACE regalloc2::ion::dump > vreg42: TRACE regalloc2::ion::dump > vreg43: TRACE regalloc2::ion::dump > vreg44: TRACE regalloc2::ion::dump > vreg45: TRACE regalloc2::ion::dump > vreg46: TRACE regalloc2::ion::dump > vreg47: TRACE regalloc2::ion::dump > vreg48: TRACE regalloc2::ion::dump > vreg49: TRACE regalloc2::ion::dump > vreg50: TRACE regalloc2::ion::dump > vreg51: TRACE regalloc2::ion::dump > vreg52: TRACE regalloc2::ion::dump > vreg53: TRACE regalloc2::ion::dump > vreg54: TRACE regalloc2::ion::dump > vreg55: TRACE regalloc2::ion::dump > vreg56: TRACE regalloc2::ion::dump > vreg57: TRACE regalloc2::ion::dump > vreg58: TRACE regalloc2::ion::dump > vreg59: TRACE regalloc2::ion::dump > vreg60: TRACE regalloc2::ion::dump > vreg61: TRACE regalloc2::ion::dump > vreg62: TRACE regalloc2::ion::dump > vreg63: TRACE regalloc2::ion::dump > vreg64: TRACE regalloc2::ion::dump > vreg65: TRACE regalloc2::ion::dump > vreg66: TRACE regalloc2::ion::dump > vreg67: TRACE regalloc2::ion::dump > vreg68: TRACE regalloc2::ion::dump > vreg69: TRACE regalloc2::ion::dump > vreg70: TRACE regalloc2::ion::dump > vreg71: TRACE regalloc2::ion::dump > vreg72: TRACE regalloc2::ion::dump > vreg73: TRACE regalloc2::ion::dump > vreg74: TRACE regalloc2::ion::dump > vreg75: TRACE regalloc2::ion::dump > vreg76: TRACE regalloc2::ion::dump > vreg77: TRACE regalloc2::ion::dump > vreg78: TRACE regalloc2::ion::dump > vreg79: TRACE regalloc2::ion::dump > vreg80: TRACE regalloc2::ion::dump > vreg81: TRACE regalloc2::ion::dump > vreg82: TRACE regalloc2::ion::dump > vreg83: TRACE regalloc2::ion::dump > vreg84: TRACE regalloc2::ion::dump > vreg85: TRACE regalloc2::ion::dump > vreg86: TRACE regalloc2::ion::dump > vreg87: TRACE regalloc2::ion::dump > vreg88: TRACE regalloc2::ion::dump > vreg89: TRACE regalloc2::ion::dump > vreg90: TRACE regalloc2::ion::dump > vreg91: TRACE regalloc2::ion::dump > vreg92: TRACE regalloc2::ion::dump > vreg93: TRACE regalloc2::ion::dump > vreg94: TRACE regalloc2::ion::dump > vreg95: TRACE regalloc2::ion::dump > vreg96: TRACE regalloc2::ion::dump > vreg97: TRACE regalloc2::ion::dump > vreg98: TRACE regalloc2::ion::dump > vreg99: TRACE regalloc2::ion::dump > vreg100: TRACE regalloc2::ion::dump > vreg101: TRACE regalloc2::ion::dump > vreg102: TRACE regalloc2::ion::dump > vreg103: TRACE regalloc2::ion::dump > vreg104: TRACE regalloc2::ion::dump > vreg105: TRACE regalloc2::ion::dump > vreg106: TRACE regalloc2::ion::dump > vreg107: TRACE regalloc2::ion::dump > vreg108: TRACE regalloc2::ion::dump > vreg109: TRACE regalloc2::ion::dump > vreg110: TRACE regalloc2::ion::dump > vreg111: TRACE regalloc2::ion::dump > vreg112: TRACE regalloc2::ion::dump > vreg113: TRACE regalloc2::ion::dump > vreg114: TRACE regalloc2::ion::dump > vreg115: TRACE regalloc2::ion::dump > vreg116: TRACE regalloc2::ion::dump > vreg117: TRACE regalloc2::ion::dump > vreg118: TRACE regalloc2::ion::dump > vreg119: TRACE regalloc2::ion::dump > vreg120: TRACE regalloc2::ion::dump > vreg121: TRACE regalloc2::ion::dump > vreg122: TRACE regalloc2::ion::dump > vreg123: TRACE regalloc2::ion::dump > vreg124: TRACE regalloc2::ion::dump > vreg125: TRACE regalloc2::ion::dump > vreg126: TRACE regalloc2::ion::dump > vreg127: TRACE regalloc2::ion::dump > vreg128: TRACE regalloc2::ion::dump > vreg129: TRACE regalloc2::ion::dump > vreg130: TRACE regalloc2::ion::dump > vreg131: TRACE regalloc2::ion::dump > vreg132: TRACE regalloc2::ion::dump > vreg133: TRACE regalloc2::ion::dump > vreg134: TRACE regalloc2::ion::dump > vreg135: TRACE regalloc2::ion::dump > vreg136: TRACE regalloc2::ion::dump > vreg137: TRACE regalloc2::ion::dump > vreg138: TRACE regalloc2::ion::dump > vreg139: TRACE regalloc2::ion::dump > vreg140: TRACE regalloc2::ion::dump > vreg141: TRACE regalloc2::ion::dump > vreg142: TRACE regalloc2::ion::dump > vreg143: TRACE regalloc2::ion::dump > vreg144: TRACE regalloc2::ion::dump > vreg145: TRACE regalloc2::ion::dump > vreg146: TRACE regalloc2::ion::dump > vreg147: TRACE regalloc2::ion::dump > vreg148: TRACE regalloc2::ion::dump > vreg149: TRACE regalloc2::ion::dump > vreg150: TRACE regalloc2::ion::dump > vreg151: TRACE regalloc2::ion::dump > vreg152: TRACE regalloc2::ion::dump > vreg153: TRACE regalloc2::ion::dump > vreg154: TRACE regalloc2::ion::dump > vreg155: TRACE regalloc2::ion::dump > vreg156: TRACE regalloc2::ion::dump > vreg157: TRACE regalloc2::ion::dump > vreg158: TRACE regalloc2::ion::dump > vreg159: TRACE regalloc2::ion::dump > vreg160: TRACE regalloc2::ion::dump > vreg161: TRACE regalloc2::ion::dump > vreg162: TRACE regalloc2::ion::dump > vreg163: TRACE regalloc2::ion::dump > vreg164: TRACE regalloc2::ion::dump > vreg165: TRACE regalloc2::ion::dump > vreg166: TRACE regalloc2::ion::dump > vreg167: TRACE regalloc2::ion::dump > vreg168: TRACE regalloc2::ion::dump > vreg169: TRACE regalloc2::ion::dump > vreg170: TRACE regalloc2::ion::dump > vreg171: TRACE regalloc2::ion::dump > vreg172: TRACE regalloc2::ion::dump > vreg173: TRACE regalloc2::ion::dump > vreg174: TRACE regalloc2::ion::dump > vreg175: TRACE regalloc2::ion::dump > vreg176: TRACE regalloc2::ion::dump > vreg177: TRACE regalloc2::ion::dump > vreg178: TRACE regalloc2::ion::dump > vreg179: TRACE regalloc2::ion::dump > vreg180: TRACE regalloc2::ion::dump > vreg181: TRACE regalloc2::ion::dump > vreg182: TRACE regalloc2::ion::dump > vreg183: TRACE regalloc2::ion::dump > vreg184: TRACE regalloc2::ion::dump > vreg185: TRACE regalloc2::ion::dump > vreg186: TRACE regalloc2::ion::dump > vreg187: TRACE regalloc2::ion::dump > vreg188: TRACE regalloc2::ion::dump > vreg189: TRACE regalloc2::ion::dump > vreg190: TRACE regalloc2::ion::dump > vreg191: TRACE regalloc2::ion::dump > vreg192: TRACE regalloc2::ion::dump > * range progpoint0-post -- progpoint2-post: range2 TRACE regalloc2::ion::dump > vreg193: TRACE regalloc2::ion::dump > vreg194: TRACE regalloc2::ion::dump > vreg195: TRACE regalloc2::ion::dump > * range progpoint2-post -- progpoint3-post: range1 TRACE regalloc2::ion::dump > vreg196: TRACE regalloc2::ion::dump > * range progpoint1-post -- progpoint3-post: range0 TRACE regalloc2::ion::dump > Ranges: TRACE regalloc2::ion::dump > range0: range=CodeRange { from: progpoint1-post, to: progpoint3-post } vreg=VRegIndex(196) bundle=LiveBundleIndex(2) weight=SpillWeight(8000.0) TRACE regalloc2::ion::dump > * use at progpoint1-post (slot 1): Def: v196i reg TRACE regalloc2::ion::dump > * use at progpoint3-pre (slot 0): Use: v196i fixed(p10i) TRACE regalloc2::ion::dump > range1: range=CodeRange { from: progpoint2-post, to: progpoint3-post } vreg=VRegIndex(195) bundle=LiveBundleIndex(1) weight=SpillWeight(8000.0) TRACE regalloc2::ion::dump > * use at progpoint2-post (slot 1): Def: v195i reg TRACE regalloc2::ion::dump > * use at progpoint3-pre (slot 1): Use: v195i fixed(p11i) TRACE regalloc2::ion::dump > range2: range=CodeRange { from: progpoint0-post, to: progpoint2-post } vreg=VRegIndex(192) bundle=LiveBundleIndex(0) weight=SpillWeight(11000.0) TRACE regalloc2::ion::dump > * use at progpoint0-post (slot 0): Def: v192i fixed(p10i) TRACE regalloc2::ion::dump > * use at progpoint1-pre (slot 0): Use: v192i reg TRACE regalloc2::ion::dump > * use at progpoint2-pre (slot 0): Use: v192i reg TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(2) hint PReg(hw = 63, class = Int, index = 63) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(2) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::requirement > -> req Register TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(2) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 3, to: 3 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(2) assigned to preg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(10) TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(0) hint PReg(hw = 63, class = Int, index = 63) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(0) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(2): CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v192i fixed(p10i), pos: progpoint0-post, slot: 0, weight: 35640 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v192i reg, pos: progpoint1-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v192i reg, pos: progpoint2-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(0) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 1, to: 1 }..: {LiveRangeKey { from: 3, to: 7 }: LiveRangeIndex(0)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(2): CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 3, to: 7 }, LiveRangeIndex(0))) TRACE regalloc2::ion::process > -> btree contains range LiveRangeIndex(0) that overlaps TRACE regalloc2::ion::process > -> from vreg VRegIndex(196) TRACE regalloc2::ion::process > -> conflict bundle LiveBundleIndex(2) TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> conflict with bundles [LiveBundleIndex(2)], first conflict at progpoint1-post TRACE regalloc2::ion::process > maximum_spill_weight_in_bundle_set: [LiveBundleIndex(2)] TRACE regalloc2::ion::process > bundle2: 4000 TRACE regalloc2::ion::process > -> max: 4000 TRACE regalloc2::ion::process > -> lowest cost evict: set Some([LiveBundleIndex(2)]), cost Some(4000) TRACE regalloc2::ion::process > -> lowest cost split: cost Some(9000), point progpoint1-post, reg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> our spill weight: 5500 TRACE regalloc2::ion::process > -> evicting LiveBundleIndex(2) TRACE regalloc2::ion::process > evicting bundle LiveBundleIndex(2): alloc p10i TRACE regalloc2::ion::process > -> removing LR LiveRangeIndex(0) from reg PRegIndex(10) TRACE regalloc2::ion::process > -> prio 2; back into queue TRACE regalloc2::ion::process > attempt 2, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(0) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 1, to: 1 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(2): CodeRange { from: progpoint0-post, to: progpoint2-post } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(0) assigned to preg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(10) TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(2) hint PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(2) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::requirement > -> req Register TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(2) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 3, to: 3 }..: {LiveRangeKey { from: 1, to: 5 }: LiveRangeIndex(2)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 1, to: 5 }, LiveRangeIndex(2))) TRACE regalloc2::ion::process > -> btree contains range LiveRangeIndex(2) that overlaps TRACE regalloc2::ion::process > -> from vreg VRegIndex(192) TRACE regalloc2::ion::process > -> conflict bundle LiveBundleIndex(0) TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> conflict with bundles [LiveBundleIndex(0)], first conflict at progpoint1-post TRACE regalloc2::ion::process > maximum_spill_weight_in_bundle_set: [LiveBundleIndex(0)] TRACE regalloc2::ion::process > bundle0: 5500 TRACE regalloc2::ion::process > -> max: 5500 TRACE regalloc2::ion::process > -> lowest cost evict: set Some([LiveBundleIndex(0)]), cost Some(5500) TRACE regalloc2::ion::process > -> lowest cost split: cost Some(10500), point progpoint1-post, reg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> our spill weight: 4000 TRACE regalloc2::ion::process > -> deciding to split: our spill weight is 4000 TRACE regalloc2::ion::process > split bundle LiveBundleIndex(2) at progpoint1-post and requeue with reg hint (for first part) PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> first use loc is Some(progpoint1-post) TRACE regalloc2::ion::process > split point is at bundle start; advancing to progpoint2-pre TRACE regalloc2::ion::process > -> LRs: [LiveRangeListEntry { range: CodeRange { from: progpoint1-post, to: progpoint3-post }, index: LiveRangeIndex(0) }] TRACE regalloc2::ion::process > -> last LR in old bundle: LR LiveRangeListEntry { range: CodeRange { from: progpoint1-post, to: progpoint3-post }, index: LiveRangeIndex(0) } TRACE regalloc2::ion::process > -> first LR in new bundle: LR LiveRangeListEntry { range: CodeRange { from: progpoint1-post, to: progpoint3-post }, index: LiveRangeIndex(0) } TRACE regalloc2::ion::process > -> splitting LR LiveRangeIndex(0) into LiveRangeIndex(3) TRACE regalloc2::ion::process > range0: use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::process > range3: use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> creating new bundle LiveBundleIndex(3) TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(2) range LiveRangeIndex(3): first use implies split point progpoint3-pre TRACE regalloc2::ion::process > -> moving leading empty region to new spill bundle LiveBundleIndex(4) with new LR LiveRangeIndex(4) TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(2) TRACE regalloc2::ion::process > -> use: Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint1-post, to: progpoint2-pre } TRACE regalloc2::ion::process > -> minimal: true TRACE regalloc2::ion::process > -> non-fixed and minimal TRACE regalloc2::ion::process > recompute bundle properties: bundle LiveBundleIndex(3) TRACE regalloc2::ion::process > -> use: Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::process > -> fixed operand at progpoint3-pre: Use: v196i fixed(p10i) TRACE regalloc2::ion::process > -> first range has range CodeRange { from: progpoint3-pre, to: progpoint3-post } TRACE regalloc2::ion::process > -> minimal: true TRACE regalloc2::ion::process > -> fixed and minimal TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(2) hint PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(2) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint2-pre } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::requirement > -> req Register TRACE regalloc2::ion::requirement > -> final: Register TRACE regalloc2::ion::process > attempt 1, req Register TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(2) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 3, to: 3 }..: {LiveRangeKey { from: 1, to: 5 }: LiveRangeIndex(2)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint2-pre } TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 1, to: 5 }, LiveRangeIndex(2))) TRACE regalloc2::ion::process > -> btree contains range LiveRangeIndex(2) that overlaps TRACE regalloc2::ion::process > -> from vreg VRegIndex(192) TRACE regalloc2::ion::process > -> conflict bundle LiveBundleIndex(0) TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> conflict with bundles [LiveBundleIndex(0)], first conflict at progpoint1-post TRACE regalloc2::ion::process > maximum_spill_weight_in_bundle_set: [LiveBundleIndex(0)] TRACE regalloc2::ion::process > bundle0: 5500 TRACE regalloc2::ion::process > -> max: 5500 TRACE regalloc2::ion::process > trying preg PRegIndex(13) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(2) -> PRegIndex(13) TRACE regalloc2::ion::process > alloc map for PRegIndex(13) in range LiveRangeKey { from: 3, to: 3 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(0): CodeRange { from: progpoint1-post, to: progpoint2-pre } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(2) assigned to preg PReg(hw = 13, class = Int, index = 13) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(13) TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(1) hint PReg(hw = 63, class = Int, index = 63) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(1) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(1): CodeRange { from: progpoint2-post, to: progpoint3-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Def: v195i reg, pos: progpoint2-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::requirement > -> req Register TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v195i fixed(p11i), pos: progpoint3-pre, slot: 1, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 11, class = Int, index = 11)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 11, class = Int, index = 11)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 11, class = Int, index = 11)) TRACE regalloc2::ion::process > trying preg PRegIndex(11) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(1) -> PRegIndex(11) TRACE regalloc2::ion::process > alloc map for PRegIndex(11) in range LiveRangeKey { from: 5, to: 5 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(1): CodeRange { from: progpoint2-post, to: progpoint3-post } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(1) assigned to preg PReg(hw = 11, class = Int, index = 11) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(11) TRACE regalloc2::ion::process > process_bundle: bundle LiveBundleIndex(3) hint PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::requirement > compute_requirement: LiveBundleIndex(3) TRACE regalloc2::ion::requirement > -> LR LiveRangeIndex(3): CodeRange { from: progpoint3-pre, to: progpoint3-post } TRACE regalloc2::ion::requirement > -> use Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::requirement > -> req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::requirement > -> final: FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > attempt 1, req FixedReg(PReg(hw = 10, class = Int, index = 10)) TRACE regalloc2::ion::process > trying preg PRegIndex(10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(3) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 6, to: 6 }..: {LiveRangeKey { from: 1, to: 5 }: LiveRangeIndex(2)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(3): CodeRange { from: progpoint3-pre, to: progpoint3-post } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(3) assigned to preg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > -> allocated to any PRegIndex(10) TRACE regalloc2::ion::spill > allocating regs for spilled bundles TRACE regalloc2::ion::spill > trying bundle LiveBundleIndex(4) to preg PReg(hw = 10, class = Int, index = 10) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(4) -> PRegIndex(10) TRACE regalloc2::ion::process > alloc map for PRegIndex(10) in range LiveRangeKey { from: 4, to: 4 }..: {LiveRangeKey { from: 1, to: 5 }: LiveRangeIndex(2), LiveRangeKey { from: 6, to: 7 }: LiveRangeIndex(3)} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(4): CodeRange { from: progpoint2-pre, to: progpoint3-pre } TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 1, to: 5 }, LiveRangeIndex(2))) TRACE regalloc2::ion::process > -> btree contains range LiveRangeIndex(2) that overlaps TRACE regalloc2::ion::process > -> from vreg VRegIndex(192) TRACE regalloc2::ion::process > -> conflict bundle LiveBundleIndex(0) TRACE regalloc2::ion::process > -> PReg range Some((LiveRangeKey { from: 6, to: 7 }, LiveRangeIndex(3))) TRACE regalloc2::ion::process > -> next PReg allocation is at LiveRangeKey { from: 6, to: 7 }; moving to next VReg range TRACE regalloc2::ion::spill > trying bundle LiveBundleIndex(4) to preg PReg(hw = 14, class = Int, index = 14) TRACE regalloc2::ion::process > try_to_allocate_bundle_to_reg: LiveBundleIndex(4) -> PRegIndex(14) TRACE regalloc2::ion::process > alloc map for PRegIndex(14) in range LiveRangeKey { from: 4, to: 4 }..: {} TRACE regalloc2::ion::process > -> range LR LiveRangeIndex(4): CodeRange { from: progpoint2-pre, to: progpoint3-pre } TRACE regalloc2::ion::process > -> PReg range None TRACE regalloc2::ion::process > -> no more PReg allocations; so no conflict possible! TRACE regalloc2::ion::process > -> bundle LiveBundleIndex(4) assigned to preg PReg(hw = 14, class = Int, index = 14) TRACE regalloc2::ion::spill > allocate spillslot: 0 TRACE regalloc2::ion::spill > allocate spillslot: 1 TRACE regalloc2::ion::spill > allocate spillslot: 2 TRACE regalloc2::ion::spill > spillslot allocator done TRACE regalloc2::ion::moves > apply_allocations_and_insert_moves TRACE regalloc2::ion::moves > blockparam_ins: [] TRACE regalloc2::ion::moves > blockparam_outs: [] TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(2) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(0) TRACE regalloc2::ion::moves > -> allocation p10i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(192) LR LiveRangeIndex(2) with range CodeRange { from: progpoint0-post, to: progpoint2-post } has alloc p10i TRACE regalloc2::ion::moves > applying to use: Use { operand: Def: v192i fixed(p10i), pos: progpoint0-post, slot: 0, weight: 35640 } TRACE regalloc2::ion::moves > applying to use: Use { operand: Use: v192i reg, pos: progpoint1-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::moves > applying to use: Use { operand: Use: v192i reg, pos: progpoint2-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(1) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(1) TRACE regalloc2::ion::moves > -> allocation p11i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(195) LR LiveRangeIndex(1) with range CodeRange { from: progpoint2-post, to: progpoint3-post } has alloc p11i TRACE regalloc2::ion::moves > applying to use: Use { operand: Def: v195i reg, pos: progpoint2-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::moves > applying to use: Use { operand: Use: v195i fixed(p11i), pos: progpoint3-pre, slot: 1, weight: 35447 } TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(0) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(2) TRACE regalloc2::ion::moves > -> allocation p13i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(196) LR LiveRangeIndex(0) with range CodeRange { from: progpoint1-post, to: progpoint2-pre } has alloc p13i TRACE regalloc2::ion::moves > applying to use: Use { operand: Def: v196i reg, pos: progpoint1-post, slot: 1, weight: 35640 } TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(4) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(4) TRACE regalloc2::ion::moves > -> allocation p14i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(196) LR LiveRangeIndex(4) with range CodeRange { from: progpoint2-pre, to: progpoint3-pre } has alloc p14i TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(0) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(2) TRACE regalloc2::ion::moves > -> allocation p13i TRACE regalloc2::ion::moves > prev LR 0 abuts LR 4 in same block; moving p13i -> p14i for v196 TRACE regalloc2::ion::data_structures > insert_move: pos progpoint2-pre prio Regular from_alloc p13i to_alloc p14i to_vreg VReg(vreg = 196, class = Int) TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(3) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(3) TRACE regalloc2::ion::moves > -> allocation p10i TRACE regalloc2::ion::moves > apply_allocations: vreg VRegIndex(196) LR LiveRangeIndex(3) with range CodeRange { from: progpoint3-pre, to: progpoint3-post } has alloc p10i TRACE regalloc2::ion::moves > get_alloc_for_range: LiveRangeIndex(4) TRACE regalloc2::ion::moves > -> bundle: LiveBundleIndex(4) TRACE regalloc2::ion::moves > -> allocation p14i TRACE regalloc2::ion::moves > prev LR 4 abuts LR 3 in same block; moving p14i -> p10i for v196 TRACE regalloc2::ion::data_structures > insert_move: pos progpoint3-pre prio Regular from_alloc p14i to_alloc p10i to_vreg VReg(vreg = 196, class = Int) TRACE regalloc2::ion::moves > applying to use: Use { operand: Use: v196i fixed(p10i), pos: progpoint3-pre, slot: 0, weight: 35447 } TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p10i TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p13i TRACE regalloc2::ion::moves > parallel moves at pos progpoint2-pre prio 1 TRACE regalloc2::ion::moves > p13i -> p14i TRACE regalloc2::ion::moves > resolved: p13i -> p14i (Some(VReg(vreg = 196, class = Int))) TRACE regalloc2::ion::redundant_moves > -> redundant move tracker: from p13i to p14i to_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> from_state None to_state None TRACE regalloc2::ion::redundant_moves > -> src_vreg None TRACE regalloc2::ion::redundant_moves > -> dst_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> existing_dst_vreg None TRACE regalloc2::ion::redundant_moves > -> elide false TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p14i TRACE regalloc2::ion::redundant_moves > -> create mapping p14i -> Copy(p13i, Some(VReg(vreg = 196, class = Int))) TRACE regalloc2::ion::moves > parallel moves at pos progpoint2-pre prio 1 TRACE regalloc2::ion::moves > parallel moves at pos progpoint2-pre prio 1 TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p11i TRACE regalloc2::ion::moves > parallel moves at pos progpoint3-pre prio 1 TRACE regalloc2::ion::moves > p14i -> p10i TRACE regalloc2::ion::moves > resolved: p14i -> p10i (Some(VReg(vreg = 196, class = Int))) TRACE regalloc2::ion::redundant_moves > -> redundant move tracker: from p14i to p10i to_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> from_state Copy(p13i, Some(VReg(vreg = 196, class = Int))) to_state None TRACE regalloc2::ion::redundant_moves > -> src_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> dst_vreg Some(VReg(vreg = 196, class = Int)) TRACE regalloc2::ion::redundant_moves > -> existing_dst_vreg None TRACE regalloc2::ion::redundant_moves > -> elide false TRACE regalloc2::ion::redundant_moves > redundant move eliminator: clear p10i TRACE regalloc2::ion::redundant_moves > -> create mapping p10i -> Copy(p14i, Some(VReg(vreg = 196, class = Int))) TRACE regalloc2::ion::moves > parallel moves at pos progpoint3-pre prio 1 TRACE regalloc2::ion::moves > parallel moves at pos progpoint3-pre prio 1 DEBUG cranelift_codegen::timing > timing: Ending Register allocation: 33ms DEBUG cranelift_codegen::timing > timing: Starting VCode emission, (during Compilation passes) TRACE cranelift_codegen::machinst::buffer > MachBuffer: first 1 labels are for blocks TRACE cranelift_codegen::machinst::vcode > emitting block Block(0) TRACE cranelift_codegen::machinst::vcode > -> entry block TRACE cranelift_codegen::machinst::buffer > MachBuffer: bind label MachLabel(0) at offset 0 TRACE cranelift_codegen::machinst::buffer > enter optimize_branches: b = [] l = [MachLabel(0)] f = [] TRACE cranelift_codegen::machinst::buffer > leave optimize_branches: b = [] l = [MachLabel(0)] f = [] TRACE cranelift_codegen::machinst::abi > Epilogue: [Ret] TRACE cranelift_codegen::machinst::buffer > enter optimize_branches: b = [] l = [] f = [] TRACE cranelift_codegen::machinst::buffer > leave optimize_branches: b = [] l = [] f = [] DEBUG cranelift_codegen::timing > timing: Starting VCode emission finalization, (during VCode emission) DEBUG cranelift_codegen::timing > timing: Ending VCode emission finalization: 0ms DEBUG cranelift_codegen::timing > timing: Ending VCode emission: 1ms DEBUG cranelift_codegen::isa::riscv64 > disassembly: block0: lh a3,0(a0) mv a4,a3 lh a1,2(a0) mv a0,a4 ret DEBUG cranelift_codegen::timing > timing: Ending Compilation passes: 43ms INFO cranelift_filetests::test_compile > Generated 20 bytes of code: block0: lh a3,0(a0) mv a4,a3 lh a1,2(a0) mv a0,a4 ret DEBUG cranelift_codegen::timing > timing: Ending Processing test file: 48ms 1 tests ```
elliottt commented 1 year ago

@cfallin and I looked through this, and it looks like the problem is the current splitting heuristic in RA2: it's splitting at the location of the first conflict, which happens to be that first load, rather than at the point where a fixed constraint exists (the return instruction). Splitting early means that we get an allocation of a3 somewhat arbitrarily to v1, however the other half of the split which contains the second load and the return now also conflicts with the ultimate requirement for v1 to be in a0, thus a second split is introduced after the second load. That second split introduces the allocation of v1 to a4, which is why we see the move from a3 to a4 between the first two loads, and ultimately the move from a4 to a0 to satisfy the abi.

One possible solution here would be to augment the split point heuristic to look at the region after the conflict and move the split point to right before the first fixed use, which would in cases like this ensure that we weren't setting ourselves up for additional splits that would require additional moves.