| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #ifndef V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ | 5 #ifndef V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ |
| 6 #define V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ | 6 #define V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ |
| 7 | 7 |
| 8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
| 9 #include "src/compiler/js-operator.h" | 9 #include "src/compiler/js-operator.h" |
| 10 #include "src/compiler/opcodes.h" | 10 #include "src/compiler/opcodes.h" |
| 11 #include "src/compiler/operator-properties.h" | 11 #include "src/compiler/operator-properties.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 namespace compiler { | 15 namespace compiler { |
| 16 | 16 |
| 17 inline bool OperatorProperties::HasValueInput(Operator* op) { | 17 inline bool OperatorProperties::HasValueInput(const Operator* op) { |
| 18 return OperatorProperties::GetValueInputCount(op) > 0; | 18 return OperatorProperties::GetValueInputCount(op) > 0; |
| 19 } | 19 } |
| 20 | 20 |
| 21 inline bool OperatorProperties::HasContextInput(Operator* op) { | 21 inline bool OperatorProperties::HasContextInput(const Operator* op) { |
| 22 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); | 22 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); |
| 23 return IrOpcode::IsJsOpcode(opcode); | 23 return IrOpcode::IsJsOpcode(opcode); |
| 24 } | 24 } |
| 25 | 25 |
| 26 inline bool OperatorProperties::HasEffectInput(Operator* op) { | 26 inline bool OperatorProperties::HasEffectInput(const Operator* op) { |
| 27 return OperatorProperties::GetEffectInputCount(op) > 0; | 27 return OperatorProperties::GetEffectInputCount(op) > 0; |
| 28 } | 28 } |
| 29 | 29 |
| 30 inline bool OperatorProperties::HasControlInput(Operator* op) { | 30 inline bool OperatorProperties::HasControlInput(const Operator* op) { |
| 31 return OperatorProperties::GetControlInputCount(op) > 0; | 31 return OperatorProperties::GetControlInputCount(op) > 0; |
| 32 } | 32 } |
| 33 | 33 |
| 34 inline bool OperatorProperties::HasFrameStateInput(Operator* op) { | 34 inline bool OperatorProperties::HasFrameStateInput(const Operator* op) { |
| 35 if (!FLAG_turbo_deoptimization) { | 35 if (!FLAG_turbo_deoptimization) { |
| 36 return false; | 36 return false; |
| 37 } | 37 } |
| 38 | 38 |
| 39 switch (op->opcode()) { | 39 switch (op->opcode()) { |
| 40 case IrOpcode::kFrameState: | 40 case IrOpcode::kFrameState: |
| 41 return true; | 41 return true; |
| 42 case IrOpcode::kJSCallRuntime: { | 42 case IrOpcode::kJSCallRuntime: { |
| 43 Runtime::FunctionId function = | 43 Runtime::FunctionId function = OpParameter<Runtime::FunctionId>(op); |
| 44 reinterpret_cast<Operator1<Runtime::FunctionId>*>(op)->parameter(); | |
| 45 return Linkage::NeedsFrameState(function); | 44 return Linkage::NeedsFrameState(function); |
| 46 } | 45 } |
| 47 | 46 |
| 48 // Strict equality cannot lazily deoptimize. | 47 // Strict equality cannot lazily deoptimize. |
| 49 case IrOpcode::kJSStrictEqual: | 48 case IrOpcode::kJSStrictEqual: |
| 50 case IrOpcode::kJSStrictNotEqual: | 49 case IrOpcode::kJSStrictNotEqual: |
| 51 return false; | 50 return false; |
| 52 | 51 |
| 53 // Calls | 52 // Calls |
| 54 case IrOpcode::kJSCallFunction: | 53 case IrOpcode::kJSCallFunction: |
| (...skipping 23 matching lines...) Expand all Loading... |
| 78 case IrOpcode::kJSStoreProperty: | 77 case IrOpcode::kJSStoreProperty: |
| 79 case IrOpcode::kJSLoadNamed: | 78 case IrOpcode::kJSLoadNamed: |
| 80 case IrOpcode::kJSStoreNamed: | 79 case IrOpcode::kJSStoreNamed: |
| 81 return true; | 80 return true; |
| 82 | 81 |
| 83 default: | 82 default: |
| 84 return false; | 83 return false; |
| 85 } | 84 } |
| 86 } | 85 } |
| 87 | 86 |
| 88 inline int OperatorProperties::GetValueInputCount(Operator* op) { | 87 inline int OperatorProperties::GetValueInputCount(const Operator* op) { |
| 89 return op->InputCount(); | 88 return op->InputCount(); |
| 90 } | 89 } |
| 91 | 90 |
| 92 inline int OperatorProperties::GetContextInputCount(Operator* op) { | 91 inline int OperatorProperties::GetContextInputCount(const Operator* op) { |
| 93 return OperatorProperties::HasContextInput(op) ? 1 : 0; | 92 return OperatorProperties::HasContextInput(op) ? 1 : 0; |
| 94 } | 93 } |
| 95 | 94 |
| 96 inline int OperatorProperties::GetFrameStateInputCount(Operator* op) { | 95 inline int OperatorProperties::GetFrameStateInputCount(const Operator* op) { |
| 97 return OperatorProperties::HasFrameStateInput(op) ? 1 : 0; | 96 return OperatorProperties::HasFrameStateInput(op) ? 1 : 0; |
| 98 } | 97 } |
| 99 | 98 |
| 100 inline int OperatorProperties::GetEffectInputCount(Operator* op) { | 99 inline int OperatorProperties::GetEffectInputCount(const Operator* op) { |
| 101 if (op->opcode() == IrOpcode::kEffectPhi || | 100 if (op->opcode() == IrOpcode::kEffectPhi || |
| 102 op->opcode() == IrOpcode::kFinish) { | 101 op->opcode() == IrOpcode::kFinish) { |
| 103 return static_cast<Operator1<int>*>(op)->parameter(); | 102 return OpParameter<int>(op); |
| 104 } | 103 } |
| 105 if (op->HasProperty(Operator::kNoRead) && op->HasProperty(Operator::kNoWrite)) | 104 if (op->HasProperty(Operator::kNoRead) && op->HasProperty(Operator::kNoWrite)) |
| 106 return 0; // no effects. | 105 return 0; // no effects. |
| 107 return 1; | 106 return 1; |
| 108 } | 107 } |
| 109 | 108 |
| 110 inline int OperatorProperties::GetControlInputCount(Operator* op) { | 109 inline int OperatorProperties::GetControlInputCount(const Operator* op) { |
| 111 switch (op->opcode()) { | 110 switch (op->opcode()) { |
| 112 case IrOpcode::kPhi: | 111 case IrOpcode::kPhi: |
| 113 case IrOpcode::kEffectPhi: | 112 case IrOpcode::kEffectPhi: |
| 114 case IrOpcode::kControlEffect: | 113 case IrOpcode::kControlEffect: |
| 115 return 1; | 114 return 1; |
| 116 #define OPCODE_CASE(x) case IrOpcode::k##x: | 115 #define OPCODE_CASE(x) case IrOpcode::k##x: |
| 117 CONTROL_OP_LIST(OPCODE_CASE) | 116 CONTROL_OP_LIST(OPCODE_CASE) |
| 118 #undef OPCODE_CASE | 117 #undef OPCODE_CASE |
| 119 return static_cast<ControlOperator*>(op)->ControlInputCount(); | 118 return reinterpret_cast<const ControlOperator*>(op)->ControlInputCount(); |
| 120 default: | 119 default: |
| 121 // Operators that have write effects must have a control | 120 // Operators that have write effects must have a control |
| 122 // dependency. Effect dependencies only ensure the correct order of | 121 // dependency. Effect dependencies only ensure the correct order of |
| 123 // write/read operations without consideration of control flow. Without an | 122 // write/read operations without consideration of control flow. Without an |
| 124 // explicit control dependency writes can be float in the schedule too | 123 // explicit control dependency writes can be float in the schedule too |
| 125 // early along a path that shouldn't generate a side-effect. | 124 // early along a path that shouldn't generate a side-effect. |
| 126 return op->HasProperty(Operator::kNoWrite) ? 0 : 1; | 125 return op->HasProperty(Operator::kNoWrite) ? 0 : 1; |
| 127 } | 126 } |
| 128 return 0; | 127 return 0; |
| 129 } | 128 } |
| 130 | 129 |
| 131 inline int OperatorProperties::GetTotalInputCount(Operator* op) { | 130 inline int OperatorProperties::GetTotalInputCount(const Operator* op) { |
| 132 return GetValueInputCount(op) + GetContextInputCount(op) + | 131 return GetValueInputCount(op) + GetContextInputCount(op) + |
| 133 GetFrameStateInputCount(op) + GetEffectInputCount(op) + | 132 GetFrameStateInputCount(op) + GetEffectInputCount(op) + |
| 134 GetControlInputCount(op); | 133 GetControlInputCount(op); |
| 135 } | 134 } |
| 136 | 135 |
| 137 // ----------------------------------------------------------------------------- | 136 // ----------------------------------------------------------------------------- |
| 138 // Output properties. | 137 // Output properties. |
| 139 | 138 |
| 140 inline bool OperatorProperties::HasValueOutput(Operator* op) { | 139 inline bool OperatorProperties::HasValueOutput(const Operator* op) { |
| 141 return GetValueOutputCount(op) > 0; | 140 return GetValueOutputCount(op) > 0; |
| 142 } | 141 } |
| 143 | 142 |
| 144 inline bool OperatorProperties::HasEffectOutput(Operator* op) { | 143 inline bool OperatorProperties::HasEffectOutput(const Operator* op) { |
| 145 return op->opcode() == IrOpcode::kStart || | 144 return op->opcode() == IrOpcode::kStart || |
| 146 op->opcode() == IrOpcode::kControlEffect || | 145 op->opcode() == IrOpcode::kControlEffect || |
| 147 op->opcode() == IrOpcode::kValueEffect || | 146 op->opcode() == IrOpcode::kValueEffect || |
| 148 (op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) > 0); | 147 (op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) > 0); |
| 149 } | 148 } |
| 150 | 149 |
| 151 inline bool OperatorProperties::HasControlOutput(Operator* op) { | 150 inline bool OperatorProperties::HasControlOutput(const Operator* op) { |
| 152 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); | 151 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); |
| 153 return (opcode != IrOpcode::kEnd && IrOpcode::IsControlOpcode(opcode)); | 152 return (opcode != IrOpcode::kEnd && IrOpcode::IsControlOpcode(opcode)); |
| 154 } | 153 } |
| 155 | 154 |
| 156 | 155 |
| 157 inline int OperatorProperties::GetValueOutputCount(Operator* op) { | 156 inline int OperatorProperties::GetValueOutputCount(const Operator* op) { |
| 158 return op->OutputCount(); | 157 return op->OutputCount(); |
| 159 } | 158 } |
| 160 | 159 |
| 161 inline int OperatorProperties::GetEffectOutputCount(Operator* op) { | 160 inline int OperatorProperties::GetEffectOutputCount(const Operator* op) { |
| 162 return HasEffectOutput(op) ? 1 : 0; | 161 return HasEffectOutput(op) ? 1 : 0; |
| 163 } | 162 } |
| 164 | 163 |
| 165 inline int OperatorProperties::GetControlOutputCount(Operator* node) { | 164 inline int OperatorProperties::GetControlOutputCount(const Operator* node) { |
| 166 return node->opcode() == IrOpcode::kBranch ? 2 : HasControlOutput(node) ? 1 | 165 return node->opcode() == IrOpcode::kBranch ? 2 : HasControlOutput(node) ? 1 |
| 167 : 0; | 166 : 0; |
| 168 } | 167 } |
| 169 | 168 |
| 170 | 169 |
| 171 inline bool OperatorProperties::IsBasicBlockBegin(Operator* op) { | 170 inline bool OperatorProperties::IsBasicBlockBegin(const Operator* op) { |
| 172 uint8_t opcode = op->opcode(); | 171 uint8_t opcode = op->opcode(); |
| 173 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd || | 172 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd || |
| 174 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop || | 173 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop || |
| 175 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue || | 174 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue || |
| 176 opcode == IrOpcode::kIfFalse; | 175 opcode == IrOpcode::kIfFalse; |
| 177 } | 176 } |
| 178 | 177 |
| 179 } | 178 } // namespace compiler |
| 180 } | 179 } // namespace internal |
| 181 } // namespace v8::internal::compiler | 180 } // namespace v8 |
| 182 | 181 |
| 183 #endif // V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ | 182 #endif // V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ |
| OLD | NEW |