diff options
Diffstat (limited to 'deps/v8/src/compiler/common-operator.h')
-rw-r--r-- | deps/v8/src/compiler/common-operator.h | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/deps/v8/src/compiler/common-operator.h b/deps/v8/src/compiler/common-operator.h new file mode 100644 index 000000000..3b581ae0c --- /dev/null +++ b/deps/v8/src/compiler/common-operator.h @@ -0,0 +1,284 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_COMPILER_COMMON_OPERATOR_H_ +#define V8_COMPILER_COMMON_OPERATOR_H_ + +#include "src/v8.h" + +#include "src/assembler.h" +#include "src/compiler/linkage.h" +#include "src/compiler/opcodes.h" +#include "src/compiler/operator.h" +#include "src/unique.h" + +namespace v8 { +namespace internal { + +class OStream; + +namespace compiler { + +class ControlOperator : public Operator1<int> { + public: + ControlOperator(IrOpcode::Value opcode, uint16_t properties, int inputs, + int outputs, int controls, const char* mnemonic) + : Operator1<int>(opcode, properties, inputs, outputs, mnemonic, + controls) {} + + virtual OStream& PrintParameter(OStream& os) const { return os; } // NOLINT + int ControlInputCount() const { return parameter(); } +}; + +class CallOperator : public Operator1<CallDescriptor*> { + public: + CallOperator(CallDescriptor* descriptor, const char* mnemonic) + : Operator1<CallDescriptor*>( + IrOpcode::kCall, descriptor->properties(), descriptor->InputCount(), + descriptor->ReturnCount(), mnemonic, descriptor) {} + + virtual OStream& PrintParameter(OStream& os) const { // NOLINT + return os << "[" << *parameter() << "]"; + } +}; + +// Interface for building common operators that can be used at any level of IR, +// including JavaScript, mid-level, and low-level. +// TODO(titzer): Move the mnemonics into SimpleOperator and Operator1 classes. +class CommonOperatorBuilder { + public: + explicit CommonOperatorBuilder(Zone* zone) : zone_(zone) {} + +#define CONTROL_OP(name, inputs, controls) \ + return new (zone_) ControlOperator(IrOpcode::k##name, Operator::kFoldable, \ + inputs, 0, controls, #name); + + Operator* Start(int num_formal_parameters) { + // Outputs are formal parameters, plus context, receiver, and JSFunction. + int outputs = num_formal_parameters + 3; + return new (zone_) ControlOperator(IrOpcode::kStart, Operator::kFoldable, 0, + outputs, 0, "Start"); + } + Operator* Dead() { CONTROL_OP(Dead, 0, 0); } + Operator* End() { CONTROL_OP(End, 0, 1); } + Operator* Branch() { CONTROL_OP(Branch, 1, 1); } + Operator* IfTrue() { CONTROL_OP(IfTrue, 0, 1); } + Operator* IfFalse() { CONTROL_OP(IfFalse, 0, 1); } + Operator* Throw() { CONTROL_OP(Throw, 1, 1); } + Operator* LazyDeoptimization() { CONTROL_OP(LazyDeoptimization, 0, 1); } + Operator* Continuation() { CONTROL_OP(Continuation, 0, 1); } + + Operator* Deoptimize() { + return new (zone_) + ControlOperator(IrOpcode::kDeoptimize, 0, 1, 0, 1, "Deoptimize"); + } + + Operator* Return() { + return new (zone_) ControlOperator(IrOpcode::kReturn, 0, 1, 0, 1, "Return"); + } + + Operator* Merge(int controls) { + return new (zone_) ControlOperator(IrOpcode::kMerge, Operator::kFoldable, 0, + 0, controls, "Merge"); + } + + Operator* Loop(int controls) { + return new (zone_) ControlOperator(IrOpcode::kLoop, Operator::kFoldable, 0, + 0, controls, "Loop"); + } + + Operator* Parameter(int index) { + return new (zone_) Operator1<int>(IrOpcode::kParameter, Operator::kPure, 1, + 1, "Parameter", index); + } + Operator* Int32Constant(int32_t value) { + return new (zone_) Operator1<int>(IrOpcode::kInt32Constant, Operator::kPure, + 0, 1, "Int32Constant", value); + } + Operator* Int64Constant(int64_t value) { + return new (zone_) + Operator1<int64_t>(IrOpcode::kInt64Constant, Operator::kPure, 0, 1, + "Int64Constant", value); + } + Operator* Float64Constant(double value) { + return new (zone_) + Operator1<double>(IrOpcode::kFloat64Constant, Operator::kPure, 0, 1, + "Float64Constant", value); + } + Operator* ExternalConstant(ExternalReference value) { + return new (zone_) Operator1<ExternalReference>(IrOpcode::kExternalConstant, + Operator::kPure, 0, 1, + "ExternalConstant", value); + } + Operator* NumberConstant(double value) { + return new (zone_) + Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1, + "NumberConstant", value); + } + Operator* HeapConstant(PrintableUnique<Object> value) { + return new (zone_) Operator1<PrintableUnique<Object> >( + IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value); + } + Operator* Phi(int arguments) { + DCHECK(arguments > 0); // Disallow empty phis. + return new (zone_) Operator1<int>(IrOpcode::kPhi, Operator::kPure, + arguments, 1, "Phi", arguments); + } + Operator* EffectPhi(int arguments) { + DCHECK(arguments > 0); // Disallow empty phis. + return new (zone_) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0, + 0, "EffectPhi", arguments); + } + Operator* StateValues(int arguments) { + return new (zone_) Operator1<int>(IrOpcode::kStateValues, Operator::kPure, + arguments, 1, "StateValues", arguments); + } + Operator* FrameState(BailoutId ast_id) { + return new (zone_) Operator1<BailoutId>( + IrOpcode::kFrameState, Operator::kPure, 3, 1, "FrameState", ast_id); + } + Operator* Call(CallDescriptor* descriptor) { + return new (zone_) CallOperator(descriptor, "Call"); + } + Operator* Projection(int index) { + return new (zone_) Operator1<int>(IrOpcode::kProjection, Operator::kPure, 1, + 1, "Projection", index); + } + + private: + Zone* zone_; +}; + + +template <typename T> +struct CommonOperatorTraits { + static inline bool Equals(T a, T b); + static inline bool HasValue(Operator* op); + static inline T ValueOf(Operator* op); +}; + +template <> +struct CommonOperatorTraits<int32_t> { + static inline bool Equals(int32_t a, int32_t b) { return a == b; } + static inline bool HasValue(Operator* op) { + return op->opcode() == IrOpcode::kInt32Constant || + op->opcode() == IrOpcode::kNumberConstant; + } + static inline int32_t ValueOf(Operator* op) { + if (op->opcode() == IrOpcode::kNumberConstant) { + // TODO(titzer): cache the converted int32 value in NumberConstant. + return FastD2I(reinterpret_cast<Operator1<double>*>(op)->parameter()); + } + CHECK_EQ(IrOpcode::kInt32Constant, op->opcode()); + return static_cast<Operator1<int32_t>*>(op)->parameter(); + } +}; + +template <> +struct CommonOperatorTraits<uint32_t> { + static inline bool Equals(uint32_t a, uint32_t b) { return a == b; } + static inline bool HasValue(Operator* op) { + return CommonOperatorTraits<int32_t>::HasValue(op); + } + static inline uint32_t ValueOf(Operator* op) { + if (op->opcode() == IrOpcode::kNumberConstant) { + // TODO(titzer): cache the converted uint32 value in NumberConstant. + return FastD2UI(reinterpret_cast<Operator1<double>*>(op)->parameter()); + } + return static_cast<uint32_t>(CommonOperatorTraits<int32_t>::ValueOf(op)); + } +}; + +template <> +struct CommonOperatorTraits<int64_t> { + static inline bool Equals(int64_t a, int64_t b) { return a == b; } + static inline bool HasValue(Operator* op) { + return op->opcode() == IrOpcode::kInt32Constant || + op->opcode() == IrOpcode::kInt64Constant || + op->opcode() == IrOpcode::kNumberConstant; + } + static inline int64_t ValueOf(Operator* op) { + if (op->opcode() == IrOpcode::kInt32Constant) { + return static_cast<int64_t>(CommonOperatorTraits<int32_t>::ValueOf(op)); + } + CHECK_EQ(IrOpcode::kInt64Constant, op->opcode()); + return static_cast<Operator1<int64_t>*>(op)->parameter(); + } +}; + +template <> +struct CommonOperatorTraits<uint64_t> { + static inline bool Equals(uint64_t a, uint64_t b) { return a == b; } + static inline bool HasValue(Operator* op) { + return CommonOperatorTraits<int64_t>::HasValue(op); + } + static inline uint64_t ValueOf(Operator* op) { + return static_cast<uint64_t>(CommonOperatorTraits<int64_t>::ValueOf(op)); + } +}; + +template <> +struct CommonOperatorTraits<double> { + static inline bool Equals(double a, double b) { + return DoubleRepresentation(a).bits == DoubleRepresentation(b).bits; + } + static inline bool HasValue(Operator* op) { + return op->opcode() == IrOpcode::kFloat64Constant || + op->opcode() == IrOpcode::kInt32Constant || + op->opcode() == IrOpcode::kNumberConstant; + } + static inline double ValueOf(Operator* op) { + if (op->opcode() == IrOpcode::kFloat64Constant || + op->opcode() == IrOpcode::kNumberConstant) { + return reinterpret_cast<Operator1<double>*>(op)->parameter(); + } + return static_cast<double>(CommonOperatorTraits<int32_t>::ValueOf(op)); + } +}; + +template <> +struct CommonOperatorTraits<ExternalReference> { + static inline bool Equals(ExternalReference a, ExternalReference b) { + return a == b; + } + static inline bool HasValue(Operator* op) { + return op->opcode() == IrOpcode::kExternalConstant; + } + static inline ExternalReference ValueOf(Operator* op) { + CHECK_EQ(IrOpcode::kExternalConstant, op->opcode()); + return static_cast<Operator1<ExternalReference>*>(op)->parameter(); + } +}; + +template <typename T> +struct CommonOperatorTraits<PrintableUnique<T> > { + static inline bool HasValue(Operator* op) { + return op->opcode() == IrOpcode::kHeapConstant; + } + static inline PrintableUnique<T> ValueOf(Operator* op) { + CHECK_EQ(IrOpcode::kHeapConstant, op->opcode()); + return static_cast<Operator1<PrintableUnique<T> >*>(op)->parameter(); + } +}; + +template <typename T> +struct CommonOperatorTraits<Handle<T> > { + static inline bool HasValue(Operator* op) { + return CommonOperatorTraits<PrintableUnique<T> >::HasValue(op); + } + static inline Handle<T> ValueOf(Operator* op) { + return CommonOperatorTraits<PrintableUnique<T> >::ValueOf(op).handle(); + } +}; + + +template <typename T> +inline T ValueOf(Operator* op) { + return CommonOperatorTraits<T>::ValueOf(op); +} +} +} +} // namespace v8::internal::compiler + +#endif // V8_COMPILER_COMMON_OPERATOR_H_ |