| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // 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 | 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 #include "src/compiler/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
| 6 | 6 |
| 7 #include "src/assembler.h" | 7 #include "src/assembler.h" |
| 8 #include "src/base/lazy-instance.h" | 8 #include "src/base/lazy-instance.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/unique.h" | 10 #include "src/unique.h" |
| 11 #include "src/zone.h" | 11 #include "src/zone.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 namespace compiler { | 15 namespace compiler { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // TODO(turbofan): Use size_t instead of int here. | 19 // TODO(turbofan): Use size_t instead of int here. |
| 20 class ControlOperator : public Operator1<int> { | 20 class ControlOperator : public Operator1<int> { |
| 21 public: | 21 public: |
| 22 ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs, | 22 ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs, |
| 23 int outputs, int controls, const char* mnemonic) | 23 int outputs, int controls, const char* mnemonic) |
| 24 : Operator1<int>(opcode, properties, inputs, outputs, mnemonic, | 24 : Operator1<int>(opcode, properties, inputs, outputs, mnemonic, |
| 25 controls) {} | 25 controls) {} |
| 26 | 26 |
| 27 virtual std::ostream& PrintParameter(std::ostream& os) const FINAL { | 27 virtual void PrintParameter(std::ostream& os) const FINAL {} |
| 28 return os; | |
| 29 } | |
| 30 }; | 28 }; |
| 31 | 29 |
| 32 } // namespace | 30 } // namespace |
| 33 | 31 |
| 34 | 32 |
| 35 // Specialization for static parameters of type {ExternalReference}. | 33 size_t hash_value(OutputFrameStateCombine const& sc) { |
| 36 template <> | 34 return base::hash_combine(sc.kind_, sc.parameter_); |
| 37 struct StaticParameterTraits<ExternalReference> { | 35 } |
| 38 static std::ostream& PrintTo(std::ostream& os, ExternalReference reference) { | 36 |
| 39 os << static_cast<const void*>(reference.address()); | 37 |
| 40 // TODO(bmeurer): Move to operator<<(os, ExternalReference) | 38 std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) { |
| 41 const Runtime::Function* function = | 39 switch (sc.kind_) { |
| 42 Runtime::FunctionForEntry(reference.address()); | 40 case OutputFrameStateCombine::kPushOutput: |
| 43 if (function) { | 41 if (sc.parameter_ == 0) return os << "Ignore"; |
| 44 os << " <" << function->name << ".entry>"; | 42 return os << "Push(" << sc.parameter_ << ")"; |
| 45 } | 43 case OutputFrameStateCombine::kPokeAt: |
| 46 return os; | 44 return os << "PokeAt(" << sc.parameter_ << ")"; |
| 47 } | 45 } |
| 48 static int HashCode(ExternalReference reference) { | 46 UNREACHABLE(); |
| 49 return bit_cast<int>(static_cast<uint32_t>( | 47 return os; |
| 50 reinterpret_cast<uintptr_t>(reference.address()))); | 48 } |
| 51 } | 49 |
| 52 static bool Equals(ExternalReference lhs, ExternalReference rhs) { | 50 |
| 53 return lhs == rhs; | 51 bool operator==(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) { |
| 54 } | 52 return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() && |
| 55 }; | 53 lhs.state_combine() == rhs.state_combine(); |
| 54 } |
| 55 |
| 56 |
| 57 bool operator!=(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) { |
| 58 return !(lhs == rhs); |
| 59 } |
| 60 |
| 61 |
| 62 size_t hash_value(FrameStateCallInfo const& info) { |
| 63 return base::hash_combine(info.type(), info.bailout_id(), |
| 64 info.state_combine()); |
| 65 } |
| 66 |
| 67 |
| 68 std::ostream& operator<<(std::ostream& os, FrameStateCallInfo const& info) { |
| 69 return os << info.type() << ", " << info.bailout_id() << ", " |
| 70 << info.state_combine(); |
| 71 } |
| 56 | 72 |
| 57 | 73 |
| 58 #define SHARED_OP_LIST(V) \ | 74 #define SHARED_OP_LIST(V) \ |
| 59 V(Dead, Operator::kFoldable, 0, 0) \ | 75 V(Dead, Operator::kFoldable, 0, 0) \ |
| 60 V(End, Operator::kFoldable, 0, 1) \ | 76 V(End, Operator::kFoldable, 0, 1) \ |
| 61 V(Branch, Operator::kFoldable, 1, 1) \ | 77 V(Branch, Operator::kFoldable, 1, 1) \ |
| 62 V(IfTrue, Operator::kFoldable, 0, 1) \ | 78 V(IfTrue, Operator::kFoldable, 0, 1) \ |
| 63 V(IfFalse, Operator::kFoldable, 0, 1) \ | 79 V(IfFalse, Operator::kFoldable, 0, 1) \ |
| 64 V(Throw, Operator::kFoldable, 1, 1) \ | 80 V(Throw, Operator::kFoldable, 1, 1) \ |
| 65 V(Return, Operator::kNoProperties, 1, 1) | 81 V(Return, Operator::kNoProperties, 1, 1) |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 | 171 |
| 156 | 172 |
| 157 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) { | 173 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) { |
| 158 return new (zone()) | 174 return new (zone()) |
| 159 Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1, | 175 Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1, |
| 160 "NumberConstant", value); | 176 "NumberConstant", value); |
| 161 } | 177 } |
| 162 | 178 |
| 163 | 179 |
| 164 const Operator* CommonOperatorBuilder::HeapConstant( | 180 const Operator* CommonOperatorBuilder::HeapConstant( |
| 165 const Unique<Object>& value) { | 181 const Unique<HeapObject>& value) { |
| 166 return new (zone()) Operator1<Unique<Object> >( | 182 return new (zone()) Operator1<Unique<HeapObject>>( |
| 167 IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value); | 183 IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value); |
| 168 } | 184 } |
| 169 | 185 |
| 170 | 186 |
| 171 const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) { | 187 const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) { |
| 172 DCHECK(arguments > 0); // Disallow empty phis. | 188 DCHECK(arguments > 0); // Disallow empty phis. |
| 173 return new (zone()) Operator1<MachineType>(IrOpcode::kPhi, Operator::kPure, | 189 return new (zone()) Operator1<MachineType>(IrOpcode::kPhi, Operator::kPure, |
| 174 arguments, 1, "Phi", type); | 190 arguments, 1, "Phi", type); |
| 175 } | 191 } |
| 176 | 192 |
| 177 | 193 |
| 178 const Operator* CommonOperatorBuilder::EffectPhi(int arguments) { | 194 const Operator* CommonOperatorBuilder::EffectPhi(int arguments) { |
| 179 DCHECK(arguments > 0); // Disallow empty phis. | 195 DCHECK(arguments > 0); // Disallow empty phis. |
| 180 return new (zone()) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0, | 196 return new (zone()) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0, |
| 181 0, "EffectPhi", arguments); | 197 0, "EffectPhi", arguments); |
| 182 } | 198 } |
| 183 | 199 |
| 184 | 200 |
| 185 const Operator* CommonOperatorBuilder::ValueEffect(int arguments) { | 201 const Operator* CommonOperatorBuilder::ValueEffect(int arguments) { |
| 186 DCHECK(arguments > 0); // Disallow empty value effects. | 202 DCHECK(arguments > 0); // Disallow empty value effects. |
| 187 return new (zone()) SimpleOperator(IrOpcode::kValueEffect, Operator::kPure, | 203 return new (zone()) Operator1<int>(IrOpcode::kValueEffect, Operator::kPure, |
| 188 arguments, 0, "ValueEffect"); | 204 arguments, 0, "ValueEffect", arguments); |
| 189 } | 205 } |
| 190 | 206 |
| 191 | 207 |
| 192 const Operator* CommonOperatorBuilder::Finish(int arguments) { | 208 const Operator* CommonOperatorBuilder::Finish(int arguments) { |
| 193 DCHECK(arguments > 0); // Disallow empty finishes. | 209 DCHECK(arguments > 0); // Disallow empty finishes. |
| 194 return new (zone()) Operator1<int>(IrOpcode::kFinish, Operator::kPure, 1, 1, | 210 return new (zone()) Operator1<int>(IrOpcode::kFinish, Operator::kPure, 1, 1, |
| 195 "Finish", arguments); | 211 "Finish", arguments); |
| 196 } | 212 } |
| 197 | 213 |
| 198 | 214 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 217 // TODO(titzer): Operator still uses int, whereas CallDescriptor uses | 233 // TODO(titzer): Operator still uses int, whereas CallDescriptor uses |
| 218 // size_t. | 234 // size_t. |
| 219 CallOperator(const CallDescriptor* descriptor, const char* mnemonic) | 235 CallOperator(const CallDescriptor* descriptor, const char* mnemonic) |
| 220 : Operator1<const CallDescriptor*>( | 236 : Operator1<const CallDescriptor*>( |
| 221 IrOpcode::kCall, descriptor->properties(), | 237 IrOpcode::kCall, descriptor->properties(), |
| 222 static_cast<int>(descriptor->InputCount() + | 238 static_cast<int>(descriptor->InputCount() + |
| 223 descriptor->FrameStateCount()), | 239 descriptor->FrameStateCount()), |
| 224 static_cast<int>(descriptor->ReturnCount()), mnemonic, | 240 static_cast<int>(descriptor->ReturnCount()), mnemonic, |
| 225 descriptor) {} | 241 descriptor) {} |
| 226 | 242 |
| 227 virtual std::ostream& PrintParameter(std::ostream& os) const OVERRIDE { | 243 virtual void PrintParameter(std::ostream& os) const OVERRIDE { |
| 228 return os << "[" << *parameter() << "]"; | 244 os << "[" << *parameter() << "]"; |
| 229 } | 245 } |
| 230 }; | 246 }; |
| 231 return new (zone()) CallOperator(descriptor, "Call"); | 247 return new (zone()) CallOperator(descriptor, "Call"); |
| 232 } | 248 } |
| 233 | 249 |
| 234 | 250 |
| 235 const Operator* CommonOperatorBuilder::Projection(size_t index) { | 251 const Operator* CommonOperatorBuilder::Projection(size_t index) { |
| 236 return new (zone()) Operator1<size_t>(IrOpcode::kProjection, Operator::kPure, | 252 return new (zone()) Operator1<size_t>(IrOpcode::kProjection, Operator::kPure, |
| 237 1, 1, "Projection", index); | 253 1, 1, "Projection", index); |
| 238 } | 254 } |
| 239 | 255 |
| 240 | |
| 241 OutputFrameStateCombine::OutputFrameStateCombine(CombineKind kind, | |
| 242 size_t parameter) | |
| 243 : kind_(kind), parameter_(parameter) {} | |
| 244 | |
| 245 // static | |
| 246 OutputFrameStateCombine OutputFrameStateCombine::Ignore() { | |
| 247 return OutputFrameStateCombine(kPushOutput, 0); | |
| 248 } | |
| 249 | |
| 250 | |
| 251 // static | |
| 252 OutputFrameStateCombine OutputFrameStateCombine::Push(size_t count) { | |
| 253 return OutputFrameStateCombine(kPushOutput, count); | |
| 254 } | |
| 255 | |
| 256 | |
| 257 // static | |
| 258 OutputFrameStateCombine OutputFrameStateCombine::PokeAt(size_t index) { | |
| 259 return OutputFrameStateCombine(kPokeAt, index); | |
| 260 } | |
| 261 | |
| 262 | |
| 263 OutputFrameStateCombine::CombineKind OutputFrameStateCombine::kind() { | |
| 264 return kind_; | |
| 265 } | |
| 266 | |
| 267 | |
| 268 size_t OutputFrameStateCombine::GetPushCount() { | |
| 269 DCHECK(kind() == kPushOutput); | |
| 270 return parameter_; | |
| 271 } | |
| 272 | |
| 273 | |
| 274 size_t OutputFrameStateCombine::GetOffsetToPokeAt() { | |
| 275 DCHECK(kind() == kPokeAt); | |
| 276 return parameter_; | |
| 277 } | |
| 278 | |
| 279 | |
| 280 bool OutputFrameStateCombine::IsOutputIgnored() { | |
| 281 return kind() == kPushOutput && GetPushCount() == 0; | |
| 282 } | |
| 283 | |
| 284 } // namespace compiler | 256 } // namespace compiler |
| 285 } // namespace internal | 257 } // namespace internal |
| 286 } // namespace v8 | 258 } // namespace v8 |
| OLD | NEW |