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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 57873002: Build new IR for functions returning a constant (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: include feedback, don't build ir for intercepted methods Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
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 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 878
879 void close() { 879 void close() {
880 // The mapping from TargetElement to JumpHandler is no longer needed. 880 // The mapping from TargetElement to JumpHandler is no longer needed.
881 for (TargetElement target in targetIndexMap.keys) { 881 for (TargetElement target in targetIndexMap.keys) {
882 builder.jumpTargets.remove(target); 882 builder.jumpTargets.remove(target);
883 } 883 }
884 super.close(); 884 super.close();
885 } 885 }
886 } 886 }
887 887
888 class SsaBuilder extends ResolvedVisitor implements Visitor { 888 /**
889 final SsaBuilderTask builder; 889 * This mixin implements functionality that is shared between the [SsaBuilder]
890 final JavaScriptBackend backend; 890 * and the [SsaFromIrBuilder] classes.
891 final CodegenWorkItem work; 891 */
892 final ConstantSystem constantSystem; 892 class SsaGraphBuilderMixin {
893 HGraph graph; 893 final HGraph graph = new HGraph();
894 LocalsHandler localsHandler;
895 HInstruction rethrowableException;
896 Map<Element, HInstruction> parameters;
897 final RuntimeTypes rti;
898 HParameterValue lastAddedParameter;
899
900 Map<TargetElement, JumpHandler> jumpTargets;
901
902 /**
903 * Variables stored in the current activation. These variables are
904 * being updated in try/catch blocks, and should be
905 * accessed indirectly through [HLocalGet] and [HLocalSet].
906 */
907 Map<Element, HLocalValue> activationVariables;
908
909 // We build the Ssa graph by simulating a stack machine.
910 List<HInstruction> stack;
911 894
912 /** 895 /**
913 * The current block to add instructions to. Might be null, if we are 896 * The current block to add instructions to. Might be null, if we are
914 * visiting dead code, but see [isReachable]. 897 * visiting dead code, but see [isReachable].
915 */ 898 */
916 HBasicBlock _current; 899 HBasicBlock _current;
917 900
918 /** 901 /**
919 * The most recently opened block. Has the same value as [_current] while 902 * The most recently opened block. Has the same value as [_current] while
920 * the block is open, but unlike [_current], it isn't cleared when the 903 * the block is open, but unlike [_current], it isn't cleared when the
921 * current block is closed. 904 * current block is closed.
922 */ 905 */
923 HBasicBlock lastOpenedBlock; 906 HBasicBlock lastOpenedBlock;
924 907
925 /** 908 /**
926 * Indicates whether the current block is dead (because it has a throw or a 909 * Indicates whether the current block is dead (because it has a throw or a
927 * return further up). If this is false, then [_current] may be null. If the 910 * return further up). If this is false, then [_current] may be null. If the
928 * block is dead then it may also be aborted, but for simplicity we only 911 * block is dead then it may also be aborted, but for simplicity we only
929 * abort on statement boundaries, not in the middle of expressions. See 912 * abort on statement boundaries, not in the middle of expressions. See
930 * isAborted. 913 * isAborted.
931 */ 914 */
932 bool isReachable = true; 915 bool isReachable = true;
933 916
917 HBasicBlock get current => _current;
918 void set current(c) {
919 isReachable = c != null;
920 _current = c;
921 }
922
923 HBasicBlock addNewBlock() {
924 HBasicBlock block = graph.addNewBlock();
925 // If adding a new block during building of an expression, it is due to
926 // conditional expressions or short-circuit logical operators.
927 return block;
928 }
929
930 void open(HBasicBlock block) {
931 block.open();
932 current = block;
933 lastOpenedBlock = block;
934 }
935
936 HBasicBlock close(HControlFlow end) {
937 HBasicBlock result = current;
938 current.close(end);
939 current = null;
940 return result;
941 }
942
943 HBasicBlock closeAndGotoExit(HControlFlow end) {
944 HBasicBlock result = current;
945 current.close(end);
946 current = null;
947 result.addSuccessor(graph.exit);
948 return result;
949 }
950
951 void goto(HBasicBlock from, HBasicBlock to) {
952 from.close(new HGoto());
953 from.addSuccessor(to);
954 }
955
956 bool isAborted() {
957 return _current == null;
958 }
959
960 /**
961 * Creates a new block, transitions to it from any current block, and
962 * opens the new block.
963 */
964 HBasicBlock openNewBlock() {
965 HBasicBlock newBlock = addNewBlock();
966 if (!isAborted()) goto(current, newBlock);
967 open(newBlock);
968 return newBlock;
969 }
970
971 void add(HInstruction instruction) {
972 current.add(instruction);
973 }
974 }
975
976 class SsaBuilder extends ResolvedVisitor with SsaGraphBuilderMixin {
977 final SsaBuilderTask builder;
978 final JavaScriptBackend backend;
979 final CodegenWorkItem work;
980 final ConstantSystem constantSystem;
981 LocalsHandler localsHandler;
982 HInstruction rethrowableException;
983 Map<Element, HInstruction> parameters;
984 final RuntimeTypes rti;
985 HParameterValue lastAddedParameter;
986
987 Map<TargetElement, JumpHandler> jumpTargets;
988
989 /**
990 * Variables stored in the current activation. These variables are
991 * being updated in try/catch blocks, and should be
992 * accessed indirectly through [HLocalGet] and [HLocalSet].
993 */
994 Map<Element, HLocalValue> activationVariables;
995
996 // We build the Ssa graph by simulating a stack machine.
997 List<HInstruction> stack;
998
934 /** 999 /**
935 * True if we are visiting the expression of a throw expression. 1000 * True if we are visiting the expression of a throw expression.
936 */ 1001 */
937 bool inThrowExpression = false; 1002 bool inThrowExpression = false;
938 1003
939 final List<Element> sourceElementStack; 1004 final List<Element> sourceElementStack;
940 1005
941 Element get currentElement => sourceElementStack.last.declaration; 1006 Element get currentElement => sourceElementStack.last.declaration;
942 Element get currentNonClosureClass { 1007 Element get currentNonClosureClass {
943 ClassElement cls = currentElement.getEnclosingClass(); 1008 ClassElement cls = currentElement.getEnclosingClass();
(...skipping 20 matching lines...) Expand all
964 // types of the type variables in an environment (like the [LocalsHandler]). 1029 // types of the type variables in an environment (like the [LocalsHandler]).
965 final List<DartType> currentInlinedInstantiations = <DartType>[]; 1030 final List<DartType> currentInlinedInstantiations = <DartType>[];
966 1031
967 Compiler get compiler => builder.compiler; 1032 Compiler get compiler => builder.compiler;
968 CodeEmitterTask get emitter => builder.emitter; 1033 CodeEmitterTask get emitter => builder.emitter;
969 1034
970 SsaBuilder(this.constantSystem, SsaBuilderTask builder, CodegenWorkItem work) 1035 SsaBuilder(this.constantSystem, SsaBuilderTask builder, CodegenWorkItem work)
971 : this.builder = builder, 1036 : this.builder = builder,
972 this.backend = builder.backend, 1037 this.backend = builder.backend,
973 this.work = work, 1038 this.work = work,
974 graph = new HGraph(),
975 stack = new List<HInstruction>(), 1039 stack = new List<HInstruction>(),
976 activationVariables = new Map<Element, HLocalValue>(), 1040 activationVariables = new Map<Element, HLocalValue>(),
977 jumpTargets = new Map<TargetElement, JumpHandler>(), 1041 jumpTargets = new Map<TargetElement, JumpHandler>(),
978 parameters = new Map<Element, HInstruction>(), 1042 parameters = new Map<Element, HInstruction>(),
979 sourceElementStack = <Element>[work.element], 1043 sourceElementStack = <Element>[work.element],
980 inliningStack = <InliningState>[], 1044 inliningStack = <InliningState>[],
981 rti = builder.backend.rti, 1045 rti = builder.backend.rti,
982 super(work.resolutionTree, builder.compiler) { 1046 super(work.resolutionTree, builder.compiler) {
983 localsHandler = new LocalsHandler(this); 1047 localsHandler = new LocalsHandler(this);
984 } 1048 }
985 1049
986 List<InliningState> inliningStack; 1050 List<InliningState> inliningStack;
987 1051
988 Element returnElement; 1052 Element returnElement;
989 DartType returnType; 1053 DartType returnType;
990 1054
991 bool inTryStatement = false; 1055 bool inTryStatement = false;
992 int loopNesting = 0; 1056 int loopNesting = 0;
993 1057
994 HBasicBlock get current => _current;
995 void set current(c) {
996 isReachable = c != null;
997 _current = c;
998 }
999
1000 Constant getConstantForNode(Node node) { 1058 Constant getConstantForNode(Node node) {
1001 ConstantHandler handler = compiler.constantHandler; 1059 ConstantHandler handler = compiler.constantHandler;
1002 Constant constant = elements.getConstant(node); 1060 Constant constant = elements.getConstant(node);
1003 assert(invariant(node, constant != null, 1061 assert(invariant(node, constant != null,
1004 message: 'No constant computed for $node')); 1062 message: 'No constant computed for $node'));
1005 return constant; 1063 return constant;
1006 } 1064 }
1007 1065
1008 HInstruction addConstant(Node node) { 1066 HInstruction addConstant(Node node) {
1009 return graph.addConstant(getConstantForNode(node), compiler); 1067 return graph.addConstant(getConstantForNode(node), compiler);
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 assert(succeeded); 1276 assert(succeeded);
1219 } 1277 }
1220 1278
1221 // Create the inlining state after evaluating the arguments, that 1279 // Create the inlining state after evaluating the arguments, that
1222 // may have an impact on the state of the current method. 1280 // may have an impact on the state of the current method.
1223 InliningState state = new InliningState( 1281 InliningState state = new InliningState(
1224 function, returnElement, returnType, elements, stack, 1282 function, returnElement, returnType, elements, stack,
1225 localsHandler, inTryStatement); 1283 localsHandler, inTryStatement);
1226 inTryStatement = false; 1284 inTryStatement = false;
1227 LocalsHandler newLocalsHandler = new LocalsHandler(this); 1285 LocalsHandler newLocalsHandler = new LocalsHandler(this);
1228 newLocalsHandler.closureData = 1286 if (function.hasIrNode(compiler)) {
1229 compiler.closureToClassMapper.computeClosureToClassMapping( 1287 // TODO(lry): handle ir functions with nested closure definitions.
1230 function, function.parseNode(compiler), elements); 1288 newLocalsHandler.closureData =
1289 new ClosureClassMap(null, null, null, new ThisElement(function));
1290 } else {
1291 newLocalsHandler.closureData =
1292 compiler.closureToClassMapper.computeClosureToClassMapping(
1293 function, function.parseNode(compiler), elements);
1294 }
1231 int argumentIndex = 0; 1295 int argumentIndex = 0;
1232 if (isInstanceMember) { 1296 if (isInstanceMember) {
1233 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, 1297 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement,
1234 compiledArguments[argumentIndex++]); 1298 compiledArguments[argumentIndex++]);
1235 } 1299 }
1236 1300
1237 FunctionSignature signature = function.computeSignature(compiler); 1301 FunctionSignature signature = function.computeSignature(compiler);
1238 signature.orderedForEachParameter((Element parameter) { 1302 signature.orderedForEachParameter((Element parameter) {
1239 HInstruction argument = compiledArguments[argumentIndex++]; 1303 HInstruction argument = compiledArguments[argumentIndex++];
1240 newLocalsHandler.updateLocal(parameter, argument); 1304 newLocalsHandler.updateLocal(parameter, argument);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 && returnType.isEmpty 1407 && returnType.isEmpty
1344 && !returnType.isNullable) { 1408 && !returnType.isNullable) {
1345 isReachable = false; 1409 isReachable = false;
1346 return false; 1410 return false;
1347 } 1411 }
1348 } 1412 }
1349 1413
1350 return true; 1414 return true;
1351 } 1415 }
1352 1416
1353 bool heuristicSayGoodToGo(FunctionExpression functionExpression) { 1417 bool heuristicSayGoodToGo(bool canBeInlined(int maxNodes)) {
1354 // Don't inline recursivly 1418 // Don't inline recursivly
1355 if (inliningStack.any((entry) => entry.function == function)) { 1419 if (inliningStack.any((entry) => entry.function == function)) {
1356 return false; 1420 return false;
1357 } 1421 }
1358 1422
1359 if (element.isSynthesized) return true; 1423 if (element.isSynthesized) return true;
1360 1424
1361 if (cachedCanBeInlined == true) return cachedCanBeInlined; 1425 if (cachedCanBeInlined == true) return cachedCanBeInlined;
1362 1426
1363 if (inThrowExpression) return false; 1427 if (inThrowExpression) return false;
1364 1428
1365 int numParameters = function.functionSignature.parameterCount; 1429 int numParameters = function.functionSignature.parameterCount;
1366 int maxInliningNodes; 1430 int maxInliningNodes;
1367 if (insideLoop) { 1431 if (insideLoop) {
1368 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + 1432 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
1369 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; 1433 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
1370 } else { 1434 } else {
1371 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + 1435 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
1372 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; 1436 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
1373 } 1437 }
1374 bool canBeInlined = InlineWeeder.canBeInlined( 1438 bool canInline = canBeInlined(maxInliningNodes);
1375 functionExpression, maxInliningNodes); 1439 if (canInline) {
1376 if (canBeInlined) {
1377 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); 1440 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop);
1378 } else { 1441 } else {
1379 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); 1442 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop);
1380 } 1443 }
1381 return canBeInlined; 1444 return canInline;
1382 } 1445 }
1383 1446
1384 void doInlining(FunctionExpression functionExpression) { 1447 void doInlining(void visitBody()) {
1385 // Add an explicit null check on the receiver before doing the 1448 // Add an explicit null check on the receiver before doing the
1386 // inlining. We use [element] to get the same name in the 1449 // inlining. We use [element] to get the same name in the
1387 // NoSuchMethodError message as if we had called it. 1450 // NoSuchMethodError message as if we had called it.
1388 if (element.isInstanceMember() 1451 if (element.isInstanceMember()
1389 && !element.isGenerativeConstructorBody() 1452 && !element.isGenerativeConstructorBody()
1390 && (selector.mask == null || selector.mask.isNullable)) { 1453 && (selector.mask == null || selector.mask.isNullable)) {
1391 addWithPosition( 1454 addWithPosition(
1392 new HFieldGet(null, providedArguments[0], backend.dynamicType, 1455 new HFieldGet(null, providedArguments[0], backend.dynamicType,
1393 isAssignable: false), 1456 isAssignable: false),
1394 currentNode); 1457 currentNode);
1395 } 1458 }
1396 InliningState state = enterInlinedMethod( 1459 InliningState state = enterInlinedMethod(
1397 function, selector, providedArguments, currentNode); 1460 function, selector, providedArguments, currentNode);
1398 1461
1399 inlinedFrom(element, () { 1462 inlinedFrom(element, () {
1400 FunctionElement function = element; 1463 FunctionElement function = element;
1401 FunctionSignature signature = function.computeSignature(compiler); 1464 FunctionSignature signature = function.computeSignature(compiler);
1402 signature.orderedForEachParameter((Element parameter) { 1465 signature.orderedForEachParameter((Element parameter) {
1403 HInstruction argument = localsHandler.readLocal(parameter); 1466 HInstruction argument = localsHandler.readLocal(parameter);
1404 potentiallyCheckType(argument, parameter.computeType(compiler)); 1467 potentiallyCheckType(argument, parameter.computeType(compiler));
1405 }); 1468 });
1406 addInlinedInstantiation(instantiatedType); 1469 addInlinedInstantiation(instantiatedType);
1407 if (element.isGenerativeConstructor()) { 1470 if (element.isGenerativeConstructor()) {
1408 buildFactory(element); 1471 buildFactory(element);
1409 } else { 1472 } else {
1410 functionExpression.body.accept(this); 1473 visitBody();
1411 } 1474 }
1412 removeInlinedInstantiation(instantiatedType); 1475 removeInlinedInstantiation(instantiatedType);
1413 }); 1476 });
1414 leaveInlinedMethod(state); 1477 leaveInlinedMethod(state);
1415 } 1478 }
1416 1479
1417 if (meetsHardConstraints()) { 1480 if (meetsHardConstraints()) {
1418 FunctionExpression functionExpression = function.parseNode(compiler); 1481 if (function.hasIrNode(compiler)) {
1419 1482 IrFunction irFunction = function.irNode(compiler);
1420 if (heuristicSayGoodToGo(functionExpression)) { 1483 bool canInline(int n) => IrInlineWeeder.canBeInlined(irFunction, n);
1421 doInlining(functionExpression); 1484 if (heuristicSayGoodToGo(canInline)) {
1422 return true; 1485 SsaFromIrInliner irInliner = new SsaFromIrInliner(this);
1486 doInlining(() => irInliner.visitAll(irFunction.statements));
1487 return true;
1488 }
1489 } else {
1490 FunctionExpression functionNode = function.parseNode(compiler);
1491 bool canInline(int n) => InlineWeeder.canBeInlined(functionNode, n);
1492 if (heuristicSayGoodToGo(canInline)) {
1493 doInlining(() => functionNode.body.accept(this));
1494 return true;
1495 }
1423 } 1496 }
1424 } 1497 }
1425 1498
1426 return false; 1499 return false;
1427 } 1500 }
1428 1501
1429 addInlinedInstantiation(DartType type) { 1502 addInlinedInstantiation(DartType type) {
1430 if (type != null) { 1503 if (type != null) {
1431 currentInlinedInstantiations.add(type); 1504 currentInlinedInstantiations.add(type);
1432 } 1505 }
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 add(assertIsSubtype); 2113 add(assertIsSubtype);
2041 } 2114 }
2042 2115
2043 HGraph closeFunction() { 2116 HGraph closeFunction() {
2044 // TODO(kasperl): Make this goto an implicit return. 2117 // TODO(kasperl): Make this goto an implicit return.
2045 if (!isAborted()) closeAndGotoExit(new HGoto()); 2118 if (!isAborted()) closeAndGotoExit(new HGoto());
2046 graph.finalize(); 2119 graph.finalize();
2047 return graph; 2120 return graph;
2048 } 2121 }
2049 2122
2050 HBasicBlock addNewBlock() {
2051 HBasicBlock block = graph.addNewBlock();
2052 // If adding a new block during building of an expression, it is due to
2053 // conditional expressions or short-circuit logical operators.
2054 return block;
2055 }
2056
2057 void open(HBasicBlock block) {
2058 block.open();
2059 current = block;
2060 lastOpenedBlock = block;
2061 }
2062
2063 HBasicBlock close(HControlFlow end) {
2064 HBasicBlock result = current;
2065 current.close(end);
2066 current = null;
2067 return result;
2068 }
2069
2070 HBasicBlock closeAndGotoExit(HControlFlow end) {
2071 HBasicBlock result = current;
2072 current.close(end);
2073 current = null;
2074 result.addSuccessor(graph.exit);
2075 return result;
2076 }
2077
2078 void goto(HBasicBlock from, HBasicBlock to) {
2079 from.close(new HGoto());
2080 from.addSuccessor(to);
2081 }
2082
2083 bool isAborted() {
2084 return _current == null;
2085 }
2086
2087 /**
2088 * Creates a new block, transitions to it from any current block, and
2089 * opens the new block.
2090 */
2091 HBasicBlock openNewBlock() {
2092 HBasicBlock newBlock = addNewBlock();
2093 if (!isAborted()) goto(current, newBlock);
2094 open(newBlock);
2095 return newBlock;
2096 }
2097
2098 void add(HInstruction instruction) {
2099 current.add(instruction);
2100 }
2101
2102 void addWithPosition(HInstruction instruction, Node node) { 2123 void addWithPosition(HInstruction instruction, Node node) {
2103 add(attachPosition(instruction, node)); 2124 add(attachPosition(instruction, node));
2104 } 2125 }
2105 2126
2106 void push(HInstruction instruction) { 2127 void push(HInstruction instruction) {
2107 add(instruction); 2128 add(instruction);
2108 stack.add(instruction); 2129 stack.add(instruction);
2109 } 2130 }
2110 2131
2111 void pushWithPosition(HInstruction instruction, Node node) { 2132 void pushWithPosition(HInstruction instruction, Node node) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2148 2169
2149 SourceFileLocation sourceFileLocationForToken(Node node, Token token) { 2170 SourceFileLocation sourceFileLocationForToken(Node node, Token token) {
2150 Element element = sourceElementStack.last; 2171 Element element = sourceElementStack.last;
2151 // TODO(johnniwinther): remove the 'element.patch' hack. 2172 // TODO(johnniwinther): remove the 'element.patch' hack.
2152 if (element is FunctionElement) { 2173 if (element is FunctionElement) {
2153 FunctionElement functionElement = element; 2174 FunctionElement functionElement = element;
2154 if (functionElement.patch != null) element = functionElement.patch; 2175 if (functionElement.patch != null) element = functionElement.patch;
2155 } 2176 }
2156 Script script = element.getCompilationUnit().script; 2177 Script script = element.getCompilationUnit().script;
2157 SourceFile sourceFile = script.file; 2178 SourceFile sourceFile = script.file;
2158 SourceFileLocation location = new SourceFileLocation(sourceFile, token); 2179 SourceFileLocation location =
2180 new TokenSourceFileLocation(sourceFile, token);
2159 if (!location.isValid()) { 2181 if (!location.isValid()) {
2160 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message( 2182 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
2161 {'offset': token.charOffset, 2183 {'offset': token.charOffset,
2162 'fileName': sourceFile.filename, 2184 'fileName': sourceFile.filename,
2163 'length': sourceFile.length}); 2185 'length': sourceFile.length});
2164 } 2186 }
2165 return location; 2187 return location;
2166 } 2188 }
2167 2189
2168 void visit(Node node) { 2190 void visit(Node node) {
(...skipping 3720 matching lines...) Expand 10 before | Expand all | Expand 10 after
5889 new HSubGraphBlockInformation(elseBranch.graph)); 5911 new HSubGraphBlockInformation(elseBranch.graph));
5890 5912
5891 HBasicBlock conditionStartBlock = conditionBranch.block; 5913 HBasicBlock conditionStartBlock = conditionBranch.block;
5892 conditionStartBlock.setBlockFlow(info, joinBlock); 5914 conditionStartBlock.setBlockFlow(info, joinBlock);
5893 SubGraph conditionGraph = conditionBranch.graph; 5915 SubGraph conditionGraph = conditionBranch.graph;
5894 HIf branch = conditionGraph.end.last; 5916 HIf branch = conditionGraph.end.last;
5895 assert(branch is HIf); 5917 assert(branch is HIf);
5896 branch.blockInformation = conditionStartBlock.blockFlow; 5918 branch.blockInformation = conditionStartBlock.blockFlow;
5897 } 5919 }
5898 } 5920 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698