blob: 7f38ca7299517debd75436382c736bbb1668065b [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// 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
3// found in the LICENSE file.
4
5#include "src/compiler/operator-properties.h"
6
7#include "src/compiler/js-operator.h"
8#include "src/compiler/linkage.h"
9#include "src/compiler/opcodes.h"
10
11namespace v8 {
12namespace internal {
13namespace compiler {
14
15// static
16bool OperatorProperties::HasContextInput(const Operator* op) {
17 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
18 return IrOpcode::IsJsOpcode(opcode);
19}
20
21
22// static
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040024 switch (op->opcode()) {
25 case IrOpcode::kFrameState:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026 return 1;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040027 case IrOpcode::kJSCallRuntime: {
28 const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029 return Linkage::FrameStateInputCount(p.id());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040030 }
31
32 // Strict equality cannot lazily deoptimize.
33 case IrOpcode::kJSStrictEqual:
34 case IrOpcode::kJSStrictNotEqual:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035 return 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040036
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 // We record the frame state immediately before and immediately after every
38 // construct/function call.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040039 case IrOpcode::kJSCallConstruct:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 case IrOpcode::kJSCallFunction:
41 return 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040042
43 // Compare operations
44 case IrOpcode::kJSEqual:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045 case IrOpcode::kJSNotEqual:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040046 case IrOpcode::kJSHasProperty:
47 case IrOpcode::kJSInstanceOf:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040048
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049 // Object operations
50 case IrOpcode::kJSCreate:
51 case IrOpcode::kJSCreateArguments:
52 case IrOpcode::kJSCreateArray:
53 case IrOpcode::kJSCreateLiteralArray:
54 case IrOpcode::kJSCreateLiteralObject:
55 case IrOpcode::kJSCreateLiteralRegExp:
56
57 // Context operations
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058 case IrOpcode::kJSCreateScriptContext:
59
60 // Conversions
Ben Murdochda12d292016-06-02 14:46:10 +010061 case IrOpcode::kJSToInteger:
62 case IrOpcode::kJSToLength:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000063 case IrOpcode::kJSToName:
64 case IrOpcode::kJSToNumber:
65 case IrOpcode::kJSToObject:
66 case IrOpcode::kJSToString:
67
68 // Misc operations
69 case IrOpcode::kJSConvertReceiver:
70 case IrOpcode::kJSForInNext:
71 case IrOpcode::kJSForInPrepare:
72 case IrOpcode::kJSStackCheck:
73 case IrOpcode::kJSDeleteProperty:
74 return 1;
75
76 // We record the frame state immediately before and immediately after
77 // every property or global variable access.
78 case IrOpcode::kJSLoadNamed:
79 case IrOpcode::kJSStoreNamed:
80 case IrOpcode::kJSLoadProperty:
81 case IrOpcode::kJSStoreProperty:
82 case IrOpcode::kJSLoadGlobal:
83 case IrOpcode::kJSStoreGlobal:
84 return 2;
85
86 // Binary operators that can deopt in the middle the operation (e.g.,
87 // as a result of lazy deopt in ToNumber conversion) need a second frame
88 // state so that we can resume before the operation.
89 case IrOpcode::kJSMultiply:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040090 case IrOpcode::kJSAdd:
91 case IrOpcode::kJSBitwiseAnd:
92 case IrOpcode::kJSBitwiseOr:
93 case IrOpcode::kJSBitwiseXor:
94 case IrOpcode::kJSDivide:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040095 case IrOpcode::kJSModulus:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040096 case IrOpcode::kJSShiftLeft:
97 case IrOpcode::kJSShiftRight:
98 case IrOpcode::kJSShiftRightLogical:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040099 case IrOpcode::kJSSubtract:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100 return 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400101
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 // Compare operators that can deopt in the middle the operation (e.g.,
103 // as a result of lazy deopt in ToNumber conversion) need a second frame
104 // state so that we can resume before the operation.
105 case IrOpcode::kJSGreaterThan:
106 case IrOpcode::kJSGreaterThanOrEqual:
107 case IrOpcode::kJSLessThan:
108 case IrOpcode::kJSLessThanOrEqual:
109 return 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110
111 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 return 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400113 }
114}
115
116
117// static
118int OperatorProperties::GetTotalInputCount(const Operator* op) {
119 return op->ValueInputCount() + GetContextInputCount(op) +
120 GetFrameStateInputCount(op) + op->EffectInputCount() +
121 op->ControlInputCount();
122}
123
124
125// static
126bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
127 Operator::Opcode const opcode = op->opcode();
128 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
129 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
130 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000131 opcode == IrOpcode::kIfFalse || opcode == IrOpcode::kIfSuccess ||
132 opcode == IrOpcode::kIfException || opcode == IrOpcode::kIfValue ||
133 opcode == IrOpcode::kIfDefault;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400134}
135
136} // namespace compiler
137} // namespace internal
138} // namespace v8