Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 * Replaces some instructions with specialized versions to make codegen easier. | 8 * Replaces some instructions with specialized versions to make codegen easier. |
| 9 * Caches codegen information on nodes. | 9 * Caches codegen information on nodes. |
| 10 */ | 10 */ |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 Set<HInstruction> pureInputs; | 328 Set<HInstruction> pureInputs; |
| 329 Set<HInstruction> generateAtUseSite; | 329 Set<HInstruction> generateAtUseSite; |
| 330 | 330 |
| 331 void markAsGenerateAtUseSite(HInstruction instruction) { | 331 void markAsGenerateAtUseSite(HInstruction instruction) { |
| 332 assert(!instruction.isJsStatement()); | 332 assert(!instruction.isJsStatement()); |
| 333 generateAtUseSite.add(instruction); | 333 generateAtUseSite.add(instruction); |
| 334 } | 334 } |
| 335 | 335 |
| 336 SsaInstructionMerger(this.generateAtUseSite, this.compiler); | 336 SsaInstructionMerger(this.generateAtUseSite, this.compiler); |
| 337 | 337 |
| 338 JavaScriptBackend get backend => compiler.backend; | |
| 339 | |
| 338 void visitGraph(HGraph graph) { | 340 void visitGraph(HGraph graph) { |
| 339 visitDominatorTree(graph); | 341 visitDominatorTree(graph); |
| 340 } | 342 } |
| 341 | 343 |
| 342 void analyzeInputs(HInstruction user, int start) { | 344 void analyzeInputs(HInstruction user, int start) { |
| 343 List<HInstruction> inputs = user.inputs; | 345 List<HInstruction> inputs = user.inputs; |
| 344 for (int i = start; i < inputs.length; i++) { | 346 for (int i = start; i < inputs.length; i++) { |
| 345 HInstruction input = inputs[i]; | 347 HInstruction input = inputs[i]; |
| 346 if (!generateAtUseSite.contains(input) | 348 if (!generateAtUseSite.contains(input) |
| 347 && !input.isCodeMotionInvariant() | 349 && !input.isCodeMotionInvariant() |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 377 } | 379 } |
| 378 } | 380 } |
| 379 } | 381 } |
| 380 | 382 |
| 381 void visitInstruction(HInstruction instruction) { | 383 void visitInstruction(HInstruction instruction) { |
| 382 // A code motion invariant instruction is dealt before visiting it. | 384 // A code motion invariant instruction is dealt before visiting it. |
| 383 assert(!instruction.isCodeMotionInvariant()); | 385 assert(!instruction.isCodeMotionInvariant()); |
| 384 analyzeInputs(instruction, 0); | 386 analyzeInputs(instruction, 0); |
| 385 } | 387 } |
| 386 | 388 |
| 389 void visitInvokeSuper(HInvokeSuper instruction) { | |
| 390 Element superMethod = instruction.element; | |
| 391 Selector selector = instruction.selector; | |
| 392 // If aliased super members cannot be used, we will generate code like | |
| 393 // | |
| 394 // C.prototype.method.call(instance) | |
|
floitsch
2015/03/11 13:59:34
indent by 4.
herhut
2015/03/13 12:28:52
Done.
| |
| 395 // | |
| 396 // where instance is the [this] object for the method. In such a case, the | |
| 397 // get of prototype might be evaluted before instance is created if we | |
|
floitsch
2015/03/11 13:59:34
evaluated
herhut
2015/03/13 12:28:52
Done.
| |
| 398 // generate instance at use site, which in turn might update the prototype | |
| 399 // after first access if we use lazy initialization. | |
|
floitsch
2015/03/11 13:59:34
Also add to the comment, how you work around it?
(
herhut
2015/03/13 12:28:52
Done.
| |
| 400 if (!backend.canUseAliasedSuperMember(superMethod, selector)) { | |
| 401 analyzeInputs(instruction, 1); | |
| 402 } else { | |
| 403 super.visitInvokeSuper(instruction); | |
| 404 } | |
| 405 } | |
| 406 | |
| 387 void visitIs(HIs instruction) { | 407 void visitIs(HIs instruction) { |
| 388 // In the general case the input might be used multple multiple times, so it | 408 // In the general case the input might be used multple multiple times, so it |
| 389 // must not be set generate at use site. If the code will generate | 409 // must not be set generate at use site. If the code will generate |
| 390 // 'instanceof' then we can generate at use site. | 410 // 'instanceof' then we can generate at use site. |
| 391 if (instruction.useInstanceOf) { | 411 if (instruction.useInstanceOf) { |
| 392 analyzeInputs(instruction, 0); | 412 analyzeInputs(instruction, 0); |
| 393 } | 413 } |
| 394 } | 414 } |
| 395 | 415 |
| 396 // A bounds check method must not have its first input generated at use site, | 416 // A bounds check method must not have its first input generated at use site, |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 } | 750 } |
| 731 | 751 |
| 732 // If [thenInput] is defined in the first predecessor, then it is only used | 752 // If [thenInput] is defined in the first predecessor, then it is only used |
| 733 // by [phi] and can be generated at use site. | 753 // by [phi] and can be generated at use site. |
| 734 if (identical(thenInput.block, end.predecessors[0])) { | 754 if (identical(thenInput.block, end.predecessors[0])) { |
| 735 assert(thenInput.usedBy.length == 1); | 755 assert(thenInput.usedBy.length == 1); |
| 736 markAsGenerateAtUseSite(thenInput); | 756 markAsGenerateAtUseSite(thenInput); |
| 737 } | 757 } |
| 738 } | 758 } |
| 739 } | 759 } |
| OLD | NEW |