| OLD | NEW |
| (Empty) | |
| 1 library dart2js.cps_ir.update_refinements; |
| 2 |
| 3 import 'cps_ir_nodes.dart'; |
| 4 import 'optimizers.dart' show Pass; |
| 5 import 'type_mask_system.dart'; |
| 6 |
| 7 /// Updates all references to use the most refined version in scope. |
| 8 /// |
| 9 /// [GVN] and [RedundantJoinElimination], and possibly other passes, can create |
| 10 /// references that don't use the best refinement in scope. This pass improves |
| 11 /// the refinement information. |
| 12 /// |
| 13 // |
| 14 // TODO(asgerf): Could be done during GVN for another adjacent pass. |
| 15 // It is easier to measure performance and rearrange passes when it has its |
| 16 // own pass, but we can merge it with an adjacent pass later. |
| 17 // |
| 18 class UpdateRefinements extends TrampolineRecursiveVisitor implements Pass { |
| 19 String get passName => 'Update refinements'; |
| 20 |
| 21 final TypeMaskSystem typeSystem; |
| 22 |
| 23 Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{}; |
| 24 |
| 25 UpdateRefinements(this.typeSystem); |
| 26 |
| 27 void rewrite(FunctionDefinition node) { |
| 28 visit(node); |
| 29 } |
| 30 |
| 31 Expression traverseLetPrim(LetPrim node) { |
| 32 visit(node.primitive); |
| 33 return node.body; |
| 34 } |
| 35 |
| 36 @override |
| 37 visitRefinement(Refinement node) { |
| 38 if (refine(node.value)) { |
| 39 // Update the type if the input has changed. |
| 40 node.type = typeSystem.intersection(node.value.definition.type, |
| 41 node.refineType); |
| 42 } |
| 43 Primitive value = node.effectiveDefinition; |
| 44 Refinement old = refinementFor[value]; |
| 45 refinementFor[value] = node; |
| 46 pushAction(() { |
| 47 refinementFor[value] = old; |
| 48 }); |
| 49 } |
| 50 |
| 51 @override |
| 52 processReference(Reference ref) { |
| 53 refine(ref); |
| 54 } |
| 55 |
| 56 bool refine(Reference ref) { |
| 57 Definition def = ref.definition; |
| 58 if (def is Primitive) { |
| 59 Refinement refinement = refinementFor[def.effectiveDefinition]; |
| 60 if (refinement != null && refinement != ref.definition) { |
| 61 ref.changeTo(refinement); |
| 62 return true; |
| 63 } |
| 64 } |
| 65 return false; |
| 66 } |
| 67 } |
| OLD | NEW |