Chromium Code Reviews| 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 blockInformation = null; | |
|
karlklose
2012/05/08 08:02:46
Consider renaming this to blockFlow.
Lasse Reichstein Nielsen
2012/05/08 11:40:34
Done.
| |
| 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 setBlockInfo(HBlockInformation blockInfo, HBasicBlock continuation) { | |
|
karlklose
2012/05/08 08:02:46
I would prefer calling this method setBlockInforma
Lasse Reichstein Nielsen
2012/05/08 11:40:34
Changed to setBlockFlow.
| |
| 455 blockInformation = new HBlockFlow(blockInfo, continuation); | |
| 456 } | |
| 457 | |
| 458 bool isLabeledBlock() => | |
| 459 blockInformation !== null && | |
| 460 blockInformation.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 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1648 HParameterValue exception; | 1650 HParameterValue exception; |
| 1649 HBasicBlock finallyBlock; | 1651 HBasicBlock finallyBlock; |
| 1650 HTry() : super(const <HInstruction>[]); | 1652 HTry() : super(const <HInstruction>[]); |
| 1651 toString() => 'try'; | 1653 toString() => 'try'; |
| 1652 accept(HVisitor visitor) => visitor.visitTry(this); | 1654 accept(HVisitor visitor) => visitor.visitTry(this); |
| 1653 HBasicBlock get joinBlock() => this.block.successors.last(); | 1655 HBasicBlock get joinBlock() => this.block.successors.last(); |
| 1654 } | 1656 } |
| 1655 | 1657 |
| 1656 class HIf extends HConditionalBranch { | 1658 class HIf extends HConditionalBranch { |
| 1657 bool hasElse; | 1659 bool hasElse; |
| 1658 HIfBlockInformation blockInformation = null; | 1660 HBlockFlow blockInformation = null; |
| 1659 HIf(HInstruction condition, this.hasElse) : super(<HInstruction>[condition]); | 1661 HIf(HInstruction condition, this.hasElse) : super(<HInstruction>[condition]); |
| 1660 toString() => 'if'; | 1662 toString() => 'if'; |
| 1661 accept(HVisitor visitor) => visitor.visitIf(this); | 1663 accept(HVisitor visitor) => visitor.visitIf(this); |
| 1662 | 1664 |
| 1663 HBasicBlock get thenBlock() { | 1665 HBasicBlock get thenBlock() { |
| 1664 assert(block.dominatedBlocks[0] === block.successors[0]); | 1666 assert(block.dominatedBlocks[0] === block.successors[0]); |
| 1665 return block.successors[0]; | 1667 return block.successors[0]; |
| 1666 } | 1668 } |
| 1667 | 1669 |
| 1668 HBasicBlock get elseBlock() { | 1670 HBasicBlock get elseBlock() { |
| 1669 if (hasElse) { | 1671 if (hasElse) { |
| 1670 assert(block.dominatedBlocks[1] === block.successors[1]); | 1672 assert(block.dominatedBlocks[1] === block.successors[1]); |
| 1671 return block.successors[1]; | 1673 return block.successors[1]; |
| 1672 } else { | 1674 } else { |
| 1673 return null; | 1675 return null; |
| 1674 } | 1676 } |
| 1675 } | 1677 } |
| 1676 | 1678 |
| 1677 HBasicBlock get joinBlock() => blockInformation.joinBlock; | 1679 HBasicBlock get joinBlock() => blockInformation.continuation; |
| 1678 } | 1680 } |
| 1679 | 1681 |
| 1680 class HLoopBranch extends HConditionalBranch { | 1682 class HLoopBranch extends HConditionalBranch { |
| 1681 static final int CONDITION_FIRST_LOOP = 0; | 1683 static final int CONDITION_FIRST_LOOP = 0; |
| 1682 static final int DO_WHILE_LOOP = 1; | 1684 static final int DO_WHILE_LOOP = 1; |
| 1683 | 1685 |
| 1684 final int kind; | 1686 final int kind; |
| 1685 HLoopBranch(HInstruction condition, [this.kind = CONDITION_FIRST_LOOP]) | 1687 HLoopBranch(HInstruction condition, [this.kind = CONDITION_FIRST_LOOP]) |
| 1686 : super(<HInstruction>[condition]); | 1688 : super(<HInstruction>[condition]); |
| 1687 toString() => 'loop-branch'; | 1689 toString() => 'loop-branch'; |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2156 assert(!hasSideEffects()); | 2158 assert(!hasSideEffects()); |
| 2157 setUseGvn(); | 2159 setUseGvn(); |
| 2158 } | 2160 } |
| 2159 | 2161 |
| 2160 accept(HVisitor visitor) => visitor.visitTypeConversion(this); | 2162 accept(HVisitor visitor) => visitor.visitTypeConversion(this); |
| 2161 int typeCode() => 27; | 2163 int typeCode() => 27; |
| 2162 bool typeEquals(other) => other is HTypeConversion; | 2164 bool typeEquals(other) => other is HTypeConversion; |
| 2163 bool dataEquals(HTypeConversion other) => type == other.type; | 2165 bool dataEquals(HTypeConversion other) => type == other.type; |
| 2164 } | 2166 } |
| 2165 | 2167 |
| 2168 // Non-block-based loop information. | |
|
karlklose
2012/05/08 08:02:46
Doc-style (/** ... *)?
Lasse Reichstein Nielsen
2012/05/08 11:40:34
Done.
| |
| 2169 class HLoopInformation { | |
| 2170 final HBasicBlock header; | |
| 2171 final List<HBasicBlock> blocks; | |
| 2172 final List<HBasicBlock> backEdges; | |
| 2173 final List<LabelElement> labels; | |
| 2174 final TargetElement target; | |
| 2175 /** The corresponding block information */ | |
|
karlklose
2012/05/08 08:02:46
Is this intended to be in doc-style?
Lasse Reichstein Nielsen
2012/05/08 11:40:34
Yes. Missing a final '.' I can see.
| |
| 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 | |
|
karlklose
2012/05/08 08:02:46
Remove line.
Lasse Reichstein Nielsen
2012/05/08 11:40:34
Done.
| |
| 2218 } | |
| 2219 | |
| 2220 | |
| 2166 /** | 2221 /** |
| 2167 * Information about a syntactic-like structure that can be attached | 2222 * Embedding of a [HBlockInformation] for block-structure based traversal |
| 2168 * to a [HBasicBlock]. | 2223 * in a dominator based flow traversal by attaching it to a basic block. |
| 2224 * To go back to dominator-based traversal, a [HSubGraphBlockInformation] | |
| 2225 * structure can be added in the block structure. | |
| 2226 */ | |
| 2227 class HBlockFlow { | |
| 2228 final HBlockInformation body; | |
| 2229 final HBasicBlock continuation; | |
| 2230 HBlockFlow(this.body, this.continuation); | |
| 2231 } | |
| 2232 | |
| 2233 | |
| 2234 /** | |
| 2235 * Information about a syntactic-like structure. | |
| 2169 */ | 2236 */ |
| 2170 interface HBlockInformation { | 2237 interface HBlockInformation { |
| 2171 HBasicBlock get start(); | 2238 HBasicBlock get start(); |
| 2172 HBasicBlock get end(); | 2239 HBasicBlock get end(); |
| 2173 bool accept(HBlockInformationVisitor visitor); | 2240 bool accept(HBlockInformationVisitor visitor); |
| 2174 } | 2241 } |
| 2175 | 2242 |
| 2243 | |
| 2176 /** | 2244 /** |
| 2177 * Information about a statement-like structure. | 2245 * Information about a statement-like structure. |
| 2178 */ | 2246 */ |
| 2179 interface HStatementInformation extends HBlockInformation { | 2247 interface HStatementInformation extends HBlockInformation { |
| 2180 bool accept(HStatementInformationVisitor visitor); | 2248 bool accept(HStatementInformationVisitor visitor); |
| 2181 } | 2249 } |
| 2182 | 2250 |
| 2251 | |
| 2183 /** | 2252 /** |
| 2184 * Information about an expression-like structure. | 2253 * Information about an expression-like structure. |
| 2185 */ | 2254 */ |
| 2186 interface HExpressionInformation extends HBlockInformation { | 2255 interface HExpressionInformation extends HBlockInformation { |
| 2187 bool accept(HExpressionInformationVisitor visitor); | 2256 bool accept(HExpressionInformationVisitor visitor); |
| 2188 HInstruction get conditionExpression(); | 2257 HInstruction get conditionExpression(); |
| 2189 } | 2258 } |
| 2190 | 2259 |
| 2191 | 2260 |
| 2192 interface HStatementInformationVisitor { | 2261 interface HStatementInformationVisitor { |
| 2193 bool visitLabeledBlockInfo(HLabeledBlockInformation info); | 2262 bool visitLabeledBlockInfo(HLabeledBlockInformation info); |
| 2194 bool visitLoopInfo(HLoopInformation info); | 2263 bool visitLoopInfo(HLoopBlockInformation info); |
| 2195 bool visitIfInfo(HIfBlockInformation info); | 2264 bool visitIfInfo(HIfBlockInformation info); |
| 2196 bool visitTryInfo(HTryBlockInformation info); | 2265 bool visitTryInfo(HTryBlockInformation info); |
| 2266 bool visitSequenceInfo(HStatementSequenceInformation info); | |
| 2267 // Pseudo-structure embedding a dominator-based traversal into | |
| 2268 // the block-structure traversal. This will eventually go away. | |
| 2197 bool visitSubGraphInfo(HSubGraphBlockInformation info); | 2269 bool visitSubGraphInfo(HSubGraphBlockInformation info); |
| 2198 } | 2270 } |
| 2199 | 2271 |
| 2272 | |
| 2200 interface HExpressionInformationVisitor { | 2273 interface HExpressionInformationVisitor { |
| 2201 bool visitAndOrInfo(HAndOrBlockInformation info); | 2274 bool visitAndOrInfo(HAndOrBlockInformation info); |
| 2202 bool visitSubExpressionInfo(HSubExpressionBlockInformation info); | 2275 bool visitSubExpressionInfo(HSubExpressionBlockInformation info); |
| 2203 } | 2276 } |
| 2204 | 2277 |
| 2278 | |
| 2205 interface HBlockInformationVisitor extends HStatementInformationVisitor, | 2279 interface HBlockInformationVisitor extends HStatementInformationVisitor, |
| 2206 HExpressionInformationVisitor { | 2280 HExpressionInformationVisitor { |
| 2207 } | 2281 } |
| 2208 | 2282 |
| 2283 | |
| 2209 /** | 2284 /** |
| 2210 * Generic class wrapping a [SubGraph] as a block-information until | 2285 * Generic class wrapping a [SubGraph] as a block-information until |
| 2211 * all structures are handled properly. | 2286 * all structures are handled properly. |
| 2212 */ | 2287 */ |
| 2213 class HSubGraphBlockInformation implements HStatementInformation { | 2288 class HSubGraphBlockInformation implements HStatementInformation { |
| 2214 final SubGraph subGraph; | 2289 final SubGraph subGraph; |
| 2215 HSubGraphBlockInformation(this.subGraph); | 2290 HSubGraphBlockInformation(this.subGraph); |
| 2216 | 2291 |
| 2217 HBasicBlock get start() => subGraph.start; | 2292 HBasicBlock get start() => subGraph.start; |
| 2218 HBasicBlock get end() => subGraph.end; | 2293 HBasicBlock get end() => subGraph.end; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 2233 HBasicBlock get start() => subExpression.start; | 2308 HBasicBlock get start() => subExpression.start; |
| 2234 HBasicBlock get end() => subExpression.end; | 2309 HBasicBlock get end() => subExpression.end; |
| 2235 | 2310 |
| 2236 HInstruction get conditionExpression() => subExpression.conditionExpression; | 2311 HInstruction get conditionExpression() => subExpression.conditionExpression; |
| 2237 | 2312 |
| 2238 bool accept(HExpressionInformationVisitor visitor) => | 2313 bool accept(HExpressionInformationVisitor visitor) => |
| 2239 visitor.visitSubExpressionInfo(this); | 2314 visitor.visitSubExpressionInfo(this); |
| 2240 } | 2315 } |
| 2241 | 2316 |
| 2242 | 2317 |
| 2318 /** A sequence of separate statements. */ | |
| 2319 class HStatementSequenceInformation implements HStatementInformation { | |
| 2320 final List<HStatementInformation> statements; | |
| 2321 HStatementSequenceInformation(this.statements); | |
| 2322 | |
| 2323 HBasicBlock get start() => statements[0].start; | |
| 2324 HBasicBlock get end() => statements.last().end; | |
| 2325 | |
| 2326 bool accept(HStatementInformationVisitor visitor) => | |
| 2327 visitor.visitSequenceInfo(this); | |
| 2328 } | |
| 2329 | |
| 2330 | |
| 2243 class HLabeledBlockInformation implements HStatementInformation { | 2331 class HLabeledBlockInformation implements HStatementInformation { |
| 2244 final HStatementInformation body; | 2332 final HStatementInformation body; |
| 2245 final HBasicBlock joinBlock; | |
| 2246 final List<LabelElement> labels; | 2333 final List<LabelElement> labels; |
| 2247 final TargetElement target; | 2334 final TargetElement target; |
| 2248 final bool isContinue; | 2335 final bool isContinue; |
| 2249 | 2336 |
| 2250 HLabeledBlockInformation(this.body, this.joinBlock, | 2337 HLabeledBlockInformation(this.body, |
| 2251 List<LabelElement> labels, | 2338 List<LabelElement> labels, |
| 2252 [this.isContinue = false]) : | 2339 [this.isContinue = false]) : |
| 2253 this.labels = labels, this.target = labels[0].target; | 2340 this.labels = labels, this.target = labels[0].target; |
| 2254 | 2341 |
| 2255 HLabeledBlockInformation.implicit(this.body, | 2342 HLabeledBlockInformation.implicit(this.body, |
| 2256 this.joinBlock, | |
| 2257 this.target, | 2343 this.target, |
| 2258 [this.isContinue = false]) | 2344 [this.isContinue = false]) |
| 2259 : this.labels = const<LabelElement>[]; | 2345 : this.labels = const<LabelElement>[]; |
| 2260 | 2346 |
| 2261 HBasicBlock get start() => body.start; | 2347 HBasicBlock get start() => body.start; |
| 2262 HBasicBlock get end() => body.end; | 2348 HBasicBlock get end() => body.end; |
| 2263 | 2349 |
| 2264 bool accept(HStatementInformationVisitor visitor) => | 2350 bool accept(HStatementInformationVisitor visitor) => |
| 2265 visitor.visitLabeledBlockInfo(this); | 2351 visitor.visitLabeledBlockInfo(this); |
| 2266 } | 2352 } |
| 2267 | 2353 |
| 2268 class LoopTypeVisitor extends AbstractVisitor { | 2354 class LoopTypeVisitor extends AbstractVisitor { |
| 2269 const LoopTypeVisitor(); | 2355 const LoopTypeVisitor(); |
| 2270 int visitNode(Node node) { | 2356 int visitNode(Node node) { |
| 2271 unreachable(); | 2357 unreachable(); |
| 2272 } | 2358 } |
| 2273 int visitWhile(While node) => HLoopInformation.WHILE_LOOP; | 2359 int visitWhile(While node) => HLoopBlockInformation.WHILE_LOOP; |
| 2274 int visitFor(For node) => HLoopInformation.FOR_LOOP; | 2360 int visitFor(For node) => HLoopBlockInformation.FOR_LOOP; |
| 2275 int visitDoWhile(DoWhile node) => HLoopInformation.DO_WHILE_LOOP; | 2361 int visitDoWhile(DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
| 2276 int visitForIn(ForIn node) => HLoopInformation.FOR_IN_LOOP; | 2362 int visitForIn(ForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 2277 } | 2363 } |
| 2278 | 2364 |
| 2279 class HLoopInformation implements HStatementInformation { | 2365 class HLoopBlockInformation implements HStatementInformation { |
| 2280 static final int WHILE_LOOP = 0; | 2366 static final int WHILE_LOOP = 0; |
| 2281 static final int FOR_LOOP = 1; | 2367 static final int FOR_LOOP = 1; |
| 2282 static final int DO_WHILE_LOOP = 2; | 2368 static final int DO_WHILE_LOOP = 2; |
| 2283 static final int FOR_IN_LOOP = 3; | 2369 static final int FOR_IN_LOOP = 3; |
| 2284 | 2370 |
| 2285 final int kind; | 2371 final int kind; |
| 2286 final HBasicBlock header; | 2372 final HExpressionInformation initializer; |
| 2287 final List<HBasicBlock> blocks; | 2373 final HExpressionInformation condition; |
| 2288 final List<HBasicBlock> backEdges; | 2374 final HStatementInformation body; |
| 2375 final HExpressionInformation updates; | |
| 2376 final TargetElement target; | |
| 2289 final List<LabelElement> labels; | 2377 final List<LabelElement> labels; |
| 2290 final TargetElement target; | |
| 2291 HExpressionInformation initializer = null; | |
| 2292 HExpressionInformation condition = null; | |
| 2293 HStatementInformation body = null; | |
| 2294 HExpressionInformation updates = null; | |
| 2295 HBasicBlock joinBlock; | |
| 2296 | 2378 |
| 2297 HLoopInformation(this.kind, this.header, this.target, this.labels) | 2379 HLoopBlockInformation( |
| 2298 : blocks = new List<HBasicBlock>(), | 2380 this.kind, |
|
karlklose
2012/05/08 08:02:46
Start parameters on the same line as constructor?
Lasse Reichstein Nielsen
2012/05/08 11:40:34
Done.
| |
| 2299 backEdges = new List<HBasicBlock>(); | 2381 this.initializer, this.condition, this.body, this.updates, |
| 2382 this.target, this.labels); | |
| 2300 | 2383 |
| 2301 HBasicBlock get start() { | 2384 HBasicBlock get start() { |
| 2302 if (initializer !== null) return initializer.start; | 2385 if (initializer !== null) return initializer.start; |
| 2303 if (kind == DO_WHILE_LOOP) { | 2386 if (kind == DO_WHILE_LOOP) { |
| 2304 return body.start; | 2387 return body.start; |
| 2305 } | 2388 } |
| 2306 return condition.start; | 2389 return condition.start; |
| 2307 } | 2390 } |
| 2308 | 2391 |
| 2309 HBasicBlock get end() { | 2392 HBasicBlock get end() { |
| 2310 if (updates !== null) return updates.end; | 2393 if (updates !== null) return updates.end; |
| 2311 if (kind == DO_WHILE_LOOP) { | 2394 if (kind == DO_WHILE_LOOP) { |
| 2312 return condition.end; | 2395 return condition.end; |
| 2313 } | 2396 } |
| 2314 return body.end; | 2397 return body.end; |
| 2315 } | 2398 } |
| 2316 | 2399 |
| 2317 static int loopType(Node node) { | 2400 static int loopType(Node node) { |
| 2318 return node.accept(const LoopTypeVisitor()); | 2401 return node.accept(const LoopTypeVisitor()); |
| 2319 } | 2402 } |
| 2320 | 2403 |
| 2321 void addBackEdge(HBasicBlock predecessor) { | |
| 2322 backEdges.add(predecessor); | |
| 2323 addBlock(predecessor); | |
| 2324 } | |
| 2325 | |
| 2326 // Adds a block and transitively all its predecessors in the loop as | |
| 2327 // loop blocks. | |
| 2328 void addBlock(HBasicBlock block) { | |
| 2329 if (block === header) return; | |
| 2330 HBasicBlock parentHeader = block.parentLoopHeader; | |
| 2331 if (parentHeader === header) { | |
| 2332 // Nothing to do in this case. | |
| 2333 } else if (parentHeader !== null) { | |
| 2334 addBlock(parentHeader); | |
| 2335 } else { | |
| 2336 block.parentLoopHeader = header; | |
| 2337 blocks.add(block); | |
| 2338 for (int i = 0, length = block.predecessors.length; i < length; i++) { | |
| 2339 addBlock(block.predecessors[i]); | |
| 2340 } | |
| 2341 } | |
| 2342 } | |
| 2343 | |
| 2344 HBasicBlock getLastBackEdge() { | |
| 2345 int maxId = -1; | |
| 2346 HBasicBlock result = null; | |
| 2347 for (int i = 0, length = backEdges.length; i < length; i++) { | |
| 2348 HBasicBlock current = backEdges[i]; | |
| 2349 if (current.id > maxId) { | |
| 2350 maxId = current.id; | |
| 2351 result = current; | |
| 2352 } | |
| 2353 } | |
| 2354 return result; | |
| 2355 } | |
| 2356 | |
| 2357 bool accept(HStatementInformationVisitor visitor) => | 2404 bool accept(HStatementInformationVisitor visitor) => |
| 2358 visitor.visitLoopInfo(this); | 2405 visitor.visitLoopInfo(this); |
| 2359 } | 2406 } |
| 2360 | 2407 |
| 2361 class HIfBlockInformation implements HStatementInformation { | 2408 class HIfBlockInformation implements HStatementInformation { |
| 2362 final HExpressionInformation condition; | 2409 final HExpressionInformation condition; |
| 2363 final HStatementInformation thenGraph; | 2410 final HStatementInformation thenGraph; |
| 2364 final HStatementInformation elseGraph; | 2411 final HStatementInformation elseGraph; |
| 2365 final HBasicBlock joinBlock; | |
| 2366 HIfBlockInformation(this.condition, | 2412 HIfBlockInformation(this.condition, |
| 2367 this.thenGraph, | 2413 this.thenGraph, |
| 2368 this.elseGraph, | 2414 this.elseGraph); |
| 2369 this.joinBlock); | |
| 2370 | 2415 |
| 2371 HBasicBlock get start() => condition.start; | 2416 HBasicBlock get start() => condition.start; |
| 2372 HBasicBlock get end() => elseGraph === null ? thenGraph.end : elseGraph.end; | 2417 HBasicBlock get end() => elseGraph === null ? thenGraph.end : elseGraph.end; |
| 2373 | 2418 |
| 2374 bool accept(HStatementInformationVisitor visitor) => | 2419 bool accept(HStatementInformationVisitor visitor) => |
| 2375 visitor.visitIfInfo(this); | 2420 visitor.visitIfInfo(this); |
| 2376 } | 2421 } |
| 2377 | 2422 |
| 2378 class HAndOrBlockInformation implements HExpressionInformation { | 2423 class HAndOrBlockInformation implements HExpressionInformation { |
| 2379 final bool isAnd; | 2424 final bool isAnd; |
| 2380 final HExpressionInformation left; | 2425 final HExpressionInformation left; |
| 2381 final HExpressionInformation right; | 2426 final HExpressionInformation right; |
| 2382 final HBasicBlock joinBlock; | |
| 2383 HAndOrBlockInformation(this.isAnd, | 2427 HAndOrBlockInformation(this.isAnd, |
| 2384 this.left, | 2428 this.left, |
| 2385 this.right, | 2429 this.right); |
| 2386 this.joinBlock); | |
| 2387 | 2430 |
| 2388 HBasicBlock get start() => left.start; | 2431 HBasicBlock get start() => left.start; |
| 2389 HBasicBlock get end() => right.end; | 2432 HBasicBlock get end() => right.end; |
| 2390 | 2433 |
| 2391 // We don't currently use HAndOrBlockInformation. | 2434 // We don't currently use HAndOrBlockInformation. |
| 2392 HInstruction get conditionExpression() { unreachable(); } | 2435 HInstruction get conditionExpression() { unreachable(); } |
| 2393 bool accept(HExpressionInformationVisitor visitor) => | 2436 bool accept(HExpressionInformationVisitor visitor) => |
| 2394 visitor.visitAndOrInfo(this); | 2437 visitor.visitAndOrInfo(this); |
| 2395 } | 2438 } |
| 2396 | 2439 |
| 2397 class HTryBlockInformation implements HStatementInformation { | 2440 class HTryBlockInformation implements HStatementInformation { |
| 2398 final HStatementInformation body; | 2441 final HStatementInformation body; |
| 2399 final HParameterValue catchVariable; | 2442 final HParameterValue catchVariable; |
| 2400 final HStatementInformation catchBlock; | 2443 final HStatementInformation catchBlock; |
| 2401 final HStatementInformation finallyBlock; | 2444 final HStatementInformation finallyBlock; |
| 2402 // TODO: Move joinBlock out of the structure, and into the surrounding | |
| 2403 // structure. | |
| 2404 final HBasicBlock joinBlock; | |
| 2405 HTryBlockInformation(this.body, | 2445 HTryBlockInformation(this.body, |
| 2406 this.catchVariable, | 2446 this.catchVariable, |
| 2407 this.catchBlock, | 2447 this.catchBlock, |
| 2408 this.finallyBlock, | 2448 this.finallyBlock); |
| 2409 this.joinBlock); | |
| 2410 | 2449 |
| 2411 HBasicBlock get start() => body.start; | 2450 HBasicBlock get start() => body.start; |
| 2412 HBasicBlock get end() => | 2451 HBasicBlock get end() => |
| 2413 finallyBlock === null ? catchBlock.end : finallyBlock.end; | 2452 finallyBlock === null ? catchBlock.end : finallyBlock.end; |
| 2414 | 2453 |
| 2415 bool accept(HStatementInformationVisitor visitor) => | 2454 bool accept(HStatementInformationVisitor visitor) => |
| 2416 visitor.visitTryInfo(this); | 2455 visitor.visitTryInfo(this); |
| 2417 } | 2456 } |
| OLD | NEW |