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

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 1109773002: [turbofan] Add SimplifiedOperator::Allocate operator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix tests for ARM. Created 5 years, 8 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
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/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/compiler/access-builder.h" 6 #include "src/compiler/access-builder.h"
7 #include "src/compiler/js-graph.h" 7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/js-typed-lowering.h" 8 #include "src/compiler/js-typed-lowering.h"
9 #include "src/compiler/linkage.h" 9 #include "src/compiler/linkage.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 } 50 }
51 } 51 }
52 52
53 53
54 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) { 54 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) {
55 NodeProperties::ReplaceWithValue(old, node, node); 55 NodeProperties::ReplaceWithValue(old, node, node);
56 return Changed(node); 56 return Changed(node);
57 } 57 }
58 58
59 59
60 // A helper class to construct inline allocations on the simplified operator
61 // level. This keeps track of the effect chain for initial stores on a newly
62 // allocated object and also provides helpers for commonly allocated objects.
63 class AllocationBuilder final {
64 public:
65 AllocationBuilder(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified,
66 Node* effect, Node* control)
67 : jsgraph_(jsgraph),
68 simplified_(simplified),
69 allocation_(nullptr),
70 effect_(effect),
71 control_(control) {}
72
73 // Primitive allocation of static size.
74 void Allocate(int size) {
75 allocation_ = graph()->NewNode(
76 simplified()->Allocate(), jsgraph()->Constant(size), effect_, control_);
77 effect_ = allocation_;
78 }
79
80 // Primitive store into a field.
81 void Store(const FieldAccess& access, Node* value) {
82 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_,
83 value, effect_, control_);
84 }
85
86 // Compound allocation of a FixedArray.
87 void AllocateArray(int length, Handle<Map> map) {
88 Allocate(FixedArray::SizeFor(length));
89 Store(AccessBuilder::ForMap(), map);
90 Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length));
91 }
92
93 // Compound store of a constant into a field.
94 void Store(const FieldAccess& access, Handle<Object> value) {
95 Store(access, jsgraph()->Constant(value));
96 }
97
98 Node* allocation() const { return allocation_; }
99 Node* effect() const { return effect_; }
100
101 protected:
102 JSGraph* jsgraph() { return jsgraph_; }
103 Graph* graph() { return jsgraph_->graph(); }
104 SimplifiedOperatorBuilder* simplified() { return simplified_; }
105
106 private:
107 JSGraph* const jsgraph_;
108 SimplifiedOperatorBuilder* simplified_;
109 Node* allocation_;
110 Node* effect_;
111 Node* control_;
112 };
113
114
60 // A helper class to simplify the process of reducing a single binop node with a 115 // A helper class to simplify the process of reducing a single binop node with a
61 // JSOperator. This class manages the rewriting of context, control, and effect 116 // JSOperator. This class manages the rewriting of context, control, and effect
62 // dependencies during lowering of a binop and contains numerous helper 117 // dependencies during lowering of a binop and contains numerous helper
63 // functions for matching the types of inputs to an operation. 118 // functions for matching the types of inputs to an operation.
64 class JSBinopReduction final { 119 class JSBinopReduction final {
65 public: 120 public:
66 JSBinopReduction(JSTypedLowering* lowering, Node* node) 121 JSBinopReduction(JSTypedLowering* lowering, Node* node)
67 : lowering_(lowering), node_(node) {} 122 : lowering_(lowering), node_(node) {}
68 123
69 void ConvertPrimitiveInputsToNumber() { 124 void ConvertPrimitiveInputsToNumber() {
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(flags)); 1057 node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(flags));
1003 node->InsertInput(graph()->zone(), 0, stub_code); 1058 node->InsertInput(graph()->zone(), 0, stub_code);
1004 node->set_op(new_op); 1059 node->set_op(new_op);
1005 return Changed(node); 1060 return Changed(node);
1006 } 1061 }
1007 1062
1008 return NoChange(); 1063 return NoChange();
1009 } 1064 }
1010 1065
1011 1066
1067 Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) {
1068 DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode());
1069 Node* const input = NodeProperties::GetValueInput(node, 0);
1070 Type* input_type = NodeProperties::GetBounds(input).upper;
1071 if (FLAG_turbo_allocate && input_type->Is(Type::Receiver())) {
1072 // JSCreateWithContext(o:receiver, f)
1073 Node* const effect = NodeProperties::GetEffectInput(node);
1074 Node* const control = NodeProperties::GetControlInput(node);
1075 Node* const closure = NodeProperties::GetValueInput(node, 1);
1076 Node* const context = NodeProperties::GetContextInput(node);
1077 Node* const load = graph()->NewNode(
1078 simplified()->LoadField(
1079 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)),
1080 context, effect, control);
1081 AllocationBuilder a(jsgraph(), simplified(), effect, control);
1082 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered.
1083 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map());
1084 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
1085 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1086 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input);
1087 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load);
1088 // TODO(mstarzinger): This is weird! Make kFinish not require this.
Benedikt Meurer 2015/04/28 08:24:23 Hm, I think Finish is fine, the problem seems to b
Michael Starzinger 2015/04/30 07:53:51 Done. Rephrased the TODO.
1089 NodeProperties::SetBounds(a.allocation(), NodeProperties::GetBounds(node));
1090 NodeProperties::ReplaceWithValue(node, node, a.effect());
1091 node->ReplaceInput(0, a.allocation());
1092 node->ReplaceInput(1, a.effect());
1093 node->set_op(common()->Finish(1));
1094 node->TrimInputCount(2);
1095 return Changed(node);
1096 }
1097 return NoChange();
1098 }
1099
1100
1101 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) {
1102 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
1103 Node* const input = NodeProperties::GetValueInput(node, 0);
1104 HeapObjectMatcher<ScopeInfo> minput(input);
1105 DCHECK(minput.HasValue()); // TODO(mstarzinger): Make ScopeInfo static.
1106 int context_length = minput.Value().handle()->ContextLength();
1107 if (FLAG_turbo_allocate && context_length < kBlockContextAllocationLimit) {
1108 // JSCreateBlockContext(s:scope[length < limit], f)
1109 Node* const effect = NodeProperties::GetEffectInput(node);
1110 Node* const control = NodeProperties::GetControlInput(node);
1111 Node* const closure = NodeProperties::GetValueInput(node, 1);
1112 Node* const context = NodeProperties::GetContextInput(node);
1113 Node* const load = graph()->NewNode(
1114 simplified()->LoadField(
1115 AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)),
1116 context, effect, control);
1117 AllocationBuilder a(jsgraph(), simplified(), effect, control);
1118 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered.
1119 a.AllocateArray(context_length, factory()->block_context_map());
1120 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
1121 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1122 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input);
1123 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load);
1124 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
1125 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant());
1126 }
1127 // TODO(mstarzinger): This is weird! Make kFinish not require this.
Benedikt Meurer 2015/04/28 08:24:23 Hm, I think Finish is fine, the problem seems to b
Michael Starzinger 2015/04/30 07:53:51 Likewise.
1128 NodeProperties::SetBounds(a.allocation(), NodeProperties::GetBounds(node));
1129 NodeProperties::ReplaceWithValue(node, node, a.effect());
1130 node->ReplaceInput(0, a.allocation());
1131 node->ReplaceInput(1, a.effect());
1132 node->set_op(common()->Finish(1));
1133 node->TrimInputCount(2);
1134 return Changed(node);
1135 }
1136 return NoChange();
1137 }
1138
1139
1012 Reduction JSTypedLowering::Reduce(Node* node) { 1140 Reduction JSTypedLowering::Reduce(Node* node) {
1013 // Check if the output type is a singleton. In that case we already know the 1141 // Check if the output type is a singleton. In that case we already know the
1014 // result value and can simply replace the node if it's eliminable. 1142 // result value and can simply replace the node if it's eliminable.
1015 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && 1143 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) &&
1016 node->op()->HasProperty(Operator::kEliminatable)) { 1144 node->op()->HasProperty(Operator::kEliminatable)) {
1017 Type* upper = NodeProperties::GetBounds(node).upper; 1145 Type* upper = NodeProperties::GetBounds(node).upper;
1018 if (upper->IsConstant()) { 1146 if (upper->IsConstant()) {
1019 Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value()); 1147 Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value());
1020 NodeProperties::ReplaceWithValue(node, replacement); 1148 NodeProperties::ReplaceWithValue(node, replacement);
1021 return Changed(replacement); 1149 return Changed(replacement);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 case IrOpcode::kJSLoadContext: 1222 case IrOpcode::kJSLoadContext:
1095 return ReduceJSLoadContext(node); 1223 return ReduceJSLoadContext(node);
1096 case IrOpcode::kJSStoreContext: 1224 case IrOpcode::kJSStoreContext:
1097 return ReduceJSStoreContext(node); 1225 return ReduceJSStoreContext(node);
1098 case IrOpcode::kJSCreateClosure: 1226 case IrOpcode::kJSCreateClosure:
1099 return ReduceJSCreateClosure(node); 1227 return ReduceJSCreateClosure(node);
1100 case IrOpcode::kJSCreateLiteralArray: 1228 case IrOpcode::kJSCreateLiteralArray:
1101 return ReduceJSCreateLiteralArray(node); 1229 return ReduceJSCreateLiteralArray(node);
1102 case IrOpcode::kJSCreateLiteralObject: 1230 case IrOpcode::kJSCreateLiteralObject:
1103 return ReduceJSCreateLiteralObject(node); 1231 return ReduceJSCreateLiteralObject(node);
1232 case IrOpcode::kJSCreateWithContext:
1233 return ReduceJSCreateWithContext(node);
1234 case IrOpcode::kJSCreateBlockContext:
1235 return ReduceJSCreateBlockContext(node);
1104 default: 1236 default:
1105 break; 1237 break;
1106 } 1238 }
1107 return NoChange(); 1239 return NoChange();
1108 } 1240 }
1109 1241
1110 1242
1111 Node* JSTypedLowering::ConvertPrimitiveToNumber(Node* input) { 1243 Node* JSTypedLowering::ConvertPrimitiveToNumber(Node* input) {
1112 DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive())); 1244 DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive()));
1113 // Avoid inserting too many eager ToNumber() operations. 1245 // Avoid inserting too many eager ToNumber() operations.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 } 1300 }
1169 1301
1170 1302
1171 MachineOperatorBuilder* JSTypedLowering::machine() const { 1303 MachineOperatorBuilder* JSTypedLowering::machine() const {
1172 return jsgraph()->machine(); 1304 return jsgraph()->machine();
1173 } 1305 }
1174 1306
1175 } // namespace compiler 1307 } // namespace compiler
1176 } // namespace internal 1308 } // namespace internal
1177 } // namespace v8 1309 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698