machinst: Avoid a full instructions traversal of all the blocks when computing the final block ordering;
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
//! Computation of basic block order in emitted code.
|
||||
|
||||
use crate::machinst::*;
|
||||
use regalloc::{BlockIx, Function};
|
||||
|
||||
/// Simple reverse postorder-based block order emission.
|
||||
///
|
||||
@@ -10,15 +9,13 @@ use regalloc::{BlockIx, Function};
|
||||
struct BlockRPO {
|
||||
visited: Vec<bool>,
|
||||
postorder: Vec<BlockIndex>,
|
||||
deferred_last: Option<BlockIndex>,
|
||||
}
|
||||
|
||||
impl BlockRPO {
|
||||
fn new<I: VCodeInst>(vcode: &VCode<I>) -> BlockRPO {
|
||||
BlockRPO {
|
||||
visited: vec![false; vcode.num_blocks()],
|
||||
postorder: vec![],
|
||||
deferred_last: None,
|
||||
postorder: Vec::with_capacity(vcode.num_blocks()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,22 +26,15 @@ impl BlockRPO {
|
||||
self.visit(vcode, *succ);
|
||||
}
|
||||
}
|
||||
|
||||
for i in vcode.block_insns(BlockIx::new(block)) {
|
||||
if vcode.get_insn(i).is_epilogue_placeholder() {
|
||||
debug_assert!(self.deferred_last.is_none());
|
||||
self.deferred_last = Some(block);
|
||||
return;
|
||||
}
|
||||
if Some(block) != vcode.fallthrough_return_block {
|
||||
self.postorder.push(block);
|
||||
}
|
||||
|
||||
self.postorder.push(block);
|
||||
}
|
||||
|
||||
fn rpo(self) -> Vec<BlockIndex> {
|
||||
fn rpo<I: VCodeInst>(self, vcode: &VCode<I>) -> Vec<BlockIndex> {
|
||||
let mut rpo = self.postorder;
|
||||
rpo.reverse();
|
||||
if let Some(block) = self.deferred_last {
|
||||
if let Some(block) = vcode.fallthrough_return_block {
|
||||
rpo.push(block);
|
||||
}
|
||||
rpo
|
||||
@@ -55,5 +45,5 @@ impl BlockRPO {
|
||||
pub fn compute_final_block_order<I: VCodeInst>(vcode: &VCode<I>) -> Vec<BlockIndex> {
|
||||
let mut rpo = BlockRPO::new(vcode);
|
||||
rpo.visit(vcode, vcode.entry());
|
||||
rpo.rpo()
|
||||
rpo.rpo(vcode)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user