Advertisement
Guest User

Untitled

a guest
Jan 9th, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.44 KB | None | 0 0
  1.  
  2. // The lattice used for constant folding.
  3. #[derive(Debug, Clone, PartialEq, Copy)]
  4. struct CfLattice {
  5.     reachable: bool,
  6.     value: Tarval,
  7. }
  8.  
  9. pub struct ConstantFolding {
  10.     values: HashMap<Node, CfLattice>,
  11.     queue: PriorityQueue<Node, Priority>,
  12.     node_topo_idx: HashMap<Node, u32>,
  13.     graph: Graph,
  14.     start_block: Node,
  15.     // duplicates are not that important for the inner list as there are at most less than 10.
  16.     deps: HashMap<Node, Vec<Node>>,
  17. }
  18.  
  19. impl optimization::Local for ConstantFolding {
  20.     fn optimize_function(graph: Graph) -> Outcome {
  21.         let mut constant_folding = ConstantFolding::new(graph);
  22.         constant_folding.run();
  23.         constant_folding.apply()
  24.     }
  25. }
  26.  
  27. impl ConstantFolding {
  28.     fn new(graph: Graph) -> Self {
  29.         let mut queue = PriorityQueue::new();
  30.         let mut topo_order = 0;
  31.         let mut node_topo_idx = HashMap::new();
  32.         let mut values = HashMap::new();
  33.  
  34.         graph.assure_outs();
  35.  
  36.         graph.walk_topological(|node| {
  37.             topo_order += 1;
  38.  
  39.             node_topo_idx.insert(*node, topo_order);
  40.  
  41.             values.insert(
  42.                 *node,
  43.                 CfLattice {
  44.                     reachable: false,
  45.                     value: Tarval::unknown(),
  46.                 },
  47.             );
  48.         });
  49.  
  50.         let start_block = graph.start().block().into();
  51.  
  52.         queue.push(
  53.             start_block,
  54.             Priority {
  55.                 topo_order: 0,
  56.                 priority: 0,
  57.             },
  58.         );
  59.  
  60.         Self {
  61.             queue,
  62.             values,
  63.             graph,
  64.             node_topo_idx,
  65.             start_block,
  66.             cur_node: None,
  67.             deps: HashMap::new(),
  68.         }
  69.     }
  70.  
  71.     fn lookup(&self, node: Node) -> CfLattice {
  72.         self.values[&node]
  73.     }
  74.  
  75.     fn update(&mut self, node: Node, new: CfLattice) {
  76.         self.values.insert(node, new).unwrap();
  77.     }
  78.  
  79.     fn run(&mut self) {
  80.         macro_rules! invalidate {
  81.             ($node: expr) => {
  82.                 let topo_order = self.node_topo_idx.get(&$node);
  83.                 if let Some(topo_order) = topo_order {
  84.                     self.queue.push(
  85.                         $node,
  86.                         Priority {
  87.                             topo_order: *topo_order,
  88.                             priority: 0,
  89.                         },
  90.                     );
  91.                 }
  92.             };
  93.         }
  94.  
  95.         while let Some((cur_node, _priority)) = self.queue.pop() {
  96.             let cur_lattice = self.lookup(cur_node);
  97.             self.cur_node = Some(cur_node);
  98.            
  99.             let updated_lattice = self.update_node(cur_node, cur_lattice);
  100.             if updated_lattice != cur_lattice {
  101.                 if let Some(deps) = self.deps.get(&cur_node) {
  102.                     // invalidate all dynamic dependants
  103.                     for out_node in deps.iter() {
  104.                         invalidate!(*out_node);
  105.                     }
  106.                 }
  107.  
  108.                 // invalidate all direct dependants
  109.                 for out_node in cur_node.out_nodes() {
  110.                     invalidate!(out_node);
  111.                 }
  112.  
  113.                 self.update(cur_node, updated_lattice);
  114.             }
  115.         }
  116.  
  117.         self.cur_node = None;
  118.     }
  119.  
  120.  
  121.     fn update_node(&mut self, cur_node: Node, cur_lattice: CfLattice) -> CfLattice {
  122.        
  123.  
  124.         CfLattice { reachable, value }
  125.     }
  126. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement