Skip to content
Snippets Groups Projects
Commit 5d7421a0 authored by Russel Arbore's avatar Russel Arbore
Browse files

Very minimal SROA working

parent fcfe3409
No related branches found
No related tags found
1 merge request!25Misc. improvements
......@@ -2,6 +2,7 @@ extern crate bitvec;
extern crate hercules_ir;
use std::collections::HashMap;
use std::iter::zip;
use self::bitvec::prelude::*;
......@@ -199,7 +200,7 @@ pub fn sroa(
// Assemble a mapping from old nodes IDs acting on the product constant
// 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()
.map(|old_id| match function.nodes[old_id.idx()] {
Node::Phi {
......@@ -240,7 +241,55 @@ pub fn sroa(
})
.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;
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment