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

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: 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 2572 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 void visitLiteralString(LiteralString node) { 2583 void visitLiteralString(LiteralString node) {
2584 stack.add(graph.addConstantString(node.dartString, node)); 2584 stack.add(graph.addConstantString(node.dartString, node));
2585 } 2585 }
2586 2586
2587 void visitStringJuxtaposition(StringJuxtaposition node) { 2587 void visitStringJuxtaposition(StringJuxtaposition node) {
2588 if (!node.isInterpolation) { 2588 if (!node.isInterpolation) {
2589 // This is a simple string with no interpolations. 2589 // This is a simple string with no interpolations.
2590 stack.add(graph.addConstantString(node.dartString, node)); 2590 stack.add(graph.addConstantString(node.dartString, node));
2591 return; 2591 return;
2592 } 2592 }
2593 int offset = node.getBeginToken().charOffset; 2593 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this);
2594 StringBuilderVisitor stringBuilder =
2595 new StringBuilderVisitor(this, offset);
2596 stringBuilder.visit(node); 2594 stringBuilder.visit(node);
2597 stack.add(stringBuilder.result(node)); 2595 stack.add(stringBuilder.result(node));
2598 } 2596 }
2599 2597
2600 void visitLiteralNull(LiteralNull node) { 2598 void visitLiteralNull(LiteralNull node) {
2601 stack.add(graph.addConstantNull()); 2599 stack.add(graph.addConstantNull());
2602 } 2600 }
2603 2601
2604 visitNodeList(NodeList node) { 2602 visitNodeList(NodeList node) {
2605 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 2603 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2737 open(joinBlock); 2735 open(joinBlock);
2738 2736
2739 localsHandler.mergeWith(thenLocals, joinBlock); 2737 localsHandler.mergeWith(thenLocals, joinBlock);
2740 HPhi phi = new HPhi.manyInputs(null, 2738 HPhi phi = new HPhi.manyInputs(null,
2741 <HInstruction>[thenInstruction, elseInstruction]); 2739 <HInstruction>[thenInstruction, elseInstruction]);
2742 joinBlock.addPhi(phi); 2740 joinBlock.addPhi(phi);
2743 stack.add(phi); 2741 stack.add(phi);
2744 } 2742 }
2745 2743
2746 visitStringInterpolation(StringInterpolation node) { 2744 visitStringInterpolation(StringInterpolation node) {
2747 int offset = node.getBeginToken().charOffset; 2745 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this);
2748 StringBuilderVisitor stringBuilder =
2749 new StringBuilderVisitor(this, offset);
2750 stringBuilder.visit(node); 2746 stringBuilder.visit(node);
2751 stack.add(stringBuilder.result(node)); 2747 stack.add(stringBuilder.result(node));
2752 } 2748 }
2753 2749
2754 visitStringInterpolationPart(StringInterpolationPart node) { 2750 visitStringInterpolationPart(StringInterpolationPart node) {
2755 // The parts are iterated in visitStringInterpolation. 2751 // The parts are iterated in visitStringInterpolation.
2756 compiler.internalError('visitStringInterpolation should not be called', 2752 compiler.internalError('visitStringInterpolation should not be called',
2757 node: node); 2753 node: node);
2758 } 2754 }
2759 2755
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
3283 3279
3284 /** 3280 /**
3285 * Visitor that handles generation of string literals (LiteralString, 3281 * Visitor that handles generation of string literals (LiteralString,
3286 * StringInterpolation), and otherwise delegates to the given visitor for 3282 * StringInterpolation), and otherwise delegates to the given visitor for
3287 * non-literal subexpressions. 3283 * non-literal subexpressions.
3288 * TODO(lrn): Consider whether to handle compile time constant int/boolean 3284 * TODO(lrn): Consider whether to handle compile time constant int/boolean
3289 * expressions as well. 3285 * expressions as well.
3290 */ 3286 */
3291 class StringBuilderVisitor extends AbstractVisitor { 3287 class StringBuilderVisitor extends AbstractVisitor {
3292 final SsaBuilder builder; 3288 final SsaBuilder builder;
3293 final Element stringConcat;
3294 final Element stringToString;
3295 3289
3296 /** 3290 /**
3297 * Offset used for the synthetic operator token used by concat. 3291 * The string value generated so far.
3298 * Can probably be removed when we stop using String.operator+.
3299 */
3300 final int offset;
3301
3302 /**
3303 * Used to collect concatenated string literals into a single literal
3304 * instead of introducing unnecessary concatenations.
3305 */
3306 DartString literalAccumulator = const LiteralDartString("");
3307
3308 /**
3309 * The string value generated so far (not including that which is still
3310 * in [literalAccumulator]).
3311 */ 3292 */
3312 HInstruction prefix = null; 3293 HInstruction prefix = null;
floitsch 2012/06/06 12:13:34 Maybe rename to 'result' and remove result-method?
kasperl 2012/06/06 13:31:03 Done.
3313 3294
3314 StringBuilderVisitor(builder, this.offset) 3295 StringBuilderVisitor(this.builder);
3315 : this.builder = builder,
3316 stringConcat = builder.compiler.findHelper(
3317 const SourceString("stringConcat")),
3318 stringToString = builder.compiler.findHelper(
3319 const SourceString("stringToString"));
3320 3296
3321 void visit(Node node) { 3297 void visit(Node node) {
3322 node.accept(this); 3298 node.accept(this);
3323 } 3299 }
3324 3300
3325 visitNode(Node node) { 3301 visitNode(Node node) {
3326 builder.compiler.internalError('unexpected node', node: node); 3302 builder.compiler.internalError('unexpected node', node: node);
3327 } 3303 }
3328 3304
3329 void visitExpression(Node node) { 3305 void visitExpression(Node node) {
3330 flushLiterals(node);
3331 node.accept(builder); 3306 node.accept(builder);
3332 HInstruction asString = buildToString(node, builder.pop()); 3307 HInstruction expression = builder.pop();
3333 prefix = buildConcat(prefix, asString); 3308 prefix = (prefix === null) ? expression : concat(prefix, expression);
3334 }
3335
3336 void visitLiteralNull(LiteralNull node) {
3337 addLiteral(const LiteralDartString("null"));
3338 }
3339
3340 void visitLiteralInt(LiteralInt node) {
3341 addLiteral(new DartString.literal(node.value.toString()));
3342 }
3343
3344 void visitLiteralDouble(LiteralDouble node) {
3345 addLiteral(new DartString.literal(node.value.toString()));
3346 }
3347
3348 void visitLiteralBool(LiteralBool node) {
3349 addLiteral(node.value ? const LiteralDartString("true")
3350 : const LiteralDartString("false"));
3351 } 3309 }
3352 3310
3353 void visitStringInterpolation(StringInterpolation node) { 3311 void visitStringInterpolation(StringInterpolation node) {
3354 node.visitChildren(this); 3312 node.visitChildren(this);
3355 } 3313 }
3356 3314
3357 void visitStringInterpolationPart(StringInterpolationPart node) { 3315 void visitStringInterpolationPart(StringInterpolationPart node) {
3358 visit(node.expression); 3316 visit(node.expression);
3359 visit(node.string); 3317 visit(node.string);
3360 } 3318 }
3361 3319
3362 void visitLiteralString(LiteralString node) {
3363 addLiteral(node.dartString);
3364 }
3365
3366 void visitStringJuxtaposition(StringJuxtaposition node) { 3320 void visitStringJuxtaposition(StringJuxtaposition node) {
3367 node.visitChildren(this); 3321 node.visitChildren(this);
3368 } 3322 }
3369 3323
3370 void visitNodeList(NodeList node) { 3324 void visitNodeList(NodeList node) {
3371 node.visitChildren(this); 3325 node.visitChildren(this);
3372 } 3326 }
3373 3327
3374 /** 3328 HInstruction concat(HInstruction left, HInstruction right) {
3375 * Add another literal string to the literalAccumulator. 3329 HInstruction result = new HStringConcat([left, right]);
3376 */ 3330 builder.add(result);
3377 void addLiteral(DartString dartString) { 3331 return result;
3378 literalAccumulator = new DartString.concat(literalAccumulator, dartString);
3379 }
3380
3381 /**
3382 * Combine the strings in [literalAccumulator] into the prefix instruction.
3383 * After this, the [literalAccumulator] is empty and [prefix] is non-null.
3384 */
3385 void flushLiterals(Node node) {
3386 if (literalAccumulator.isEmpty()) {
3387 if (prefix === null) {
3388 prefix = builder.graph.addConstantString(literalAccumulator, node);
3389 }
3390 return;
3391 }
3392 HInstruction string =
3393 builder.graph.addConstantString(literalAccumulator, node);
3394 literalAccumulator = new DartString.empty();
3395 if (prefix !== null) {
3396 prefix = buildConcat(prefix, string);
3397 } else {
3398 prefix = string;
3399 }
3400 }
3401
3402 HInstruction buildConcat(HInstruction left, HInstruction right) {
3403 HStatic target = new HStatic(stringConcat);
3404 builder.add(target);
3405 builder.push(new HAdd(target, left, right));
3406 return builder.pop();
3407 }
3408
3409 HInstruction buildToString(Node node, HInstruction input) {
3410 HStatic target = new HStatic(stringToString);
3411 builder.add(target);
3412 builder.push(new HInvokeStatic(Selector.INVOCATION_1,
3413 <HInstruction>[target, input],
3414 HType.STRING));
3415 return builder.pop();
3416 } 3332 }
3417 3333
3418 HInstruction result(Node node) { 3334 HInstruction result(Node node) {
floitsch 2012/06/06 12:13:34 If you keep the result-method, remove the argument
3419 flushLiterals(node);
3420 return prefix; 3335 return prefix;
3421 } 3336 }
3422 } 3337 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698