blob: 1ee31d5ba554029b83672f9438375e85950735d9 [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
61 case IrOpcode::kJSToName:
62 case IrOpcode::kJSToNumber:
63 case IrOpcode::kJSToObject:
64 case IrOpcode::kJSToString:
65
66 // Misc operations
67 case IrOpcode::kJSConvertReceiver:
68 case IrOpcode::kJSForInNext:
69 case IrOpcode::kJSForInPrepare:
70 case IrOpcode::kJSStackCheck:
71 case IrOpcode::kJSDeleteProperty:
72 return 1;
73
74 // We record the frame state immediately before and immediately after
75 // every property or global variable access.
76 case IrOpcode::kJSLoadNamed:
77 case IrOpcode::kJSStoreNamed:
78 case IrOpcode::kJSLoadProperty:
79 case IrOpcode::kJSStoreProperty:
80 case IrOpcode::kJSLoadGlobal:
81 case IrOpcode::kJSStoreGlobal:
82 return 2;
83
84 // Binary operators that can deopt in the middle the operation (e.g.,
85 // as a result of lazy deopt in ToNumber conversion) need a second frame
86 // state so that we can resume before the operation.
87 case IrOpcode::kJSMultiply:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040088 case IrOpcode::kJSAdd:
89 case IrOpcode::kJSBitwiseAnd:
90 case IrOpcode::kJSBitwiseOr:
91 case IrOpcode::kJSBitwiseXor:
92 case IrOpcode::kJSDivide:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093 case IrOpcode::kJSModulus:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040094 case IrOpcode::kJSShiftLeft:
95 case IrOpcode::kJSShiftRight:
96 case IrOpcode::kJSShiftRightLogical:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040097 case IrOpcode::kJSSubtract:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000098 return 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040099
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100 // Compare operators that can deopt in the middle the operation (e.g.,
101 // as a result of lazy deopt in ToNumber conversion) need a second frame
102 // state so that we can resume before the operation.
103 case IrOpcode::kJSGreaterThan:
104 case IrOpcode::kJSGreaterThanOrEqual:
105 case IrOpcode::kJSLessThan:
106 case IrOpcode::kJSLessThanOrEqual:
107 return 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400108
109 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110 return 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400111 }
112}
113
114
115// static
116int OperatorProperties::GetTotalInputCount(const Operator* op) {
117 return op->ValueInputCount() + GetContextInputCount(op) +
118 GetFrameStateInputCount(op) + op->EffectInputCount() +
119 op->ControlInputCount();
120}
121
122
123// static
124bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
125 Operator::Opcode const opcode = op->opcode();
126 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
127 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
128 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129 opcode == IrOpcode::kIfFalse || opcode == IrOpcode::kIfSuccess ||
130 opcode == IrOpcode::kIfException || opcode == IrOpcode::kIfValue ||
131 opcode == IrOpcode::kIfDefault;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400132}
133
134} // namespace compiler
135} // namespace internal
136} // namespace v8