When splitting a const, insert prior to the terminal branch group. (#1325)
* When splitting a const, insert prior to the terminal branch group. Closes #1159 Given code like the following, on x86_64, which does not have i128 registers: ebb0(v0: i64): v1 = iconst.i128 0 v2 = icmp_imm eq v0, 1 brnz v2, ebb1 jump ebb2(v1) It would be split to: ebb0(v0: i64): v1 = iconst.i128 0 v2 = icmp_imm eq v0, 1 brnz v2, ebb1 v3, v4 = isplit.i128 v1 jump ebb2(v3, v4) But that fails basic-block invariants. This patch changes that to: ebb0(v0: i64): v1 = iconst.i128 0 v2 = icmp_imm eq v0, 1 v3, v4 = isplit.i128 v1 brnz v2, ebb1 jump ebb2(v3, v4) * Add isplit-bb.clif testcase
This commit is contained in:
committed by
Benjamin Bouvier
parent
d6134a6f3a
commit
b4c6bfd371
@@ -4,6 +4,7 @@
|
||||
//! determined by the `Layout` data structure defined in this module.
|
||||
|
||||
use crate::entity::SecondaryMap;
|
||||
use crate::ir::dfg::DataFlowGraph;
|
||||
use crate::ir::progpoint::{ExpandedProgramPoint, ProgramOrder};
|
||||
use crate::ir::{Ebb, Inst};
|
||||
use crate::packed_option::PackedOption;
|
||||
@@ -573,6 +574,19 @@ impl Layout {
|
||||
self.insts[inst].prev.expand()
|
||||
}
|
||||
|
||||
/// Fetch the first instruction in an ebb's terminal branch group.
|
||||
pub fn canonical_branch_inst(&self, dfg: &DataFlowGraph, ebb: Ebb) -> Option<Inst> {
|
||||
// Basic blocks permit at most two terminal branch instructions.
|
||||
// If two, the former is conditional and the latter is unconditional.
|
||||
let last = self.last_inst(ebb)?;
|
||||
if let Some(prev) = self.prev_inst(last) {
|
||||
if dfg[prev].opcode().is_branch() {
|
||||
return Some(prev);
|
||||
}
|
||||
}
|
||||
Some(last)
|
||||
}
|
||||
|
||||
/// Insert `inst` before the instruction `before` in the same EBB.
|
||||
pub fn insert_inst(&mut self, inst: Inst, before: Inst) {
|
||||
debug_assert_eq!(self.inst_ebb(inst), None);
|
||||
|
||||
Reference in New Issue
Block a user