| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
| 8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
| 9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
| 10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 blocks.add(block); | 132 blocks.add(block); |
| 133 assert(blocks[id] === block); | 133 assert(blocks[id] === block); |
| 134 } | 134 } |
| 135 | 135 |
| 136 HBasicBlock addNewBlock() { | 136 HBasicBlock addNewBlock() { |
| 137 HBasicBlock result = new HBasicBlock(); | 137 HBasicBlock result = new HBasicBlock(); |
| 138 addBlock(result); | 138 addBlock(result); |
| 139 return result; | 139 return result; |
| 140 } | 140 } |
| 141 | 141 |
| 142 HBasicBlock addNewLoopHeaderBlock(int kind, | 142 HBasicBlock addNewLoopHeaderBlock(TargetElement target, |
| 143 TargetElement target, | |
| 144 List<LabelElement> labels) { | 143 List<LabelElement> labels) { |
| 145 HBasicBlock result = addNewBlock(); | 144 HBasicBlock result = addNewBlock(); |
| 146 result.blockInformation = | 145 result.loopInformation = |
| 147 new HLoopInformation(kind, result, target, labels); | 146 new HLoopInformation(result, target, labels); |
| 148 return result; | 147 return result; |
| 149 } | 148 } |
| 150 | 149 |
| 151 static HType mapConstantTypeToSsaType(Constant constant) { | 150 static HType mapConstantTypeToSsaType(Constant constant) { |
| 152 if (constant.isNull()) return HType.UNKNOWN; | 151 if (constant.isNull()) return HType.UNKNOWN; |
| 153 if (constant.isBool()) return HType.BOOLEAN; | 152 if (constant.isBool()) return HType.BOOLEAN; |
| 154 if (constant.isInt()) return HType.INTEGER; | 153 if (constant.isInt()) return HType.INTEGER; |
| 155 if (constant.isDouble()) return HType.DOUBLE; | 154 if (constant.isDouble()) return HType.DOUBLE; |
| 156 if (constant.isString()) return HType.STRING; | 155 if (constant.isString()) return HType.STRING; |
| 157 if (constant.isList()) return HType.READABLE_ARRAY; | 156 if (constant.isList()) return HType.READABLE_ARRAY; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 // this [id]. The exception are back-edges. | 415 // this [id]. The exception are back-edges. |
| 417 int id; | 416 int id; |
| 418 | 417 |
| 419 static final int STATUS_NEW = 0; | 418 static final int STATUS_NEW = 0; |
| 420 static final int STATUS_OPEN = 1; | 419 static final int STATUS_OPEN = 1; |
| 421 static final int STATUS_CLOSED = 2; | 420 static final int STATUS_CLOSED = 2; |
| 422 int status = STATUS_NEW; | 421 int status = STATUS_NEW; |
| 423 | 422 |
| 424 HInstructionList phis; | 423 HInstructionList phis; |
| 425 | 424 |
| 426 HBlockInformation blockInformation = null; | 425 HLoopInformation loopInformation = null; |
| 426 HBlockFlow blockFlow = null; |
| 427 HBasicBlock parentLoopHeader = null; | 427 HBasicBlock parentLoopHeader = null; |
| 428 List<HTypeGuard> guards; | 428 List<HTypeGuard> guards; |
| 429 | 429 |
| 430 final List<HBasicBlock> predecessors; | 430 final List<HBasicBlock> predecessors; |
| 431 List<HBasicBlock> successors; | 431 List<HBasicBlock> successors; |
| 432 | 432 |
| 433 HBasicBlock dominator = null; | 433 HBasicBlock dominator = null; |
| 434 final List<HBasicBlock> dominatedBlocks; | 434 final List<HBasicBlock> dominatedBlocks; |
| 435 | 435 |
| 436 HBasicBlock() : this.withId(null); | 436 HBasicBlock() : this.withId(null); |
| 437 HBasicBlock.withId(this.id) | 437 HBasicBlock.withId(this.id) |
| 438 : phis = new HInstructionList(), | 438 : phis = new HInstructionList(), |
| 439 predecessors = <HBasicBlock>[], | 439 predecessors = <HBasicBlock>[], |
| 440 successors = const <HBasicBlock>[], | 440 successors = const <HBasicBlock>[], |
| 441 dominatedBlocks = <HBasicBlock>[], | 441 dominatedBlocks = <HBasicBlock>[], |
| 442 guards = <HTypeGuard>[]; | 442 guards = <HTypeGuard>[]; |
| 443 | 443 |
| 444 int hashCode() => id; | 444 int hashCode() => id; |
| 445 | 445 |
| 446 bool isNew() => status == STATUS_NEW; | 446 bool isNew() => status == STATUS_NEW; |
| 447 bool isOpen() => status == STATUS_OPEN; | 447 bool isOpen() => status == STATUS_OPEN; |
| 448 bool isClosed() => status == STATUS_CLOSED; | 448 bool isClosed() => status == STATUS_CLOSED; |
| 449 | 449 |
| 450 bool isLoopHeader() { | 450 bool isLoopHeader() { |
| 451 if (blockInformation is HLoopInformation) { | 451 return loopInformation !== null; |
| 452 HLoopInformation info = blockInformation; | |
| 453 return (this === info.header); | |
| 454 } | |
| 455 return false; | |
| 456 } | 452 } |
| 457 bool isLabeledBlock() => blockInformation is HLabeledBlockInformation; | 453 |
| 454 void setBlockFlow(HBlockInformation blockInfo, HBasicBlock continuation) { |
| 455 blockFlow = new HBlockFlow(blockInfo, continuation); |
| 456 } |
| 457 |
| 458 bool isLabeledBlock() => |
| 459 blockFlow !== null && |
| 460 blockFlow.body is HLabeledBlockInformation; |
| 458 | 461 |
| 459 HBasicBlock get enclosingLoopHeader() { | 462 HBasicBlock get enclosingLoopHeader() { |
| 460 if (isLoopHeader()) return this; | 463 if (isLoopHeader()) return this; |
| 461 return parentLoopHeader; | 464 return parentLoopHeader; |
| 462 } | 465 } |
| 463 | 466 |
| 464 bool hasGuards() => !guards.isEmpty(); | 467 bool hasGuards() => !guards.isEmpty(); |
| 465 | 468 |
| 466 void open() { | 469 void open() { |
| 467 assert(isNew()); | 470 assert(isNew()); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 } else { | 564 } else { |
| 562 successors.add(block); | 565 successors.add(block); |
| 563 } | 566 } |
| 564 block.predecessors.add(this); | 567 block.predecessors.add(this); |
| 565 } | 568 } |
| 566 | 569 |
| 567 void postProcessLoopHeader() { | 570 void postProcessLoopHeader() { |
| 568 assert(isLoopHeader()); | 571 assert(isLoopHeader()); |
| 569 // Only the first entry into the loop is from outside the | 572 // Only the first entry into the loop is from outside the |
| 570 // loop. All other entries must be back edges. | 573 // loop. All other entries must be back edges. |
| 571 HLoopInformation loopInformation = this.blockInformation; | |
| 572 for (int i = 1, length = predecessors.length; i < length; i++) { | 574 for (int i = 1, length = predecessors.length; i < length; i++) { |
| 573 loopInformation.addBackEdge(predecessors[i]); | 575 loopInformation.addBackEdge(predecessors[i]); |
| 574 } | 576 } |
| 575 } | 577 } |
| 576 | 578 |
| 577 /** | 579 /** |
| 578 * Rewrites all uses of the [from] instruction to using the [to] | 580 * Rewrites all uses of the [from] instruction to using the [to] |
| 579 * instruction instead. | 581 * instruction instead. |
| 580 */ | 582 */ |
| 581 void rewrite(HInstruction from, HInstruction to) { | 583 void rewrite(HInstruction from, HInstruction to) { |
| (...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1650 HParameterValue exception; | 1652 HParameterValue exception; |
| 1651 HBasicBlock finallyBlock; | 1653 HBasicBlock finallyBlock; |
| 1652 HTry() : super(const <HInstruction>[]); | 1654 HTry() : super(const <HInstruction>[]); |
| 1653 toString() => 'try'; | 1655 toString() => 'try'; |
| 1654 accept(HVisitor visitor) => visitor.visitTry(this); | 1656 accept(HVisitor visitor) => visitor.visitTry(this); |
| 1655 HBasicBlock get joinBlock() => this.block.successors.last(); | 1657 HBasicBlock get joinBlock() => this.block.successors.last(); |
| 1656 } | 1658 } |
| 1657 | 1659 |
| 1658 class HIf extends HConditionalBranch { | 1660 class HIf extends HConditionalBranch { |
| 1659 bool hasElse; | 1661 bool hasElse; |
| 1660 HIfBlockInformation blockInformation = null; | 1662 HBlockFlow blockInformation = null; |
| 1661 HIf(HInstruction condition, this.hasElse) : super(<HInstruction>[condition]); | 1663 HIf(HInstruction condition, this.hasElse) : super(<HInstruction>[condition]); |
| 1662 toString() => 'if'; | 1664 toString() => 'if'; |
| 1663 accept(HVisitor visitor) => visitor.visitIf(this); | 1665 accept(HVisitor visitor) => visitor.visitIf(this); |
| 1664 | 1666 |
| 1665 HBasicBlock get thenBlock() { | 1667 HBasicBlock get thenBlock() { |
| 1666 assert(block.dominatedBlocks[0] === block.successors[0]); | 1668 assert(block.dominatedBlocks[0] === block.successors[0]); |
| 1667 return block.successors[0]; | 1669 return block.successors[0]; |
| 1668 } | 1670 } |
| 1669 | 1671 |
| 1670 HBasicBlock get elseBlock() { | 1672 HBasicBlock get elseBlock() { |
| 1671 if (hasElse) { | 1673 if (hasElse) { |
| 1672 assert(block.dominatedBlocks[1] === block.successors[1]); | 1674 assert(block.dominatedBlocks[1] === block.successors[1]); |
| 1673 return block.successors[1]; | 1675 return block.successors[1]; |
| 1674 } else { | 1676 } else { |
| 1675 return null; | 1677 return null; |
| 1676 } | 1678 } |
| 1677 } | 1679 } |
| 1678 | 1680 |
| 1679 HBasicBlock get joinBlock() => blockInformation.joinBlock; | 1681 HBasicBlock get joinBlock() => blockInformation.continuation; |
| 1680 } | 1682 } |
| 1681 | 1683 |
| 1682 class HLoopBranch extends HConditionalBranch { | 1684 class HLoopBranch extends HConditionalBranch { |
| 1683 static final int CONDITION_FIRST_LOOP = 0; | 1685 static final int CONDITION_FIRST_LOOP = 0; |
| 1684 static final int DO_WHILE_LOOP = 1; | 1686 static final int DO_WHILE_LOOP = 1; |
| 1685 | 1687 |
| 1686 final int kind; | 1688 final int kind; |
| 1687 HLoopBranch(HInstruction condition, [this.kind = CONDITION_FIRST_LOOP]) | 1689 HLoopBranch(HInstruction condition, [this.kind = CONDITION_FIRST_LOOP]) |
| 1688 : super(<HInstruction>[condition]); | 1690 : super(<HInstruction>[condition]); |
| 1689 toString() => 'loop-branch'; | 1691 toString() => 'loop-branch'; |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2155 [bool this.checked = false]) | 2157 [bool this.checked = false]) |
| 2156 : super(<HInstruction>[input]) { | 2158 : super(<HInstruction>[input]) { |
| 2157 sourceElement = input.sourceElement; | 2159 sourceElement = input.sourceElement; |
| 2158 } | 2160 } |
| 2159 | 2161 |
| 2160 HType get guaranteedType() => type; | 2162 HType get guaranteedType() => type; |
| 2161 | 2163 |
| 2162 accept(HVisitor visitor) => visitor.visitTypeConversion(this); | 2164 accept(HVisitor visitor) => visitor.visitTypeConversion(this); |
| 2163 } | 2165 } |
| 2164 | 2166 |
| 2167 /** Non-block-based (aka. traditional) loop information. */ |
| 2168 class HLoopInformation { |
| 2169 final HBasicBlock header; |
| 2170 final List<HBasicBlock> blocks; |
| 2171 final List<HBasicBlock> backEdges; |
| 2172 final List<LabelElement> labels; |
| 2173 final TargetElement target; |
| 2174 |
| 2175 /** Corresponding block information for the loop. */ |
| 2176 HLoopBlockInformation loopBlockInformation; |
| 2177 |
| 2178 HLoopInformation(this.header, this.target, this.labels) |
| 2179 : blocks = new List<HBasicBlock>(), |
| 2180 backEdges = new List<HBasicBlock>(); |
| 2181 |
| 2182 void addBackEdge(HBasicBlock predecessor) { |
| 2183 backEdges.add(predecessor); |
| 2184 addBlock(predecessor); |
| 2185 } |
| 2186 |
| 2187 // Adds a block and transitively all its predecessors in the loop as |
| 2188 // loop blocks. |
| 2189 void addBlock(HBasicBlock block) { |
| 2190 if (block === header) return; |
| 2191 HBasicBlock parentHeader = block.parentLoopHeader; |
| 2192 if (parentHeader === header) { |
| 2193 // Nothing to do in this case. |
| 2194 } else if (parentHeader !== null) { |
| 2195 addBlock(parentHeader); |
| 2196 } else { |
| 2197 block.parentLoopHeader = header; |
| 2198 blocks.add(block); |
| 2199 for (int i = 0, length = block.predecessors.length; i < length; i++) { |
| 2200 addBlock(block.predecessors[i]); |
| 2201 } |
| 2202 } |
| 2203 } |
| 2204 |
| 2205 HBasicBlock getLastBackEdge() { |
| 2206 int maxId = -1; |
| 2207 HBasicBlock result = null; |
| 2208 for (int i = 0, length = backEdges.length; i < length; i++) { |
| 2209 HBasicBlock current = backEdges[i]; |
| 2210 if (current.id > maxId) { |
| 2211 maxId = current.id; |
| 2212 result = current; |
| 2213 } |
| 2214 } |
| 2215 return result; |
| 2216 } |
| 2217 } |
| 2218 |
| 2219 |
| 2165 /** | 2220 /** |
| 2166 * Information about a syntactic-like structure that can be attached | 2221 * Embedding of a [HBlockInformation] for block-structure based traversal |
| 2167 * to a [HBasicBlock]. | 2222 * in a dominator based flow traversal by attaching it to a basic block. |
| 2223 * To go back to dominator-based traversal, a [HSubGraphBlockInformation] |
| 2224 * structure can be added in the block structure. |
| 2225 */ |
| 2226 class HBlockFlow { |
| 2227 final HBlockInformation body; |
| 2228 final HBasicBlock continuation; |
| 2229 HBlockFlow(this.body, this.continuation); |
| 2230 } |
| 2231 |
| 2232 |
| 2233 /** |
| 2234 * Information about a syntactic-like structure. |
| 2168 */ | 2235 */ |
| 2169 interface HBlockInformation { | 2236 interface HBlockInformation { |
| 2170 HBasicBlock get start(); | 2237 HBasicBlock get start(); |
| 2171 HBasicBlock get end(); | 2238 HBasicBlock get end(); |
| 2172 bool accept(HBlockInformationVisitor visitor); | 2239 bool accept(HBlockInformationVisitor visitor); |
| 2173 } | 2240 } |
| 2174 | 2241 |
| 2242 |
| 2175 /** | 2243 /** |
| 2176 * Information about a statement-like structure. | 2244 * Information about a statement-like structure. |
| 2177 */ | 2245 */ |
| 2178 interface HStatementInformation extends HBlockInformation { | 2246 interface HStatementInformation extends HBlockInformation { |
| 2179 bool accept(HStatementInformationVisitor visitor); | 2247 bool accept(HStatementInformationVisitor visitor); |
| 2180 } | 2248 } |
| 2181 | 2249 |
| 2250 |
| 2182 /** | 2251 /** |
| 2183 * Information about an expression-like structure. | 2252 * Information about an expression-like structure. |
| 2184 */ | 2253 */ |
| 2185 interface HExpressionInformation extends HBlockInformation { | 2254 interface HExpressionInformation extends HBlockInformation { |
| 2186 bool accept(HExpressionInformationVisitor visitor); | 2255 bool accept(HExpressionInformationVisitor visitor); |
| 2187 HInstruction get conditionExpression(); | 2256 HInstruction get conditionExpression(); |
| 2188 } | 2257 } |
| 2189 | 2258 |
| 2190 | 2259 |
| 2191 interface HStatementInformationVisitor { | 2260 interface HStatementInformationVisitor { |
| 2192 bool visitLabeledBlockInfo(HLabeledBlockInformation info); | 2261 bool visitLabeledBlockInfo(HLabeledBlockInformation info); |
| 2193 bool visitLoopInfo(HLoopInformation info); | 2262 bool visitLoopInfo(HLoopBlockInformation info); |
| 2194 bool visitIfInfo(HIfBlockInformation info); | 2263 bool visitIfInfo(HIfBlockInformation info); |
| 2195 bool visitTryInfo(HTryBlockInformation info); | 2264 bool visitTryInfo(HTryBlockInformation info); |
| 2265 bool visitSequenceInfo(HStatementSequenceInformation info); |
| 2266 // Pseudo-structure embedding a dominator-based traversal into |
| 2267 // the block-structure traversal. This will eventually go away. |
| 2196 bool visitSubGraphInfo(HSubGraphBlockInformation info); | 2268 bool visitSubGraphInfo(HSubGraphBlockInformation info); |
| 2197 } | 2269 } |
| 2198 | 2270 |
| 2271 |
| 2199 interface HExpressionInformationVisitor { | 2272 interface HExpressionInformationVisitor { |
| 2200 bool visitAndOrInfo(HAndOrBlockInformation info); | 2273 bool visitAndOrInfo(HAndOrBlockInformation info); |
| 2201 bool visitSubExpressionInfo(HSubExpressionBlockInformation info); | 2274 bool visitSubExpressionInfo(HSubExpressionBlockInformation info); |
| 2202 } | 2275 } |
| 2203 | 2276 |
| 2277 |
| 2204 interface HBlockInformationVisitor extends HStatementInformationVisitor, | 2278 interface HBlockInformationVisitor extends HStatementInformationVisitor, |
| 2205 HExpressionInformationVisitor { | 2279 HExpressionInformationVisitor { |
| 2206 } | 2280 } |
| 2207 | 2281 |
| 2282 |
| 2208 /** | 2283 /** |
| 2209 * Generic class wrapping a [SubGraph] as a block-information until | 2284 * Generic class wrapping a [SubGraph] as a block-information until |
| 2210 * all structures are handled properly. | 2285 * all structures are handled properly. |
| 2211 */ | 2286 */ |
| 2212 class HSubGraphBlockInformation implements HStatementInformation { | 2287 class HSubGraphBlockInformation implements HStatementInformation { |
| 2213 final SubGraph subGraph; | 2288 final SubGraph subGraph; |
| 2214 HSubGraphBlockInformation(this.subGraph); | 2289 HSubGraphBlockInformation(this.subGraph); |
| 2215 | 2290 |
| 2216 HBasicBlock get start() => subGraph.start; | 2291 HBasicBlock get start() => subGraph.start; |
| 2217 HBasicBlock get end() => subGraph.end; | 2292 HBasicBlock get end() => subGraph.end; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2232 HBasicBlock get start() => subExpression.start; | 2307 HBasicBlock get start() => subExpression.start; |
| 2233 HBasicBlock get end() => subExpression.end; | 2308 HBasicBlock get end() => subExpression.end; |
| 2234 | 2309 |
| 2235 HInstruction get conditionExpression() => subExpression.conditionExpression; | 2310 HInstruction get conditionExpression() => subExpression.conditionExpression; |
| 2236 | 2311 |
| 2237 bool accept(HExpressionInformationVisitor visitor) => | 2312 bool accept(HExpressionInformationVisitor visitor) => |
| 2238 visitor.visitSubExpressionInfo(this); | 2313 visitor.visitSubExpressionInfo(this); |
| 2239 } | 2314 } |
| 2240 | 2315 |
| 2241 | 2316 |
| 2317 /** A sequence of separate statements. */ |
| 2318 class HStatementSequenceInformation implements HStatementInformation { |
| 2319 final List<HStatementInformation> statements; |
| 2320 HStatementSequenceInformation(this.statements); |
| 2321 |
| 2322 HBasicBlock get start() => statements[0].start; |
| 2323 HBasicBlock get end() => statements.last().end; |
| 2324 |
| 2325 bool accept(HStatementInformationVisitor visitor) => |
| 2326 visitor.visitSequenceInfo(this); |
| 2327 } |
| 2328 |
| 2329 |
| 2242 class HLabeledBlockInformation implements HStatementInformation { | 2330 class HLabeledBlockInformation implements HStatementInformation { |
| 2243 final HStatementInformation body; | 2331 final HStatementInformation body; |
| 2244 final HBasicBlock joinBlock; | |
| 2245 final List<LabelElement> labels; | 2332 final List<LabelElement> labels; |
| 2246 final TargetElement target; | 2333 final TargetElement target; |
| 2247 final bool isContinue; | 2334 final bool isContinue; |
| 2248 | 2335 |
| 2249 HLabeledBlockInformation(this.body, this.joinBlock, | 2336 HLabeledBlockInformation(this.body, |
| 2250 List<LabelElement> labels, | 2337 List<LabelElement> labels, |
| 2251 [this.isContinue = false]) : | 2338 [this.isContinue = false]) : |
| 2252 this.labels = labels, this.target = labels[0].target; | 2339 this.labels = labels, this.target = labels[0].target; |
| 2253 | 2340 |
| 2254 HLabeledBlockInformation.implicit(this.body, | 2341 HLabeledBlockInformation.implicit(this.body, |
| 2255 this.joinBlock, | |
| 2256 this.target, | 2342 this.target, |
| 2257 [this.isContinue = false]) | 2343 [this.isContinue = false]) |
| 2258 : this.labels = const<LabelElement>[]; | 2344 : this.labels = const<LabelElement>[]; |
| 2259 | 2345 |
| 2260 HBasicBlock get start() => body.start; | 2346 HBasicBlock get start() => body.start; |
| 2261 HBasicBlock get end() => body.end; | 2347 HBasicBlock get end() => body.end; |
| 2262 | 2348 |
| 2263 bool accept(HStatementInformationVisitor visitor) => | 2349 bool accept(HStatementInformationVisitor visitor) => |
| 2264 visitor.visitLabeledBlockInfo(this); | 2350 visitor.visitLabeledBlockInfo(this); |
| 2265 } | 2351 } |
| 2266 | 2352 |
| 2267 class LoopTypeVisitor extends AbstractVisitor { | 2353 class LoopTypeVisitor extends AbstractVisitor { |
| 2268 const LoopTypeVisitor(); | 2354 const LoopTypeVisitor(); |
| 2269 int visitNode(Node node) { | 2355 int visitNode(Node node) { |
| 2270 unreachable(); | 2356 unreachable(); |
| 2271 } | 2357 } |
| 2272 int visitWhile(While node) => HLoopInformation.WHILE_LOOP; | 2358 int visitWhile(While node) => HLoopBlockInformation.WHILE_LOOP; |
| 2273 int visitFor(For node) => HLoopInformation.FOR_LOOP; | 2359 int visitFor(For node) => HLoopBlockInformation.FOR_LOOP; |
| 2274 int visitDoWhile(DoWhile node) => HLoopInformation.DO_WHILE_LOOP; | 2360 int visitDoWhile(DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
| 2275 int visitForIn(ForIn node) => HLoopInformation.FOR_IN_LOOP; | 2361 int visitForIn(ForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 2276 } | 2362 } |
| 2277 | 2363 |
| 2278 class HLoopInformation implements HStatementInformation { | 2364 class HLoopBlockInformation implements HStatementInformation { |
| 2279 static final int WHILE_LOOP = 0; | 2365 static final int WHILE_LOOP = 0; |
| 2280 static final int FOR_LOOP = 1; | 2366 static final int FOR_LOOP = 1; |
| 2281 static final int DO_WHILE_LOOP = 2; | 2367 static final int DO_WHILE_LOOP = 2; |
| 2282 static final int FOR_IN_LOOP = 3; | 2368 static final int FOR_IN_LOOP = 3; |
| 2283 | 2369 |
| 2284 final int kind; | 2370 final int kind; |
| 2285 final HBasicBlock header; | 2371 final HExpressionInformation initializer; |
| 2286 final List<HBasicBlock> blocks; | 2372 final HExpressionInformation condition; |
| 2287 final List<HBasicBlock> backEdges; | 2373 final HStatementInformation body; |
| 2374 final HExpressionInformation updates; |
| 2375 final TargetElement target; |
| 2288 final List<LabelElement> labels; | 2376 final List<LabelElement> labels; |
| 2289 final TargetElement target; | |
| 2290 HExpressionInformation initializer = null; | |
| 2291 HExpressionInformation condition = null; | |
| 2292 HStatementInformation body = null; | |
| 2293 HExpressionInformation updates = null; | |
| 2294 HBasicBlock joinBlock; | |
| 2295 | 2377 |
| 2296 HLoopInformation(this.kind, this.header, this.target, this.labels) | 2378 HLoopBlockInformation(this.kind, |
| 2297 : blocks = new List<HBasicBlock>(), | 2379 this.initializer, |
| 2298 backEdges = new List<HBasicBlock>(); | 2380 this.condition, |
| 2381 this.body, |
| 2382 this.updates, |
| 2383 this.target, |
| 2384 this.labels); |
| 2299 | 2385 |
| 2300 HBasicBlock get start() { | 2386 HBasicBlock get start() { |
| 2301 if (initializer !== null) return initializer.start; | 2387 if (initializer !== null) return initializer.start; |
| 2302 if (kind == DO_WHILE_LOOP) { | 2388 if (kind == DO_WHILE_LOOP) { |
| 2303 return body.start; | 2389 return body.start; |
| 2304 } | 2390 } |
| 2305 return condition.start; | 2391 return condition.start; |
| 2306 } | 2392 } |
| 2307 | 2393 |
| 2308 HBasicBlock get end() { | 2394 HBasicBlock get end() { |
| 2309 if (updates !== null) return updates.end; | 2395 if (updates !== null) return updates.end; |
| 2310 if (kind == DO_WHILE_LOOP) { | 2396 if (kind == DO_WHILE_LOOP) { |
| 2311 return condition.end; | 2397 return condition.end; |
| 2312 } | 2398 } |
| 2313 return body.end; | 2399 return body.end; |
| 2314 } | 2400 } |
| 2315 | 2401 |
| 2316 static int loopType(Node node) { | 2402 static int loopType(Node node) { |
| 2317 return node.accept(const LoopTypeVisitor()); | 2403 return node.accept(const LoopTypeVisitor()); |
| 2318 } | 2404 } |
| 2319 | 2405 |
| 2320 void addBackEdge(HBasicBlock predecessor) { | |
| 2321 backEdges.add(predecessor); | |
| 2322 addBlock(predecessor); | |
| 2323 } | |
| 2324 | |
| 2325 // Adds a block and transitively all its predecessors in the loop as | |
| 2326 // loop blocks. | |
| 2327 void addBlock(HBasicBlock block) { | |
| 2328 if (block === header) return; | |
| 2329 HBasicBlock parentHeader = block.parentLoopHeader; | |
| 2330 if (parentHeader === header) { | |
| 2331 // Nothing to do in this case. | |
| 2332 } else if (parentHeader !== null) { | |
| 2333 addBlock(parentHeader); | |
| 2334 } else { | |
| 2335 block.parentLoopHeader = header; | |
| 2336 blocks.add(block); | |
| 2337 for (int i = 0, length = block.predecessors.length; i < length; i++) { | |
| 2338 addBlock(block.predecessors[i]); | |
| 2339 } | |
| 2340 } | |
| 2341 } | |
| 2342 | |
| 2343 HBasicBlock getLastBackEdge() { | |
| 2344 int maxId = -1; | |
| 2345 HBasicBlock result = null; | |
| 2346 for (int i = 0, length = backEdges.length; i < length; i++) { | |
| 2347 HBasicBlock current = backEdges[i]; | |
| 2348 if (current.id > maxId) { | |
| 2349 maxId = current.id; | |
| 2350 result = current; | |
| 2351 } | |
| 2352 } | |
| 2353 return result; | |
| 2354 } | |
| 2355 | |
| 2356 bool accept(HStatementInformationVisitor visitor) => | 2406 bool accept(HStatementInformationVisitor visitor) => |
| 2357 visitor.visitLoopInfo(this); | 2407 visitor.visitLoopInfo(this); |
| 2358 } | 2408 } |
| 2359 | 2409 |
| 2360 class HIfBlockInformation implements HStatementInformation { | 2410 class HIfBlockInformation implements HStatementInformation { |
| 2361 final HExpressionInformation condition; | 2411 final HExpressionInformation condition; |
| 2362 final HStatementInformation thenGraph; | 2412 final HStatementInformation thenGraph; |
| 2363 final HStatementInformation elseGraph; | 2413 final HStatementInformation elseGraph; |
| 2364 final HBasicBlock joinBlock; | |
| 2365 HIfBlockInformation(this.condition, | 2414 HIfBlockInformation(this.condition, |
| 2366 this.thenGraph, | 2415 this.thenGraph, |
| 2367 this.elseGraph, | 2416 this.elseGraph); |
| 2368 this.joinBlock); | |
| 2369 | 2417 |
| 2370 HBasicBlock get start() => condition.start; | 2418 HBasicBlock get start() => condition.start; |
| 2371 HBasicBlock get end() => elseGraph === null ? thenGraph.end : elseGraph.end; | 2419 HBasicBlock get end() => elseGraph === null ? thenGraph.end : elseGraph.end; |
| 2372 | 2420 |
| 2373 bool accept(HStatementInformationVisitor visitor) => | 2421 bool accept(HStatementInformationVisitor visitor) => |
| 2374 visitor.visitIfInfo(this); | 2422 visitor.visitIfInfo(this); |
| 2375 } | 2423 } |
| 2376 | 2424 |
| 2377 class HAndOrBlockInformation implements HExpressionInformation { | 2425 class HAndOrBlockInformation implements HExpressionInformation { |
| 2378 final bool isAnd; | 2426 final bool isAnd; |
| 2379 final HExpressionInformation left; | 2427 final HExpressionInformation left; |
| 2380 final HExpressionInformation right; | 2428 final HExpressionInformation right; |
| 2381 final HBasicBlock joinBlock; | |
| 2382 HAndOrBlockInformation(this.isAnd, | 2429 HAndOrBlockInformation(this.isAnd, |
| 2383 this.left, | 2430 this.left, |
| 2384 this.right, | 2431 this.right); |
| 2385 this.joinBlock); | |
| 2386 | 2432 |
| 2387 HBasicBlock get start() => left.start; | 2433 HBasicBlock get start() => left.start; |
| 2388 HBasicBlock get end() => right.end; | 2434 HBasicBlock get end() => right.end; |
| 2389 | 2435 |
| 2390 // We don't currently use HAndOrBlockInformation. | 2436 // We don't currently use HAndOrBlockInformation. |
| 2391 HInstruction get conditionExpression() { unreachable(); } | 2437 HInstruction get conditionExpression() { unreachable(); } |
| 2392 bool accept(HExpressionInformationVisitor visitor) => | 2438 bool accept(HExpressionInformationVisitor visitor) => |
| 2393 visitor.visitAndOrInfo(this); | 2439 visitor.visitAndOrInfo(this); |
| 2394 } | 2440 } |
| 2395 | 2441 |
| 2396 class HTryBlockInformation implements HStatementInformation { | 2442 class HTryBlockInformation implements HStatementInformation { |
| 2397 final HStatementInformation body; | 2443 final HStatementInformation body; |
| 2398 final HParameterValue catchVariable; | 2444 final HParameterValue catchVariable; |
| 2399 final HStatementInformation catchBlock; | 2445 final HStatementInformation catchBlock; |
| 2400 final HStatementInformation finallyBlock; | 2446 final HStatementInformation finallyBlock; |
| 2401 // TODO: Move joinBlock out of the structure, and into the surrounding | |
| 2402 // structure. | |
| 2403 final HBasicBlock joinBlock; | |
| 2404 HTryBlockInformation(this.body, | 2447 HTryBlockInformation(this.body, |
| 2405 this.catchVariable, | 2448 this.catchVariable, |
| 2406 this.catchBlock, | 2449 this.catchBlock, |
| 2407 this.finallyBlock, | 2450 this.finallyBlock); |
| 2408 this.joinBlock); | |
| 2409 | 2451 |
| 2410 HBasicBlock get start() => body.start; | 2452 HBasicBlock get start() => body.start; |
| 2411 HBasicBlock get end() => | 2453 HBasicBlock get end() => |
| 2412 finallyBlock === null ? catchBlock.end : finallyBlock.end; | 2454 finallyBlock === null ? catchBlock.end : finallyBlock.end; |
| 2413 | 2455 |
| 2414 bool accept(HStatementInformationVisitor visitor) => | 2456 bool accept(HStatementInformationVisitor visitor) => |
| 2415 visitor.visitTryInfo(this); | 2457 visitor.visitTryInfo(this); |
| 2416 } | 2458 } |
| OLD | NEW |