Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 26662006: Changed LinkedHashSet to Set and LinkedHashMap to Map. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: HashMap -> Map. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 /** 94 /**
95 * Keeps track of locals (including parameters and phis) when building. The 95 * Keeps track of locals (including parameters and phis) when building. The
96 * 'this' reference is treated as parameter and hence handled by this class, 96 * 'this' reference is treated as parameter and hence handled by this class,
97 * too. 97 * too.
98 */ 98 */
99 class LocalsHandler { 99 class LocalsHandler {
100 /** 100 /**
101 * The values of locals that can be directly accessed (without redirections 101 * The values of locals that can be directly accessed (without redirections
102 * to boxes or closure-fields). 102 * to boxes or closure-fields).
103 * 103 *
104 * [directLocals] is iterated, so it is a [LinkedHashMap] to make the 104 * [directLocals] is iterated, so it is "insertion ordered" to make the
105 * iteration order a function only of insertions and not a function of 105 * iteration order a function only of insertions and not a function of
106 * e.g. Element hash codes. I'd prefer to use a SortedMap but some elements 106 * e.g. Element hash codes. I'd prefer to use a SortedMap but some elements
107 * don't have source locations for [Elements.compareByPosition]. 107 * don't have source locations for [Elements.compareByPosition].
108 */ 108 */
109 LinkedHashMap<Element, HInstruction> directLocals; 109 Map<Element, HInstruction> directLocals;
110 Map<Element, Element> redirectionMapping; 110 Map<Element, Element> redirectionMapping;
111 SsaBuilder builder; 111 SsaBuilder builder;
112 ClosureClassMap closureData; 112 ClosureClassMap closureData;
113 113
114 LocalsHandler(this.builder) 114 LocalsHandler(this.builder)
115 : directLocals = new LinkedHashMap<Element, HInstruction>(), 115 : directLocals = new Map<Element, HInstruction>(),
116 redirectionMapping = new Map<Element, Element>(); 116 redirectionMapping = new Map<Element, Element>();
117 117
118 get typesTask => builder.compiler.typesTask; 118 get typesTask => builder.compiler.typesTask;
119 119
120 /** 120 /**
121 * Creates a new [LocalsHandler] based on [other]. We only need to 121 * Creates a new [LocalsHandler] based on [other]. We only need to
122 * copy the [directLocals], since the other fields can be shared 122 * copy the [directLocals], since the other fields can be shared
123 * throughout the AST visit. 123 * throughout the AST visit.
124 */ 124 */
125 LocalsHandler.from(LocalsHandler other) 125 LocalsHandler.from(LocalsHandler other)
126 : directLocals = 126 : directLocals = new Map<Element, HInstruction>.from(other.directLocals),
127 new LinkedHashMap<Element, HInstruction>.from(other.directLocals),
128 redirectionMapping = other.redirectionMapping, 127 redirectionMapping = other.redirectionMapping,
129 builder = other.builder, 128 builder = other.builder,
130 closureData = other.closureData; 129 closureData = other.closureData;
131 130
132 /** 131 /**
133 * Redirects accesses from element [from] to element [to]. The [to] element 132 * Redirects accesses from element [from] to element [to]. The [to] element
134 * must be a boxed variable or a variable that is stored in a closure-field. 133 * must be a boxed variable or a variable that is stored in a closure-field.
135 */ 134 */
136 void redirectElement(Element from, Element to) { 135 void redirectElement(Element from, Element to) {
137 assert(redirectionMapping[from] == null); 136 assert(redirectionMapping[from] == null);
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 } 496 }
498 } 497 }
499 498
500 /** 499 /**
501 * Create phis at the loop entry for local variables (ready for the values 500 * Create phis at the loop entry for local variables (ready for the values
502 * from the back edge). Populate the phis with the current values. 501 * from the back edge). Populate the phis with the current values.
503 */ 502 */
504 void beginLoopHeader(HBasicBlock loopEntry) { 503 void beginLoopHeader(HBasicBlock loopEntry) {
505 // Create a copy because we modify the map while iterating over it. 504 // Create a copy because we modify the map while iterating over it.
506 Map<Element, HInstruction> savedDirectLocals = 505 Map<Element, HInstruction> savedDirectLocals =
507 new LinkedHashMap<Element, HInstruction>.from(directLocals); 506 new Map<Element, HInstruction>.from(directLocals);
508 507
509 // Create phis for all elements in the definitions environment. 508 // Create phis for all elements in the definitions environment.
510 savedDirectLocals.forEach((Element element, HInstruction instruction) { 509 savedDirectLocals.forEach((Element element, HInstruction instruction) {
511 if (isAccessedDirectly(element)) { 510 if (isAccessedDirectly(element)) {
512 // We know 'this' cannot be modified. 511 // We know 'this' cannot be modified.
513 if (!identical(element, closureData.thisElement)) { 512 if (!identical(element, closureData.thisElement)) {
514 HPhi phi = new HPhi.singleInput(element, instruction); 513 HPhi phi = new HPhi.singleInput(element, instruction);
515 loopEntry.addPhi(phi); 514 loopEntry.addPhi(phi);
516 directLocals[element] = phi; 515 directLocals[element] = phi;
517 } else { 516 } else {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 * If a phi node is necessary, it will use this handler's instruction as the 564 * If a phi node is necessary, it will use this handler's instruction as the
566 * first input, and the otherLocals instruction as the second. 565 * first input, and the otherLocals instruction as the second.
567 */ 566 */
568 void mergeWith(LocalsHandler otherLocals, HBasicBlock joinBlock) { 567 void mergeWith(LocalsHandler otherLocals, HBasicBlock joinBlock) {
569 // If an element is in one map but not the other we can safely 568 // If an element is in one map but not the other we can safely
570 // ignore it. It means that a variable was declared in the 569 // ignore it. It means that a variable was declared in the
571 // block. Since variable declarations are scoped the declared 570 // block. Since variable declarations are scoped the declared
572 // variable cannot be alive outside the block. Note: this is only 571 // variable cannot be alive outside the block. Note: this is only
573 // true for nodes where we do joins. 572 // true for nodes where we do joins.
574 Map<Element, HInstruction> joinedLocals = 573 Map<Element, HInstruction> joinedLocals =
575 new LinkedHashMap<Element, HInstruction>(); 574 new Map<Element, HInstruction>();
576 otherLocals.directLocals.forEach((element, instruction) { 575 otherLocals.directLocals.forEach((element, instruction) {
577 // We know 'this' cannot be modified. 576 // We know 'this' cannot be modified.
578 if (identical(element, closureData.thisElement)) { 577 if (identical(element, closureData.thisElement)) {
579 assert(directLocals[element] == instruction); 578 assert(directLocals[element] == instruction);
580 joinedLocals[element] = instruction; 579 joinedLocals[element] = instruction;
581 } else { 580 } else {
582 HInstruction mine = directLocals[element]; 581 HInstruction mine = directLocals[element];
583 if (mine == null) return; 582 if (mine == null) return;
584 if (identical(instruction, mine)) { 583 if (identical(instruction, mine)) {
585 joinedLocals[element] = instruction; 584 joinedLocals[element] = instruction;
(...skipping 13 matching lines...) Expand all
599 * localsHandlers into a new one using phis. The new localsHandler is 598 * localsHandlers into a new one using phis. The new localsHandler is
600 * returned. Unless it is also in the list, the current localsHandler is not 599 * returned. Unless it is also in the list, the current localsHandler is not
601 * used for its values, only for its declared variables. This is a way to 600 * used for its values, only for its declared variables. This is a way to
602 * exclude local values from the result when they are no longer in scope. 601 * exclude local values from the result when they are no longer in scope.
603 */ 602 */
604 LocalsHandler mergeMultiple(List<LocalsHandler> localsHandlers, 603 LocalsHandler mergeMultiple(List<LocalsHandler> localsHandlers,
605 HBasicBlock joinBlock) { 604 HBasicBlock joinBlock) {
606 assert(localsHandlers.length > 0); 605 assert(localsHandlers.length > 0);
607 if (localsHandlers.length == 1) return localsHandlers[0]; 606 if (localsHandlers.length == 1) return localsHandlers[0];
608 Map<Element, HInstruction> joinedLocals = 607 Map<Element, HInstruction> joinedLocals =
609 new LinkedHashMap<Element,HInstruction>(); 608 new Map<Element,HInstruction>();
610 HInstruction thisValue = null; 609 HInstruction thisValue = null;
611 directLocals.forEach((Element element, HInstruction instruction) { 610 directLocals.forEach((Element element, HInstruction instruction) {
612 if (element != closureData.thisElement) { 611 if (element != closureData.thisElement) {
613 HPhi phi = new HPhi.noInputs(element); 612 HPhi phi = new HPhi.noInputs(element);
614 joinedLocals[element] = phi; 613 joinedLocals[element] = phi;
615 joinBlock.addPhi(phi); 614 joinBlock.addPhi(phi);
616 } else { 615 } else {
617 // We know that "this" never changes, if it's there. 616 // We know that "this" never changes, if it's there.
618 // Save it for later. While merging, there is no phi for "this", 617 // Save it for later. While merging, there is no phi for "this",
619 // so we don't have to special case it in the merge loop. 618 // so we don't have to special case it in the merge loop.
620 thisValue = instruction; 619 thisValue = instruction;
621 } 620 }
622 }); 621 });
623 for (LocalsHandler handler in localsHandlers) { 622 for (LocalsHandler handler in localsHandlers) {
624 handler.directLocals.forEach((Element element, HInstruction instruction) { 623 handler.directLocals.forEach((Element element, HInstruction instruction) {
625 HPhi phi = joinedLocals[element]; 624 HPhi phi = joinedLocals[element];
626 if (phi != null) { 625 if (phi != null) {
627 phi.addInput(instruction); 626 phi.addInput(instruction);
628 } 627 }
629 }); 628 });
630 } 629 }
631 if (thisValue != null) { 630 if (thisValue != null) {
632 // If there was a "this" for the scope, add it to the new locals. 631 // If there was a "this" for the scope, add it to the new locals.
633 joinedLocals[closureData.thisElement] = thisValue; 632 joinedLocals[closureData.thisElement] = thisValue;
634 } 633 }
635 634
636 // Remove locals that are not in all handlers. 635 // Remove locals that are not in all handlers.
637 directLocals = new LinkedHashMap<Element, HInstruction>(); 636 directLocals = new Map<Element, HInstruction>();
638 joinedLocals.forEach((element, instruction) { 637 joinedLocals.forEach((element, instruction) {
639 if (instruction is HPhi 638 if (instruction is HPhi
640 && instruction.inputs.length != localsHandlers.length) { 639 && instruction.inputs.length != localsHandlers.length) {
641 joinBlock.removePhi(instruction); 640 joinBlock.removePhi(instruction);
642 } else { 641 } else {
643 directLocals[element] = instruction; 642 directLocals[element] = instruction;
644 } 643 }
645 }); 644 });
646 return this; 645 return this;
647 } 646 }
(...skipping 4971 matching lines...) Expand 10 before | Expand all | Expand 10 after
5619 new HSubGraphBlockInformation(elseBranch.graph)); 5618 new HSubGraphBlockInformation(elseBranch.graph));
5620 5619
5621 HBasicBlock conditionStartBlock = conditionBranch.block; 5620 HBasicBlock conditionStartBlock = conditionBranch.block;
5622 conditionStartBlock.setBlockFlow(info, joinBlock); 5621 conditionStartBlock.setBlockFlow(info, joinBlock);
5623 SubGraph conditionGraph = conditionBranch.graph; 5622 SubGraph conditionGraph = conditionBranch.graph;
5624 HIf branch = conditionGraph.end.last; 5623 HIf branch = conditionGraph.end.last;
5625 assert(branch is HIf); 5624 assert(branch is HIf);
5626 branch.blockInformation = conditionStartBlock.blockFlow; 5625 branch.blockInformation = conditionStartBlock.blockFlow;
5627 } 5626 }
5628 } 5627 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698