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

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

Issue 12334088: Stop creating selectors in the SSA builder that were already created by the resolver. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
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 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 stack.add(graph.addConstant(folded)); 2237 stack.add(graph.addConstant(folded));
2238 return; 2238 return;
2239 } 2239 }
2240 } 2240 }
2241 2241
2242 HInvokeDynamicMethod result = 2242 HInvokeDynamicMethod result =
2243 buildInvokeDynamic(node, elements.getSelector(node), operand, []); 2243 buildInvokeDynamic(node, elements.getSelector(node), operand, []);
2244 pushWithPosition(result, node); 2244 pushWithPosition(result, node);
2245 } 2245 }
2246 2246
2247 void visitBinary( 2247 void visitBinary(HInstruction left,
2248 HInstruction left, Operator op, HInstruction right, Send send) { 2248 Operator op,
2249 Selector selector = null; 2249 HInstruction right,
2250 // TODO(ngeoffray): The resolver creates these selectors already 2250 Selector selector,
2251 // but does not put them on the [send] instruction. 2251 Send send) {
2252 switch (op.source.stringValue) { 2252 switch (op.source.stringValue) {
2253 case "+":
2254 case "+=":
2255 case "++":
2256 selector = new Selector.binaryOperator(const SourceString('+'));
2257 break;
2258 case "-":
2259 case "-=":
2260 case "--":
2261 selector = new Selector.binaryOperator(const SourceString('-'));
2262 break;
2263 case "*":
2264 case "*=":
2265 selector = new Selector.binaryOperator(const SourceString('*'));
2266 break;
2267 case "/":
2268 case "/=":
2269 selector = new Selector.binaryOperator(const SourceString('/'));
2270 break;
2271 case "~/":
2272 case "~/=":
2273 selector = new Selector.binaryOperator(const SourceString('~/'));
2274 break;
2275 case "%":
2276 case "%=":
2277 selector = new Selector.binaryOperator(const SourceString('%'));
2278 break;
2279 case "<<":
2280 case "<<=":
2281 selector = new Selector.binaryOperator(const SourceString('<<'));
2282 break;
2283 case ">>":
2284 case ">>=":
2285 selector = new Selector.binaryOperator(const SourceString('>>'));
2286 break;
2287 case "|":
2288 case "|=":
2289 selector = new Selector.binaryOperator(const SourceString('|'));
2290 break;
2291 case "&":
2292 case "&=":
2293 selector = new Selector.binaryOperator(const SourceString('&'));
2294 break;
2295 case "^":
2296 case "^=":
2297 selector = new Selector.binaryOperator(const SourceString('^'));
2298 break;
2299 case "==":
2300 case "!=":
2301 selector = new Selector.binaryOperator(const SourceString('=='));
2302 break;
2303 case "<":
2304 selector = new Selector.binaryOperator(const SourceString('<'));
2305 break;
2306 case "<=":
2307 selector = new Selector.binaryOperator(const SourceString('<='));
2308 break;
2309 case ">":
2310 selector = new Selector.binaryOperator(const SourceString('>'));
2311 break;
2312 case ">=":
2313 selector = new Selector.binaryOperator(const SourceString('>='));
2314 break;
2315 case "===": 2253 case "===":
2316 pushWithPosition(new HIdentity(left, right), op); 2254 pushWithPosition(new HIdentity(left, right), op);
2317 return; 2255 return;
2318 case "!==": 2256 case "!==":
2319 HIdentity eq = new HIdentity(left, right); 2257 HIdentity eq = new HIdentity(left, right);
2320 add(eq); 2258 add(eq);
2321 pushWithPosition(new HNot(eq), op); 2259 pushWithPosition(new HNot(eq), op);
2322 return; 2260 return;
2323 default:
2324 compiler.internalError("Unexpected operator $op", node: op);
2325 break;
2326 } 2261 }
2327 2262
2328 pushWithPosition( 2263 pushWithPosition(
2329 buildInvokeDynamic(send, selector, left, [right]), 2264 buildInvokeDynamic(send, selector, left, [right]),
2330 op); 2265 op);
2331 if (op.source.stringValue == '!=') { 2266 if (op.source.stringValue == '!=') {
2332 pushWithPosition(new HNot(popBoolified()), op); 2267 pushWithPosition(new HNot(popBoolified()), op);
2333 } 2268 }
2334 } 2269 }
2335 2270
(...skipping 16 matching lines...) Expand all
2352 2287
2353 /** 2288 /**
2354 * Returns a set of interceptor classes that contain a member whose 2289 * Returns a set of interceptor classes that contain a member whose
2355 * signature matches the given [selector]. 2290 * signature matches the given [selector].
2356 */ 2291 */
2357 Set<ClassElement> getInterceptedClassesOn(Selector selector) { 2292 Set<ClassElement> getInterceptedClassesOn(Selector selector) {
2358 return backend.getInterceptedClassesOn(selector); 2293 return backend.getInterceptedClassesOn(selector);
2359 } 2294 }
2360 2295
2361 void generateInstanceGetterWithCompiledReceiver(Send send, 2296 void generateInstanceGetterWithCompiledReceiver(Send send,
2297 Selector selector,
2362 HInstruction receiver) { 2298 HInstruction receiver) {
2363 assert(Elements.isInstanceSend(send, elements)); 2299 assert(Elements.isInstanceSend(send, elements));
2364 // TODO(kasperl): This is a convoluted way of checking if we're
2365 // generating code for a compound assignment. If we are, we need
2366 // to get the selector from the mapping for the AST selector node.
2367 Selector selector = (send.asSendSet() == null)
2368 ? elements.getSelector(send)
2369 : elements.getSelector(send.selector);
2370 assert(selector.isGetter()); 2300 assert(selector.isGetter());
2371 SourceString getterName = selector.name; 2301 SourceString getterName = selector.name;
2372 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); 2302 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
2373 2303
2374 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); 2304 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
2375 HInstruction instruction; 2305 HInstruction instruction;
2376 if (interceptedClasses != null) { 2306 if (interceptedClasses != null) {
2377 // If we're using an interceptor class, emit a call to the 2307 // If we're using an interceptor class, emit a call to the
2378 // interceptor method and then the actual dynamic call on the 2308 // interceptor method and then the actual dynamic call on the
2379 // interceptor object. 2309 // interceptor object.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2412 } 2342 }
2413 // TODO(5346): Try to avoid the need for calling [declaration] before 2343 // TODO(5346): Try to avoid the need for calling [declaration] before
2414 // creating an [HStatic]. 2344 // creating an [HStatic].
2415 push(new HStatic(element.declaration)); 2345 push(new HStatic(element.declaration));
2416 if (element.isGetter()) { 2346 if (element.isGetter()) {
2417 push(new HInvokeStatic(<HInstruction>[pop()], HType.UNKNOWN)); 2347 push(new HInvokeStatic(<HInstruction>[pop()], HType.UNKNOWN));
2418 } 2348 }
2419 } 2349 }
2420 } else if (Elements.isInstanceSend(send, elements)) { 2350 } else if (Elements.isInstanceSend(send, elements)) {
2421 HInstruction receiver = generateInstanceSendReceiver(send); 2351 HInstruction receiver = generateInstanceSendReceiver(send);
2422 generateInstanceGetterWithCompiledReceiver(send, receiver); 2352 generateInstanceGetterWithCompiledReceiver(
2353 send, elements.getSelector(send), receiver);
2423 } else if (Elements.isStaticOrTopLevelFunction(element)) { 2354 } else if (Elements.isStaticOrTopLevelFunction(element)) {
2424 // TODO(5346): Try to avoid the need for calling [declaration] before 2355 // TODO(5346): Try to avoid the need for calling [declaration] before
2425 // creating an [HStatic]. 2356 // creating an [HStatic].
2426 push(new HStatic(element.declaration)); 2357 push(new HStatic(element.declaration));
2427 // TODO(ahe): This should be registered in codegen. 2358 // TODO(ahe): This should be registered in codegen.
2428 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 2359 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
2429 } else if (Elements.isErroneousElement(element)) { 2360 } else if (Elements.isErroneousElement(element)) {
2430 // An erroneous element indicates an unresolved static getter. 2361 // An erroneous element indicates an unresolved static getter.
2431 generateThrowNoSuchMethod(send, 2362 generateThrowNoSuchMethod(send,
2432 getTargetName(element, 'get'), 2363 getTargetName(element, 'get'),
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 DartType type = elements.getType(typeAnnotation); 2636 DartType type = elements.getType(typeAnnotation);
2706 HInstruction converted = expression.convertType( 2637 HInstruction converted = expression.convertType(
2707 compiler, type, HTypeConversion.CAST_TYPE_CHECK); 2638 compiler, type, HTypeConversion.CAST_TYPE_CHECK);
2708 if (converted != expression) add(converted); 2639 if (converted != expression) add(converted);
2709 stack.add(converted); 2640 stack.add(converted);
2710 } else { 2641 } else {
2711 visit(node.receiver); 2642 visit(node.receiver);
2712 visit(node.argumentsNode); 2643 visit(node.argumentsNode);
2713 var right = pop(); 2644 var right = pop();
2714 var left = pop(); 2645 var left = pop();
2715 visitBinary(left, op, right, node); 2646 visitBinary(left, op, right, elements.getSelector(node), node);
2716 } 2647 }
2717 } 2648 }
2718 2649
2719 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { 2650 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) {
2720 Selector selector = elements.getSelector(node); 2651 Selector selector = elements.getSelector(node);
2721 if (selector.namedArgumentCount == 0) { 2652 if (selector.namedArgumentCount == 0) {
2722 addGenericSendArgumentsToList(node.arguments, list); 2653 addGenericSendArgumentsToList(node.arguments, list);
2723 } else { 2654 } else {
2724 // Visit positional arguments and add them to the list. 2655 // Visit positional arguments and add them to the list.
2725 Link<Node> arguments = node.arguments; 2656 Link<Node> arguments = node.arguments;
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
3112 Element element = elements[node]; 3043 Element element = elements[node];
3113 if (element != null && identical(element, currentElement)) { 3044 if (element != null && identical(element, currentElement)) {
3114 graph.isRecursiveMethod = true; 3045 graph.isRecursiveMethod = true;
3115 } 3046 }
3116 super.visitSend(node); 3047 super.visitSend(node);
3117 } 3048 }
3118 3049
3119 visitSuperSend(Send node) { 3050 visitSuperSend(Send node) {
3120 Selector selector = elements.getSelector(node); 3051 Selector selector = elements.getSelector(node);
3121 Element element = elements[node]; 3052 Element element = elements[node];
3122 if (element == null) return generateSuperNoSuchMethodSend(node); 3053 if (Elements.isUnresolved(element)) {
3054 return generateSuperNoSuchMethodSend(node);
3055 }
3123 // TODO(5346): Try to avoid the need for calling [declaration] before 3056 // TODO(5346): Try to avoid the need for calling [declaration] before
3124 // creating an [HStatic]. 3057 // creating an [HStatic].
3125 HInstruction target = new HStatic(element.declaration); 3058 HInstruction target = new HStatic(element.declaration);
3126 HInstruction context = localsHandler.readThis(); 3059 HInstruction context = localsHandler.readThis();
3127 add(target); 3060 add(target);
3128 var inputs = <HInstruction>[target, context]; 3061 var inputs = <HInstruction>[target, context];
3129 if (node.isPropertyAccess) { 3062 if (node.isPropertyAccess) {
3130 push(new HInvokeSuper(inputs)); 3063 push(new HInvokeSuper(inputs));
3131 } else if (element.isFunction() || element.isGenerativeConstructor()) { 3064 } else if (element.isFunction() || element.isGenerativeConstructor()) {
3132 // TODO(5347): Try to avoid the need for calling [implementation] before 3065 // TODO(5347): Try to avoid the need for calling [implementation] before
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
3619 bool isPrefix = !node.isPostfix; 3552 bool isPrefix = !node.isPostfix;
3620 if (isCompoundAssignment) { 3553 if (isCompoundAssignment) {
3621 value = pop(); 3554 value = pop();
3622 index = pop(); 3555 index = pop();
3623 } else { 3556 } else {
3624 index = pop(); 3557 index = pop();
3625 value = graph.addConstantInt(1, constantSystem); 3558 value = graph.addConstantInt(1, constantSystem);
3626 } 3559 }
3627 3560
3628 HInvokeDynamicMethod left = buildInvokeDynamic( 3561 HInvokeDynamicMethod left = buildInvokeDynamic(
3629 node, new Selector.index(), receiver, [index]); 3562 node,
3563 elements.getGetterSelectorInComplexSendSet(node),
3564 receiver,
3565 <HInstruction>[index]);
3630 add(left); 3566 add(left);
3631 visitBinary(left, op, value, node); 3567 visitBinary(left, op, value,
3568 elements.getOperatorSelectorInComplexSendSet(node), node);
3632 value = pop(); 3569 value = pop();
3633 HInvokeDynamicMethod assign = buildInvokeDynamic( 3570 HInvokeDynamicMethod assign = buildInvokeDynamic(
3634 node, new Selector.indexSet(), receiver, [index, value]); 3571 node, elements.getSelector(node), receiver, [index, value]);
3635 add(assign); 3572 add(assign);
3636 if (isPrefix) { 3573 if (isPrefix) {
3637 stack.add(value); 3574 stack.add(value);
3638 } else { 3575 } else {
3639 stack.add(left); 3576 stack.add(left);
3640 } 3577 }
3641 } 3578 }
3642 } else if (const SourceString("=") == op.source) { 3579 } else if (const SourceString("=") == op.source) {
3643 Link<Node> link = node.arguments; 3580 Link<Node> link = node.arguments;
3644 assert(!link.isEmpty && link.tail.isEmpty); 3581 assert(!link.isEmpty && link.tail.isEmpty);
3645 visit(link.head); 3582 visit(link.head);
3646 HInstruction value = pop(); 3583 HInstruction value = pop();
3647 generateSetter(node, element, value); 3584 generateSetter(node, element, value);
3648 } else if (identical(op.source.stringValue, "is")) { 3585 } else if (identical(op.source.stringValue, "is")) {
3649 compiler.internalError("is-operator as SendSet", node: op); 3586 compiler.internalError("is-operator as SendSet", node: op);
3650 } else { 3587 } else {
3651 assert(const SourceString("++") == op.source || 3588 assert(const SourceString("++") == op.source ||
3652 const SourceString("--") == op.source || 3589 const SourceString("--") == op.source ||
3653 node.assignmentOperator.source.stringValue.endsWith("=")); 3590 node.assignmentOperator.source.stringValue.endsWith("="));
3654 bool isCompoundAssignment = !node.arguments.isEmpty; 3591 bool isCompoundAssignment = !node.arguments.isEmpty;
3655 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. 3592 bool isPrefix = !node.isPostfix; // Compound assignments are prefix.
3656 3593
3657 // [receiver] is only used if the node is an instance send. 3594 // [receiver] is only used if the node is an instance send.
3658 HInstruction receiver = null; 3595 HInstruction receiver = null;
3659 if (Elements.isInstanceSend(node, elements)) { 3596 if (Elements.isInstanceSend(node, elements)) {
3660 receiver = generateInstanceSendReceiver(node); 3597 receiver = generateInstanceSendReceiver(node);
3661 generateInstanceGetterWithCompiledReceiver(node, receiver); 3598 generateInstanceGetterWithCompiledReceiver(
3599 node, elements.getGetterSelectorInComplexSendSet(node), receiver);
3662 } else { 3600 } else {
3663 generateGetter(node, elements[node.selector]); 3601 generateGetter(node, elements[node.selector]);
3664 } 3602 }
3665 HInstruction left = pop(); 3603 HInstruction left = pop();
3666 HInstruction right; 3604 HInstruction right;
3667 if (isCompoundAssignment) { 3605 if (isCompoundAssignment) {
3668 visit(node.argumentsNode); 3606 visit(node.argumentsNode);
3669 right = pop(); 3607 right = pop();
3670 } else { 3608 } else {
3671 right = graph.addConstantInt(1, constantSystem); 3609 right = graph.addConstantInt(1, constantSystem);
3672 } 3610 }
3673 visitBinary(left, op, right, node); 3611 visitBinary(left, op, right,
3612 elements.getOperatorSelectorInComplexSendSet(node), node);
3674 HInstruction operation = pop(); 3613 HInstruction operation = pop();
3675 assert(operation != null); 3614 assert(operation != null);
3676 if (Elements.isInstanceSend(node, elements)) { 3615 if (Elements.isInstanceSend(node, elements)) {
3677 assert(receiver != null); 3616 assert(receiver != null);
3678 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); 3617 generateInstanceSetterWithCompiledReceiver(node, receiver, operation);
3679 } else { 3618 } else {
3680 assert(receiver == null); 3619 assert(receiver == null);
3681 generateSetter(node, element, operation); 3620 generateSetter(node, element, operation);
3682 } 3621 }
3683 if (!isPrefix) { 3622 if (!isPrefix) {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3909 // Generate a structure equivalent to: 3848 // Generate a structure equivalent to:
3910 // Iterator<E> $iter = <iterable>.iterator; 3849 // Iterator<E> $iter = <iterable>.iterator;
3911 // while ($iter.moveNext()) { 3850 // while ($iter.moveNext()) {
3912 // E <declaredIdentifier> = $iter.current; 3851 // E <declaredIdentifier> = $iter.current;
3913 // <body> 3852 // <body>
3914 // } 3853 // }
3915 3854
3916 // The iterator is shared between initializer, condition and body. 3855 // The iterator is shared between initializer, condition and body.
3917 HInstruction iterator; 3856 HInstruction iterator;
3918 void buildInitializer() { 3857 void buildInitializer() {
3919 SourceString iteratorName = const SourceString("iterator"); 3858 Selector selector = elements.getIteratorSelector(node);
3920 Selector selector =
3921 new Selector.getter(iteratorName, currentElement.getLibrary());
3922 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); 3859 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
3923 visit(node.expression); 3860 visit(node.expression);
3924 HInstruction receiver = pop(); 3861 HInstruction receiver = pop();
3925 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); 3862 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
3926 if (interceptedClasses == null) { 3863 if (interceptedClasses == null) {
3927 iterator = 3864 iterator =
3928 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter); 3865 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter);
3929 } else { 3866 } else {
3930 HInterceptor interceptor = 3867 HInterceptor interceptor =
3931 invokeInterceptor(interceptedClasses, receiver, null); 3868 invokeInterceptor(interceptedClasses, receiver, null);
3932 iterator = 3869 iterator =
3933 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter); 3870 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter);
3934 // Add the receiver as an argument to the getter call on the 3871 // Add the receiver as an argument to the getter call on the
3935 // interceptor. 3872 // interceptor.
3936 iterator.inputs.add(receiver); 3873 iterator.inputs.add(receiver);
3937 } 3874 }
3938 add(iterator); 3875 add(iterator);
3939 } 3876 }
3940 HInstruction buildCondition() { 3877 HInstruction buildCondition() {
3941 SourceString name = const SourceString('moveNext'); 3878 Selector selector = elements.getMoveNextSelector(node);
3942 Selector selector = new Selector.call(
3943 name, currentElement.getLibrary(), 0);
3944 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); 3879 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator]));
3945 return popBoolified(); 3880 return popBoolified();
3946 } 3881 }
3947 void buildBody() { 3882 void buildBody() {
3948 SourceString name = const SourceString('current'); 3883 Selector call = elements.getCurrentSelector(node);
3949 Selector call = new Selector.getter(name, currentElement.getLibrary());
3950 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); 3884 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call);
3951 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter)); 3885 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter));
3952 3886
3953 Element variable; 3887 Element variable;
3954 if (node.declaredIdentifier.asSend() != null) { 3888 if (node.declaredIdentifier.asSend() != null) {
3955 variable = elements[node.declaredIdentifier]; 3889 variable = elements[node.declaredIdentifier];
3956 } else { 3890 } else {
3957 assert(node.declaredIdentifier.asVariableDefinitions() != null); 3891 assert(node.declaredIdentifier.asVariableDefinitions() != null);
3958 VariableDefinitions variableDefinitions = node.declaredIdentifier; 3892 VariableDefinitions variableDefinitions = node.declaredIdentifier;
3959 variable = elements[variableDefinitions.definitions.nodes.head]; 3893 variable = elements[variableDefinitions.definitions.nodes.head];
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
5031 new HSubGraphBlockInformation(elseBranch.graph)); 4965 new HSubGraphBlockInformation(elseBranch.graph));
5032 4966
5033 HBasicBlock conditionStartBlock = conditionBranch.block; 4967 HBasicBlock conditionStartBlock = conditionBranch.block;
5034 conditionStartBlock.setBlockFlow(info, joinBlock); 4968 conditionStartBlock.setBlockFlow(info, joinBlock);
5035 SubGraph conditionGraph = conditionBranch.graph; 4969 SubGraph conditionGraph = conditionBranch.graph;
5036 HIf branch = conditionGraph.end.last; 4970 HIf branch = conditionGraph.end.last;
5037 assert(branch is HIf); 4971 assert(branch is HIf);
5038 branch.blockInformation = conditionStartBlock.blockFlow; 4972 branch.blockInformation = conditionStartBlock.blockFlow;
5039 } 4973 }
5040 } 4974 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698