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

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

Powered by Google App Engine
This is Rietveld 408576698