MCPcopy Create free account
hub / github.com/Amanieu/regalloc3 / get_value_for_use

Method get_value_for_use

src/debug_utils/generic_function/arbitrary.rs:460–516  ·  view source on GitHub ↗

Returns a value for use as an `OperandKind::Use` in the given block. Because we process instructions in post-order, uses are processed before definitions. If necessary, this function will create a new value to be defined as a later point in the current block or in a dominating block.

(
        &mut self,
        bank: RegBank,
        block: Block,
        is_first_inst: bool,
    )

Source from the content-addressed store, hash-verified

458 /// definitions. If necessary, this function will create a new value to be
459 /// defined as a later point in the current block or in a dominating block.
460 fn get_value_for_use(
461 &mut self,
462 bank: RegBank,
463 block: Block,
464 is_first_inst: bool,
465 ) -> Result<Value> {
466 // Try to reuse an existing value.
467 if self.u.arbitrary()? {
468 self.use_candidates.clear();
469
470 // Walk up the dominator tree to collect all values that we can use.
471 // Specifically: any value whose definition dominates us and which
472 // comes from a compatible register bank.
473 let mut reuse_block = block;
474 loop {
475 self.use_candidates.extend(
476 self.defs_by_blocks[reuse_block]
477 .iter()
478 .chain(&self.func.blocks[reuse_block].block_params_in)
479 .copied()
480 .filter(|&value| self.func.values[value].bank == bank),
481 );
482
483 let Some(idom) = self.domtree.immediate_dominator(reuse_block) else {
484 break;
485 };
486 reuse_block = idom;
487 }
488
489 // If no suitable values exist, just define a new one.
490 if !self.use_candidates.is_empty() {
491 return self.u.choose(&self.use_candidates).copied();
492 }
493 }
494
495 // Walk up the dominator tree to find a block in which to define this
496 // value. If this is the first instruction then we cannot add a new
497 // definition in the current block.
498 let mut def_block = if is_first_inst {
499 self.domtree.immediate_dominator(block).unwrap()
500 } else {
501 block
502 };
503 while let Some(idom) = self.domtree.immediate_dominator(def_block) {
504 // This halves the probability every time we go up the tree.
505 if self.u.arbitrary()? {
506 break;
507 }
508
509 def_block = idom;
510 }
511
512 // Define a new value and record it to be defined in the chosen block.
513 let value = self.new_value(bank)?;
514 self.defs_by_blocks[def_block].push(value);
515 Ok(value)
516 }
517

Callers 2

gen_block_instsMethod · 0.80
gen_useMethod · 0.80

Calls 9

immediate_dominatorMethod · 0.80
unwrapMethod · 0.80
new_valueMethod · 0.80
pushMethod · 0.80
arbitraryMethod · 0.45
clearMethod · 0.45
extendMethod · 0.45
iterMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected