Skip to content
Snippets Groups Projects

Fix outlining

Merged rarbore2 requested to merge outline_fix into main
1 file
+ 15
16
Compare changes
  • Side-by-side
  • Inline
+ 15
16
extern crate bitvec;
extern crate hercules_ir;
use std::collections::{BTreeMap, BTreeSet};
use std::iter::zip;
use std::sync::atomic::{AtomicUsize, Ordering};
use self::bitvec::prelude::*;
use self::hercules_ir::def_use::*;
use self::hercules_ir::dom::*;
use self::hercules_ir::gcm::*;
@@ -88,7 +85,11 @@ pub fn outline(
// Note, this is the control ID of the exit point of the previous partition,
// not just the previous partition - partition A may have multiple exit
// points that jump to partition B.
let callee_pred_param_idx = if control_subgraph.preds(top_node).count() > 1 {
let top_node_outside_preds: Box<[_]> = control_subgraph
.preds(top_node)
.filter(|pred_id| !partition.contains(pred_id))
.collect();
let callee_pred_param_idx = if top_node_outside_preds.len() > 1 {
Some(param_idx_to_outside_id.len())
} else {
None
@@ -97,10 +98,10 @@ pub fn outline(
.iter()
.map(|outside_id| {
let func = editor.func();
control_subgraph.preds(top_node).map(move |pred_id| {
top_node_outside_preds.iter().map(move |pred_id| {
(
(*outside_id, pred_id),
does_data_dom_control(func, *outside_id, pred_id, dom),
(*outside_id, *pred_id),
does_data_dom_control(func, *outside_id, *pred_id, dom),
)
})
})
@@ -421,11 +422,9 @@ pub fn outline(
// - Region (single predecessor), If, Match, or Fork: the original top
// node gets replaced with a new region with a single predecessor. The
// call is generated in a straightforward manner.
let (new_region_id, call_id) = if let Node::Region { preds } = edit.get_node(top_node)
&& preds.len() > 1
{
let (new_region_id, call_id) = if top_node_outside_preds.len() > 1 {
let new_region = Node::Region {
preds: preds.clone(),
preds: top_node_outside_preds.clone(),
};
let new_region_id = edit.add_node(new_region);
let mut args = vec![];
@@ -439,10 +438,10 @@ pub fn outline(
let undef_id = edit.add_node(undef);
let phi = Node::Phi {
control: new_region_id,
data: control_subgraph
.preds(top_node)
data: top_node_outside_preds
.iter()
.map(|pred_id| {
if outside_id_and_top_pred_to_does_dom[&(*outside_id, pred_id)] {
if outside_id_and_top_pred_to_does_dom[&(*outside_id, *pred_id)] {
*outside_id
} else {
undef_id
@@ -454,7 +453,7 @@ pub fn outline(
}
// Add a phi for the control predecessor indicator.
let control_id_constants = control_subgraph.preds(top_node).map(|pred_id| {
let control_id_constants = top_node_outside_preds.iter().map(|pred_id| {
let id = edit.add_constant(Constant::UnsignedInteger32(pred_id.idx() as u32));
edit.add_node(Node::Constant { id })
});
@@ -474,7 +473,7 @@ pub fn outline(
(new_region_id, call_id)
} else {
let new_region = Node::Region {
preds: Box::new([control_subgraph.preds(top_node).next().unwrap()]),
preds: top_node_outside_preds,
};
let new_region_id = edit.add_node(new_region);
let call = Node::Call {
Loading