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

Side by Side Diff: src/compiler/instruction-selector.cc

Issue 1425183003: [turbofan] Move CallBuffer from header to cc file. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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/instruction-selector.h ('k') | src/compiler/instruction-selector-impl.h » ('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/instruction-selector.h" 5 #include "src/compiler/instruction-selector.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/base/adapters.h" 9 #include "src/base/adapters.h"
10 #include "src/compiler/instruction-selector-impl.h" 10 #include "src/compiler/instruction-selector-impl.h"
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register()); 247 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
248 } 248 }
249 249
250 250
251 void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) { 251 void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) {
252 rep = RepresentationOf(rep); 252 rep = RepresentationOf(rep);
253 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node)); 253 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
254 } 254 }
255 255
256 256
257 // TODO(bmeurer): Get rid of the CallBuffer business and make 257 namespace {
258 // InstructionSelector::VisitCall platform independent instead. 258
259 CallBuffer::CallBuffer(Zone* zone, const CallDescriptor* d, 259 enum class FrameStateInputKind { kAny, kStackSlot };
260 FrameStateDescriptor* frame_desc) 260
261 : descriptor(d), 261
262 frame_state_descriptor(frame_desc), 262 InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
263 output_nodes(zone), 263 FrameStateInputKind kind) {
264 outputs(zone), 264 switch (input->opcode()) {
265 instruction_args(zone), 265 case IrOpcode::kInt32Constant:
266 pushed_nodes(zone) { 266 case IrOpcode::kNumberConstant:
267 output_nodes.reserve(d->ReturnCount()); 267 case IrOpcode::kFloat32Constant:
268 outputs.reserve(d->ReturnCount()); 268 case IrOpcode::kFloat64Constant:
269 pushed_nodes.reserve(input_count()); 269 case IrOpcode::kHeapConstant:
270 instruction_args.reserve(input_count() + frame_state_value_count()); 270 return g->UseImmediate(input);
271 default:
272 switch (kind) {
273 case FrameStateInputKind::kStackSlot:
274 return g->UseUniqueSlot(input);
275 case FrameStateInputKind::kAny:
276 return g->UseAny(input);
277 }
278 UNREACHABLE();
279 return InstructionOperand();
280 }
271 } 281 }
272 282
273 283
284 void AddFrameStateInputs(Node* state, OperandGenerator* g,
285 InstructionOperandVector* inputs,
286 FrameStateDescriptor* descriptor,
287 FrameStateInputKind kind, Zone* zone) {
288 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
289
290 if (descriptor->outer_state()) {
291 AddFrameStateInputs(state->InputAt(kFrameStateOuterStateInput), g, inputs,
292 descriptor->outer_state(), kind, zone);
293 }
294
295 Node* parameters = state->InputAt(kFrameStateParametersInput);
296 Node* locals = state->InputAt(kFrameStateLocalsInput);
297 Node* stack = state->InputAt(kFrameStateStackInput);
298 Node* context = state->InputAt(kFrameStateContextInput);
299 Node* function = state->InputAt(kFrameStateFunctionInput);
300
301 DCHECK_EQ(descriptor->parameters_count(),
302 StateValuesAccess(parameters).size());
303 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
304 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
305
306 ZoneVector<MachineType> types(zone);
307 types.reserve(descriptor->GetSize());
308
309 size_t value_index = 0;
310 inputs->push_back(OperandForDeopt(g, function, kind));
311 descriptor->SetType(value_index++, kMachAnyTagged);
312 for (StateValuesAccess::TypedNode input_node :
313 StateValuesAccess(parameters)) {
314 inputs->push_back(OperandForDeopt(g, input_node.node, kind));
315 descriptor->SetType(value_index++, input_node.type);
316 }
317 if (descriptor->HasContext()) {
318 inputs->push_back(OperandForDeopt(g, context, kind));
319 descriptor->SetType(value_index++, kMachAnyTagged);
320 }
321 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
322 inputs->push_back(OperandForDeopt(g, input_node.node, kind));
323 descriptor->SetType(value_index++, input_node.type);
324 }
325 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
326 inputs->push_back(OperandForDeopt(g, input_node.node, kind));
327 descriptor->SetType(value_index++, input_node.type);
328 }
329 DCHECK(value_index == descriptor->GetSize());
330 }
331
332 } // namespace
333
334
335 // An internal helper class for generating the operands to calls.
274 // TODO(bmeurer): Get rid of the CallBuffer business and make 336 // TODO(bmeurer): Get rid of the CallBuffer business and make
337 // InstructionSelector::VisitCall platform independent instead.
338 struct CallBuffer {
339 CallBuffer(Zone* zone, const CallDescriptor* descriptor,
340 FrameStateDescriptor* frame_state)
341 : descriptor(descriptor),
342 frame_state_descriptor(frame_state),
343 output_nodes(zone),
344 outputs(zone),
345 instruction_args(zone),
346 pushed_nodes(zone) {
347 output_nodes.reserve(descriptor->ReturnCount());
348 outputs.reserve(descriptor->ReturnCount());
349 pushed_nodes.reserve(input_count());
350 instruction_args.reserve(input_count() + frame_state_value_count());
351 }
352
353
354 const CallDescriptor* descriptor;
355 FrameStateDescriptor* frame_state_descriptor;
356 NodeVector output_nodes;
357 InstructionOperandVector outputs;
358 InstructionOperandVector instruction_args;
359 NodeVector pushed_nodes;
360
361 size_t input_count() const { return descriptor->InputCount(); }
362
363 size_t frame_state_count() const { return descriptor->FrameStateCount(); }
364
365 size_t frame_state_value_count() const {
366 return (frame_state_descriptor == NULL)
367 ? 0
368 : (frame_state_descriptor->GetTotalSize() +
369 1); // Include deopt id.
370 }
371 };
372
373
374 // TODO(bmeurer): Get rid of the CallBuffer business and make
275 // InstructionSelector::VisitCall platform independent instead. 375 // InstructionSelector::VisitCall platform independent instead.
276 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, 376 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
277 bool call_code_immediate, 377 bool call_code_immediate,
278 bool call_address_immediate) { 378 bool call_address_immediate) {
279 OperandGenerator g(this); 379 OperandGenerator g(this);
280 DCHECK_LE(call->op()->ValueOutputCount(), 380 DCHECK_LE(call->op()->ValueOutputCount(),
281 static_cast<int>(buffer->descriptor->ReturnCount())); 381 static_cast<int>(buffer->descriptor->ReturnCount()));
282 DCHECK_EQ( 382 DCHECK_EQ(
283 call->op()->ValueInputCount(), 383 call->op()->ValueInputCount(),
284 static_cast<int>(buffer->input_count() + buffer->frame_state_count())); 384 static_cast<int>(buffer->input_count() + buffer->frame_state_count()));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 // follows (n is the number of value inputs to the frame state): 456 // follows (n is the number of value inputs to the frame state):
357 // arg 1 : deoptimization id. 457 // arg 1 : deoptimization id.
358 // arg 2 - arg (n + 1) : value inputs to the frame state. 458 // arg 2 - arg (n + 1) : value inputs to the frame state.
359 if (buffer->frame_state_descriptor != NULL) { 459 if (buffer->frame_state_descriptor != NULL) {
360 InstructionSequence::StateId state_id = 460 InstructionSequence::StateId state_id =
361 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor); 461 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor);
362 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt())); 462 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt()));
363 463
364 Node* frame_state = 464 Node* frame_state =
365 call->InputAt(static_cast<int>(buffer->descriptor->InputCount())); 465 call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
366 AddFrameStateInputs(frame_state, &buffer->instruction_args, 466 AddFrameStateInputs(frame_state, &g, &buffer->instruction_args,
367 buffer->frame_state_descriptor, 467 buffer->frame_state_descriptor,
368 FrameStateInputKind::kStackSlot); 468 FrameStateInputKind::kStackSlot, instruction_zone());
369 } 469 }
370 DCHECK(1 + buffer->frame_state_value_count() == 470 DCHECK(1 + buffer->frame_state_value_count() ==
371 buffer->instruction_args.size()); 471 buffer->instruction_args.size());
372 472
373 size_t input_count = static_cast<size_t>(buffer->input_count()); 473 size_t input_count = static_cast<size_t>(buffer->input_count());
374 474
375 // Split the arguments into pushed_nodes and instruction_args. Pushed 475 // Split the arguments into pushed_nodes and instruction_args. Pushed
376 // arguments require an explicit push instruction before the call and do 476 // arguments require an explicit push instruction before the call and do
377 // not appear as arguments to the call. Everything else ends up 477 // not appear as arguments to the call. Everything else ends up
378 // as an InstructionOperand argument to the call. 478 // as an InstructionOperand argument to the call.
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 FrameStateDescriptor* desc = GetFrameStateDescriptor(value); 1275 FrameStateDescriptor* desc = GetFrameStateDescriptor(value);
1176 size_t arg_count = desc->GetTotalSize() + 1; // Include deopt id. 1276 size_t arg_count = desc->GetTotalSize() + 1; // Include deopt id.
1177 1277
1178 InstructionOperandVector args(instruction_zone()); 1278 InstructionOperandVector args(instruction_zone());
1179 args.reserve(arg_count); 1279 args.reserve(arg_count);
1180 1280
1181 InstructionSequence::StateId state_id = 1281 InstructionSequence::StateId state_id =
1182 sequence()->AddFrameStateDescriptor(desc); 1282 sequence()->AddFrameStateDescriptor(desc);
1183 args.push_back(g.TempImmediate(state_id.ToInt())); 1283 args.push_back(g.TempImmediate(state_id.ToInt()));
1184 1284
1185 AddFrameStateInputs(value, &args, desc, FrameStateInputKind::kAny); 1285 AddFrameStateInputs(value, &g, &args, desc, FrameStateInputKind::kAny,
1286 instruction_zone());
1186 1287
1187 DCHECK_EQ(args.size(), arg_count); 1288 DCHECK_EQ(args.size(), arg_count);
1188 1289
1189 Emit(kArchDeoptimize, 0, nullptr, arg_count, &args.front(), 0, nullptr); 1290 Emit(kArchDeoptimize, 0, nullptr, arg_count, &args.front(), 0, nullptr);
1190 } 1291 }
1191 1292
1192 1293
1193 void InstructionSelector::VisitThrow(Node* value) { 1294 void InstructionSelector::VisitThrow(Node* value) {
1194 OperandGenerator g(this); 1295 OperandGenerator g(this);
1195 Emit(kArchNop, g.NoOutput()); // TODO(titzer) 1296 Emit(kArchNop, g.NoOutput()); // TODO(titzer)
(...skipping 22 matching lines...) Expand all
1218 outer_state = GetFrameStateDescriptor(outer_node); 1319 outer_state = GetFrameStateDescriptor(outer_node);
1219 } 1320 }
1220 1321
1221 return new (instruction_zone()) FrameStateDescriptor( 1322 return new (instruction_zone()) FrameStateDescriptor(
1222 instruction_zone(), state_info.type(), state_info.bailout_id(), 1323 instruction_zone(), state_info.type(), state_info.bailout_id(),
1223 state_info.state_combine(), parameters, locals, stack, 1324 state_info.state_combine(), parameters, locals, stack,
1224 state_info.shared_info(), outer_state); 1325 state_info.shared_info(), outer_state);
1225 } 1326 }
1226 1327
1227 1328
1228 InstructionOperand InstructionSelector::OperandForDeopt(
1229 OperandGenerator* g, Node* input, FrameStateInputKind kind) {
1230 switch (input->opcode()) {
1231 case IrOpcode::kInt32Constant:
1232 case IrOpcode::kNumberConstant:
1233 case IrOpcode::kFloat32Constant:
1234 case IrOpcode::kFloat64Constant:
1235 case IrOpcode::kHeapConstant:
1236 return g->UseImmediate(input);
1237 default:
1238 switch (kind) {
1239 case FrameStateInputKind::kStackSlot:
1240 return g->UseUniqueSlot(input);
1241 case FrameStateInputKind::kAny:
1242 return g->UseAny(input);
1243 }
1244 UNREACHABLE();
1245 return InstructionOperand();
1246 }
1247 }
1248
1249
1250 void InstructionSelector::AddFrameStateInputs(Node* state,
1251 InstructionOperandVector* inputs,
1252 FrameStateDescriptor* descriptor,
1253 FrameStateInputKind kind) {
1254 DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
1255
1256 if (descriptor->outer_state()) {
1257 AddFrameStateInputs(state->InputAt(kFrameStateOuterStateInput), inputs,
1258 descriptor->outer_state(), kind);
1259 }
1260
1261 Node* parameters = state->InputAt(kFrameStateParametersInput);
1262 Node* locals = state->InputAt(kFrameStateLocalsInput);
1263 Node* stack = state->InputAt(kFrameStateStackInput);
1264 Node* context = state->InputAt(kFrameStateContextInput);
1265 Node* function = state->InputAt(kFrameStateFunctionInput);
1266
1267 DCHECK_EQ(descriptor->parameters_count(),
1268 StateValuesAccess(parameters).size());
1269 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
1270 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
1271
1272 ZoneVector<MachineType> types(instruction_zone());
1273 types.reserve(descriptor->GetSize());
1274
1275 OperandGenerator g(this);
1276 size_t value_index = 0;
1277 inputs->push_back(OperandForDeopt(&g, function, kind));
1278 descriptor->SetType(value_index++, kMachAnyTagged);
1279 for (StateValuesAccess::TypedNode input_node :
1280 StateValuesAccess(parameters)) {
1281 inputs->push_back(OperandForDeopt(&g, input_node.node, kind));
1282 descriptor->SetType(value_index++, input_node.type);
1283 }
1284 if (descriptor->HasContext()) {
1285 inputs->push_back(OperandForDeopt(&g, context, kind));
1286 descriptor->SetType(value_index++, kMachAnyTagged);
1287 }
1288 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
1289 inputs->push_back(OperandForDeopt(&g, input_node.node, kind));
1290 descriptor->SetType(value_index++, input_node.type);
1291 }
1292 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
1293 inputs->push_back(OperandForDeopt(&g, input_node.node, kind));
1294 descriptor->SetType(value_index++, input_node.type);
1295 }
1296 DCHECK(value_index == descriptor->GetSize());
1297 }
1298
1299 } // namespace compiler 1329 } // namespace compiler
1300 } // namespace internal 1330 } // namespace internal
1301 } // namespace v8 1331 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector.h ('k') | src/compiler/instruction-selector-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698