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

Side by Side Diff: frog/leg/ssa/builder.dart

Issue 9592009: Reapply "Refactor constant part." (r4958) with fixes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add TODO. Created 8 years, 9 months 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
« no previous file with comments | « frog/leg/native_handler.dart ('k') | frog/leg/ssa/codegen.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 // the emitter. 851 // the emitter.
852 List<HInstruction> constructorArguments = <HInstruction>[]; 852 List<HInstruction> constructorArguments = <HInstruction>[];
853 ClassElement element = classElement; 853 ClassElement element = classElement;
854 while (element != null) { 854 while (element != null) {
855 for (Element member in element.members) { 855 for (Element member in element.members) {
856 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { 856 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) {
857 HInstruction value; 857 HInstruction value;
858 if (localsHandler.hasValueForDirectLocal(member)) { 858 if (localsHandler.hasValueForDirectLocal(member)) {
859 value = localsHandler.readLocal(member); 859 value = localsHandler.readLocal(member);
860 } else { 860 } else {
861 var fieldValue = 861 Constant fieldValue =
862 compiler.compileTimeConstantHandler.compileVariable(member); 862 compiler.constantHandler.compileVariable(member);
863 // TODO(floitsch): this constant should be treated like all 863 value = graph.addConstant(fieldValue);
864 // other constants and should be at the top of the graph.
865 value = new HLiteral.internal(fieldValue, HType.UNKNOWN);
866 add(value);
867 } 864 }
868 constructorArguments.add(value); 865 constructorArguments.add(value);
869 } 866 }
870 } 867 }
871 element = element.superclass; 868 element = element.superclass;
872 } 869 }
873 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); 870 HForeignNew newObject = new HForeignNew(classElement, constructorArguments);
874 add(newObject); 871 add(newObject);
875 // Generate calls to the constructor bodies. 872 // Generate calls to the constructor bodies.
876 for (int index = constructors.length - 1; index >= 0; index--) { 873 for (int index = constructors.length - 1; index >= 0; index--) {
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 visit(node.receiver); 1306 visit(node.receiver);
1310 HNot not = new HNot(popBoolified()); 1307 HNot not = new HNot(popBoolified());
1311 push(not); 1308 push(not);
1312 } 1309 }
1313 1310
1314 void visitUnary(Send node, Operator op) { 1311 void visitUnary(Send node, Operator op) {
1315 assert(node.argumentsNode is Prefix); 1312 assert(node.argumentsNode is Prefix);
1316 visit(node.receiver); 1313 visit(node.receiver);
1317 assert(op.token.kind !== PLUS_TOKEN); 1314 assert(op.token.kind !== PLUS_TOKEN);
1318 HInstruction operand = pop(); 1315 HInstruction operand = pop();
1316 // See if we can constant-fold right away. This avoids rewrites later on.
1317 if (operand is HConstant) {
1318 HConstant typedOperand = operand;
1319 Constant constant = typedOperand.constant;
1320 Constant folded = constant.unaryFold(op.source.stringValue);
1321 if (folded !== null) {
1322 stack.add(graph.addConstant(folded));
1323 return;
1324 }
1325 }
1319 HInstruction target = 1326 HInstruction target =
1320 new HStatic(interceptors.getPrefixOperatorInterceptor(op)); 1327 new HStatic(interceptors.getPrefixOperatorInterceptor(op));
1321 add(target); 1328 add(target);
1322 switch (op.source.stringValue) { 1329 switch (op.source.stringValue) {
1323 case "-": 1330 case "-": push(new HNegate(target, operand)); break;
1324 // TODO(kasperl): Avoid calling visit(node.receiver) above.
1325 if ((operand is HLiteral) && (operand.value is double)) {
1326 stack.add(graph.addNewLiteralDouble(-operand.value));
1327 } else if ((operand is HLiteral) && (operand.value is int)) {
1328 stack.add(graph.addNewLiteralInt(-operand.value));
1329 } else {
1330 push(new HNegate(target, operand));
1331 }
1332 break;
1333 case "~": push(new HBitNot(target, operand)); break; 1331 case "~": push(new HBitNot(target, operand)); break;
1334 default: unreachable(); 1332 default: unreachable();
1335 } 1333 }
1336 } 1334 }
1337 1335
1338 void visitBinary(HInstruction left, Operator op, HInstruction right) { 1336 void visitBinary(HInstruction left, Operator op, HInstruction right) {
1339 Element element = interceptors.getOperatorInterceptor(op); 1337 Element element = interceptors.getOperatorInterceptor(op);
1340 assert(element != null); 1338 assert(element != null);
1341 HInstruction target = new HStatic(element); 1339 HInstruction target = new HStatic(element);
1342 add(target); 1340 add(target);
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 for (int i = 0; i < selector.namedArguments.length; i++) { 1628 for (int i = 0; i < selector.namedArguments.length; i++) {
1631 SourceString name = selector.namedArguments[i]; 1629 SourceString name = selector.namedArguments[i];
1632 if (name == parameter.name) { 1630 if (name == parameter.name) {
1633 foundIndex = i; 1631 foundIndex = i;
1634 break; 1632 break;
1635 } 1633 }
1636 } 1634 }
1637 if (foundIndex != -1) { 1635 if (foundIndex != -1) {
1638 list.add(namedArguments[foundIndex]); 1636 list.add(namedArguments[foundIndex]);
1639 } else { 1637 } else {
1640 // TODO(kasperl): This needs more work. Ideally these 1638 Constant constant = compiler.compileVariable(parameter);
1641 // constants should be treated like any other constant and 1639 list.add(graph.addConstant(constant));
1642 // canonicalized by the graph methods.
1643 var constant = compiler.compileVariable(parameter);
1644 push(new HLiteral.internal(constant, HType.UNKNOWN));
1645 list.add(pop());
1646 } 1640 }
1647 } 1641 }
1648 } 1642 }
1649 } 1643 }
1650 1644
1651 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) { 1645 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
1652 for (; !link.isEmpty(); link = link.tail) { 1646 for (; !link.isEmpty(); link = link.tail) {
1653 visit(link.head); 1647 visit(link.head);
1654 list.add(pop()); 1648 list.add(pop());
1655 } 1649 }
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 HInstruction index; 1864 HInstruction index;
1871 bool isCompoundAssignment = op.source.stringValue.endsWith('='); 1865 bool isCompoundAssignment = op.source.stringValue.endsWith('=');
1872 // Compound assignments are considered as being prefix. 1866 // Compound assignments are considered as being prefix.
1873 bool isPrefix = !node.isPostfix; 1867 bool isPrefix = !node.isPostfix;
1874 Element getter = elements[node.selector]; 1868 Element getter = elements[node.selector];
1875 if (isCompoundAssignment) { 1869 if (isCompoundAssignment) {
1876 value = pop(); 1870 value = pop();
1877 index = pop(); 1871 index = pop();
1878 } else { 1872 } else {
1879 index = pop(); 1873 index = pop();
1880 value = graph.addNewLiteralInt(1); 1874 value = graph.addConstantInt(1);
1881 } 1875 }
1882 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); 1876 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor());
1883 add(indexMethod); 1877 add(indexMethod);
1884 HInstruction left = new HIndex(indexMethod, receiver, index); 1878 HInstruction left = new HIndex(indexMethod, receiver, index);
1885 add(left); 1879 add(left);
1886 Element opElement = elements[op]; 1880 Element opElement = elements[op];
1887 visitBinary(left, op, value); 1881 visitBinary(left, op, value);
1888 HInstruction assign = new HIndexAssign( 1882 HInstruction assign = new HIndexAssign(
1889 target, receiver, index, pop()); 1883 target, receiver, index, pop());
1890 add(assign); 1884 add(assign);
(...skipping 20 matching lines...) Expand all
1911 Element element = elements[node]; 1905 Element element = elements[node];
1912 bool isCompoundAssignment = !node.arguments.isEmpty(); 1906 bool isCompoundAssignment = !node.arguments.isEmpty();
1913 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. 1907 bool isPrefix = !node.isPostfix; // Compound assignments are prefix.
1914 generateGetter(node, elements[node.selector]); 1908 generateGetter(node, elements[node.selector]);
1915 HInstruction left = pop(); 1909 HInstruction left = pop();
1916 HInstruction right; 1910 HInstruction right;
1917 if (isCompoundAssignment) { 1911 if (isCompoundAssignment) {
1918 visit(node.argumentsNode); 1912 visit(node.argumentsNode);
1919 right = pop(); 1913 right = pop();
1920 } else { 1914 } else {
1921 right = graph.addNewLiteralInt(1); 1915 right = graph.addConstantInt(1);
1922 } 1916 }
1923 visitBinary(left, op, right); 1917 visitBinary(left, op, right);
1924 HInstruction operation = pop(); 1918 HInstruction operation = pop();
1925 assert(operation !== null); 1919 assert(operation !== null);
1926 generateSetter(node, element, operation); 1920 generateSetter(node, element, operation);
1927 if (!isPrefix) { 1921 if (!isPrefix) {
1928 pop(); 1922 pop();
1929 stack.add(left); 1923 stack.add(left);
1930 } 1924 }
1931 } 1925 }
1932 } 1926 }
1933 1927
1934 void visitLiteralInt(LiteralInt node) { 1928 void visitLiteralInt(LiteralInt node) {
1935 stack.add(graph.addNewLiteralInt(node.value)); 1929 stack.add(graph.addConstantInt(node.value));
1936 } 1930 }
1937 1931
1938 void visitLiteralDouble(LiteralDouble node) { 1932 void visitLiteralDouble(LiteralDouble node) {
1939 stack.add(graph.addNewLiteralDouble(node.value)); 1933 stack.add(graph.addConstantDouble(node.value));
1940 } 1934 }
1941 1935
1942 void visitLiteralBool(LiteralBool node) { 1936 void visitLiteralBool(LiteralBool node) {
1943 stack.add(graph.addNewLiteralBool(node.value)); 1937 stack.add(graph.addConstantBool(node.value));
1944 } 1938 }
1945 1939
1946 void visitLiteralString(LiteralString node) { 1940 void visitLiteralString(LiteralString node) {
1947 stack.add(graph.addNewLiteralString(node.dartString)); 1941 stack.add(graph.addConstantString(node.dartString));
1948 } 1942 }
1949 1943
1950 void visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node) { 1944 void visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node) {
1951 visitLiteralString(node); 1945 visitLiteralString(node);
1952 } 1946 }
1953 1947
1954 void visitLiteralNull(LiteralNull node) { 1948 void visitLiteralNull(LiteralNull node) {
1955 stack.add(graph.addNewLiteralNull()); 1949 stack.add(graph.addConstantNull());
1956 } 1950 }
1957 1951
1958 visitNodeList(NodeList node) { 1952 visitNodeList(NodeList node) {
1959 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 1953 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
1960 if (isAborted()) { 1954 if (isAborted()) {
1961 compiler.reportWarning(link.head, 'dead code'); 1955 compiler.reportWarning(link.head, 'dead code');
1962 } else { 1956 } else {
1963 visit(link.head); 1957 visit(link.head);
1964 } 1958 }
1965 } 1959 }
1966 } 1960 }
1967 1961
1968 void visitParenthesizedExpression(ParenthesizedExpression node) { 1962 void visitParenthesizedExpression(ParenthesizedExpression node) {
1969 visit(node.expression); 1963 visit(node.expression);
1970 } 1964 }
1971 1965
1972 visitOperator(Operator node) { 1966 visitOperator(Operator node) {
1973 // Operators are intercepted in their surrounding Send nodes. 1967 // Operators are intercepted in their surrounding Send nodes.
1974 unreachable(); 1968 unreachable();
1975 } 1969 }
1976 1970
1977 visitReturn(Return node) { 1971 visitReturn(Return node) {
1978 HInstruction value; 1972 HInstruction value;
1979 if (node.expression === null) { 1973 if (node.expression === null) {
1980 value = graph.addNewLiteralNull(); 1974 value = graph.addConstantNull();
1981 } else { 1975 } else {
1982 visit(node.expression); 1976 visit(node.expression);
1983 value = pop(); 1977 value = pop();
1984 } 1978 }
1985 close(new HReturn(value)).addSuccessor(graph.exit); 1979 close(new HReturn(value)).addSuccessor(graph.exit);
1986 } 1980 }
1987 1981
1988 visitThrow(Throw node) { 1982 visitThrow(Throw node) {
1989 if (node.expression === null) { 1983 if (node.expression === null) {
1990 HInstruction exception = rethrowableException; 1984 HInstruction exception = rethrowableException;
1991 if (exception === null) { 1985 if (exception === null) {
1992 exception = graph.addNewLiteralNull(); 1986 exception = graph.addConstantNull();
1993 compiler.reportError(node, 1987 compiler.reportError(node,
1994 'throw without expression outside catch block'); 1988 'throw without expression outside catch block');
1995 } 1989 }
1996 close(new HThrow(exception, isRethrow: true)); 1990 close(new HThrow(exception, isRethrow: true));
1997 } else { 1991 } else {
1998 visit(node.expression); 1992 visit(node.expression);
1999 close(new HThrow(pop())); 1993 close(new HThrow(pop()));
2000 } 1994 }
2001 } 1995 }
2002 1996
2003 visitTypeAnnotation(TypeAnnotation node) { 1997 visitTypeAnnotation(TypeAnnotation node) {
2004 compiler.internalError('visiting type annotation in SSA builder', 1998 compiler.internalError('visiting type annotation in SSA builder',
2005 node: node); 1999 node: node);
2006 } 2000 }
2007 2001
2008 visitVariableDefinitions(VariableDefinitions node) { 2002 visitVariableDefinitions(VariableDefinitions node) {
2009 for (Link<Node> link = node.definitions.nodes; 2003 for (Link<Node> link = node.definitions.nodes;
2010 !link.isEmpty(); 2004 !link.isEmpty();
2011 link = link.tail) { 2005 link = link.tail) {
2012 Node definition = link.head; 2006 Node definition = link.head;
2013 if (definition is Identifier) { 2007 if (definition is Identifier) {
2014 HInstruction initialValue = graph.addNewLiteralNull(); 2008 HInstruction initialValue = graph.addConstantNull();
2015 localsHandler.updateLocal(elements[definition], initialValue); 2009 localsHandler.updateLocal(elements[definition], initialValue);
2016 } else { 2010 } else {
2017 assert(definition is SendSet); 2011 assert(definition is SendSet);
2018 visitSendSet(definition); 2012 visitSendSet(definition);
2019 pop(); // Discard value. 2013 pop(); // Discard value.
2020 } 2014 }
2021 } 2015 }
2022 } 2016 }
2023 2017
2024 visitLiteralList(LiteralList node) { 2018 visitLiteralList(LiteralList node) {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 handleThen() { 2282 handleThen() {
2289 if (cases.head.statements.nodes.isEmpty()) { 2283 if (cases.head.statements.nodes.isEmpty()) {
2290 compiler.unimplemented('fall-through', node: cases.head); 2284 compiler.unimplemented('fall-through', node: cases.head);
2291 } 2285 }
2292 visit(cases.head.statements); 2286 visit(cases.head.statements);
2293 cases = cases.tail; 2287 cases = cases.tail;
2294 } 2288 }
2295 handleElse() { 2289 handleElse() {
2296 if (cases.isEmpty()) return; 2290 if (cases.isEmpty()) return;
2297 if (cases.head is DefaultCase) { 2291 if (cases.head is DefaultCase) {
2298 stack.add(graph.addNewLiteralBool(true)); 2292 stack.add(graph.addConstantBool(true));
2299 if (!cases.tail.isEmpty()) { 2293 if (!cases.tail.isEmpty()) {
2300 compiler.unimplemented('default case not last', node: cases.head); 2294 compiler.unimplemented('default case not last', node: cases.head);
2301 } 2295 }
2302 } else { 2296 } else {
2303 SwitchCase switchCase = cases.head; 2297 SwitchCase switchCase = cases.head;
2304 visit(switchCase.expression); 2298 visit(switchCase.expression);
2305 HInstruction caseExpression = pop(); 2299 HInstruction caseExpression = pop();
2306 Element equalsHelper = compiler.findHelper(const SourceString('eq')); 2300 Element equalsHelper = compiler.findHelper(const SourceString('eq'));
2307 HInstruction target = new HStatic(equalsHelper); 2301 HInstruction target = new HStatic(equalsHelper);
2308 add(target); 2302 add(target);
(...skipping 11 matching lines...) Expand all
2320 2314
2321 if (isAborted()) { 2315 if (isAborted()) {
2322 compiler.unimplemented("SsaBuilder for loop with aborting body", 2316 compiler.unimplemented("SsaBuilder for loop with aborting body",
2323 node: node); 2317 node: node);
2324 } 2318 }
2325 2319
2326 HBasicBlock bodyExitBlock = close(new HGoto()); 2320 HBasicBlock bodyExitBlock = close(new HGoto());
2327 HBasicBlock conditionBlock = addNewBlock(); 2321 HBasicBlock conditionBlock = addNewBlock();
2328 bodyExitBlock.addSuccessor(conditionBlock); 2322 bodyExitBlock.addSuccessor(conditionBlock);
2329 open(conditionBlock); 2323 open(conditionBlock);
2330 stack.add(graph.addNewLiteralBool(false)); 2324 stack.add(graph.addConstantBool(false));
2331 2325
2332 conditionBlock = close(new HLoopBranch(popBoolified(), 2326 conditionBlock = close(new HLoopBranch(popBoolified(),
2333 HLoopBranch.DO_WHILE_LOOP)); 2327 HLoopBranch.DO_WHILE_LOOP));
2334 2328
2335 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. 2329 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge.
2336 loopEntryBlock.postProcessLoopHeader(); 2330 loopEntryBlock.postProcessLoopHeader();
2337 2331
2338 endLoop(loopEntryBlock, conditionBlock, breakHandler); 2332 endLoop(loopEntryBlock, conditionBlock, breakHandler);
2339 } 2333 }
2340 2334
(...skipping 30 matching lines...) Expand all
2371 new HInvokeStatic(Selector.INVOCATION_1, inputs); 2365 new HInvokeStatic(Selector.INVOCATION_1, inputs);
2372 add(unwrappedException); 2366 add(unwrappedException);
2373 2367
2374 tryInstruction.exception = exception; 2368 tryInstruction.exception = exception;
2375 Link<Node> link = node.catchBlocks.nodes; 2369 Link<Node> link = node.catchBlocks.nodes;
2376 2370
2377 void pushCondition(CatchBlock catchBlock) { 2371 void pushCondition(CatchBlock catchBlock) {
2378 VariableDefinitions declaration = catchBlock.formals.nodes.head; 2372 VariableDefinitions declaration = catchBlock.formals.nodes.head;
2379 HInstruction condition = null; 2373 HInstruction condition = null;
2380 if (declaration.type == null) { 2374 if (declaration.type == null) {
2381 condition = graph.addNewLiteralTrue(); 2375 condition = graph.addConstantBool(true);
2382 stack.add(condition); 2376 stack.add(condition);
2383 } else { 2377 } else {
2384 Element typeElement = elements[declaration.type]; 2378 Element typeElement = elements[declaration.type];
2385 if (typeElement == null) { 2379 if (typeElement == null) {
2386 compiler.cancel('Catch with unresolved type', node: catchBlock); 2380 compiler.cancel('Catch with unresolved type', node: catchBlock);
2387 } 2381 }
2388 condition = new HIs(typeElement, unwrappedException, nullOk: true); 2382 condition = new HIs(typeElement, unwrappedException, nullOk: true);
2389 push(condition); 2383 push(condition);
2390 } 2384 }
2391 } 2385 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 visitCatchBlock(CatchBlock node) { 2435 visitCatchBlock(CatchBlock node) {
2442 visit(node.block); 2436 visit(node.block);
2443 } 2437 }
2444 2438
2445 visitTypedef(Typedef node) { 2439 visitTypedef(Typedef node) {
2446 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 2440 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
2447 } 2441 }
2448 2442
2449 generateUnimplemented(String reason, [bool isExpression = false]) { 2443 generateUnimplemented(String reason, [bool isExpression = false]) {
2450 DartString string = new DartString.literal(reason); 2444 DartString string = new DartString.literal(reason);
2451 HInstruction message = graph.addNewLiteralString(string); 2445 HInstruction message = graph.addConstantString(string);
2452 2446
2453 // Normally, we would call [close] here. However, then we hit 2447 // Normally, we would call [close] here. However, then we hit
2454 // another unimplemented feature: aborting loop body. Simply 2448 // another unimplemented feature: aborting loop body. Simply
2455 // calling [add] does not work as it asserts that the instruction 2449 // calling [add] does not work as it asserts that the instruction
2456 // isn't a control flow instruction. So we inline parts of [add]. 2450 // isn't a control flow instruction. So we inline parts of [add].
2457 current.addAfter(current.last, new HThrow(message)); 2451 current.addAfter(current.last, new HThrow(message));
2458 if (isExpression) { 2452 if (isExpression) {
2459 stack.add(graph.addNewLiteralNull()); 2453 stack.add(graph.addConstantNull());
2460 } 2454 }
2461 } 2455 }
2462 } 2456 }
OLDNEW
« no previous file with comments | « frog/leg/native_handler.dart ('k') | frog/leg/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698