blob: 43b00761feb5b310b45503c454cdc3f471380b92 [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()) {
Ben Murdoch61f157c2016-09-16 13:49:30 +010025 case IrOpcode::kCheckpoint:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040026 case IrOpcode::kFrameState:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027 return 1;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040028 case IrOpcode::kJSCallRuntime: {
29 const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
Ben Murdoch61f157c2016-09-16 13:49:30 +010030 return Linkage::NeedsFrameStateInput(p.id()) ? 1 : 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040031 }
32
33 // Strict equality cannot lazily deoptimize.
34 case IrOpcode::kJSStrictEqual:
35 case IrOpcode::kJSStrictNotEqual:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036 return 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040037
Emily Bernierd0a1eb72015-03-24 16:35:39 -040038 // Compare operations
39 case IrOpcode::kJSEqual:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 case IrOpcode::kJSNotEqual:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040041 case IrOpcode::kJSHasProperty:
42 case IrOpcode::kJSInstanceOf:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040043
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 // Object operations
45 case IrOpcode::kJSCreate:
46 case IrOpcode::kJSCreateArguments:
47 case IrOpcode::kJSCreateArray:
48 case IrOpcode::kJSCreateLiteralArray:
49 case IrOpcode::kJSCreateLiteralObject:
50 case IrOpcode::kJSCreateLiteralRegExp:
51
Ben Murdoch61f157c2016-09-16 13:49:30 +010052 // Property access operations
53 case IrOpcode::kJSLoadNamed:
54 case IrOpcode::kJSStoreNamed:
55 case IrOpcode::kJSLoadProperty:
56 case IrOpcode::kJSStoreProperty:
57 case IrOpcode::kJSLoadGlobal:
58 case IrOpcode::kJSStoreGlobal:
59 case IrOpcode::kJSDeleteProperty:
60
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061 // Context operations
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 case IrOpcode::kJSCreateScriptContext:
63
64 // Conversions
Ben Murdochda12d292016-06-02 14:46:10 +010065 case IrOpcode::kJSToInteger:
66 case IrOpcode::kJSToLength:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067 case IrOpcode::kJSToName:
68 case IrOpcode::kJSToNumber:
69 case IrOpcode::kJSToObject:
70 case IrOpcode::kJSToString:
71
Ben Murdoch61f157c2016-09-16 13:49:30 +010072 // Call operations
73 case IrOpcode::kJSCallConstruct:
74 case IrOpcode::kJSCallFunction:
75
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076 // Misc operations
77 case IrOpcode::kJSConvertReceiver:
78 case IrOpcode::kJSForInNext:
79 case IrOpcode::kJSForInPrepare:
80 case IrOpcode::kJSStackCheck:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000081 return 1;
82
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000083 // Binary operators that can deopt in the middle the operation (e.g.,
84 // as a result of lazy deopt in ToNumber conversion) need a second frame
85 // state so that we can resume before the operation.
86 case IrOpcode::kJSMultiply:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040087 case IrOpcode::kJSAdd:
88 case IrOpcode::kJSBitwiseAnd:
89 case IrOpcode::kJSBitwiseOr:
90 case IrOpcode::kJSBitwiseXor:
91 case IrOpcode::kJSDivide:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040092 case IrOpcode::kJSModulus:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093 case IrOpcode::kJSShiftLeft:
94 case IrOpcode::kJSShiftRight:
95 case IrOpcode::kJSShiftRightLogical:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040096 case IrOpcode::kJSSubtract:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097 return 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040098
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000099 // Compare operators that can deopt in the middle the operation (e.g.,
100 // as a result of lazy deopt in ToNumber conversion) need a second frame
101 // state so that we can resume before the operation.
102 case IrOpcode::kJSGreaterThan:
103 case IrOpcode::kJSGreaterThanOrEqual:
104 case IrOpcode::kJSLessThan:
105 case IrOpcode::kJSLessThanOrEqual:
106 return 2;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400107
108 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000109 return 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110 }
111}
112
113
114// static
115int OperatorProperties::GetTotalInputCount(const Operator* op) {
116 return op->ValueInputCount() + GetContextInputCount(op) +
117 GetFrameStateInputCount(op) + op->EffectInputCount() +
118 op->ControlInputCount();
119}
120
121
122// static
123bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
124 Operator::Opcode const opcode = op->opcode();
125 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
126 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
127 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 opcode == IrOpcode::kIfFalse || opcode == IrOpcode::kIfSuccess ||
129 opcode == IrOpcode::kIfException || opcode == IrOpcode::kIfValue ||
130 opcode == IrOpcode::kIfDefault;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400131}
132
133} // namespace compiler
134} // namespace internal
135} // namespace v8