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

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 1439473003: [turbofan] Move simplified alloc, load and store lowering to change lowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: A bit of cement. Created 5 years, 1 month 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
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | test/cctest/compiler/test-simplified-lowering.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <limits> 7 #include <limits>
8 8
9 #include "src/address-map.h"
10 #include "src/base/bits.h" 9 #include "src/base/bits.h"
11 #include "src/code-factory.h" 10 #include "src/code-factory.h"
12 #include "src/compiler/common-operator.h" 11 #include "src/compiler/common-operator.h"
13 #include "src/compiler/diamond.h" 12 #include "src/compiler/diamond.h"
14 #include "src/compiler/linkage.h" 13 #include "src/compiler/linkage.h"
15 #include "src/compiler/node-matchers.h" 14 #include "src/compiler/node-matchers.h"
16 #include "src/compiler/node-properties.h" 15 #include "src/compiler/node-properties.h"
17 #include "src/compiler/operator-properties.h" 16 #include "src/compiler/operator-properties.h"
18 #include "src/compiler/representation-change.h" 17 #include "src/compiler/representation-change.h"
19 #include "src/compiler/simplified-operator.h" 18 #include "src/compiler/simplified-operator.h"
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 } 812 }
814 case IrOpcode::kStringLessThanOrEqual: { 813 case IrOpcode::kStringLessThanOrEqual: {
815 VisitBinop(node, kMachAnyTagged, kRepBit); 814 VisitBinop(node, kMachAnyTagged, kRepBit);
816 if (lower()) lowering->DoStringLessThanOrEqual(node); 815 if (lower()) lowering->DoStringLessThanOrEqual(node);
817 break; 816 break;
818 } 817 }
819 case IrOpcode::kAllocate: { 818 case IrOpcode::kAllocate: {
820 ProcessInput(node, 0, kMachAnyTagged); 819 ProcessInput(node, 0, kMachAnyTagged);
821 ProcessRemainingInputs(node, 1); 820 ProcessRemainingInputs(node, 1);
822 SetOutput(node, kMachAnyTagged); 821 SetOutput(node, kMachAnyTagged);
823 if (lower()) lowering->DoAllocate(node);
824 break; 822 break;
825 } 823 }
826 case IrOpcode::kLoadField: { 824 case IrOpcode::kLoadField: {
827 FieldAccess access = FieldAccessOf(node->op()); 825 FieldAccess access = FieldAccessOf(node->op());
828 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 826 ProcessInput(node, 0, changer_->TypeForBasePointer(access));
829 ProcessRemainingInputs(node, 1); 827 ProcessRemainingInputs(node, 1);
830 SetOutput(node, access.machine_type); 828 SetOutput(node, access.machine_type);
831 if (lower()) lowering->DoLoadField(node);
832 break; 829 break;
833 } 830 }
834 case IrOpcode::kStoreField: { 831 case IrOpcode::kStoreField: {
835 FieldAccess access = FieldAccessOf(node->op()); 832 FieldAccess access = FieldAccessOf(node->op());
836 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 833 ProcessInput(node, 0, changer_->TypeForBasePointer(access));
837 ProcessInput(node, 1, access.machine_type); 834 ProcessInput(node, 1, access.machine_type);
838 ProcessRemainingInputs(node, 2); 835 ProcessRemainingInputs(node, 2);
839 SetOutput(node, 0); 836 SetOutput(node, 0);
840 if (lower()) lowering->DoStoreField(node);
841 break; 837 break;
842 } 838 }
843 case IrOpcode::kLoadBuffer: { 839 case IrOpcode::kLoadBuffer: {
844 BufferAccess access = BufferAccessOf(node->op()); 840 BufferAccess access = BufferAccessOf(node->op());
845 ProcessInput(node, 0, kMachPtr); // buffer 841 ProcessInput(node, 0, kMachPtr); // buffer
846 ProcessInput(node, 1, kMachInt32); // offset 842 ProcessInput(node, 1, kMachInt32); // offset
847 ProcessInput(node, 2, kMachInt32); // length 843 ProcessInput(node, 2, kMachInt32); // length
848 ProcessRemainingInputs(node, 3); 844 ProcessRemainingInputs(node, 3);
849 // Tagged overrides everything if we have to do a typed array bounds 845 // Tagged overrides everything if we have to do a typed array bounds
850 // check, because we may need to return undefined then. 846 // check, because we may need to return undefined then.
(...skipping 25 matching lines...) Expand all
876 SetOutput(node, 0); 872 SetOutput(node, 0);
877 if (lower()) lowering->DoStoreBuffer(node); 873 if (lower()) lowering->DoStoreBuffer(node);
878 break; 874 break;
879 } 875 }
880 case IrOpcode::kLoadElement: { 876 case IrOpcode::kLoadElement: {
881 ElementAccess access = ElementAccessOf(node->op()); 877 ElementAccess access = ElementAccessOf(node->op());
882 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); // base 878 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); // base
883 ProcessInput(node, 1, kMachInt32); // index 879 ProcessInput(node, 1, kMachInt32); // index
884 ProcessRemainingInputs(node, 2); 880 ProcessRemainingInputs(node, 2);
885 SetOutput(node, access.machine_type); 881 SetOutput(node, access.machine_type);
886 if (lower()) lowering->DoLoadElement(node);
887 break; 882 break;
888 } 883 }
889 case IrOpcode::kStoreElement: { 884 case IrOpcode::kStoreElement: {
890 ElementAccess access = ElementAccessOf(node->op()); 885 ElementAccess access = ElementAccessOf(node->op());
891 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); // base 886 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); // base
892 ProcessInput(node, 1, kMachInt32); // index 887 ProcessInput(node, 1, kMachInt32); // index
893 ProcessInput(node, 2, access.machine_type); // value 888 ProcessInput(node, 2, access.machine_type); // value
894 ProcessRemainingInputs(node, 3); 889 ProcessRemainingInputs(node, 3);
895 SetOutput(node, 0); 890 SetOutput(node, 0);
896 if (lower()) lowering->DoStoreElement(node);
897 break; 891 break;
898 } 892 }
899 case IrOpcode::kObjectIsNumber: { 893 case IrOpcode::kObjectIsNumber: {
900 ProcessInput(node, 0, kMachAnyTagged); 894 ProcessInput(node, 0, kMachAnyTagged);
901 SetOutput(node, kRepBit | kTypeBool); 895 SetOutput(node, kRepBit | kTypeBool);
902 if (lower()) lowering->DoObjectIsNumber(node); 896 if (lower()) lowering->DoObjectIsNumber(node);
903 break; 897 break;
904 } 898 }
905 case IrOpcode::kObjectIsSmi: { 899 case IrOpcode::kObjectIsSmi: {
906 ProcessInput(node, 0, kMachAnyTagged); 900 ProcessInput(node, 0, kMachAnyTagged);
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 1129
1136 1130
1137 void SimplifiedLowering::LowerAllNodes() { 1131 void SimplifiedLowering::LowerAllNodes() {
1138 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); 1132 RepresentationChanger changer(jsgraph(), jsgraph()->isolate());
1139 RepresentationSelector selector(jsgraph(), zone_, &changer, 1133 RepresentationSelector selector(jsgraph(), zone_, &changer,
1140 source_positions_); 1134 source_positions_);
1141 selector.Run(this); 1135 selector.Run(this);
1142 } 1136 }
1143 1137
1144 1138
1145 namespace {
1146
1147 WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged,
1148 MachineType representation,
1149 Type* field_type, Type* input_type) {
1150 if (field_type->Is(Type::TaggedSigned()) ||
1151 input_type->Is(Type::TaggedSigned())) {
1152 // Write barriers are only for writes of heap objects.
1153 return kNoWriteBarrier;
1154 }
1155 if (input_type->Is(Type::BooleanOrNullOrUndefined())) {
1156 // Write barriers are not necessary when storing true, false, null or
1157 // undefined, because these special oddballs are always in the root set.
1158 return kNoWriteBarrier;
1159 }
1160 if (base_is_tagged == kTaggedBase &&
1161 RepresentationOf(representation) == kRepTagged) {
1162 if (input_type->IsConstant() &&
1163 input_type->AsConstant()->Value()->IsHeapObject()) {
1164 Handle<HeapObject> input =
1165 Handle<HeapObject>::cast(input_type->AsConstant()->Value());
1166 if (input->IsMap()) {
1167 // Write barriers for storing maps are cheaper.
1168 return kMapWriteBarrier;
1169 }
1170 Isolate* const isolate = input->GetIsolate();
1171 RootIndexMap root_index_map(isolate);
1172 int root_index = root_index_map.Lookup(*input);
1173 if (root_index != RootIndexMap::kInvalidRootIndex &&
1174 isolate->heap()->RootIsImmortalImmovable(root_index)) {
1175 // Write barriers are unnecessary for immortal immovable roots.
1176 return kNoWriteBarrier;
1177 }
1178 }
1179 if (field_type->Is(Type::TaggedPointer()) ||
1180 input_type->Is(Type::TaggedPointer())) {
1181 // Write barriers for heap objects don't need a Smi check.
1182 return kPointerWriteBarrier;
1183 }
1184 // Write barriers are only for writes into heap objects (i.e. tagged base).
1185 return kFullWriteBarrier;
1186 }
1187 return kNoWriteBarrier;
1188 }
1189
1190 } // namespace
1191
1192
1193 void SimplifiedLowering::DoAllocate(Node* node) {
1194 PretenureFlag pretenure = OpParameter<PretenureFlag>(node->op());
1195 if (pretenure == NOT_TENURED) {
1196 Callable callable = CodeFactory::AllocateInNewSpace(isolate());
1197 Node* target = jsgraph()->HeapConstant(callable.code());
1198 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
1199 isolate(), jsgraph()->zone(), callable.descriptor(), 0,
1200 CallDescriptor::kNoFlags, Operator::kNoThrow);
1201 const Operator* op = common()->Call(descriptor);
1202 node->InsertInput(graph()->zone(), 0, target);
1203 node->InsertInput(graph()->zone(), 2, jsgraph()->NoContextConstant());
1204 NodeProperties::ChangeOp(node, op);
1205 } else {
1206 DCHECK_EQ(TENURED, pretenure);
1207 AllocationSpace space = OLD_SPACE;
1208 Runtime::FunctionId f = Runtime::kAllocateInTargetSpace;
1209 Operator::Properties props = node->op()->properties();
1210 CallDescriptor* desc =
1211 Linkage::GetRuntimeCallDescriptor(zone(), f, 2, props);
1212 ExternalReference ref(f, jsgraph()->isolate());
1213 int32_t flags = AllocateTargetSpace::encode(space);
1214 node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1));
1215 node->InsertInput(graph()->zone(), 2, jsgraph()->SmiConstant(flags));
1216 node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref));
1217 node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2));
1218 node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant());
1219 NodeProperties::ChangeOp(node, common()->Call(desc));
1220 }
1221 }
1222
1223
1224 void SimplifiedLowering::DoLoadField(Node* node) {
1225 const FieldAccess& access = FieldAccessOf(node->op());
1226 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
1227 node->InsertInput(graph()->zone(), 1, offset);
1228 NodeProperties::ChangeOp(node, machine()->Load(access.machine_type));
1229 }
1230
1231
1232 void SimplifiedLowering::DoStoreField(Node* node) {
1233 const FieldAccess& access = FieldAccessOf(node->op());
1234 Type* type = NodeProperties::GetType(node->InputAt(1));
1235 WriteBarrierKind kind = ComputeWriteBarrierKind(
1236 access.base_is_tagged, access.machine_type, access.type, type);
1237 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
1238 node->InsertInput(graph()->zone(), 1, offset);
1239 NodeProperties::ChangeOp(
1240 node, machine()->Store(StoreRepresentation(access.machine_type, kind)));
1241 }
1242
1243
1244 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
1245 Node* const key) {
1246 Node* index = key;
1247 const int element_size_shift = ElementSizeLog2Of(access.machine_type);
1248 if (element_size_shift) {
1249 index = graph()->NewNode(machine()->Word32Shl(), index,
1250 jsgraph()->Int32Constant(element_size_shift));
1251 }
1252 const int fixed_offset = access.header_size - access.tag();
1253 if (fixed_offset) {
1254 index = graph()->NewNode(machine()->Int32Add(), index,
1255 jsgraph()->Int32Constant(fixed_offset));
1256 }
1257 if (machine()->Is64()) {
1258 // TODO(turbofan): This is probably only correct for typed arrays, and only
1259 // if the typed arrays are at most 2GiB in size, which happens to match
1260 // exactly our current situation.
1261 index = graph()->NewNode(machine()->ChangeUint32ToUint64(), index);
1262 }
1263 return index;
1264 }
1265
1266
1267 void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, 1139 void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
1268 RepresentationChanger* changer) { 1140 RepresentationChanger* changer) {
1269 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); 1141 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode());
1270 DCHECK_NE(kMachNone, RepresentationOf(output_type)); 1142 DCHECK_NE(kMachNone, RepresentationOf(output_type));
1271 MachineType const type = BufferAccessOf(node->op()).machine_type(); 1143 MachineType const type = BufferAccessOf(node->op()).machine_type();
1272 if (output_type != type) { 1144 if (output_type != type) {
1273 Node* const buffer = node->InputAt(0); 1145 Node* const buffer = node->InputAt(0);
1274 Node* const offset = node->InputAt(1); 1146 Node* const offset = node->InputAt(1);
1275 Node* const length = node->InputAt(2); 1147 Node* const length = node->InputAt(2);
1276 Node* const effect = node->InputAt(3); 1148 Node* const effect = node->InputAt(3);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 } 1194 }
1323 1195
1324 1196
1325 void SimplifiedLowering::DoStoreBuffer(Node* node) { 1197 void SimplifiedLowering::DoStoreBuffer(Node* node) {
1326 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); 1198 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode());
1327 MachineType const type = BufferAccessOf(node->op()).machine_type(); 1199 MachineType const type = BufferAccessOf(node->op()).machine_type();
1328 NodeProperties::ChangeOp(node, machine()->CheckedStore(type)); 1200 NodeProperties::ChangeOp(node, machine()->CheckedStore(type));
1329 } 1201 }
1330 1202
1331 1203
1332 void SimplifiedLowering::DoLoadElement(Node* node) {
1333 const ElementAccess& access = ElementAccessOf(node->op());
1334 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
1335 NodeProperties::ChangeOp(node, machine()->Load(access.machine_type));
1336 }
1337
1338
1339 void SimplifiedLowering::DoStoreElement(Node* node) {
1340 const ElementAccess& access = ElementAccessOf(node->op());
1341 Type* type = NodeProperties::GetType(node->InputAt(2));
1342 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
1343 NodeProperties::ChangeOp(
1344 node,
1345 machine()->Store(StoreRepresentation(
1346 access.machine_type,
1347 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type,
1348 access.type, type))));
1349 }
1350
1351
1352 void SimplifiedLowering::DoObjectIsNumber(Node* node) { 1204 void SimplifiedLowering::DoObjectIsNumber(Node* node) {
1353 Node* input = NodeProperties::GetValueInput(node, 0); 1205 Node* input = NodeProperties::GetValueInput(node, 0);
1354 // TODO(bmeurer): Optimize somewhat based on input type. 1206 // TODO(bmeurer): Optimize somewhat based on input type.
1355 Node* check = 1207 Node* check =
1356 graph()->NewNode(machine()->WordEqual(), 1208 graph()->NewNode(machine()->WordEqual(),
1357 graph()->NewNode(machine()->WordAnd(), input, 1209 graph()->NewNode(machine()->WordAnd(), input,
1358 jsgraph()->IntPtrConstant(kSmiTagMask)), 1210 jsgraph()->IntPtrConstant(kSmiTagMask)),
1359 jsgraph()->IntPtrConstant(kSmiTag)); 1211 jsgraph()->IntPtrConstant(kSmiTag));
1360 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start()); 1212 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
1361 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1213 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 ReplaceEffectUses(node, comparison); 1554 ReplaceEffectUses(node, comparison);
1703 node->ReplaceInput(0, comparison); 1555 node->ReplaceInput(0, comparison);
1704 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1556 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1705 node->TrimInputCount(2); 1557 node->TrimInputCount(2);
1706 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); 1558 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual());
1707 } 1559 }
1708 1560
1709 } // namespace compiler 1561 } // namespace compiler
1710 } // namespace internal 1562 } // namespace internal
1711 } // namespace v8 1563 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | test/cctest/compiler/test-simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698