Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/compiler/common-operator.h" | 9 #include "src/compiler/common-operator.h" |
| 10 #include "src/compiler/graph-inl.h" | 10 #include "src/compiler/graph-inl.h" |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 578 SetOutput(node, 0); | 578 SetOutput(node, 0); |
| 579 if (lower()) lowering->DoStoreField(node); | 579 if (lower()) lowering->DoStoreField(node); |
| 580 break; | 580 break; |
| 581 } | 581 } |
| 582 case IrOpcode::kLoadElement: { | 582 case IrOpcode::kLoadElement: { |
| 583 ElementAccess access = ElementAccessOf(node->op()); | 583 ElementAccess access = ElementAccessOf(node->op()); |
| 584 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); | 584 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); |
| 585 ProcessInput(node, 1, kMachInt32); // element index | 585 ProcessInput(node, 1, kMachInt32); // element index |
| 586 ProcessInput(node, 2, kMachInt32); // length | 586 ProcessInput(node, 2, kMachInt32); // length |
| 587 ProcessRemainingInputs(node, 3); | 587 ProcessRemainingInputs(node, 3); |
| 588 SetOutput(node, access.machine_type); | 588 // Tagged overrides everything if we have to do a typed array bounds |
| 589 if (lower()) lowering->DoLoadElement(node); | 589 // check, because we may need to return undefined then. |
| 590 MachineType output_type = | |
| 591 (access.bounds_check == kTypedArrayBoundsCheck && | |
| 592 (use & kRepTagged)) | |
| 593 ? kMachAnyTagged | |
| 594 : access.machine_type; | |
| 595 SetOutput(node, output_type); | |
| 596 if (lower()) lowering->DoLoadElement(node, output_type); | |
| 590 break; | 597 break; |
| 591 } | 598 } |
| 592 case IrOpcode::kStoreElement: { | 599 case IrOpcode::kStoreElement: { |
| 593 ElementAccess access = ElementAccessOf(node->op()); | 600 ElementAccess access = ElementAccessOf(node->op()); |
| 594 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); | 601 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); |
| 595 ProcessInput(node, 1, kMachInt32); // element index | 602 ProcessInput(node, 1, kMachInt32); // element index |
| 596 ProcessInput(node, 2, kMachInt32); // length | 603 ProcessInput(node, 2, kMachInt32); // length |
| 597 ProcessInput(node, 3, access.machine_type); | 604 ProcessInput(node, 3, access.machine_type); |
| 598 ProcessRemainingInputs(node, 4); | 605 ProcessRemainingInputs(node, 4); |
| 599 SetOutput(node, 0); | 606 SetOutput(node, 0); |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 index = graph()->NewNode(machine()->Int32Mul(), | 866 index = graph()->NewNode(machine()->Int32Mul(), |
| 860 jsgraph()->Int32Constant(element_size), index); | 867 jsgraph()->Int32Constant(element_size), index); |
| 861 } | 868 } |
| 862 int fixed_offset = access.header_size - access.tag(); | 869 int fixed_offset = access.header_size - access.tag(); |
| 863 if (fixed_offset == 0) return index; | 870 if (fixed_offset == 0) return index; |
| 864 return graph()->NewNode(machine()->Int32Add(), index, | 871 return graph()->NewNode(machine()->Int32Add(), index, |
| 865 jsgraph()->Int32Constant(fixed_offset)); | 872 jsgraph()->Int32Constant(fixed_offset)); |
| 866 } | 873 } |
| 867 | 874 |
| 868 | 875 |
| 869 void SimplifiedLowering::DoLoadElement(Node* node) { | 876 void SimplifiedLowering::DoLoadElement(Node* node, MachineType output_type) { |
|
Michael Starzinger
2014/10/08 09:25:31
Instead of passing the output_type as an argument
Benedikt Meurer
2014/10/08 10:54:58
As discussed offline: Not possible.
| |
| 870 const ElementAccess& access = ElementAccessOf(node->op()); | 877 const ElementAccess& access = ElementAccessOf(node->op()); |
| 871 node->set_op(machine()->Load(access.machine_type)); | 878 const Operator* op = machine()->Load(access.machine_type); |
| 872 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); | 879 Node* key = node->InputAt(1); |
| 873 node->RemoveInput(2); | 880 Node* index = ComputeIndex(access, key); |
| 881 if (access.bounds_check == kNoBoundsCheck) { | |
| 882 DCHECK_EQ(access.machine_type, output_type); | |
| 883 node->set_op(op); | |
| 884 node->ReplaceInput(1, index); | |
| 885 node->RemoveInput(2); | |
| 886 } else { | |
| 887 DCHECK_EQ(kTypedArrayBoundsCheck, access.bounds_check); | |
| 888 | |
| 889 Node* base = node->InputAt(0); | |
| 890 Node* length = node->InputAt(2); | |
| 891 Node* effect = node->InputAt(3); | |
| 892 Node* control = node->InputAt(4); | |
| 893 | |
| 894 Node* check = graph()->NewNode(machine()->Uint32LessThan(), key, length); | |
| 895 Node* branch = graph()->NewNode(common()->Branch(), check, control); | |
| 896 | |
| 897 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
| 898 Node* load = graph()->NewNode(op, base, index, effect, if_true); | |
| 899 Node* result = load; | |
| 900 if (output_type & kRepTagged) { | |
| 901 // TODO(turbofan): This is ugly as hell! | |
|
Michael Starzinger
2014/10/08 09:25:31
I concur. :)
| |
| 902 SimplifiedOperatorBuilder simplified(graph()->zone()); | |
| 903 RepresentationChanger changer(jsgraph(), &simplified, | |
| 904 graph()->zone()->isolate()); | |
| 905 result = changer.GetTaggedRepresentationFor(result, access.machine_type); | |
| 906 } | |
| 907 | |
| 908 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 909 Node* undefined; | |
| 910 if (output_type & kRepTagged) { | |
| 911 DCHECK(!(access.machine_type & kRepTagged)); | |
| 912 undefined = jsgraph()->UndefinedConstant(); | |
| 913 } else if (output_type & kRepFloat32) { | |
| 914 undefined = jsgraph()->Float32Constant(0.0f); | |
| 915 } else if (output_type & kRepFloat64) { | |
| 916 undefined = jsgraph()->Float64Constant(0.0); | |
| 917 } else { | |
| 918 undefined = jsgraph()->Int32Constant(0); | |
| 919 } | |
| 920 | |
| 921 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
| 922 Node* phi = graph()->NewNode(common()->EffectPhi(2), load, effect, merge); | |
| 923 | |
| 924 // Replace effect uses of node with the effect phi. | |
| 925 for (UseIter i = node->uses().begin(); i != node->uses().end();) { | |
| 926 if (NodeProperties::IsEffectEdge(i.edge())) { | |
| 927 i = i.UpdateToAndIncrement(phi); | |
| 928 } else { | |
| 929 ++i; | |
| 930 } | |
| 931 } | |
| 932 | |
| 933 node->set_op(common()->Phi(output_type, 2)); | |
| 934 node->ReplaceInput(0, result); | |
| 935 node->ReplaceInput(1, undefined); | |
| 936 node->ReplaceInput(2, merge); | |
| 937 node->TrimInputCount(3); | |
| 938 } | |
| 874 } | 939 } |
| 875 | 940 |
| 876 | 941 |
| 877 void SimplifiedLowering::DoStoreElement(Node* node) { | 942 void SimplifiedLowering::DoStoreElement(Node* node) { |
| 878 const ElementAccess& access = ElementAccessOf(node->op()); | 943 const ElementAccess& access = ElementAccessOf(node->op()); |
| 879 const Operator* op = machine()->Store(StoreRepresentation( | 944 const Operator* op = machine()->Store(StoreRepresentation( |
| 880 access.machine_type, | 945 access.machine_type, |
| 881 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, | 946 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, |
| 882 access.type))); | 947 access.type))); |
| 883 Node* key = node->InputAt(1); | 948 Node* key = node->InputAt(1); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 964 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1029 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
| 965 node->set_op(machine()->IntLessThanOrEqual()); | 1030 node->set_op(machine()->IntLessThanOrEqual()); |
| 966 node->ReplaceInput(0, StringComparison(node, true)); | 1031 node->ReplaceInput(0, StringComparison(node, true)); |
| 967 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1032 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 968 } | 1033 } |
| 969 | 1034 |
| 970 | 1035 |
| 971 } // namespace compiler | 1036 } // namespace compiler |
| 972 } // namespace internal | 1037 } // namespace internal |
| 973 } // namespace v8 | 1038 } // namespace v8 |
| OLD | NEW |