v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
checkpoint-elimination.cc
Go to the documentation of this file.
1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
9
10namespace v8 {
11namespace internal {
12namespace compiler {
13
16
17namespace {
18
19FrameStateFunctionInfo const* GetFunctionInfo(Node* checkpoint) {
20 DCHECK_EQ(IrOpcode::kCheckpoint, checkpoint->opcode());
21 Node* frame_state = NodeProperties::GetFrameStateInput(checkpoint);
22 return frame_state->opcode() == IrOpcode::kFrameState
23 ? FrameStateInfoOf(frame_state->op()).function_info()
24 : nullptr;
25}
26
27// The given checkpoint is redundant if it is effect-wise dominated by another
28// checkpoint of the same origin (*) and there is no observable write in
29// between. For now we consider a linear effect chain only instead of true
30// effect-wise dominance.
31// "Same origin" here refers to the same graph building pass and is expressed as
32// the identity of the checkpoint's FrameStateFunctionInfo pointer. This
33// restriction ensures that an eager deopt from an inlined function will resume
34// the inlined function's bytecode (rather than, say, the call in the caller's
35// bytecode), which in turn is necessary to ensure that we learn something from
36// the deopt in the case where an optimized code object for the inlined function
37// exists. See regress-9945-*.js and v8:9945.
38bool IsRedundantCheckpoint(Node* node) {
39 FrameStateFunctionInfo const* function_info = GetFunctionInfo(node);
40 if (function_info == nullptr) return false;
41 Node* effect = NodeProperties::GetEffectInput(node);
42 while (effect->op()->HasProperty(Operator::kNoWrite) &&
43 effect->op()->EffectInputCount() == 1) {
44 if (effect->opcode() == IrOpcode::kCheckpoint) {
45 return GetFunctionInfo(effect) == function_info;
46 }
47 effect = NodeProperties::GetEffectInput(effect);
48 }
49 return false;
50}
51
52} // namespace
53
55 DCHECK_EQ(IrOpcode::kCheckpoint, node->opcode());
56 if (IsRedundantCheckpoint(node)) {
57 return Replace(NodeProperties::GetEffectInput(node));
58 }
59 return NoChange();
60}
61
63 DisallowHeapAccess no_heap_access;
64 switch (node->opcode()) {
65 case IrOpcode::kCheckpoint:
66 return ReduceCheckpoint(node);
67 default:
68 break;
69 }
70 return NoChange();
71}
72
73} // namespace compiler
74} // namespace internal
75} // namespace v8
static Node * GetEffectInput(Node *node, int index=0)
static Node * GetFrameStateInput(Node *node)
constexpr IrOpcode::Value opcode() const
Definition node.h:52
const Operator * op() const
Definition node.h:50
const FrameStateInfo & FrameStateInfoOf(const Operator *op)
#define DCHECK_EQ(v1, v2)
Definition logging.h:485