Skip to content
Snippets Groups Projects

Misc. improvements

Merged rarbore2 requested to merge misc into main
1 file
+ 51
2
Compare changes
  • Side-by-side
  • Inline
+ 51
2
@@ -2,6 +2,7 @@ extern crate bitvec;
@@ -2,6 +2,7 @@ extern crate bitvec;
extern crate hercules_ir;
extern crate hercules_ir;
use std::collections::HashMap;
use std::collections::HashMap;
 
use std::iter::zip;
use self::bitvec::prelude::*;
use self::bitvec::prelude::*;
@@ -199,7 +200,7 @@ pub fn sroa(
@@ -199,7 +200,7 @@ pub fn sroa(
// Assemble a mapping from old nodes IDs acting on the product constant
// Assemble a mapping from old nodes IDs acting on the product constant
// to new nodes IDs operating on the field constants.
// to new nodes IDs operating on the field constants.
let map: HashMap<NodeID, Vec<NodeID>> = to_replace
let old_to_new_id_map: HashMap<NodeID, Vec<NodeID>> = to_replace
.iter()
.iter()
.map(|old_id| match function.nodes[old_id.idx()] {
.map(|old_id| match function.nodes[old_id.idx()] {
Node::Phi {
Node::Phi {
@@ -240,7 +241,55 @@ pub fn sroa(
@@ -240,7 +241,55 @@ pub fn sroa(
})
})
.collect();
.collect();
// Replace the old nodes with the new nodes.
// Replace the old nodes with the new nodes. Since we've already
 
// allocated the node IDs, at this point we can iterate through the to-
 
// replace nodes in an arbitrary order.
 
for (old_id, new_ids) in &old_to_new_id_map {
 
// First, add the new nodes to the node list.
 
let node = function.nodes[old_id.idx()].clone();
 
match node {
 
// Replace the original constant with constants for each field.
 
Node::Constant { id: _ } => {
 
for (new_id, field_id) in zip(new_ids.iter(), constant_fields.iter()) {
 
function.nodes[new_id.idx()] = Node::Constant { id: *field_id };
 
}
 
}
 
// Replace writes using the constant as the data use with a
 
// series of writes writing the invidiual constant fields. TODO:
 
// handle the case where the constant is the collect use of the
 
// write node.
 
Node::Write {
 
collect,
 
data,
 
ref indices,
 
} => {
 
// Create the write chain.
 
assert!(old_to_new_id_map.contains_key(&data), "PANIC: Can't handle case where write node depends on constant to SROA in the collect use yet.");
 
let mut collect_def = collect;
 
for (idx, (new_id, new_data_def)) in
 
zip(new_ids.iter(), old_to_new_id_map[&data].iter()).enumerate()
 
{
 
let mut new_indices = indices.clone().into_vec();
 
new_indices.push(Index::Field(idx));
 
function.nodes[new_id.idx()] = Node::Write {
 
collect: collect_def,
 
data: *new_data_def,
 
indices: new_indices.into_boxed_slice(),
 
};
 
collect_def = *new_id;
 
}
 
 
// Replace uses of the old write with the new write.
 
for user in def_use.get_users(*old_id) {
 
get_uses_mut(&mut function.nodes[user.idx()]).map(*old_id, collect_def);
 
}
 
}
 
_ => todo!(),
 
}
 
 
// Delete the old node.
 
function.nodes[old_id.idx()] = Node::Start;
 
}
}
}
}
}
Loading