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

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

Issue 10544026: Simplify generated code for string interpolation by delaying the constant folding. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Merge. Created 8 years, 6 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 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 2544 matching lines...) Expand 10 before | Expand all | Expand 10 after
2555 void visitLiteralString(LiteralString node) { 2555 void visitLiteralString(LiteralString node) {
2556 stack.add(graph.addConstantString(node.dartString, node)); 2556 stack.add(graph.addConstantString(node.dartString, node));
2557 } 2557 }
2558 2558
2559 void visitStringJuxtaposition(StringJuxtaposition node) { 2559 void visitStringJuxtaposition(StringJuxtaposition node) {
2560 if (!node.isInterpolation) { 2560 if (!node.isInterpolation) {
2561 // This is a simple string with no interpolations. 2561 // This is a simple string with no interpolations.
2562 stack.add(graph.addConstantString(node.dartString, node)); 2562 stack.add(graph.addConstantString(node.dartString, node));
2563 return; 2563 return;
2564 } 2564 }
2565 int offset = node.getBeginToken().charOffset; 2565 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this);
2566 StringBuilderVisitor stringBuilder =
2567 new StringBuilderVisitor(this, offset);
2568 stringBuilder.visit(node); 2566 stringBuilder.visit(node);
2569 stack.add(stringBuilder.result(node)); 2567 stack.add(stringBuilder.result);
2570 } 2568 }
2571 2569
2572 void visitLiteralNull(LiteralNull node) { 2570 void visitLiteralNull(LiteralNull node) {
2573 stack.add(graph.addConstantNull()); 2571 stack.add(graph.addConstantNull());
2574 } 2572 }
2575 2573
2576 visitNodeList(NodeList node) { 2574 visitNodeList(NodeList node) {
2577 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 2575 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
2578 if (isAborted()) { 2576 if (isAborted()) {
2579 compiler.reportWarning(link.head, 'dead code'); 2577 compiler.reportWarning(link.head, 'dead code');
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2709 open(joinBlock); 2707 open(joinBlock);
2710 2708
2711 localsHandler.mergeWith(thenLocals, joinBlock); 2709 localsHandler.mergeWith(thenLocals, joinBlock);
2712 HPhi phi = new HPhi.manyInputs(null, 2710 HPhi phi = new HPhi.manyInputs(null,
2713 <HInstruction>[thenInstruction, elseInstruction]); 2711 <HInstruction>[thenInstruction, elseInstruction]);
2714 joinBlock.addPhi(phi); 2712 joinBlock.addPhi(phi);
2715 stack.add(phi); 2713 stack.add(phi);
2716 } 2714 }
2717 2715
2718 visitStringInterpolation(StringInterpolation node) { 2716 visitStringInterpolation(StringInterpolation node) {
2719 int offset = node.getBeginToken().charOffset; 2717 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this);
2720 StringBuilderVisitor stringBuilder =
2721 new StringBuilderVisitor(this, offset);
2722 stringBuilder.visit(node); 2718 stringBuilder.visit(node);
2723 stack.add(stringBuilder.result(node)); 2719 stack.add(stringBuilder.result);
2724 } 2720 }
2725 2721
2726 visitStringInterpolationPart(StringInterpolationPart node) { 2722 visitStringInterpolationPart(StringInterpolationPart node) {
2727 // The parts are iterated in visitStringInterpolation. 2723 // The parts are iterated in visitStringInterpolation.
2728 compiler.internalError('visitStringInterpolation should not be called', 2724 compiler.internalError('visitStringInterpolation should not be called',
2729 node: node); 2725 node: node);
2730 } 2726 }
2731 2727
2732 visitEmptyStatement(EmptyStatement node) { 2728 visitEmptyStatement(EmptyStatement node) {
2733 // Do nothing, empty statement. 2729 // Do nothing, empty statement.
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
3388 3384
3389 /** 3385 /**
3390 * Visitor that handles generation of string literals (LiteralString, 3386 * Visitor that handles generation of string literals (LiteralString,
3391 * StringInterpolation), and otherwise delegates to the given visitor for 3387 * StringInterpolation), and otherwise delegates to the given visitor for
3392 * non-literal subexpressions. 3388 * non-literal subexpressions.
3393 * TODO(lrn): Consider whether to handle compile time constant int/boolean 3389 * TODO(lrn): Consider whether to handle compile time constant int/boolean
3394 * expressions as well. 3390 * expressions as well.
3395 */ 3391 */
3396 class StringBuilderVisitor extends AbstractVisitor { 3392 class StringBuilderVisitor extends AbstractVisitor {
3397 final SsaBuilder builder; 3393 final SsaBuilder builder;
3398 final Element stringConcat;
3399 final Element stringToString;
3400 3394
3401 /** 3395 /**
3402 * Offset used for the synthetic operator token used by concat. 3396 * The string value generated so far.
3403 * Can probably be removed when we stop using String.operator+.
3404 */ 3397 */
3405 final int offset; 3398 HInstruction result = null;
3406 3399
3407 /** 3400 StringBuilderVisitor(this.builder);
3408 * Used to collect concatenated string literals into a single literal
3409 * instead of introducing unnecessary concatenations.
3410 */
3411 DartString literalAccumulator = const LiteralDartString("");
3412
3413 /**
3414 * The string value generated so far (not including that which is still
3415 * in [literalAccumulator]).
3416 */
3417 HInstruction prefix = null;
3418
3419 StringBuilderVisitor(builder, this.offset)
3420 : this.builder = builder,
3421 stringConcat = builder.compiler.findHelper(
3422 const SourceString("stringConcat")),
3423 stringToString = builder.compiler.findHelper(
3424 const SourceString("stringToString"));
3425 3401
3426 void visit(Node node) { 3402 void visit(Node node) {
3427 node.accept(this); 3403 node.accept(this);
3428 } 3404 }
3429 3405
3430 visitNode(Node node) { 3406 visitNode(Node node) {
3431 builder.compiler.internalError('unexpected node', node: node); 3407 builder.compiler.internalError('unexpected node', node: node);
3432 } 3408 }
3433 3409
3434 void visitExpression(Node node) { 3410 void visitExpression(Node node) {
3435 flushLiterals(node);
3436 node.accept(builder); 3411 node.accept(builder);
3437 HInstruction asString = buildToString(node, builder.pop()); 3412 HInstruction expression = builder.pop();
3438 prefix = buildConcat(prefix, asString); 3413 result = (result === null) ? expression : concat(result, expression);
3439 }
3440
3441 void visitLiteralNull(LiteralNull node) {
3442 addLiteral(const LiteralDartString("null"));
3443 }
3444
3445 void visitLiteralInt(LiteralInt node) {
3446 addLiteral(new DartString.literal(node.value.toString()));
3447 }
3448
3449 void visitLiteralDouble(LiteralDouble node) {
3450 addLiteral(new DartString.literal(node.value.toString()));
3451 }
3452
3453 void visitLiteralBool(LiteralBool node) {
3454 addLiteral(node.value ? const LiteralDartString("true")
3455 : const LiteralDartString("false"));
3456 } 3414 }
3457 3415
3458 void visitStringInterpolation(StringInterpolation node) { 3416 void visitStringInterpolation(StringInterpolation node) {
3459 node.visitChildren(this); 3417 node.visitChildren(this);
3460 } 3418 }
3461 3419
3462 void visitStringInterpolationPart(StringInterpolationPart node) { 3420 void visitStringInterpolationPart(StringInterpolationPart node) {
3463 visit(node.expression); 3421 visit(node.expression);
3464 visit(node.string); 3422 visit(node.string);
3465 } 3423 }
3466 3424
3467 void visitLiteralString(LiteralString node) {
3468 addLiteral(node.dartString);
3469 }
3470
3471 void visitStringJuxtaposition(StringJuxtaposition node) { 3425 void visitStringJuxtaposition(StringJuxtaposition node) {
3472 node.visitChildren(this); 3426 node.visitChildren(this);
3473 } 3427 }
3474 3428
3475 void visitNodeList(NodeList node) { 3429 void visitNodeList(NodeList node) {
3476 node.visitChildren(this); 3430 node.visitChildren(this);
3477 } 3431 }
3478 3432
3479 /** 3433 HInstruction concat(HInstruction left, HInstruction right) {
3480 * Add another literal string to the literalAccumulator. 3434 HInstruction instruction = new HStringConcat(left, right);
3481 */ 3435 builder.add(instruction);
3482 void addLiteral(DartString dartString) { 3436 return instruction;
3483 literalAccumulator = new DartString.concat(literalAccumulator, dartString);
3484 }
3485
3486 /**
3487 * Combine the strings in [literalAccumulator] into the prefix instruction.
3488 * After this, the [literalAccumulator] is empty and [prefix] is non-null.
3489 */
3490 void flushLiterals(Node node) {
3491 if (literalAccumulator.isEmpty()) {
3492 if (prefix === null) {
3493 prefix = builder.graph.addConstantString(literalAccumulator, node);
3494 }
3495 return;
3496 }
3497 HInstruction string =
3498 builder.graph.addConstantString(literalAccumulator, node);
3499 literalAccumulator = new DartString.empty();
3500 if (prefix !== null) {
3501 prefix = buildConcat(prefix, string);
3502 } else {
3503 prefix = string;
3504 }
3505 }
3506
3507 HInstruction buildConcat(HInstruction left, HInstruction right) {
3508 HStatic target = new HStatic(stringConcat);
3509 builder.add(target);
3510 builder.push(new HAdd(target, left, right));
3511 return builder.pop();
3512 }
3513
3514 HInstruction buildToString(Node node, HInstruction input) {
3515 HStatic target = new HStatic(stringToString);
3516 builder.add(target);
3517 builder.push(new HInvokeStatic(Selector.INVOCATION_1,
3518 <HInstruction>[target, input],
3519 HType.STRING));
3520 return builder.pop();
3521 }
3522
3523 HInstruction result(Node node) {
3524 flushLiterals(node);
3525 return prefix;
3526 } 3437 }
3527 } 3438 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698