@@ -321,6 +321,42 @@ impl<'a> Elaborator<'a> {
321321 } ;
322322 }
323323
324+ // Elaborate the best value (from required/skeleton use). If we have already found a best value,
325+ // we can just return that. Otherwise, we traverse the aegraph from this point, keeping track
326+ // of previously seen values along argument paths to avoid double-counting DAG entries (e.g., to
327+ // have a cost function that does not repeat costs for subexpressions). This involves carefully
328+ // handling union nodes, only counting their values as permanently seen once a choice is made between
329+ // the unioned values.
330+
331+ // Once the `best_value_traversal` helper is complete, we know we have found a best value for the
332+ // current node, and every node newly seen in its chosen traversal. We can thus add all of these
333+ // values to our per-function `value_to_best_value` map.
334+ fn elaborate_best_value (
335+ dfg : & DataFlowGraph ,
336+ layout : & Layout ,
337+ best_map : & mut SecondaryMap < Value , BestEntry > ,
338+ value : Value ,
339+ ) -> BestEntry {
340+ let best_found = best_map[ value] ;
341+ if !best_found. 1 . is_reserved_value ( ) {
342+ trace ! (
343+ "skipping expensive elaboration, already have best for value {:?}" ,
344+ value
345+ ) ;
346+ return best_found;
347+ }
348+ let mut seen_this_traversal: FxHashSet < Value > = FxHashSet :: default ( ) ;
349+ let def = dfg. value_def ( value) ;
350+ trace ! ( "elaborating value {:?} def {:?}" , value, def) ;
351+ let ( best, new_seen) =
352+ Self :: best_value_traversal ( dfg, layout, best_map, value, & mut seen_this_traversal) ;
353+ best_map[ value] = best;
354+ for ( v, best) in new_seen. iter ( ) {
355+ best_map[ v] = * best;
356+ }
357+ return best;
358+ }
359+
324360 /// Elaborate use of an eclass, inserting any needed new
325361 /// instructions before the given inst `before`. Should only be
326362 /// given values corresponding to results of instructions or
0 commit comments