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

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

Issue 85813002: Revert "Revert "Build new IR for functions returning a constant."" (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: feedback by kasper Created 7 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 | 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 (compiler.irBuilder.hasIr(function)) {
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, bool useMax)) {
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;
(...skipping 11 matching lines...) Expand all
1375 1439
1376 // If a method is called only once, and all the methods in the 1440 // If a method is called only once, and all the methods in the
1377 // inlining stack are called only once as well, we know we will 1441 // inlining stack are called only once as well, we know we will
1378 // save on output size by inlining this method. 1442 // save on output size by inlining this method.
1379 TypesInferrer inferrer = compiler.typesTask.typesInferrer; 1443 TypesInferrer inferrer = compiler.typesTask.typesInferrer;
1380 if (inferrer.isCalledOnce(element) 1444 if (inferrer.isCalledOnce(element)
1381 && (inliningStack.every( 1445 && (inliningStack.every(
1382 (entry) => inferrer.isCalledOnce(entry.function)))) { 1446 (entry) => inferrer.isCalledOnce(entry.function)))) {
1383 useMaxInliningNodes = false; 1447 useMaxInliningNodes = false;
1384 } 1448 }
1385 bool canBeInlined = InlineWeeder.canBeInlined( 1449 bool canInline = canBeInlined(maxInliningNodes, useMaxInliningNodes);
1386 functionExpression, maxInliningNodes, useMaxInliningNodes); 1450 if (canInline) {
1387 if (canBeInlined) {
1388 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); 1451 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop);
1389 } else { 1452 } else {
1390 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); 1453 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop);
1391 } 1454 }
1392 return canBeInlined; 1455 return canInline;
1393 } 1456 }
1394 1457
1395 void doInlining(FunctionExpression functionExpression) { 1458 void doInlining(void visitBody()) {
1396 // Add an explicit null check on the receiver before doing the 1459 // Add an explicit null check on the receiver before doing the
1397 // inlining. We use [element] to get the same name in the 1460 // inlining. We use [element] to get the same name in the
1398 // NoSuchMethodError message as if we had called it. 1461 // NoSuchMethodError message as if we had called it.
1399 if (element.isInstanceMember() 1462 if (element.isInstanceMember()
1400 && !element.isGenerativeConstructorBody() 1463 && !element.isGenerativeConstructorBody()
1401 && (selector.mask == null || selector.mask.isNullable)) { 1464 && (selector.mask == null || selector.mask.isNullable)) {
1402 addWithPosition( 1465 addWithPosition(
1403 new HFieldGet(null, providedArguments[0], backend.dynamicType, 1466 new HFieldGet(null, providedArguments[0], backend.dynamicType,
1404 isAssignable: false), 1467 isAssignable: false),
1405 currentNode); 1468 currentNode);
1406 } 1469 }
1407 InliningState state = enterInlinedMethod( 1470 InliningState state = enterInlinedMethod(
1408 function, selector, providedArguments, currentNode); 1471 function, selector, providedArguments, currentNode);
1409 1472
1410 inlinedFrom(element, () { 1473 inlinedFrom(element, () {
1411 FunctionElement function = element; 1474 FunctionElement function = element;
1412 FunctionSignature signature = function.computeSignature(compiler); 1475 FunctionSignature signature = function.computeSignature(compiler);
1413 signature.orderedForEachParameter((Element parameter) { 1476 signature.orderedForEachParameter((Element parameter) {
1414 HInstruction argument = localsHandler.readLocal(parameter); 1477 HInstruction argument = localsHandler.readLocal(parameter);
1415 potentiallyCheckType(argument, parameter.computeType(compiler)); 1478 potentiallyCheckType(argument, parameter.computeType(compiler));
1416 }); 1479 });
1417 addInlinedInstantiation(instantiatedType); 1480 addInlinedInstantiation(instantiatedType);
1418 if (element.isGenerativeConstructor()) { 1481 if (element.isGenerativeConstructor()) {
1419 buildFactory(element); 1482 buildFactory(element);
1420 } else { 1483 } else {
1421 functionExpression.body.accept(this); 1484 visitBody();
1422 } 1485 }
1423 removeInlinedInstantiation(instantiatedType); 1486 removeInlinedInstantiation(instantiatedType);
1424 }); 1487 });
1425 leaveInlinedMethod(state); 1488 leaveInlinedMethod(state);
1426 } 1489 }
1427 1490
1428 if (meetsHardConstraints()) { 1491 if (meetsHardConstraints()) {
1429 FunctionExpression functionExpression = function.parseNode(compiler); 1492 if (compiler.irBuilder.hasIr(function)) {
1430 1493 IrFunction irFunction = compiler.irBuilder.getIr(function);
1431 if (heuristicSayGoodToGo(functionExpression)) { 1494 bool canInline(int n, bool b) {
1432 doInlining(functionExpression); 1495 return IrInlineWeeder.canBeInlined(irFunction, n, b);
1433 return true; 1496 }
1497 if (heuristicSayGoodToGo(canInline)) {
1498 SsaFromIrInliner irInliner = new SsaFromIrInliner(this);
1499 doInlining(() => irInliner.visitAll(irFunction.statements));
1500 return true;
1501 }
1502 } else {
1503 FunctionExpression functionNode = function.parseNode(compiler);
1504 bool canInline(int n, bool b) {
1505 return InlineWeeder.canBeInlined(functionNode, n, b);
1506 }
1507 if (heuristicSayGoodToGo(canInline)) {
1508 doInlining(() => functionNode.body.accept(this));
1509 return true;
1510 }
1434 } 1511 }
1435 } 1512 }
1436 1513
1437 return false; 1514 return false;
1438 } 1515 }
1439 1516
1440 addInlinedInstantiation(DartType type) { 1517 addInlinedInstantiation(DartType type) {
1441 if (type != null) { 1518 if (type != null) {
1442 currentInlinedInstantiations.add(type); 1519 currentInlinedInstantiations.add(type);
1443 } 1520 }
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
2051 add(assertIsSubtype); 2128 add(assertIsSubtype);
2052 } 2129 }
2053 2130
2054 HGraph closeFunction() { 2131 HGraph closeFunction() {
2055 // TODO(kasperl): Make this goto an implicit return. 2132 // TODO(kasperl): Make this goto an implicit return.
2056 if (!isAborted()) closeAndGotoExit(new HGoto()); 2133 if (!isAborted()) closeAndGotoExit(new HGoto());
2057 graph.finalize(); 2134 graph.finalize();
2058 return graph; 2135 return graph;
2059 } 2136 }
2060 2137
2061 HBasicBlock addNewBlock() {
2062 HBasicBlock block = graph.addNewBlock();
2063 // If adding a new block during building of an expression, it is due to
2064 // conditional expressions or short-circuit logical operators.
2065 return block;
2066 }
2067
2068 void open(HBasicBlock block) {
2069 block.open();
2070 current = block;
2071 lastOpenedBlock = block;
2072 }
2073
2074 HBasicBlock close(HControlFlow end) {
2075 HBasicBlock result = current;
2076 current.close(end);
2077 current = null;
2078 return result;
2079 }
2080
2081 HBasicBlock closeAndGotoExit(HControlFlow end) {
2082 HBasicBlock result = current;
2083 current.close(end);
2084 current = null;
2085 result.addSuccessor(graph.exit);
2086 return result;
2087 }
2088
2089 void goto(HBasicBlock from, HBasicBlock to) {
2090 from.close(new HGoto());
2091 from.addSuccessor(to);
2092 }
2093
2094 bool isAborted() {
2095 return _current == null;
2096 }
2097
2098 /**
2099 * Creates a new block, transitions to it from any current block, and
2100 * opens the new block.
2101 */
2102 HBasicBlock openNewBlock() {
2103 HBasicBlock newBlock = addNewBlock();
2104 if (!isAborted()) goto(current, newBlock);
2105 open(newBlock);
2106 return newBlock;
2107 }
2108
2109 void add(HInstruction instruction) {
2110 current.add(instruction);
2111 }
2112
2113 void addWithPosition(HInstruction instruction, Node node) { 2138 void addWithPosition(HInstruction instruction, Node node) {
2114 add(attachPosition(instruction, node)); 2139 add(attachPosition(instruction, node));
2115 } 2140 }
2116 2141
2117 void push(HInstruction instruction) { 2142 void push(HInstruction instruction) {
2118 add(instruction); 2143 add(instruction);
2119 stack.add(instruction); 2144 stack.add(instruction);
2120 } 2145 }
2121 2146
2122 void pushWithPosition(HInstruction instruction, Node node) { 2147 void pushWithPosition(HInstruction instruction, Node node) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 2184
2160 SourceFileLocation sourceFileLocationForToken(Node node, Token token) { 2185 SourceFileLocation sourceFileLocationForToken(Node node, Token token) {
2161 Element element = sourceElementStack.last; 2186 Element element = sourceElementStack.last;
2162 // TODO(johnniwinther): remove the 'element.patch' hack. 2187 // TODO(johnniwinther): remove the 'element.patch' hack.
2163 if (element is FunctionElement) { 2188 if (element is FunctionElement) {
2164 FunctionElement functionElement = element; 2189 FunctionElement functionElement = element;
2165 if (functionElement.patch != null) element = functionElement.patch; 2190 if (functionElement.patch != null) element = functionElement.patch;
2166 } 2191 }
2167 Script script = element.getCompilationUnit().script; 2192 Script script = element.getCompilationUnit().script;
2168 SourceFile sourceFile = script.file; 2193 SourceFile sourceFile = script.file;
2169 SourceFileLocation location = new SourceFileLocation(sourceFile, token); 2194 SourceFileLocation location =
2195 new TokenSourceFileLocation(sourceFile, token);
2170 if (!location.isValid()) { 2196 if (!location.isValid()) {
2171 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message( 2197 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
2172 {'offset': token.charOffset, 2198 {'offset': token.charOffset,
2173 'fileName': sourceFile.filename, 2199 'fileName': sourceFile.filename,
2174 'length': sourceFile.length}); 2200 'length': sourceFile.length});
2175 } 2201 }
2176 return location; 2202 return location;
2177 } 2203 }
2178 2204
2179 void visit(Node node) { 2205 void visit(Node node) {
(...skipping 3758 matching lines...) Expand 10 before | Expand all | Expand 10 after
5938 new HSubGraphBlockInformation(elseBranch.graph)); 5964 new HSubGraphBlockInformation(elseBranch.graph));
5939 5965
5940 HBasicBlock conditionStartBlock = conditionBranch.block; 5966 HBasicBlock conditionStartBlock = conditionBranch.block;
5941 conditionStartBlock.setBlockFlow(info, joinBlock); 5967 conditionStartBlock.setBlockFlow(info, joinBlock);
5942 SubGraph conditionGraph = conditionBranch.graph; 5968 SubGraph conditionGraph = conditionBranch.graph;
5943 HIf branch = conditionGraph.end.last; 5969 HIf branch = conditionGraph.end.last;
5944 assert(branch is HIf); 5970 assert(branch is HIf);
5945 branch.blockInformation = conditionStartBlock.blockFlow; 5971 branch.blockInformation = conditionStartBlock.blockFlow;
5946 } 5972 }
5947 } 5973 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698