| Index: lib/compiler/implementation/ssa/types.dart
|
| diff --git a/lib/compiler/implementation/ssa/types.dart b/lib/compiler/implementation/ssa/types.dart
|
| index d59d7be820f5ecf776d0bf70cafbb84cb06b1376..563231387cfbf79165f2f6944d169644e9d8f162 100644
|
| --- a/lib/compiler/implementation/ssa/types.dart
|
| +++ b/lib/compiler/implementation/ssa/types.dart
|
| @@ -14,21 +14,19 @@ class SsaTypePropagator extends HGraphVisitor implements OptimizationPhase {
|
| worklist = new List<int>();
|
|
|
|
|
| - HType computeType(HInstruction instruction) {
|
| - return instruction.computeTypeFromInputTypes();
|
| - }
|
| + HType computeType(HInstruction instruction) => instruction.computeType();
|
|
|
| // Re-compute and update the type of the instruction. Returns
|
| // whether or not the type was changed.
|
| bool updateType(HInstruction instruction) {
|
| - if (instruction.propagatedType.isConflicting()) return false;
|
| -
|
| - HType oldType = instruction.propagatedType;
|
| - HType newType = instruction.hasGuaranteedType()
|
| - ? instruction.guaranteedType
|
| - : computeType(instruction);
|
| - instruction.propagatedType = oldType.combine(newType);
|
| - return oldType !== instruction.propagatedType;
|
| + if (instruction.type.isConflicting()) return false;
|
| + // Constants have the type they have. It can't be changed.
|
| + if (instruction.isConstant()) return false;
|
| +
|
| + HType oldType = instruction.type;
|
| + HType newType = computeType(instruction);
|
| + instruction.type = oldType.combine(newType);
|
| + return oldType !== instruction.type;
|
| }
|
|
|
| void visitGraph(HGraph graph) {
|
| @@ -39,24 +37,19 @@ class SsaTypePropagator extends HGraphVisitor implements OptimizationPhase {
|
| visitBasicBlock(HBasicBlock block) {
|
| if (block.isLoopHeader()) {
|
| block.forEachPhi((HPhi phi) {
|
| - // Set the initial type for the phi. In theory we would need to mark the
|
| - // type of all other incoming edges as "unitialized" and take this into
|
| - // account when doing the propagation inside the phis. Just setting
|
| - // the [propagatedType] is however easier.
|
| - phi.propagatedType = phi.inputs[0].propagatedType;
|
| + // Set the initial type for the phi.
|
| + phi.type = phi.inputs[0].type;
|
| addToWorkList(phi);
|
| });
|
| } else {
|
| block.forEachPhi((HPhi phi) {
|
| - if (updateType(phi)) addDependentInstructionsToWorkList(phi);
|
| + if (updateType(phi)) addUsersAndInputsToWorklist(phi);
|
| });
|
| }
|
|
|
| HInstruction instruction = block.first;
|
| while (instruction !== null) {
|
| - if (updateType(instruction)) {
|
| - addDependentInstructionsToWorkList(instruction);
|
| - }
|
| + if (updateType(instruction)) addUsersAndInputsToWorklist(instruction);
|
| instruction = instruction.next;
|
| }
|
| }
|
| @@ -67,18 +60,17 @@ class SsaTypePropagator extends HGraphVisitor implements OptimizationPhase {
|
| HInstruction instruction = workmap[id];
|
| assert(instruction !== null);
|
| workmap.remove(id);
|
| - if (updateType(instruction)) {
|
| - addDependentInstructionsToWorkList(instruction);
|
| - }
|
| + if (updateType(instruction)) addUsersAndInputsToWorklist(instruction);
|
| }
|
| }
|
|
|
| - void addDependentInstructionsToWorkList(HInstruction instruction) {
|
| + void addUsersAndInputsToWorklist(HInstruction instruction) {
|
| for (int i = 0, length = instruction.usedBy.length; i < length; i++) {
|
| - // The non-speculative type propagator only propagates types forward. We
|
| - // thus only need to add the users of the [instruction] to the list.
|
| addToWorkList(instruction.usedBy[i]);
|
| - }
|
| + }
|
| + for (int i = 0, length = instruction.inputs.length; i < length; i++) {
|
| + addToWorkList(instruction.inputs[i]);
|
| + }
|
| }
|
|
|
| void addToWorkList(HInstruction instruction) {
|
| @@ -94,24 +86,11 @@ class SsaSpeculativeTypePropagator extends SsaTypePropagator {
|
| final String name = 'speculative type propagator';
|
| SsaSpeculativeTypePropagator(Compiler compiler) : super(compiler);
|
|
|
| - void addDependentInstructionsToWorkList(HInstruction instruction) {
|
| - // The speculative type propagator propagates types forward and backward.
|
| - // Not only do we need to add the users of the [instruction] to the list.
|
| - // We also need to add the inputs fo the [instruction], since they might
|
| - // want to propagate the desired outgoing type.
|
| - for (int i = 0, length = instruction.usedBy.length; i < length; i++) {
|
| - addToWorkList(instruction.usedBy[i]);
|
| - }
|
| - for (int i = 0, length = instruction.inputs.length; i < length; i++) {
|
| - addToWorkList(instruction.inputs[i]);
|
| - }
|
| - }
|
| -
|
| HType computeDesiredType(HInstruction instruction) {
|
| HType desiredType = HType.UNKNOWN;
|
| for (final user in instruction.usedBy) {
|
| desiredType =
|
| - desiredType.combine(user.computeDesiredTypeForInput(instruction));
|
| + desiredType.combine(user.computeDesiredInputType(instruction));
|
| // No need to continue if two users disagree on the type.
|
| if (desiredType.isConflicting()) break;
|
| }
|
| @@ -120,12 +99,9 @@ class SsaSpeculativeTypePropagator extends SsaTypePropagator {
|
|
|
| HType computeType(HInstruction instruction) {
|
| HType newType = super.computeType(instruction);
|
| - // [computeDesiredType] goes to all usedBys and lets them compute their
|
| - // desired type. By setting the [newType] here we give them more context to
|
| - // work with.
|
| - instruction.propagatedType = newType;
|
| HType desiredType = computeDesiredType(instruction);
|
| - // If the desired type is conflicting just return the computed type.
|
| + // If the desired type is conflicting just return the computed
|
| + // type.
|
| if (desiredType.isConflicting()) return newType;
|
| return newType.combine(desiredType);
|
| }
|
|
|