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

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

Powered by Google App Engine
This is Rietveld 408576698