Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: pkg/compiler/lib/src/ssa/loop_handler.dart

Issue 2581143003: implement LabeledStatement and Break in kernel (Closed)
Patch Set: fix some tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../elements/elements.dart'; 7 import '../elements/elements.dart';
8 import '../io/source_information.dart'; 8 import '../io/source_information.dart';
9 import '../tree/tree.dart' as ast; 9 import '../tree/tree.dart' as ast;
10 10
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 99
100 if (bodyBlock != null) { 100 if (bodyBlock != null) {
101 continueHandlers.add(builder.localsHandler); 101 continueHandlers.add(builder.localsHandler);
102 bodyBlock.addSuccessor(updateBlock); 102 bodyBlock.addSuccessor(updateBlock);
103 } 103 }
104 104
105 builder.open(updateBlock); 105 builder.open(updateBlock);
106 builder.localsHandler = 106 builder.localsHandler =
107 continueHandlers[0].mergeMultiple(continueHandlers, updateBlock); 107 continueHandlers[0].mergeMultiple(continueHandlers, updateBlock);
108 108
109 List<LabelDefinition> labels = jumpHandler.labels(); 109 List<LabelDefinition> labels = jumpHandler.labels;
110 JumpTarget target = getTargetDefinition(loop); 110 JumpTarget target = getTargetDefinition(loop);
111 if (!labels.isEmpty) { 111 if (labels.isNotEmpty) {
112 beginBodyBlock.setBlockFlow( 112 beginBodyBlock.setBlockFlow(
113 new HLabeledBlockInformation( 113 new HLabeledBlockInformation(
114 new HSubGraphBlockInformation(bodyGraph), jumpHandler.labels(), 114 new HSubGraphBlockInformation(bodyGraph), jumpHandler.labels,
115 isContinue: true), 115 isContinue: true),
116 updateBlock); 116 updateBlock);
117 } else if (target != null && target.isContinueTarget) { 117 } else if (target != null && target.isContinueTarget) {
118 beginBodyBlock.setBlockFlow( 118 beginBodyBlock.setBlockFlow(
119 new HLabeledBlockInformation.implicit( 119 new HLabeledBlockInformation.implicit(
120 new HSubGraphBlockInformation(bodyGraph), target, 120 new HSubGraphBlockInformation(bodyGraph), target,
121 isContinue: true), 121 isContinue: true),
122 updateBlock); 122 updateBlock);
123 } 123 }
124 124
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 215
216 /// Creates a new loop-header block. The previous [current] block 216 /// Creates a new loop-header block. The previous [current] block
217 /// is closed with an [HGoto] and replaced by the newly created block. 217 /// is closed with an [HGoto] and replaced by the newly created block.
218 /// Also notifies the locals handler that we're entering a loop. 218 /// Also notifies the locals handler that we're entering a loop.
219 JumpHandler beginLoopHeader(T node) { 219 JumpHandler beginLoopHeader(T node) {
220 assert(!builder.isAborted()); 220 assert(!builder.isAborted());
221 HBasicBlock previousBlock = builder.close(new HGoto()); 221 HBasicBlock previousBlock = builder.close(new HGoto());
222 222
223 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: true); 223 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: true);
224 HBasicBlock loopEntry = builder.graph 224 HBasicBlock loopEntry = builder.graph
225 .addNewLoopHeaderBlock(jumpHandler.target, jumpHandler.labels()); 225 .addNewLoopHeaderBlock(jumpHandler.target, jumpHandler.labels);
226 previousBlock.addSuccessor(loopEntry); 226 previousBlock.addSuccessor(loopEntry);
227 builder.open(loopEntry); 227 builder.open(loopEntry);
228 228
229 builder.localsHandler.beginLoopHeader(loopEntry); 229 builder.localsHandler.beginLoopHeader(loopEntry);
230 return jumpHandler; 230 return jumpHandler;
231 } 231 }
232 232
233 /// Ends the loop. 233 /// Ends the loop.
234 /// 234 ///
235 /// It does this by: 235 /// It does this by:
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; 343 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
344 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; 344 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
345 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 345 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
346 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 346 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
347 int visitSwitchStatement(ast.SwitchStatement node) => 347 int visitSwitchStatement(ast.SwitchStatement node) =>
348 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; 348 HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
349 } 349 }
350 350
351 // TODO(het): Since kernel simplifies loop breaks and continues, we should 351 // TODO(het): Since kernel simplifies loop breaks and continues, we should
352 // rewrite the loop handler from scratch to account for the simplified structure 352 // rewrite the loop handler from scratch to account for the simplified structure
353 class KernelLoopHandler extends LoopHandler<ir.Node> { 353 class KernelLoopHandler extends LoopHandler<ir.TreeNode> {
354 final KernelSsaBuilder builder; 354 final KernelSsaBuilder builder;
355 355
356 KernelAstAdapter get astAdapter => builder.astAdapter; 356 KernelAstAdapter get astAdapter => builder.astAdapter;
357 357
358 KernelLoopHandler(KernelSsaBuilder builder) 358 KernelLoopHandler(KernelSsaBuilder builder)
359 : this.builder = builder, 359 : this.builder = builder,
360 super(builder); 360 super(builder);
361 361
362 @override 362 @override
363 JumpHandler createJumpHandler(ir.Node node, {bool isLoopJump}) { 363 JumpHandler createJumpHandler(ir.TreeNode node, {bool isLoopJump}) {
364 JumpTarget element = getTargetDefinition(node); 364 if (node.parent is! ir.LabeledStatement) {
365 if (element == null || !identical(element.statement, node)) {
366 // No breaks or continues to this node. 365 // No breaks or continues to this node.
367 return new NullJumpHandler(builder.compiler.reporter); 366 return new NullJumpHandler(builder.compiler.reporter);
368 } 367 }
369 if (isLoopJump && node is ast.SwitchStatement) { 368 // We must have already created a JumpHandler for the labeled statement
370 // Create a special jump handler for loops created for switch statements 369 JumpHandler result =
371 // with continue statements. 370 builder.jumpTargets[astAdapter.getJumpTarget(node.parent)];
372 return new SwitchCaseJumpHandler(builder, element, getNode(node)); 371 assert(result != null);
373 } 372 return result;
374 return new JumpHandler(builder, element);
375 } 373 }
376 374
377 @override 375 @override
378 ast.Node getNode(ir.Node node) => astAdapter.getNode(node); 376 ast.Node getNode(ir.TreeNode node) => astAdapter.getNode(node);
379 377
380 @override 378 @override
381 JumpTarget getTargetDefinition(ir.Node node) => 379 JumpTarget getTargetDefinition(ir.TreeNode node) {
382 astAdapter.getTargetDefinition(node); 380 if (node.parent is ir.LabeledStatement) {
381 return astAdapter.getJumpTarget(node.parent);
382 }
383 return null;
384 }
383 385
384 @override 386 @override
385 int loopKind(ir.Node node) => node.accept(new _KernelLoopTypeVisitor()); 387 int loopKind(ir.TreeNode node) => node.accept(new _KernelLoopTypeVisitor());
386 388
387 // TODO(het): return the actual source information 389 // TODO(het): return the actual source information
388 @override 390 @override
389 SourceInformation loopSourceInformation(ir.Node node) => null; 391 SourceInformation loopSourceInformation(ir.TreeNode node) => null;
390 } 392 }
391 393
392 class _KernelLoopTypeVisitor extends ir.Visitor<int> { 394 class _KernelLoopTypeVisitor extends ir.Visitor<int> {
393 @override 395 @override
394 int defaultNode(ir.Node node) => HLoopBlockInformation.NOT_A_LOOP; 396 int defaultNode(ir.Node node) => HLoopBlockInformation.NOT_A_LOOP;
395 397
396 @override 398 @override
397 int visitWhileStatement(ir.WhileStatement node) => 399 int visitWhileStatement(ir.WhileStatement node) =>
398 HLoopBlockInformation.WHILE_LOOP; 400 HLoopBlockInformation.WHILE_LOOP;
399 401
400 @override 402 @override
401 int visitForStatement(ir.ForStatement node) => HLoopBlockInformation.FOR_LOOP; 403 int visitForStatement(ir.ForStatement node) => HLoopBlockInformation.FOR_LOOP;
402 404
403 @override 405 @override
404 int visitDoStatement(ir.DoStatement node) => 406 int visitDoStatement(ir.DoStatement node) =>
405 HLoopBlockInformation.DO_WHILE_LOOP; 407 HLoopBlockInformation.DO_WHILE_LOOP;
406 408
407 @override 409 @override
408 int visitForInStatement(ir.ForInStatement node) => 410 int visitForInStatement(ir.ForInStatement node) =>
409 HLoopBlockInformation.FOR_IN_LOOP; 411 HLoopBlockInformation.FOR_IN_LOOP;
410 412
411 @override 413 @override
412 int visitSwitchStatement(ir.SwitchStatement node) => 414 int visitSwitchStatement(ir.SwitchStatement node) =>
413 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; 415 HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
414 } 416 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698