Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // The lattice used for constant folding.
- #[derive(Debug, Clone, PartialEq, Copy)]
- struct CfLattice {
- reachable: bool,
- value: Tarval,
- }
- pub struct ConstantFolding {
- values: HashMap<Node, CfLattice>,
- queue: PriorityQueue<Node, Priority>,
- node_topo_idx: HashMap<Node, u32>,
- graph: Graph,
- start_block: Node,
- // duplicates are not that important for the inner list as there are at most less than 10.
- deps: HashMap<Node, Vec<Node>>,
- }
- impl optimization::Local for ConstantFolding {
- fn optimize_function(graph: Graph) -> Outcome {
- let mut constant_folding = ConstantFolding::new(graph);
- constant_folding.run();
- constant_folding.apply()
- }
- }
- impl ConstantFolding {
- fn new(graph: Graph) -> Self {
- let mut queue = PriorityQueue::new();
- let mut topo_order = 0;
- let mut node_topo_idx = HashMap::new();
- let mut values = HashMap::new();
- graph.assure_outs();
- graph.walk_topological(|node| {
- topo_order += 1;
- node_topo_idx.insert(*node, topo_order);
- values.insert(
- *node,
- CfLattice {
- reachable: false,
- value: Tarval::unknown(),
- },
- );
- });
- let start_block = graph.start().block().into();
- queue.push(
- start_block,
- Priority {
- topo_order: 0,
- priority: 0,
- },
- );
- Self {
- queue,
- values,
- graph,
- node_topo_idx,
- start_block,
- cur_node: None,
- deps: HashMap::new(),
- }
- }
- fn lookup(&self, node: Node) -> CfLattice {
- self.values[&node]
- }
- fn update(&mut self, node: Node, new: CfLattice) {
- self.values.insert(node, new).unwrap();
- }
- fn run(&mut self) {
- macro_rules! invalidate {
- ($node: expr) => {
- let topo_order = self.node_topo_idx.get(&$node);
- if let Some(topo_order) = topo_order {
- self.queue.push(
- $node,
- Priority {
- topo_order: *topo_order,
- priority: 0,
- },
- );
- }
- };
- }
- while let Some((cur_node, _priority)) = self.queue.pop() {
- let cur_lattice = self.lookup(cur_node);
- self.cur_node = Some(cur_node);
- let updated_lattice = self.update_node(cur_node, cur_lattice);
- if updated_lattice != cur_lattice {
- if let Some(deps) = self.deps.get(&cur_node) {
- // invalidate all dynamic dependants
- for out_node in deps.iter() {
- invalidate!(*out_node);
- }
- }
- // invalidate all direct dependants
- for out_node in cur_node.out_nodes() {
- invalidate!(out_node);
- }
- self.update(cur_node, updated_lattice);
- }
- }
- self.cur_node = None;
- }
- fn update_node(&mut self, cur_node: Node, cur_lattice: CfLattice) -> CfLattice {
- CfLattice { reachable, value }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement