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

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

Issue 24282005: Move compile-time constant registrations to the backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status Created 7 years, 2 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 } else { 50 } else {
51 compiler.internalErrorOnElement(element, 51 compiler.internalErrorOnElement(element,
52 'unexpected element kind $kind'); 52 'unexpected element kind $kind');
53 } 53 }
54 assert(graph.isValid()); 54 assert(graph.isValid());
55 if (!identical(kind, ElementKind.FIELD)) { 55 if (!identical(kind, ElementKind.FIELD)) {
56 FunctionElement function = element; 56 FunctionElement function = element;
57 FunctionSignature signature = function.computeSignature(compiler); 57 FunctionSignature signature = function.computeSignature(compiler);
58 signature.forEachOptionalParameter((Element parameter) { 58 signature.forEachOptionalParameter((Element parameter) {
59 // This ensures the default value will be computed. 59 // This ensures the default value will be computed.
60 builder.compileVariable(parameter); 60 Constant constant =
61 compiler.constantHandler.getConstantForVariable(parameter);
62 backend.registerCompileTimeConstant(constant, work.resolutionTree);
63 compiler.constantHandler.addCompileTimeConstantForEmission(
64 constant);
61 }); 65 });
62 } 66 }
63
64 if (compiler.tracer.enabled) { 67 if (compiler.tracer.enabled) {
65 String name; 68 String name;
66 if (element.isMember()) { 69 if (element.isMember()) {
67 String className = element.getEnclosingClass().name.slowToString(); 70 String className = element.getEnclosingClass().name.slowToString();
68 String memberName = element.name.slowToString(); 71 String memberName = element.name.slowToString();
69 name = "$className.$memberName"; 72 name = "$className.$memberName";
70 if (element.isGenerativeConstructorBody()) { 73 if (element.isGenerativeConstructorBody()) {
71 name = "$name (body)"; 74 name = "$name (body)";
72 } 75 }
73 } else { 76 } else {
(...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 949
947 bool inTryStatement = false; 950 bool inTryStatement = false;
948 int loopNesting = 0; 951 int loopNesting = 0;
949 952
950 HBasicBlock get current => _current; 953 HBasicBlock get current => _current;
951 void set current(c) { 954 void set current(c) {
952 isReachable = c != null; 955 isReachable = c != null;
953 _current = c; 956 _current = c;
954 } 957 }
955 958
956 /** 959 Constant getConstantForNode(Node node) {
957 * Compiles compile-time constants. Never returns [:null:]. If the 960 ConstantHandler handler = compiler.constantHandler;
958 * initial value is not a compile-time constants, it reports an 961 Constant constant = elements.getConstant(node);
959 * internal error. 962 assert(invariant(node, constant != null,
960 */ 963 message: 'No constant computed for $node'));
961 Constant compileConstant(VariableElement element) { 964 return constant;
962 return compiler.constantHandler.compileConstant(element);
963 } 965 }
964 966
965 Constant compileVariable(VariableElement element) { 967 HInstruction addConstant(Node node) {
966 return compiler.constantHandler.compileVariable(element); 968 return graph.addConstant(getConstantForNode(node), compiler);
967 } 969 }
968 970
969 bool isLazilyInitialized(VariableElement element) { 971 bool isLazilyInitialized(VariableElement element) {
970 Constant initialValue = compileVariable(element); 972 Constant initialValue =
973 compiler.constantHandler.getConstantForVariable(element);
971 return initialValue == null; 974 return initialValue == null;
972 } 975 }
973 976
974 HType cachedTypeOfThis; 977 HType cachedTypeOfThis;
975 978
976 HType getTypeOfThis() { 979 HType getTypeOfThis() {
977 HType result = cachedTypeOfThis; 980 HType result = cachedTypeOfThis;
978 if (result == null) { 981 if (result == null) {
979 Element element = localsHandler.closureData.thisElement; 982 Element element = localsHandler.closureData.thisElement;
980 ClassElement cls = element.enclosingElement.getEnclosingClass(); 983 ClassElement cls = element.enclosingElement.getEnclosingClass();
(...skipping 1635 matching lines...) Expand 10 before | Expand all | Expand 10 after
2616 assert(selector.isGetter()); 2619 assert(selector.isGetter());
2617 pushInvokeDynamic(send, selector, [receiver]); 2620 pushInvokeDynamic(send, selector, [receiver]);
2618 } 2621 }
2619 2622
2620 void generateGetter(Send send, Element element) { 2623 void generateGetter(Send send, Element element) {
2621 if (Elements.isStaticOrTopLevelField(element)) { 2624 if (Elements.isStaticOrTopLevelField(element)) {
2622 Constant value; 2625 Constant value;
2623 if (element.isField() && !element.isAssignable()) { 2626 if (element.isField() && !element.isAssignable()) {
2624 // A static final or const. Get its constant value and inline it if 2627 // A static final or const. Get its constant value and inline it if
2625 // the value can be compiled eagerly. 2628 // the value can be compiled eagerly.
2626 value = compileVariable(element); 2629 value = compiler.constantHandler.getConstantForVariable(element);
2627 } 2630 }
2628 if (value != null) { 2631 if (value != null) {
2629 HInstruction instruction = graph.addConstant(value, compiler); 2632 HInstruction instruction = graph.addConstant(value, compiler);
2630 stack.add(instruction); 2633 stack.add(instruction);
2631 // The inferrer may have found a better type than the constant 2634 // The inferrer may have found a better type than the constant
2632 // handler in the case of lists, because the constant handler 2635 // handler in the case of lists, because the constant handler
2633 // does not look at elements in the list. 2636 // does not look at elements in the list.
2634 HType type = new HType.inferredTypeForElement(element, compiler); 2637 HType type = new HType.inferredTypeForElement(element, compiler);
2635 if (!type.isUnknown()) instruction.instructionType = type; 2638 if (!type.isUnknown()) instruction.instructionType = type;
2636 } else if (element.isField() && isLazilyInitialized(element)) { 2639 } else if (element.isField() && isLazilyInitialized(element)) {
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
2943 // of instructions, in an order that can be shared with 2946 // of instructions, in an order that can be shared with
2944 // selectors with the same named arguments. 2947 // selectors with the same named arguments.
2945 List<SourceString> orderedNames = selector.getOrderedNamedArguments(); 2948 List<SourceString> orderedNames = selector.getOrderedNamedArguments();
2946 for (SourceString name in orderedNames) { 2949 for (SourceString name in orderedNames) {
2947 list.add(instructions[name]); 2950 list.add(instructions[name]);
2948 } 2951 }
2949 } 2952 }
2950 } 2953 }
2951 2954
2952 HInstruction handleConstantForOptionalParameter(Element parameter) { 2955 HInstruction handleConstantForOptionalParameter(Element parameter) {
2953 Constant constant = compileConstant(parameter); 2956 Constant constant =
2957 compiler.constantHandler.getConstantForVariable(parameter);
2958 assert(invariant(parameter, constant != null,
2959 message: 'No constant computed for $parameter'));
2954 return graph.addConstant(constant, compiler); 2960 return graph.addConstant(constant, compiler);
2955 } 2961 }
2956 2962
2957 /** 2963 /**
2958 * Returns true if the arguments were compatible with the function signature. 2964 * Returns true if the arguments were compatible with the function signature.
2959 * 2965 *
2960 * Invariant: [element] must be an implementation element. 2966 * Invariant: [element] must be an implementation element.
2961 */ 2967 */
2962 bool addStaticSendArgumentsToList(Selector selector, 2968 bool addStaticSendArgumentsToList(Selector selector,
2963 Link<Node> arguments, 2969 Link<Node> arguments,
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
3661 HConstant addConstantString(Node node, String string) { 3667 HConstant addConstantString(Node node, String string) {
3662 DartString dartString = new DartString.literal(string); 3668 DartString dartString = new DartString.literal(string);
3663 Constant constant = constantSystem.createString(dartString, node); 3669 Constant constant = constantSystem.createString(dartString, node);
3664 return graph.addConstant(constant, compiler); 3670 return graph.addConstant(constant, compiler);
3665 } 3671 }
3666 3672
3667 visitTypeReferenceSend(Send node) { 3673 visitTypeReferenceSend(Send node) {
3668 Element element = elements[node]; 3674 Element element = elements[node];
3669 if (element.isClass() || element.isTypedef()) { 3675 if (element.isClass() || element.isTypedef()) {
3670 // TODO(karlklose): add type representation 3676 // TODO(karlklose): add type representation
3671 ConstantHandler handler = compiler.constantHandler; 3677 stack.add(addConstant(node));
3672 Constant constant = handler.compileNodeWithDefinitions(node, elements);
3673 stack.add(graph.addConstant(constant, compiler));
3674 } else if (element.isTypeVariable()) { 3678 } else if (element.isTypeVariable()) {
3675 HInstruction value = 3679 HInstruction value =
3676 addTypeVariableReference(element.computeType(compiler)); 3680 addTypeVariableReference(element.computeType(compiler));
3677 pushInvokeStatic(node, 3681 pushInvokeStatic(node,
3678 backend.getRuntimeTypeToString(), 3682 backend.getRuntimeTypeToString(),
3679 [value], 3683 [value],
3680 backend.stringType); 3684 backend.stringType);
3681 pushInvokeStatic(node, 3685 pushInvokeStatic(node,
3682 backend.getCreateRuntimeType(), 3686 backend.getCreateRuntimeType(),
3683 [pop()]); 3687 [pop()]);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3794 ErroneousElement error = element; 3798 ErroneousElement error = element;
3795 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR.error) { 3799 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR.error) {
3796 generateThrowNoSuchMethod(node.send, 3800 generateThrowNoSuchMethod(node.send,
3797 getTargetName(error, 'constructor'), 3801 getTargetName(error, 'constructor'),
3798 argumentNodes: node.send.arguments); 3802 argumentNodes: node.send.arguments);
3799 } else { 3803 } else {
3800 Message message = error.messageKind.message(error.messageArguments); 3804 Message message = error.messageKind.message(error.messageArguments);
3801 generateRuntimeError(node.send, message.toString()); 3805 generateRuntimeError(node.send, message.toString());
3802 } 3806 }
3803 } else if (node.isConst()) { 3807 } else if (node.isConst()) {
3804 ConstantHandler handler = compiler.constantHandler; 3808 stack.add(addConstant(node));
3805 Constant constant = handler.compileNodeWithDefinitions(node, elements);
3806 stack.add(graph.addConstant(constant, compiler));
3807 if (isSymbolConstructor) { 3809 if (isSymbolConstructor) {
3808 ConstructedConstant symbol = constant; 3810 ConstructedConstant symbol = elements.getConstant(node);
3809 StringConstant stringConstant = symbol.fields.single; 3811 StringConstant stringConstant = symbol.fields.single;
3810 String nameString = stringConstant.toDartString().slowToString(); 3812 String nameString = stringConstant.toDartString().slowToString();
3811 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements); 3813 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements);
3812 } 3814 }
3813 } else { 3815 } else {
3814 handleNewSend(node); 3816 handleNewSend(node);
3815 } 3817 }
3816 } 3818 }
3817 3819
3818 void pushInvokeDynamic(Node node, 3820 void pushInvokeDynamic(Node node,
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
4114 4116
4115 void visitLiteralBool(LiteralBool node) { 4117 void visitLiteralBool(LiteralBool node) {
4116 stack.add(graph.addConstantBool(node.value, compiler)); 4118 stack.add(graph.addConstantBool(node.value, compiler));
4117 } 4119 }
4118 4120
4119 void visitLiteralString(LiteralString node) { 4121 void visitLiteralString(LiteralString node) {
4120 stack.add(graph.addConstantString(node.dartString, node, compiler)); 4122 stack.add(graph.addConstantString(node.dartString, node, compiler));
4121 } 4123 }
4122 4124
4123 void visitLiteralSymbol(LiteralSymbol node) { 4125 void visitLiteralSymbol(LiteralSymbol node) {
4124 ConstantHandler handler = compiler.constantHandler; 4126 stack.add(addConstant(node));
4125 ConstructedConstant constant = 4127 compiler.enqueuer.codegen.registerConstSymbol(
4126 handler.compileNodeWithDefinitions(node, elements); 4128 node.slowNameString, elements);
4127 stack.add(graph.addConstant(constant, compiler));
4128 compiler.enqueuer.codegen.registerConstSymbol(node.slowNameString, elements) ;
4129 } 4129 }
4130 4130
4131 void visitStringJuxtaposition(StringJuxtaposition node) { 4131 void visitStringJuxtaposition(StringJuxtaposition node) {
4132 if (!node.isInterpolation) { 4132 if (!node.isInterpolation) {
4133 // This is a simple string with no interpolations. 4133 // This is a simple string with no interpolations.
4134 stack.add(graph.addConstantString(node.dartString, node, compiler)); 4134 stack.add(graph.addConstantString(node.dartString, node, compiler));
4135 return; 4135 return;
4136 } 4136 }
4137 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); 4137 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
4138 stringBuilder.visit(node); 4138 stringBuilder.visit(node);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4192 closeAndGotoExit(new HThrow(exception, isRethrow: true)); 4192 closeAndGotoExit(new HThrow(exception, isRethrow: true));
4193 } 4193 }
4194 4194
4195 visitReturn(Return node) { 4195 visitReturn(Return node) {
4196 if (identical(node.getBeginToken().stringValue, 'native')) { 4196 if (identical(node.getBeginToken().stringValue, 'native')) {
4197 native.handleSsaNative(this, node.expression); 4197 native.handleSsaNative(this, node.expression);
4198 return; 4198 return;
4199 } 4199 }
4200 HInstruction value; 4200 HInstruction value;
4201 if (node.isRedirectingFactoryBody) { 4201 if (node.isRedirectingFactoryBody) {
4202 FunctionElement element = elements[node.expression]; 4202 FunctionElement element = elements[node.expression].implementation;
4203 FunctionElement function = currentElement; 4203 FunctionElement function = currentElement;
4204 List<HInstruction> inputs = <HInstruction>[]; 4204 List<HInstruction> inputs = <HInstruction>[];
4205 FunctionSignature calleeSignature = element.functionSignature; 4205 FunctionSignature calleeSignature = element.functionSignature;
4206 FunctionSignature callerSignature = function.functionSignature; 4206 FunctionSignature callerSignature = function.functionSignature;
4207 callerSignature.forEachRequiredParameter((Element element) { 4207 callerSignature.forEachRequiredParameter((Element element) {
4208 inputs.add(localsHandler.readLocal(element)); 4208 inputs.add(localsHandler.readLocal(element));
4209 }); 4209 });
4210 List<Element> calleeOptionals = 4210 List<Element> calleeOptionals =
4211 calleeSignature.orderedOptionalParameters; 4211 calleeSignature.orderedOptionalParameters;
4212 List<Element> callerOptionals = 4212 List<Element> callerOptionals =
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
4276 visitSendSet(definition); 4276 visitSendSet(definition);
4277 pop(); // Discard value. 4277 pop(); // Discard value.
4278 } 4278 }
4279 } 4279 }
4280 } 4280 }
4281 4281
4282 visitLiteralList(LiteralList node) { 4282 visitLiteralList(LiteralList node) {
4283 HInstruction instruction; 4283 HInstruction instruction;
4284 4284
4285 if (node.isConst()) { 4285 if (node.isConst()) {
4286 ConstantHandler handler = compiler.constantHandler; 4286 instruction = addConstant(node);
4287 Constant constant = handler.compileNodeWithDefinitions(node, elements);
4288 instruction = graph.addConstant(constant, compiler);
4289 } else { 4287 } else {
4290 List<HInstruction> inputs = <HInstruction>[]; 4288 List<HInstruction> inputs = <HInstruction>[];
4291 for (Link<Node> link = node.elements.nodes; 4289 for (Link<Node> link = node.elements.nodes;
4292 !link.isEmpty; 4290 !link.isEmpty;
4293 link = link.tail) { 4291 link = link.tail) {
4294 visit(link.head); 4292 visit(link.head);
4295 inputs.add(pop()); 4293 inputs.add(pop());
4296 } 4294 }
4297 instruction = buildLiteralList(inputs); 4295 instruction = buildLiteralList(inputs);
4298 add(instruction); 4296 add(instruction);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
4475 entryBlock.setBlockFlow( 4473 entryBlock.setBlockFlow(
4476 new HLabeledBlockInformation(new HSubGraphBlockInformation(bodyGraph), 4474 new HLabeledBlockInformation(new HSubGraphBlockInformation(bodyGraph),
4477 handler.labels()), 4475 handler.labels()),
4478 joinBlock); 4476 joinBlock);
4479 } 4477 }
4480 handler.close(); 4478 handler.close();
4481 } 4479 }
4482 4480
4483 visitLiteralMap(LiteralMap node) { 4481 visitLiteralMap(LiteralMap node) {
4484 if (node.isConst()) { 4482 if (node.isConst()) {
4485 ConstantHandler handler = compiler.constantHandler; 4483 stack.add(addConstant(node));
4486 Constant constant = handler.compileNodeWithDefinitions(node, elements);
4487 stack.add(graph.addConstant(constant, compiler));
4488 return; 4484 return;
4489 } 4485 }
4490 List<HInstruction> inputs = <HInstruction>[]; 4486 List<HInstruction> inputs = <HInstruction>[];
4491 for (Link<Node> link = node.entries.nodes; 4487 for (Link<Node> link = node.entries.nodes;
4492 !link.isEmpty; 4488 !link.isEmpty;
4493 link = link.tail) { 4489 link = link.tail) {
4494 visit(link.head); 4490 visit(link.head);
4495 inputs.add(pop()); 4491 inputs.add(pop());
4496 inputs.add(pop()); 4492 inputs.add(pop());
4497 } 4493 }
(...skipping 17 matching lines...) Expand all
4515 // First check whether all case expressions are compile-time constants, 4511 // First check whether all case expressions are compile-time constants,
4516 // and all have the same type that doesn't override operator==. 4512 // and all have the same type that doesn't override operator==.
4517 // TODO(lrn): Move the constant resolution to the resolver, so 4513 // TODO(lrn): Move the constant resolution to the resolver, so
4518 // we can report an error before reaching the backend. 4514 // we can report an error before reaching the backend.
4519 DartType firstConstantType = null; 4515 DartType firstConstantType = null;
4520 bool failure = false; 4516 bool failure = false;
4521 for (SwitchCase switchCase in node.cases) { 4517 for (SwitchCase switchCase in node.cases) {
4522 for (Node labelOrCase in switchCase.labelsAndCases) { 4518 for (Node labelOrCase in switchCase.labelsAndCases) {
4523 if (labelOrCase is CaseMatch) { 4519 if (labelOrCase is CaseMatch) {
4524 CaseMatch match = labelOrCase; 4520 CaseMatch match = labelOrCase;
4525 Constant constant = 4521 Constant constant = getConstantForNode(match.expression);
4526 compiler.constantHandler.compileNodeWithDefinitions(
4527 match.expression, elements, isConst: true);
4528 if (firstConstantType == null) { 4522 if (firstConstantType == null) {
4529 firstConstantType = constant.computeType(compiler); 4523 firstConstantType = constant.computeType(compiler);
4530 if (nonPrimitiveTypeOverridesEquals(constant)) { 4524 if (nonPrimitiveTypeOverridesEquals(constant)) {
4531 compiler.reportFatalError( 4525 compiler.reportFatalError(
4532 match.expression, 4526 match.expression,
4533 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS); 4527 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS);
4534 failure = true; 4528 failure = true;
4535 } 4529 }
4536 } 4530 }
4537 constants[labelOrCase] = constant; 4531 constants[labelOrCase] = constant;
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
5554 new HSubGraphBlockInformation(elseBranch.graph)); 5548 new HSubGraphBlockInformation(elseBranch.graph));
5555 5549
5556 HBasicBlock conditionStartBlock = conditionBranch.block; 5550 HBasicBlock conditionStartBlock = conditionBranch.block;
5557 conditionStartBlock.setBlockFlow(info, joinBlock); 5551 conditionStartBlock.setBlockFlow(info, joinBlock);
5558 SubGraph conditionGraph = conditionBranch.graph; 5552 SubGraph conditionGraph = conditionBranch.graph;
5559 HIf branch = conditionGraph.end.last; 5553 HIf branch = conditionGraph.end.last;
5560 assert(branch is HIf); 5554 assert(branch is HIf);
5561 branch.blockInformation = conditionStartBlock.blockFlow; 5555 branch.blockInformation = conditionStartBlock.blockFlow;
5562 } 5556 }
5563 } 5557 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698