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

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

Issue 12042003: Move relational operators to the new interceptors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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
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 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 * 1016 *
1017 * Invariant: [functionElement] must be an implementation element. 1017 * Invariant: [functionElement] must be an implementation element.
1018 */ 1018 */
1019 HGraph buildMethod(FunctionElement functionElement) { 1019 HGraph buildMethod(FunctionElement functionElement) {
1020 assert(invariant(functionElement, functionElement.isImplementation)); 1020 assert(invariant(functionElement, functionElement.isImplementation));
1021 FunctionExpression function = functionElement.parseNode(compiler); 1021 FunctionExpression function = functionElement.parseNode(compiler);
1022 assert(function != null); 1022 assert(function != null);
1023 assert(!function.modifiers.isExternal()); 1023 assert(!function.modifiers.isExternal());
1024 assert(elements[function] != null); 1024 assert(elements[function] != null);
1025 openFunction(functionElement, function); 1025 openFunction(functionElement, function);
1026 SourceString name = functionElement.name;
1027 // If [functionElement] is operator== we explicitely add a null
1028 // check at the beginning of the method. This is to avoid having
1029 // call sites do the null check.
1030 if (name == const SourceString('==')) {
1031 handleIf(
1032 function,
1033 () {
1034 HParameterValue parameter = parameters.values.first;
1035 push(new HIdentity(
1036 parameter, graph.addConstantNull(constantSystem)));
1037 },
1038 () {
1039 HReturn ret = new HReturn(
1040 graph.addConstantBool(false, constantSystem));
1041 close(ret).addSuccessor(graph.exit);
1042 },
1043 null);
1044 }
1026 function.body.accept(this); 1045 function.body.accept(this);
1027 return closeFunction(); 1046 return closeFunction();
1028 } 1047 }
1029 1048
1030 HGraph buildLazyInitializer(VariableElement variable) { 1049 HGraph buildLazyInitializer(VariableElement variable) {
1031 SendSet node = variable.parseNode(compiler); 1050 SendSet node = variable.parseNode(compiler);
1032 openFunction(variable, node); 1051 openFunction(variable, node);
1033 Link<Node> link = node.arguments; 1052 Link<Node> link = node.arguments;
1034 assert(!link.isEmpty && link.tail.isEmpty); 1053 assert(!link.isEmpty && link.tail.isEmpty);
1035 visit(link.head); 1054 visit(link.head);
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 1559
1541 // Fetch the original default value of [element]; 1560 // Fetch the original default value of [element];
1542 Constant constant = compileVariable(element); 1561 Constant constant = compileVariable(element);
1543 HConstant defaultValue = constant == null 1562 HConstant defaultValue = constant == null
1544 ? graph.addConstantNull(constantSystem) 1563 ? graph.addConstantNull(constantSystem)
1545 : graph.addConstant(constant); 1564 : graph.addConstant(constant);
1546 1565
1547 // Emit the equality check with the sentinel. 1566 // Emit the equality check with the sentinel.
1548 HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL); 1567 HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL);
1549 Element equalsHelper = interceptors.getTripleEqualsInterceptor(); 1568 Element equalsHelper = interceptors.getTripleEqualsInterceptor();
1550 HInstruction target = new HStatic(equalsHelper);
1551 add(target);
1552 HInstruction operand = parameters[element]; 1569 HInstruction operand = parameters[element];
1553 check = new HIdentity(target, sentinel, operand); 1570 check = new HIdentity(sentinel, operand);
1554 add(check); 1571 add(check);
1555 1572
1556 // If the check succeeds, we must update the parameter with the 1573 // If the check succeeds, we must update the parameter with the
1557 // default value. 1574 // default value.
1558 handleIf(element.parseNode(compiler), 1575 handleIf(element.parseNode(compiler),
1559 () => stack.add(check), 1576 () => stack.add(check),
1560 () => localsHandler.updateLocal(element, defaultValue), 1577 () => localsHandler.updateLocal(element, defaultValue),
1561 null); 1578 null);
1562 1579
1563 // Create the instruction that parameter checks will use. 1580 // Create the instruction that parameter checks will use.
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 selector = new Selector.binaryOperator(const SourceString('|')); 2372 selector = new Selector.binaryOperator(const SourceString('|'));
2356 break; 2373 break;
2357 case "&": 2374 case "&":
2358 case "&=": 2375 case "&=":
2359 selector = new Selector.binaryOperator(const SourceString('&')); 2376 selector = new Selector.binaryOperator(const SourceString('&'));
2360 break; 2377 break;
2361 case "^": 2378 case "^":
2362 case "^=": 2379 case "^=":
2363 selector = new Selector.binaryOperator(const SourceString('^')); 2380 selector = new Selector.binaryOperator(const SourceString('^'));
2364 break; 2381 break;
2382 case "==":
2383 case "!=":
2384 selector = new Selector.binaryOperator(const SourceString('=='));
2385 break;
2386 case "<":
2387 selector = new Selector.binaryOperator(const SourceString('<'));
2388 break;
2389 case "<=":
2390 selector = new Selector.binaryOperator(const SourceString('<='));
2391 break;
2392 case ">":
2393 selector = new Selector.binaryOperator(const SourceString('>'));
2394 break;
2395 case ">=":
2396 selector = new Selector.binaryOperator(const SourceString('>='));
2397 break;
2398 case "===":
2399 pushWithPosition(new HIdentity(left, right), op);
2400 return;
2401 case "!==":
2402 HIdentity eq = new HIdentity(left, right);
2403 add(eq);
2404 pushWithPosition(new HNot(eq), op);
2405 return;
2365 default: 2406 default:
2366 break; 2407 break;
2367 } 2408 }
2368 2409
2369 if (selector != null) { 2410 if (selector != null) {
2370 pushWithPosition( 2411 pushWithPosition(
2371 buildInvokeDynamic(send, selector, left, [right]), 2412 buildInvokeDynamic(send, selector, left, [right]),
2372 op); 2413 op);
2414 if (op.source.stringValue == '!=') {
2415 HBoolify bl = new HBoolify(pop());
2416 add(bl);
2417 pushWithPosition(new HNot(bl), op);
2418 }
2373 return; 2419 return;
2374 } 2420 }
2375 Element element = interceptors.getOperatorInterceptor(op); 2421 Element element = interceptors.getOperatorInterceptor(op);
2376 assert(element != null); 2422 assert(element != null);
2377 HInstruction target = new HStatic(element); 2423 HInstruction target = new HStatic(element);
2378 add(target); 2424 add(target);
2379 switch (op.source.stringValue) { 2425 switch (op.source.stringValue) {
2380 case "==":
2381 pushWithPosition(new HEquals(target, left, right), op);
2382 break;
2383 case "===":
2384 pushWithPosition(new HIdentity(target, left, right), op);
2385 break;
2386 case "!==":
2387 HIdentity eq = new HIdentity(target, left, right);
2388 add(eq);
2389 pushWithPosition(new HNot(eq), op);
2390 break;
2391 case "<":
2392 pushWithPosition(new HLess(target, left, right), op);
2393 break;
2394 case "<=":
2395 pushWithPosition(new HLessEqual(target, left, right), op);
2396 break;
2397 case ">":
2398 pushWithPosition(new HGreater(target, left, right), op);
2399 break;
2400 case ">=":
2401 pushWithPosition(new HGreaterEqual(target, left, right), op);
2402 break;
2403 case "!=":
2404 HEquals eq = new HEquals(target, left, right);
2405 add(eq);
2406 HBoolify bl = new HBoolify(eq);
2407 add(bl);
2408 pushWithPosition(new HNot(bl), op);
2409 break;
2410 default: compiler.unimplemented("SsaBuilder.visitBinary"); 2426 default: compiler.unimplemented("SsaBuilder.visitBinary");
2411 } 2427 }
2412 } 2428 }
2413 2429
2414 HInstruction generateInstanceSendReceiver(Send send) { 2430 HInstruction generateInstanceSendReceiver(Send send) {
2415 assert(Elements.isInstanceSend(send, elements)); 2431 assert(Elements.isInstanceSend(send, elements));
2416 if (send.receiver == null) { 2432 if (send.receiver == null) {
2417 return localsHandler.readThis(); 2433 return localsHandler.readThis();
2418 } 2434 }
2419 visit(send.receiver); 2435 visit(send.receiver);
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
3472 // calling [addStaticSendArgumentsToList]. 3488 // calling [addStaticSendArgumentsToList].
3473 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 3489 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
3474 element.implementation, 3490 element.implementation,
3475 inputs); 3491 inputs);
3476 if (!succeeded) { 3492 if (!succeeded) {
3477 generateWrongArgumentCountError(node, element, node.arguments); 3493 generateWrongArgumentCountError(node, element, node.arguments);
3478 return; 3494 return;
3479 } 3495 }
3480 3496
3481 if (isIdenticalFunction) { 3497 if (isIdenticalFunction) {
3482 pushWithPosition(new HIdentity(target, inputs[1], inputs[2]), node); 3498 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node);
3483 return; 3499 return;
3484 } 3500 }
3485 3501
3486 HInvokeStatic instruction = new HInvokeStatic(inputs); 3502 HInvokeStatic instruction = new HInvokeStatic(inputs);
3487 // TODO(ngeoffray): Only do this if knowing the return type is 3503 // TODO(ngeoffray): Only do this if knowing the return type is
3488 // useful. 3504 // useful.
3489 HType returnType = 3505 HType returnType =
3490 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( 3506 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange(
3491 work.element, element); 3507 work.element, element);
3492 if (returnType != null) instruction.guaranteedType = returnType; 3508 if (returnType != null) instruction.guaranteedType = returnType;
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after
4449 // This must be the final case (otherwise "default" would be invalid), 4465 // This must be the final case (otherwise "default" would be invalid),
4450 // so we don't need to check for fallthrough. 4466 // so we don't need to check for fallthrough.
4451 return; 4467 return;
4452 } 4468 }
4453 4469
4454 // Recursively build the test conditions. Leaves the result on the 4470 // Recursively build the test conditions. Leaves the result on the
4455 // expression stack. 4471 // expression stack.
4456 void buildTests(Link<Node> remainingCases) { 4472 void buildTests(Link<Node> remainingCases) {
4457 // Build comparison for one case expression. 4473 // Build comparison for one case expression.
4458 void left() { 4474 void left() {
4459 Element equalsHelper = interceptors.getEqualsInterceptor();
4460 HInstruction target = new HStatic(equalsHelper);
4461 add(target);
4462 CaseMatch match = remainingCases.head; 4475 CaseMatch match = remainingCases.head;
4463 // TODO(lrn): Move the constant resolution to the resolver, so 4476 // TODO(lrn): Move the constant resolution to the resolver, so
4464 // we can report an error before reaching the backend. 4477 // we can report an error before reaching the backend.
4465 Constant constant = 4478 Constant constant =
4466 compiler.constantHandler.tryCompileNodeWithDefinitions( 4479 compiler.constantHandler.tryCompileNodeWithDefinitions(
4467 match.expression, elements); 4480 match.expression, elements);
4468 if (constant != null) { 4481 if (constant != null) {
4469 stack.add(graph.addConstant(constant)); 4482 stack.add(graph.addConstant(constant));
4470 } else { 4483 } else {
4471 visit(match.expression); 4484 visit(match.expression);
4472 } 4485 }
4473 push(new HEquals(target, pop(), expression)); 4486 push(new HIdentity(pop(), expression));
4474 } 4487 }
4475 4488
4476 // If this is the last expression, just return it. 4489 // If this is the last expression, just return it.
4477 Link<Node> tail = skipLabels(remainingCases.tail); 4490 Link<Node> tail = skipLabels(remainingCases.tail);
4478 if (tail.isEmpty) { 4491 if (tail.isEmpty) {
4479 left(); 4492 left();
4480 return; 4493 return;
4481 } 4494 }
4482 4495
4483 void right() { 4496 void right() {
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
5119 new HSubGraphBlockInformation(elseBranch.graph)); 5132 new HSubGraphBlockInformation(elseBranch.graph));
5120 5133
5121 HBasicBlock conditionStartBlock = conditionBranch.block; 5134 HBasicBlock conditionStartBlock = conditionBranch.block;
5122 conditionStartBlock.setBlockFlow(info, joinBlock); 5135 conditionStartBlock.setBlockFlow(info, joinBlock);
5123 SubGraph conditionGraph = conditionBranch.graph; 5136 SubGraph conditionGraph = conditionBranch.graph;
5124 HIf branch = conditionGraph.end.last; 5137 HIf branch = conditionGraph.end.last;
5125 assert(branch is HIf); 5138 assert(branch is HIf);
5126 branch.blockInformation = conditionStartBlock.blockFlow; 5139 branch.blockInformation = conditionStartBlock.blockFlow;
5127 } 5140 }
5128 } 5141 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698