| 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/linkage.h" | 10 #include "src/compiler/linkage.h" |
| 11 #include "src/compiler/opcodes.h" | 11 #include "src/compiler/opcodes.h" |
| 12 #include "src/compiler/operator-properties.h" | 12 #include "src/compiler/operator-properties.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 namespace compiler { | 16 namespace compiler { |
| 17 | 17 |
| 18 inline bool OperatorProperties::HasValueInput(const Operator* op) { | 18 inline bool OperatorProperties::HasValueInput(const Operator* op) { |
| 19 return OperatorProperties::GetValueInputCount(op) > 0; | 19 return op->ValueInputCount() > 0; |
| 20 } | 20 } |
| 21 | 21 |
| 22 inline bool OperatorProperties::HasContextInput(const Operator* op) { | 22 inline bool OperatorProperties::HasContextInput(const Operator* op) { |
| 23 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); | 23 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); |
| 24 return IrOpcode::IsJsOpcode(opcode); | 24 return IrOpcode::IsJsOpcode(opcode); |
| 25 } | 25 } |
| 26 | 26 |
| 27 inline bool OperatorProperties::HasEffectInput(const Operator* op) { | 27 inline bool OperatorProperties::HasEffectInput(const Operator* op) { |
| 28 return OperatorProperties::GetEffectInputCount(op) > 0; | 28 return op->EffectInputCount() > 0; |
| 29 } | 29 } |
| 30 | 30 |
| 31 inline bool OperatorProperties::HasControlInput(const Operator* op) { | 31 inline bool OperatorProperties::HasControlInput(const Operator* op) { |
| 32 return OperatorProperties::GetControlInputCount(op) > 0; | 32 return op->ControlInputCount() > 0; |
| 33 } | 33 } |
| 34 | 34 |
| 35 inline bool OperatorProperties::HasFrameStateInput(const Operator* op) { | 35 inline bool OperatorProperties::HasFrameStateInput(const Operator* op) { |
| 36 if (!FLAG_turbo_deoptimization) { | 36 if (!FLAG_turbo_deoptimization) { |
| 37 return false; | 37 return false; |
| 38 } | 38 } |
| 39 | 39 |
| 40 switch (op->opcode()) { | 40 switch (op->opcode()) { |
| 41 case IrOpcode::kFrameState: | 41 case IrOpcode::kFrameState: |
| 42 return true; | 42 return true; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 // Other | 87 // Other |
| 88 case IrOpcode::kJSDeleteProperty: | 88 case IrOpcode::kJSDeleteProperty: |
| 89 return true; | 89 return true; |
| 90 | 90 |
| 91 default: | 91 default: |
| 92 return false; | 92 return false; |
| 93 } | 93 } |
| 94 } | 94 } |
| 95 | 95 |
| 96 inline int OperatorProperties::GetValueInputCount(const Operator* op) { | 96 inline int OperatorProperties::GetValueInputCount(const Operator* op) { |
| 97 return op->InputCount(); | 97 return op->ValueInputCount(); |
| 98 } | 98 } |
| 99 | 99 |
| 100 inline int OperatorProperties::GetContextInputCount(const Operator* op) { | 100 inline int OperatorProperties::GetContextInputCount(const Operator* op) { |
| 101 return OperatorProperties::HasContextInput(op) ? 1 : 0; | 101 return OperatorProperties::HasContextInput(op) ? 1 : 0; |
| 102 } | 102 } |
| 103 | 103 |
| 104 inline int OperatorProperties::GetFrameStateInputCount(const Operator* op) { | 104 inline int OperatorProperties::GetFrameStateInputCount(const Operator* op) { |
| 105 return OperatorProperties::HasFrameStateInput(op) ? 1 : 0; | 105 return OperatorProperties::HasFrameStateInput(op) ? 1 : 0; |
| 106 } | 106 } |
| 107 | 107 |
| 108 inline int OperatorProperties::GetEffectInputCount(const Operator* op) { | 108 inline int OperatorProperties::GetEffectInputCount(const Operator* op) { |
| 109 if (op->opcode() == IrOpcode::kEffectPhi || | 109 return op->EffectInputCount(); |
| 110 op->opcode() == IrOpcode::kFinish || | |
| 111 op->opcode() == IrOpcode::kTerminate) { | |
| 112 return OpParameter<int>(op); | |
| 113 } | |
| 114 if (op->HasProperty(Operator::kNoRead) && op->HasProperty(Operator::kNoWrite)) | |
| 115 return 0; // no effects. | |
| 116 return 1; | |
| 117 } | 110 } |
| 118 | 111 |
| 119 inline int OperatorProperties::GetControlInputCount(const Operator* op) { | 112 inline int OperatorProperties::GetControlInputCount(const Operator* op) { |
| 120 // TODO(titzer): fix this mess; just make them a count on the operator. | 113 return op->ControlInputCount(); |
| 121 switch (op->opcode()) { | |
| 122 case IrOpcode::kPhi: | |
| 123 case IrOpcode::kEffectPhi: | |
| 124 case IrOpcode::kLoad: | |
| 125 case IrOpcode::kLoadField: | |
| 126 case IrOpcode::kInt32Div: | |
| 127 case IrOpcode::kInt32Mod: | |
| 128 case IrOpcode::kUint32Div: | |
| 129 case IrOpcode::kUint32Mod: | |
| 130 return 1; | |
| 131 #define OPCODE_CASE(x) case IrOpcode::k##x: | |
| 132 CONTROL_OP_LIST(OPCODE_CASE) | |
| 133 #undef OPCODE_CASE | |
| 134 if (op->opcode() == IrOpcode::kBranch) return 1; | |
| 135 if (op->opcode() == IrOpcode::kTerminate) return 1; | |
| 136 // Control operators are Operator1<int>. | |
| 137 return OpParameter<int>(op); | |
| 138 default: | |
| 139 // Operators that have write effects must have a control | |
| 140 // dependency. Effect dependencies only ensure the correct order of | |
| 141 // write/read operations without consideration of control flow. Without an | |
| 142 // explicit control dependency writes can be float in the schedule too | |
| 143 // early along a path that shouldn't generate a side-effect. | |
| 144 return op->HasProperty(Operator::kNoWrite) ? 0 : 1; | |
| 145 } | |
| 146 return 0; | |
| 147 } | 114 } |
| 148 | 115 |
| 149 inline int OperatorProperties::GetTotalInputCount(const Operator* op) { | 116 inline int OperatorProperties::GetTotalInputCount(const Operator* op) { |
| 150 return GetValueInputCount(op) + GetContextInputCount(op) + | 117 return GetValueInputCount(op) + GetContextInputCount(op) + |
| 151 GetFrameStateInputCount(op) + GetEffectInputCount(op) + | 118 GetFrameStateInputCount(op) + GetEffectInputCount(op) + |
| 152 GetControlInputCount(op); | 119 GetControlInputCount(op); |
| 153 } | 120 } |
| 154 | 121 |
| 155 // ----------------------------------------------------------------------------- | 122 // ----------------------------------------------------------------------------- |
| 156 // Output properties. | 123 // Output properties. |
| 157 | 124 |
| 158 inline bool OperatorProperties::HasValueOutput(const Operator* op) { | 125 inline bool OperatorProperties::HasValueOutput(const Operator* op) { |
| 159 return GetValueOutputCount(op) > 0; | 126 return op->ValueOutputCount() > 0; |
| 160 } | 127 } |
| 161 | 128 |
| 162 inline bool OperatorProperties::HasEffectOutput(const Operator* op) { | 129 inline bool OperatorProperties::HasEffectOutput(const Operator* op) { |
| 163 return op->opcode() == IrOpcode::kStart || | 130 return op->EffectOutputCount() > 0; |
| 164 op->opcode() == IrOpcode::kValueEffect || | |
| 165 (op->opcode() != IrOpcode::kFinish && | |
| 166 op->opcode() != IrOpcode::kTerminate && GetEffectInputCount(op) > 0); | |
| 167 } | 131 } |
| 168 | 132 |
| 169 inline bool OperatorProperties::HasControlOutput(const Operator* op) { | 133 inline bool OperatorProperties::HasControlOutput(const Operator* op) { |
| 170 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); | 134 return op->ControlOutputCount() > 0; |
| 171 return (opcode != IrOpcode::kEnd && IrOpcode::IsControlOpcode(opcode)); | |
| 172 } | 135 } |
| 173 | 136 |
| 174 | 137 |
| 175 inline int OperatorProperties::GetValueOutputCount(const Operator* op) { | 138 inline int OperatorProperties::GetValueOutputCount(const Operator* op) { |
| 176 return op->OutputCount(); | 139 return op->ValueOutputCount(); |
| 177 } | 140 } |
| 178 | 141 |
| 179 inline int OperatorProperties::GetEffectOutputCount(const Operator* op) { | 142 inline int OperatorProperties::GetEffectOutputCount(const Operator* op) { |
| 180 return HasEffectOutput(op) ? 1 : 0; | 143 return op->EffectOutputCount(); |
| 181 } | 144 } |
| 182 | 145 |
| 183 inline int OperatorProperties::GetControlOutputCount(const Operator* node) { | 146 inline int OperatorProperties::GetControlOutputCount(const Operator* op) { |
| 184 return node->opcode() == IrOpcode::kBranch ? 2 : HasControlOutput(node) ? 1 | 147 return op->ControlOutputCount(); |
| 185 : 0; | |
| 186 } | 148 } |
| 187 | 149 |
| 188 | 150 |
| 189 inline bool OperatorProperties::IsBasicBlockBegin(const Operator* op) { | 151 inline bool OperatorProperties::IsBasicBlockBegin(const Operator* op) { |
| 190 uint8_t opcode = op->opcode(); | 152 uint8_t opcode = op->opcode(); |
| 191 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd || | 153 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd || |
| 192 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop || | 154 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop || |
| 193 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue || | 155 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue || |
| 194 opcode == IrOpcode::kIfFalse; | 156 opcode == IrOpcode::kIfFalse; |
| 195 } | 157 } |
| 196 | 158 |
| 197 } // namespace compiler | 159 } // namespace compiler |
| 198 } // namespace internal | 160 } // namespace internal |
| 199 } // namespace v8 | 161 } // namespace v8 |
| 200 | 162 |
| 201 #endif // V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ | 163 #endif // V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ |
| OLD | NEW |