| Index: sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
|
| index 8a72f491d0f9089193b1ac0e48551e1cc65ba280..1e83906f09e213186317df5c505165962b732c96 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
|
| @@ -5,6 +5,89 @@
|
| part of ssa;
|
|
|
| /**
|
| + * Replaces some instructions with specialized versions to make codegen easier.
|
| + * Caches codegen information on nodes.
|
| + */
|
| +class SsaInstructionSelection extends HBaseVisitor {
|
| + final Compiler compiler;
|
| +
|
| + SsaInstructionSelection(this.compiler);
|
| +
|
| + void visitGraph(HGraph graph) {
|
| + visitDominatorTree(graph);
|
| + }
|
| +
|
| + visitBasicBlock(HBasicBlock block) {
|
| + HInstruction instruction = block.first;
|
| + while (instruction != null) {
|
| + HInstruction next = instruction.next;
|
| + HInstruction replacement = instruction.accept(this);
|
| + if (replacement != instruction) {
|
| + block.rewrite(instruction, replacement);
|
| +
|
| + // If the replacement instruction does not know its source element, use
|
| + // the source element of the instruction.
|
| + if (replacement.sourceElement == null) {
|
| + replacement.sourceElement = instruction.sourceElement;
|
| + }
|
| + if (replacement.sourcePosition == null) {
|
| + replacement.sourcePosition = instruction.sourcePosition;
|
| + }
|
| + if (!replacement.isInBasicBlock()) {
|
| + // The constant folding can return an instruction that is already
|
| + // part of the graph (like an input), so we only add the replacement
|
| + // if necessary.
|
| + block.addAfter(instruction, replacement);
|
| + // Visit the replacement as the next instruction in case it can also
|
| + // be constant folded away.
|
| + next = replacement;
|
| + }
|
| + block.remove(instruction);
|
| + }
|
| + instruction = next;
|
| + }
|
| + }
|
| +
|
| + HInstruction visitInstruction(HInstruction node) {
|
| + return node;
|
| + }
|
| +
|
| + HInstruction visitIs(HIs node) {
|
| + if (node.kind == HIs.RAW_CHECK) {
|
| + HInstruction interceptor = node.interceptor;
|
| + if (interceptor != null) {
|
| + JavaScriptBackend backend = compiler.backend;
|
| + return new HIsViaInterceptor(node.typeExpression, interceptor,
|
| + backend.boolType);
|
| + }
|
| + }
|
| + return node;
|
| + }
|
| +
|
| + HInstruction visitIdentity(HIdentity node) {
|
| + node.singleComparisonOp = simpleOp(node.left, node.right);
|
| + return node;
|
| + }
|
| +
|
| + String simpleOp(HInstruction left, HInstruction right) {
|
| + // Returns the single identity comparison (== or ===) or null if a more
|
| + // complex expression is required.
|
| + TypeMask leftType = left.instructionType;
|
| + TypeMask rightType = right.instructionType;
|
| + if (leftType.isNullable && rightType.isNullable) {
|
| + if (left.isConstantNull() ||
|
| + right.isConstantNull() ||
|
| + (left.isPrimitive(compiler) &&
|
| + leftType == rightType)) {
|
| + return '==';
|
| + }
|
| + return null;
|
| + }
|
| + return '===';
|
| + }
|
| +}
|
| +
|
| +/**
|
| * Remove [HTypeKnown] instructions from the graph, to make codegen
|
| * analysis easier.
|
| */
|
| @@ -124,9 +207,7 @@ class SsaInstructionMerger extends HBaseVisitor {
|
| // does not require an expression with multiple uses (because of null /
|
| // undefined).
|
| void visitIdentity(HIdentity instruction) {
|
| - HInstruction left = instruction.left;
|
| - HInstruction right = instruction.right;
|
| - if (singleIdentityComparison(left, right, compiler) != null) {
|
| + if (instruction.singleComparisonOp != null) {
|
| super.visitIdentity(instruction);
|
| }
|
| // Do nothing.
|
|
|