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 |