Skip to content
This repository was archived by the owner on Oct 4, 2022. It is now read-only.

Commit 5081c02

Browse files
committed
Add orig_insn_map: mapping from original to new insn indices.
This is needed in the Cranelift client code in order to track source-location mapping for debug info: we need to be able to shuffle the source locations into the new locations after the regalloc has done its instruction-stream editing. The `target_map` result is not quite good enough, because it only provides old --> new mappings at a basic block granularity.
1 parent 497c2ed commit 5081c02

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

lib/src/backtracking.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2803,7 +2803,7 @@ pub fn alloc_main<F: Function>(
28032803
// ======== BEGIN Create the RegAllocResult ========
28042804

28052805
match final_insns_and_targetmap__or_err {
2806-
Ok((ref final_insns, ref _targetmap)) => {
2806+
Ok((ref final_insns, ..)) => {
28072807
info!(
28082808
"alloc_main: out: VLRs: {} initially, {} processed",
28092809
num_vlrs_initial, num_vlrs_processed
@@ -2829,7 +2829,7 @@ pub fn alloc_main<F: Function>(
28292829
}
28302830
}
28312831

2832-
let (final_insns, target_map) = match final_insns_and_targetmap__or_err {
2832+
let (final_insns, target_map, orig_insn_map) = match final_insns_and_targetmap__or_err {
28332833
Err(e) => {
28342834
info!("alloc_main: fail");
28352835
return Err(e);
@@ -2891,6 +2891,7 @@ pub fn alloc_main<F: Function>(
28912891
let ra_res = RegAllocResult {
28922892
insns: final_insns,
28932893
target_map,
2894+
orig_insn_map,
28942895
clobbered_registers,
28952896
num_spill_slots: spill_slot_allocator.slots.len() as u32,
28962897
block_annotations,

lib/src/inst_stream.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,14 @@ fn map_vregs_to_rregs<F: Function>(
432432
fn add_spills_reloads_and_moves<F: Function>(
433433
func: &mut F,
434434
mut insts_to_add: Vec<InstToInsertAndPoint>,
435-
) -> Result<(Vec<F::Inst>, TypedIxVec<BlockIx, InstIx>), String> {
435+
) -> Result<
436+
(
437+
Vec<F::Inst>,
438+
TypedIxVec<BlockIx, InstIx>,
439+
TypedIxVec<InstIx, Option<InstIx>>,
440+
),
441+
String,
442+
> {
436443
// Construct the final code by interleaving the mapped code with the the
437444
// spills, reloads and moves that we have been requested to insert. To do
438445
// that requires having the latter sorted by InstPoint.
@@ -447,6 +454,7 @@ fn add_spills_reloads_and_moves<F: Function>(
447454

448455
let mut insns: Vec<F::Inst> = vec![];
449456
let mut target_map: TypedIxVec<BlockIx, InstIx> = TypedIxVec::new();
457+
let mut orig_insn_map: TypedIxVec<InstIx, Option<InstIx>> = TypedIxVec::new();
450458

451459
for iix in func.insn_indices() {
452460
// Is `iix` the first instruction in a block? Meaning, are we
@@ -463,15 +471,18 @@ fn add_spills_reloads_and_moves<F: Function>(
463471
&& insts_to_add[curITA].point == InstPoint::new_reload(iix)
464472
{
465473
insns.push(insts_to_add[curITA].inst.construct(func));
474+
orig_insn_map.push(None);
466475
curITA += 1;
467476
}
468477
// Copy the inst at `iix` itself
478+
orig_insn_map.push(Some(iix));
469479
insns.push(func.get_insn(iix).clone());
470480
// And copy the extra insts that are to be placed at the spill point of
471481
// `iix`.
472482
while curITA < insts_to_add.len() && insts_to_add[curITA].point == InstPoint::new_spill(iix)
473483
{
474484
insns.push(insts_to_add[curITA].inst.construct(func));
485+
orig_insn_map.push(None);
475486
curITA += 1;
476487
}
477488

@@ -485,7 +496,7 @@ fn add_spills_reloads_and_moves<F: Function>(
485496
debug_assert!(curITA == insts_to_add.len());
486497
debug_assert!(curB.get() == func.blocks().len() as u32);
487498

488-
Ok((insns, target_map))
499+
Ok((insns, target_map, orig_insn_map))
489500
}
490501

491502
//=============================================================================
@@ -501,7 +512,14 @@ pub(crate) fn edit_inst_stream<F: Function>(
501512
reg_universe: &RealRegUniverse,
502513
has_multiple_blocks_per_frag: bool,
503514
use_checker: bool,
504-
) -> Result<(Vec<F::Inst>, TypedIxVec<BlockIx, InstIx>), RegAllocError> {
515+
) -> Result<
516+
(
517+
Vec<F::Inst>,
518+
TypedIxVec<BlockIx, InstIx>,
519+
TypedIxVec<InstIx, Option<InstIx>>,
520+
),
521+
RegAllocError,
522+
> {
505523
map_vregs_to_rregs(
506524
func,
507525
frag_map,

lib/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,12 @@ pub struct RegAllocResult<F: Function> {
313313
/// branch targets appropriately.
314314
pub target_map: TypedIxVec<BlockIx, InstIx>,
315315

316+
/// Full mapping from new instruction indices to original instruction
317+
/// indices. May be needed by the client to, for example, update metadata
318+
/// such as debug/source-location info as the instructions are spliced
319+
/// and reordered.
320+
pub orig_insn_map: TypedIxVec</* new */ InstIx, /* orig */ Option<InstIx>>,
321+
316322
/// Which real registers were overwritten? This will contain all real regs
317323
/// that appear as defs or modifies in register slots of the output
318324
/// instruction list. This will only list registers that are available to

lib/src/linear_scan.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3251,7 +3251,7 @@ fn apply_registers<F: Function>(
32513251
use_checker,
32523252
);
32533253

3254-
let (final_insns, target_map) = match final_insns_and_targetmap_or_err {
3254+
let (final_insns, target_map, orig_insn_map) = match final_insns_and_targetmap_or_err {
32553255
Err(e) => return Err(e),
32563256
Ok(pair) => pair,
32573257
};
@@ -3295,6 +3295,7 @@ fn apply_registers<F: Function>(
32953295
let ra_res = RegAllocResult {
32963296
insns: final_insns,
32973297
target_map,
3298+
orig_insn_map,
32983299
clobbered_registers,
32993300
num_spill_slots,
33003301
block_annotations: None,

0 commit comments

Comments
 (0)