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

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

Issue 1485183002: [turbofan] Deopt support for escape analysis (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@ea-local
Patch Set: Created 5 years 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/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 namespace {
258
259 enum class FrameStateInputKind { kAny, kStackSlot };
260
261
262 InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
263 FrameStateInputKind kind) {
264 switch (input->opcode()) {
265 case IrOpcode::kInt32Constant:
266 case IrOpcode::kNumberConstant:
267 case IrOpcode::kFloat32Constant:
268 case IrOpcode::kFloat64Constant:
269 case IrOpcode::kHeapConstant:
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 }
281 }
282
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. 257 // An internal helper class for generating the operands to calls.
336 // TODO(bmeurer): Get rid of the CallBuffer business and make 258 // TODO(bmeurer): Get rid of the CallBuffer business and make
337 // InstructionSelector::VisitCall platform independent instead. 259 // InstructionSelector::VisitCall platform independent instead.
338 struct CallBuffer { 260 struct CallBuffer {
339 CallBuffer(Zone* zone, const CallDescriptor* descriptor, 261 CallBuffer(Zone* zone, const CallDescriptor* descriptor,
340 FrameStateDescriptor* frame_state) 262 FrameStateDescriptor* frame_state)
341 : descriptor(descriptor), 263 : descriptor(descriptor),
342 frame_state_descriptor(frame_state), 264 frame_state_descriptor(frame_state),
343 output_nodes(zone), 265 output_nodes(zone),
344 outputs(zone), 266 outputs(zone),
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 // The target is ignored, but we still need to pass a value here. 373 // The target is ignored, but we still need to pass a value here.
452 buffer->instruction_args.push_back(g.UseImmediate(callee)); 374 buffer->instruction_args.push_back(g.UseImmediate(callee));
453 break; 375 break;
454 } 376 }
455 DCHECK_EQ(1u, buffer->instruction_args.size()); 377 DCHECK_EQ(1u, buffer->instruction_args.size());
456 378
457 // If the call needs a frame state, we insert the state information as 379 // If the call needs a frame state, we insert the state information as
458 // follows (n is the number of value inputs to the frame state): 380 // follows (n is the number of value inputs to the frame state):
459 // arg 1 : deoptimization id. 381 // arg 1 : deoptimization id.
460 // arg 2 - arg (n + 1) : value inputs to the frame state. 382 // arg 2 - arg (n + 1) : value inputs to the frame state.
383 size_t frame_state_entries = 0;
461 if (buffer->frame_state_descriptor != NULL) { 384 if (buffer->frame_state_descriptor != NULL) {
462 InstructionSequence::StateId state_id = 385 InstructionSequence::StateId state_id =
463 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor); 386 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor);
464 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt())); 387 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt()));
465 388
466 Node* frame_state = 389 Node* frame_state =
467 call->InputAt(static_cast<int>(buffer->descriptor->InputCount())); 390 call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
468 AddFrameStateInputs(frame_state, &g, &buffer->instruction_args, 391
469 buffer->frame_state_descriptor, 392 StateObjectCache cache(instruction_zone());
470 FrameStateInputKind::kStackSlot, instruction_zone()); 393
394 frame_state_entries =
395 1 +
396 buffer->frame_state_descriptor->AddInputs(
397 frame_state, &g, &cache, &buffer->instruction_args,
398 FrameStateInputKind::kStackSlot, instruction_zone());
399
400 DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size());
471 } 401 }
472 DCHECK(1 + buffer->frame_state_value_count() ==
473 buffer->instruction_args.size());
474 402
475 size_t input_count = static_cast<size_t>(buffer->input_count()); 403 size_t input_count = static_cast<size_t>(buffer->input_count());
476 404
477 // Split the arguments into pushed_nodes and instruction_args. Pushed 405 // Split the arguments into pushed_nodes and instruction_args. Pushed
478 // arguments require an explicit push instruction before the call and do 406 // arguments require an explicit push instruction before the call and do
479 // not appear as arguments to the call. Everything else ends up 407 // not appear as arguments to the call. Everything else ends up
480 // as an InstructionOperand argument to the call. 408 // as an InstructionOperand argument to the call.
481 auto iter(call->inputs().begin()); 409 auto iter(call->inputs().begin());
482 size_t pushed_count = 0; 410 size_t pushed_count = 0;
483 bool call_tail = (flags & kCallTail) != 0; 411 bool call_tail = (flags & kCallTail) != 0;
(...skipping 15 matching lines...) Expand all
499 buffer->pushed_nodes.resize(stack_index + 1, NULL); 427 buffer->pushed_nodes.resize(stack_index + 1, NULL);
500 } 428 }
501 DCHECK(!buffer->pushed_nodes[stack_index]); 429 DCHECK(!buffer->pushed_nodes[stack_index]);
502 buffer->pushed_nodes[stack_index] = *iter; 430 buffer->pushed_nodes[stack_index] = *iter;
503 pushed_count++; 431 pushed_count++;
504 } else { 432 } else {
505 buffer->instruction_args.push_back(op); 433 buffer->instruction_args.push_back(op);
506 } 434 }
507 } 435 }
508 DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count - 436 DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count -
509 buffer->frame_state_value_count()); 437 frame_state_entries);
Jarin 2015/12/02 12:24:34 Hmm, does not the compiler complain that frame_sta
sigurds 2015/12/02 16:35:13 Done.
510 if (call_tail && stack_param_delta != 0) { 438 if (call_tail && stack_param_delta != 0) {
511 // For tail calls that change the size of their parameter list, move the 439 // For tail calls that change the size of their parameter list, move the
512 // saved caller return address, parent frame pointer and parent constant 440 // saved caller return address, parent frame pointer and parent constant
513 // pool pointer to just above the parameters. 441 // pool pointer to just above the parameters.
514 442
515 // Return address 443 // Return address
516 LinkageLocation saved_return_location = 444 LinkageLocation saved_return_location =
517 LinkageLocation::ForSavedCallerReturnAddress(); 445 LinkageLocation::ForSavedCallerReturnAddress();
518 InstructionOperand return_address = 446 InstructionOperand return_address =
519 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation( 447 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation(
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 return MarkAsReference(node), VisitConstant(node); 654 return MarkAsReference(node), VisitConstant(node);
727 case IrOpcode::kNumberConstant: { 655 case IrOpcode::kNumberConstant: {
728 double value = OpParameter<double>(node); 656 double value = OpParameter<double>(node);
729 if (!IsSmiDouble(value)) MarkAsReference(node); 657 if (!IsSmiDouble(value)) MarkAsReference(node);
730 return VisitConstant(node); 658 return VisitConstant(node);
731 } 659 }
732 case IrOpcode::kCall: 660 case IrOpcode::kCall:
733 return VisitCall(node); 661 return VisitCall(node);
734 case IrOpcode::kFrameState: 662 case IrOpcode::kFrameState:
735 case IrOpcode::kStateValues: 663 case IrOpcode::kStateValues:
664 case IrOpcode::kObjectState:
736 return; 665 return;
737 case IrOpcode::kLoad: { 666 case IrOpcode::kLoad: {
738 LoadRepresentation rep = OpParameter<LoadRepresentation>(node); 667 LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
739 MarkAsRepresentation(rep, node); 668 MarkAsRepresentation(rep, node);
740 return VisitLoad(node); 669 return VisitLoad(node);
741 } 670 }
742 case IrOpcode::kStore: 671 case IrOpcode::kStore:
743 return VisitStore(node); 672 return VisitStore(node);
744 case IrOpcode::kWord32And: 673 case IrOpcode::kWord32And:
745 return MarkAsWord32(node), VisitWord32And(node); 674 return MarkAsWord32(node), VisitWord32And(node);
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 } 1343 }
1415 Emit(kArchRet, 0, nullptr, ret_count, value_locations); 1344 Emit(kArchRet, 0, nullptr, ret_count, value_locations);
1416 } 1345 }
1417 } 1346 }
1418 1347
1419 1348
1420 void InstructionSelector::VisitDeoptimize(Node* value) { 1349 void InstructionSelector::VisitDeoptimize(Node* value) {
1421 OperandGenerator g(this); 1350 OperandGenerator g(this);
1422 1351
1423 FrameStateDescriptor* desc = GetFrameStateDescriptor(value); 1352 FrameStateDescriptor* desc = GetFrameStateDescriptor(value);
1424 size_t arg_count = desc->GetTotalSize() + 1; // Include deopt id.
1425 1353
1426 InstructionOperandVector args(instruction_zone()); 1354 InstructionOperandVector args(instruction_zone());
1427 args.reserve(arg_count); 1355 args.reserve(desc->GetTotalSize() + 1); // Include deopt id.
1428 1356
1429 InstructionSequence::StateId state_id = 1357 InstructionSequence::StateId state_id =
1430 sequence()->AddFrameStateDescriptor(desc); 1358 sequence()->AddFrameStateDescriptor(desc);
1431 args.push_back(g.TempImmediate(state_id.ToInt())); 1359 args.push_back(g.TempImmediate(state_id.ToInt()));
1432 1360
1433 AddFrameStateInputs(value, &g, &args, desc, FrameStateInputKind::kAny, 1361 StateObjectCache cache(instruction_zone());
1434 instruction_zone());
1435 1362
1436 DCHECK_EQ(args.size(), arg_count); 1363 desc->AddInputs(value, &g, &cache, &args, FrameStateInputKind::kAny,
1364 instruction_zone());
1437 1365
1438 Emit(kArchDeoptimize, 0, nullptr, arg_count, &args.front(), 0, nullptr); 1366 Emit(kArchDeoptimize, 0, nullptr, args.size(), &args.front(), 0, nullptr);
1439 } 1367 }
1440 1368
1441 1369
1442 void InstructionSelector::VisitThrow(Node* value) { 1370 void InstructionSelector::VisitThrow(Node* value) {
1443 OperandGenerator g(this); 1371 OperandGenerator g(this);
1444 Emit(kArchNop, g.NoOutput()); // TODO(titzer) 1372 Emit(kArchNop, g.NoOutput()); // TODO(titzer)
1445 } 1373 }
1446 1374
1447 1375
1448 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( 1376 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
(...skipping 21 matching lines...) Expand all
1470 return new (instruction_zone()) FrameStateDescriptor( 1398 return new (instruction_zone()) FrameStateDescriptor(
1471 instruction_zone(), state_info.type(), state_info.bailout_id(), 1399 instruction_zone(), state_info.type(), state_info.bailout_id(),
1472 state_info.state_combine(), parameters, locals, stack, 1400 state_info.state_combine(), parameters, locals, stack,
1473 state_info.shared_info(), outer_state); 1401 state_info.shared_info(), outer_state);
1474 } 1402 }
1475 1403
1476 1404
1477 } // namespace compiler 1405 } // namespace compiler
1478 } // namespace internal 1406 } // namespace internal
1479 } // namespace v8 1407 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698