OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import '../compiler.dart'; | 5 import '../compiler.dart'; |
6 import '../io/source_information.dart'; | 6 import '../io/source_information.dart'; |
7 import '../js_backend/js_backend.dart'; | 7 import '../js_backend/js_backend.dart'; |
8 import '../tree/tree.dart' as ast; | 8 import '../tree/tree.dart' as ast; |
9 | 9 |
10 import 'graph_builder.dart'; | 10 import 'graph_builder.dart'; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 checkNotAborted(); | 45 checkNotAborted(); |
46 assert(identical(builder.current, builder.lastOpenedBlock)); | 46 assert(identical(builder.current, builder.lastOpenedBlock)); |
47 HInstruction conditionValue = builder.popBoolified(); | 47 HInstruction conditionValue = builder.popBoolified(); |
48 HIf branch = new HIf(conditionValue)..sourceInformation = sourceInformation; | 48 HIf branch = new HIf(conditionValue)..sourceInformation = sourceInformation; |
49 HBasicBlock conditionExitBlock = builder.current; | 49 HBasicBlock conditionExitBlock = builder.current; |
50 builder.close(branch); | 50 builder.close(branch); |
51 conditionBranch.exitLocals = builder.localsHandler; | 51 conditionBranch.exitLocals = builder.localsHandler; |
52 conditionExitBlock.addSuccessor(thenBranch.block); | 52 conditionExitBlock.addSuccessor(thenBranch.block); |
53 conditionExitBlock.addSuccessor(elseBranch.block); | 53 conditionExitBlock.addSuccessor(elseBranch.block); |
54 bool conditionBranchLocalsCanBeReused = | 54 bool conditionBranchLocalsCanBeReused = |
55 mergeLocals(conditionBranch, thenBranch, mayReuseFromLocals: true); | 55 mergeLocals(conditionBranch, thenBranch, mayReuseFromLocals: true); |
56 mergeLocals(conditionBranch, elseBranch, | 56 mergeLocals(conditionBranch, elseBranch, |
57 mayReuseFromLocals: conditionBranchLocalsCanBeReused); | 57 mayReuseFromLocals: conditionBranchLocalsCanBeReused); |
58 | 58 |
59 conditionBranch.graph = | 59 conditionBranch.graph = |
60 new SubExpression(conditionBranch.block, conditionExitBlock); | 60 new SubExpression(conditionBranch.block, conditionExitBlock); |
61 } | 61 } |
62 | 62 |
63 /** | 63 /** |
64 * Returns true if the locals of the [fromBranch] may be reused. A [:true:] | 64 * Returns true if the locals of the [fromBranch] may be reused. A [:true:] |
65 * return value implies that [mayReuseFromLocals] was set to [:true:]. | 65 * return value implies that [mayReuseFromLocals] was set to [:true:]. |
66 */ | 66 */ |
67 bool mergeLocals(SsaBranch fromBranch, SsaBranch toBranch, | 67 bool mergeLocals(SsaBranch fromBranch, SsaBranch toBranch, |
68 {bool mayReuseFromLocals}) { | 68 {bool mayReuseFromLocals}) { |
69 LocalsHandler fromLocals = fromBranch.exitLocals; | 69 LocalsHandler fromLocals = fromBranch.exitLocals; |
70 if (toBranch.startLocals == null) { | 70 if (toBranch.startLocals == null) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 SsaBranch thenBranch = new SsaBranch(this); | 187 SsaBranch thenBranch = new SsaBranch(this); |
188 SsaBranch elseBranch = new SsaBranch(this); | 188 SsaBranch elseBranch = new SsaBranch(this); |
189 SsaBranch joinBranch = new SsaBranch(this); | 189 SsaBranch joinBranch = new SsaBranch(this); |
190 | 190 |
191 conditionBranch.startLocals = builder.localsHandler; | 191 conditionBranch.startLocals = builder.localsHandler; |
192 builder.goto(builder.current, conditionBranch.block); | 192 builder.goto(builder.current, conditionBranch.block); |
193 | 193 |
194 buildCondition(visitCondition, conditionBranch, thenBranch, elseBranch, | 194 buildCondition(visitCondition, conditionBranch, thenBranch, elseBranch, |
195 sourceInformation); | 195 sourceInformation); |
196 HInstruction thenValue = | 196 HInstruction thenValue = |
197 buildBranch(thenBranch, visitThen, joinBranch, isExpression); | 197 buildBranch(thenBranch, visitThen, joinBranch, isExpression); |
198 HInstruction elseValue = | 198 HInstruction elseValue = |
199 buildBranch(elseBranch, visitElse, joinBranch, isExpression); | 199 buildBranch(elseBranch, visitElse, joinBranch, isExpression); |
200 | 200 |
201 if (isExpression) { | 201 if (isExpression) { |
202 assert(thenValue != null && elseValue != null); | 202 assert(thenValue != null && elseValue != null); |
203 JavaScriptBackend backend = compiler.backend; | 203 JavaScriptBackend backend = compiler.backend; |
204 HPhi phi = new HPhi.manyInputs( | 204 HPhi phi = new HPhi.manyInputs( |
205 null, <HInstruction>[thenValue, elseValue], backend.dynamicType); | 205 null, <HInstruction>[thenValue, elseValue], backend.dynamicType); |
206 joinBranch.block.addPhi(phi); | 206 joinBranch.block.addPhi(phi); |
207 builder.stack.add(phi); | 207 builder.stack.add(phi); |
208 } | 208 } |
209 | 209 |
210 HBasicBlock joinBlock; | 210 HBasicBlock joinBlock; |
211 // If at least one branch did not abort, open the joinBranch. | 211 // If at least one branch did not abort, open the joinBranch. |
212 if (!joinBranch.block.predecessors.isEmpty) { | 212 if (!joinBranch.block.predecessors.isEmpty) { |
213 startBranch(joinBranch); | 213 startBranch(joinBranch); |
214 joinBlock = joinBranch.block; | 214 joinBlock = joinBranch.block; |
215 } | 215 } |
216 | 216 |
217 HIfBlockInformation info = new HIfBlockInformation( | 217 HIfBlockInformation info = new HIfBlockInformation( |
218 new HSubExpressionBlockInformation(conditionBranch.graph), | 218 new HSubExpressionBlockInformation(conditionBranch.graph), |
219 new HSubGraphBlockInformation(thenBranch.graph), | 219 new HSubGraphBlockInformation(thenBranch.graph), |
220 new HSubGraphBlockInformation(elseBranch.graph)); | 220 new HSubGraphBlockInformation(elseBranch.graph)); |
221 | 221 |
222 HBasicBlock conditionStartBlock = conditionBranch.block; | 222 HBasicBlock conditionStartBlock = conditionBranch.block; |
223 conditionStartBlock.setBlockFlow(info, joinBlock); | 223 conditionStartBlock.setBlockFlow(info, joinBlock); |
224 SubGraph conditionGraph = conditionBranch.graph; | 224 SubGraph conditionGraph = conditionBranch.graph; |
225 HIf branch = conditionGraph.end.last; | 225 HIf branch = conditionGraph.end.last; |
226 assert(branch is HIf); | 226 assert(branch is HIf); |
227 branch.blockInformation = conditionStartBlock.blockFlow; | 227 branch.blockInformation = conditionStartBlock.blockFlow; |
228 } | 228 } |
229 } | 229 } |
OLD | NEW |