| 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) |
| 395 // |
| 396 // where instance is the [this] object for the method. In such a case, the |
| 397 // get of prototype might be evaluated before instance is created if we |
| 398 // generate instance at use site, which in turn might update the prototype |
| 399 // after first access if we use lazy initialization. |
| 400 // In this case, we therefore don't allow the receiver (the first argument) |
| 401 // to be generated at use site, and only analyze all other arguments. |
| 402 if (!backend.canUseAliasedSuperMember(superMethod, selector)) { |
| 403 analyzeInputs(instruction, 1); |
| 404 } else { |
| 405 super.visitInvokeSuper(instruction); |
| 406 } |
| 407 } |
| 408 |
| 387 void visitIs(HIs instruction) { | 409 void visitIs(HIs instruction) { |
| 388 // In the general case the input might be used multple multiple times, so it | 410 // 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 | 411 // must not be set generate at use site. If the code will generate |
| 390 // 'instanceof' then we can generate at use site. | 412 // 'instanceof' then we can generate at use site. |
| 391 if (instruction.useInstanceOf) { | 413 if (instruction.useInstanceOf) { |
| 392 analyzeInputs(instruction, 0); | 414 analyzeInputs(instruction, 0); |
| 393 } | 415 } |
| 394 } | 416 } |
| 395 | 417 |
| 396 // A bounds check method must not have its first input generated at use site, | 418 // 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 } | 752 } |
| 731 | 753 |
| 732 // If [thenInput] is defined in the first predecessor, then it is only used | 754 // If [thenInput] is defined in the first predecessor, then it is only used |
| 733 // by [phi] and can be generated at use site. | 755 // by [phi] and can be generated at use site. |
| 734 if (identical(thenInput.block, end.predecessors[0])) { | 756 if (identical(thenInput.block, end.predecessors[0])) { |
| 735 assert(thenInput.usedBy.length == 1); | 757 assert(thenInput.usedBy.length == 1); |
| 736 markAsGenerateAtUseSite(thenInput); | 758 markAsGenerateAtUseSite(thenInput); |
| 737 } | 759 } |
| 738 } | 760 } |
| 739 } | 761 } |
| OLD | NEW |