Chromium Code Reviews| Index: pkg/compiler/lib/src/ssa/optimize.dart |
| diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart |
| index c5286677eddfc8d146f1d6588de4c43166f1274f..98fd517eb9c0162949dadce4ff755dcf677fae58 100644 |
| --- a/pkg/compiler/lib/src/ssa/optimize.dart |
| +++ b/pkg/compiler/lib/src/ssa/optimize.dart |
| @@ -8,7 +8,7 @@ import '../common/tasks.dart' show CompilerTask; |
| import '../compiler.dart' show Compiler; |
| import '../constants/constant_system.dart'; |
| import '../constants/values.dart'; |
| -import '../core_types.dart' show CoreClasses; |
| +import '../core_types.dart' show CommonElements, CoreClasses; |
| import '../dart_types.dart'; |
| import '../elements/elements.dart'; |
| import '../js/js.dart' as js; |
| @@ -139,10 +139,10 @@ bool isFixedLength(mask, Compiler compiler) { |
| return true; |
| } |
| // TODO(sra): Recognize any combination of fixed length indexables. |
| - if (mask.containsOnly(backend.helpers.jsFixedArrayClass) || |
| - mask.containsOnly(backend.helpers.jsUnmodifiableArrayClass) || |
| + if (mask.containsOnly(closedWorld.backendClasses.fixedListImplementation) || |
| + mask.containsOnly(closedWorld.backendClasses.constListImplementation) || |
| mask.containsOnlyString(closedWorld) || |
| - backend.isTypedArray(mask)) { |
| + closedWorld.commonMasks.isTypedArray(mask)) { |
| return true; |
| } |
| return false; |
| @@ -170,12 +170,17 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| SsaInstructionSimplifier( |
| this.constantSystem, this.backend, this.optimizer, this.registry); |
| - CoreClasses get coreClasses => compiler.coreClasses; |
| + CoreClasses get coreClasses => closedWorld.coreClasses; |
|
Siggi Cherem (dart-lang)
2016/12/12 15:50:16
should we remove this one and use commonElements i
Johnni Winther
2016/12/13 11:20:28
Done.
|
| ClosedWorld get closedWorld => compiler.closedWorld; |
| + CommonElements get commonElements => closedWorld.commonElements; |
| + |
| BackendHelpers get helpers => backend.helpers; |
| + GlobalTypeInferenceResults get globalInferenceResults => |
| + compiler.globalInference.results; |
| + |
| void visitGraph(HGraph visitee) { |
| graph = visitee; |
| visitDominatorTree(visitee); |
| @@ -447,9 +452,9 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| if (folded != node) return folded; |
| } |
| - TypeMask receiverType = node.getDartReceiver(compiler).instructionType; |
| + TypeMask receiverType = node.getDartReceiver(closedWorld).instructionType; |
| Element element = |
| - compiler.closedWorld.locateSingleElement(node.selector, receiverType); |
| + closedWorld.locateSingleElement(node.selector, receiverType); |
| // TODO(ngeoffray): Also fold if it's a getter or variable. |
| if (element != null && |
| element.isFunction |
| @@ -482,9 +487,10 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| element.isField && |
| element.name == node.selector.name) { |
| FieldElement field = element; |
| - if (!backend.isNative(field) && !node.isCallOnInterceptor(compiler)) { |
| - HInstruction receiver = node.getDartReceiver(compiler); |
| - TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler); |
| + if (!backend.isNative(field) && !node.isCallOnInterceptor(closedWorld)) { |
| + HInstruction receiver = node.getDartReceiver(closedWorld); |
| + TypeMask type = TypeMaskFactory.inferredTypeForElement( |
| + field, globalInferenceResults); |
| HInstruction load = new HFieldGet(field, receiver, type); |
| node.block.addBefore(node, load); |
| Selector callSelector = new Selector.callClosureFrom(node.selector); |
| @@ -554,7 +560,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| native.NativeBehavior nativeBehavior = |
| backend.getNativeMethodBehavior(method); |
| TypeMask returnType = |
| - TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); |
| + TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
| HInvokeDynamicMethod result = |
| new HInvokeDynamicMethod(node.selector, node.mask, inputs, returnType); |
| result.element = method; |
| @@ -744,7 +750,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| if (expression.isInteger(closedWorld)) { |
| if (element == coreClasses.intClass || |
| element == coreClasses.numClass || |
| - Elements.isNumberOrStringSupertype(element, compiler)) { |
| + Elements.isNumberOrStringSupertype(element, commonElements)) { |
| return graph.addConstantBool(true, compiler); |
| } else if (element == coreClasses.doubleClass) { |
| // We let the JS semantics decide for that check. Currently |
| @@ -756,7 +762,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| } else if (expression.isDouble(closedWorld)) { |
| if (element == coreClasses.doubleClass || |
| element == coreClasses.numClass || |
| - Elements.isNumberOrStringSupertype(element, compiler)) { |
| + Elements.isNumberOrStringSupertype(element, commonElements)) { |
| return graph.addConstantBool(true, compiler); |
| } else if (element == coreClasses.intClass) { |
| // We let the JS semantics decide for that check. Currently |
| @@ -845,7 +851,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| FieldElement findConcreteFieldForDynamicAccess( |
| HInstruction receiver, Selector selector) { |
| TypeMask receiverType = receiver.instructionType; |
| - return compiler.closedWorld.locateSingleField(selector, receiverType); |
| + return closedWorld.locateSingleField(selector, receiverType); |
| } |
| HInstruction visitFieldGet(HFieldGet node) { |
| @@ -916,7 +922,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| HInstruction folded = handleInterceptedCall(node); |
| if (folded != node) return folded; |
| } |
| - HInstruction receiver = node.getDartReceiver(compiler); |
| + HInstruction receiver = node.getDartReceiver(closedWorld); |
| FieldElement field = |
| findConcreteFieldForDynamicAccess(receiver, node.selector); |
| if (field != null) return directFieldGet(receiver, field); |
| @@ -943,9 +949,10 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| TypeMask type; |
| if (backend.isNative(field.enclosingClass)) { |
| type = TypeMaskFactory.fromNativeBehavior( |
| - backend.getNativeFieldLoadBehavior(field), compiler); |
| + backend.getNativeFieldLoadBehavior(field), closedWorld); |
| } else { |
| - type = TypeMaskFactory.inferredTypeForElement(field, compiler); |
| + type = |
| + TypeMaskFactory.inferredTypeForElement(field, globalInferenceResults); |
| } |
| return new HFieldGet(field, receiver, type, isAssignable: isAssignable); |
| @@ -957,7 +964,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| if (folded != node) return folded; |
| } |
| - HInstruction receiver = node.getDartReceiver(compiler); |
| + HInstruction receiver = node.getDartReceiver(closedWorld); |
| FieldElement field = |
| findConcreteFieldForDynamicAccess(receiver, node.selector); |
| if (field == null || !field.isAssignable) return node; |
| @@ -1094,7 +1101,7 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| if (input.canBeNull()) return null; |
| Selector selector = Selectors.toString_; |
| TypeMask toStringType = TypeMaskFactory.inferredTypeForSelector( |
| - selector, input.instructionType, compiler); |
| + selector, input.instructionType, globalInferenceResults); |
| if (!toStringType.containsOnlyString(closedWorld)) return null; |
| // All intercepted classes extend `Interceptor`, so if the receiver can't |
| // be a class extending `Interceptor` then it can be called directly. |
| @@ -1437,10 +1444,10 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
| /// effects after [instruction], throws [NoSuchMethodError] on the |
| /// same receiver of [instruction]. |
| bool hasFollowingThrowingNSM(HInstruction instruction) { |
| - HInstruction receiver = instruction.getDartReceiver(compiler); |
| + HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| HInstruction current = instruction.next; |
| do { |
| - if ((current.getDartReceiver(compiler) == receiver) && |
| + if ((current.getDartReceiver(closedWorld) == receiver) && |
| current.canThrow()) { |
| return true; |
| } |
| @@ -1484,9 +1491,9 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
| if (use is HFieldSet) { |
| // The use must be the receiver. Even if the use is also the argument, |
| // i.e. a.x = a, the store is still dead if all other uses are dead. |
| - if (use.getDartReceiver(compiler) == instruction) return true; |
| + if (use.getDartReceiver(closedWorld) == instruction) return true; |
| } else if (use is HFieldGet) { |
| - assert(use.getDartReceiver(compiler) == instruction); |
| + assert(use.getDartReceiver(closedWorld) == instruction); |
| if (isDeadCode(use)) return true; |
| } |
| return false; |
| @@ -1500,7 +1507,7 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
| bool isTrivialDeadStore(HInstruction instruction) { |
| return instruction is HFieldSet && |
| - isTrivialDeadStoreReceiver(instruction.getDartReceiver(compiler)); |
| + isTrivialDeadStoreReceiver(instruction.getDartReceiver(closedWorld)); |
| } |
| bool isDeadCode(HInstruction instruction) { |
| @@ -2229,6 +2236,8 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| SsaLoadElimination(this.compiler); |
| + ClosedWorld get closedWorld => compiler.closedWorld; |
| + |
| void visitGraph(HGraph graph) { |
| memories = new List<MemorySet>(graph.blocks.length); |
| List<HBasicBlock> blocks = graph.blocks; |
| @@ -2249,7 +2258,7 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| void visitBasicBlock(HBasicBlock block) { |
| if (block.predecessors.length == 0) { |
| // Entry block. |
| - memorySet = new MemorySet(compiler); |
| + memorySet = new MemorySet(closedWorld); |
| } else if (block.predecessors.length == 1 && |
| block.predecessors[0].successors.length == 1) { |
| // No need to clone, there is no other successor for |
| @@ -2283,7 +2292,7 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| void visitFieldGet(HFieldGet instruction) { |
| if (instruction.isNullCheck) return; |
| MemberElement element = instruction.element; |
| - HInstruction receiver = instruction.getDartReceiver(compiler).nonCheck(); |
| + HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck(); |
| HInstruction existing = memorySet.lookupFieldValue(element, receiver); |
| if (existing != null) { |
| instruction.block.rewriteWithBetterUser(instruction, existing); |
| @@ -2294,7 +2303,7 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| } |
| void visitFieldSet(HFieldSet instruction) { |
| - HInstruction receiver = instruction.getDartReceiver(compiler).nonCheck(); |
| + HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck(); |
| memorySet.registerFieldValueUpdate( |
| instruction.element, receiver, instruction.inputs.last); |
| } |
| @@ -2434,7 +2443,7 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| * refinements to help further optimizations. |
| */ |
| class MemorySet { |
| - final Compiler compiler; |
| + final ClosedWorld closedWorld; |
| /** |
| * Maps a field to a map of receiver to value. |
| @@ -2453,9 +2462,7 @@ class MemorySet { |
| */ |
| final Setlet<HInstruction> nonEscapingReceivers = new Setlet<HInstruction>(); |
| - MemorySet(this.compiler); |
| - |
| - JavaScriptBackend get backend => compiler.backend; |
| + MemorySet(this.closedWorld); |
| /** |
| * Returns whether [first] and [second] always alias to the same object. |
| @@ -2475,11 +2482,11 @@ class MemorySet { |
| // Typed arrays of different types might have a shared buffer. |
| if (couldBeTypedArray(first) && couldBeTypedArray(second)) return true; |
| return !first.instructionType |
| - .isDisjoint(second.instructionType, compiler.closedWorld); |
| + .isDisjoint(second.instructionType, closedWorld); |
| } |
| bool isFinal(Element element) { |
| - return compiler.closedWorld.fieldNeverChanges(element); |
| + return closedWorld.fieldNeverChanges(element); |
| } |
| bool isConcrete(HInstruction instruction) { |
| @@ -2489,8 +2496,7 @@ class MemorySet { |
| } |
| bool couldBeTypedArray(HInstruction receiver) { |
| - JavaScriptBackend backend = compiler.backend; |
| - return backend.couldBeTypedArray(receiver.instructionType); |
| + return closedWorld.commonMasks.couldBeTypedArray(receiver.instructionType); |
| } |
| /** |
| @@ -2513,7 +2519,7 @@ class MemorySet { |
| void registerFieldValueUpdate( |
| MemberElement element, HInstruction receiver, HInstruction value) { |
| assert(receiver == null || receiver == receiver.nonCheck()); |
| - if (backend.isNative(element)) { |
| + if (closedWorld.backendClasses.isNative(element)) { |
| return; // TODO(14955): Remove this restriction? |
| } |
| // [value] is being set in some place in memory, we remove it from |
| @@ -2533,7 +2539,7 @@ class MemorySet { |
| void registerFieldValue( |
| MemberElement element, HInstruction receiver, HInstruction value) { |
| assert(receiver == null || receiver == receiver.nonCheck()); |
| - if (backend.isNative(element)) { |
| + if (closedWorld.backendClasses.isNative(element)) { |
| return; // TODO(14955): Remove this restriction? |
| } |
| Map<HInstruction, HInstruction> map = |
| @@ -2643,8 +2649,8 @@ class MemorySet { |
| HBasicBlock block, int predecessorIndex) { |
| if (first == null || second == null) return null; |
| if (first == second) return first; |
| - TypeMask phiType = second.instructionType |
| - .union(first.instructionType, compiler.closedWorld); |
| + TypeMask phiType = |
| + second.instructionType.union(first.instructionType, closedWorld); |
| if (first is HPhi && first.block == block) { |
| HPhi phi = first; |
| phi.addInput(second); |
| @@ -2668,7 +2674,7 @@ class MemorySet { |
| */ |
| MemorySet intersectionFor( |
| MemorySet other, HBasicBlock block, int predecessorIndex) { |
| - MemorySet result = new MemorySet(compiler); |
| + MemorySet result = new MemorySet(closedWorld); |
| if (other == null) { |
| // This is the first visit to a loop header ([other] is `null` because we |
| // have not visited the back edge). Copy the nonEscapingReceivers that are |
| @@ -2733,7 +2739,7 @@ class MemorySet { |
| * Returns a copy of [this]. |
| */ |
| MemorySet clone() { |
| - MemorySet result = new MemorySet(compiler); |
| + MemorySet result = new MemorySet(closedWorld); |
| fieldValues.forEach((element, values) { |
| result.fieldValues[element] = |